From a91150c41fd6df3644cb71bfab715801614ab60b Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 4 May 2026 22:45:23 +0200 Subject: [PATCH] chore: 502 bei propfind-fail, min_length path, exact-call assertion --- app/bulk.py | 25 ++++++++++++++++--------- tests/test_bulk.py | 12 +++++++++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/bulk.py b/app/bulk.py index 1c65060..ac4c3ae 100644 --- a/app/bulk.py +++ b/app/bulk.py @@ -4,8 +4,8 @@ from pathlib import PurePosixPath from urllib.parse import unquote import httpx -from fastapi import APIRouter, BackgroundTasks, Header, status -from pydantic import BaseModel +from fastapi import APIRouter, BackgroundTasks, Header, HTTPException, status +from pydantic import BaseModel, Field from app.config import get_settings from app.ingest.extractors import SUPPORTED_TYPES @@ -19,7 +19,7 @@ router = APIRouter() class BulkRequest(BaseModel): - path: str + path: str = Field(min_length=1) PROPFIND_BODY = """ @@ -74,12 +74,19 @@ async def bulk_import( settings = get_settings() verify_secret(x_webhook_secret, settings.webhook_secret) - files = await list_files_recursive( - settings.nextcloud_webdav_url, - settings.nextcloud_user, - settings.nextcloud_app_password, - body.path, - ) + try: + files = await list_files_recursive( + settings.nextcloud_webdav_url, + settings.nextcloud_user, + settings.nextcloud_app_password, + body.path, + ) + except (RuntimeError, httpx.HTTPError, ET.ParseError) as exc: + logger.exception( + "bulk listing failed", + extra={"event": "bulk_listing_failed", "path": body.path, "error": str(exc)}, + ) + raise HTTPException(status_code=502, detail="webdav listing failed") from exc dispatched = 0 for f in files: diff --git a/tests/test_bulk.py b/tests/test_bulk.py index 7972630..0a7be44 100644 --- a/tests/test_bulk.py +++ b/tests/test_bulk.py @@ -1,6 +1,9 @@ -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, call + from fastapi.testclient import TestClient +from app.webhook.models import EventType + def _make_app(monkeypatch): monkeypatch.setenv("NEXTCLOUD_WEBDAV_URL", "http://nc") @@ -45,6 +48,13 @@ def test_bulk_import_lists_and_dispatches(monkeypatch): assert r.status_code == 202 body = r.json() assert body["dispatched"] == 2 # only .pdf and .docx, not the json sidecar + process_mock.assert_has_calls( + [ + call("Documents/THB/Studium/2.Semester/Databases/a.pdf", EventType.CREATED), + call("Documents/THB/Studium/2.Semester/Databases/b.docx", EventType.CREATED), + ] + ) + assert process_mock.await_count == 2 def test_bulk_import_rejects_wrong_secret(monkeypatch):