From b9c5b0b7ad1ebf813dfb166c96d27bba475b1b3f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 15:05:22 +1030 Subject: [PATCH] Decouple queue from config endpoint; load via paginated API with correct ordering (#2) * Initial plan * Refactor: remove queue from /api/system/configuration, use existing paginated /api/history endpoint for queue data Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> * Remove accidentally committed package-lock.json and add to gitignore Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> * Simplify loadMoreQueue to use loadNextPage for reduced duplication Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> * Order in-progress downloads oldest-to-newest (order of processing) Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> * Fix queue ordering: remove client-side timestamp sort, rely on backend created_at ASC Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> * Revert "Fix queue ordering: remove client-side timestamp sort, rely on backend created_at ASC" This reverts commit 9b53112e0050a45e4db95c85064577d22ed47a50. Changes not needed --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jbatesy <51190172+jbatesy@users.noreply.github.com> Co-authored-by: Jesse Bate --- .gitignore | 1 + app/routes/api/system.py | 3 +- app/tests/test_system_routes.py | 46 ++++++++++- ui/app/components/Queue.vue | 60 +++++++++++++-- ui/app/components/Simple.vue | 14 +++- ui/app/stores/ConfigStore.ts | 5 -- ui/app/stores/StateStore.ts | 131 +++++++++++++++----------------- 7 files changed, 175 insertions(+), 85 deletions(-) diff --git a/.gitignore b/.gitignore index 7701ab66..a0d7c598 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ version.txt test_impl.py ./eslint.config.js .pytest_cache +ui/package-lock.json diff --git a/app/routes/api/system.py b/app/routes/api/system.py index e1744a4e..67b25b2b 100644 --- a/app/routes/api/system.py +++ b/app/routes/api/system.py @@ -32,7 +32,7 @@ LOG: logging.Logger = logging.getLogger(__name__) @route("GET", "api/system/configuration", "system.configuration") async def system_config(queue: DownloadQueue, config: Config, encoder: Encoder) -> Response: """ - Pause non-active downloads. + Get the system configuration. Args: queue (DownloadQueue): The download queue instance. @@ -55,7 +55,6 @@ async def system_config(queue: DownloadQueue, config: Config, encoder: Encoder) depth_limit=config.download_path_depth - 1, ), "history_count": await queue.done.get_total_count(), - "queue": (await queue.get("queue"))["queue"], }, status=web.HTTPOk.status_code, dumps=encoder.encode, diff --git a/app/tests/test_system_routes.py b/app/tests/test_system_routes.py index 209ccd7c..b185e62f 100644 --- a/app/tests/test_system_routes.py +++ b/app/tests/test_system_routes.py @@ -1,10 +1,52 @@ +import json + import pytest -from unittest.mock import AsyncMock, patch +from unittest.mock import AsyncMock, MagicMock, patch from app.library.config import Config from app.library.encoder import Encoder from app.library.UpdateChecker import UpdateChecker -from app.routes.api.system import check_updates +from app.routes.api.system import check_updates, system_config + + +class TestSystemConfigEndpoint: + """Tests for the system configuration endpoint.""" + + def setup_method(self): + """Reset singletons before each test.""" + Config._reset_singleton() + + @pytest.mark.asyncio + async def test_system_config_does_not_return_queue(self): + """Test that the configuration endpoint does not include queue data.""" + config = Config.get_instance() + encoder = Encoder() + + mock_queue = MagicMock() + mock_queue.is_paused.return_value = False + mock_done = AsyncMock() + mock_done.get_total_count = AsyncMock(return_value=0) + mock_queue.done = mock_done + + with ( + patch("app.routes.api.system.Presets") as mock_presets_cls, + patch("app.routes.api.system.DLFields") as mock_dl_fields_cls, + patch("app.routes.api.system.list_folders", return_value=[]), + ): + mock_presets_cls.get_instance.return_value.get_all.return_value = [] + mock_dl_fields_cls.get_instance.return_value.get_all_serialized = AsyncMock(return_value=[]) + + response = await system_config(mock_queue, config, encoder) + + assert 200 == response.status + body = json.loads(response.body.decode("utf-8")) + assert "queue" not in body, "Configuration response should not include queue data" + assert "app" in body, "Configuration response should include app data" + assert "paused" in body, "Configuration response should include paused status" + assert "history_count" in body, "Configuration response should include history_count" + assert "presets" in body, "Configuration response should include presets" + assert "dl_fields" in body, "Configuration response should include dl_fields" + assert "folders" in body, "Configuration response should include folders" class TestCheckUpdatesEndpoint: diff --git a/ui/app/components/Queue.vue b/ui/app/components/Queue.vue index c7d263bb..bffcb8e3 100644 --- a/ui/app/components/Queue.vue +++ b/ui/app/components/Queue.vue @@ -470,6 +470,21 @@ +
+
+
+ + + +

Loading more items...

+
+
+
+