fix: a first watch state and a first Watch later survive two requests at once

The first checkpoint of an item and the final flush beside it both read no
state and both inserted; the loser failed on uq_plex_user_item. Two first saves
each made a Watch later list. Both are created by an ON CONFLICT DO NOTHING
insert and then read; a partial unique index holds one Watch later per user, and
the migration folds an existing second list into the first. Plex keeps one
per-item state map (rollup.item_state_map).
This commit is contained in:
2026-10-20 00:45:22 +02:00
parent b376373af5
commit 3a5212cd8a
11 changed files with 215 additions and 40 deletions
+18
View File
@@ -308,3 +308,21 @@ def test_a_pin_is_one_per_thing_and_only_its_owners(db, make_user):
pins.remove(db, pins.own_pin(db, user, pin.id))
db.commit()
assert db.execute(select(ComfortPin)).first() is None
def test_a_watch_later_save_that_lost_the_race_uses_the_winners_list(db, make_user, monkeypatch):
"""The first two saves at once both read "no Watch later"; the second must land in the list the
first made, not make one of its own."""
user = make_user()
won = service.watch_later(db, user)
db.commit()
real = queries.watch_later
stale = [True] # this request's first read happened before the winner committed
def read(d, u):
return None if stale and stale.pop() else real(d, u)
monkeypatch.setattr(queries, "watch_later", read)
assert service.watch_later(db, user).id == won.id
db.commit()
assert [p.id for p in queries.playlists_for(db, user) if p.kind == "watch_later"] == [won.id]