Import missing artist portraits from uploaded album folders
ci / module boundaries / boundaries (push) Successful in 6s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 2m1s
ci / ts / ts (packages + web) (push) Failing after 5m13s
ci / api / api (push) Successful in 41s
ci / db / db (push) Failing after 1m33s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 2m25s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 2m19s
ci / module boundaries / boundaries (push) Successful in 6s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 2m1s
ci / ts / ts (packages + web) (push) Failing after 5m13s
ci / api / api (push) Successful in 41s
ci / db / db (push) Failing after 1m33s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 2m25s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 2m19s
This commit is contained in:
1 parent
fd17c06397
commit
82bf015283
23 files changed
+829
-317
No files matched your search
@@ -0,0 +1,77 @@
|
||||
//go:build integration
|
||||
|
||||
package dbtest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"pipu/api/internal/library"
|
||||
"pipu/api/internal/library/meta"
|
||||
"pipu/api/internal/platform/db"
|
||||
)
|
||||
|
||||
type portraitProber struct{ artist string }
|
||||
|
||||
func (p portraitProber) Probe(context.Context, string) (library.Probe, error) {
|
||||
return library.Probe{Format: "flac", Codec: "flac", DurationMs: 180000,
|
||||
Tags: meta.Fields{Artist: p.artist + ", Guest " + p.artist, AlbumArtist: p.artist, Album: "Portrait album", Title: "Song", Track: "1"}}, nil
|
||||
}
|
||||
|
||||
func TestArtistImagesPreserveLocalExternalAndConcurrentPortraits(t *testing.T) {
|
||||
pool := connect(t)
|
||||
ctx := context.Background()
|
||||
require.NoError(t, db.Migrate(ctx, pool))
|
||||
store := library.NewStore(pool)
|
||||
source, err := store.SaveSource(ctx, library.Source{ID: uuid.New(), Name: "portraits", Type: library.SourceLocal, Status: "mounted", TagsFirst: true, NFSOptions: "ro"})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, store.DeleteSource(ctx, source.ID))
|
||||
require.NoError(t, store.CleanupOrphans(ctx))
|
||||
})
|
||||
root := t.TempDir()
|
||||
for _, scenario := range []string{"empty", "local", "external", "concurrent"} {
|
||||
t.Run(scenario, func(t *testing.T) {
|
||||
artist := "Portrait " + uuid.NewString()
|
||||
scanner := library.NewScanner(store, portraitProber{artist}, library.NewProgressBoard(), slog.New(slog.DiscardHandler))
|
||||
rel := scenario + ".flac"
|
||||
require.NoError(t, os.WriteFile(filepath.Join(root, rel), []byte(scenario), 0o644))
|
||||
file, err := scanner.ScanFile(ctx, source, root, rel)
|
||||
require.NoError(t, err)
|
||||
id, err := store.ArtistWithoutImageForFile(ctx, file)
|
||||
require.NoError(t, err)
|
||||
if scenario == "local" {
|
||||
require.NoError(t, store.SetArtistImageIfMissing(ctx, id, "existing-local"))
|
||||
}
|
||||
if scenario == "external" || scenario == "concurrent" {
|
||||
_, err = pool.Exec(ctx, `UPDATE artists SET genius_image_url='https://example.org/portrait.jpg' WHERE id=$1`, id)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
if scenario != "empty" {
|
||||
_, err = store.ArtistWithoutImageForFile(ctx, file)
|
||||
require.ErrorIs(t, err, library.ErrNotFound)
|
||||
}
|
||||
// Even a caller that looked up the artist before another writer cannot overwrite it.
|
||||
require.NoError(t, store.SetArtistImageIfMissing(ctx, id, "uploaded-portrait"))
|
||||
a, err := store.Artist(ctx, id)
|
||||
require.NoError(t, err)
|
||||
switch scenario {
|
||||
case "empty":
|
||||
require.Equal(t, "uploaded-portrait", *a.ImagePath)
|
||||
case "local":
|
||||
require.Equal(t, "existing-local", *a.ImagePath)
|
||||
default:
|
||||
require.Nil(t, a.ImagePath)
|
||||
require.Equal(t, "https://example.org/portrait.jpg", *a.ImageURL)
|
||||
}
|
||||
var guestImage *string
|
||||
require.NoError(t, pool.QueryRow(ctx, `SELECT image_path FROM artists WHERE name=$1`, "Guest "+artist).Scan(&guestImage))
|
||||
require.Nil(t, guestImage, "a parent folder portrait belongs to the album artist, not guests")
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user