package backend import ( "context" "os" "testing" "time" "music-server/internal/db/repository" "music-server/internal/testutil/fakedb" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLibrarySoundtracks(t *testing.T) { store := fakedb.New() b := store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "B Game", TimesPlayed: 3}) a := store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "A Game"}) deleted := time.Now() store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "Gone", Deleted: &deleted}) soundtracks, err := NewLibraryService(store).Soundtracks(context.Background()) require.NoError(t, err) require.Len(t, soundtracks, 2) assert.Equal(t, Soundtrack{Uuid: a.Uuid, Name: "A Game", AlternativeNames: []string{}}, soundtracks[0]) assert.Equal(t, b.Uuid, soundtracks[1].Uuid) assert.Equal(t, int32(3), soundtracks[1].TimesPlayed) } func TestLibrarySetAlternativeNames(t *testing.T) { store := fakedb.New() st := store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "Final Fantasy VII"}) l := NewLibraryService(store) ctx := context.Background() soundtrack, err := l.SetAlternativeNames(ctx, st.Uuid, []string{" FF7 ", "ff7", "", "final fantasy vii", "ファイナルファンタジーVII", " "}) require.NoError(t, err) assert.Equal(t, []string{"FF7", "ファイナルファンタジーVII"}, soundtrack.AlternativeNames, "trimmed, without empty names, duplicates or the soundtrack's own name") stored, err := l.Soundtrack(ctx, st.Uuid) require.NoError(t, err) assert.Equal(t, []string{"FF7", "ファイナルファンタジーVII"}, stored.AlternativeNames) soundtrack, err = l.SetAlternativeNames(ctx, st.Uuid, nil) require.NoError(t, err) assert.Equal(t, []string{}, soundtrack.AlternativeNames, "an empty list removes them") _, err = l.SetAlternativeNames(ctx, uuid.New(), []string{"x"}) assert.ErrorIs(t, err, ErrNotFound) } func TestLibrarySetAlternativeNamesSearchesForACoverAgain(t *testing.T) { store := fakedb.New() checked := pgtype.Timestamptz{Time: time.Now(), Valid: true} without := store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "No cover", CoverChecked: checked}) file := "cover.jpg" with := store.AddSoundtrack(repository.Soundtrack{SoundtrackName: "Cover", CoverFile: &file, CoverChecked: checked}) l := NewLibraryService(store) _, err := l.SetAlternativeNames(context.Background(), without.Uuid, []string{"x"}) require.NoError(t, err) _, err = l.SetAlternativeNames(context.Background(), with.Uuid, []string{"y"}) require.NoError(t, err) st, _ := store.Soundtrack("No cover") assert.False(t, st.CoverChecked.Valid, "searched again with the new names") st, _ = store.Soundtrack("Cover") assert.True(t, st.CoverChecked.Valid, "a soundtrack with a cover keeps it") } func TestLibrarySoundtrackWithSongs(t *testing.T) { store := fakedb.New() st := addSoundtrackWithSongs(t, store, t.TempDir(), "Game A", 0, "Song B", "Song A") l := NewLibraryService(store) result, err := l.Soundtrack(context.Background(), st.Uuid) require.NoError(t, err) assert.Equal(t, "Game A", result.Name) require.Len(t, result.Songs, 2) assert.Equal(t, "Song A", result.Songs[0].Name) assert.Equal(t, st.Uuid, result.Songs[0].SoundtrackUuid) assert.Equal(t, "Game A", result.Songs[0].SoundtrackName) _, err = l.Soundtrack(context.Background(), uuid.New()) assert.ErrorIs(t, err, ErrNotFound) } func TestLibrarySong(t *testing.T) { store := fakedb.New() st := addSoundtrackWithSongs(t, store, t.TempDir(), "Game A", 0, "Song") song := store.SongsOf(st.ID)[0] l := NewLibraryService(store) ctx := context.Background() result, err := l.Song(ctx, song.Uuid) require.NoError(t, err) assert.Equal(t, Song{Uuid: song.Uuid, Name: "Song", FileName: song.FileName, SoundtrackUuid: st.Uuid, SoundtrackName: "Game A"}, result) path, err := l.SongPath(ctx, song.Uuid) require.NoError(t, err) assert.Equal(t, song.Path, path) require.NoError(t, os.Remove(song.Path)) _, err = l.SongPath(ctx, song.Uuid) assert.ErrorIs(t, err, ErrNotFound, "missing files are not served") _, err = l.Song(ctx, uuid.New()) assert.ErrorIs(t, err, ErrNotFound) } func TestLibraryHidesSongsOfDeletedSoundtracks(t *testing.T) { store := fakedb.New() st := addSoundtrackWithSongs(t, store, t.TempDir(), "Game A", 0, "Song") song := store.SongsOf(st.ID)[0] require.NoError(t, store.MarkSoundtracksDeletedExcept(context.Background(), nil)) _, err := NewLibraryService(store).Song(context.Background(), song.Uuid) assert.ErrorIs(t, err, ErrNotFound) _, err = NewLibraryService(store).Soundtrack(context.Background(), st.Uuid) assert.ErrorIs(t, err, ErrNotFound) }