fix(playlists): what the first review of bulk actions found
An Esc during a pointer drag is spent on the drag and leaves the selection. A wheel over the rail re-reads the target each frame, so a drop lands on the row under the pointer. After a bulk removal the focus goes to the next row left, and to the list's menu when the list is emptied. remove-bulk names the videos that went, and its Undo brings back only those. An Undo of a move keeps each row (and when it was saved), leaves out a video that moved on from the target, closes up its place, and says how many came back. Delete with every tick hidden removes nothing and says why. A list gone before the lock answers 404, and a body without its videos 422. One removal path now: the single row goes through the bulk one, the same toast and undo, which also retires the add-at-position route. railDrop reuses the store and scrollParent, the drag image the overlay and the z-index token, and the sensors keep their number. The count is read out from a region that outlives the band. Tests fill the gaps the review named, each seen failing.
This commit is contained in:
@@ -102,17 +102,24 @@ PLEX = PlexPlaylist.__table__.name
|
||||
"call",
|
||||
[
|
||||
lambda c, pid, other: c.post(f"/api/playlists/{pid}/items", json={"video_id": "v2"}),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items", json={"video_id": "v2", "position": 0}
|
||||
),
|
||||
lambda c, pid, other: c.post("/api/playlists/watch-later", json={"video_id": "v2"}),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/move-bulk",
|
||||
json={"video_ids": ["v1"], "target_playlist_id": other},
|
||||
),
|
||||
lambda c, pid, other: c.put(f"/api/playlists/{pid}/order", json={"video_ids": ["v1"]}),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/remove-bulk", json={"video_ids": ["v1"]}
|
||||
),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/restore", json={"video_ids": ["v2"], "positions": [0]}
|
||||
),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/undo-move",
|
||||
json={"from_playlist_id": other, "moved": ["v2"], "positions": [0]},
|
||||
),
|
||||
],
|
||||
ids=["add", "add-at", "watch-later", "move", "reorder"],
|
||||
ids=["add", "watch-later", "move", "reorder", "remove-bulk", "restore", "undo-move"],
|
||||
)
|
||||
def test_a_youtube_playlist_write_locks_the_playlist(db, make_user, as_user, locks, call):
|
||||
user = make_user()
|
||||
@@ -169,9 +176,6 @@ PLEX_ITEMS = PlexPlaylistItem.__table__.name
|
||||
"call",
|
||||
[
|
||||
lambda c, pid, other: c.post(f"/api/playlists/{pid}/items", json={"video_id": "v1"}),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items", json={"video_id": "v2", "position": 0}
|
||||
),
|
||||
lambda c, pid, other: c.delete(f"/api/playlists/{pid}/items/v1"),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/move-bulk",
|
||||
@@ -180,8 +184,27 @@ PLEX_ITEMS = PlexPlaylistItem.__table__.name
|
||||
lambda c, pid, other: c.put(f"/api/playlists/{pid}/order", json={"video_ids": ["v1"]}),
|
||||
# the ORM cascade deletes the items before the list row
|
||||
lambda c, pid, other: c.delete(f"/api/playlists/{pid}"),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/remove-bulk", json={"video_ids": ["v1"]}
|
||||
),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/restore", json={"video_ids": ["v2"], "positions": [0]}
|
||||
),
|
||||
lambda c, pid, other: c.post(
|
||||
f"/api/playlists/{pid}/items/undo-move",
|
||||
json={"from_playlist_id": other, "moved": ["v2"], "positions": [0]},
|
||||
),
|
||||
],
|
||||
ids=[
|
||||
"add-present",
|
||||
"remove",
|
||||
"move",
|
||||
"reorder",
|
||||
"delete",
|
||||
"remove-bulk",
|
||||
"restore",
|
||||
"undo-move",
|
||||
],
|
||||
ids=["add-present", "add-at", "remove", "move", "reorder", "delete"],
|
||||
)
|
||||
def test_a_youtube_item_write_locks_the_playlist_before_any_item(
|
||||
db, make_user, as_user, statements, call
|
||||
@@ -195,15 +218,23 @@ def test_a_youtube_item_write_locks_the_playlist_before_any_item(
|
||||
assert _locked_before_items(statements, YT, YT_ITEMS), statements
|
||||
|
||||
|
||||
def test_a_move_locks_both_lists_in_one_ordered_statement(db, make_user, as_user, statements):
|
||||
"""Two moves A→B and B→A each locking "its" list first would lock crosswise."""
|
||||
@pytest.mark.parametrize(
|
||||
("path", "body"),
|
||||
[
|
||||
("move-bulk", lambda other: {"video_ids": ["v1"], "target_playlist_id": other}),
|
||||
("undo-move", lambda other: {"from_playlist_id": other, "moved": ["v2"], "positions": [0]}),
|
||||
],
|
||||
ids=["move", "undo"],
|
||||
)
|
||||
def test_a_move_locks_both_lists_in_one_ordered_statement(
|
||||
db, make_user, as_user, statements, path, body
|
||||
):
|
||||
"""Two moves A→B and B→A each locking "its" list first would lock crosswise, and an Undo runs the
|
||||
other way round from a move by its nature."""
|
||||
user = make_user()
|
||||
pid, other = _yt(db, user)
|
||||
statements.clear()
|
||||
r = as_user(user).post(
|
||||
f"/api/playlists/{pid}/items/move-bulk",
|
||||
json={"video_ids": ["v1"], "target_playlist_id": other},
|
||||
)
|
||||
r = as_user(user).post(f"/api/playlists/{pid}/items/{path}", json=body(other))
|
||||
assert r.status_code == 200, r.text
|
||||
lock = _locked_before_items(statements, YT, YT_ITEMS)
|
||||
assert lock and "ORDER BY" in lock, lock
|
||||
|
||||
Reference in New Issue
Block a user