soulsync/tests/imports/test_normalize_disc_number.py
BoulderBadgeDad c11a742e58 Multi-disc albums: never write a disc-less track (floor disc to >=1)
Sokhi: some tracks in a multi-disc album showed up with a null disc in Jellyfin
and floated ungrouped above the disc sections (tracks 3/9/15). Mechanism: the tag
writer only wrote the disc tag when disc_number was truthy, and enrichment CLEARS
all tags before rewriting — so a track whose disc came back 0 / None / '' lost its
disc entirely. Those falsy values slipped through because source.py defaulted with
'is not None' (a literal 0 passed) and context.py's or-chain can yield None; this
happens especially when a track resolves to a different edition than its siblings.

Fix: normalize_disc_number() floors any value to >=1, and enrichment now writes the
disc tag UNCONDITIONALLY (like the track number) so a track is never disc-less.
source.py uses the same floor so the metadata dict (and the 'Disc N' folder org)
stays consistent. Valid multi-disc values are preserved untouched.

Tests: normalize floors 0/None/''/negatives/non-numeric -> 1, preserves 1..4 and
tolerates '2.0'. 1406 enrich/metadata/track-number tests green, ruff clean.

NOTE: this fixes the SYMPTOM (never ungrouped). The deeper cause — a track matching
a DIFFERENT edition/release than its album siblings (the Persona-box-set mismatch in
the sample file; the canonical-version problem) — is separate and still open.
2026-06-22 09:30:04 -07:00

31 lines
1.2 KiB
Python

"""Sokhi: some tracks in a multi-disc album got a null disc in Jellyfin and floated
ungrouped above the disc sections. Root cause: the tag-writer only wrote the disc
tag when disc_number was truthy, and upstream a 0 / None / '' (esp. when a track
matched a different edition than its siblings) slipped through — so on the
clear-then-rewrite those tracks lost their disc entirely. normalize_disc_number
floors any value to >=1 so a track is never written disc-less."""
from __future__ import annotations
import pytest
from core.imports.track_number import normalize_disc_number
@pytest.mark.parametrize("value,expected", [
(1, 1), (2, 2), (4, 4),
("1", 1), ("3", 3), (" 2 ", 2),
(0, 1), ("0", 1), # the bug: 0 must floor to 1, not vanish
(None, 1), ("", 1), (" ", 1),
(-1, 1), ("-2", 1), # negatives floor to 1
("abc", 1), ("1/4", 1), # non-numeric -> 1 (never raises)
(2.0, 2), # float-ish via str()
])
def test_normalize_disc_number(value, expected):
assert normalize_disc_number(value) == expected
def test_valid_multidisc_values_preserved():
# a real disc on a 4xLP must survive untouched
for d in (1, 2, 3, 4):
assert normalize_disc_number(d) == d