From cbfbbcd9151cde316d48c12df4e5abdd2b5f9b2b Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:01:45 -0500 Subject: [PATCH] Fix bugs and add tests --- .../lock_code_manager/__init__.py | 21 +++--- tests/conftest.py | 17 ++++- tests/test_init.py | 66 ++++++++++++++++++- 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/custom_components/lock_code_manager/__init__.py b/custom_components/lock_code_manager/__init__.py index 42b34865..c39e0499 100644 --- a/custom_components/lock_code_manager/__init__.py +++ b/custom_components/lock_code_manager/__init__.py @@ -69,15 +69,14 @@ async def async_setup(hass: HomeAssistant, config: Config) -> bool: """Set up integration.""" hass.data.setdefault(DOMAIN, {CONF_LOCKS: {}, COORDINATORS: {}, "resources": False}) + # Expose strategy javascript + hass.http.register_static_path( + STRATEGY_PATH, Path(__file__).parent / "www" / STRATEGY_FILENAME + ) + _LOGGER.debug("Exposed strategy module at %s", STRATEGY_PATH) resources: ResourceStorageCollection | ResourceYAMLCollection if resources := hass.data.get(LL_DOMAIN, {}).get("resources"): - # Expose strategy javascript - hass.http.register_static_path( - STRATEGY_PATH, Path(__file__).parent / "www" / STRATEGY_FILENAME - ) - _LOGGER.debug("Exposed strategy module at %s", STRATEGY_PATH) - # Load resources if needed if not resources.loaded: await resources.async_load() @@ -86,7 +85,7 @@ async def async_setup(hass: HomeAssistant, config: Config) -> bool: try: res_id = next( - data[CONF_ID] + data.get(CONF_ID) for data in resources.async_items() if data[CONF_URL] == STRATEGY_PATH ) @@ -114,9 +113,9 @@ async def async_setup(hass: HomeAssistant, config: Config) -> bool: "Strategy module already registered with resource ID %s", res_id ) - # Set up websocket API - await async_websocket_setup(hass) - _LOGGER.debug("Finished setting up websocket API") + # Set up websocket API + await async_websocket_setup(hass) + _LOGGER.debug("Finished setting up websocket API") # Hard refresh usercodes async def _hard_refresh_usercodes(service: ServiceCall) -> None: @@ -266,7 +265,7 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> COORDINATORS: {}, }: resources: ResourceStorageCollection - if resources := hass.data[LL_DOMAIN].get("resources"): + if resources := hass.data.get(LL_DOMAIN, {}).get("resources"): if hass_data["resources"]: try: resource_id = next( diff --git a/tests/conftest.py b/tests/conftest.py index 6260ea06..335d52dd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections.abc import Generator +from typing import Any import pytest from pytest_homeassistant_custom_component.common import ( @@ -57,6 +58,20 @@ def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]: yield +# @pytest.fixture(name="setup_lovelace_ui") +# async def setup_lovelace_ui_fixture(hass: HomeAssistant): +# """Set up Lovelace in UI mode.""" +# assert await async_setup_component(hass, LL_DOMAIN, {}) +# yield + + +@pytest.fixture(name="setup_lovelace_ui") +async def setup_lovelace_ui_fixture(hass: HomeAssistant, config: dict[str, Any]): + """Set up Lovelace in UI mode.""" + assert await async_setup_component(hass, LL_DOMAIN, {"lovelace": config}) + yield + + @pytest.fixture(name="mock_lock_config_entry") async def mock_lock_config_entry_fixture(hass: HomeAssistant, mock_config_flow): """Set up lock entities using an entity platform.""" @@ -126,8 +141,6 @@ async def async_setup_entry_calendar_platform( assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - assert await async_setup_component(hass, LL_DOMAIN, {}) - yield config_entry await hass.config_entries.async_unload(config_entry.entry_id) diff --git a/tests/test_init.py b/tests/test_init.py index 1583e53f..70ed24f1 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -43,8 +43,10 @@ _LOGGER = logging.getLogger(__name__) +@pytest.mark.parametrize("config", [{}]) async def test_entry_setup_and_unload( hass: HomeAssistant, + setup_lovelace_ui, mock_lock_config_entry, lock_code_manager_config_entry, ): @@ -202,13 +204,15 @@ async def test_reauth(hass: HomeAssistant, lock_code_manager_config_entry): ) -async def test_resource_already_loaded( +@pytest.mark.parametrize("config", [{}]) +async def test_resource_already_loaded_ui( hass: HomeAssistant, + setup_lovelace_ui, mock_lock_config_entry, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch, ): - """Test when strategy resource is already loaded.""" + """Test when strategy resource is already loaded in UI mode.""" resources = hass.data[LL_DOMAIN].get("resources") assert resources await resources.async_load() @@ -231,3 +235,61 @@ async def test_resource_already_loaded( assert "already registered" in caplog.text await hass.config_entries.async_unload(config_entry.entry_id) + + +@pytest.mark.parametrize( + "config", + [{"mode": "yaml", "resources": [{"type": "module", "url": STRATEGY_PATH}]}], +) +async def test_resource_already_loaded_yaml( + hass: HomeAssistant, + setup_lovelace_ui, + mock_lock_config_entry, + monkeypatch: pytest.MonkeyPatch, + caplog: pytest.LogCaptureFixture, +): + """Test when strategy resource is already loaded in YAML mode.""" + monkeypatch.setattr( + "custom_components.lock_code_manager.helpers.INTEGRATIONS_CLASS_MAP", + {"test": MockLCMLock}, + ) + + config_entry = MockConfigEntry( + domain=DOMAIN, data=BASE_CONFIG, unique_id="Mock Title" + ) + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert "already registered" in caplog.text + + await hass.config_entries.async_unload(config_entry.entry_id) + + +@pytest.mark.parametrize( + "config", + [{"mode": "yaml", "resources": [{"type": "module", "url": "fake_module.js"}]}], +) +async def test_resource_not_loaded_yaml( + hass: HomeAssistant, + setup_lovelace_ui, + mock_lock_config_entry, + monkeypatch: pytest.MonkeyPatch, + caplog: pytest.LogCaptureFixture, +): + """Test when strategy resource is not loaded in YAML mode.""" + monkeypatch.setattr( + "custom_components.lock_code_manager.helpers.INTEGRATIONS_CLASS_MAP", + {"test": MockLCMLock}, + ) + + config_entry = MockConfigEntry( + domain=DOMAIN, data=BASE_CONFIG, unique_id="Mock Title" + ) + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert "module can't automatically be registered" in caplog.text + + await hass.config_entries.async_unload(config_entry.entry_id)