Skip to content

AI Code2WF — Test Cases

These cases validate the MVP contract in Code2WF I/O Definition. Page build/capture tests belong to Page Import. Every contract area must map to at least one case below; the Coverage Matrix is the traceability index.

Convention: Test IDs use C2W-<area>-<NN>, where the area is trigger (T), queue/dispatch (Q), source (S), conversion (C), idempotency/webhook (I), result API (R), Figma recovery (F), or authorization/security (A). The Expected column is the assertion contract; behavior not stated there is not asserted.


Test Layers & Tooling

The default suite is local and deterministic. Deployed end-to-end checks are opt-in smoke tests.

Layer Scope Tooling
Unit (U) Closed message/result schemas, one-read source-pin derivation, source/lineage validation, deterministic conversion and annotation numbering, shared DesignSpecModel serialization, limits, and full-artifact validation pytest, no network; storage and webhook clients faked at their boundaries
Component (C) Backend trigger/list/result/placement boundaries, one complete worker record through immutable result + manifest publication, webhook effects, and plugin materialization/recovery Existing backend and plugin test runners; ephemeral PostgreSQL where the backend row is exercised; localstack S3/SQS for artifact flow; webhook and Figma boundaries mocked
End-to-end (E) Deployed non-production backend, queue, worker, S3, PostgreSQL, and authenticated Figma plugin round-trip Opt-in smoke suite using dedicated test data and bounded runtime

Fixtures

Build messages and artifacts from shared fixtures rather than hand-writing partial dictionaries.

Fixture Purpose
completed_page_import(...) Scoped completed Page Import row plus one immutable normalized-manifest object with controllable raw bytes, page_result_hash, and capture_hash
build_code2wf_message(**overrides) Well-formed closed SQS message with Code2WF identity, tenant, fixed attempt, nonce, Page Import pins, and screen_id
page_result_bytes(**overrides) Exact normalized-manifest bytes used for the backend's single verified read and the worker's source validation
design_spec(**overrides) Canonical existing DesignSpecModel tree, including shared defaults and boundary variants
code2wf_result_artifact(**overrides) Complete worker artifact: outer identity/status/time, Page Import inputs, and nested spec
code2wf_terminal_manifest(**overrides) Success/failure manifest with the existing row_effects.code2wf contract
code2wf_row(status=..., materialized_at=...) Scoped backend row in processing/completed/failed and materialized/unmaterialized states
mock_ai_status(http_status=200) Captures the terminal webhook envelope and returns the configured response
figma_file_fixture(...) Current-page target, stale/cross-page targets, prior stamped root, and materializer failure variants

Coverage Matrix

Rows are contract areas from the I/O Definition. Every defined case ID appears here.

Contract area Happy path Failure path Idempotency / Recovery
Trigger and PostgreSQL row C2W-T-01, C2W-T-04 C2W-T-02, C2W-T-03, C2W-T-05, C2W-T-06, C2W-T-08 C2W-T-04, C2W-T-07
Dispatch message and Page Import pins C2W-Q-01, C2W-Q-05 C2W-Q-02, C2W-Q-03, C2W-Q-04 C2W-Q-02, C2W-Q-05
Worker source validation C2W-S-01, C2W-S-07 C2W-S-02, C2W-S-03, C2W-S-04, C2W-S-05, C2W-S-06 —
Conversion and shared spec C2W-C-01, C2W-C-02, C2W-C-03, C2W-C-04, C2W-C-06, C2W-C-08, C2W-C-09, C2W-C-13, C2W-C-14 C2W-C-05, C2W-C-07, C2W-C-10, C2W-C-11, C2W-C-12, C2W-C-15 C2W-C-02, C2W-C-08, C2W-C-13
Immutable result, manifest, and webhook C2W-I-04 C2W-I-03, C2W-I-05, C2W-I-07 C2W-I-01, C2W-I-02, C2W-I-06
Result/list API C2W-R-01, C2W-R-05, C2W-R-06, C2W-R-08 C2W-R-02, C2W-R-03, C2W-R-04, C2W-R-07 —
Figma recovery and placement C2W-F-01, C2W-F-06, C2W-F-08, C2W-F-09, C2W-F-10, C2W-F-11, C2W-F-12, C2W-F-13, C2W-F-14, C2W-F-16 C2W-F-02, C2W-F-03, C2W-F-04, C2W-F-05, C2W-F-07, C2W-F-15, C2W-F-17 C2W-F-02, C2W-F-03, C2W-F-08, C2W-F-09, C2W-F-14, C2W-F-15, C2W-F-18
Authorization and security — C2W-A-01, C2W-A-02, C2W-A-03, C2W-A-04, C2W-A-05 —

