105 lines
3.3 KiB
Python
105 lines
3.3 KiB
Python
"""@file
|
|
@brief Tests of the add_songs and time_travel use cases with fake ports.
|
|
"""
|
|
|
|
from datetime import date
|
|
|
|
import pytest
|
|
from conftest import FakeChartSource, FakeMusicService
|
|
|
|
from musical_time_machine.application.use_cases import add_songs, time_travel
|
|
from musical_time_machine.constants import ADD_PAUSE_SECONDS
|
|
from musical_time_machine.domain.errors import (
|
|
AuthenticationError,
|
|
BrowserFileMissingError,
|
|
SongAddError,
|
|
SongSearchError,
|
|
)
|
|
from musical_time_machine.domain.song import Song
|
|
|
|
ONE = Song("One", "A")
|
|
TWO = Song("Two", "B")
|
|
THREE = Song("Three", "C")
|
|
|
|
|
|
def _no_pause(_seconds: float) -> None:
|
|
return None
|
|
|
|
|
|
def test_add_songs_adds_every_found_song() -> None:
|
|
service = FakeMusicService()
|
|
|
|
result = add_songs([ONE, TWO], "pl", service, pause=_no_pause)
|
|
|
|
assert (result.added, result.skipped) == (2, [])
|
|
assert service.added == [("pl", "vid-One"), ("pl", "vid-Two")]
|
|
assert service.searched == [("One", "A"), ("Two", "B")]
|
|
|
|
|
|
def test_add_songs_skips_song_not_found() -> None:
|
|
service = FakeMusicService(video_ids={"One": "v1", "Three": "v3"})
|
|
|
|
result = add_songs([ONE, TWO, THREE], "pl", service, pause=_no_pause)
|
|
|
|
assert result.added == 2
|
|
assert result.skipped == [TWO]
|
|
assert service.added == [("pl", "v1"), ("pl", "v3")]
|
|
|
|
|
|
def test_add_songs_skips_song_whose_add_fails_and_continues() -> None:
|
|
service = FakeMusicService(add_errors={"vid-One": SongAddError("no")})
|
|
|
|
result = add_songs([ONE, TWO], "pl", service, pause=_no_pause)
|
|
|
|
assert result.added == 1
|
|
assert result.skipped == [ONE]
|
|
assert service.added == [("pl", "vid-Two")]
|
|
|
|
|
|
def test_add_songs_skips_song_whose_search_fails_and_continues() -> None:
|
|
service = FakeMusicService(search_errors={"One": SongSearchError("no")})
|
|
|
|
result = add_songs([ONE, TWO], "pl", service, pause=_no_pause)
|
|
|
|
assert (result.added, result.skipped) == (1, [ONE])
|
|
|
|
|
|
@pytest.mark.parametrize("error", [AuthenticationError("auth"), BrowserFileMissingError("gone")])
|
|
def test_add_songs_propagates_login_errors(error: Exception) -> None:
|
|
service = FakeMusicService(search_errors={"One": error})
|
|
|
|
with pytest.raises(type(error)):
|
|
add_songs([ONE, TWO], "pl", service, pause=_no_pause)
|
|
|
|
assert service.searched == [("One", "A")]
|
|
|
|
|
|
def test_add_songs_pauses_between_songs_only() -> None:
|
|
pauses: list[float] = []
|
|
|
|
add_songs([ONE, TWO, THREE], "pl", FakeMusicService(), pause=pauses.append)
|
|
|
|
assert pauses == [ADD_PAUSE_SECONDS, ADD_PAUSE_SECONDS]
|
|
|
|
|
|
def test_add_songs_with_no_songs_adds_nothing() -> None:
|
|
pauses: list[float] = []
|
|
|
|
result = add_songs([], "pl", FakeMusicService(), pause=pauses.append)
|
|
|
|
assert (result.added, result.skipped, pauses) == (0, [], [])
|
|
|
|
|
|
def test_time_travel_scrapes_creates_playlist_and_adds() -> None:
|
|
source = FakeChartSource([ONE, TWO, THREE])
|
|
service = FakeMusicService(video_ids={"One": "v1", "Three": "v3"})
|
|
|
|
result = time_travel(date(2026, 4, 18), source, service, pause=_no_pause)
|
|
|
|
playlist_id = result.playlist.playlist_id
|
|
assert source.requested == [date(2026, 4, 18)]
|
|
assert result.playlist.title == "2026-04-18 Billboard 100"
|
|
assert result.playlist.created is True
|
|
assert (result.added, result.skipped, result.total) == (2, [TWO], 3)
|
|
assert service.added == [(playlist_id, "v1"), (playlist_id, "v3")]
|