molecule-core/tests/e2e
Hongming Wang e632a31347 feat(chat_files): rewrite Upload as HTTP-forward to workspace (RFC #2312, PR-C)
Closes the SaaS upload gap (#2308) with the unified architecture from
RFC #2312: same code path on local Docker and SaaS, no Docker socket
dependency, no `dockerCli == nil` cliff. Stacked on PR-A (#2313) +
PR-B (#2314).

Before:
  Upload → findContainer (nil in SaaS) → 503

After:
  Upload → resolve workspaces.url + platform_inbound_secret
        → stream multipart to <url>/internal/chat/uploads/ingest
        → forward response back unchanged

Same call site whether the workspace runs on local docker-compose
("http://ws-<id>:8000") or SaaS EC2 ("https://<id>.<tenant>...").
The bug behind #2308 cannot exist by construction.

Why streaming, not parse-then-re-encode:
  * No 50 MB intermediate buffer on the platform
  * Per-file size + path-safety enforcement is the workspace's job
    (see workspace/internal_chat_uploads.py, PR-B)
  * Workspace's error responses (413 with offending filename, 400 on
    missing files field, etc.) propagate through unchanged

Changes:
  * workspace-server/internal/handlers/chat_files.go — Upload rewritten
    as a streaming HTTP proxy. Drops sanitizeFilename, copyFlatToContainer,
    and the entire docker-exec path. ChatFilesHandler gains an httpClient
    (broken out for test injection). Download stays docker-exec for now;
    follow-up PR will migrate it to the same shape.
  * workspace-server/internal/handlers/chat_files_external_test.go —
    deleted. Pinned the wrong-headed runtime=external 422 gate from
    #2309 (already reverted in #2311). Superseded by the proxy tests.
  * workspace-server/internal/handlers/chat_files_test.go — replaced
    sanitize-filename tests (now in workspace/tests/test_internal_chat_uploads.py)
    with sqlmock + httptest proxy tests:
      - 400 invalid workspace id
      - 404 workspace row missing
      - 503 platform_inbound_secret NULL (with RFC #2312 detail)
      - 503 workspaces.url empty
      - happy-path forward (asserts auth header, content-type forwarded,
        body streamed, response propagated back)
      - 413 from workspace propagated unchanged (NOT remapped to 500)
      - 502 on workspace unreachable (connect refused)
    Existing Download + ContentDisposition tests preserved.
  * tests/e2e/test_chat_upload_e2e.sh — single-script-everywhere E2E.
    Takes BASE as env (default http://localhost:8080). Creates a
    workspace, waits for online, mints a test token, uploads a fixture,
    reads it back via /chat/download, asserts content matches +
    bearer-required. Same script runs against staging tenants (set
    BASE=https://<id>.<tenant>.staging.moleculesai.app).

Test plan:
  * go build ./... — green
  * go test ./internal/handlers/ ./internal/wsauth/ — green (full suite)
  * tests/e2e/test_chat_upload_e2e.sh against local docker-compose
    after PR-A + PR-B + this PR all merge — TODO before merge

Refs #2312 (parent RFC), #2308 (chat upload 503 incident).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:26:37 -07:00
..
_extract_token.py chore: apply round-7 review nits 2026-04-13 17:08:45 -07:00
_lib.sh feat(platform): GET /admin/workspaces/:id/test-token for E2E (#6) 2026-04-14 09:35:26 -07:00
STAGING_SAAS_E2E.md feat(e2e): pivot to admin-bearer-only auth + add sanity self-check workflow 2026-04-21 04:34:11 -07:00
test_a2a_e2e.sh initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
test_activity_e2e.sh chore: apply code-review round-6 suggestions 2026-04-13 17:08:45 -07:00
test_api.sh fix(e2e): stop asserting current_task on public workspace GET (#966) 2026-04-19 02:19:15 -07:00
test_chat_attachments_e2e.sh feat(canvas+platform): chat attachments, model selection, deploy/delete UX 2026-04-24 13:27:51 -07:00
test_chat_attachments_multiruntime_e2e.sh feat(canvas+platform): chat attachments, model selection, deploy/delete UX 2026-04-24 13:27:51 -07:00
test_chat_upload_e2e.sh feat(chat_files): rewrite Upload as HTTP-forward to workspace (RFC #2312, PR-C) 2026-04-29 14:26:37 -07:00
test_claude_code_e2e.sh chore: final open-source cleanup — binary, stale paths, private refs 2026-04-18 00:38:55 -07:00
test_comprehensive_e2e.sh fix(e2e): make provisioning-status assertions robust to CI environment 2026-04-13 17:31:07 -07:00
test_dev_mode.sh fix(quickstart): hotfixes discovered during live testing session 2026-04-23 14:57:18 -07:00
test_harness_rc_normalization.sh fix(e2e-sanity): normalize unexpected curl exit codes in cleanup trap (#2159) 2026-04-27 02:55:44 -07:00
test_notify_attachments_e2e.sh test(notify): pre-sweep prior workspaces so interrupted runs don't pile up 2026-04-26 20:55:13 -07:00
test_priority_runtimes_e2e.sh feat(e2e): extend priority-runtimes test to cover all 8 templates 2026-04-27 05:57:59 -07:00
test_saas_tenant.sh chore: final open-source cleanup — binary, stale paths, private refs 2026-04-18 00:38:55 -07:00
test_staging_full_saas.sh fix(e2e): teardown patience matches prod cascade duration (~30–90s) 2026-04-28 11:13:56 -07:00