You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SoulSync/tests/test_lb_series_detect.py

90 lines
3.8 KiB

"""Tests for the LB rotating-series detector that powers the
rolling-mirror collapse on the Sync page.
Pins the title patterns + canonical-name templates so accidental
regex tweaks don't silently break the auto-mirror grouping the
Auto-Sync manager + Mirrored tab rely on.
"""
from __future__ import annotations
import pytest
from core.playlists.lb_series import (
detect_series,
is_series_synthetic_id,
list_series_synthetic_ids,
)
class TestDetectSeries:
def test_weekly_jams_collapses_into_rolling_series(self):
m = detect_series("Weekly Jams for Nezreka, week of 2026-05-25 Mon")
assert m is not None
assert m.series_id == "lb_weekly_jams_Nezreka"
assert m.canonical_name == "ListenBrainz Weekly Jams"
assert m.source_for_mirror == "listenbrainz"
assert m.title_pattern == "Weekly Jams for Nezreka, week of %"
def test_weekly_exploration_collapses_into_rolling_series(self):
m = detect_series("Weekly Exploration for Nezreka, week of 2026-04-13 Mon")
assert m is not None
assert m.series_id == "lb_weekly_exploration_Nezreka"
assert m.canonical_name == "ListenBrainz Weekly Exploration"
assert m.title_pattern == "Weekly Exploration for Nezreka, week of %"
def test_top_discoveries_collapses_per_user(self):
m = detect_series("Top Discoveries of 2024 for Nezreka")
assert m is not None
assert m.series_id == "lb_top_discoveries_Nezreka"
assert m.canonical_name == "ListenBrainz Top Discoveries (latest year)"
assert m.title_pattern == "Top Discoveries of % for Nezreka"
def test_top_missed_collapses_per_user(self):
m = detect_series("Top Missed Recordings of 2025 for Nezreka")
assert m is not None
assert m.series_id == "lb_top_missed_Nezreka"
assert m.canonical_name == "ListenBrainz Top Missed Recordings (latest year)"
def test_user_with_spaces_in_name(self):
# ListenBrainz allows usernames with spaces; the regex should
# still match and the series id propagates the literal user
# token. Whether SQLite LIKE works on that is the caller's
# problem — we just preserve the captured value.
m = detect_series("Weekly Jams for Some User, week of 2026-01-05 Mon")
assert m is not None
assert m.series_id == "lb_weekly_jams_Some User"
def test_lastfm_radio_is_not_a_series(self):
# Last.fm radios get their own per-seed MBID — they should NOT
# be collapsed into a rolling series.
assert detect_series("Last.fm Radio: Selfish by Madison Beer") is None
def test_user_created_playlist_is_not_a_series(self):
assert detect_series("My Custom Playlist") is None
def test_empty_title_returns_none(self):
assert detect_series("") is None
assert detect_series(None) is None # type: ignore[arg-type]
class TestSyntheticIdHelpers:
def test_known_prefixes_listed(self):
prefixes = list_series_synthetic_ids()
assert "lb_weekly_jams_" in prefixes
assert "lb_weekly_exploration_" in prefixes
assert "lb_top_discoveries_" in prefixes
assert "lb_top_missed_" in prefixes
def test_is_series_synthetic_id_matches_known(self):
assert is_series_synthetic_id("lb_weekly_jams_Nezreka") is True
assert is_series_synthetic_id("lb_weekly_exploration_OtherUser") is True
assert is_series_synthetic_id("lb_top_discoveries_X") is True
def test_is_series_synthetic_id_rejects_mbids(self):
# Real LB playlist MBIDs are UUID-shaped, never start with ``lb_``.
assert is_series_synthetic_id("4badb5c9-266e-42ef-9d06-879ee311c9e0") is False
assert is_series_synthetic_id("") is False
assert is_series_synthetic_id("lb_") is False # not a real series
assert is_series_synthetic_id("lb_random_thing") is False