Skip to content

Commit d7cab14

Browse files
committed
Fix ValueError in calculate_work() when licensed_through is transiently empty (PP-3977)
1 parent d969d5f commit d7cab14

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/palace/manager/sqlalchemy/model/licensing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,7 @@ def calculate_work(
12241224
lp.work = None
12251225
if lp.presentation_edition:
12261226
lp.presentation_edition.work = None
1227-
else:
1227+
elif len(existing_works) == 1:
12281228
# There is a consensus Work for this Identifier.
12291229
[self.work] = existing_works
12301230

tests/manager/sqlalchemy/model/test_work.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,36 @@ def test_calculate_work_success(self, db: DatabaseTransactionFixture):
21462146
assert p.presentation_edition == work.presentation_edition
21472147
assert True == new
21482148

2149+
def test_calculate_work_does_not_raise_when_licensed_through_is_empty(
2150+
self, db: DatabaseTransactionFixture
2151+
):
2152+
"""Regression test: calculate_work() must not raise ValueError when
2153+
licensed_through is transiently empty (no existing works to unpack).
2154+
2155+
This could happen when the relationship collection is stale or has not
2156+
yet been populated, resulting in an empty ``existing_works`` set. The
2157+
original code used a bare destructuring assignment
2158+
``[self.work] = existing_works`` which raised
2159+
``ValueError: not enough values to unpack (expected 1, got 0)``.
2160+
"""
2161+
from unittest.mock import PropertyMock
2162+
2163+
edition, pool = db.edition(with_license_pool=True)
2164+
2165+
# Temporarily replace the licensed_through descriptor on the Identifier
2166+
# class so that it returns an empty list, simulating a transient state
2167+
# where the relationship collection has not yet been populated.
2168+
with patch.object(
2169+
type(pool.identifier),
2170+
"licensed_through",
2171+
new_callable=PropertyMock,
2172+
return_value=[],
2173+
):
2174+
work, created = pool.calculate_work()
2175+
2176+
assert work is not None
2177+
assert created is True
2178+
21492179
def test_calculate_work_bails_out_if_no_title(self, db: DatabaseTransactionFixture):
21502180
e, p = db.edition(with_license_pool=True)
21512181
e.title = None

0 commit comments

Comments
 (0)