|
| 1 | +from ipaddress import IPv4Address |
| 2 | +from unittest import TestCase, main |
| 3 | + |
| 4 | +from macaddress import EUI48 |
| 5 | + |
| 6 | +from tplinkrouterc6u import Connection |
| 7 | +from tplinkrouterc6u.client.wr844n import TplinkWR844NRouter |
| 8 | +from tplinkrouterc6u.common.dataclass import Device, Firmware, Status |
| 9 | +from tplinkrouterc6u.common.exception import ClientException |
| 10 | + |
| 11 | + |
| 12 | +FIRMWARE_RESPONSE = ('00000\r\nid 0|1,0,0\r\nfullName 300Mbps%20Wi-Fi%20Router\r\nfacturer TP-Link\r\n' |
| 13 | + 'modelName TL-WR844N\r\nmodelVer 1.0\r\n' |
| 14 | + 'softVer 1.10.0%20Build%20211011%20Rel.66152n(4555)\r\n' |
| 15 | + 'hardVer TL-WR844N%201.0\r\nprodId 0x8440001') |
| 16 | + |
| 17 | +STATUS_RESPONSE = ('00000\r\nid 1|1,0,0\r\nauthKey token\r\nreserved\r\nsetWzd 1\r\nmode 4\r\n' |
| 18 | + 'mac 0 40-ae-30-af-c8-72\r\nmac 1 40-ae-30-af-c8-73\r\nwanMacType 0\r\n' |
| 19 | + 'id 4|1,0,0\r\nip 192.168.2.1\r\nmask 255.255.255.0\r\nmode 0\r\n' |
| 20 | + 'smartIp 0\r\ngateway 0.0.0.0\r\n' |
| 21 | + 'id 9|1,0,0\r\nhostName 0 LGwebOSTV\r\nhostName 1 Kaspars\r\n' |
| 22 | + 'hostName 2 Redmi-Note-13-Pro-5G\r\nhostName 3\r\n' |
| 23 | + 'mac 0 60-75-6c-a1-4a-82\r\nmac 1 70-08-10-0b-c6-24\r\n' |
| 24 | + 'mac 2 d6-02-54-6b-67-c4\r\nmac 3 00-00-00-00-00-00\r\n' |
| 25 | + 'ip 0 192.168.2.100\r\nip 1 192.168.2.101\r\nip 2 192.168.2.102\r\nip 3 0.0.0.0\r\n' |
| 26 | + 'state 0 5\r\nstate 1 5\r\nstate 2 5\r\nstate 3 0\r\n' |
| 27 | + 'expires 0 4979\r\nexpires 1 5514\r\nexpires 2 6296\r\nexpires 3 0\r\n' |
| 28 | + 'id 0|1,0,0\r\nmodelName TL-WR844N\r\nhardVer TL-WR844N%201.0') |
| 29 | + |
| 30 | + |
| 31 | +class ResponseMock: |
| 32 | + def __init__(self, text, status_code=0): |
| 33 | + self.text = text |
| 34 | + self.status_code = status_code |
| 35 | + |
| 36 | + |
| 37 | +class TplinkWR844NRouterTest(TplinkWR844NRouter): |
| 38 | + response = '' |
| 39 | + |
| 40 | + def request(self, code: int, asyn: int, use_token: bool = False, data: str = None) -> ResponseMock | None: |
| 41 | + if code == 2 and asyn == 1: |
| 42 | + if use_token is False: |
| 43 | + if data == '0|1,0,0': |
| 44 | + return ResponseMock(FIRMWARE_RESPONSE, 200) |
| 45 | + return ResponseMock('blabla\r\nblabla\r\nblabla\r\nauthinfo1\r\nauthinfo2') |
| 46 | + return ResponseMock(self.response) |
| 47 | + if (code == 16 or code == 7) and asyn == 0: |
| 48 | + if use_token is False: |
| 49 | + return ResponseMock('00000\r\n010001\r\nBC97577E65233B3E1137C61091D64176C334E52AD78FFBDDABC826B685435E' |
| 50 | + '9D3DE83FE70C2AC62D6B13BD8EADA10B5623F9354DA0E99636A4F5519CA2DC2DC3\r\n12345656') |
| 51 | + return ResponseMock('00000') |
| 52 | + |
| 53 | + raise ClientException() |
| 54 | + |
| 55 | + |
| 56 | +class TestTPLinkWR844NClient(TestCase): |
| 57 | + def test_supports(self) -> None: |
| 58 | + client = TplinkWR844NRouterTest('', '') |
| 59 | + |
| 60 | + self.assertTrue(client.supports()) |
| 61 | + |
| 62 | + def test_get_firmware_handles_plaintext_response(self) -> None: |
| 63 | + client = TplinkWR844NRouterTest('', '') |
| 64 | + client.authorize() |
| 65 | + client.response = FIRMWARE_RESPONSE |
| 66 | + |
| 67 | + firmware = client.get_firmware() |
| 68 | + |
| 69 | + self.assertIsInstance(firmware, Firmware) |
| 70 | + self.assertEqual(firmware.hardware_version, 'TL-WR844N 1.0') |
| 71 | + self.assertEqual(firmware.model, 'TL-WR844N') |
| 72 | + self.assertEqual(firmware.firmware_version, '1.10.0 Build 211011 Rel.66152n(4555)') |
| 73 | + |
| 74 | + def test_get_status_uses_dhcp_client_block(self) -> None: |
| 75 | + client = TplinkWR844NRouterTest('http://192.168.0.68', '') |
| 76 | + client.authorize() |
| 77 | + client.response = STATUS_RESPONSE |
| 78 | + |
| 79 | + status = client.get_status() |
| 80 | + |
| 81 | + self.assertIsInstance(status, Status) |
| 82 | + self.assertEqual(status.lan_macaddr, '40-AE-30-AF-C8-72') |
| 83 | + self.assertIsInstance(status.lan_macaddress, EUI48) |
| 84 | + self.assertEqual(status.wan_macaddr, '40-AE-30-AF-C8-73') |
| 85 | + self.assertEqual(status.lan_ipv4_addr, '192.168.2.1') |
| 86 | + self.assertIsInstance(status.lan_ipv4_address, IPv4Address) |
| 87 | + self.assertEqual(status.wan_ipv4_addr, '192.168.0.68') |
| 88 | + self.assertEqual(status.conn_type, 'Router/AP') |
| 89 | + self.assertTrue(status.wifi_2g_enable) |
| 90 | + self.assertEqual(status.clients_total, 3) |
| 91 | + self.assertEqual(status.wifi_clients_total, 3) |
| 92 | + self.assertEqual(status.wired_total, 0) |
| 93 | + self.assertEqual(len(status.devices), 3) |
| 94 | + |
| 95 | + device = status.devices[0] |
| 96 | + self.assertIsInstance(device, Device) |
| 97 | + self.assertEqual(device.type, Connection.HOST_2G) |
| 98 | + self.assertEqual(device.hostname, 'LGwebOSTV') |
| 99 | + self.assertEqual(device.ipaddr, '192.168.2.100') |
| 100 | + self.assertEqual(device.macaddr, '60-75-6C-A1-4A-82') |
| 101 | + |
| 102 | + device = status.devices[2] |
| 103 | + self.assertEqual(device.hostname, 'Redmi-Note-13-Pro-5G') |
| 104 | + self.assertEqual(device.ipaddr, '192.168.2.102') |
| 105 | + self.assertEqual(device.macaddr, 'D6-02-54-6B-67-C4') |
| 106 | + |
| 107 | + |
| 108 | +if __name__ == '__main__': |
| 109 | + main() |
0 commit comments