65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
"""Tests for conservative Spotify candidate matching."""
|
|
|
|
from app.domain.matching import judge_candidate_match, normalize_text, title_similarity
|
|
from app.domain.models import Track, TrackCandidate
|
|
|
|
|
|
def test_normalization_removes_case_punctuation_marks_and_suffixes() -> None:
|
|
value = " H\u00e9llo, WORLD! (2011 Remaster) [Deluxe] "
|
|
|
|
assert normalize_text(value) == "hello world"
|
|
|
|
|
|
def test_title_similarity_uses_normalized_values() -> None:
|
|
assert title_similarity("Signal Fire", "Signal Fire (Remastered)") == 1.0
|
|
|
|
|
|
def test_matching_accepts_a_similar_title_with_the_requested_artist() -> None:
|
|
candidate = TrackCandidate(title="The Night Drive", artist="Example Artist")
|
|
track = _track(title="The Night Drive (Radio Edit)", artist="Example Artist")
|
|
|
|
verdict = judge_candidate_match(candidate, track, title_threshold=0.82)
|
|
|
|
assert verdict.is_match
|
|
assert verdict.is_artist_match
|
|
|
|
|
|
def test_matching_drops_a_title_substitution_from_another_artist() -> None:
|
|
candidate = TrackCandidate(title="The Night Drive", artist="Requested Artist")
|
|
substitution = _track(title="The Night Drive", artist="Different Artist")
|
|
|
|
verdict = judge_candidate_match(candidate, substitution, title_threshold=0.82)
|
|
|
|
assert not verdict.is_match
|
|
assert verdict.title_similarity == 1.0
|
|
assert not verdict.is_artist_match
|
|
|
|
|
|
def test_matching_drops_a_weak_title_even_for_the_right_artist() -> None:
|
|
candidate = TrackCandidate(title="The Night Drive", artist="Requested Artist")
|
|
substitution = _track(title="Morning Train", artist="Requested Artist")
|
|
|
|
assert not judge_candidate_match(candidate, substitution, title_threshold=0.82).is_match
|
|
|
|
|
|
def _track(*, title: str, artist: str) -> Track:
|
|
return Track(
|
|
id="track-id",
|
|
uri="spotify:track:track-id",
|
|
title=title,
|
|
artists=(artist,),
|
|
album_name="Album",
|
|
album_art_url=None,
|
|
external_url=None,
|
|
)
|
|
|
|
|
|
def test_title_similarity_tolerates_version_dash_suffix() -> None:
|
|
assert title_similarity("Immunity", "Immunity - Remaster 2023") > 0.95
|
|
assert title_similarity("Nightcall", "Nightcall - Breakbot Remix") > 0.95
|
|
|
|
|
|
def test_title_similarity_prefers_the_unsuffixed_release() -> None:
|
|
plain = title_similarity("Immunity", "Immunity")
|
|
suffixed = title_similarity("Immunity", "Immunity - Remaster 2023")
|
|
assert plain > suffixed
|