Scrobbled tracks CRUD
- Failing tests - Warnings
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
defmodule MusicLibrary.ScrobbleActivityTest do
|
||||
use MusicLibrary.DataCase
|
||||
|
||||
import MusicLibrary.ScrobbledTracksFixtures
|
||||
|
||||
alias LastFm.Track
|
||||
alias MusicLibrary.{Repo, 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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.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 = ScrobbleActivity.list_tracks(%{page: 1, page_size: 2})
|
||||
assert length(tracks_page_1) == 2
|
||||
|
||||
# Get next 2 tracks
|
||||
tracks_page_2 = ScrobbleActivity.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 = ScrobbleActivity.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
|
||||
end
|
||||
@@ -0,0 +1,321 @@
|
||||
defmodule MusicLibraryWeb.ScrobbledTracksLiveTest do
|
||||
use MusicLibraryWeb.ConnCase
|
||||
|
||||
import MusicLibrary.ScrobbledTracksFixtures
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias MusicLibrary.ScrobbleActivity
|
||||
|
||||
# Test data
|
||||
@invalid_track_attrs %{title: "", artist: %{name: ""}, album: %{title: ""}}
|
||||
@valid_track_attrs %{
|
||||
title: "Updated Track Title",
|
||||
artist: %{name: "Updated Artist"},
|
||||
album: %{title: "Updated Album"},
|
||||
scrobbled_at_label: "02/02/2024 14:00:00",
|
||||
cover_url: "https://example.com/updated-cover.jpg"
|
||||
}
|
||||
|
||||
defp create_track(_) do
|
||||
track = track_fixture()
|
||||
%{track: track}
|
||||
end
|
||||
|
||||
defp create_multiple_tracks(_) do
|
||||
tracks = create_test_tracks(10)
|
||||
%{tracks: tracks}
|
||||
end
|
||||
|
||||
describe "Index" do
|
||||
setup [:create_track]
|
||||
|
||||
test "lists scrobbled tracks", %{conn: conn, track: track} do
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
assert html =~ track.title
|
||||
assert html =~ track.artist.name
|
||||
assert html =~ track.album.title
|
||||
end
|
||||
|
||||
test "shows empty state when no tracks", %{conn: conn} do
|
||||
# Delete the created track
|
||||
ScrobbleActivity.delete_track(track_fixture())
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
assert html =~ "No scrobbled tracks found"
|
||||
end
|
||||
|
||||
test "displays track count", %{conn: conn} do
|
||||
create_test_tracks(3)
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
assert html =~ ~r/\d+ tracks?/
|
||||
end
|
||||
end
|
||||
|
||||
describe "Search functionality" do
|
||||
setup [:create_multiple_tracks]
|
||||
|
||||
test "searches tracks by title", %{conn: conn} do
|
||||
track_fixture(%{title: "Unique Track Title"})
|
||||
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> form("form[phx-submit='search']", %{query: "Unique Track"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Unique Track Title"
|
||||
end
|
||||
|
||||
test "searches tracks by artist name", %{conn: conn} do
|
||||
track_fixture(%{artist_name: "Unique Artist Name"})
|
||||
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> form("form[phx-submit='search']", %{query: "Unique Artist"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Unique Artist Name"
|
||||
end
|
||||
|
||||
test "searches tracks by album title", %{conn: conn} do
|
||||
track_fixture(%{album_title: "Unique Album Title"})
|
||||
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> form("form[phx-submit='search']", %{query: "Unique Album"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Unique Album Title"
|
||||
end
|
||||
|
||||
test "shows no results message for non-matching search", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> form("form[phx-submit='search']", %{query: "NonexistentTrack"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Try adjusting your search"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Sorting functionality" do
|
||||
setup [:create_multiple_tracks]
|
||||
|
||||
test "sorts by scrobbled date (default)", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
# Click on scrobbled date sort button
|
||||
html =
|
||||
index_live
|
||||
|> element("button[patch*='order=scrobbled_at']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
# Check that URL contains the order parameter
|
||||
assert_patch(
|
||||
index_live,
|
||||
~p"/scrobbled-tracks?order=scrobbled_at&page=1&page_size=200&query="
|
||||
)
|
||||
end
|
||||
|
||||
test "sorts by track title", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> element("button[patch*='order=title']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
assert_patch(index_live, ~p"/scrobbled-tracks?order=title&page=1&page_size=200&query=")
|
||||
end
|
||||
|
||||
test "sorts by artist name", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> element("button[patch*='order=artist']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
assert_patch(index_live, ~p"/scrobbled-tracks?order=artist&page=1&page_size=200&query=")
|
||||
end
|
||||
|
||||
test "sorts by album title", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> element("button[patch*='order=album']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
assert_patch(index_live, ~p"/scrobbled-tracks?order=album&page=1&page_size=200&query=")
|
||||
end
|
||||
end
|
||||
|
||||
describe "Edit track" do
|
||||
setup [:create_track]
|
||||
|
||||
test "updates track successfully", %{conn: conn, track: track} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
assert index_live
|
||||
|> element("button[patch='/scrobbled-tracks/#{track.scrobbled_at_uts}/edit']")
|
||||
|> render_click() =~ "Edit Scrobbled Track"
|
||||
|
||||
assert_patch(index_live, ~p"/scrobbled-tracks/#{track.scrobbled_at_uts}/edit")
|
||||
|
||||
assert index_live
|
||||
|> form("#track-form", track: @invalid_track_attrs)
|
||||
|> render_change() =~ "can't be blank"
|
||||
|
||||
html =
|
||||
index_live
|
||||
|> form("#track-form", track: @valid_track_attrs)
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Track updated successfully"
|
||||
assert html =~ "Updated Track Title"
|
||||
end
|
||||
|
||||
test "shows validation errors", %{conn: conn, track: track} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
assert index_live
|
||||
|> element("button[patch='/scrobbled-tracks/#{track.scrobbled_at_uts}/edit']")
|
||||
|> render_click()
|
||||
|
||||
assert index_live
|
||||
|> form("#track-form", track: @invalid_track_attrs)
|
||||
|> render_change() =~ "can't be blank"
|
||||
end
|
||||
|
||||
test "closes modal when clicking outside or cancel", %{conn: conn, track: track} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
# Open edit modal
|
||||
assert index_live
|
||||
|> element("button[patch='/scrobbled-tracks/#{track.scrobbled_at_uts}/edit']")
|
||||
|> render_click()
|
||||
|
||||
# Close modal by patching back to index
|
||||
html = index_live |> element("button[phx-click='JS.patch']") |> render_click()
|
||||
|
||||
assert_patch(index_live, ~p"/scrobbled-tracks")
|
||||
end
|
||||
end
|
||||
|
||||
describe "Delete track" do
|
||||
setup [:create_track]
|
||||
|
||||
test "deletes track successfully", %{conn: conn, track: track} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
# Find and click delete button
|
||||
assert index_live
|
||||
|> element(
|
||||
"button[phx-click='delete'][phx-value-scrobbled-at-uts='#{track.scrobbled_at_uts}']"
|
||||
)
|
||||
|> render_click()
|
||||
|
||||
# Track should no longer be visible
|
||||
refute has_element?(index_live, "#tracks-#{track.scrobbled_at_uts}")
|
||||
end
|
||||
end
|
||||
|
||||
describe "Pagination" do
|
||||
test "shows pagination when more than one page", %{conn: conn} do
|
||||
# Create enough tracks to require pagination (more than 200)
|
||||
create_test_tracks(250)
|
||||
|
||||
{:ok, index_live, html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
# Should show pagination component
|
||||
assert html =~ "Next"
|
||||
assert has_element?(index_live, "#bottom_pagination")
|
||||
end
|
||||
|
||||
test "navigates to next page", %{conn: conn} do
|
||||
create_test_tracks(250)
|
||||
|
||||
{:ok, index_live, _html} = live(conn, ~p"/scrobbled-tracks")
|
||||
|
||||
# Click next page button (if visible)
|
||||
if has_element?(index_live, "button[patch*='page=2']") do
|
||||
html =
|
||||
index_live
|
||||
|> element("button[patch*='page=2']")
|
||||
|> render_click()
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "URL parameter handling" do
|
||||
test "handles query parameter", %{conn: conn} do
|
||||
track_fixture(%{title: "Special Track"})
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks?query=Special")
|
||||
|
||||
assert html =~ "Special Track"
|
||||
end
|
||||
|
||||
test "handles page parameter", %{conn: conn} do
|
||||
create_test_tracks(250)
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks?page=2&page_size=100")
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
end
|
||||
|
||||
test "handles order parameter", %{conn: conn} do
|
||||
create_test_tracks(5)
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks?order=title")
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
end
|
||||
|
||||
test "handles invalid parameters gracefully", %{conn: conn} do
|
||||
create_test_tracks(5)
|
||||
|
||||
{:ok, _index_live, html} = live(conn, ~p"/scrobbled-tracks?page=invalid&order=invalid")
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Navigation integration" do
|
||||
test "shows Scrobbled Tracks link in navigation", %{conn: conn} do
|
||||
{:ok, _index_live, html} = live(conn, ~p"/")
|
||||
|
||||
assert html =~ "Scrobbled Tracks"
|
||||
assert html =~ ~p"/scrobbled-tracks"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Error handling" do
|
||||
test "handles non-existent track edit gracefully", %{conn: conn} do
|
||||
invalid_id = 999_999_999
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn ->
|
||||
live(conn, ~p"/scrobbled-tracks/#{invalid_id}/edit")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
defmodule MusicLibrary.ScrobbledTracksFixtures do
|
||||
@moduledoc """
|
||||
This module defines test helpers for creating
|
||||
scrobbled track entities via the database.
|
||||
"""
|
||||
|
||||
alias MusicLibrary.Repo
|
||||
alias LastFm.Track
|
||||
|
||||
@doc """
|
||||
Generate a scrobbled track.
|
||||
"""
|
||||
def track_fixture(attrs \\ %{}) do
|
||||
scrobbled_at_uts =
|
||||
attrs[:scrobbled_at_uts] || System.system_time(:second) - Enum.random(0..86400)
|
||||
|
||||
# Create map attributes for embedded schemas
|
||||
artist_attrs = %{
|
||||
musicbrainz_id: attrs[:artist_musicbrainz_id] || "",
|
||||
name: attrs[:artist_name] || "Test Artist"
|
||||
}
|
||||
|
||||
album_attrs = %{
|
||||
musicbrainz_id: attrs[:album_musicbrainz_id] || "",
|
||||
title: attrs[:album_title] || "Test Album"
|
||||
}
|
||||
|
||||
track_attrs = %{
|
||||
scrobbled_at_uts: scrobbled_at_uts,
|
||||
musicbrainz_id: attrs[:musicbrainz_id] || "",
|
||||
title: attrs[:title] || "Test Track",
|
||||
cover_url: attrs[:cover_url] || "https://example.com/cover.jpg",
|
||||
scrobbled_at_label: attrs[:scrobbled_at_label] || "01/01/2024 12:00:00",
|
||||
artist: artist_attrs,
|
||||
album: album_attrs,
|
||||
last_fm_data: attrs[:last_fm_data] || %{}
|
||||
}
|
||||
|
||||
changeset = Track.changeset(%Track{}, track_attrs)
|
||||
{:ok, track} = Repo.insert(changeset)
|
||||
track
|
||||
end
|
||||
|
||||
@doc """
|
||||
Generate multiple scrobbled tracks for testing pagination and search.
|
||||
"""
|
||||
def create_test_tracks(count \\ 5) do
|
||||
artists = ["Pink Floyd", "The Beatles", "Led Zeppelin", "Queen", "The Rolling Stones"]
|
||||
albums = ["Dark Side", "Abbey Road", "IV", "A Night", "Sticky Fingers"]
|
||||
tracks = ["Money", "Come Together", "Stairway", "Bohemian", "Brown Sugar"]
|
||||
|
||||
1..count
|
||||
|> Enum.map(fn i ->
|
||||
track_fixture(%{
|
||||
# 1 hour apart
|
||||
scrobbled_at_uts: System.system_time(:second) - i * 3600,
|
||||
title: Enum.at(tracks, rem(i - 1, length(tracks))) <> " #{i}",
|
||||
artist_name: Enum.at(artists, rem(i - 1, length(artists))),
|
||||
album_title: Enum.at(albums, rem(i - 1, length(albums))) <> " #{i}",
|
||||
scrobbled_at_label: "0#{rem(i, 9) + 1}/01/2024 1#{rem(i, 2)}:00:00"
|
||||
})
|
||||
end)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user