fix(api): answer 400 for a malformed body on integrations and document export-zip (#6905)

This commit is contained in:
dxrpl
2026-10-27 18:33:23 +01:00
parent 4d0610a1eb
commit 91922d854c
4 changed files with 79 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
"""POST /api/documents/export-zip answers 400 for ids that are not a list of document ids."""
import json
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from fastapi import HTTPException
from tests.helpers.import_state import clear_fake_database_modules
clear_fake_database_modules()
import routes.document_routes as droutes
class _Req:
def __init__(self, body):
self.state = SimpleNamespace(current_user="tester")
self._body = body
async def json(self):
return self._body
def _export_zip():
router = droutes.setup_document_routes(MagicMock(), None)
for r in router.routes:
if getattr(r, "path", None) == "/api/documents/export-zip":
return r.endpoint
raise RuntimeError("export-zip route not found")
@pytest.mark.parametrize("body", [[], "x", 5, {}, {"ids": []}, {"ids": None}])
async def test_missing_ids_is_a_400(body):
with pytest.raises(HTTPException) as exc:
await _export_zip()(_Req(body))
assert exc.value.status_code == 400
assert exc.value.detail == "No documents specified"
@pytest.mark.parametrize("ids", [5, "abc", {"a": 1}, [1, 2], [["a"]], ["a", None]])
async def test_ids_that_are_not_a_list_of_strings_is_a_400(ids):
with pytest.raises(HTTPException) as exc:
await _export_zip()(_Req({"ids": ids}))
assert exc.value.status_code == 400
assert exc.value.detail == "ids must be a list of document ids"
+25
View File
@@ -177,3 +177,28 @@ def test_update_integration_rejects_invalid_base_url_without_changing_existing(
assert exc.value.status_code == 400
assert exc.value.detail == message
assert integrations.load_integrations()[0]["base_url"] == "https://example.test"
@pytest.mark.parametrize("body", [[], "x", 5, None])
def test_create_integration_rejects_non_object_body(integrations_routes, body):
endpoint, session_cookie, http_exception = integrations_routes
create_integration = endpoint("/api/auth/integrations", "POST")
with pytest.raises(http_exception) as exc:
asyncio.run(create_integration(_JsonRequest(body, session_cookie)))
assert exc.value.status_code == 400
assert integrations.load_integrations() == []
@pytest.mark.parametrize("body", [[], "x", 5, None])
def test_update_integration_rejects_non_object_body(integrations_routes, body):
endpoint, session_cookie, http_exception = integrations_routes
update_integration = endpoint("/api/auth/integrations/{integration_id}", "PUT")
integrations.save_integrations([{"id": "existing", "name": "Original", "base_url": "https://example.test"}])
with pytest.raises(http_exception) as exc:
asyncio.run(update_integration("existing", _JsonRequest(body, session_cookie)))
assert exc.value.status_code == 400
assert integrations.load_integrations()[0]["name"] == "Original"