1. Trigger and Row Contract

ID Scenario Expected
C2W-T-01 Valid completed Page Import and valid Figma fields Generate UUIDv7; insert one code2wf row with status="0", attempt=1; send one SQS message
C2W-T-02 Page Import is processing/failed 409; no Code2WF row or message
C2W-T-03 Page Import is missing, deleted, or in another scope 404; no row or message
C2W-T-04 Identical valid trigger body is submitted twice Create two backend-generated rows and dispatch two jobs
C2W-T-05 Request supplies code2wfId 400; caller-generated job IDs are not accepted
C2W-T-06 SQS send fails after insert CAS processing row to failed using id/attempt/status; safe error is pollable
C2W-T-07 New trigger after dispatch failure Create and dispatch a new row; do not mutate or redispatch the failed row
C2W-T-08 Request tries status, attempt, result, or materialization fields 400; server-owned fields are not accepted

Schema assertion: the row uses the WF2Des-aligned fields only—id, organization/project, page_import_id, figma_file_key, screen_id, optional placement_target, status using the existing wf2des_status enum, fixed attempt, result/error/flag fields, materialized_at, and shared audit fields. It does not persist Page Import hashes, Figma page IDs, nonces, materialization states, node IDs, or retry ledgers.


2. Dispatch Contract

ID Scenario Expected
C2W-Q-01 Backend dispatches a valid job Message contains exact Page Import result URL/hash/capture hash resolved from the completed import
C2W-Q-02 Backend resolves the completed Page Import pins for dispatch Read and verify the immutable normalized manifest exactly once; that one read supplies page_result_url, page_result_hash, and capture_hash. Missing or corrupt bytes fail before SQS dispatch; do not assert a PostgreSQL/S3 transaction
C2W-Q-03 Message attempt is not 1 Worker rejects invalid_message
C2W-Q-04 Message contains Figma destination or credentials Closed message validation rejects it
C2W-Q-05 Valid message nonce is observed Validate and log it, but never persist it or include it in row CAS; duplicate delivery reuses the immutable result

3. Source Validation

ID Scenario Expected
C2W-S-01 Valid source bytes and lineage Conversion proceeds
C2W-S-02 Result hash differs Terminal source_hash_mismatch; no output
C2W-S-03 Organization/project/Page Import ID differs Terminal source_scope_mismatch
C2W-S-04 Capture hash differs Terminal source_scope_mismatch
C2W-S-05 Source/object escapes tenant/import prefix Terminal source_scope_mismatch
C2W-S-06 Unsupported Page Import schema Terminal unsupported_source_schema
C2W-S-07 Original route is unavailable No effect; worker reads only immutable Page Import artifacts

4. Conversion and Schema

ID Scenario Expected
C2W-C-01 Grouping, text, controls, and geometry are present Exact existing DesignSpecModel with layout_frame / text nodes and unique layer_path values
C2W-C-02 Captured link/form/control evidence exists Stable sibling marker plus matching deterministic annotation text; the original control label is unchanged
C2W-C-03 No evidence exists for an assumed interaction No invented behavior annotation
C2W-C-04 Button, input, or other ordinary control is mapped Existing nested layout_frame / text; no new primitive node case
C2W-C-05 Media, overlap, transform, or positioning relationship cannot be expressed by existing nodes Existing visible unmatched placeholder with flagged=true and source.kind="none"
C2W-C-06 Valid final compatibility fields spec_version="1.0", parse_confirmed=true, style_bindings={}, and an existing SpecNode root
C2W-C-07 Unknown node discriminator Shared discriminated-union validation returns invalid_result; nothing is published
C2W-C-08 Multiple evidence-backed annotations [A001] markers are assigned deterministically in normalized DOM order
C2W-C-09 Spec has flagged/unmatched outcomes flag_count equals the count of existing spec outcomes with flagged=true
C2W-C-10 Result exceeds a locked structural limit Terminal result_limit_exceeded
C2W-C-11 UTF-8 result exceeds 10 MiB Terminal result_limit_exceeded
C2W-C-12 Code2WF producer attempts a Code2WF-only spec field/collection Producer contract test fails; only fields from the existing shared model are emitted
C2W-C-13 Valid spec is serialized Exact DesignSpecModel.model_dump(mode="json") output includes shared defaults such as lineage arrays, text style refs, nullable source component key, and all auto-layout defaults
C2W-C-14 Page Import document is taller than its viewport Screen bbox.h uses full document_height; below-the-fold visible evidence is represented
C2W-C-15 Source has absolute/fixed/sticky overlap that auto-layout cannot preserve Do not add an absolute-position field; preserve visible order where possible and emit a flagged unmatched placeholder for irreducible content

