Improve coverage for LastFM (#93661)
* Improve coverage for LastFM * Improve tests * Improve tests
This commit is contained in:
parent
ca936d0b38
commit
b3a001996d
6 changed files with 291 additions and 134 deletions
|
@ -618,7 +618,6 @@ omit =
|
||||||
homeassistant/components/kwb/sensor.py
|
homeassistant/components/kwb/sensor.py
|
||||||
homeassistant/components/lacrosse/sensor.py
|
homeassistant/components/lacrosse/sensor.py
|
||||||
homeassistant/components/lannouncer/notify.py
|
homeassistant/components/lannouncer/notify.py
|
||||||
homeassistant/components/lastfm/sensor.py
|
|
||||||
homeassistant/components/launch_library/__init__.py
|
homeassistant/components/launch_library/__init__.py
|
||||||
homeassistant/components/launch_library/sensor.py
|
homeassistant/components/launch_library/sensor.py
|
||||||
homeassistant/components/lcn/climate.py
|
homeassistant/components/lcn/climate.py
|
||||||
|
|
|
@ -22,64 +22,83 @@ CONF_FRIENDS_DATA = {CONF_USERS: [USERNAME_2]}
|
||||||
class MockNetwork:
|
class MockNetwork:
|
||||||
"""Mock _Network object for pylast."""
|
"""Mock _Network object for pylast."""
|
||||||
|
|
||||||
def __init__(self, username: str):
|
def __init__(self, username: str) -> None:
|
||||||
"""Initialize the mock."""
|
"""Initialize the mock."""
|
||||||
self.username = username
|
self.username = username
|
||||||
|
|
||||||
|
|
||||||
|
class MockTopTrack:
|
||||||
|
"""Mock TopTrack object for pylast."""
|
||||||
|
|
||||||
|
def __init__(self, item: Track) -> None:
|
||||||
|
"""Initialize the mock."""
|
||||||
|
self.item = item
|
||||||
|
|
||||||
|
|
||||||
|
class MockLastTrack:
|
||||||
|
"""Mock LastTrack object for pylast."""
|
||||||
|
|
||||||
|
def __init__(self, track: Track) -> None:
|
||||||
|
"""Initialize the mock."""
|
||||||
|
self.track = track
|
||||||
|
|
||||||
|
|
||||||
class MockUser:
|
class MockUser:
|
||||||
"""Mock User object for pylast."""
|
"""Mock User object for pylast."""
|
||||||
|
|
||||||
def __init__(self, now_playing_result, error, has_friends, username):
|
def __init__(
|
||||||
|
self,
|
||||||
|
username: str = USERNAME_1,
|
||||||
|
now_playing_result: Track | None = None,
|
||||||
|
thrown_error: Exception | None = None,
|
||||||
|
friends: list = [],
|
||||||
|
recent_tracks: list[Track] = [],
|
||||||
|
top_tracks: list[Track] = [],
|
||||||
|
) -> None:
|
||||||
"""Initialize the mock."""
|
"""Initialize the mock."""
|
||||||
self._now_playing_result = now_playing_result
|
self._now_playing_result = now_playing_result
|
||||||
self._thrown_error = error
|
self._thrown_error = thrown_error
|
||||||
self._has_friends = has_friends
|
self._friends = friends
|
||||||
|
self._recent_tracks = recent_tracks
|
||||||
|
self._top_tracks = top_tracks
|
||||||
self.name = username
|
self.name = username
|
||||||
|
|
||||||
def get_name(self, capitalized: bool) -> str:
|
def get_name(self, capitalized: bool) -> str:
|
||||||
"""Get name of the user."""
|
"""Get name of the user."""
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_playcount(self):
|
def get_playcount(self) -> int:
|
||||||
"""Get mock play count."""
|
"""Get mock play count."""
|
||||||
if self._thrown_error:
|
if self._thrown_error:
|
||||||
raise self._thrown_error
|
raise self._thrown_error
|
||||||
return 1
|
return len(self._recent_tracks)
|
||||||
|
|
||||||
def get_image(self):
|
def get_image(self) -> str:
|
||||||
"""Get mock image."""
|
"""Get mock image."""
|
||||||
|
return ""
|
||||||
|
|
||||||
def get_recent_tracks(self, limit):
|
def get_recent_tracks(self, limit: int) -> list[MockLastTrack]:
|
||||||
"""Get mock recent tracks."""
|
"""Get mock recent tracks."""
|
||||||
return []
|
return [MockLastTrack(track) for track in self._recent_tracks]
|
||||||
|
|
||||||
def get_top_tracks(self, limit):
|
def get_top_tracks(self, limit: int) -> list[MockTopTrack]:
|
||||||
"""Get mock top tracks."""
|
"""Get mock top tracks."""
|
||||||
return []
|
return [MockTopTrack(track) for track in self._recent_tracks]
|
||||||
|
|
||||||
def get_now_playing(self):
|
def get_now_playing(self) -> Track:
|
||||||
"""Get mock now playing."""
|
"""Get mock now playing."""
|
||||||
return self._now_playing_result
|
return self._now_playing_result
|
||||||
|
|
||||||
def get_friends(self):
|
def get_friends(self) -> list[any]:
|
||||||
"""Get mock friends."""
|
"""Get mock friends."""
|
||||||
if self._has_friends is False:
|
if len(self._friends) == 0:
|
||||||
raise PyLastError("network", "status", "Page not found")
|
raise PyLastError("network", "status", "Page not found")
|
||||||
return [MockUser(None, None, True, USERNAME_2)]
|
return self._friends
|
||||||
|
|
||||||
|
|
||||||
def patch_fetch_user(
|
def patch_user(user: MockUser) -> MockUser:
|
||||||
now_playing: Track | None = None,
|
|
||||||
thrown_error: Exception | None = None,
|
|
||||||
has_friends: bool = True,
|
|
||||||
username: str = USERNAME_1,
|
|
||||||
) -> MockUser:
|
|
||||||
"""Patch interface."""
|
"""Patch interface."""
|
||||||
return patch(
|
return patch("pylast.User", return_value=user)
|
||||||
"pylast.User",
|
|
||||||
return_value=MockUser(now_playing, thrown_error, has_friends, username),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def patch_setup_entry() -> bool:
|
def patch_setup_entry() -> bool:
|
||||||
|
|
67
tests/components/lastfm/conftest.py
Normal file
67
tests/components/lastfm/conftest.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
"""Configure tests for the LastFM integration."""
|
||||||
|
from collections.abc import Awaitable, Callable
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pylast import Track
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.lastfm.const import CONF_MAIN_USER, CONF_USERS, DOMAIN
|
||||||
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
from tests.components.lastfm import (
|
||||||
|
API_KEY,
|
||||||
|
USERNAME_1,
|
||||||
|
USERNAME_2,
|
||||||
|
MockNetwork,
|
||||||
|
MockUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
ComponentSetup = Callable[[MockConfigEntry, MockUser], Awaitable[None]]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="config_entry")
|
||||||
|
def mock_config_entry() -> MockConfigEntry:
|
||||||
|
"""Create LastFM entry in Home Assistant."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={},
|
||||||
|
options={
|
||||||
|
CONF_API_KEY: API_KEY,
|
||||||
|
CONF_MAIN_USER: USERNAME_1,
|
||||||
|
CONF_USERS: [USERNAME_1, USERNAME_2],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="setup_integration")
|
||||||
|
async def mock_setup_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
) -> Callable[[MockConfigEntry, MockUser], Awaitable[None]]:
|
||||||
|
"""Fixture for setting up the component."""
|
||||||
|
|
||||||
|
async def func(mock_config_entry: MockConfigEntry, mock_user: MockUser) -> None:
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
with patch("pylast.User", return_value=mock_user):
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="default_user")
|
||||||
|
def mock_default_user() -> MockUser:
|
||||||
|
"""Return default mock user."""
|
||||||
|
return MockUser(
|
||||||
|
now_playing_result=Track("artist", "title", MockNetwork("lastfm")),
|
||||||
|
top_tracks=[Track("artist", "title", MockNetwork("lastfm"))],
|
||||||
|
recent_tracks=[Track("artist", "title", MockNetwork("lastfm"))],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="first_time_user")
|
||||||
|
def mock_first_time_user() -> MockUser:
|
||||||
|
"""Return first time mock user."""
|
||||||
|
return MockUser(now_playing_result=None, top_tracks=[], recent_tracks=[])
|
|
@ -1,4 +1,6 @@
|
||||||
"""Test Lastfm config flow."""
|
"""Test Lastfm config flow."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from pylast import WSError
|
from pylast import WSError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -21,16 +23,17 @@ from . import (
|
||||||
CONF_USER_DATA,
|
CONF_USER_DATA,
|
||||||
USERNAME_1,
|
USERNAME_1,
|
||||||
USERNAME_2,
|
USERNAME_2,
|
||||||
patch_fetch_user,
|
MockUser,
|
||||||
patch_setup_entry,
|
patch_setup_entry,
|
||||||
)
|
)
|
||||||
|
from .conftest import ComponentSetup
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
async def test_full_user_flow(hass: HomeAssistant) -> None:
|
async def test_full_user_flow(hass: HomeAssistant, default_user: MockUser) -> None:
|
||||||
"""Test the full user configuration flow."""
|
"""Test the full user configuration flow."""
|
||||||
with patch_fetch_user(), patch_setup_entry():
|
with patch("pylast.User", return_value=default_user), patch_setup_entry():
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
|
@ -68,9 +71,11 @@ async def test_full_user_flow(hass: HomeAssistant) -> None:
|
||||||
(WSError("network", "status", "Something strange"), "unknown"),
|
(WSError("network", "status", "Something strange"), "unknown"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_flow_fails(hass: HomeAssistant, error: Exception, message: str) -> None:
|
async def test_flow_fails(
|
||||||
|
hass: HomeAssistant, error: Exception, message: str, default_user: MockUser
|
||||||
|
) -> None:
|
||||||
"""Test user initialized flow with invalid username."""
|
"""Test user initialized flow with invalid username."""
|
||||||
with patch_fetch_user(thrown_error=error):
|
with patch("pylast.User", return_value=MockUser(thrown_error=error)):
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONF_USER_DATA
|
DOMAIN, context={"source": SOURCE_USER}, data=CONF_USER_DATA
|
||||||
)
|
)
|
||||||
|
@ -78,7 +83,7 @@ async def test_flow_fails(hass: HomeAssistant, error: Exception, message: str) -
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"]["base"] == message
|
assert result["errors"]["base"] == message
|
||||||
|
|
||||||
with patch_fetch_user(), patch_setup_entry():
|
with patch("pylast.User", return_value=default_user), patch_setup_entry():
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input=CONF_USER_DATA,
|
user_input=CONF_USER_DATA,
|
||||||
|
@ -95,9 +100,11 @@ async def test_flow_fails(hass: HomeAssistant, error: Exception, message: str) -
|
||||||
assert result["options"] == CONF_DATA
|
assert result["options"] == CONF_DATA
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_friends_invalid_username(hass: HomeAssistant) -> None:
|
async def test_flow_friends_invalid_username(
|
||||||
|
hass: HomeAssistant, default_user: MockUser
|
||||||
|
) -> None:
|
||||||
"""Test user initialized flow with invalid username."""
|
"""Test user initialized flow with invalid username."""
|
||||||
with patch_fetch_user(), patch_setup_entry():
|
with patch("pylast.User", return_value=default_user), patch_setup_entry():
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
|
@ -109,7 +116,12 @@ async def test_flow_friends_invalid_username(hass: HomeAssistant) -> None:
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
assert result["step_id"] == "friends"
|
assert result["step_id"] == "friends"
|
||||||
|
|
||||||
with patch_fetch_user(thrown_error=WSError("network", "status", "User not found")):
|
with patch(
|
||||||
|
"pylast.User",
|
||||||
|
return_value=MockUser(
|
||||||
|
thrown_error=WSError("network", "status", "User not found")
|
||||||
|
),
|
||||||
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input=CONF_FRIENDS_DATA
|
result["flow_id"], user_input=CONF_FRIENDS_DATA
|
||||||
)
|
)
|
||||||
|
@ -117,7 +129,7 @@ async def test_flow_friends_invalid_username(hass: HomeAssistant) -> None:
|
||||||
assert result["step_id"] == "friends"
|
assert result["step_id"] == "friends"
|
||||||
assert result["errors"]["base"] == "invalid_account"
|
assert result["errors"]["base"] == "invalid_account"
|
||||||
|
|
||||||
with patch_fetch_user(), patch_setup_entry():
|
with patch("pylast.User", return_value=default_user), patch_setup_entry():
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input=CONF_FRIENDS_DATA
|
result["flow_id"], user_input=CONF_FRIENDS_DATA
|
||||||
)
|
)
|
||||||
|
@ -126,9 +138,11 @@ async def test_flow_friends_invalid_username(hass: HomeAssistant) -> None:
|
||||||
assert result["options"] == CONF_DATA
|
assert result["options"] == CONF_DATA
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_friends_no_friends(hass: HomeAssistant) -> None:
|
async def test_flow_friends_no_friends(
|
||||||
|
hass: HomeAssistant, default_user: MockUser
|
||||||
|
) -> None:
|
||||||
"""Test options is empty when user has no friends."""
|
"""Test options is empty when user has no friends."""
|
||||||
with patch_fetch_user(has_friends=False), patch_setup_entry():
|
with patch("pylast.User", return_value=default_user), patch_setup_entry():
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
|
@ -142,9 +156,9 @@ async def test_flow_friends_no_friends(hass: HomeAssistant) -> None:
|
||||||
assert len(result["data_schema"].schema[CONF_USERS].config["options"]) == 0
|
assert len(result["data_schema"].schema[CONF_USERS].config["options"]) == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_import_flow_success(hass: HomeAssistant) -> None:
|
async def test_import_flow_success(hass: HomeAssistant, default_user: MockUser) -> None:
|
||||||
"""Test import flow."""
|
"""Test import flow."""
|
||||||
with patch_fetch_user():
|
with patch("pylast.User", return_value=default_user):
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_IMPORT},
|
context={"source": SOURCE_IMPORT},
|
||||||
|
@ -160,16 +174,16 @@ async def test_import_flow_success(hass: HomeAssistant) -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_import_flow_already_exist(hass: HomeAssistant) -> None:
|
async def test_import_flow_already_exist(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test import of yaml already exist."""
|
"""Test import of yaml already exist."""
|
||||||
|
await setup_integration(config_entry, default_user)
|
||||||
|
|
||||||
MockConfigEntry(
|
with patch("pylast.User", return_value=default_user):
|
||||||
domain=DOMAIN,
|
|
||||||
data={},
|
|
||||||
options={CONF_API_KEY: API_KEY, CONF_USERS: ["test"]},
|
|
||||||
).add_to_hass(hass)
|
|
||||||
|
|
||||||
with patch_fetch_user():
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_IMPORT},
|
context={"source": SOURCE_IMPORT},
|
||||||
|
@ -181,20 +195,16 @@ async def test_import_flow_already_exist(hass: HomeAssistant) -> None:
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow(hass: HomeAssistant) -> None:
|
async def test_options_flow(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test updating options."""
|
"""Test updating options."""
|
||||||
entry = MockConfigEntry(
|
await setup_integration(config_entry, default_user)
|
||||||
domain=DOMAIN,
|
with patch("pylast.User", return_value=default_user):
|
||||||
data={},
|
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
options={
|
|
||||||
CONF_API_KEY: API_KEY,
|
|
||||||
CONF_MAIN_USER: USERNAME_1,
|
|
||||||
CONF_USERS: [USERNAME_1, USERNAME_2],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user():
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -215,27 +225,28 @@ async def test_options_flow(hass: HomeAssistant) -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow_incorrect_username(hass: HomeAssistant) -> None:
|
async def test_options_flow_incorrect_username(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test updating options doesn't work with incorrect username."""
|
"""Test updating options doesn't work with incorrect username."""
|
||||||
entry = MockConfigEntry(
|
await setup_integration(config_entry, default_user)
|
||||||
domain=DOMAIN,
|
with patch("pylast.User", return_value=default_user):
|
||||||
data={},
|
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
options={
|
|
||||||
CONF_API_KEY: API_KEY,
|
|
||||||
CONF_MAIN_USER: USERNAME_1,
|
|
||||||
CONF_USERS: [USERNAME_1],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user():
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
assert result["step_id"] == "init"
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
with patch_fetch_user(thrown_error=WSError("network", "status", "User not found")):
|
with patch(
|
||||||
|
"pylast.User",
|
||||||
|
return_value=MockUser(
|
||||||
|
thrown_error=WSError("network", "status", "User not found")
|
||||||
|
),
|
||||||
|
):
|
||||||
result = await hass.config_entries.options.async_configure(
|
result = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={CONF_USERS: [USERNAME_1]},
|
user_input={CONF_USERS: [USERNAME_1]},
|
||||||
|
@ -246,7 +257,7 @@ async def test_options_flow_incorrect_username(hass: HomeAssistant) -> None:
|
||||||
assert result["step_id"] == "init"
|
assert result["step_id"] == "init"
|
||||||
assert result["errors"]["base"] == "invalid_account"
|
assert result["errors"]["base"] == "invalid_account"
|
||||||
|
|
||||||
with patch_fetch_user():
|
with patch("pylast.User", return_value=default_user):
|
||||||
result = await hass.config_entries.options.async_configure(
|
result = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={CONF_USERS: [USERNAME_1]},
|
user_input={CONF_USERS: [USERNAME_1]},
|
||||||
|
@ -261,20 +272,16 @@ async def test_options_flow_incorrect_username(hass: HomeAssistant) -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow_from_import(hass: HomeAssistant) -> None:
|
async def test_options_flow_from_import(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test updating options gained from import."""
|
"""Test updating options gained from import."""
|
||||||
entry = MockConfigEntry(
|
await setup_integration(config_entry, default_user)
|
||||||
domain=DOMAIN,
|
with patch("pylast.User", return_value=default_user):
|
||||||
data={},
|
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
options={
|
|
||||||
CONF_API_KEY: API_KEY,
|
|
||||||
CONF_MAIN_USER: None,
|
|
||||||
CONF_USERS: [USERNAME_1],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user():
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -283,20 +290,16 @@ async def test_options_flow_from_import(hass: HomeAssistant) -> None:
|
||||||
assert len(result["data_schema"].schema[CONF_USERS].config["options"]) == 0
|
assert len(result["data_schema"].schema[CONF_USERS].config["options"]) == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow_without_friends(hass: HomeAssistant) -> None:
|
async def test_options_flow_without_friends(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test updating options for someone without friends."""
|
"""Test updating options for someone without friends."""
|
||||||
entry = MockConfigEntry(
|
await setup_integration(config_entry, default_user)
|
||||||
domain=DOMAIN,
|
with patch("pylast.User", return_value=default_user):
|
||||||
data={},
|
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
options={
|
|
||||||
CONF_API_KEY: API_KEY,
|
|
||||||
CONF_MAIN_USER: USERNAME_1,
|
|
||||||
CONF_USERS: [USERNAME_1],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user(has_friends=False):
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,24 @@
|
||||||
"""Test LastFM component setup process."""
|
"""Test LastFM component setup process."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from homeassistant.components.lastfm.const import CONF_MAIN_USER, CONF_USERS, DOMAIN
|
from homeassistant.components.lastfm.const import DOMAIN
|
||||||
from homeassistant.const import CONF_API_KEY
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import USERNAME_1, USERNAME_2, patch_fetch_user
|
from . import MockUser
|
||||||
|
from .conftest import ComponentSetup
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
async def test_load_unload_entry(hass: HomeAssistant) -> None:
|
async def test_load_unload_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test load and unload entry."""
|
"""Test load and unload entry."""
|
||||||
entry = MockConfigEntry(
|
await setup_integration(config_entry, default_user)
|
||||||
domain=DOMAIN,
|
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
data={},
|
|
||||||
options={
|
|
||||||
CONF_API_KEY: "12345678",
|
|
||||||
CONF_MAIN_USER: [USERNAME_1],
|
|
||||||
CONF_USERS: [USERNAME_1, USERNAME_2],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user():
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.testaccount1")
|
state = hass.states.get("sensor.testaccount1")
|
||||||
assert state
|
assert state
|
||||||
|
|
|
@ -1,22 +1,92 @@
|
||||||
"""Tests for the lastfm sensor."""
|
"""Tests for the lastfm sensor."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from pylast import Track
|
from pylast import WSError
|
||||||
|
|
||||||
from homeassistant.components.lastfm.const import DOMAIN, STATE_NOT_SCROBBLING
|
from homeassistant.components.lastfm.const import (
|
||||||
|
ATTR_LAST_PLAYED,
|
||||||
|
ATTR_PLAY_COUNT,
|
||||||
|
ATTR_TOP_PLAYED,
|
||||||
|
CONF_USERS,
|
||||||
|
DOMAIN,
|
||||||
|
STATE_NOT_SCROBBLING,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.const import CONF_API_KEY, CONF_PLATFORM, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import issue_registry as ir
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from . import CONF_DATA, MockNetwork, patch_fetch_user
|
from . import API_KEY, USERNAME_1, MockUser
|
||||||
|
from .conftest import ComponentSetup
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
LEGACY_CONFIG = {
|
||||||
|
Platform.SENSOR: [
|
||||||
|
{CONF_PLATFORM: DOMAIN, CONF_API_KEY: API_KEY, CONF_USERS: [USERNAME_1]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
async def test_update_not_playing(hass: HomeAssistant) -> None:
|
|
||||||
"""Test update when no playing song."""
|
async def test_legacy_migration(hass: HomeAssistant) -> None:
|
||||||
entry = MockConfigEntry(domain=DOMAIN, data={}, options=CONF_DATA)
|
"""Test migration from yaml to config flow."""
|
||||||
entry.add_to_hass(hass)
|
with patch("pylast.User", return_value=None):
|
||||||
with patch_fetch_user(None):
|
assert await async_setup_component(hass, Platform.SENSOR, LEGACY_CONFIG)
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert len(entries) == 1
|
||||||
|
assert entries[0].state is ConfigEntryState.LOADED
|
||||||
|
issue_registry = ir.async_get(hass)
|
||||||
|
assert len(issue_registry.issues) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_user_unavailable(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test update when user can't be fetched."""
|
||||||
|
await setup_integration(
|
||||||
|
config_entry,
|
||||||
|
MockUser(thrown_error=WSError("network", "status", "User not found")),
|
||||||
|
)
|
||||||
|
|
||||||
|
entity_id = "sensor.testaccount1"
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_first_time_user(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
first_time_user: MockUser,
|
||||||
|
) -> None:
|
||||||
|
"""Test first time user."""
|
||||||
|
await setup_integration(config_entry, first_time_user)
|
||||||
|
|
||||||
|
entity_id = "sensor.testaccount1"
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
|
||||||
|
assert state.state == STATE_NOT_SCROBBLING
|
||||||
|
assert state.attributes[ATTR_LAST_PLAYED] is None
|
||||||
|
assert state.attributes[ATTR_TOP_PLAYED] is None
|
||||||
|
assert state.attributes[ATTR_PLAY_COUNT] == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_update_not_playing(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
first_time_user: MockUser,
|
||||||
|
) -> None:
|
||||||
|
"""Test update when no playing song."""
|
||||||
|
await setup_integration(config_entry, first_time_user)
|
||||||
|
|
||||||
entity_id = "sensor.testaccount1"
|
entity_id = "sensor.testaccount1"
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
|
@ -24,15 +94,20 @@ async def test_update_not_playing(hass: HomeAssistant) -> None:
|
||||||
assert state.state == STATE_NOT_SCROBBLING
|
assert state.state == STATE_NOT_SCROBBLING
|
||||||
|
|
||||||
|
|
||||||
async def test_update_playing(hass: HomeAssistant) -> None:
|
async def test_update_playing(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration: ComponentSetup,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
default_user: MockUser,
|
||||||
|
) -> None:
|
||||||
"""Test update when playing a song."""
|
"""Test update when playing a song."""
|
||||||
entry = MockConfigEntry(domain=DOMAIN, data={}, options=CONF_DATA)
|
await setup_integration(config_entry, default_user)
|
||||||
entry.add_to_hass(hass)
|
|
||||||
with patch_fetch_user(Track("artist", "title", MockNetwork("test"))):
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
entity_id = "sensor.testaccount1"
|
entity_id = "sensor.testaccount1"
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
|
|
||||||
assert state.state == "artist - title"
|
assert state.state == "artist - title"
|
||||||
|
assert state.attributes[ATTR_LAST_PLAYED] == "artist - title"
|
||||||
|
assert state.attributes[ATTR_TOP_PLAYED] == "artist - title"
|
||||||
|
assert state.attributes[ATTR_PLAY_COUNT] == 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue