Mark custom components that overwrite core (#127937)
This commit is contained in:
parent
5d590bc2cf
commit
1ff1b82fc7
3 changed files with 41 additions and 0 deletions
|
@ -255,6 +255,7 @@ class Manifest(TypedDict, total=False):
|
||||||
usb: list[dict[str, str]]
|
usb: list[dict[str, str]]
|
||||||
homekit: dict[str, list[str]]
|
homekit: dict[str, list[str]]
|
||||||
is_built_in: bool
|
is_built_in: bool
|
||||||
|
overwrites_built_in: bool
|
||||||
version: str
|
version: str
|
||||||
codeowners: list[str]
|
codeowners: list[str]
|
||||||
loggers: list[str]
|
loggers: list[str]
|
||||||
|
@ -451,6 +452,7 @@ async def async_get_integration_descriptions(
|
||||||
"single_config_entry": integration.manifest.get(
|
"single_config_entry": integration.manifest.get(
|
||||||
"single_config_entry", False
|
"single_config_entry", False
|
||||||
),
|
),
|
||||||
|
"overwrites_built_in": integration.overwrites_built_in,
|
||||||
}
|
}
|
||||||
custom_flows[integration_key][integration.domain] = metadata
|
custom_flows[integration_key][integration.domain] = metadata
|
||||||
|
|
||||||
|
@ -762,6 +764,7 @@ class Integration:
|
||||||
self.file_path = file_path
|
self.file_path = file_path
|
||||||
self.manifest = manifest
|
self.manifest = manifest
|
||||||
manifest["is_built_in"] = self.is_built_in
|
manifest["is_built_in"] = self.is_built_in
|
||||||
|
manifest["overwrites_built_in"] = self.overwrites_built_in
|
||||||
|
|
||||||
if self.dependencies:
|
if self.dependencies:
|
||||||
self._all_dependencies_resolved: bool | None = None
|
self._all_dependencies_resolved: bool | None = None
|
||||||
|
@ -909,6 +912,16 @@ class Integration:
|
||||||
"""Test if package is a built-in integration."""
|
"""Test if package is a built-in integration."""
|
||||||
return self.pkg_path.startswith(PACKAGE_BUILTIN)
|
return self.pkg_path.startswith(PACKAGE_BUILTIN)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def overwrites_built_in(self) -> bool:
|
||||||
|
"""Return if package overwrites a built-in integration."""
|
||||||
|
if self.is_built_in:
|
||||||
|
return False
|
||||||
|
core_comp_path = (
|
||||||
|
pathlib.Path(__file__).parent / "components" / self.domain / "manifest.json"
|
||||||
|
)
|
||||||
|
return core_comp_path.is_file()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def version(self) -> AwesomeVersion | None:
|
def version(self) -> AwesomeVersion | None:
|
||||||
"""Return the version of the integration."""
|
"""Return the version of the integration."""
|
||||||
|
|
|
@ -174,6 +174,7 @@ async def test_download_diagnostics(
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"domain": "fake_integration",
|
"domain": "fake_integration",
|
||||||
"is_built_in": True,
|
"is_built_in": True,
|
||||||
|
"overwrites_built_in": False,
|
||||||
"name": "fake_integration",
|
"name": "fake_integration",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
},
|
},
|
||||||
|
@ -260,6 +261,7 @@ async def test_download_diagnostics(
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"domain": "fake_integration",
|
"domain": "fake_integration",
|
||||||
"is_built_in": True,
|
"is_built_in": True,
|
||||||
|
"overwrites_built_in": False,
|
||||||
"name": "fake_integration",
|
"name": "fake_integration",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -583,6 +583,7 @@ def test_integration_properties(hass: HomeAssistant) -> None:
|
||||||
assert integration.dependencies == ["test-dep"]
|
assert integration.dependencies == ["test-dep"]
|
||||||
assert integration.requirements == ["test-req==1.0.0"]
|
assert integration.requirements == ["test-req==1.0.0"]
|
||||||
assert integration.is_built_in is True
|
assert integration.is_built_in is True
|
||||||
|
assert integration.overwrites_built_in is False
|
||||||
assert integration.version == "1.0.0"
|
assert integration.version == "1.0.0"
|
||||||
|
|
||||||
integration = loader.Integration(
|
integration = loader.Integration(
|
||||||
|
@ -597,6 +598,7 @@ def test_integration_properties(hass: HomeAssistant) -> None:
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert integration.is_built_in is False
|
assert integration.is_built_in is False
|
||||||
|
assert integration.overwrites_built_in is True
|
||||||
assert integration.homekit is None
|
assert integration.homekit is None
|
||||||
assert integration.zeroconf is None
|
assert integration.zeroconf is None
|
||||||
assert integration.dhcp is None
|
assert integration.dhcp is None
|
||||||
|
@ -619,6 +621,7 @@ def test_integration_properties(hass: HomeAssistant) -> None:
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert integration.is_built_in is False
|
assert integration.is_built_in is False
|
||||||
|
assert integration.overwrites_built_in is True
|
||||||
assert integration.homekit is None
|
assert integration.homekit is None
|
||||||
assert integration.zeroconf == [{"type": "_hue._tcp.local.", "name": "hue*"}]
|
assert integration.zeroconf == [{"type": "_hue._tcp.local.", "name": "hue*"}]
|
||||||
assert integration.dhcp is None
|
assert integration.dhcp is None
|
||||||
|
@ -828,6 +831,29 @@ async def test_get_custom_components(hass: HomeAssistant) -> None:
|
||||||
mock_get.assert_called_once_with(hass)
|
mock_get.assert_called_once_with(hass)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("enable_custom_integrations")
|
||||||
|
async def test_custom_component_overwriting_core(hass: HomeAssistant) -> None:
|
||||||
|
"""Test loading a custom component that overwrites a core component."""
|
||||||
|
# First load the core 'light' component
|
||||||
|
core_light = await loader.async_get_integration(hass, "light")
|
||||||
|
assert core_light.is_built_in is True
|
||||||
|
|
||||||
|
# create a mock custom 'light' component
|
||||||
|
mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule("light", partial_manifest={"version": "1.0.0"}),
|
||||||
|
built_in=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Try to load the 'light' component again
|
||||||
|
custom_light = await loader.async_get_integration(hass, "light")
|
||||||
|
|
||||||
|
# Assert that we got the custom component instead of the core one
|
||||||
|
assert custom_light.is_built_in is False
|
||||||
|
assert custom_light.overwrites_built_in is True
|
||||||
|
assert custom_light.version == "1.0.0"
|
||||||
|
|
||||||
|
|
||||||
async def test_get_config_flows(hass: HomeAssistant) -> None:
|
async def test_get_config_flows(hass: HomeAssistant) -> None:
|
||||||
"""Verify that custom components with config_flow are available."""
|
"""Verify that custom components with config_flow are available."""
|
||||||
test_1_integration = _get_test_integration(hass, "test_1", False)
|
test_1_integration = _get_test_integration(hass, "test_1", False)
|
||||||
|
|
Loading…
Add table
Reference in a new issue