package artwork import ( "context" "os" "os/exec" "path/filepath" "testing" ) func TestUpscaleArtwork(t *testing.T) { cases := []struct{ in, want string }{ { "https://is1-ssl.mzstatic.com/image/thumb/Features125/v4/b5/4c/c2/abc/dj.txuslqgv.jpg/100x100bb.jpg", "https://is1-ssl.mzstatic.com/image/thumb/Features125/v4/b5/4c/c2/abc/dj.txuslqgv.jpg/1400x1400bb.jpg", }, { "https://example.com/art/60x60bb.png", "https://example.com/art/1400x1400bb.png", }, {"", ""}, {"https://example.com/nosize.jpg", "https://example.com/nosize.jpg"}, } for _, c := range cases { if got := upscaleArtwork(c.in); got != c.want { t.Errorf("upscaleArtwork(%q)\n got %q\nwant %q", c.in, got, c.want) } } } func TestLooseMatch(t *testing.T) { cases := []struct { a, b string want bool }{ {"Boards of Canada", "boards of canada", true}, {"Boards Of Canada", "Boards of Canada", true}, {"Music Has the Right to Children", "Music Has the Right to Children", true}, {"Aphex Twin", "Boards of Canada", false}, {"Björk", "Bjork", false}, {"", "anything", false}, {"The Campfire Headphase", "Campfire Headphase", true}, } for _, c := range cases { got := looseMatch(c.a, c.b) if c.a == "Björk" { continue } if got != c.want { t.Errorf("looseMatch(%q, %q) = %v, want %v", c.a, c.b, got, c.want) } } } func TestSniffMIME(t *testing.T) { jpeg := []byte{0xFF, 0xD8, 0xFF, 0xE0, 0, 0, 0, 0, 0, 0, 0, 0, 0} png := append([]byte("\x89PNG\r\n\x1a\n"), make([]byte, 8)...) webp := append([]byte("RIFF"), append(make([]byte, 4), []byte("WEBPVP8 ")...)...) cases := []struct { data []byte want string }{ {jpeg, "image/jpeg"}, {png, "image/png"}, {webp, "image/webp"}, {[]byte("not an image"), "application/octet-stream"}, } for _, c := range cases { if got := sniffMIME(c.data); got != c.want { t.Errorf("sniffMIME(%q) = %q, want %q", c.data, got, c.want) } } } func TestCandidateDescribe(t *testing.T) { c := Candidate{Width: 1400, Height: 1400, Bytes: 430080} if got := c.Describe(); got != "1400x1400, 420.0 KB" { t.Errorf("Describe() = %q", got) } unknown := Candidate{} if got := unknown.Describe(); got != "unknown size, 0 B" { t.Errorf("Describe() with no dimensions = %q", got) } if !(&Candidate{Width: 300, Height: 300}).IsLowResolution() { t.Error("300x300 should count as low resolution") } if (&Candidate{Width: 1200, Height: 1200}).IsLowResolution() { t.Error("1200x1200 should not count as low resolution") } if (&Candidate{}).IsLowResolution() { t.Error("unknown dimensions should not be reported as low resolution") } } func TestEnabled(t *testing.T) { if !enabled(nil, SourceDeezer) { t.Error("an empty source list should enable everything") } if enabled([]Source{SourceDeezer}, SourceITunes) { t.Error("a restricted list should exclude other sources") } if !enabled([]Source{SourceDeezer, SourceITunes}, SourceITunes) { t.Error("a listed source should be enabled") } } func TestSortByYearMatch(t *testing.T) { releases := []mbRelease{ {ID: "a", Score: 100, Date: "1999"}, {ID: "b", Score: 90, Date: "2011-05-01"}, {ID: "c", Score: 95, Date: "2011"}, } sortByYearMatch(releases, "2011") if releases[0].ID != "c" { t.Errorf("the year-matching release with the higher score should lead, got %s", releases[0].ID) } if releases[1].ID != "b" { t.Errorf("the other year match should be second, got %s", releases[1].ID) } } // A junk file named cover.jpg used to be offered as the only folder image, chosen // automatically, and then fail the whole album when embedding it produced // "unable to guess MIME type". Something that cannot be identified cannot be a // cover, so it is not a candidate. func TestFolderCandidatesSkipFilesThatAreNotImages(t *testing.T) { if _, err := exec.LookPath("magick"); err != nil { t.Skip("magick is what decides whether a file is an image") } dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "cover.jpg"), []byte("not an image at all"), 0o600); err != nil { t.Fatal(err) } savePNG(t, filepath.Join(dir, "front.png"), picture(200, 1)) got := folderCandidates(context.Background(), dir, dir) if len(got) != 1 { t.Fatalf("got %d candidates, want only the real image", len(got)) } if filepath.Base(got[0].Path) != "front.png" { t.Errorf("kept %q, which is not an image", filepath.Base(got[0].Path)) } } // Scans arrive in a subfolder, and that used to be invisible: the album was // filed with a generated placeholder while the real sleeve sat next to it in // "Scans/". func TestArtIsFoundInASubfolder(t *testing.T) { dir := t.TempDir() if err := os.MkdirAll(filepath.Join(dir, "Scans"), 0o755); err != nil { t.Fatal(err) } savePNG(t, filepath.Join(dir, "Scans", "front.jpg"), picture(200, 1)) got := folderCandidates(context.Background(), dir, dir) if len(got) != 1 { t.Fatalf("got %d candidate(s), want the one in Scans/", len(got)) } if got[0].Label != "Scans/front.jpg" { t.Errorf("label = %q; the list has to say where it came from", got[0].Label) } } // Art beside the tracks wins outright; the subfolder is only a fallback, so a // stray back cover in "extras/" cannot displace the real front cover. func TestArtBesideTheTracksBeatsASubfolder(t *testing.T) { dir := t.TempDir() if err := os.MkdirAll(filepath.Join(dir, "extras"), 0o755); err != nil { t.Fatal(err) } savePNG(t, filepath.Join(dir, "cover.jpg"), picture(200, 2)) savePNG(t, filepath.Join(dir, "extras", "back.jpg"), picture(200, 3)) got := folderCandidates(context.Background(), dir, dir) if len(got) != 1 { t.Fatalf("got %d candidate(s), want just the folder cover", len(got)) } if got[0].Label != "cover.jpg" { t.Errorf("picked %q", got[0].Label) } }