diff --git a/backend/app/api/settings.py b/backend/app/api/settings.py index cdf0a3b..33e3878 100644 --- a/backend/app/api/settings.py +++ b/backend/app/api/settings.py @@ -20,6 +20,8 @@ _EDITABLE_FIELDS = ( "single_color_threshold", "single_color_tolerance", "phash_threshold", + "download_rate_limit_seconds", + "download_validate_files", ) @@ -38,6 +40,8 @@ async def get_import_settings(): "single_color_threshold": row.single_color_threshold, "single_color_tolerance": row.single_color_tolerance, "phash_threshold": row.phash_threshold, + "download_rate_limit_seconds": row.download_rate_limit_seconds, + "download_validate_files": row.download_validate_files, }) @@ -56,6 +60,19 @@ async def update_import_settings(): {"error": "phash_threshold must be a non-negative integer"} ), 400 + if "download_rate_limit_seconds" in body: + val = body["download_rate_limit_seconds"] + if not isinstance(val, (int, float)) or isinstance(val, bool) or val < 0: + return jsonify( + {"error": "download_rate_limit_seconds must be a non-negative number"} + ), 400 + if "download_validate_files" in body and not isinstance( + body["download_validate_files"], bool + ): + return jsonify( + {"error": "download_validate_files must be a boolean"} + ), 400 + async with get_session() as session: row = ( await session.execute(select(ImportSettings).where(ImportSettings.id == 1)) diff --git a/tests/test_api_settings_downloader.py b/tests/test_api_settings_downloader.py new file mode 100644 index 0000000..814dec8 --- /dev/null +++ b/tests/test_api_settings_downloader.py @@ -0,0 +1,59 @@ +import pytest + +from backend.app import create_app + +pytestmark = pytest.mark.integration + + +@pytest.fixture +async def app(): + return create_app() + + +@pytest.fixture +async def client(app): + async with app.test_client() as c: + yield c + + +@pytest.mark.asyncio +async def test_get_includes_downloader_fields(client): + resp = await client.get("/api/settings/import") + assert resp.status_code == 200 + body = await resp.get_json() + assert body["download_rate_limit_seconds"] == 3.0 + assert body["download_validate_files"] is True + + +@pytest.mark.asyncio +async def test_patch_download_rate_limit(client): + resp = await client.patch( + "/api/settings/import", json={"download_rate_limit_seconds": 1.5} + ) + assert resp.status_code == 200 + assert (await resp.get_json())["download_rate_limit_seconds"] == 1.5 + + +@pytest.mark.asyncio +async def test_patch_download_validate_files_false(client): + resp = await client.patch( + "/api/settings/import", json={"download_validate_files": False} + ) + assert resp.status_code == 200 + assert (await resp.get_json())["download_validate_files"] is False + + +@pytest.mark.asyncio +async def test_patch_rejects_negative_rate_limit(client): + resp = await client.patch( + "/api/settings/import", json={"download_rate_limit_seconds": -1.0} + ) + assert resp.status_code == 400 + + +@pytest.mark.asyncio +async def test_patch_rejects_non_bool_validate(client): + resp = await client.patch( + "/api/settings/import", json={"download_validate_files": "yes"} + ) + assert resp.status_code == 400