async def _setup_mock_domain( hass: HomeAssistant, platform: BackupPlatformProtocol | None = None, ) -> None: """Set up a mock domain.""" mock_platform(hass, "some_domain.backup", platform or MockPlatform()) assert await async_setup_component(hass, "some_domain", {})
async def test_process_integration_platforms(opp): """Test processing integrations.""" loaded_platform = Mock() mock_platform(opp, "loaded.platform_to_check", loaded_platform) opp.config.components.add("loaded") event_platform = Mock() mock_platform(opp, "event.platform_to_check", event_platform) processed = [] async def _process_platform(opp, domain, platform): """Process platform.""" processed.append((domain, platform)) await opp.helpers.integration_platform.async_process_integration_platforms( "platform_to_check", _process_platform) assert len(processed) == 1 assert processed[0][0] == "loaded" assert processed[0][1] == loaded_platform opp.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: "event"}) await opp.async_block_till_done() assert len(processed) == 2 assert processed[1][0] == "event" assert processed[1][1] == event_platform
def config_flow_handler( hass: HomeAssistant, current_request_with_host: Any ) -> Generator[FakeConfigFlow, None, None]: """Fixture for a test config flow.""" mock_platform(hass, f"{TEST_DOMAIN}.config_flow") with patch.dict(config_entries.HANDLERS, {TEST_DOMAIN: FakeConfigFlow}): yield FakeConfigFlow
async def test_websocket_without_authorization_server( hass: HomeAssistant, ws_client: ClientFixture): """Test platform with incorrect implementation.""" assert await async_setup_component(hass, "application_credentials", {}) hass.config.components.add(TEST_DOMAIN) # Platform does not implemenent async_get_authorization_server platform = Mock() del platform.async_get_authorization_server mock_platform( hass, f"{TEST_DOMAIN}.application_credentials", platform, ) client = await ws_client() resp = await client.cmd( "create", { CONF_DOMAIN: TEST_DOMAIN, CONF_CLIENT_ID: CLIENT_ID, CONF_CLIENT_SECRET: CLIENT_SECRET, }, ) assert not resp.get("success") assert "error" in resp assert resp["error"].get("code") == "invalid_format" # Config flow does not have authentication with pytest.raises(ValueError): await hass.config_entries.flow.async_init( TEST_DOMAIN, context={"source": config_entries.SOURCE_USER})
async def test_process_integration_platforms(hass): """Test processing integrations.""" loaded_platform = Mock() mock_platform(hass, "loaded.platform_to_check", loaded_platform) hass.config.components.add("loaded") event_platform = Mock() mock_platform(hass, "event.platform_to_check", event_platform) processed = [] async def _process_platform(hass, domain, platform): """Process platform.""" processed.append((domain, platform)) await async_process_integration_platforms(hass, "platform_to_check", _process_platform) assert len(processed) == 1 assert processed[0][0] == "loaded" assert processed[0][1] == loaded_platform hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: "event"}) await hass.async_block_till_done() assert len(processed) == 2 assert processed[1][0] == "event" assert processed[1][1] == event_platform # Verify we only process the platform once if we call it manually await async_process_integration_platform_for_component(hass, "event") assert len(processed) == 2
async def test_platform_loading(opp, opp_ws_client, aioclient_mock): """Test registering via platform.""" aioclient_mock.get("http://example.com/status", text="") aioclient_mock.get("http://example.com/status_fail", exc=ClientError) aioclient_mock.get("http://example.com/timeout", exc=asyncio.TimeoutError) opp.config.components.add("fake_integration") mock_platform( opp, "fake_integration.system_health", Mock(async_register=lambda opp, register: register.async_register_info( AsyncMock( return_value={ "hello": "info", "server_reachable": system_health.async_check_can_reach_url( opp, "http://example.com/status"), "server_fail_reachable": system_health.async_check_can_reach_url( opp, "http://example.com/status_fail", more_info="http://more-info-url.com", ), "server_timeout": system_health.async_check_can_reach_url( opp, "http://example.com/timeout", more_info="http://more-info-url.com", ), "async_crash": AsyncMock(side_effect=ValueError)(), }), "/config/fake_integration", )), ) assert await async_setup_component(opp, "system_health", {}) data = await gather_system_health_info(opp, opp_ws_client) assert data["fake_integration"] == { "info": { "hello": "info", "server_reachable": "ok", "server_fail_reachable": { "type": "failed", "error": "unreachable", "more_info": "http://more-info-url.com", }, "server_timeout": { "type": "failed", "error": "timeout", "more_info": "http://more-info-url.com", }, "async_crash": { "type": "failed", "error": "unknown", }, }, "manage_url": "/config/fake_integration", }
def mock_notify_platform( hass, tmp_path, integration="notify", async_get_service=None, get_service=None ): """Specialize the mock platform for notify.""" loaded_platform = MockNotifyPlatform(async_get_service, get_service) mock_platform(hass, f"{integration}.notify", loaded_platform) return loaded_platform
async def mock_diagnostics_integration(hass): """Mock a diagnostics integration.""" hass.config.components.add("fake_integration") mock_platform( hass, "fake_integration.diagnostics", Mock(async_get_config_entry_diagnostics=AsyncMock(return_value={ "hello": "info", }), ), ) assert await async_setup_component(hass, "diagnostics", {})
async def setup_application_credentials_integration( hass: HomeAssistant, domain: str, authorization_server: AuthorizationServer, ) -> None: """Set up a fake application_credentials integration.""" hass.config.components.add(domain) mock_platform( hass, f"{domain}.application_credentials", Mock(async_get_authorization_server=AsyncMock( return_value=authorization_server), ), )
def mock_energy_platform(hass): """Mock an energy platform.""" hass.config.components.add("some_domain") mock_platform( hass, "some_domain.energy", Mock(async_get_solar_forecast=AsyncMock( return_value={ "wh_hours": { "2021-06-27T13:00:00+00:00": 12, "2021-06-27T14:00:00+00:00": 8, } })), )
def flow_handler(opp): """Return a registered config flow.""" mock_platform(opp, f"{TEST_DOMAIN}.config_flow") class TestFlowHandler(config_entry_oauth2_flow.AbstractOAuth2FlowHandler): """Test flow handler.""" DOMAIN = TEST_DOMAIN @property def logger(self) -> logging.Logger: """Return logger.""" return logging.getLogger(__name__) with patch.dict(config_entries.HANDLERS, {TEST_DOMAIN: TestFlowHandler}): yield TestFlowHandler
async def mock_repairs_integration(hass): """Mock a repairs integration.""" hass.config.components.add("fake_integration") def async_create_fix_flow(hass, issue_id, data): assert issue_id in EXPECTED_DATA assert data == EXPECTED_DATA[issue_id] return MockFixFlow() mock_platform( hass, "fake_integration.repairs", Mock(async_create_fix_flow=AsyncMock(wraps=async_create_fix_flow)), ) mock_platform( hass, "integration_without_repairs.repairs", Mock(spec=[]), )
async def test_config_platform_raise(hass): """Test bad config validation platform.""" mock_platform( hass, "bla.config", Mock(async_validate_config=Mock(side_effect=Exception("Broken"))), ) files = { YAML_CONFIG_FILE: BASE_CONFIG + """ bla: value: 1 """, } with patch("os.path.isfile", return_value=True), patch_yaml_files(files): res = await async_check_ha_config_file(hass) assert len(res.errors) == 1 err = res.errors[0] assert err.domain == "bla" assert err.message == "Unexpected error calling config validator: Broken" assert err.config == {"value": 1}
async def test_non_compliant_platform(hass: HomeAssistant, hass_ws_client) -> None: """Test non-compliant platforms are not registered.""" hass.config.components.add("fake_integration") hass.config.components.add("integration_without_diagnostics") mock_platform( hass, "fake_integration.repairs", Mock(async_create_fix_flow=AsyncMock(return_value=True)), ) mock_platform( hass, "integration_without_diagnostics.repairs", Mock(spec=[]), ) assert await async_setup_component(hass, DOMAIN, {}) await async_process_repairs_platforms(hass) assert list(hass.data[DOMAIN]["platforms"].keys()) == ["fake_integration"]
def flow_handler(hass): """Return a registered config flow.""" mock_platform(hass, f"{TEST_DOMAIN}.config_flow") class TestFlowHandler(config_entry_oauth2_flow.AbstractOAuth2FlowHandler): """Test flow handler.""" DOMAIN = TEST_DOMAIN @property def logger(self) -> logging.Logger: """Return logger.""" return logging.getLogger(__name__) @property def extra_authorize_data(self) -> dict: """Extra data that needs to be appended to the authorize url.""" return {"scope": "read write"} with patch.dict(config_entries.HANDLERS, {TEST_DOMAIN: TestFlowHandler}): yield TestFlowHandler
async def test_platform_with_auth_implementation( hass, hass_client_no_auth, aioclient_mock, oauth_fixture, config_credential, import_config_credential, authorization_server, ): """Test config flow with custom OAuth2 implementation.""" assert await async_setup_component(hass, "application_credentials", {}) hass.config.components.add(TEST_DOMAIN) async def get_auth_impl( hass: HomeAssistant, auth_domain: str, credential: ClientCredential ) -> config_entry_oauth2_flow.AbstractOAuth2Implementation: return AuthImplementation(hass, auth_domain, credential, authorization_server) mock_platform_impl = Mock( async_get_auth_implementation=get_auth_impl, ) del mock_platform_impl.async_get_authorization_server mock_platform( hass, f"{TEST_DOMAIN}.application_credentials", mock_platform_impl, ) result = await hass.config_entries.flow.async_init( TEST_DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result.get("type") == data_entry_flow.RESULT_TYPE_EXTERNAL_STEP oauth_fixture.title = DEFAULT_IMPORT_NAME result = await oauth_fixture.complete_external_step(result) # Uses the imported auth domain for compatibility assert result["data"].get("auth_implementation") == TEST_DOMAIN