mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Set xuid as unique_id and gamertag as title in Xbox config flow (#154693)
This commit is contained in:
@@ -54,6 +54,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> bool
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
await async_migrate_unique_id(hass, entry)
|
||||
return True
|
||||
|
||||
|
||||
@@ -61,3 +62,28 @@ async def async_unload_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> boo
|
||||
"""Unload a config entry."""
|
||||
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_migrate_unique_id(hass: HomeAssistant, entry: XboxConfigEntry) -> bool:
|
||||
"""Migrate config entry.
|
||||
|
||||
Migration requires runtime data
|
||||
"""
|
||||
|
||||
if entry.version == 1 and entry.minor_version < 2:
|
||||
# Migrate unique_id from `xbox` to account xuid and
|
||||
# change generic entry name to user's gamertag
|
||||
return hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
unique_id=entry.runtime_data.client.xuid,
|
||||
title=(
|
||||
entry.runtime_data.data.presence[
|
||||
entry.runtime_data.client.xuid
|
||||
].gamertag
|
||||
if entry.title == "Home Assistant Cloud"
|
||||
else entry.title
|
||||
),
|
||||
minor_version=2,
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from xbox.webapi.api.client import XboxLiveClient
|
||||
from xbox.webapi.authentication.manager import AuthenticationManager
|
||||
from xbox.webapi.authentication.models import OAuth2TokenResponse
|
||||
from xbox.webapi.common.signed_session import SignedSession
|
||||
|
||||
from homeassistant.config_entries import ConfigFlowResult
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
|
||||
@@ -16,6 +21,8 @@ class OAuth2FlowHandler(
|
||||
|
||||
DOMAIN = DOMAIN
|
||||
|
||||
MINOR_VERSION = 2
|
||||
|
||||
@property
|
||||
def logger(self) -> logging.Logger:
|
||||
"""Return logger."""
|
||||
@@ -31,9 +38,23 @@ class OAuth2FlowHandler(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow start."""
|
||||
await self.async_set_unique_id(DOMAIN)
|
||||
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
return await super().async_step_user(user_input)
|
||||
|
||||
async def async_oauth_create_entry(self, data: dict) -> ConfigFlowResult:
|
||||
"""Create an entry for the flow."""
|
||||
|
||||
async with SignedSession() as session:
|
||||
auth = AuthenticationManager(session, "", "", "")
|
||||
auth.oauth = OAuth2TokenResponse(**data["token"])
|
||||
await auth.refresh_tokens()
|
||||
|
||||
client = XboxLiveClient(auth)
|
||||
|
||||
me = await client.people.get_friends_own_batch([client.xuid])
|
||||
|
||||
await self.async_set_unique_id(client.xuid)
|
||||
return self.async_create_entry(title=me.people[0].gamertag, data=data)
|
||||
|
||||
@@ -65,17 +65,36 @@ def mock_config_entry() -> MockConfigEntry:
|
||||
"user_id": "AAAAAAAAAAAAAAAAAAAAA",
|
||||
},
|
||||
},
|
||||
unique_id="xbox",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="authentication_manager")
|
||||
def mock_authentication_manager() -> Generator[AsyncMock]:
|
||||
"""Mock xbox-webapi AuthenticationManager."""
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.xbox.config_flow.AuthenticationManager",
|
||||
autospec=True,
|
||||
) as mock_client,
|
||||
):
|
||||
client = mock_client.return_value
|
||||
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.fixture(name="signed_session")
|
||||
def mock_signed_session() -> Generator[AsyncMock]:
|
||||
"""Mock xbox-webapi SignedSession."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xbox.SignedSession", autospec=True
|
||||
) as mock_client:
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.xbox.SignedSession", autospec=True
|
||||
) as mock_client,
|
||||
patch(
|
||||
"homeassistant.components.xbox.config_flow.SignedSession", new=mock_client
|
||||
),
|
||||
):
|
||||
client = mock_client.return_value
|
||||
|
||||
yield client
|
||||
@@ -85,9 +104,14 @@ def mock_signed_session() -> Generator[AsyncMock]:
|
||||
def mock_xbox_live_client(signed_session) -> Generator[AsyncMock]:
|
||||
"""Mock xbox-webapi XboxLiveClient."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xbox.XboxLiveClient", autospec=True
|
||||
) as mock_client:
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.xbox.XboxLiveClient", autospec=True
|
||||
) as mock_client,
|
||||
patch(
|
||||
"homeassistant.components.xbox.config_flow.XboxLiveClient", new=mock_client
|
||||
),
|
||||
):
|
||||
client = mock_client.return_value
|
||||
|
||||
client.smartglass = AsyncMock()
|
||||
@@ -110,4 +134,7 @@ def mock_xbox_live_client(signed_session) -> Generator[AsyncMock]:
|
||||
client.people.get_friends_own.return_value = PeopleResponse(
|
||||
**load_json_object_fixture("people_friends_own.json", DOMAIN)
|
||||
)
|
||||
|
||||
client.xuid = "271958441785640"
|
||||
|
||||
yield client
|
||||
|
||||
@@ -29,7 +29,11 @@ async def test_abort_if_existing_entry(hass: HomeAssistant) -> None:
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("current_request_with_host")
|
||||
@pytest.mark.usefixtures(
|
||||
"current_request_with_host",
|
||||
"xbox_live_client",
|
||||
"authentication_manager",
|
||||
)
|
||||
async def test_full_flow(
|
||||
hass: HomeAssistant,
|
||||
hass_client_no_auth: ClientSessionGenerator,
|
||||
@@ -68,13 +72,57 @@ async def test_full_flow(
|
||||
"access_token": "mock-access-token",
|
||||
"type": "Bearer",
|
||||
"expires_in": 60,
|
||||
"scope": "XboxLive.signin XboxLive.offline_access",
|
||||
"service": "xbox",
|
||||
"token_type": "bearer",
|
||||
"user_id": "AAAAAAAAAAAAAAAAAAAAA",
|
||||
},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xbox.async_setup_entry", return_value=True
|
||||
) as mock_setup:
|
||||
await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["result"].unique_id == "271958441785640"
|
||||
assert result["result"].title == "GSR Ae"
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
async def test_unique_id_migration(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test config entry unique_id migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home Assistant Cloud",
|
||||
data={
|
||||
"auth_implementation": "cloud",
|
||||
"token": {
|
||||
"access_token": "1234567890",
|
||||
"expires_at": 1760697327.7298331,
|
||||
"expires_in": 3600,
|
||||
"refresh_token": "0987654321",
|
||||
"scope": "XboxLive.signin XboxLive.offline_access",
|
||||
"service": "xbox",
|
||||
"token_type": "bearer",
|
||||
"user_id": "AAAAAAAAAAAAAAAAAAAAA",
|
||||
},
|
||||
},
|
||||
unique_id=DOMAIN,
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is config_entries.ConfigEntryState.LOADED
|
||||
assert config_entry.version == 1
|
||||
assert config_entry.minor_version == 2
|
||||
assert config_entry.unique_id == "271958441785640"
|
||||
assert config_entry.title == "GSR Ae"
|
||||
|
||||
Reference in New Issue
Block a user