Skip to content

Commit

Permalink
refactor from integration testing
Browse files Browse the repository at this point in the history
  • Loading branch information
fcusson committed Dec 14, 2024
1 parent 94c74f2 commit 85c2231
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 85 deletions.
8 changes: 8 additions & 0 deletions custom_components/spotcast/spotify/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ def select_image_url(images: list[dict]) -> str:

for image in images:

width = image.get("width")
height = image.get("height")

# assume top image best fit when no size provided
if any(x is None for x in (width, height)):
image_url = image["url"]
break

area = image["width"] * image["height"]

if area > max_area:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/spotcast/websocket/search_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
vol.Required("type"): ENDPOINT,
vol.Required("query"): cv.string,
# Playlist or song, default playlist
vol.Optional("searchType"): cv.string,
vol.Optional("search_type"): cv.string,
vol.Optional("limit"): cv.positive_int,
vol.Optional("account"): cv.string,
}
Expand All @@ -42,7 +42,7 @@ async def async_search_handler(
"""
account_id = msg.get("account")
query = msg.get("query")
search_type = msg.get("searchType", "playlist")
search_type = msg.get("search_type", "playlist")
limit = msg.get("limit", 10)

account = await async_get_account(hass, account_id)
Expand Down
2 changes: 1 addition & 1 deletion docs/websocket/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Search for playlists or tracks based on a query.
"id": 7,
"type": "spotcast/search",
"query": "rock",
"searchType": "playlist",
"search_type": "playlist",
"limit": 10,
"account": "01JDG07KSBTYWZGJSBJ1EW6XEF"
}
Expand Down
4 changes: 1 addition & 3 deletions docs/websocket/view.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ The endpoint of the websocket to reach. Must be `spotcast/view`

### `name` (str)

### `name` (str)

The name of the view to retrieve playlists for. This could represent different types of views, including **featured**, **recently-played** and **Discover Weekly**. You can view all available options in the Spotify API (token needed) [here](https://api.spotify.com/v1/views/personalized-recommendations).

### `account` (str)
Expand Down Expand Up @@ -111,4 +109,4 @@ The result of the transaction.
> >
> > ##### `icon` (str)
> >
> > A URL to the playlist's icon or image.
> > A URL to the playlist's icon or image.
97 changes: 23 additions & 74 deletions test/services/play_media/test_async_episode_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,95 +4,44 @@
from unittest.mock import MagicMock, AsyncMock

from custom_components.spotcast.services.play_media import (
async_track_index,
async_episode_index,
SpotifyAccount,
)


class TestSingleDiscAlbum(IsolatedAsyncioTestCase):
class TestEpisodeIndexRetrieval(IsolatedAsyncioTestCase):

async def asyncSetUp(self):

self.mocks = {
"account": MagicMock(spec=SpotifyAccount)
}

self.mocks["account"].async_get_track = AsyncMock()
self.mocks["account"].async_get_track.return_value = {
"disc_number": 1,
"track_number": 5,
"album": {
"uri": "spotify:album:foo"
self.mocks["account"].async_get_episode = AsyncMock(return_value={
"show": {
"uri": "spotify:show:bar"
}
}

self.uri, self.index = await async_track_index(
self.mocks["account"],
"spotify:track:bar",
)

def test_proper_order_of_tuple_object(self):
self.assertIsInstance(self.uri, str)
self.assertIsInstance(self.index, int)

def test_correct_uri_returned(self):
self.assertEqual(self.uri, "spotify:album:foo")

def test_currect_index_returned(self):
self.assertEqual(self.index, 5)


class TestMultiDiscAlbum(IsolatedAsyncioTestCase):

async def asyncSetUp(self):
})

self.mocks = {
"account": MagicMock(spec=SpotifyAccount)
}

self.mocks["account"].async_get_track = AsyncMock()
self.mocks["account"].async_get_track.return_value = {
"disc_number": 2,
"track_number": 5,
"album": {
"uri": "spotify:album:foo"
}
}

self.mocks["account"].async_get_album = AsyncMock()
self.mocks["account"].async_get_album.return_value = {
"tracks": {
"items": [
{"uri": "spotify:track:chasing-shadows"},
{"uri": "spotify:track:midnight-serenade"},
{"uri": "spotify:track:crimson-harmony"},
{"uri": "spotify:track:echoes-of-dawn"},
{"uri": "spotify:track:whispered-lullaby"},
{"uri": "spotify:track:stellar-dreams"},
{"uri": "spotify:track:rising-tide"},
{"uri": "spotify:track:bar"},
{"uri": "spotify:track:forgotten-anthem"},
{"uri": "spotify:track:wandering-spirit"},
{"uri": "spotify:track:golden-reverie"},
{"uri": "spotify:track:fractured-melody"},
{"uri": "spotify:track:lost-horizons"},
{"uri": "spotify:track:serenade-of-starlight"},
{"uri": "spotify:track:eternal-drift"},
]
}
}
self.mocks["account"].async_get_show_episodes = AsyncMock(return_value=[
{"uri": "spotify:episode:bar"},
{"uri": "spotify:episode:foo"},
{"uri": "spotify:episode:baz"},
])

self.uri, self.index = await async_track_index(
self.mocks["account"],
"spotify:track:bar",
self.result = await async_episode_index(
account=self.mocks["account"],
uri="spotify:episode:foo",
)

def test_proper_order_of_tuple_object(self):
self.assertIsInstance(self.uri, str)
self.assertIsInstance(self.index, int)
def test_reply_has_proper_format(self):
self.assertIsInstance(self.result, tuple)
self.assertEqual(len(self.result), 2)
self.assertIsInstance(self.result[0], str)
self.assertIsInstance(self.result[1], int)

def test_correct_uri_returned(self):
self.assertEqual(self.uri, "spotify:album:foo")
def test_proper_show_rui_returned(self):
self.assertEqual(self.result[0], "spotify:show:bar")

def test_currect_index_returned(self):
self.assertEqual(self.index, 8)
def test_proper_index_returned(self):
self.assertEqual(self.result[1], 1)
67 changes: 66 additions & 1 deletion test/services/play_media/test_async_play_media.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,72 @@ def test_account_play_media_called_with_expected_arguments(self):
"12345",
"spotify:album:foo",
random=True,
offset=4,
offset=5,
)
except AssertionError:
self.fail()

def test_random_offset_ignored_in_case_of_track_uri(self):
try:
self.mocks["random"].assert_not_called()
except AssertionError:
self.fail()


class TestEpisodeUri(IsolatedAsyncioTestCase):

@patch(f"{TEST_MODULE}.async_episode_index")
@patch(f"{TEST_MODULE}.async_random_index")
@patch(f"{TEST_MODULE}.async_media_player_from_id")
@patch.object(SpotifyAccount, "async_from_config_entry")
@patch(f"{TEST_MODULE}.get_account_entry", new_callable=MagicMock)
async def asyncSetUp(
self,
mock_entry: MagicMock,
mock_account: AsyncMock,
mock_player: AsyncMock,
mock_random: AsyncMock,
mock_index: AsyncMock,
):

mock_entry.return_value = MagicMock()
mock_account.return_value = MagicMock(spec=SpotifyAccount)
mock_player.return_value.id = "12345"

self.mocks = {
"hass": MagicMock(spec=HomeAssistant),
"call": MagicMock(spec=ServiceCall),
"entry": mock_entry(),
"account": mock_account.return_value,
"player": mock_player(),
"random": mock_random,
"index": mock_index,
}

self.mocks["index"].return_value = ("spotify:show:foo", 5)
self.mocks["call"].data = {
"spotify_uri": "spotify:episode:bar",
"account": "12345",
"media_player": {
"entity_id": [
"media_player.foo"
]
},
"data": {
"random": True,
}
}

await async_play_media(self.mocks["hass"], self.mocks["call"])

def test_account_play_media_called_with_expected_arguments(self):
try:
self.mocks["account"].async_play_media\
.assert_called_with(
"12345",
"spotify:show:foo",
random=True,
offset=5,
)
except AssertionError:
self.fail()
Expand Down
4 changes: 2 additions & 2 deletions test/services/play_media/test_async_track_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_correct_uri_returned(self):
self.assertEqual(self.uri, "spotify:album:foo")

def test_currect_index_returned(self):
self.assertEqual(self.index, 5)
self.assertEqual(self.index, 4)


class TestMultiDiscAlbum(IsolatedAsyncioTestCase):
Expand Down Expand Up @@ -95,4 +95,4 @@ def test_correct_uri_returned(self):
self.assertEqual(self.uri, "spotify:album:foo")

def test_currect_index_returned(self):
self.assertEqual(self.index, 8)
self.assertEqual(self.index, 7)
4 changes: 2 additions & 2 deletions test/spotify/account/test_async_get_show_episodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async def asyncSetUp(self, mock_spotify: MagicMock):
)

self.result = await self.account.async_get_show_episodes(
"spotify:playlist:foo"
"spotify:show:foo"
)

def test_expected_result_received(self):
Expand All @@ -54,7 +54,7 @@ def test_pager_properly_called(self):
try:
self.account._async_pager.assert_called_with(
function=self.account.apis["private"].show_episodes,
prepends=["foo"],
prepends=["spotify:show:foo"],
appends=["CA"],
max_items=None,
)
Expand Down
22 changes: 22 additions & 0 deletions test/spotify/utils/test_select_image_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,25 @@ def setUp(self):

def test_correct_image_selected(self):
self.assertEqual(self.result, "http://image.com/1")


class TestImageWithoutSize(TestCase):

def setUp(self):

self.images = [
{
"url": "http://image.com/2",
},
{
"url": "http://image.com/1",
},
{
"url": "http://image.com/3",
}
]

self.result = select_image_url(self.images)

def test_correct_image_selected(self):
self.assertEqual(self.result, "http://image.com/2")

0 comments on commit 85c2231

Please sign in to comment.