diff --git a/tests/snapshots/test_config.ambr b/tests/snapshots/test_config.ambr index af4374e25f9..87d2af1e755 100644 --- a/tests/snapshots/test_config.ambr +++ b/tests/snapshots/test_config.ambr @@ -63,6 +63,18 @@ "Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_5.yaml, line 6: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option", ]) # --- +# name: test_component_config_validation_error_with_docs[basic] + list([ + "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 6: required key not provided 'platform', got None. Please check the docs at https://www.home-assistant.io/integrations/iot_domain", + "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 9: expected str for dictionary value 'option1', got 123. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007", + "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007", + "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007", + "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 27: required key not provided 'adr_0007_2->host', got None. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_2", + "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 32: expected int for dictionary value 'adr_0007_3->port', got 'foo'. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_3", + "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 37: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option Please check the docs at https://www.home-assistant.io/integrations/adr_0007_4", + "Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 44: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5", + ]) +# --- # name: test_package_merge_error[packages] list([ 'Package pack_1 setup failed. Integration adr_0007_1 cannot be merged. Dict expected in main config. (See /fixtures/core/config/package_errors/packages/configuration.yaml:9).', diff --git a/tests/test_config.py b/tests/test_config.py index fb88e8ca3a2..ca6fb3b52bc 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -114,7 +114,26 @@ async def mock_iot_domain_integration(hass: HomeAssistant) -> Integration: @pytest.fixture -async def mock_non_adr_0007_integration(hass) -> None: +async def mock_iot_domain_integration_with_docs(hass: HomeAssistant) -> Integration: + """Mock an integration which provides an IoT domain.""" + comp_platform_schema = cv.PLATFORM_SCHEMA.extend({vol.Remove("old"): str}) + comp_platform_schema_base = comp_platform_schema.extend({}, extra=vol.ALLOW_EXTRA) + + return mock_integration( + hass, + MockModule( + "iot_domain", + platform_schema_base=comp_platform_schema_base, + platform_schema=comp_platform_schema, + partial_manifest={ + "documentation": "https://www.home-assistant.io/integrations/iot_domain" + }, + ), + ) + + +@pytest.fixture +async def mock_non_adr_0007_integration(hass: HomeAssistant) -> None: """Mock a non-ADR-0007 compliant integration with iot_domain platform. The integration allows setting up iot_domain entities under the iot_domain's @@ -132,7 +151,34 @@ async def mock_non_adr_0007_integration(hass) -> None: @pytest.fixture -async def mock_adr_0007_integrations(hass) -> list[Integration]: +async def mock_non_adr_0007_integration_with_docs(hass: HomeAssistant) -> None: + """Mock a non-ADR-0007 compliant integration with iot_domain platform. + + The integration allows setting up iot_domain entities under the iot_domain's + configuration key + """ + + mock_integration( + hass, + MockModule( + "non_adr_0007", + partial_manifest={ + "documentation": "https://www.home-assistant.io/integrations/non_adr_0007" + }, + ), + ) + test_platform_schema = IOT_DOMAIN_PLATFORM_SCHEMA.extend( + {vol.Required("option1"): str, vol.Optional("option2"): str} + ) + mock_platform( + hass, + "non_adr_0007.iot_domain", + MockPlatform(platform_schema=test_platform_schema), + ) + + +@pytest.fixture +async def mock_adr_0007_integrations(hass: HomeAssistant) -> list[Integration]: """Mock ADR-0007 compliant integrations.""" integrations = [] for domain in [ @@ -162,6 +208,45 @@ async def mock_adr_0007_integrations(hass) -> list[Integration]: return integrations +@pytest.fixture +async def mock_adr_0007_integrations_with_docs( + hass: HomeAssistant, +) -> list[Integration]: + """Mock ADR-0007 compliant integrations.""" + integrations = [] + for domain in [ + "adr_0007_1", + "adr_0007_2", + "adr_0007_3", + "adr_0007_4", + "adr_0007_5", + ]: + adr_0007_config_schema = vol.Schema( + { + domain: vol.Schema( + { + vol.Required("host"): str, + vol.Required("port", default=8080): int, + } + ) + }, + extra=vol.ALLOW_EXTRA, + ) + integrations.append( + mock_integration( + hass, + MockModule( + domain, + config_schema=adr_0007_config_schema, + partial_manifest={ + "documentation": f"https://www.home-assistant.io/integrations/{domain}" + }, + ), + ) + ) + return integrations + + async def test_create_default_config(hass: HomeAssistant) -> None: """Test creation of default config.""" assert not os.path.isfile(YAML_PATH) @@ -1529,6 +1614,52 @@ async def test_component_config_validation_error( assert error_records == snapshot +@pytest.mark.parametrize( + "config_dir", + [ + "basic", + ], +) +async def test_component_config_validation_error_with_docs( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + config_dir: str, + mock_iot_domain_integration_with_docs: Integration, + mock_non_adr_0007_integration_with_docs: None, + mock_adr_0007_integrations_with_docs: list[Integration], + snapshot: SnapshotAssertion, +) -> None: + """Test schema error in component.""" + + base_path = os.path.dirname(__file__) + hass.config.config_dir = os.path.join( + base_path, "fixtures", "core", "config", "component_validation", config_dir + ) + config = await config_util.async_hass_config_yaml(hass) + + for domain in [ + "iot_domain", + "adr_0007_1", + "adr_0007_2", + "adr_0007_3", + "adr_0007_4", + "adr_0007_5", + ]: + integration = await async_get_integration(hass, domain) + await config_util.async_process_component_config( + hass, + config, + integration=integration, + ) + + error_records = [ + record.message.replace(base_path, "") + for record in caplog.get_records("call") + if record.levelno == logging.ERROR + ] + assert error_records == snapshot + + @pytest.mark.parametrize( "config_dir", ["packages", "packages_include_dir_named"],