"""Round 52 — Identify Track stops calling Dionne Farris "Jay-Z". trav's "Dionne Farris - I Know [fqng9NDqKB8].mp3" kept being identified as Jay-Z's "I Know" from American Gangster, and AcoustID was not at fault. The fingerprint matched one AcoustID result at 0.97, and *six* recordings hang off that one result — Dionne Farris twice, plus Jay-Z, Marisela, New Atlantic and David Essex, all of whom recorded a song called "I Know". The score belongs to the audio, so all six carried 0.97, and ranking fell through to the duration bucket, where Jay-Z's 222.7 s beat Dionne's 227.3 s against a 224 s file. The tags said "dionne farris" the whole time. Two things were missing. The lookup never asked for ``sources`` — how many people submitted each link, which is 475 for Dionne against 6 for Jay-Z and 1 for the rest — and nothing compared the candidates' artist against the file's own. So the ranking now goes: strays below real links, then the artist the file names, then the take whose length matches, then the release the hint echoes. """ import pytest from lintunes import fingerprint from lintunes.fingerprint import ( artist_hint_for, lookup_fingerprint, parse_lookup, ) class _Track: def __init__(self, name="", artist="", album="", album_artist="", location=""): self.track_id = 1 self.name = name self.artist = artist self.album = album self.album_artist = album_artist self.location = location def _group(title, year, type_="Album", secondary=None): return {"title": title, "type": type_, "secondarytypes": list(secondary or []), "releases": [{"date": {"year": year} if year else {}}]} def _recording(title, artist, duration=None, sources=None, groups=()): rec = {"title": title, "artists": [{"name": artist}], "releasegroups": list(groups)} if duration is not None: rec["duration"] = duration if sources is not None: rec["sources"] = sources return rec def _payload(*recordings, score=0.9695): return {"status": "ok", "results": [{"score": score, "recordings": list(recordings)}]} # The real response, trimmed to the release groups that matter. Durations and # source counts are exactly what AcoustID returned for trav's file; the file # itself is 224 s, which is why Jay-Z used to win. def _i_know_payload(): return _payload( _recording("I Know", "Marisela", duration=227.8, sources=1, groups=[_group("Salsa: Original Motion Picture Soundtrack", 1988)]), _recording("I Know (NY reprise mix)", "Dionne Farris", duration=229.4, sources=11, groups=[_group("I Know", 1994, type_="Single")]), _recording("I Know", "Jay‐Z", duration=222.706, sources=6, groups=[_group("American Gangster", 2007)]), _recording("I Know", "New Atlantic", duration=238.986, sources=1, groups=[_group("Very Best of Back to the Old Skool", 2001, secondary=["Compilation"])]), _recording("I Know", "David Essex", duration=214.0, sources=1, groups=[_group("David Essex", 1974)]), _recording("I Know", "Dionne Farris", duration=227.266, sources=475, groups=[_group("Wild Seed - Wild Flower", 1994), _group("The Hangover Cure: Time to Chill", 1996, secondary=["Compilation"])]), ) DIONNE_TRACK = _Track( name="I Know", artist="dionne farris", album="Wild Seed – Wild Flower", location="/m/dionne farris/Wild Seed – Wild Flower/" "Dionne Farris - I Know [fqng9NDqKB8].mp3") class TestTheDionneFarrisCase: def test_the_file_is_no_longer_told_it_is_jay_z(self): top = parse_lookup(_i_know_payload(), duration=224, hint=fingerprint.hint_for(DIONNE_TRACK), artist_hint=artist_hint_for(DIONNE_TRACK))[0] assert top.artist == "Dionne Farris" assert top.album == "Wild Seed - Wild Flower" assert top.year == 1994 def test_submissions_alone_settle_it_when_the_file_says_nothing(self): """An untagged rip has no artist to agree with, and 475 links against 6 still say whose song this is.""" top = parse_lookup(_i_know_payload(), duration=224)[0] assert top.artist == "Dionne Farris" def test_a_stray_link_cannot_confirm_a_wrong_tag(self): """Tagged Jay-Z, so agreement points at the mis-tag — but 6 links against 475 is a stray, and strays rank below real links.""" wrong = _Track(name="I Know", artist="Jay-Z", location="/m/x/y/z.mp3") top = parse_lookup(_i_know_payload(), duration=224, hint=fingerprint.hint_for(wrong), artist_hint=artist_hint_for(wrong))[0] assert top.artist == "Dionne Farris" def test_a_closer_duration_no_longer_outranks_the_artist(self): """The whole bug in one line: Jay-Z's take is the closest match by length, and it still must not win.""" best_length = min( _i_know_payload()["results"][0]["recordings"], key=lambda r: abs(r["duration"] - 224)) assert best_length["artists"][0]["name"] == "Jay‐Z" top = parse_lookup(_i_know_payload(), duration=224, artist_hint="Dionne Farris")[0] assert top.artist == "Dionne Farris" class TestContestedLinks: """Two links people genuinely submitted, rather than one and a stray.""" def _contested(self): return _payload( _recording("Shadow", "The Loud Ones", duration=180.0, sources=20, groups=[_group("Loud Album", 2001)]), _recording("Shadow", "Quiet Hour", duration=180.0, sources=3, groups=[_group("Quiet Album", 2001)]), ) def test_the_files_own_tags_decide(self): top = parse_lookup(self._contested(), duration=180, artist_hint="Quiet Hour")[0] assert top.artist == "Quiet Hour" def test_without_tags_the_stronger_link_leads(self): assert parse_lookup(self._contested(), duration=180)[0].artist == \ "The Loud Ones" def test_a_tenth_is_the_line_between_a_rival_and_a_stray(self): assert fingerprint._link_tier({"sources": 3}, 20) == 0 assert fingerprint._link_tier({"sources": 1}, 20) == 1 class TestNoEvidenceChangesNothing: def test_a_payload_without_sources_ranks_as_before(self): """Older responses (and every canned payload in rounds 45–46) carry no counts, so nothing may be demoted for lacking them.""" payload = _payload( _recording("Snowfall", "The Band", duration=155.0, groups=[_group("The Long Take", 2000)]), _recording("Snowfall", "The Band", duration=150.3, groups=[_group("The Short Take", 2000)]), ) assert parse_lookup(payload, duration=150)[0].album == "The Short Take" def test_a_result_where_nobody_reported_counts_demotes_nothing(self): assert fingerprint._link_tier({}, 0) == 0 assert fingerprint._link_tier({"sources": 1}, 0) == 0 def test_a_placeholder_artist_agrees_with_nothing(self): track = _Track(artist="Unknown Artist", location="/m/Unknown Artist/Unknown Album/blurf.mp3") tokens = fingerprint._artist_tokens(artist_hint_for(track)) assert tokens == set() def test_duration_still_separates_takes_by_one_artist(self): """Artist agreement ties between two takes by the same person, so length decides — the round 46 rule, intact.""" payload = _payload( _recording("Snowfall", "Ahmad Jamal", duration=155.0, sources=50, groups=[_group("The Long Take", 2000)]), _recording("Snowfall", "Ahmad Jamal", duration=150.3, sources=50, groups=[_group("The Short Take", 2000)]), ) assert parse_lookup(payload, duration=150, artist_hint="Ahmad Jamal")[0].album == \ "The Short Take" class TestArtistHint: def test_it_gathers_tags_and_the_filename(self): track = _Track(artist="dionne farris", album_artist="Dionne Farris", location="/m/x/y/Dionne Farris - I Know [fqng9NDqKB8].mp3") assert artist_hint_for(track).lower().count("dionne") == 3 def test_a_track_with_no_artist_anywhere_hints_nothing(self): assert artist_hint_for(_Track()) == "" def test_the_title_is_not_part_of_it(self): """Only the artist: every candidate here is titled "I Know", so title words separate nothing and would just dilute the agreement count.""" assert "know" not in artist_hint_for(DIONNE_TRACK).lower() class TestTheLookupAsksForSources: def test_meta_requests_submission_counts(self, monkeypatch): sent = {} class FakeResponse: def raise_for_status(self): pass def json(self): return _i_know_payload() import requests monkeypatch.setattr(requests, "post", lambda *a, **k: sent.update(k["data"]) or FakeResponse()) candidates = lookup_fingerprint("key", 224, "fp", hint="I Know dionne farris", artist_hint="dionne farris") assert "sources" in sent["meta"] assert candidates[0].artist == "Dionne Farris" @pytest.mark.parametrize("artist, expected", [ ("Dionne Farris", 2), ("Jay-Z", 0), ("", 0), ]) def test_agreement_counts_shared_artist_words(artist, expected): candidate = fingerprint.IdentifyCandidate(score=1.0, artist="Dionne Farris") tokens = fingerprint._artist_tokens(artist) assert fingerprint._artist_agreement(tokens, candidate) == expected