Files
socweb/doc/start/test.md
T
gongzhiyongandClaude Sonnet 4.6 c6ca9dc126 fix: restore workspace components accidentally dropped from git index
workspace/ files existed on disk but were not included in previous
incremental commit, causing git to record them as deleted. Re-adding
all workspace card components, AgentWorkspace, ActivityTimeline, and
WorkspaceCardRenderer to properly track them.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 03:09:41 +08:00

4.1 KiB

SOC End-to-End Test Reports


File Upload End-to-End Integration Test

Date: 2026-04-08 Tester: Claude Agent (Opus 4.6) Backend: https://soc-backend.azurewebsites.net Frontend: https://proud-pebble-04db8fd00.2.azurestaticapps.net

Pre-test Fixes Applied

Before testing could succeed, three issues were identified and fixed:

  1. delete_attachment Litestar startup crash (ImproperlyConfiguredException)

    • Cause: @delete(..., status_code=204) with -> None return type triggers Litestar validation error
    • Fix: Added return_dto=None to the @delete decorator in backend/app/api/attachments.py
  2. create_tables ExceptionGroup race condition

    • Cause: Two gunicorn workers call CREATE TABLE simultaneously; PostgreSQL raises UniqueViolation, but anyio wraps it in ExceptionGroup (a BaseException subclass) which bypasses except Exception
    • Fix: Changed except Exception to except BaseException in backend/app/store/postgres.py
  3. ForeignKeyViolationError on upload with non-existent conversation_id

    • Cause: attachments.conversation_id has a FK constraint to conversations.id; uploading with an arbitrary conversation_id that doesn't exist fails
    • Status: Not a bug -- expected behavior. Tests adapted to create a conversation first or upload without conversation_id

Commit: 48d7dd7 -- fix: resolve attachment upload 500 errors (delete_attachment startup crash + create_tables ExceptionGroup)

Test Results

# Test Item Method Expected Actual Result
1 Health check GET /health 200 {"status":"ok"} 200 {"status":"ok"} PASS
2 Upload attachment (no conversation) POST /api/attachments/upload multipart 201 with {id, filename, blob_url, size_bytes, content_type, created_at} 201 -- id=7c0eba99, filename=CLAUDE.md, blob_url=https://authdatablol.blob.core.windows.net/soc-files/..., size_bytes=4966, content_type=text/markdown PASS
2b Upload attachment (with valid conversation_id) POST /api/attachments/upload?conversation_id={id} 201 with all fields + conversation_id set 201 -- id=a0dd9108, conversation_id=3d859ce5-..., all fields present PASS
3 Get attachment metadata GET /api/attachments/{id} 200 with attachment JSON 200 -- all fields match upload response PASS
4 Download attachment (SAS redirect) GET /api/attachments/{id}/download 302 with Location header containing SAS URL 302 -- Location: https://authdatablol.blob.core.windows.net/soc-files/...?se=...&sp=r&sv=...&sr=b&sig=... PASS
5 Delete attachment DELETE /api/attachments/{id} 204 No Content 204 PASS
6 Get after delete GET /api/attachments/{id} 404 404 {"status_code":404,"detail":"Attachment ... not found"} PASS
7 Frontend homepage + upload button GET / + source verification 200 + upload UI code in source 200 (25464 bytes) + handleFileUpload, uploadAttachment, file input in GeminiInput.tsx PASS
8 SSE chat regression POST /api/chat/stream SSE tokens + done event Received token events ("Hi! How can I help?") + {"type":"done"} PASS
9 Tickets/summary regression GET /api/tickets/summary 200 with summary JSON 200 {"total":3,"by_status":{"pending":0,"processing":1,"resolved":2},"by_priority":{"P0":0,"P1":2,"P2":1,"P3":0}} PASS

Summary

Result: 10/10 PASS (counting 2 and 2b as separate items = 10 tests total)

All file upload CRUD operations work correctly end-to-end:

  • Upload to Azure Blob Storage succeeds (both with and without conversation_id)
  • Metadata persisted in PostgreSQL and retrievable via GET
  • Download generates a time-limited SAS URL and returns 302 redirect
  • Delete removes both the blob and the database record
  • Frontend has upload UI wired to the backend API
  • SSE chat and tickets/summary remain functional (no regressions)

Note on debug=True

The debug=True flag was left enabled in backend/app/main.py to aid ongoing development. This should be set back to debug=False before production hardening.