feat(discovery): DiscoverySuggestion schema + WatchedArtist.lastDiscoveredAt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-11 23:58:45 +02:00
parent 0d2b7f0ae5
commit 0ddc9db611
5 changed files with 129 additions and 5 deletions
+32 -5
View File
@@ -27,9 +27,14 @@ def conn():
cur.execute('DELETE FROM "LibraryItem"')
cur.execute('DELETE FROM "MonitoredRelease"')
cur.execute('DELETE FROM "WatchedArtist"')
cur.execute('DELETE FROM "DiscoverySuggestion"')
cur.execute('DELETE FROM "Config"')
connection.commit()
yield connection
# A test may have left the transaction aborted (e.g. asserting on a
# UniqueViolation via pytest.raises without rolling back); reset it so
# the cleanup below can run.
connection.rollback()
# Clean up rows created during the test (Job cascades from Request).
with connection.cursor() as cur:
cur.execute('DELETE FROM "Job"')
@@ -37,6 +42,7 @@ def conn():
cur.execute('DELETE FROM "LibraryItem"')
cur.execute('DELETE FROM "MonitoredRelease"')
cur.execute('DELETE FROM "WatchedArtist"')
cur.execute('DELETE FROM "DiscoverySuggestion"')
cur.execute('DELETE FROM "Config"')
connection.commit()
connection.close()
@@ -62,14 +68,15 @@ def insert_request(conn, artist="Artist", album="Album"):
def insert_watched_artist(conn, mbid="mbid", name="Artist", auto_monitor_future=False,
monitor_from_sql="now()", last_polled_sql="NULL"):
"""Insert a WatchedArtist; monitor_from_sql / last_polled_sql are raw SQL time expressions."""
monitor_from_sql="now()", last_polled_sql="NULL",
last_discovered_sql="NULL"):
"""Insert a WatchedArtist; *_sql args are raw SQL time expressions."""
with conn.cursor() as cur:
cur.execute(
'INSERT INTO "WatchedArtist" (id, mbid, name, "autoMonitorFuture", '
f'"monitorFrom", "lastPolledAt", "createdAt") '
f"VALUES (gen_random_uuid()::text, %s, %s, %s, {monitor_from_sql}, {last_polled_sql}, now()) "
"RETURNING id",
f'"monitorFrom", "lastPolledAt", "lastDiscoveredAt", "createdAt") '
f"VALUES (gen_random_uuid()::text, %s, %s, %s, {monitor_from_sql}, "
f"{last_polled_sql}, {last_discovered_sql}, now()) RETURNING id",
(mbid, name, auto_monitor_future),
)
artist_id = cur.fetchone()[0]
@@ -97,3 +104,23 @@ def insert_monitored_release(conn, watched_artist_id=None, artist_mbid="mbid", a
rel_id = cur.fetchone()[0]
conn.commit()
return rel_id
def insert_discovery_suggestion(conn, kind="artist", artist_mbid="cand", artist_name="Cand",
rg_mbid=None, album=None, score=1.0, seed_count=1,
sources=None, status="pending"):
"""Insert a DiscoverySuggestion; returns its id."""
dedupe = f"{kind}:{artist_mbid}:{rg_mbid or ''}"
with conn.cursor() as cur:
cur.execute(
'INSERT INTO "DiscoverySuggestion" (id, kind, "artistMbid", "artistName", '
'"rgMbid", album, score, "seedCount", sources, status, "dedupeKey", '
'"createdAt", "updatedAt") '
'VALUES (gen_random_uuid()::text, %s::"DiscoveryKind", %s, %s, %s, %s, %s, %s, %s, '
'%s::"SuggestionStatus", %s, now(), now()) RETURNING id',
(kind, artist_mbid, artist_name, rg_mbid, album, score, seed_count,
sources if sources is not None else ["listenbrainz"], status, dedupe),
)
sid = cur.fetchone()[0]
conn.commit()
return sid
+31
View File
@@ -0,0 +1,31 @@
import psycopg
import pytest
from tests.conftest import insert_discovery_suggestion, insert_watched_artist
def test_suggestion_round_trip(conn):
sid = insert_discovery_suggestion(
conn, kind="album", artist_mbid="a1", artist_name="Boygenius",
rg_mbid="rg1", album="the record", score=2.5, seed_count=2,
sources=["listenbrainz"], status="pending",
)
with conn.cursor() as cur:
cur.execute(
'SELECT kind::text, "artistName", "rgMbid", album, score, "seedCount", '
'sources, status::text FROM "DiscoverySuggestion" WHERE id = %s', (sid,))
assert cur.fetchone() == (
"album", "Boygenius", "rg1", "the record", 2.5, 2, ["listenbrainz"], "pending")
def test_dedupe_key_is_unique(conn):
insert_discovery_suggestion(conn, kind="artist", artist_mbid="dup", rg_mbid=None)
with pytest.raises(psycopg.errors.UniqueViolation):
insert_discovery_suggestion(conn, kind="artist", artist_mbid="dup", rg_mbid=None)
def test_watched_artist_has_last_discovered_column(conn):
insert_watched_artist(conn, mbid="a1", last_discovered_sql="now()")
with conn.cursor() as cur:
cur.execute('SELECT "lastDiscoveredAt" IS NOT NULL FROM "WatchedArtist" WHERE mbid = %s', ("a1",))
assert cur.fetchone()[0] is True