This commit is contained in:
Franck Nijhof
2026-07-24 09:31:32 +02:00
committed by GitHub
14 changed files with 166 additions and 94 deletions
@@ -8,7 +8,7 @@
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pybravia"],
"requirements": ["pybravia==0.4.1"],
"requirements": ["pybravia==0.5.1"],
"ssdp": [
{
"manufacturer": "Sony Corporation",
@@ -79,7 +79,9 @@ async def _get_fixture_collection(envoy: Envoy, serial: str) -> dict[str, Any]:
try:
response: ClientResponse = await envoy.request(end_point)
fixture_data[end_point] = (
(await response.text()).replace("\n", "").replace(serial, CLEAN_TEXT)
(await response.text(errors="replace"))
.replace("\n", "")
.replace(serial, CLEAN_TEXT)
)
fixture_data[f"{end_point}_log"] = json_dumps(
{
@@ -37,5 +37,5 @@
"iot_class": "cloud_push",
"loggers": ["pylamarzocco"],
"quality_scale": "platinum",
"requirements": ["pylamarzocco==2.4.2"]
"requirements": ["pylamarzocco==2.4.3"]
}
@@ -193,9 +193,9 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ProxmoxConfigEntry) ->
if "@" in data.get(CONF_USERNAME, ""):
username, realm = data[CONF_USERNAME].split("@", 1)
data[CONF_USERNAME] = username
data[CONF_REALM] = realm.lower()
data[CONF_REALM] = realm
realm = data[CONF_REALM].lower()
realm = data[CONF_REALM]
# If the realm is one of the base providers,
# set the provider to match the realm.
+1 -1
View File
@@ -16,7 +16,7 @@ def sanitize_config_entry(input_data: Mapping[str, Any]) -> dict[str, Any]:
realm = provider.lower()
if provider == AUTH_OTHER:
realm = data[CONF_REALM].lower()
realm = data[CONF_REALM]
data[CONF_REALM] = realm
data[CONF_USERNAME] = f"{username}@{realm}"
+1 -1
View File
@@ -10,5 +10,5 @@
"iot_class": "cloud_push",
"loggers": ["yoto_api"],
"quality_scale": "platinum",
"requirements": ["yoto-api==4.3.1"]
"requirements": ["yoto-api==4.3.2"]
}
+1 -1
View File
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
APPLICATION_NAME: Final = "HomeAssistant"
MAJOR_VERSION: Final = 2026
MINOR_VERSION: Final = 7
PATCH_VERSION: Final = "3"
PATCH_VERSION: Final = "4"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 14, 2)
+2 -2
View File
@@ -6,7 +6,7 @@ aiodns==4.0.4
aiogithubapi==26.0.0
aiohttp-asyncmdnsresolver==0.2.0
aiohttp-fast-zlib==0.3.0
aiohttp==3.14.1
aiohttp==3.14.3
aiohttp_cors==0.8.1
aiousbwatcher==1.1.2
aiozoneinfo==0.2.3
@@ -75,7 +75,7 @@ voluptuous-openapi==0.4.1
voluptuous-serialize==2.7.0
voluptuous==0.15.2
webrtc-models==0.3.0
yarl==1.24.2
yarl==1.24.5
zeroconf==0.150.0
# Constrain pycryptodome to avoid vulnerability
+3 -3
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "homeassistant"
version = "2026.7.3"
version = "2026.7.4"
license = "Apache-2.0"
license-files = ["LICENSE*", "homeassistant/backports/LICENSE*"]
description = "Open-source home automation platform running on Python 3."
@@ -28,7 +28,7 @@ dependencies = [
# module level in `bootstrap.py` and its requirements thus need to be in
# requirements.txt to ensure they are always installed
"aiogithubapi==26.0.0",
"aiohttp==3.14.1",
"aiohttp==3.14.3",
"aiohttp_cors==0.8.1",
"aiohttp-fast-zlib==0.3.0",
"aiohttp-asyncmdnsresolver==0.2.0",
@@ -78,7 +78,7 @@ dependencies = [
"voluptuous==0.15.2",
"voluptuous-serialize==2.7.0",
"voluptuous-openapi==0.4.1",
"yarl==1.24.2",
"yarl==1.24.5",
"webrtc-models==0.3.0",
"zeroconf==0.150.0",
]
+2 -2
View File
@@ -7,7 +7,7 @@ aiodns==4.0.4
aiogithubapi==26.0.0
aiohttp-asyncmdnsresolver==0.2.0
aiohttp-fast-zlib==0.3.0
aiohttp==3.14.1
aiohttp==3.14.3
aiohttp_cors==0.8.1
aiozoneinfo==0.2.3
annotatedyaml==1.0.2
@@ -60,5 +60,5 @@ voluptuous-openapi==0.4.1
voluptuous-serialize==2.7.0
voluptuous==0.15.2
webrtc-models==0.3.0
yarl==1.24.2
yarl==1.24.5
zeroconf==0.150.0
+3 -3
View File
@@ -2048,7 +2048,7 @@ pyblu==2.0.8
pybotvac==0.0.29
# homeassistant.components.braviatv
pybravia==0.4.1
pybravia==0.5.1
# homeassistant.components.nissan_leaf
pycarwings2==2.14
@@ -2298,7 +2298,7 @@ pykwb==0.0.8
pylacrosse==0.4
# homeassistant.components.lamarzocco
pylamarzocco==2.4.2
pylamarzocco==2.4.3
# homeassistant.components.lastfm
pylast==5.1.0
@@ -3414,7 +3414,7 @@ yeelightsunflower==0.0.10
yolink-api==0.6.5
# homeassistant.components.yoto
yoto-api==4.3.1
yoto-api==4.3.2
# homeassistant.components.youless
youless-api==2.2.0
+4 -4
View File
@@ -64,8 +64,8 @@ MOCK_TEST_TOKEN_CONFIG = {
MOCK_TEST_OTHER_CONFIG = {
**MOCK_TEST_CONFIG,
CONF_AUTH_METHOD: "other",
CONF_REALM: "test_realm",
CONF_USERNAME: "test_user@test_realm",
CONF_REALM: "Test_Realm",
CONF_USERNAME: "test_user@Test_Realm",
}
MOCK_TEST_TOKEN_OTHER_CONFIG = {
@@ -74,8 +74,8 @@ MOCK_TEST_TOKEN_OTHER_CONFIG = {
CONF_TOKEN_ID: "test_token_id",
CONF_TOKEN_SECRET: "test_token_secret",
CONF_AUTH_METHOD: "other",
CONF_REALM: "test_realm",
CONF_USERNAME: "test_user@test_realm",
CONF_REALM: "Test_Realm",
CONF_USERNAME: "test_user@Test_Realm",
}
@@ -75,7 +75,7 @@ MOCK_USER_STEP_OTHER = {
MOCK_USER_AUTH_STEP_OTHER = {
**MOCK_USER_AUTH_STEP_PASSWORD,
CONF_REALM: "test_realm",
CONF_REALM: "Test_Realm",
}
# Other authentication method with realm and token
@@ -86,7 +86,7 @@ MOCK_USER_STEP_OTHER_TOKEN = {
MOCK_USER_AUTH_STEP_OTHER_TOKEN = {
**MOCK_USER_AUTH_STEP_TOKEN,
CONF_REALM: "test_realm",
CONF_REALM: "Test_Realm",
}
MOCK_USER_SETUP = {CONF_NODES: ["pve1"]}
@@ -724,7 +724,7 @@ async def test_full_flow_reauth_token_other(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_REALM: "test_realm",
CONF_REALM: "Test_Realm",
CONF_TOKEN_ID: "test_token_id",
CONF_TOKEN_SECRET: "new_token_secret",
},
+139 -69
View File
@@ -9,6 +9,7 @@ import requests
from requests.exceptions import ConnectTimeout, SSLError
from homeassistant.components.proxmoxve.const import (
AUTH_OTHER,
AUTH_PAM,
CONF_AUTH_METHOD,
CONF_CONTAINERS,
@@ -165,25 +166,56 @@ async def test_setup_exceptions(
assert mock_config_entry.state is expected_state
@pytest.mark.parametrize(
("mock_config_entry", "expected_auth_method", "expected_realm"),
[
(
MockConfigEntry(
domain=DOMAIN,
version=1,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "pam",
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_PAM,
"pam",
),
(
MockConfigEntry(
domain=DOMAIN,
version=1,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "Test_Realm",
CONF_USERNAME: "test_user@Test_Realm",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_OTHER,
"Test_Realm",
),
],
)
async def test_migration_v1_to_v3(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
device_registry: dr.DeviceRegistry,
mock_config_entry: MockConfigEntry,
expected_auth_method: str,
expected_realm: str,
) -> None:
"""Test migration from version 1."""
entry = MockConfigEntry(
domain=DOMAIN,
version=1,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "pam",
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
)
"""Test migration from version 1 to 3."""
entry = mock_config_entry
entry.add_to_hass(hass)
assert entry.version == 1
@@ -227,6 +259,8 @@ async def test_migration_v1_to_v3(
await hass.async_block_till_done()
assert entry.version == 3
assert entry.data[CONF_AUTH_METHOD] == expected_auth_method
assert entry.data[CONF_REALM] == expected_realm
vm_entity_after = entity_registry.async_get(vm_entity.entity_id)
container_entity_after = entity_registry.async_get(container_entity.entity_id)
@@ -235,6 +269,97 @@ async def test_migration_v1_to_v3(
assert container_entity_after.unique_id == f"{entry.entry_id}_200_status"
@pytest.mark.parametrize(
("mock_config_entry", "expected_auth_method", "expected_realm"),
[
(
MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "pam",
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_PAM,
"pam",
),
(
MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "Test_Realm",
CONF_USERNAME: "test_user@Test_Realm",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_OTHER,
"Test_Realm",
),
(
MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_PAM,
"pam",
),
(
MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_USERNAME: "test_user@Test_Realm",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
),
AUTH_OTHER,
"Test_Realm",
),
],
)
async def test_migration_v2_to_v3(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
expected_auth_method: str,
expected_realm: str,
) -> None:
"""Test migration from version 2 to 3."""
entry = mock_config_entry
entry.add_to_hass(hass)
assert entry.version == 2
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.version == 3
assert entry.data[CONF_AUTH_METHOD] == expected_auth_method
assert entry.data[CONF_REALM] == expected_realm
async def test_offline_node(
hass: HomeAssistant,
mock_proxmox_client: MagicMock,
@@ -253,61 +378,6 @@ async def test_offline_node(
assert state.state == STATE_OFF
async def test_migration_v2_to_v3(
hass: HomeAssistant,
) -> None:
"""Test migration from version 2 to 3."""
entry = MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_REALM: "pam",
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
)
entry.add_to_hass(hass)
assert entry.version == 2
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.version == 3
assert entry.data[CONF_AUTH_METHOD] == AUTH_PAM
assert entry.data[CONF_REALM] == AUTH_PAM
async def test_migration_v2_to_v3_without_realm(
hass: HomeAssistant,
) -> None:
"""Test migration from version 2 to 3."""
entry = MockConfigEntry(
domain=DOMAIN,
version=2,
unique_id="1",
data={
CONF_HOST: "http://test_host",
CONF_PORT: 8006,
CONF_USERNAME: "test_user@pam",
CONF_PASSWORD: "test_password",
CONF_VERIFY_SSL: True,
},
)
entry.add_to_hass(hass)
assert entry.version == 2
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.version == 3
assert entry.data[CONF_AUTH_METHOD] == AUTH_PAM
assert entry.data[CONF_REALM] == AUTH_PAM
async def test_new_vm_creates_entity(
hass: HomeAssistant,
mock_proxmox_client: MagicMock,