Property tests generate the existing node union at boundary values and assert maximum depth/node counts, finite bounding boxes, unique paths/markers, exact DesignSpecModel validation/serialization, unknown-discriminator rejection, and an emitter allowlist matching the existing shared fields. A regression test also records the current shared-model behavior that extra object properties are ignored rather than falsely asserting that Pydantic rejects them.


5. Result Idempotency and Webhook

ID Scenario Expected
C2W-I-01 Same SQS record delivered twice One immutable result/manifest pair; both deliveries converge on the manifest URL
C2W-I-02 Concurrent worker loses conditional write Read and validate winner; emit winner's terminal event
C2W-I-03 Existing result has different lineage Fail closed; never overwrite
C2W-I-04 Valid success webhook on processing row Validate result_manifest_url; CAS (id, attempt=1, status="0") to completed; store inner row_effects.code2wf.result_url and flag count
C2W-I-05 Valid failure webhook on processing row Same CAS to failed; require the failure manifest and safe error, store its failed-artifact result_url / error_message, and leave row flag_count null
C2W-I-06 Duplicate/conflicting webhook after terminal state Accepted no-op; terminal winner is unchanged
C2W-I-07 Webhook dependency temporarily unavailable SQS record retries; worker never writes PostgreSQL

6. Result API

ID Scenario Expected
C2W-R-01 Completed row with a valid result artifact Validate the complete worker artifact—outer job_id/tenant/attempt/screen/status/time, Page Import inputs, and the existing DesignSpecModel—then return that full validated artifact verbatim
C2W-R-02 Processing or failed row 404 from result endpoint; status remains available from GET
C2W-R-03 result.json has invalid shared result content or lineage 500; invalid content is not returned
C2W-R-04 Existing DesignSpecModel validation fails 500; plugin receives no artifact or partial spec
C2W-R-05 Valid result is returned Response preserves the full artifact fields job_id, attempt, organization_id, project_id, screen_id, status, generated_at, inputs, and spec with no projection, asset signing, or schema translation; the plugin consumes artifact.spec
C2W-R-06 List request omits pagination Apply WF2Des-compatible limit=50, offset=0, and return total before pagination
C2W-R-07 S3 metadata declares more than 10 MiB, or a stream crosses 10 MiB Reject with 500 before validation or abort the bounded stream; never allocate an unbounded full-object buffer
C2W-R-08 generated_at uses Z or an equivalent +00:00 offset Parse and compare the same UTC instant rather than requiring one timestamp spelling

7. Figma Recovery and Placement

