From b0ce92c15bffef3dae55cc6e59dae71f2c25d815 Mon Sep 17 00:00:00 2001 From: tomballgithub Date: Wed, 21 Jan 2026 19:54:12 -0600 Subject: [PATCH 1/4] Fix error when activity is provided, because it is a Dict not a List --- src/pythonxbox/api/provider/presence/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pythonxbox/api/provider/presence/models.py b/src/pythonxbox/api/provider/presence/models.py index 0fb766c..c7b2baf 100644 --- a/src/pythonxbox/api/provider/presence/models.py +++ b/src/pythonxbox/api/provider/presence/models.py @@ -32,7 +32,7 @@ class ActivityRecord(CamelCaseModel): class TitleRecord(CamelCaseModel): id: str | None = None name: str | None = None - activity: list[ActivityRecord] | None = None + activity: ActivityRecord | None = None lastModified: str | None = None placement: str | None = None state: str | None = None From baea0e4a5acf88bbdb237885b93143c5a971a18b Mon Sep 17 00:00:00 2001 From: tomballgithub Date: Thu, 22 Jan 2026 10:05:34 -0600 Subject: [PATCH 2/4] Add test to verify activity response doesn't break pydantic check --- tests/test_presence.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test_presence.py b/tests/test_presence.py index e7711a3..a6dc0d7 100644 --- a/tests/test_presence.py +++ b/tests/test_presence.py @@ -77,3 +77,36 @@ async def test_presence_own_set_fail( assert route.called assert not ret + +@pytest.mark.asyncio +async def test_presence_with_activity(respx_mock: MockRouter, xbl_client: XboxLiveClient) -> None: + custom_data = { + "xuid": "0123456789", + "state": "online", + "devices": [ + { + "type": "D", + "titles": [ + { + "id": "12341234", + "name": "Contoso 5", + "state": "active", + "placement": "fill", + "timestamp": "2012-09-17T07:15:23.4930000", + "activity": {"richPresence": "Team Deathmatch on Nirvana"} + } + ] + } + ] + } + + route = respx_mock.get("https://userpresence.xboxlive.com").mock( + return_value=Response(200, json=custom_data) + ) + + response = await xbl_client.presence.get_presence("0123456789") + + assert route.called + assert response.xuid == "0123456789" + assert response.devices[0].titles[0].activity.richPresence == "Team Deathmatch on Nirvana" + From ce03cdba82c10b2bd28796dc84a303da0da16bea Mon Sep 17 00:00:00 2001 From: tomballgithub Date: Thu, 22 Jan 2026 12:43:25 -0600 Subject: [PATCH 3/4] Use responses file to store json test information --- tests/test_presence.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tests/test_presence.py b/tests/test_presence.py index a6dc0d7..9472157 100644 --- a/tests/test_presence.py +++ b/tests/test_presence.py @@ -80,28 +80,9 @@ async def test_presence_own_set_fail( @pytest.mark.asyncio async def test_presence_with_activity(respx_mock: MockRouter, xbl_client: XboxLiveClient) -> None: - custom_data = { - "xuid": "0123456789", - "state": "online", - "devices": [ - { - "type": "D", - "titles": [ - { - "id": "12341234", - "name": "Contoso 5", - "state": "active", - "placement": "fill", - "timestamp": "2012-09-17T07:15:23.4930000", - "activity": {"richPresence": "Team Deathmatch on Nirvana"} - } - ] - } - ] - } route = respx_mock.get("https://userpresence.xboxlive.com").mock( - return_value=Response(200, json=custom_data) + return_value=Response(200, json=get_response_json("presence_activity")) ) response = await xbl_client.presence.get_presence("0123456789") From aa1814389b7ddfe910458e954c6a4ae32daf10c8 Mon Sep 17 00:00:00 2001 From: tomballgithub Date: Thu, 22 Jan 2026 12:43:43 -0600 Subject: [PATCH 4/4] Add additional json test file --- tests/data/responses/presence_activity.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/data/responses/presence_activity.json diff --git a/tests/data/responses/presence_activity.json b/tests/data/responses/presence_activity.json new file mode 100644 index 0000000..35375e4 --- /dev/null +++ b/tests/data/responses/presence_activity.json @@ -0,0 +1,20 @@ +{ + "xuid": "0123456789", + "state": "online", + "devices": [ + { + "type": "D", + "titles": [ + { + "id": "12341234", + "name": "Contoso 5", + "state": "active", + "placement": "fill", + "timestamp": "2012-09-17T07:15:23.4930000", + "activity": {"richPresence": "Team Deathmatch on Nirvana"} + } + ] + } + ] +} +