Phase 5: Frontend - Use key as primary series identifier

- Updated app.js to use 'key' as primary series identifier
  - selectedSeries Set now uses key instead of folder
  - createSerieCard() uses data-key attribute for identification
  - toggleSerieSelection() uses key for lookups
  - downloadSelected() iterates with key values
  - updateSelectionUI() and toggleSelectAll() use key

- Updated WebSocket service tests
  - Tests now include key and folder in broadcast data
  - Verified both fields are included in messages

- No changes needed for queue.js and other JS files
  - They use download item IDs correctly, not series identifiers

- No template changes needed
  - Series cards rendered dynamically in app.js

All 996 tests passing
This commit is contained in:
2025-11-28 16:18:33 +01:00
parent 5aabad4d13
commit a833077f97
7 changed files with 238 additions and 322 deletions

View File

@@ -307,10 +307,16 @@ class TestWebSocketService:
@pytest.mark.asyncio
async def test_broadcast_download_progress(self, service, mock_websocket):
"""Test broadcasting download progress."""
"""Test broadcasting download progress.
Verifies that progress data includes 'key' as the primary series
identifier and 'folder' for display purposes only.
"""
connection_id = "test-conn"
download_id = "download123"
progress_data = {
"key": "attack-on-titan",
"folder": "Attack on Titan (2013)",
"percent": 50.0,
"speed_mbps": 2.5,
"eta_seconds": 120,
@@ -325,14 +331,24 @@ class TestWebSocketService:
call_args = mock_websocket.send_json.call_args[0][0]
assert call_args["type"] == "download_progress"
assert call_args["data"]["download_id"] == download_id
assert call_args["data"]["key"] == "attack-on-titan"
assert call_args["data"]["folder"] == "Attack on Titan (2013)"
assert call_args["data"]["percent"] == 50.0
@pytest.mark.asyncio
async def test_broadcast_download_complete(self, service, mock_websocket):
"""Test broadcasting download completion."""
"""Test broadcasting download completion.
Verifies that result data includes 'key' as the primary series
identifier and 'folder' for display purposes only.
"""
connection_id = "test-conn"
download_id = "download123"
result_data = {"file_path": "/path/to/file.mp4"}
result_data = {
"key": "attack-on-titan",
"folder": "Attack on Titan (2013)",
"file_path": "/path/to/file.mp4"
}
await service.connect(mock_websocket, connection_id)
await service._manager.join_room(connection_id, "downloads")
@@ -342,13 +358,23 @@ class TestWebSocketService:
call_args = mock_websocket.send_json.call_args[0][0]
assert call_args["type"] == "download_complete"
assert call_args["data"]["download_id"] == download_id
assert call_args["data"]["key"] == "attack-on-titan"
assert call_args["data"]["folder"] == "Attack on Titan (2013)"
@pytest.mark.asyncio
async def test_broadcast_download_failed(self, service, mock_websocket):
"""Test broadcasting download failure."""
"""Test broadcasting download failure.
Verifies that error data includes 'key' as the primary series
identifier and 'folder' for display purposes only.
"""
connection_id = "test-conn"
download_id = "download123"
error_data = {"error_message": "Network error"}
error_data = {
"key": "attack-on-titan",
"folder": "Attack on Titan (2013)",
"error_message": "Network error"
}
await service.connect(mock_websocket, connection_id)
await service._manager.join_room(connection_id, "downloads")
@@ -358,6 +384,8 @@ class TestWebSocketService:
call_args = mock_websocket.send_json.call_args[0][0]
assert call_args["type"] == "download_failed"
assert call_args["data"]["download_id"] == download_id
assert call_args["data"]["key"] == "attack-on-titan"
assert call_args["data"]["folder"] == "Attack on Titan (2013)"
@pytest.mark.asyncio
async def test_broadcast_queue_status(self, service, mock_websocket):