296 lines
8.8 KiB
Elixir
296 lines
8.8 KiB
Elixir
defmodule MusicLibrary.ScrobbleActivityTest do
|
|
use MusicLibrary.DataCase
|
|
|
|
import MusicLibrary.ScrobbledTracksFixtures
|
|
|
|
alias LastFm.Track
|
|
alias MusicLibrary.ScrobbleActivity
|
|
|
|
describe "list_tracks/1" do
|
|
test "returns all tracks when no parameters provided" do
|
|
_track1 = track_fixture(%{title: "First Track"})
|
|
_track2 = track_fixture(%{title: "Second Track"})
|
|
|
|
tracks = list_tracks()
|
|
|
|
assert length(tracks) == 2
|
|
track_titles = Enum.map(tracks, & &1.title)
|
|
assert "First Track" in track_titles
|
|
assert "Second Track" in track_titles
|
|
end
|
|
|
|
test "returns tracks ordered by scrobbled_at_uts by default" do
|
|
_older_track =
|
|
track_fixture(%{
|
|
title: "Older Track",
|
|
scrobbled_at_uts: System.system_time(:second) - 3600
|
|
})
|
|
|
|
_newer_track =
|
|
track_fixture(%{
|
|
title: "Newer Track",
|
|
scrobbled_at_uts: System.system_time(:second)
|
|
})
|
|
|
|
tracks = list_tracks(%{order: :scrobbled_at})
|
|
|
|
assert length(tracks) == 2
|
|
# Should be ordered by scrobbled_at_uts descending (newest first)
|
|
assert List.first(tracks).title == "Newer Track"
|
|
assert List.last(tracks).title == "Older Track"
|
|
end
|
|
|
|
test "returns tracks ordered by title" do
|
|
track_fixture(%{title: "Zebra Track"})
|
|
track_fixture(%{title: "Alpha Track"})
|
|
|
|
tracks = list_tracks(%{order: :title})
|
|
|
|
assert length(tracks) == 2
|
|
assert List.first(tracks).title == "Alpha Track"
|
|
assert List.last(tracks).title == "Zebra Track"
|
|
end
|
|
|
|
test "returns tracks ordered by artist name" do
|
|
track_fixture(%{artist_name: "Zebra Artist", title: "Track 1"})
|
|
track_fixture(%{artist_name: "Alpha Artist", title: "Track 2"})
|
|
|
|
tracks = list_tracks(%{order: :artist})
|
|
|
|
assert length(tracks) == 2
|
|
assert List.first(tracks).artist.name == "Alpha Artist"
|
|
assert List.last(tracks).artist.name == "Zebra Artist"
|
|
end
|
|
|
|
test "returns tracks ordered by album title" do
|
|
track_fixture(%{album_title: "Zebra Album", title: "Track 1"})
|
|
track_fixture(%{album_title: "Alpha Album", title: "Track 2"})
|
|
|
|
tracks = list_tracks(%{order: :album})
|
|
|
|
assert length(tracks) == 2
|
|
assert List.first(tracks).album.title == "Alpha Album"
|
|
assert List.last(tracks).album.title == "Zebra Album"
|
|
end
|
|
|
|
test "filters tracks by search query matching track title" do
|
|
track_fixture(%{title: "Special Track"})
|
|
track_fixture(%{title: "Regular Track"})
|
|
|
|
tracks = list_tracks(%{query: "Special"})
|
|
|
|
assert length(tracks) == 1
|
|
assert List.first(tracks).title == "Special Track"
|
|
end
|
|
|
|
test "filters tracks by search query matching artist name" do
|
|
track_fixture(%{artist_name: "Special Artist", title: "Track 1"})
|
|
track_fixture(%{artist_name: "Regular Artist", title: "Track 2"})
|
|
|
|
tracks = list_tracks(%{query: "Special Artist"})
|
|
|
|
assert length(tracks) == 1
|
|
assert List.first(tracks).artist.name == "Special Artist"
|
|
end
|
|
|
|
test "filters tracks by search query matching album title" do
|
|
track_fixture(%{album_title: "Special Album", title: "Track 1"})
|
|
track_fixture(%{album_title: "Regular Album", title: "Track 2"})
|
|
|
|
tracks = list_tracks(%{query: "Special Album"})
|
|
|
|
assert length(tracks) == 1
|
|
assert List.first(tracks).album.title == "Special Album"
|
|
end
|
|
|
|
test "applies pagination correctly" do
|
|
create_test_tracks(5)
|
|
|
|
# Get first 2 tracks
|
|
tracks_page_1 = list_tracks(%{page: 1, page_size: 2})
|
|
assert length(tracks_page_1) == 2
|
|
|
|
# Get next 2 tracks
|
|
tracks_page_2 = list_tracks(%{page: 2, page_size: 2})
|
|
assert length(tracks_page_2) == 2
|
|
|
|
# Ensure they're different tracks
|
|
page_1_ids = Enum.map(tracks_page_1, & &1.scrobbled_at_uts)
|
|
page_2_ids = Enum.map(tracks_page_2, & &1.scrobbled_at_uts)
|
|
assert Enum.empty?(page_1_ids -- (page_1_ids -- page_2_ids))
|
|
end
|
|
|
|
test "returns empty list when query matches no tracks" do
|
|
track_fixture(%{title: "Test Track"})
|
|
|
|
tracks = list_tracks(%{query: "NonexistentTrack"})
|
|
|
|
assert tracks == []
|
|
end
|
|
end
|
|
|
|
describe "get_track!/1" do
|
|
test "returns the track with given scrobbled_at_uts as integer" do
|
|
track = track_fixture()
|
|
|
|
found_track = ScrobbleActivity.get_track!(track.scrobbled_at_uts)
|
|
|
|
assert found_track.scrobbled_at_uts == track.scrobbled_at_uts
|
|
assert found_track.title == track.title
|
|
end
|
|
|
|
test "returns the track with given scrobbled_at_uts as string" do
|
|
track = track_fixture()
|
|
|
|
found_track = ScrobbleActivity.get_track!(to_string(track.scrobbled_at_uts))
|
|
|
|
assert found_track.scrobbled_at_uts == track.scrobbled_at_uts
|
|
end
|
|
|
|
test "raises Ecto.NoResultsError when track does not exist" do
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
ScrobbleActivity.get_track!(999_999_999)
|
|
end
|
|
end
|
|
|
|
test "raises Ecto.NoResultsError when given invalid string" do
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
ScrobbleActivity.get_track!("invalid")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "update_track/2" do
|
|
test "updates the track with valid attributes" do
|
|
track = track_fixture(%{title: "Original Title"})
|
|
|
|
update_attrs = %{
|
|
title: "Updated Title",
|
|
artist: %{name: "Updated Artist"},
|
|
album: %{title: "Updated Album"}
|
|
}
|
|
|
|
assert {:ok, updated_track} = ScrobbleActivity.update_track(track, update_attrs)
|
|
assert updated_track.title == "Updated Title"
|
|
assert updated_track.artist.name == "Updated Artist"
|
|
assert updated_track.album.title == "Updated Album"
|
|
end
|
|
|
|
test "returns error changeset with invalid attributes" do
|
|
track = track_fixture()
|
|
|
|
invalid_attrs = %{title: ""}
|
|
|
|
assert {:error, %Ecto.Changeset{}} = ScrobbleActivity.update_track(track, invalid_attrs)
|
|
end
|
|
|
|
test "updates scrobbled_at_label" do
|
|
track = track_fixture(%{scrobbled_at_label: "01/01/2024 12:00:00"})
|
|
|
|
update_attrs = %{scrobbled_at_label: "02/02/2024 14:30:00"}
|
|
|
|
assert {:ok, updated_track} = ScrobbleActivity.update_track(track, update_attrs)
|
|
assert updated_track.scrobbled_at_label == "02/02/2024 14:30:00"
|
|
end
|
|
|
|
test "updates cover_url" do
|
|
track = track_fixture(%{cover_url: "https://example.com/old.jpg"})
|
|
|
|
update_attrs = %{cover_url: "https://example.com/new.jpg"}
|
|
|
|
assert {:ok, updated_track} = ScrobbleActivity.update_track(track, update_attrs)
|
|
assert updated_track.cover_url == "https://example.com/new.jpg"
|
|
end
|
|
end
|
|
|
|
describe "delete_track/1" do
|
|
test "deletes the track" do
|
|
track = track_fixture()
|
|
|
|
assert {:ok, %Track{}} = ScrobbleActivity.delete_track(track)
|
|
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
ScrobbleActivity.get_track!(track.scrobbled_at_uts)
|
|
end
|
|
end
|
|
|
|
test "returns error when track has already been deleted" do
|
|
track = track_fixture()
|
|
{:ok, _} = ScrobbleActivity.delete_track(track)
|
|
|
|
# Attempt to delete again should fail
|
|
assert_raise Ecto.StaleEntryError, fn ->
|
|
ScrobbleActivity.delete_track(track)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "search_tracks_count/1" do
|
|
test "returns total count when no query provided" do
|
|
create_test_tracks(3)
|
|
|
|
count = ScrobbleActivity.search_tracks_count()
|
|
|
|
assert count == 3
|
|
end
|
|
|
|
test "returns filtered count when query provided" do
|
|
track_fixture(%{title: "Special Track"})
|
|
track_fixture(%{title: "Regular Track"})
|
|
track_fixture(%{title: "Another Track"})
|
|
|
|
count = ScrobbleActivity.search_tracks_count("Special")
|
|
|
|
assert count == 1
|
|
end
|
|
|
|
test "returns zero when query matches no tracks" do
|
|
track_fixture(%{title: "Test Track"})
|
|
|
|
count = ScrobbleActivity.search_tracks_count("Nonexistent")
|
|
|
|
assert count == 0
|
|
end
|
|
|
|
test "counts tracks matching artist name" do
|
|
track_fixture(%{artist_name: "Special Artist", title: "Track 1"})
|
|
track_fixture(%{artist_name: "Regular Artist", title: "Track 2"})
|
|
|
|
count = ScrobbleActivity.search_tracks_count("Special")
|
|
|
|
assert count == 1
|
|
end
|
|
|
|
test "counts tracks matching album title" do
|
|
track_fixture(%{album_title: "Special Album", title: "Track 1"})
|
|
track_fixture(%{album_title: "Regular Album", title: "Track 2"})
|
|
|
|
count = ScrobbleActivity.search_tracks_count("Special")
|
|
|
|
assert count == 1
|
|
end
|
|
end
|
|
|
|
describe "integration with existing functions" do
|
|
test "scrobble_count returns correct count" do
|
|
initial_count = ScrobbleActivity.scrobble_count()
|
|
|
|
create_test_tracks(3)
|
|
|
|
new_count = ScrobbleActivity.scrobble_count()
|
|
|
|
assert new_count == initial_count + 3
|
|
end
|
|
end
|
|
|
|
defp list_tracks do
|
|
ScrobbleActivity.list_tracks()
|
|
|> Enum.map(fn r -> r.track end)
|
|
end
|
|
|
|
defp list_tracks(params) do
|
|
ScrobbleActivity.list_tracks(params)
|
|
|> Enum.map(fn r -> r.track end)
|
|
end
|
|
end
|