soulsync/tests/test_wing_it_pool.py
BoulderBadgeDad 602b035bad Wing It Pool: review + re-match tracks Wing It auto-matched
Wing It auto-matches tracks to the server library on a best-effort guess; those tracks are flagged wing_it_fallback in extra_data and count as 'discovered', so the Discovery Pool hides them — there was no way to see or audit the guesses. New 'Wing It Pool' button (next to Discovery Pool on the Mirrored Playlists tab) opens a modal listing them with a per-playlist filter + search; 'Fix Match' reuses the Discovery Pool's fix flow (/api/discovery-pool/fix), and a manual match drops the track from the pool on refresh.

No new table or provider hooks needed — the wing-it flag is already persisted, so this is a pure query (get_wing_it_pool / get_wing_it_pool_stats, cloning the failed-pool LIKE pattern) + a /api/wing-it-pool endpoint + a cloned modal. Found 81 wing-it tracks on a real library. Seam-tested (include unverified / exclude manual-matched / scope by playlist+profile).
2026-06-25 13:57:50 -07:00

76 lines
3.5 KiB
Python

"""Wing It Pool query — surfaces tracks Wing It auto-matched (best-effort guesses).
Wing-it tracks are persisted as the ``wing_it_fallback: true`` flag on a mirrored track's
extra_data and count as 'discovered', so the Discovery Pool's failed list excludes them. The
Wing It Pool is the only surface that lists them. It must: include unverified wing-it tracks,
exclude ones the user already manually matched, scope by playlist + profile, and never include
plain matched/failed tracks.
"""
from __future__ import annotations
import json
from database.music_database import MusicDatabase
def _playlist(db, name, profile_id=1, source_id='pl1'):
with db._get_connection() as conn:
cur = conn.execute(
"INSERT INTO mirrored_playlists (source, source_playlist_id, name, profile_id) VALUES (?,?,?,?)",
('spotify', source_id, name, profile_id))
conn.commit()
return cur.lastrowid
def _track(db, playlist_id, pos, name, artist, extra):
with db._get_connection() as conn:
conn.execute(
"INSERT INTO mirrored_playlist_tracks (playlist_id, position, track_name, artist_name, extra_data) "
"VALUES (?,?,?,?,?)",
(playlist_id, pos, name, artist, json.dumps(extra) if extra is not None else None))
conn.commit()
WING_IT = {'discovered': True, 'provider': 'wing_it_fallback', 'confidence': 0, 'wing_it_fallback': True}
WING_IT_FIXED = {'discovered': True, 'provider': 'spotify', 'confidence': 1.0,
'wing_it_fallback': True, 'manual_match': True}
MATCHED = {'discovered': True, 'provider': 'spotify', 'confidence': 0.95}
FAILED = {'discovery_attempted': True, 'discovered': False}
def test_lists_only_unverified_wing_it_tracks(tmp_path):
db = MusicDatabase(database_path=str(tmp_path / "w.db"))
pid = _playlist(db, 'Liked Songs')
_track(db, pid, 0, 'Orbital Trans', 'Yoga Mao', WING_IT) # unverified wing-it -> include
_track(db, pid, 1, 'Dopamine', 'Rvdical the Kid', WING_IT_FIXED) # manually fixed -> exclude
_track(db, pid, 2, 'Real Match', 'Some Artist', MATCHED) # normal match -> exclude
_track(db, pid, 3, 'Lost Track', 'Nobody', FAILED) # failed -> exclude (it's Discovery Pool's)
out = db.get_wing_it_pool(profile_id=1)
assert [t['track_name'] for t in out] == ['Orbital Trans']
assert out[0]['artist_name'] == 'Yoga Mao'
assert out[0]['playlist_name'] == 'Liked Songs'
assert db.get_wing_it_pool_stats(profile_id=1) == {'wing_it': 1}
def test_scopes_by_playlist_and_profile(tmp_path):
db = MusicDatabase(database_path=str(tmp_path / "w2.db"))
a = _playlist(db, 'Playlist A', profile_id=1, source_id='a')
b = _playlist(db, 'Playlist B', profile_id=1, source_id='b')
other = _playlist(db, 'Other Profile', profile_id=2, source_id='c')
_track(db, a, 0, 'A Song', 'AA', WING_IT)
_track(db, b, 0, 'B Song', 'BB', WING_IT)
_track(db, other, 0, 'C Song', 'CC', WING_IT)
assert {t['track_name'] for t in db.get_wing_it_pool(profile_id=1)} == {'A Song', 'B Song'}
assert [t['track_name'] for t in db.get_wing_it_pool(playlist_id=a)] == ['A Song']
assert db.get_wing_it_pool_stats(profile_id=1) == {'wing_it': 2}
def test_empty_when_no_wing_it(tmp_path):
db = MusicDatabase(database_path=str(tmp_path / "w3.db"))
pid = _playlist(db, 'Clean')
_track(db, pid, 0, 'Matched', 'X', MATCHED)
assert db.get_wing_it_pool(profile_id=1) == []
assert db.get_wing_it_pool_stats(profile_id=1) == {'wing_it': 0}