ID Scenario Expected
C2W-F-01 Plugin opens target file after generation completed List discovers completed row with materialized=false
C2W-F-02 Caught build failure Partial staging root is discarded; row remains unmaterialized and the next session rebuilds from the immutable result
C2W-F-03 Plugin process closes midway through build Row remains unmaterialized and reopen rebuilds; test records any partial unstamped node, without asserting unsupported automatic cleanup
C2W-F-04 Placement includes an invalid node ID 400; no timestamp
C2W-F-05 Placement targets a processing/failed row 404; no timestamp
C2W-F-06 Valid placement Backend stamps materialized_at on the completed row and echoes placedNodeId
C2W-F-07 Placement backend write fails Timestamp remains null; later plugin action can retry
C2W-F-08 Identical or different placement after timestamp exists 200 with existing timestamp; no second stamp
C2W-F-09 Prior completed root exists for the same job ID Rebuild succeeds first, then the WF2Des swap removes the prior root and preserves a single completed output
C2W-F-10 Text node carries existing fallback size/weight/color/bbox width Shared builder applies fallback before bindings, lets a resolved binding override its field, keeps width bounded and height auto-growing, and records existing font fallback diagnostics when needed
C2W-F-11 Layout frame carries existing sizing/wrap/bbox-height values fixed pins width/height, hug keeps width-pinned auto height, explicit WRAP plus counter_gap is applied, and empty wrap retains only the existing overflow-safety behavior
C2W-F-12 Code2WF output is materialized Existing wf2des stamp/index namespace and root label wf2des · 1.0 are retained
C2W-F-13 placementTarget resolves on current page / is absent, stale, nested cross-page, or other-page Shared placeRoot receives absolute page x/y and leaves the target unchanged / falls back to viewport center
C2W-F-14 More than 50 completed unmaterialized rows exist for the open file Plugin processes rows sequentially and repeatedly queries limit=50&offset=0 until empty; shrinking results do not skip rows
C2W-F-15 One row fails result fetch/build among valid rows Leave it unmaterialized, report it, continue later rows, and stop repeated failure through the bounded no-progress guard
C2W-F-16 Plugin session expires during open-time discovery Prompt for login and retry discovery after authentication
C2W-F-17 List/result belongs to another Figma file Do not fetch or materialize it
C2W-F-18 Two plugin sessions discover the same row concurrently Exercise the shared job-ID stamp/index and idempotent placement, but record that no atomic server claim is provided

The server stores no placed node ID, claim, retry count, or recovery state. The node ID is request/response data. The planned plugin extension uses root key wf2des with JSON {jobId, specVersion, role: "root"} and document key wf2des_index with {[jobId]: rootId}; PostgreSQL stores only materialized_at.


8. Security

ID Scenario Expected
C2W-A-01 No JWT 401
C2W-A-02 Read session triggers or records placement Opaque 404; no existence leak
C2W-A-03 Cross-project row/result access 404; no existence leak
C2W-A-04 Worker role tries PostgreSQL/DocumentDB/Figma Denied; role has no such credentials
C2W-A-05 Result contains credentials or presigned URLs Validation rejects publication

Cross-cutting Checks

These invariants apply across the relevant cases and are verified alongside them.

  • One-read Page Import pins (C2W-Q-01, C2W-Q-02): one verified immutable normalized-manifest read supplies page_result_url, page_result_hash, and capture_hash; missing or corrupt bytes stop the request before dispatch. No PostgreSQL/S3 transaction is claimed.
  • Closed worker boundary (C2W-Q-03, C2W-Q-04, C2W-A-04): the message contains only documented fields and no Figma destination, credentials, or direct database access.
  • Full result artifact (C2W-R-01, C2W-R-05): the result API returns the complete validated worker artifact verbatim. The plugin reads artifact.spec; the API does not project a smaller response or translate the shared spec.
  • Shared spec only (C2W-C-01–C2W-C-15): Code2WF emits the existing DesignSpecModel and node union with canonical defaults, deterministic paths/annotation markers, and visible flagged placeholders for unsupported fidelity.
  • Tenant and credential safety (C2W-S-03, C2W-S-05, C2W-A-01–C2W-A-05): every source/result access is tenant-scoped, and neither artifacts nor responses expose credentials or presigned URLs.
  • Immutable retry convergence (C2W-I-01, C2W-I-02, C2W-I-03, C2W-I-06): redelivery validates and reuses the winning create-only artifact pair; it never overwrites different lineage.
  • Plugin-owned Figma writes (C2W-F-01–C2W-F-18): the server returns data and records materialized_at; native Figma creation, swap, and recovery remain in the authenticated plugin.

Intentionally Out of Scope

Listed so future tests land with the owning feature or layer.

  • Page Import build/browser/capture behavior
  • navigation or prototype generation
  • high-fidelity design generation
  • repeated generation with the same job ID
  • server-side Figma writes