From 20df68d19438edac7ad82810be4367a10362872c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BC=D0=BE=D0=BD=D1=82=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 19 Dec 2022 17:37:10 +0300 Subject: [PATCH] Add support VPN --- .gitignore | 4 + custom_components/miwifi/binary_sensor.py | 10 ++ custom_components/miwifi/const.py | 6 + custom_components/miwifi/luci.py | 8 ++ custom_components/miwifi/sensor.py | 9 ++ custom_components/miwifi/updater.py | 24 ++++ pyvenv.cfg | 3 + tests/fixtures/vpn_status_data.json | 5 + tests/fixtures/vpn_status_off_data.json | 5 + tests/setup.py | 3 + tests/test_binary_sensors.py | 110 ++++++++++++++++++ tests/test_button.py | 2 + tests/test_config_flow.py | 12 ++ tests/test_device_tracker.py | 11 ++ tests/test_device_trigger.py | 1 + tests/test_diagnostics.py | 6 + tests/test_discovery.py | 4 + tests/test_init.py | 1 + tests/test_light.py | 2 + tests/test_luci.py | 52 +++++++++ tests/test_select.py | 24 ++++ tests/test_self_check.py | 2 + tests/test_sensor.py | 135 ++++++++++++++++++++++ tests/test_services.py | 11 ++ tests/test_switch.py | 17 +++ tests/test_system_health.py | 1 + tests/test_update.py | 8 ++ tests/test_updater_ap_mode.py | 21 +++- tests/test_updater_default_mode.py | 18 ++- tests/test_updater_main.py | 25 ++++ tests/test_updater_mesh_mode.py | 21 +++- tests/test_updater_repeater_mode.py | 21 +++- 32 files changed, 569 insertions(+), 13 deletions(-) create mode 100644 pyvenv.cfg create mode 100644 tests/fixtures/vpn_status_data.json create mode 100644 tests/fixtures/vpn_status_off_data.json diff --git a/.gitignore b/.gitignore index 6b686c4..e3ae372 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,7 @@ dmypy.json .DS_Store .idea +.run +bin +share +include \ No newline at end of file diff --git a/custom_components/miwifi/binary_sensor.py b/custom_components/miwifi/binary_sensor.py index 8654ab6..3dffa31 100644 --- a/custom_components/miwifi/binary_sensor.py +++ b/custom_components/miwifi/binary_sensor.py @@ -22,6 +22,8 @@ ATTR_BINARY_SENSOR_DUAL_BAND_NAME, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_BINARY_SENSOR_WAN_STATE_NAME, + ATTR_BINARY_SENSOR_VPN_STATE, + ATTR_BINARY_SENSOR_VPN_STATE_NAME, ATTR_STATE, ATTR_STATE_NAME, ) @@ -51,6 +53,14 @@ entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=True, ), + BinarySensorEntityDescription( + key=ATTR_BINARY_SENSOR_VPN_STATE, + name=ATTR_BINARY_SENSOR_VPN_STATE_NAME, + icon="mdi:security-network", + device_class=BinarySensorDeviceClass.CONNECTIVITY, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), BinarySensorEntityDescription( key=ATTR_BINARY_SENSOR_DUAL_BAND, name=ATTR_BINARY_SENSOR_DUAL_BAND_NAME, diff --git a/custom_components/miwifi/const.py b/custom_components/miwifi/const.py index 5c9bcb1..8a08b46 100644 --- a/custom_components/miwifi/const.py +++ b/custom_components/miwifi/const.py @@ -127,6 +127,9 @@ ATTR_SENSOR_UPTIME: Final = "uptime" ATTR_SENSOR_UPTIME_NAME: Final = "Uptime" +ATTR_SENSOR_VPN_UPTIME: Final = "vpn_uptime" +ATTR_SENSOR_VPN_UPTIME_NAME: Final = "Vpn uptime" + ATTR_SENSOR_MEMORY_USAGE: Final = "memory_usage" ATTR_SENSOR_MEMORY_USAGE_NAME: Final = "Memory usage" @@ -173,6 +176,9 @@ ATTR_BINARY_SENSOR_DUAL_BAND: Final = "dual_band" ATTR_BINARY_SENSOR_DUAL_BAND_NAME: Final = "Dual band" +ATTR_BINARY_SENSOR_VPN_STATE: Final = "vpn_state" +ATTR_BINARY_SENSOR_VPN_STATE_NAME: Final = "Vpn state" + """Light attributes""" ATTR_LIGHT_LED: Final = "led" ATTR_LIGHT_LED_NAME: Final = "Led" diff --git a/custom_components/miwifi/luci.py b/custom_components/miwifi/luci.py index 164da4c..8de7070 100644 --- a/custom_components/miwifi/luci.py +++ b/custom_components/miwifi/luci.py @@ -258,6 +258,14 @@ async def wifi_diag_detail_all(self) -> dict: return await self.get("xqnetwork/wifi_diag_detail_all") + async def vpn_status(self) -> dict: + """xqsystem/vpn_status method. + + :return dict: dict with api data. + """ + + return await self.get("xqsystem/vpn_status") + async def set_wifi(self, data: dict) -> dict: """xqnetwork/set_wifi method. diff --git a/custom_components/miwifi/sensor.py b/custom_components/miwifi/sensor.py index 507899a..7165a4c 100644 --- a/custom_components/miwifi/sensor.py +++ b/custom_components/miwifi/sensor.py @@ -44,6 +44,8 @@ ATTR_SENSOR_TEMPERATURE_NAME, ATTR_SENSOR_UPTIME, ATTR_SENSOR_UPTIME_NAME, + ATTR_SENSOR_VPN_UPTIME, + ATTR_SENSOR_VPN_UPTIME_NAME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_DOWNLOAD_SPEED_NAME, ATTR_SENSOR_WAN_UPLOAD_SPEED, @@ -77,6 +79,13 @@ entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, ), + SensorEntityDescription( + key=ATTR_SENSOR_VPN_UPTIME, + name=ATTR_SENSOR_VPN_UPTIME_NAME, + icon="mdi:timer-sand", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), SensorEntityDescription( key=ATTR_SENSOR_MEMORY_USAGE, name=ATTR_SENSOR_MEMORY_USAGE_NAME, diff --git a/custom_components/miwifi/updater.py b/custom_components/miwifi/updater.py index f9dacb6..9e16941 100644 --- a/custom_components/miwifi/updater.py +++ b/custom_components/miwifi/updater.py @@ -25,6 +25,7 @@ from .const import ( ATTR_BINARY_SENSOR_DUAL_BAND, + ATTR_BINARY_SENSOR_VPN_STATE, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_DEVICE_HW_VERSION, ATTR_DEVICE_MAC_ADDRESS, @@ -46,6 +47,7 @@ ATTR_SENSOR_MODE, ATTR_SENSOR_TEMPERATURE, ATTR_SENSOR_UPTIME, + ATTR_SENSOR_VPN_UPTIME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_UPLOAD_SPEED, ATTR_STATE, @@ -102,6 +104,7 @@ PREPARE_METHODS: Final = ( "init", "status", + "vpn", "rom_update", "mode", "wan", @@ -520,6 +523,27 @@ async def _async_prepare_status(self, data: dict) -> None: ) if "upspeed" in response["wan"] else 0 # fmt: on + async def _async_prepare_vpn(self, data: dict) -> None: + """Prepare vpn. + + :param data: dict + """ + + response: dict = await self.luci.vpn_status() + + data |= { + ATTR_SENSOR_VPN_UPTIME: 0, + ATTR_BINARY_SENSOR_VPN_STATE: False, + } + + if "uptime" in response: + data |= { + ATTR_SENSOR_VPN_UPTIME: str( + timedelta(seconds=int(float(response["uptime"]))) + ), + ATTR_BINARY_SENSOR_VPN_STATE: int(float(response["uptime"])) > 0, + } + async def _async_prepare_rom_update(self, data: dict) -> None: """Prepare rom update. diff --git a/pyvenv.cfg b/pyvenv.cfg new file mode 100644 index 0000000..920272e --- /dev/null +++ b/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /opt/homebrew/opt/python@3.10/bin +include-system-site-packages = false +version = 3.10.8 diff --git a/tests/fixtures/vpn_status_data.json b/tests/fixtures/vpn_status_data.json new file mode 100644 index 0000000..30f2a2f --- /dev/null +++ b/tests/fixtures/vpn_status_data.json @@ -0,0 +1,5 @@ +{ + "status": 0, + "uptime": 343757, + "code": 0 +} \ No newline at end of file diff --git a/tests/fixtures/vpn_status_off_data.json b/tests/fixtures/vpn_status_off_data.json new file mode 100644 index 0000000..a9e74fc --- /dev/null +++ b/tests/fixtures/vpn_status_off_data.json @@ -0,0 +1,5 @@ +{ + "status": 4, + "uptime": 0, + "code": 0 +} \ No newline at end of file diff --git a/tests/setup.py b/tests/setup.py index d054ac4..587c881 100644 --- a/tests/setup.py +++ b/tests/setup.py @@ -152,6 +152,9 @@ async def async_mock_luci_client(mock_luci_client) -> None: mock_luci_client.return_value.device_list = AsyncMock( return_value=json.loads(load_fixture("device_list_data.json")) ) + mock_luci_client.return_value.vpn_status = AsyncMock( + return_value=json.loads(load_fixture("vpn_status_data.json")) + ) async def mock_avaliable_channels(index: int = 1) -> dict: """Mock channels""" diff --git a/tests/test_binary_sensors.py b/tests/test_binary_sensors.py index 3f33667..992be42 100644 --- a/tests/test_binary_sensors.py +++ b/tests/test_binary_sensors.py @@ -26,6 +26,7 @@ from custom_components.miwifi.const import ( ATTR_BINARY_SENSOR_DUAL_BAND_NAME, + ATTR_BINARY_SENSOR_VPN_STATE_NAME, ATTR_BINARY_SENSOR_WAN_STATE_NAME, ATTR_DEVICE_MAC_ADDRESS, ATTR_STATE_NAME, @@ -49,6 +50,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -100,7 +102,13 @@ async def test_init(hass: HomeAssistant) -> None: ) assert dual_band_state is None + vpn_state: State | None = hass.states.get( + _generate_id(ATTR_BINARY_SENSOR_VPN_STATE_NAME, updater) + ) + assert vpn_state is None + +@pytest.mark.asyncio async def test_update_state(hass: HomeAssistant) -> None: """Test update state. @@ -172,6 +180,7 @@ def error() -> None: assert state.attributes["icon"] == "mdi:router-wireless-off" +@pytest.mark.asyncio async def test_update_wan_state(hass: HomeAssistant) -> None: """Test update wan state. @@ -251,6 +260,7 @@ def _off() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_dual_band(hass: HomeAssistant) -> None: """Test update dual_band. @@ -350,6 +360,106 @@ def _on() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio +async def test_update_vpn_state(hass: HomeAssistant) -> None: + """Test update vpn_state. + + :param hass: HomeAssistant + """ + + with patch( + "custom_components.miwifi.updater.LuciClient" + ) as mock_luci_client, patch( + "custom_components.miwifi.async_start_discovery", return_value=None + ), patch( + "custom_components.miwifi.device_tracker.socket.socket" + ) as mock_socket, patch( + "custom_components.miwifi.updater.asyncio.sleep", return_value=None + ): + await async_mock_luci_client(mock_luci_client) + + mock_socket.return_value.recv.return_value = AsyncMock(return_value=None) + + def success() -> dict: + return json.loads(load_fixture("device_list_data.json")) + + def error() -> None: + raise LuciRequestError + + mock_luci_client.return_value.device_list = AsyncMock( + side_effect=MultipleSideEffect(success, success, success, error, error) + ) + + def _off() -> dict: + return json.loads(load_fixture("vpn_status_off_data.json")) + + def _on() -> dict: + return json.loads(load_fixture("vpn_status_data.json")) + + mock_luci_client.return_value.vpn_status = AsyncMock( + side_effect=MultipleSideEffect(_off, _off, _off, _on, _on) + ) + + setup_data: list = await async_setup(hass) + + config_entry: MockConfigEntry = setup_data[1] + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + updater: LuciUpdater = hass.data[DOMAIN][config_entry.entry_id][UPDATER] + registry = er.async_get(hass) + + assert updater.last_update_success + + unique_id: str = _generate_id(ATTR_BINARY_SENSOR_VPN_STATE_NAME, updater) + + entry: er.RegistryEntry | None = registry.async_get(unique_id) + state: State = hass.states.get(unique_id) + assert state is None + assert entry is not None + assert entry.disabled_by == er.RegistryEntryDisabler.INTEGRATION + + registry.async_update_entity(entity_id=unique_id, disabled_by=None) + await hass.async_block_till_done() + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + entry = registry.async_get(unique_id) + state = hass.states.get(unique_id) + + assert entry.disabled_by is None + assert state.state == STATE_OFF + assert state.name == ATTR_BINARY_SENSOR_VPN_STATE_NAME + assert state.attributes["icon"] == "mdi:security-network" + assert state.attributes["attribution"] == ATTRIBUTION + assert entry.entity_category == EntityCategory.DIAGNOSTIC + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + state = hass.states.get(unique_id) + assert state.state == STATE_ON + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + state = hass.states.get(unique_id) + assert state.state == STATE_UNAVAILABLE + + def _generate_id(code: str, updater: LuciUpdater) -> str: """Generate unique id diff --git a/tests/test_button.py b/tests/test_button.py index 85a3c81..9311f8d 100644 --- a/tests/test_button.py +++ b/tests/test_button.py @@ -47,6 +47,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -85,6 +86,7 @@ async def test_init(hass: HomeAssistant) -> None: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_update_reboot(hass: HomeAssistant) -> None: """Test update reboot. diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 9761936..576bac0 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -53,6 +53,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_user(hass: HomeAssistant) -> None: """Test user config. @@ -101,6 +102,7 @@ async def test_user(hass: HomeAssistant) -> None: assert len(mock_async_setup_entry.mock_calls) == 1 +@pytest.mark.asyncio async def test_user_ip_error(hass: HomeAssistant) -> None: """Test user config ip error. @@ -130,6 +132,7 @@ async def test_user_ip_error(hass: HomeAssistant) -> None: assert len(mock_luci_client.mock_calls) == 4 +@pytest.mark.asyncio async def test_token_error(hass: HomeAssistant) -> None: """Test user config token error. @@ -159,6 +162,7 @@ async def test_token_error(hass: HomeAssistant) -> None: assert len(mock_luci_client.mock_calls) == 4 +@pytest.mark.asyncio async def test_undefined_router(hass: HomeAssistant) -> None: """Test user undefined router config. @@ -198,6 +202,7 @@ async def test_undefined_router(hass: HomeAssistant) -> None: assert len(mock_async_self_check.mock_calls) == 1 +@pytest.mark.asyncio async def test_undefined_router_without_hardware_info(hass: HomeAssistant) -> None: """Test user undefined router without hardware info config. @@ -237,6 +242,7 @@ async def test_undefined_router_without_hardware_info(hass: HomeAssistant) -> No assert len(mock_async_create_pm.mock_calls) == 1 +@pytest.mark.asyncio async def test_ssdp(hass: HomeAssistant) -> None: """Test ssdp config. @@ -260,6 +266,7 @@ async def test_ssdp(hass: HomeAssistant) -> None: assert len(mock_async_start_discovery.mock_calls) == 1 +@pytest.mark.asyncio async def test_dhcp(hass: HomeAssistant) -> None: """Test dhcp config. @@ -283,6 +290,7 @@ async def test_dhcp(hass: HomeAssistant) -> None: assert len(mock_async_start_discovery.mock_calls) == 1 +@pytest.mark.asyncio async def test_integration_discovery(hass: HomeAssistant) -> None: """Test integration_discovery config. @@ -302,6 +310,7 @@ async def test_integration_discovery(hass: HomeAssistant) -> None: assert result_init["step_id"] == "discovery_confirm" +@pytest.mark.asyncio async def test_options_flow(hass: HomeAssistant) -> None: """Test options flow. @@ -361,6 +370,7 @@ async def test_options_flow(hass: HomeAssistant) -> None: assert len(mock_async_setup_entry.mock_calls) == 1 +@pytest.mark.asyncio async def test_options_flow_ip_error(hass: HomeAssistant) -> None: """Test options flow ip error. @@ -404,6 +414,7 @@ async def test_options_flow_ip_error(hass: HomeAssistant) -> None: assert len(mock_luci_client.mock_calls) == 4 +@pytest.mark.asyncio async def test_options_flow_token_error(hass: HomeAssistant) -> None: """Test options flow token error. @@ -447,6 +458,7 @@ async def test_options_flow_token_error(hass: HomeAssistant) -> None: assert len(mock_luci_client.mock_calls) == 4 +@pytest.mark.asyncio async def test_options_flow_undefined_router(hass: HomeAssistant) -> None: """Test options flow undefined router. diff --git a/tests/test_device_tracker.py b/tests/test_device_tracker.py index 2c6f7a5..4301b55 100644 --- a/tests/test_device_tracker.py +++ b/tests/test_device_tracker.py @@ -51,6 +51,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -135,6 +136,7 @@ async def test_init(hass: HomeAssistant) -> None: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_with_restore(hass: HomeAssistant) -> None: """Test init. @@ -243,6 +245,7 @@ async def test_init_with_restore(hass: HomeAssistant) -> None: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_with_parent(hass: HomeAssistant) -> None: """Test init. @@ -458,6 +461,7 @@ async def test_init_with_parent(hass: HomeAssistant) -> None: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_with_parent_revert(hass: HomeAssistant) -> None: """Test init. @@ -754,6 +758,7 @@ def revert() -> dict: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_in_force_mode(hass: HomeAssistant) -> None: """Test init. @@ -828,6 +833,7 @@ async def test_init_in_force_mode(hass: HomeAssistant) -> None: assert state is None +@pytest.mark.asyncio async def test_init_with_force_and_parent(hass: HomeAssistant) -> None: """Test init. @@ -1043,6 +1049,7 @@ async def test_init_with_force_and_parent(hass: HomeAssistant) -> None: assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_with_restore_without_connection(hass: HomeAssistant) -> None: """Test init. @@ -1153,6 +1160,7 @@ async def test_init_with_restore_without_connection(hass: HomeAssistant) -> None assert state.attributes["attribution"] == ATTRIBUTION +@pytest.mark.asyncio async def test_init_with_optional_parent(hass: HomeAssistant) -> None: """Test init. @@ -1307,6 +1315,7 @@ async def test_init_with_optional_parent(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_init_with_restore_and_remove(hass: HomeAssistant) -> None: """Test init. @@ -1407,6 +1416,7 @@ async def test_init_with_restore_and_remove(hass: HomeAssistant) -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_init_detect_manufacturer(hass: HomeAssistant) -> None: """Test init. @@ -1481,6 +1491,7 @@ async def test_init_detect_manufacturer(hass: HomeAssistant) -> None: assert device.manufacturer == MANUFACTURERS["CC50E3"] +@pytest.mark.asyncio async def test_init_detect_url(hass: HomeAssistant) -> None: """Test init. diff --git a/tests/test_device_trigger.py b/tests/test_device_trigger.py index d3d4436..708c9c1 100644 --- a/tests/test_device_trigger.py +++ b/tests/test_device_trigger.py @@ -23,6 +23,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_get_triggers(hass: HomeAssistant) -> None: """Get triggers test. diff --git a/tests/test_diagnostics.py b/tests/test_diagnostics.py index b861710..4d7d84d 100644 --- a/tests/test_diagnostics.py +++ b/tests/test_diagnostics.py @@ -31,6 +31,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Test init. @@ -63,6 +64,11 @@ async def test_init(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: method="GET", url=get_url("xqnetwork/wifi_diag_detail_all"), ) + httpx_mock.add_response( + text=load_fixture("vpn_status_data.json"), + method="GET", + url=get_url("xqsystem/vpn_status"), + ) httpx_mock.add_response( text=load_fixture("avaliable_channels_2g_data.json"), method="GET", diff --git a/tests/test_discovery.py b/tests/test_discovery.py index 6a96d7c..a6ca9d9 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -27,6 +27,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_discovery(hass: HomeAssistant) -> None: """discovery init. @@ -51,6 +52,7 @@ async def test_discovery(hass: HomeAssistant) -> None: assert flow["context"]["source"] == "integration_discovery" +@pytest.mark.asyncio async def test_discovery_sub_leaf(hass: HomeAssistant) -> None: """discovery init. @@ -82,6 +84,7 @@ async def test_discovery_sub_leaf(hass: HomeAssistant) -> None: assert flow["context"]["source"] == "integration_discovery" +@pytest.mark.asyncio async def test_discovery_error(hass: HomeAssistant) -> None: """discovery init error. @@ -99,6 +102,7 @@ async def test_discovery_error(hass: HomeAssistant) -> None: assert len(hass.config_entries.flow._progress) == 0 +@pytest.mark.asyncio async def test_discovery_invalid_device(hass: HomeAssistant) -> None: """discovery init. diff --git a/tests/test_init.py b/tests/test_init.py index 9c48c54..b8bc6b6 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -25,6 +25,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. diff --git a/tests/test_light.py b/tests/test_light.py index d1bcbfd..af2a51e 100644 --- a/tests/test_light.py +++ b/tests/test_light.py @@ -47,6 +47,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -92,6 +93,7 @@ async def test_init(hass: HomeAssistant) -> None: assert entry.entity_category == EntityCategory.CONFIG +@pytest.mark.asyncio async def test_update_led(hass: HomeAssistant) -> None: """Test update led. diff --git a/tests/test_luci.py b/tests/test_luci.py index e683226..cde907a 100644 --- a/tests/test_luci.py +++ b/tests/test_luci.py @@ -26,6 +26,7 @@ _LOGGER = logging.getLogger(__name__) +@pytest.mark.asyncio async def test_login(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Login test""" @@ -44,6 +45,7 @@ async def test_login(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert client._token == "**REDACTED**" +@pytest.mark.asyncio async def test_login_error_request(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Login test""" @@ -57,6 +59,7 @@ async def test_login_error_request(hass: HomeAssistant, httpx_mock: HTTPXMock) - await client.login() +@pytest.mark.asyncio async def test_login_incorrect_token( hass: HomeAssistant, httpx_mock: HTTPXMock ) -> None: @@ -72,6 +75,7 @@ async def test_login_incorrect_token( await client.login() +@pytest.mark.asyncio async def test_logout_without_token(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Logout test""" @@ -84,6 +88,7 @@ async def test_logout_without_token(hass: HomeAssistant, httpx_mock: HTTPXMock) assert not httpx_mock.get_request() +@pytest.mark.asyncio async def test_logout(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Logout test""" @@ -106,6 +111,7 @@ async def test_logout(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_logout_error(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """Logout test""" @@ -122,6 +128,7 @@ async def test_logout_error(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert client.diagnostics["logout"]["message"] == "Logout error" +@pytest.mark.asyncio async def test_get_without_token(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -135,6 +142,7 @@ async def test_get_without_token(hass: HomeAssistant, httpx_mock: HTTPXMock) -> assert not httpx_mock.get_request() +@pytest.mark.asyncio async def test_get(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -154,6 +162,7 @@ async def test_get(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_get_sha256(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -176,6 +185,7 @@ async def test_get_sha256(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_get_without_stok(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -193,6 +203,7 @@ async def test_get_without_stok(hass: HomeAssistant, httpx_mock: HTTPXMock) -> N assert request.method == "GET" +@pytest.mark.asyncio async def test_get_error(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -209,6 +220,7 @@ async def test_get_error(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: await client.get("misystem/miwifi") +@pytest.mark.asyncio async def test_get_error_code(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """get test""" @@ -230,6 +242,7 @@ async def test_get_error_code(hass: HomeAssistant, httpx_mock: HTTPXMock) -> Non assert str(error.value) == "custom errors" +@pytest.mark.asyncio async def test_topo_graph(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """topo_graph test""" @@ -250,6 +263,7 @@ async def test_topo_graph(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_init_info(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """init_info test""" @@ -270,6 +284,7 @@ async def test_init_info(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_status(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """status test""" @@ -290,6 +305,7 @@ async def test_status(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_new_status(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """new_status test""" @@ -310,6 +326,7 @@ async def test_new_status(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_mode(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """mode test""" @@ -330,6 +347,7 @@ async def test_mode(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_wifi_ap_signal(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """wifi_ap_signal test""" @@ -352,6 +370,7 @@ async def test_wifi_ap_signal(hass: HomeAssistant, httpx_mock: HTTPXMock) -> Non assert request.method == "GET" +@pytest.mark.asyncio async def test_wifi_detail_all(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """wifi_detail_all test""" @@ -376,6 +395,7 @@ async def test_wifi_detail_all(hass: HomeAssistant, httpx_mock: HTTPXMock) -> No assert request.method == "GET" +@pytest.mark.asyncio async def test_wifi_diag_detail_all(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """wifi_diag_detail_all test""" @@ -400,6 +420,28 @@ async def test_wifi_diag_detail_all(hass: HomeAssistant, httpx_mock: HTTPXMock) assert request.method == "GET" +@pytest.mark.asyncio +async def test_vpn_status(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: + """vpn_status test""" + + httpx_mock.add_response(text=load_fixture("login_data.json"), method="POST") + httpx_mock.add_response(text=load_fixture("vpn_status_data.json"), method="GET") + + client: LuciClient = LuciClient( + get_async_client(hass, False), f"{MOCK_IP_ADDRESS}/", "test" + ) + + await client.login() + + assert await client.vpn_status() == json.loads(load_fixture("vpn_status_data.json")) + + request: Request | None = httpx_mock.get_request(method="GET") + assert request is not None + assert request.url == get_url("xqsystem/vpn_status") + assert request.method == "GET" + + +@pytest.mark.asyncio async def test_set_wifi(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """set_wifi test""" @@ -432,6 +474,7 @@ async def test_set_wifi(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_set_guest_wifi(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """set_guest_wifi test""" @@ -459,6 +502,7 @@ async def test_set_guest_wifi(hass: HomeAssistant, httpx_mock: HTTPXMock) -> Non assert request.method == "GET" +@pytest.mark.asyncio async def test_set_avaliable_channels( hass: HomeAssistant, httpx_mock: HTTPXMock ) -> None: @@ -521,6 +565,7 @@ async def test_set_avaliable_channels( assert request.method == "GET" +@pytest.mark.asyncio async def test_wan_info(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """wan_info test""" @@ -541,6 +586,7 @@ async def test_wan_info(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_reboot(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """reboot test""" @@ -561,6 +607,7 @@ async def test_reboot(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_set_led(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """led test""" @@ -615,6 +662,7 @@ async def test_set_led(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_device_list(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """device_list test""" @@ -637,6 +685,7 @@ async def test_device_list(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_wifi_connect_devices(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """wifi_connect_devices test""" @@ -661,6 +710,7 @@ async def test_wifi_connect_devices(hass: HomeAssistant, httpx_mock: HTTPXMock) assert request.method == "GET" +@pytest.mark.asyncio async def test_rom_update(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """rom_update test""" @@ -681,6 +731,7 @@ async def test_rom_update(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_rom_upgrade(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """rom_upgrade test""" @@ -705,6 +756,7 @@ async def test_rom_upgrade(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: assert request.method == "GET" +@pytest.mark.asyncio async def test_flash_permission(hass: HomeAssistant, httpx_mock: HTTPXMock) -> None: """flash_permission test""" diff --git a/tests/test_select.py b/tests/test_select.py index 8254b11..bdb8248 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -59,6 +59,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -119,6 +120,7 @@ async def test_init(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_init_with_game(hass: HomeAssistant) -> None: """Test init. @@ -183,6 +185,7 @@ async def test_init_with_game(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_update_channel_2_4(hass: HomeAssistant) -> None: """Test update channel 2.4. @@ -273,6 +276,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_channel_2_4_empty_channels(hass: HomeAssistant) -> None: """Test update channel 2.4. @@ -336,6 +340,7 @@ async def test_update_channel_2_4_empty_channels(hass: HomeAssistant) -> None: assert state.attributes["options"] == ATTR_SELECT_WIFI_2_4_CHANNEL_OPTIONS +@pytest.mark.asyncio async def test_update_channel_2_4_wifi_data(hass: HomeAssistant) -> None: """Test update channel 2.4. @@ -439,6 +444,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_channel_2_4_change_channel(hass: HomeAssistant) -> None: """Test update channel 2.4. @@ -535,6 +541,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 2 +@pytest.mark.asyncio async def test_update_channel_5_0(hass: HomeAssistant) -> None: """Test update channel 5.0. @@ -634,6 +641,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_channel_5_0_empty_channels(hass: HomeAssistant) -> None: """Test update channel 5.0. @@ -697,6 +705,7 @@ async def test_update_channel_5_0_empty_channels(hass: HomeAssistant) -> None: assert state.attributes["options"] == ATTR_SELECT_WIFI_5_0_CHANNEL_OPTIONS +@pytest.mark.asyncio async def test_update_channel_5_0_empty_channels_and_5g_game( hass: HomeAssistant, ) -> None: @@ -766,6 +775,7 @@ async def test_update_channel_5_0_empty_channels_and_5g_game( assert state.attributes["options"] == ["149", "153", "157", "161", "165"] +@pytest.mark.asyncio async def test_update_channel_5_0_wifi_data(hass: HomeAssistant) -> None: """Test update channel 5.0. @@ -869,6 +879,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_channel_5_0_change_channel(hass: HomeAssistant) -> None: """Test update channel 5.0. @@ -965,6 +976,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 2 +@pytest.mark.asyncio async def test_update_channel_5_0_game(hass: HomeAssistant) -> None: """Test update channel 5.0 game. @@ -1059,6 +1071,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_channel_5_0_game_empty_channels(hass: HomeAssistant) -> None: """Test update channel 5.0 game. @@ -1126,6 +1139,7 @@ async def test_update_channel_5_0_game_empty_channels(hass: HomeAssistant) -> No assert state.attributes["options"] == ATTR_SELECT_WIFI_5_0_GAME_CHANNEL_OPTIONS +@pytest.mark.asyncio async def test_update_channel_5_0_game_wifi_data(hass: HomeAssistant) -> None: """Test update channel 5.0 game. @@ -1231,6 +1245,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_channel_5_0_game_change_channel(hass: HomeAssistant) -> None: """Test update channel 5.0 game. @@ -1331,6 +1346,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 2 +@pytest.mark.asyncio async def test_update_strength_2_4(hass: HomeAssistant) -> None: """Test update strength 2.4. @@ -1423,6 +1439,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_strength_2_4_wifi_data(hass: HomeAssistant) -> None: """Test update strength 2.4. @@ -1528,6 +1545,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_strength_2_4_change_strength(hass: HomeAssistant) -> None: """Test update strength 2.4. @@ -1632,6 +1650,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 2 +@pytest.mark.asyncio async def test_update_strength_5_0(hass: HomeAssistant) -> None: """Test update strength 5.0. @@ -1724,6 +1743,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_strength_5_0_wifi_data(hass: HomeAssistant) -> None: """Test update strength 5.0. @@ -1829,6 +1849,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_strength_5_0_change_channel(hass: HomeAssistant) -> None: """Test update strength 5.0. @@ -1932,6 +1953,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 2 +@pytest.mark.asyncio async def test_update_strength_5_0_game(hass: HomeAssistant) -> None: """Test update strength 5.0 game. @@ -2028,6 +2050,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_strength_5_0_game_wifi_data(hass: HomeAssistant) -> None: """Test update strength 5.0 game. @@ -2135,6 +2158,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_strength_5_0_game_change_strength(hass: HomeAssistant) -> None: """Test update strength 5.0 game. diff --git a/tests/test_self_check.py b/tests/test_self_check.py index 17f176d..7146e8c 100644 --- a/tests/test_self_check.py +++ b/tests/test_self_check.py @@ -26,6 +26,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_supported(hass: HomeAssistant) -> None: """supported init. @@ -57,6 +58,7 @@ def pn_check(hass: HomeAssistant, message: str, title: str) -> None: await async_self_check(hass, updater.luci, "R3600") +@pytest.mark.asyncio async def test_unsupported(hass: HomeAssistant) -> None: """unsupported init. diff --git a/tests/test_sensor.py b/tests/test_sensor.py index 499db71..09db9bf 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -36,6 +36,7 @@ ATTR_SENSOR_MODE_NAME, ATTR_SENSOR_TEMPERATURE_NAME, ATTR_SENSOR_UPTIME_NAME, + ATTR_SENSOR_VPN_UPTIME_NAME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED_NAME, ATTR_SENSOR_WAN_UPLOAD_SPEED_NAME, ATTRIBUTION, @@ -58,6 +59,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -95,6 +97,10 @@ async def test_init(hass: HomeAssistant) -> None: assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_VPN_UPTIME_NAME, updater) + assert hass.states.get(unique_id) is None + assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_MEMORY_USAGE_NAME, updater) assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None @@ -148,6 +154,7 @@ async def test_init(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_init_with_game( hass: HomeAssistant, ) -> None: @@ -191,6 +198,10 @@ async def test_init_with_game( assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_VPN_UPTIME_NAME, updater) + assert hass.states.get(unique_id) is None + assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_MEMORY_USAGE_NAME, updater) assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None @@ -244,6 +255,7 @@ async def test_init_with_game( assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_init_without_zero( hass: HomeAssistant, ) -> None: @@ -290,6 +302,10 @@ async def test_init_without_zero( assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_VPN_UPTIME_NAME, updater) + assert hass.states.get(unique_id) is None + assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_MEMORY_USAGE_NAME, updater) assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None @@ -343,6 +359,7 @@ async def test_init_without_zero( assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_init_without_wan( hass: HomeAssistant, ) -> None: @@ -386,6 +403,10 @@ async def test_init_without_wan( assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_VPN_UPTIME_NAME, updater) + assert hass.states.get(unique_id) is None + assert registry.async_get(unique_id) is not None + unique_id = _generate_id(ATTR_SENSOR_MEMORY_USAGE_NAME, updater) assert hass.states.get(unique_id) is None assert registry.async_get(unique_id) is not None @@ -439,6 +460,7 @@ async def test_init_without_wan( assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_update_uptime(hass: HomeAssistant) -> None: """Test update uptime. @@ -538,6 +560,107 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio +async def test_update_vpn_uptime(hass: HomeAssistant) -> None: + """Test update vpn uptime. + + :param hass: HomeAssistant + """ + + with patch( + "custom_components.miwifi.updater.LuciClient" + ) as mock_luci_client, patch( + "custom_components.miwifi.async_start_discovery", return_value=None + ), patch( + "custom_components.miwifi.device_tracker.socket.socket" + ) as mock_socket, patch( + "custom_components.miwifi.updater.asyncio.sleep", return_value=None + ): + await async_mock_luci_client(mock_luci_client) + + mock_socket.return_value.recv.return_value = AsyncMock(return_value=None) + + def success() -> dict: + return json.loads(load_fixture("device_list_data.json")) + + def error() -> None: + raise LuciRequestError + + mock_luci_client.return_value.device_list = AsyncMock( + side_effect=MultipleSideEffect(success, success, success, error, error) + ) + + def original() -> dict: + return json.loads(load_fixture("vpn_status_data.json")) + + def change() -> dict: + return json.loads(load_fixture("vpn_status_off_data.json")) + + mock_luci_client.return_value.vpn_status = AsyncMock( + side_effect=MultipleSideEffect(original, original, original, change, change) + ) + + setup_data: list = await async_setup(hass) + + config_entry: MockConfigEntry = setup_data[1] + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + updater: LuciUpdater = hass.data[DOMAIN][config_entry.entry_id][UPDATER] + registry = er.async_get(hass) + + assert updater.last_update_success + + unique_id: str = _generate_id(ATTR_SENSOR_VPN_UPTIME_NAME, updater) + + entry: er.RegistryEntry | None = registry.async_get(unique_id) + state: State = hass.states.get(unique_id) + assert state is None + assert entry is not None + assert entry.disabled_by == er.RegistryEntryDisabler.INTEGRATION + + registry.async_update_entity(entity_id=unique_id, disabled_by=None) + await hass.async_block_till_done() + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + entry = registry.async_get(unique_id) + state = hass.states.get(unique_id) + + assert entry.disabled_by is None + assert state.state == "3 days, 23:29:17" + assert state.name == ATTR_SENSOR_VPN_UPTIME_NAME + assert state.attributes["icon"] == "mdi:timer-sand" + assert state.attributes["attribution"] == ATTRIBUTION + assert entry.entity_category == EntityCategory.DIAGNOSTIC + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + state = hass.states.get(unique_id) + assert state.state == "0:00:00" + + async_fire_time_changed( + hass, utcnow() + timedelta(seconds=DEFAULT_SCAN_INTERVAL + 1) + ) + await hass.async_block_till_done() + + state = hass.states.get(unique_id) + assert state.state == STATE_UNAVAILABLE + + +@pytest.mark.asyncio async def test_update_memory_usage(hass: HomeAssistant) -> None: """Test update memory usage. @@ -637,6 +760,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_memory_total(hass: HomeAssistant) -> None: """Test update memory total. @@ -736,6 +860,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_temperature(hass: HomeAssistant) -> None: """Test update temperature. @@ -835,6 +960,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_mode(hass: HomeAssistant) -> None: """Test update mode. @@ -914,6 +1040,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_ap_signal(hass: HomeAssistant) -> None: """Test update ap signal. @@ -997,6 +1124,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_download_speed(hass: HomeAssistant) -> None: """Test update download speed. @@ -1076,6 +1204,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_upload_speed(hass: HomeAssistant) -> None: """Test update upload speed. @@ -1155,6 +1284,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices(hass: HomeAssistant) -> None: """Test update devices. @@ -1242,6 +1372,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices_lan(hass: HomeAssistant) -> None: """Test update devices lan. @@ -1351,6 +1482,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices_2_4(hass: HomeAssistant) -> None: """Test update devices 2.4. @@ -1460,6 +1592,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices_5_0(hass: HomeAssistant) -> None: """Test update devices 5.0. @@ -1569,6 +1702,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices_guest(hass: HomeAssistant) -> None: """Test update devices guest. @@ -1678,6 +1812,7 @@ def change() -> dict: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_devices_5_0_game(hass: HomeAssistant) -> None: """Test update devices 5.0 game. diff --git a/tests/test_services.py b/tests/test_services.py index f070711..6bcb941 100644 --- a/tests/test_services.py +++ b/tests/test_services.py @@ -54,6 +54,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") +@pytest.mark.asyncio async def setup_automation(hass, device_id, trigger_type): """Set up an automation trigger for testing triggering.""" @@ -79,6 +80,7 @@ async def setup_automation(hass, device_id, trigger_type): ) +@pytest.mark.asyncio async def test_calc_passwd(hass: HomeAssistant) -> None: """Test calc passwd. @@ -131,6 +133,7 @@ def pn_check(hass: HomeAssistant, message: str, title: str) -> None: ) +@pytest.mark.asyncio async def test_calc_passwd_not_found_device(hass: HomeAssistant) -> None: """Test calc passwd not found device. @@ -171,6 +174,7 @@ async def test_calc_passwd_not_found_device(hass: HomeAssistant) -> None: assert str(error.value) == "Device test not found." +@pytest.mark.asyncio async def test_calc_passwd_unsupported_device(hass: HomeAssistant) -> None: """Test calc passwd unsupported device. @@ -221,6 +225,7 @@ async def test_calc_passwd_unsupported_device(hass: HomeAssistant) -> None: ) +@pytest.mark.asyncio async def test_calc_passwd_unsupported_device_with_integration( hass: HomeAssistant, ) -> None: @@ -277,6 +282,7 @@ async def test_calc_passwd_unsupported_device_with_integration( ) +@pytest.mark.asyncio async def test_request( hass: HomeAssistant, httpx_mock: HTTPXMock, @@ -315,6 +321,11 @@ async def test_request( method="GET", url=get_url("xqnetwork/wifi_diag_detail_all"), ) + httpx_mock.add_response( + text=load_fixture("vpn_status_data.json"), + method="GET", + url=get_url("xqsystem/vpn_status"), + ) httpx_mock.add_response( text=load_fixture("avaliable_channels_2g_data.json"), method="GET", diff --git a/tests/test_switch.py b/tests/test_switch.py index a5c98c7..f414051 100644 --- a/tests/test_switch.py +++ b/tests/test_switch.py @@ -54,6 +54,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -104,6 +105,7 @@ async def test_init(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_init_with_game(hass: HomeAssistant) -> None: """Test init. @@ -163,6 +165,7 @@ async def test_init_with_game(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_init_without_guest(hass: HomeAssistant) -> None: """Test init. @@ -218,6 +221,7 @@ async def test_init_without_guest(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_init_with_error(hass: HomeAssistant) -> None: """Test init. @@ -268,6 +272,7 @@ async def test_init_with_error(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_init_bsd( hass: HomeAssistant, ) -> None: @@ -368,6 +373,7 @@ def bsd_on() -> dict: assert entry.original_name == ATTR_SWITCH_WIFI_5_0_GAME_NAME +@pytest.mark.asyncio async def test_update_2_4(hass: HomeAssistant) -> None: """Test update 2.4. @@ -435,6 +441,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_2_4_wifi_data(hass: HomeAssistant) -> None: """Test update 2.4. @@ -518,6 +525,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_2_4_turn(hass: HomeAssistant) -> None: """Test update 2.4. @@ -623,6 +631,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 4 +@pytest.mark.asyncio async def test_update_5_0(hass: HomeAssistant) -> None: """Test update 5.0. @@ -690,6 +699,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_5_0_wifi_data(hass: HomeAssistant) -> None: """Test update 5.0. @@ -773,6 +783,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_5_0_turn(hass: HomeAssistant) -> None: """Test update 5.0. @@ -878,6 +889,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 4 +@pytest.mark.asyncio async def test_update_5_0_game(hass: HomeAssistant) -> None: """Test update 5.0 game. @@ -954,6 +966,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_5_0_game_wifi_data(hass: HomeAssistant) -> None: """Test update 5.0. @@ -1045,6 +1058,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_5_0_game_turn(hass: HomeAssistant) -> None: """Test update 5.0 game. @@ -1159,6 +1173,7 @@ def error_set_wifi(data: dict) -> None: assert len(mock_luci_client.mock_calls) == _prev_calls + 4 +@pytest.mark.asyncio async def test_update_guest(hass: HomeAssistant) -> None: """Test update guest. @@ -1250,6 +1265,7 @@ def error() -> None: assert state.state == STATE_UNAVAILABLE +@pytest.mark.asyncio async def test_update_guest_wifi_data(hass: HomeAssistant) -> None: """Test update guest. @@ -1343,6 +1359,7 @@ def change_wifi_data() -> dict: } +@pytest.mark.asyncio async def test_update_guest_turn(hass: HomeAssistant) -> None: """Test update guest. diff --git a/tests/test_system_health.py b/tests/test_system_health.py index 51293bd..d4fcd52 100644 --- a/tests/test_system_health.py +++ b/tests/test_system_health.py @@ -29,6 +29,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_system_health(hass: HomeAssistant) -> None: """Test system_health. diff --git a/tests/test_update.py b/tests/test_update.py index d690c9b..2180aab 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -56,6 +56,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_init(hass: HomeAssistant) -> None: """Test init. @@ -94,6 +95,7 @@ async def test_init(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is not None +@pytest.mark.asyncio async def test_init_unsupported(hass: HomeAssistant) -> None: """Test init. @@ -136,6 +138,7 @@ async def test_init_unsupported(hass: HomeAssistant) -> None: assert registry.async_get(unique_id) is None +@pytest.mark.asyncio async def test_update(hass: HomeAssistant) -> None: """Test update. @@ -191,6 +194,7 @@ async def test_update(hass: HomeAssistant) -> None: ) +@pytest.mark.asyncio async def test_need_update(hass: HomeAssistant) -> None: """Test need update. @@ -265,6 +269,7 @@ def _on() -> dict: ) +@pytest.mark.asyncio async def test_release_notes(hass: HomeAssistant) -> None: """Test init. @@ -306,6 +311,7 @@ async def test_release_notes(hass: HomeAssistant) -> None: assert await entity.async_release_notes() == MAP_NOTES[ATTR_UPDATE_FIRMWARE] +@pytest.mark.asyncio async def test_install(hass: HomeAssistant) -> None: """Test install. @@ -387,6 +393,7 @@ def _on() -> dict: assert len(mock_asyncio_sleep.mock_calls) == 739 +@pytest.mark.asyncio async def test_install_flash_error(hass: HomeAssistant) -> None: """Test install. @@ -459,6 +466,7 @@ def _on() -> dict: assert len(mock_asyncio_sleep.mock_calls) == 18 +@pytest.mark.asyncio async def test_install_error(hass: HomeAssistant) -> None: """Test install error. diff --git a/tests/test_updater_ap_mode.py b/tests/test_updater_ap_mode.py index 1eb1b3b..50305c5 100644 --- a/tests/test_updater_ap_mode.py +++ b/tests/test_updater_ap_mode.py @@ -18,6 +18,7 @@ from custom_components.miwifi.const import ( ATTR_BINARY_SENSOR_DUAL_BAND, + ATTR_BINARY_SENSOR_VPN_STATE, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_DEVICE_HW_VERSION, ATTR_DEVICE_MAC_ADDRESS, @@ -44,6 +45,7 @@ ATTR_SENSOR_MODE, ATTR_SENSOR_TEMPERATURE, ATTR_SENSOR_UPTIME, + ATTR_SENSOR_VPN_UPTIME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_UPLOAD_SPEED, ATTR_STATE, @@ -91,6 +93,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_updater_ap_mode(hass: HomeAssistant) -> None: """Test updater. @@ -149,6 +152,8 @@ async def test_updater_ap_mode(hass: HomeAssistant) -> None: assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -236,9 +241,10 @@ async def test_updater_ap_mode(hass: HomeAssistant) -> None: assert updater._signals == {"00:00:00:00:00:01": 100, "00:00:00:00:00:02": 100} assert len(mock_async_dispatcher_send.mock_calls) == 0 - assert len(mock_luci_client.mock_calls) == 15 + assert len(mock_luci_client.mock_calls) == 16 +@pytest.mark.asyncio async def test_updater_ap_mode_force_load(hass: HomeAssistant) -> None: """Test updater in force load. @@ -303,6 +309,8 @@ async def test_updater_ap_mode_force_load(hass: HomeAssistant) -> None: assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -427,9 +435,10 @@ async def test_updater_ap_mode_force_load(hass: HomeAssistant) -> None: } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 25 + assert len(mock_luci_client.mock_calls) == 27 +@pytest.mark.asyncio async def test_updater_ap_mode_move(hass: HomeAssistant) -> None: """Test updater. @@ -610,6 +619,7 @@ async def test_updater_ap_mode_move(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_ap_mode_revert_move(hass: HomeAssistant) -> None: """Test updater. @@ -912,6 +922,7 @@ def second_device_list() -> None: } +@pytest.mark.asyncio async def test_updater_ap_mode_revert_move_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1211,6 +1222,7 @@ async def test_updater_ap_mode_revert_move_force_mode(hass: HomeAssistant) -> No } +@pytest.mark.asyncio async def test_updater_ap_mode_move_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1382,6 +1394,7 @@ async def test_updater_ap_mode_move_force_mode(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_ap_mode_restore(hass: HomeAssistant) -> None: """Test updater. @@ -1603,6 +1616,7 @@ async def test_updater_ap_mode_restore(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_ap_mode_restore_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1781,6 +1795,7 @@ async def test_updater_ap_mode_restore_force_mode(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> None: """Test updater in force load. @@ -1871,4 +1886,4 @@ async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 25 + assert len(mock_luci_client.mock_calls) == 27 diff --git a/tests/test_updater_default_mode.py b/tests/test_updater_default_mode.py index 8ba57b6..47e5c49 100644 --- a/tests/test_updater_default_mode.py +++ b/tests/test_updater_default_mode.py @@ -18,6 +18,7 @@ from custom_components.miwifi.const import ( ATTR_BINARY_SENSOR_DUAL_BAND, + ATTR_BINARY_SENSOR_VPN_STATE, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_DEVICE_HW_VERSION, ATTR_DEVICE_MAC_ADDRESS, @@ -44,6 +45,7 @@ ATTR_SENSOR_MODE, ATTR_SENSOR_TEMPERATURE, ATTR_SENSOR_UPTIME, + ATTR_SENSOR_VPN_UPTIME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_UPLOAD_SPEED, ATTR_STATE, @@ -91,6 +93,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_updater_default_mode( hass: HomeAssistant, ) -> None: @@ -148,6 +151,8 @@ async def test_updater_default_mode( assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -291,9 +296,10 @@ async def test_updater_default_mode( } assert len(mock_async_dispatcher_send.mock_calls) == 3 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_restore_data(hass: HomeAssistant) -> None: """Test updater. @@ -405,9 +411,10 @@ async def test_updater_restore_data(hass: HomeAssistant) -> None: assert len(mock_async_dispatcher_send.mock_calls) == 4 assert len(mock_store.mock_calls) == 3 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_incorrect_connection_restore_data(hass: HomeAssistant) -> None: """Test updater. @@ -521,9 +528,10 @@ async def test_updater_incorrect_connection_restore_data(hass: HomeAssistant) -> assert len(mock_async_dispatcher_send.mock_calls) == 4 assert len(mock_store.mock_calls) == 3 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_incorrect_mac_default_mode(hass: HomeAssistant) -> None: """Test updater. @@ -612,9 +620,10 @@ async def test_updater_incorrect_mac_default_mode(hass: HomeAssistant) -> None: } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_default_mode_auto_remove(hass: HomeAssistant) -> None: """Test updater. @@ -704,6 +713,7 @@ async def test_updater_default_mode_auto_remove(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_default_mode_auto_remove_incorrect(hass: HomeAssistant) -> None: """Test updater. diff --git a/tests/test_updater_main.py b/tests/test_updater_main.py index 4f4a12c..5cbe951 100644 --- a/tests/test_updater_main.py +++ b/tests/test_updater_main.py @@ -71,6 +71,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_updater(hass: HomeAssistant) -> None: """Test updater. @@ -123,6 +124,7 @@ async def test_updater(hass: HomeAssistant) -> None: assert updater.device_info["configuration_url"] == f"http://{MOCK_IP_ADDRESS}/" +@pytest.mark.asyncio async def test_updater_login_fail(hass: HomeAssistant) -> None: """Test updater login_fail. @@ -152,6 +154,7 @@ async def test_updater_login_fail(hass: HomeAssistant) -> None: assert len(mock_luci_client.mock_calls) == 13 +@pytest.mark.asyncio async def test_updater_reauthorization(hass: HomeAssistant) -> None: """Test updater reauthorization. @@ -201,6 +204,7 @@ def login_error() -> None: assert not updater.data[ATTR_STATE] +@pytest.mark.asyncio async def test_updater_skip_method(hass: HomeAssistant) -> None: """Test updater skip unsupported method. @@ -233,6 +237,7 @@ async def test_updater_skip_method(hass: HomeAssistant) -> None: assert len(mock_new_status.mock_calls) == 0 +@pytest.mark.asyncio async def test_updater_without_model_info(hass: HomeAssistant) -> None: """Test updater without model info. @@ -262,6 +267,7 @@ async def test_updater_without_model_info(hass: HomeAssistant) -> None: assert updater.device_info["manufacturer"] == DEFAULT_MANUFACTURER +@pytest.mark.asyncio async def test_updater_undefined_router(hass: HomeAssistant) -> None: """Test updater undefined router config. @@ -295,6 +301,7 @@ async def test_updater_undefined_router(hass: HomeAssistant) -> None: assert len(mock_async_self_check.mock_calls) == 1 +@pytest.mark.asyncio async def test_updater_without_hardware_info(hass: HomeAssistant) -> None: """Test updater without hardware info. @@ -328,6 +335,7 @@ async def test_updater_without_hardware_info(hass: HomeAssistant) -> None: assert len(mock_async_create_pm.mock_calls) == 1 +@pytest.mark.asyncio async def test_updater_without_version_info(hass: HomeAssistant) -> None: """Test updater without version info. @@ -355,6 +363,7 @@ async def test_updater_without_version_info(hass: HomeAssistant) -> None: assert ATTR_UPDATE_CURRENT_VERSION not in updater.data +@pytest.mark.asyncio async def test_updater_raise_rom_update(hass: HomeAssistant) -> None: """Test updater raise rom update. @@ -384,6 +393,7 @@ async def test_updater_raise_rom_update(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_need_rom_update(hass: HomeAssistant) -> None: """Test updater need rom update. @@ -419,6 +429,7 @@ async def test_updater_need_rom_update(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_key_error_rom_update(hass: HomeAssistant) -> None: """Test updater key error rom update. @@ -447,6 +458,7 @@ async def test_updater_key_error_rom_update(hass: HomeAssistant) -> None: assert ATTR_UPDATE_FIRMWARE not in updater.data +@pytest.mark.asyncio async def test_updater_skip_mode_mesh(hass: HomeAssistant) -> None: """Test updater key error rom update. @@ -472,6 +484,7 @@ async def test_updater_skip_mode_mesh(hass: HomeAssistant) -> None: assert updater.data[ATTR_SENSOR_MODE] == Mode.MESH +@pytest.mark.asyncio async def test_updater_value_error_mode(hass: HomeAssistant) -> None: """Test updater value error mode. @@ -500,6 +513,7 @@ async def test_updater_value_error_mode(hass: HomeAssistant) -> None: assert updater.data[ATTR_SENSOR_MODE] == Mode.DEFAULT +@pytest.mark.asyncio async def test_updater_incorrect_wan_info(hass: HomeAssistant) -> None: """Test updater incorrect wan info. @@ -528,6 +542,7 @@ async def test_updater_incorrect_wan_info(hass: HomeAssistant) -> None: assert not updater.data[ATTR_BINARY_SENSOR_WAN_STATE] +@pytest.mark.asyncio async def test_updater_incorrect_led(hass: HomeAssistant) -> None: """Test updater incorrect led. @@ -556,6 +571,7 @@ async def test_updater_incorrect_led(hass: HomeAssistant) -> None: assert not updater.data[ATTR_LIGHT_LED] +@pytest.mark.asyncio async def test_updater_undefined_bsd_wifi_info(hass: HomeAssistant) -> None: """Test updater undefined bsd wifi info. @@ -586,6 +602,7 @@ async def test_updater_undefined_bsd_wifi_info(hass: HomeAssistant) -> None: assert not updater.data[ATTR_BINARY_SENSOR_DUAL_BAND] +@pytest.mark.asyncio async def test_updater_empty_wifi_info(hass: HomeAssistant) -> None: """Test updater empty wifi info. @@ -629,6 +646,7 @@ async def test_updater_empty_wifi_info(hass: HomeAssistant) -> None: assert ATTR_SELECT_WIFI_5_0_GAME_SIGNAL_STRENGTH not in updater.data +@pytest.mark.asyncio async def test_updater_unsupported_guest_wifi_info(hass: HomeAssistant) -> None: """Test updater unsupported guest wifi info. @@ -661,6 +679,7 @@ async def test_updater_unsupported_guest_wifi_info(hass: HomeAssistant) -> None: assert not updater.supports_guest +@pytest.mark.asyncio async def test_updater_error_guest_wifi_info(hass: HomeAssistant) -> None: """Test updater error guest wifi info. @@ -691,6 +710,7 @@ async def test_updater_error_guest_wifi_info(hass: HomeAssistant) -> None: assert not updater.supports_guest +@pytest.mark.asyncio async def test_updater_is_absent_ifname_wifi_info(hass: HomeAssistant) -> None: """Test updater is absent ifname wifi info. @@ -726,6 +746,7 @@ async def test_updater_is_absent_ifname_wifi_info(hass: HomeAssistant) -> None: assert ATTR_SELECT_WIFI_2_4_SIGNAL_STRENGTH not in updater.data +@pytest.mark.asyncio async def test_updater_undefined_ifname_wifi_info(hass: HomeAssistant) -> None: """Test updater undefined ifname wifi info. @@ -761,6 +782,7 @@ async def test_updater_undefined_ifname_wifi_info(hass: HomeAssistant) -> None: assert ATTR_SELECT_WIFI_2_4_SIGNAL_STRENGTH not in updater.data +@pytest.mark.asyncio async def test_updater_empty_2g_avaliable_channels(hass: HomeAssistant) -> None: """Test updater empty 2g avaliable channels. @@ -798,6 +820,7 @@ async def mock_avaliable_channels(index: int = 1) -> dict: assert ATTR_SELECT_WIFI_5_0_CHANNELS in updater.data +@pytest.mark.asyncio async def test_updater_without_store(hass: HomeAssistant) -> None: """Test updater without_store. @@ -828,6 +851,7 @@ async def test_updater_without_store(hass: HomeAssistant) -> None: assert len(mock_store.mock_calls) == 0 +@pytest.mark.asyncio async def test_updater_with_clean_store(hass: HomeAssistant) -> None: """Test updater with clean store. @@ -851,6 +875,7 @@ async def test_updater_with_clean_store(hass: HomeAssistant) -> None: await hass.async_block_till_done() +@pytest.mark.asyncio async def test_get_updater_by_ip_error(hass: HomeAssistant) -> None: """Test updater by ip error. diff --git a/tests/test_updater_mesh_mode.py b/tests/test_updater_mesh_mode.py index 964b0c3..8dfe289 100644 --- a/tests/test_updater_mesh_mode.py +++ b/tests/test_updater_mesh_mode.py @@ -18,6 +18,7 @@ from custom_components.miwifi.const import ( ATTR_BINARY_SENSOR_DUAL_BAND, + ATTR_BINARY_SENSOR_VPN_STATE, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_DEVICE_HW_VERSION, ATTR_DEVICE_MAC_ADDRESS, @@ -44,6 +45,7 @@ ATTR_SENSOR_MODE, ATTR_SENSOR_TEMPERATURE, ATTR_SENSOR_UPTIME, + ATTR_SENSOR_VPN_UPTIME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_UPLOAD_SPEED, ATTR_STATE, @@ -91,6 +93,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_updater_mesh_mode( hass: HomeAssistant, ) -> None: @@ -151,6 +154,8 @@ async def test_updater_mesh_mode( assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -242,9 +247,10 @@ async def test_updater_mesh_mode( } assert len(mock_async_dispatcher_send.mock_calls) == 0 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_mesh_mode_force_load( hass: HomeAssistant, ) -> None: @@ -311,6 +317,8 @@ async def test_updater_mesh_mode_force_load( assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -438,9 +446,10 @@ async def test_updater_mesh_mode_force_load( } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 26 + assert len(mock_luci_client.mock_calls) == 28 +@pytest.mark.asyncio async def test_updater_mesh_mode_move(hass: HomeAssistant) -> None: """Test updater. @@ -621,6 +630,7 @@ async def test_updater_mesh_mode_move(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_mesh_mode_revert_move( hass: HomeAssistant, ) -> None: @@ -925,6 +935,7 @@ def second_device_list() -> None: } +@pytest.mark.asyncio async def test_updater_mesh_mode_revert_move_force_mode( hass: HomeAssistant, ) -> None: @@ -1228,6 +1239,7 @@ async def test_updater_mesh_mode_revert_move_force_mode( } +@pytest.mark.asyncio async def test_updater_mesh_mode_move_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1399,6 +1411,7 @@ async def test_updater_mesh_mode_move_force_mode(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_mesh_mode_restore(hass: HomeAssistant) -> None: """Test updater. @@ -1620,6 +1633,7 @@ async def test_updater_mesh_mode_restore(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_mesh_mode_restore_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1798,6 +1812,7 @@ async def test_updater_mesh_mode_restore_force_mode(hass: HomeAssistant) -> None } +@pytest.mark.asyncio async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> None: """Test updater in force load. @@ -1891,4 +1906,4 @@ async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 26 + assert len(mock_luci_client.mock_calls) == 28 diff --git a/tests/test_updater_repeater_mode.py b/tests/test_updater_repeater_mode.py index cdef5ca..ceb9757 100644 --- a/tests/test_updater_repeater_mode.py +++ b/tests/test_updater_repeater_mode.py @@ -18,6 +18,7 @@ from custom_components.miwifi.const import ( ATTR_BINARY_SENSOR_DUAL_BAND, + ATTR_BINARY_SENSOR_VPN_STATE, ATTR_BINARY_SENSOR_WAN_STATE, ATTR_DEVICE_HW_VERSION, ATTR_DEVICE_MAC_ADDRESS, @@ -45,6 +46,7 @@ ATTR_SENSOR_MODE, ATTR_SENSOR_TEMPERATURE, ATTR_SENSOR_UPTIME, + ATTR_SENSOR_VPN_UPTIME, ATTR_SENSOR_WAN_DOWNLOAD_SPEED, ATTR_SENSOR_WAN_UPLOAD_SPEED, ATTR_STATE, @@ -92,6 +94,7 @@ def auto_enable_custom_integrations(enable_custom_integrations): yield +@pytest.mark.asyncio async def test_updater_repeater_mode( hass: HomeAssistant, ) -> None: @@ -152,6 +155,8 @@ async def test_updater_repeater_mode( assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -243,9 +248,10 @@ async def test_updater_repeater_mode( } assert len(mock_async_dispatcher_send.mock_calls) == 0 - assert len(mock_luci_client.mock_calls) == 16 + assert len(mock_luci_client.mock_calls) == 17 +@pytest.mark.asyncio async def test_updater_repeater_mode_force_load( hass: HomeAssistant, ) -> None: @@ -312,6 +318,8 @@ async def test_updater_repeater_mode_force_load( assert updater.data[ATTR_DEVICE_MAC_ADDRESS] == "00:00:00:00:00:00" assert updater.data[ATTR_UPDATE_CURRENT_VERSION] == "3.0.34" assert updater.data[ATTR_SENSOR_UPTIME] == "8:06:26" + assert updater.data[ATTR_BINARY_SENSOR_VPN_STATE] + assert updater.data[ATTR_SENSOR_VPN_UPTIME] == "3 days, 23:29:17" assert updater.data[ATTR_SENSOR_MEMORY_USAGE] == 53 assert updater.data[ATTR_SENSOR_MEMORY_TOTAL] == 256 assert updater.data[ATTR_SENSOR_TEMPERATURE] == 0.0 @@ -439,9 +447,10 @@ async def test_updater_repeater_mode_force_load( } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 27 + assert len(mock_luci_client.mock_calls) == 29 +@pytest.mark.asyncio async def test_updater_repeater_mode_move(hass: HomeAssistant) -> None: """Test updater. @@ -622,6 +631,7 @@ async def test_updater_repeater_mode_move(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_repeater_mode_revert_move( hass: HomeAssistant, ) -> None: @@ -926,6 +936,7 @@ def second_device_list() -> None: } +@pytest.mark.asyncio async def test_updater_repeater_mode_revert_move_force_mode( hass: HomeAssistant, ) -> None: @@ -1229,6 +1240,7 @@ async def test_updater_repeater_mode_revert_move_force_mode( } +@pytest.mark.asyncio async def test_updater_repeater_mode_move_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1400,6 +1412,7 @@ async def test_updater_repeater_mode_move_force_mode(hass: HomeAssistant) -> Non } +@pytest.mark.asyncio async def test_updater_repeater_mode_restore(hass: HomeAssistant) -> None: """Test updater. @@ -1621,6 +1634,7 @@ async def test_updater_repeater_mode_restore(hass: HomeAssistant) -> None: } +@pytest.mark.asyncio async def test_updater_repeater_mode_restore_force_mode(hass: HomeAssistant) -> None: """Test updater. @@ -1799,6 +1813,7 @@ async def test_updater_repeater_mode_restore_force_mode(hass: HomeAssistant) -> } +@pytest.mark.asyncio async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> None: """Test updater in force load. @@ -1892,4 +1907,4 @@ async def test_updater_ap_mode_force_load_incorrect_type(hass: HomeAssistant) -> } assert len(mock_async_dispatcher_send.mock_calls) == 2 - assert len(mock_luci_client.mock_calls) == 27 + assert len(mock_luci_client.mock_calls) == 29