fix(05-12): close 3 UAT gaps — OAuth 400 preflight, 502 cloud fallback, upload hint

- oauth_initiate: pre-flight check returns 400 with env-var hint when
  GOOGLE_CLIENT_ID/SECRET or ONEDRIVE_CLIENT_ID/SECRET are not configured,
  preventing opaque MSAL/OAuth library 500 errors on misconfigured servers
- stream_document_content: broad except-clause catches non-CloudConnectionError
  exceptions and returns 502 with user-friendly message (was raw 500)
- docker-compose.yml: add volumes: - ./backend:/app to celery-worker so code
  changes are picked up by docker compose restart without a rebuild
- CloudStorageView: upload hint paragraph directs users to navigate into a
  cloud folder; no DropZone added (no folder context at overview level)
- 3 new backend tests pass; 2 existing tests patched with credential monkeypatch;
  full suite: 293 passed, 0 new failures, 1 pre-existing (test_extract_docx)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curo1305
2026-05-30 17:55:08 +02:00
parent f4f340545b
commit 10175ee4b5
8 changed files with 479 additions and 1 deletions
+37
View File
@@ -593,3 +593,40 @@ async def test_parse_range_416(async_client, auth_user, db_session, monkeypatch)
headers={**auth_user["headers"], "Range": "bytes=100-200"},
)
assert resp.status_code == 416
async def test_stream_document_content_cloud_backend_error(async_client, auth_user, db_session, monkeypatch):
"""GET /api/documents/{id}/content returns 502 when cloud backend raises a non-CloudConnectionError exception.
Plan 05-12 gap closure: broad except-clause catches RuntimeError, timeout, etc. and
returns a user-friendly 502 instead of an opaque 500.
"""
import uuid as _uuid
from unittest.mock import AsyncMock
from db.models import Document
doc_id = _uuid.uuid4()
doc = Document(
id=doc_id,
user_id=auth_user["user"].id,
filename="cloud_doc.pdf",
content_type="application/pdf",
size_bytes=1024,
storage_backend="google_drive",
status="uploaded",
object_key=f"{auth_user['user'].id}/{doc_id}/{_uuid.uuid4()}.pdf",
)
db_session.add(doc)
await db_session.commit()
async def raise_runtime_error(*args, **kwargs):
raise RuntimeError("connection timeout")
monkeypatch.setattr("api.documents.get_storage_backend_for_document", raise_runtime_error)
resp = await async_client.get(
f"/api/documents/{doc_id}/content",
headers=auth_user["headers"],
)
assert resp.status_code == 502, f"Expected 502, got {resp.status_code}: {resp.text}"
assert "Cloud backend unreachable" in resp.json()["detail"]