ci / module boundaries / boundaries (push) Successful in 7s
ci / db / db (push) Successful in 2m33s
ci / api / api (push) Successful in 1m10s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 3m45s
ci / ts / ts (packages + web) (push) Successful in 6m29s
101 lines
4.3 KiB
Go
101 lines
4.3 KiB
Go
package uploads
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"pipu/api/internal/library"
|
|
)
|
|
|
|
type previewCatalog struct{ source library.Source }
|
|
|
|
func (c *previewCatalog) GetSource(context.Context, uuid.UUID) (library.Source, error) {
|
|
return c.source, nil
|
|
}
|
|
func (c *previewCatalog) ListSources(context.Context) ([]library.Source, error) {
|
|
return []library.Source{c.source}, nil
|
|
}
|
|
func (c *previewCatalog) Patterns(context.Context, uuid.UUID) ([]library.PatternRow, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
type previewStore struct{}
|
|
|
|
func (previewStore) Settings(context.Context) (Settings, error) { return Settings{}, nil }
|
|
func (previewStore) MatchCatalog(context.Context, string, string) (*uuid.UUID, *uuid.UUID, int, error) {
|
|
return nil, nil, 0, nil
|
|
}
|
|
func (previewStore) BatchMaxDisc(context.Context, uuid.UUID, string) (int, error) { return 1, nil }
|
|
|
|
type previewRoot string
|
|
|
|
func TestPreviewMissingYearStillHasImportPath(t *testing.T) {
|
|
root := t.TempDir()
|
|
catalog := &previewCatalog{source: library.Source{ID: uuid.New(), Name: "Base", Type: library.SourceLocal,
|
|
AcceptsUploads: true, WriteTemplate: nullable("{albumartist}/{albumartist} - {album} ({year})/{title}.{ext}")}}
|
|
planner := &PlacementPlanner{store: previewStore{}, lib: catalog, roots: previewRoot(root)}
|
|
f := File{Status: StatusPendingReview, OriginalName: "song.mp3", Meta: &Meta{
|
|
Artist: "Artist feat. Guest", AlbumArtist: "Artist", Album: "Album", Title: "Song"}}
|
|
planner.previewPlacement(context.Background(), &f)
|
|
require.NotNil(t, f.TargetRelPath)
|
|
require.Equal(t, "Artist/Artist - Album/Song.mp3", *f.TargetRelPath)
|
|
require.NotNil(t, f.TargetStoragePath)
|
|
require.Equal(t, CodeMissingYear, *f.StatusReason)
|
|
pl := planner.plan(context.Background(), f, *f.Meta, f.TargetSourceID)
|
|
require.Equal(t, f.TargetRelPath, pl.RelPath)
|
|
require.Nil(t, f.Meta.Year, "path rendering must not invent metadata")
|
|
year := 2026
|
|
f.Meta.Year = &year
|
|
planner.previewPlacement(context.Background(), &f)
|
|
require.Equal(t, "Artist/Artist - Album (2026)/Song.mp3", *f.TargetRelPath)
|
|
require.Nil(t, f.StatusReason)
|
|
}
|
|
|
|
func (r previewRoot) Root(library.Source) (string, error) { return string(r), nil }
|
|
|
|
func TestPreviewUsesCurrentImportTemplate(t *testing.T) {
|
|
ctx := context.Background()
|
|
root := t.TempDir()
|
|
catalog := &previewCatalog{source: library.Source{ID: uuid.New(), Name: "Base", Type: library.SourceLocal,
|
|
AcceptsUploads: true, WriteTemplate: nullable("{albumartist}/{album}/{title}.{ext}")}}
|
|
planner := &PlacementPlanner{store: previewStore{}, lib: catalog, roots: previewRoot(root)}
|
|
track := 3
|
|
year := 2026
|
|
f := File{Status: StatusPendingReview, OriginalName: "song.flac", Meta: &Meta{
|
|
Artist: "Artist", AlbumArtist: "Artist", Album: "Album", Title: "Song", Track: &track, Year: &year},
|
|
TargetSourceID: &catalog.source.ID, TargetRelPath: nullable("stale/path.flac"), StatusReason: nullable(CodeNoTarget)}
|
|
planner.previewPlacement(ctx, &f)
|
|
require.Equal(t, "Artist/Album/Song.flac", *f.TargetRelPath)
|
|
require.Equal(t, filepath.Join(root, "Artist", "Album", "Song.flac"), *f.TargetStoragePath)
|
|
require.Nil(t, f.StatusReason)
|
|
|
|
catalog.source.WriteTemplate = nullable("{albumartist}/{album}/{track:02} - {title}.{ext}")
|
|
planner.previewPlacement(ctx, &f)
|
|
planned := planner.plan(ctx, f, *f.Meta, f.TargetSourceID)
|
|
require.Equal(t, "Artist/Album/03 - Song.flac", *f.TargetRelPath)
|
|
require.Equal(t, planned.RelPath, f.TargetRelPath, "preview and import must use the same path")
|
|
|
|
catalog.source.Type = library.SourceNFS
|
|
catalog.source.NFSServer, catalog.source.NFSExport = nullable("nas"), nullable("/music/")
|
|
planner.previewPlacement(ctx, &f)
|
|
require.Equal(t, "nas:/music/Artist/Album/03 - Song.flac", *f.TargetStoragePath)
|
|
|
|
f.Status = StatusImported
|
|
catalog.source.WriteTemplate = nullable("changed/{title}.{ext}")
|
|
planner.previewPlacement(ctx, &f)
|
|
require.Equal(t, "Artist/Album/03 - Song.flac", *f.TargetRelPath, "imported files retain their actual destination")
|
|
|
|
f.Status = StatusPendingReview
|
|
catalog.source.WriteTemplate = nil
|
|
planner.previewPlacement(ctx, &f)
|
|
require.Nil(t, f.TargetRelPath, "invalid configuration must not show the stale path")
|
|
require.Nil(t, f.TargetStoragePath)
|
|
require.Equal(t, CodeTemplate, *f.StatusReason)
|
|
// Reading a preview does not write to the store or change the review status.
|
|
require.Equal(t, StatusPendingReview, f.Status)
|
|
}
|