fix: every first watch state survives a write beside it, and a folded Watch later keeps its pin
A season marked watched, a pull from Plex and a YouTube resume point made their first row by a read then an add, and failed on the unique key when a first checkpoint or the watched mark made it in between. They go through the same insert-then-read as the checkpoint (the resume point is one upsert); a pull that meets a local change still waiting for its push leaves it. Folding duplicate Watch later lists moved their videos but not a Home pin, which the cascade then deleted; the first pin of a dropped copy moves onto the kept list. Marking one notice read trimmed before its own flag was flushed, so the trim left one past the cap. The route test now crosses the cap and reads the result from a session of its own.
This commit is contained in:
@@ -326,3 +326,18 @@ def test_a_watch_later_save_that_lost_the_race_uses_the_winners_list(db, make_us
|
||||
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]
|
||||
|
||||
|
||||
def test_a_first_resume_point_beside_the_watched_mark_lands_on_its_row(db, make_user, monkeypatch):
|
||||
"""The first checkpoint of a video and the end-of-playback mark both read "no row"; the
|
||||
checkpoint that writes second must update the mark's row, not fail on `uq_user_video`."""
|
||||
user = make_user()
|
||||
_videos(db, "v1")
|
||||
service.mark(db, user, "v1", "watched") # the mark that won, committed
|
||||
db.commit()
|
||||
monkeypatch.setattr(queries, "video_state", lambda *a, **k: None) # read before it committed
|
||||
service.set_progress(db, user, "v1", 90)
|
||||
db.commit()
|
||||
db.expire_all()
|
||||
rows = db.execute(select(VideoState)).scalars().all()
|
||||
assert [(r.status, r.position_seconds) for r in rows] == [("watched", 90)]
|
||||
|
||||
Reference in New Issue
Block a user