Add get_account service to Mastodon (#161930)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
Andrew Jackson
2026-02-15 11:59:34 +01:00
committed by GitHub
co-authored by Copilot Norbert Rittel
parent 49689ad677
commit 2850192068
9 changed files with 280 additions and 81 deletions
+4 -1
View File
@@ -39,7 +39,10 @@ def mock_mastodon_client() -> Generator[AsyncMock]:
load_fixture("instance.json", DOMAIN)
)
client.account_verify_credentials.return_value = Account.from_json(
load_fixture("account_verify_credentials.json", DOMAIN)
load_fixture("account.json", DOMAIN)
)
client.account_lookup.return_value = Account.from_json(
load_fixture("account.json", DOMAIN)
)
client.mastodon_api_version = 2
client.status_post.return_value = None
@@ -0,0 +1,64 @@
# serializer version: 1
# name: test_get_account_success
dict({
'account': Account({
'id': 14715,
'username': 'trwnh',
'acct': 'trwnh',
'display_name': 'infinite love ⴳ',
'discoverable': True,
'group': False,
'locked': False,
'created_at': datetime.datetime(2016, 11, 24, 0, 0, tzinfo=tzlocal()),
'following_count': 328,
'followers_count': 3169,
'statuses_count': 69523,
'note': '<p>i have approximate knowledge of many things. perpetual student. (nb/ace/they)</p><p>xmpp/email: a@trwnh.com<br /><a href="https://trwnh.com" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">trwnh.com</span><span class="invisible"></span></a><br />help me live:<br />- <a href="https://donate.stripe.com/4gwcPCaMpcQ19RC4gg" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">donate.stripe.com/4gwcPCaMpcQ1</span><span class="invisible">9RC4gg</span></a><br />- <a href="https://liberapay.com/trwnh" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">liberapay.com/trwnh</span><span class="invisible"></span></a></p><p>notes:<br />- my triggers are moths and glitter<br />- i have all notifs except mentions turned off, so please interact if you wanna be friends! i literally will not notice otherwise<br />- dm me if i did something wrong, so i can improve<br />- purest person on fedi, do not lewd in my presence</p>',
'url': 'https://mastodon.social/@trwnh',
'uri': 'https://mastodon.social/users/trwnh',
'avatar': 'https://files.mastodon.social/accounts/avatars/000/014/715/original/051c958388818705.png',
'header': 'https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg',
'avatar_static': 'https://files.mastodon.social/accounts/avatars/000/014/715/original/051c958388818705.png',
'header_static': 'https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg',
'moved': None,
'suspended': None,
'limited': None,
'bot': True,
'fields': NonPaginatableList([
AccountField({
'name': 'Website',
'value': '<a href="https://trwnh.com" target="_blank" rel="nofollow noopener me" translate="no"><span class="invisible">https://</span><span class="">trwnh.com</span><span class="invisible"></span></a>',
'verified_at': '2019-08-29T04:14:55.571+00:00',
}),
AccountField({
'name': 'Portfolio',
'value': '<a href="https://abdullahtarawneh.com" target="_blank" rel="nofollow noopener me" translate="no"><span class="invisible">https://</span><span class="">abdullahtarawneh.com</span><span class="invisible"></span></a>',
'verified_at': '2021-02-11T20:34:13.574+00:00',
}),
AccountField({
'name': 'Fan of:',
'value': 'Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo&#39;s Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)',
'verified_at': None,
}),
AccountField({
'name': 'What to expect:',
'value': 'talking about various things i find interesting, and otherwise being a genuine and decent wholesome poster. i&#39;m just here to hang out and talk to cool people! and to spill my thoughts.',
'verified_at': None,
}),
]),
'emojis': NonPaginatableList([
]),
'last_status_at': datetime.datetime(2025, 3, 4, 0, 0),
'noindex': False,
'roles': NonPaginatableList([
]),
'role': None,
'source': None,
'mute_expires_at': None,
'indexable': False,
'hide_collections': True,
'memorial': None,
'moved_to_account': None,
}),
})
# ---
+55 -1
View File
@@ -4,8 +4,10 @@ from unittest.mock import AsyncMock, Mock, patch
from mastodon.Mastodon import MastodonAPIError, MediaAttachment
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.mastodon.const import (
ATTR_ACCOUNT_NAME,
ATTR_CONTENT_WARNING,
ATTR_IDEMPOTENCY_KEY,
ATTR_LANGUAGE,
@@ -15,7 +17,7 @@ from homeassistant.components.mastodon.const import (
ATTR_VISIBILITY,
DOMAIN,
)
from homeassistant.components.mastodon.services import SERVICE_POST
from homeassistant.components.mastodon.services import SERVICE_GET_ACCOUNT, SERVICE_POST
from homeassistant.const import ATTR_CONFIG_ENTRY_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
@@ -25,6 +27,58 @@ from . import setup_integration
from tests.common import MockConfigEntry
async def test_get_account_success(
hass: HomeAssistant,
mock_mastodon_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the get_account service successfully returns account data."""
await setup_integration(hass, mock_config_entry)
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_ACCOUNT,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_ACCOUNT_NAME: "@trwnh@mastodon.social",
},
blocking=True,
return_response=True,
)
assert response == snapshot
mock_mastodon_client.account_lookup.assert_called_once_with(
acct="@trwnh@mastodon.social"
)
async def test_get_account_failure(
hass: HomeAssistant,
mock_mastodon_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the get_account service handles API errors."""
await setup_integration(hass, mock_config_entry)
# Test API error (this is the only error type currently caught by the service)
mock_mastodon_client.account_lookup.side_effect = MastodonAPIError("API error")
with pytest.raises(
HomeAssistantError,
match='Unable to get account "@test@mastodon.social"',
):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_ACCOUNT,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_ACCOUNT_NAME: "@test@mastodon.social",
},
blocking=True,
return_response=True,
)
@pytest.mark.parametrize(
("payload", "kwargs"),
[