From 206f5642483105b6ba8683a07ed621a62183aa5f Mon Sep 17 00:00:00 2001 From: curo1305 Date: Sat, 20 Jun 2026 12:35:35 +0200 Subject: [PATCH] test(12-05): fix test_nextcloud_connect_persists + compose migration test path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test_nextcloud_connect_persists: provider=nextcloud routes to NextcloudBackend (not WebDAVBackend) — add storage.nextcloud_backend.validate_cloud_url patch and use AsyncMock for asyncio.to_thread (plain return_value=True is not awaitable, swallowed by except → False). Test now passes HTTP 201. - test_compose_migrations: skip module when docker-compose.yml is not found at the expected repo-root path (file is not mounted inside the backend container). Co-Authored-By: Claude Sonnet 4.6 --- backend/tests/test_cloud.py | 36 ++++++++++++++++++++++++ backend/tests/test_compose_migrations.py | 9 ++++++ 2 files changed, 45 insertions(+) diff --git a/backend/tests/test_cloud.py b/backend/tests/test_cloud.py index c54bebd..917b4a0 100644 --- a/backend/tests/test_cloud.py +++ b/backend/tests/test_cloud.py @@ -292,6 +292,42 @@ async def test_oauth_callback_invalid_state(async_client, db_session, monkeypatc app.state.redis = None +async def test_nextcloud_connect_persists(async_client, db_session): + """POST /api/cloud/connections/webdav with provider=nextcloud creates a connection. + + Regression for Phase 12 UAT blocker: POST /api/cloud/connections/webdav failed with + UndefinedColumn (display_name_override) when the DB was at revision 0005. + Uses unittest.mock.patch to stub SSRF validation and health probe at sys.modules level. + """ + from unittest.mock import patch, AsyncMock + + auth = await _create_user_and_token(db_session, role="user") + + # provider=nextcloud routes to NextcloudBackend (not WebDAVBackend) in the + # cloud_backend_factory — patch validate_cloud_url in all namespaces that hold + # a from-import binding. asyncio.to_thread is accessed as a module attribute + # in both backends, so a single AsyncMock covers both. + with patch("api.cloud.connections.validate_cloud_url", return_value=None), \ + patch("storage.webdav_backend.validate_cloud_url", return_value=None), \ + patch("storage.nextcloud_backend.validate_cloud_url", return_value=None), \ + patch("asyncio.to_thread", new_callable=AsyncMock, return_value=True): + resp = await async_client.post( + "/api/cloud/connections/webdav", + json={ + "server_url": "https://nc.example.com/remote.php/dav", + "username": "testuser", + "password": "testpass", + "provider": "nextcloud", + }, + headers=auth["headers"], + ) + + assert resp.status_code == 201, f"Unexpected: {resp.status_code} — {resp.text}" + data = resp.json() + assert data["provider"] == "nextcloud" + assert "credentials_enc" not in data + + async def test_webdav_connect_validates(async_client, db_session, monkeypatch): """POST /api/cloud/connections/webdav with localhost URL returns 422 (SSRF blocked).""" auth = await _create_user_and_token(db_session, role="user") diff --git a/backend/tests/test_compose_migrations.py b/backend/tests/test_compose_migrations.py index 1b7cabb..eecae81 100644 --- a/backend/tests/test_compose_migrations.py +++ b/backend/tests/test_compose_migrations.py @@ -21,6 +21,15 @@ import yaml REPO_ROOT = pathlib.Path(__file__).resolve().parents[2] COMPOSE_PATH = REPO_ROOT / "docker-compose.yml" +# When running inside the Docker container the repo root is not mounted; +# skip the whole module rather than erroring with FileNotFoundError. +if not COMPOSE_PATH.exists(): + pytest.skip( + f"docker-compose.yml not found at {COMPOSE_PATH} — " + "these static analysis tests must run from the host repo root, not inside a container.", + allow_module_level=True, + ) + APPLICATION_SERVICES = {"backend", "celery-worker", "celery-beat"}