//go:build integration package backend import ( "context" "path/filepath" "testing" "time" "music-server/internal/db/repository" "music-server/internal/testutil/pgtest" "github.com/jackc/pgx/v5/pgtype" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestAlternativeNamesAndCoversWithPostgres checks the alternative name and cover queries // against a real database. func TestAlternativeNamesAndCoversWithPostgres(t *testing.T) { ctx := context.Background() q := repository.New(pgtest.NewMigratedDatabase(t).Pool) s := NewSyncService(q, copyTestMusic(t), nil) require.True(t, s.Start(false)) s.Wait() library := NewLibraryService(q) soundtracks, err := library.Soundtracks(ctx) require.NoError(t, err) require.GreaterOrEqual(t, len(soundtracks), 2) first, second := soundtracks[0], soundtracks[1] assert.Equal(t, []string{}, first.AlternativeNames) assert.Nil(t, first.CoverModified) // Alternative names, in every soundtrack response. updated, err := library.SetAlternativeNames(ctx, first.Uuid, []string{" Alt ", "alt", first.Name, "Другое"}) require.NoError(t, err) assert.Equal(t, []string{"Alt", "Другое"}, updated.AlternativeNames) stats, err := NewStatisticsService(q).AllSoundtracks(ctx) require.NoError(t, err) assert.Equal(t, []string{"Alt", "Другое"}, stats[0].AlternativeNames) never, err := NewStatisticsService(q).NeverPlayedSoundtracks(ctx) require.NoError(t, err) assert.Equal(t, []string{"Alt", "Другое"}, never[0].AlternativeNames) search, err := NewMusicService(q, t.TempDir()).SearchSoundtracks(ctx) require.NoError(t, err) assert.Equal(t, []string{"Alt", "Другое"}, search[0].AlternativeNames) // Covers. c, err := NewCoverService(q, filepath.Join(t.TempDir(), "covers"), CoverOptions{}) require.NoError(t, err) require.NoError(t, c.Upload(ctx, first.Uuid, pngBytes(t))) withCover, err := library.Soundtrack(ctx, first.Uuid) require.NoError(t, err) require.NotNil(t, withCover.CoverModified) stats, err = NewStatisticsService(q).AllSoundtracks(ctx) require.NoError(t, err) assert.Equal(t, withCover.CoverModified, stats[0].CoverModified) needing, err := q.ListSoundtracksNeedingCover(ctx, nowPlus(0)) require.NoError(t, err) for _, row := range needing { assert.NotEqual(t, first.Uuid, row.Uuid, "a soundtrack with a cover is not searched") } require.NoError(t, q.MarkCoverChecked(ctx, second.Uuid)) needing, err = q.ListSoundtracksNeedingCover(ctx, nowPlus(-60)) require.NoError(t, err) for _, row := range needing { assert.NotEqual(t, second.Uuid, row.Uuid, "searched recently") } // New names make a soundtrack without a cover searched again. _, err = library.SetAlternativeNames(ctx, second.Uuid, []string{"Other"}) require.NoError(t, err) needing, err = q.ListSoundtracksNeedingCover(ctx, nowPlus(-60)) require.NoError(t, err) var found bool for _, row := range needing { if row.Uuid == second.Uuid { found = true assert.Equal(t, []string{"Other"}, row.AlternativeNames) } } assert.True(t, found) files, err := q.ListCoverFiles(ctx) require.NoError(t, err) assert.Equal(t, []string{first.Uuid.String() + ".png"}, files) require.NoError(t, c.Remove(ctx, first.Uuid)) files, err = q.ListCoverFiles(ctx) require.NoError(t, err) assert.Empty(t, files) } func nowPlus(seconds int) pgtype.Timestamptz { return pgtype.Timestamptz{Time: time.Now().Add(time.Duration(seconds) * time.Second), Valid: true} }