import os import sys import unittest sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'payload', 'user', 'remote_access', 'pager-webui')) import server def setUpModule(): __import__('importlib').reload(server) def patch_device(fn): def wrapper(self): server.device_run = fn self.addCleanup(lambda: setattr(server, 'device_run', server.device_run)) return wrapper class StatusTest(unittest.TestCase): def test_battery_from_capacity_file(self): import tempfile base = tempfile.mkdtemp() os.makedirs(os.path.join(base, 'battery')) with open(os.path.join(base, 'battery', 'type'), 'w') as f: f.write('Battery') with open(os.path.join(base, 'battery', 'capacity'), 'w') as f: f.write('87') with open(os.path.join(base, 'battery', 'status'), 'w') as f: f.write('Charging') self.assertEqual(server.battery_data(base), {'level': 87, 'charging': True}) def test_battery_missing_returns_none(self): import tempfile self.assertEqual(server.battery_data(tempfile.mkdtemp()), {'level': None, 'charging': False}) def test_uptime_parses(self): server.device_run = lambda args, timeout=20: (0, '1234.56 4321.10\n', '') self.assertEqual(server.uptime_data(), 1234) def test_disk_parses_df(self): server.device_run = lambda args, timeout=20: (0, 'Filesystem 1K-blocks Used Available Use% Mounted on\n/dev/mmcblk0p3 8388608 1024000 7364608 13% /root\n', '') d = server.disk_data() self.assertEqual(d['avail'], 7364608 * 1024) def test_mem_parses_meminfo(self): import tempfile base = tempfile.mkdtemp() with open(os.path.join(base, 'meminfo'), 'w') as f: f.write('MemTotal: 262144 kB\nMemFree: 102400 kB\nMemAvailable: 122880 kB\nBuffers: 20480 kB\n') d = server.mem_data(os.path.join(base, 'meminfo')) self.assertEqual(d['size'], 262144 * 1024) self.assertEqual(d['used'], (262144 - 122880) * 1024) self.assertEqual(d['avail'], 122880 * 1024) def test_mem_missing_returns_empty(self): import tempfile self.assertEqual(server.mem_data(os.path.join(tempfile.mkdtemp(), 'nope')), {}) def test_wifi_ifaces_extracts_names(self): server.device_run = lambda args, timeout=20: (0, 'wlan0 ESSID: "Pineapple"\nwlan1 ESSID: "Pineapple"\n', '') if args == ['iwinfo'] else (0, '', '') self.assertEqual(server.wifi_ifaces(), ['wlan0', 'wlan1']) def test_assoc_clients_parses(self): def fake(args, timeout=20): if args == ['iwinfo']: return 0, 'wlan0 ESSID: "Pineapple"\n', '' if args[0] == 'iw': return 1, '', 'busy' if args == ['iwinfo', 'wlan0', 'assoclist']: return 0, '00:11:22:33:44:55 -64 dBm Signal: -64 dBm Rate: 12 Mbit/s\nAA:BB:CC:DD:EE:FF -40 dBm Signal: -40 dBm Rate: 24 Mbit/s\n', '' return 0, '', '' server.device_run = fake clients = server.assoc_clients() self.assertEqual(len(clients), 2) self.assertEqual(clients[0]['mac'], '00:11:22:33:44:55') self.assertEqual(clients[0]['rssi'], -64) self.assertEqual(clients[0]['iface'], 'wlan0') def test_assoc_clients_skips_monitor_ifaces(self): def fake(args, timeout=20): if args == ['iwinfo']: return 0, 'wlan0mon ESSID: unknown\nwlan0wpa ESSID: "x"\n', '' if args[0] == 'iw' and len(args) > 2 and args[2] == 'wlan0mon': raise AssertionError('must not query monitor ifaces') if args[:2] == ['iwinfo', 'wlan0mon']: raise AssertionError('must not query monitor ifaces') if args == ['iw', 'dev', 'wlan0wpa', 'station', 'dump']: return 0, 'Station aa:bb:cc:dd:ee:ff (on wlan0wpa)\n\tsignal: -50 dBm\n', '' return 1, '', '' server.device_run = fake clients = server.assoc_clients() self.assertEqual(len(clients), 1) self.assertEqual(clients[0]['mac'], 'AA:BB:CC:DD:EE:FF') self.assertEqual(clients[0]['iface'], 'wlan0wpa') def test_h_status_shape(self): server.device_run = lambda args, timeout=20: (0, '', '') server.current_token = lambda: 'tok' server.daemon_call = lambda m, p, body=None, token=None, timeout=15: (200, {'version': '1'}) class Ctx: cookie = 'AUTH_S=tok' args = () status, payload = server.h_status(Ctx()) self.assertEqual(status, 200) for k in ('battery', 'firmware', 'daemon', 'wifi', 'clients', 'disk', 'mem', 'uptime', 'hostname'): self.assertIn(k, payload) def test_status_discovers_wifi_interfaces_once(self): calls = [] def fake(args, timeout=20): calls.append(args) if args == ['iwinfo']: return 0, 'wlan0 ESSID: "Pineapple"\n', '' return 0, '', '' server.device_run = fake server.current_token = lambda: 'tok' server.daemon_call = lambda m, p, body=None, token=None, timeout=15: (200, {}) server.status_data() self.assertEqual(calls.count(['iwinfo']), 1) class DeviceTest(unittest.TestCase): def test_h_device(self): server.device_run = lambda args, timeout=20: (0, 'pager\n', '') class Ctx: args = () status, payload = server.h_device(Ctx()) self.assertEqual(status, 200) self.assertEqual(payload['hostname'], 'pager') self.assertIn('macs', payload) if __name__ == '__main__': unittest.main()