package match import ( "context" "strings" "testing" "navimigrate/internal/model" "navimigrate/internal/navidrome" ) type fakeSearcher struct { tracks []navidrome.Track } func (f fakeSearcher) SearchTracks(context.Context, string, int) ([]navidrome.Track, error) { return f.tracks, nil } func TestNormalizeTransliteratesCyrillic(t *testing.T) { got := normalize("детство") if got != "detstvo" { t.Fatalf("expected detstvo, got %q", got) } } func TestBuildQueriesIncludesLatinVariant(t *testing.T) { m := NewMatcher(fakeSearcher{}, 45) q := m.buildQueries(model.Track{ Title: "детство", Artists: []string{"Rauf & Faik"}, }) joined := strings.Join(q, "\n") if !strings.Contains(strings.ToLower(joined), "detstvo") { t.Fatalf("expected transliterated query to include detstvo, got %v", q) } } func TestMatchThresholdIsConfigurable(t *testing.T) { src := model.Track{ Title: "One More Time", Artists: []string{"Daft Punk"}, DurationMS: 317000, } candidate := navidrome.Track{ ID: "track-1", Title: "One More Time", Artist: "Daft Punk", Duration: 317, } m := NewMatcher(fakeSearcher{tracks: []navidrome.Track{candidate}}, 100) res := m.MatchTrack(context.Background(), src) if res.Matched { t.Fatalf("expected no match with high threshold, score=%.1f", res.Score) } m = NewMatcher(fakeSearcher{tracks: []navidrome.Track{candidate}}, 0) res = m.MatchTrack(context.Background(), src) if !res.Matched { t.Fatalf("expected match with low threshold, score=%.1f", res.Score) } }