//go:build integration package backend import ( "context" "testing" "music-server/internal/db/repository" "music-server/internal/testutil/pgtest" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestQueueWithPostgres checks the queue queries against a real database. func TestQueueWithPostgres(t *testing.T) { ctx := context.Background() database := pgtest.NewMigratedDatabase(t) q := repository.New(database.Pool) s := NewSyncService(q, copyTestMusic(t), nil) require.True(t, s.Start(false)) s.Wait() m := NewMusicService(q, t.TempDir()) queueID, err := m.ResolveQueue(ctx, "") require.NoError(t, err) require.NoError(t, m.AddLatestToQueue(ctx, queueID), "nothing fetched yet") var paths []string for range 3 { path, err := m.RandomSong(ctx, queueID) require.NoError(t, err) require.NoError(t, m.AddLatestToQueue(ctx, queueID)) paths = append(paths, path) } require.NoError(t, m.AddLatestToQueue(ctx, queueID), "a fetched song is only added once") played, err := m.PlayedSongs(ctx, queueID) require.NoError(t, err) require.Len(t, played, 3) for i, song := range played { assert.Equal(t, i, song.SongNo) assert.Equal(t, i == 2, song.CurrentlyPlaying, "the last added song is current") assert.NotEmpty(t, song.Soundtrack) assert.NotEqual(t, uuid.Nil, song.SoundtrackUuid) } path, err := m.PreviousSong(ctx, queueID) require.NoError(t, err) assert.Equal(t, paths[1], path) require.NoError(t, m.AddLatestPlayed(ctx, queueID)) info, err := m.SongInfo(ctx, queueID) require.NoError(t, err) assert.Equal(t, 1, info.SongNo) assert.Equal(t, int32(1), info.SongPlayed) // A new service, as after a restart, sees the same queue. restarted := NewMusicService(q, t.TempDir()) same, err := restarted.ResolveQueue(ctx, queueID.String()) require.NoError(t, err) assert.Equal(t, queueID, same) newID, err := m.NewQueue(ctx, queueID) require.NoError(t, err) assert.NotEqual(t, queueID, newID) resolved, err := m.ResolveQueue(ctx, queueID.String()) require.NoError(t, err) assert.NotEqual(t, queueID, resolved, "an ended queue is not used again") other, err := m.ResolveQueue(ctx, "") require.NoError(t, err) require.NoError(t, m.EndAllQueues(ctx)) var active int require.NoError(t, database.Pool.QueryRow(ctx, "SELECT COUNT(*) FROM queue WHERE ended_at IS NULL").Scan(&active)) assert.Zero(t, active) _, err = m.ResolveQueue(ctx, other.String()) require.NoError(t, err) // Ended queues keep their songs, also after the songs are removed from the library. require.NoError(t, q.ClearSongs(ctx)) played, err = m.PlayedSongs(ctx, queueID) require.NoError(t, err) require.Len(t, played, 3) assert.NotEmpty(t, played[0].Song) _, err = m.Song(ctx, queueID, 0) assert.ErrorIs(t, err, ErrNotFound) }