Files
pipu-music/services/api/internal/uploads/release_audio_test.go
T
mrleo1nid 39bf7d4b70
ci / module boundaries / boundaries (push) Successful in 10s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m30s
ci / api / api (push) Successful in 58s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m1s
ci / db / db (push) Failing after 25s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m36s
ci / ts / ts (packages + web) (push) Failing after 6m3s
feat(uploads): match release groups with MusicBrainz and AcoustID
2026-10-29 20:44:59 +03:00

91 lines
3.5 KiB
Go

package uploads
import (
"context"
"errors"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"pipu/api/internal/acoustid"
"pipu/api/internal/musicbrainz"
)
func TestAudioRecognitionRejectsWeakAndAmbiguousRecordings(t *testing.T) {
a, b := uuid.NewString(), uuid.NewString()
for _, tc := range []struct {
matches []acoustid.Match
state string
}{
{nil, "not_found"},
{[]acoustid.Match{{RecordingID: a, Score: .89}}, "ambiguous"},
{[]acoustid.Match{{RecordingID: a, Score: .99}, {RecordingID: b, Score: .97}}, "ambiguous"},
{[]acoustid.Match{{RecordingID: a, Score: .99}, {RecordingID: a, Score: .98}, {RecordingID: b, Score: .7}}, "matched"},
{[]acoustid.Match{{RecordingID: "invalid", Score: 1}}, "not_found"},
} {
r := chooseAudioMatch(uuid.New(), tc.matches)
require.Equal(t, tc.state, r.State)
if tc.state != "matched" {
require.Empty(t, r.RecordingID)
}
}
}
func TestAudioOverridesWrongTagsButDoesNotProveEditionOrDuration(t *testing.T) {
id := uuid.NewString()
f := releaseFile("Wrong title", 9, 1, 180000)
r := musicbrainz.Release{Tracks: []musicbrainz.Track{{RecordingID: id, Title: "Correct title", Artist: "Correct artist", Position: 1, Disc: 1, DurationMs: 180000}}}
audio := map[uuid.UUID]AudioRecognition{f.ID: {FileID: f.ID, State: "matched", RecordingID: id, Score: .99}}
c := matchReleaseWithAudio([]File{f}, r, audio)
require.True(t, c.Complete)
require.Equal(t, "acoustid", c.Matches[0].Method)
require.Equal(t, "Wrong title", f.Meta.Title)
require.Empty(t, f.Tags)
r.Tracks = append(r.Tracks, r.Tracks[0])
c = matchReleaseWithAudio([]File{f}, r, audio)
require.False(t, c.Complete)
require.Empty(t, c.Matches, "same recording twice in an edition remains ambiguous")
r.Tracks = r.Tracks[:1]
r.Tracks[0].DurationMs = 195000
c = matchReleaseWithAudio([]File{f}, r, audio)
require.False(t, c.Complete)
require.Equal(t, "medium", c.Matches[0].Confidence)
r.Tracks[0].RecordingID = uuid.NewString()
c = matchReleaseWithAudio([]File{f}, r, audio)
require.Empty(t, c.Matches)
}
type testAudioIdentifier struct {
calls int
err error
id string
duration int
}
func (a *testAudioIdentifier) Lookup(_ context.Context, fp string, duration int) ([]acoustid.Match, error) {
a.calls++
a.duration = duration
return []acoustid.Match{{RecordingID: a.id, Score: .99}}, a.err
}
func TestAudioIdentificationUsesFullDurationAndSkipsUnavailableFiles(t *testing.T) {
f := releaseFile("Unknown", 1, 1, 321000)
f.StagingPath = "batch/file.flac"
provider := &testAudioIdentifier{id: uuid.NewString()}
s := &Service{cfg: Config{StagingDir: t.TempDir()}, identifier: provider, encodedFingerprint: func(context.Context, string) (string, error) { return "fp", nil }}
results, byFile, ids, err := s.identifyAudio(context.Background(), []File{f})
require.NoError(t, err)
require.Len(t, results, 1)
require.Equal(t, 321, provider.duration)
require.Equal(t, provider.id, byFile[f.ID].RecordingID)
require.Equal(t, []string{provider.id}, ids)
s.encodedFingerprint = func(context.Context, string) (string, error) { return "", errors.New("fpcalc missing") }
results, _, ids, err = s.identifyAudio(context.Background(), []File{f})
require.NoError(t, err)
require.Equal(t, "unavailable", results[0].State)
require.Empty(t, ids)
require.Equal(t, 1, provider.calls)
s.encodedFingerprint = func(context.Context, string) (string, error) { return "fp", nil }
provider.err = errors.New("provider offline")
_, _, _, err = s.identifyAudio(context.Background(), []File{f})
require.ErrorContains(t, err, "provider offline")
}