Vega Test Suite

89 rows
TTest
THow I Test It
TExpected Outcome
Status
TSpec File
1
POST /api/auth — send magic link
POST /api/auth with @test.dock email; check token in response
status 200, token present in body
Pass
auth.spec.ts
2
POST /api/auth — reject malformed email
POST with garbage string as email
status 422, validation error
Pass
auth.spec.ts
3
POST /api/auth — verify issues session cookie
POST verify action with valid token; inspect Set-Cookie header
status 200, dock-session cookie set
Pass
auth.spec.ts
4
POST /api/auth — reject invalid token
POST verify with a made-up token
status 401 unauthorized
Pass
auth.spec.ts
5
GET /api/me — 401 when unauthenticated
GET /api/me with no cookie
status 401
Pass
auth.spec.ts
6
GET /api/me — returns signed-in user
GET /api/me with valid session cookie from fixture
status 200, user object with correct email
Pass
auth.spec.ts
7
PUT /api/me — updates name
PUT /api/me with { name } body
status 200, name persisted
Pass
auth.spec.ts
8
Magic link rate limiting
POST /api/auth same email >N times rapidly
status 429 after threshold
Pass
auth.spec.ts
9
GET /api/billing — returns plan summary
GET /api/billing with session auth
status 200, shape has plan/agentCap/memberCap/workspaceCap/stripe
Pass
billing.spec.ts
10
GET /api/billing — 401 without auth
GET /api/billing with no auth
status 401
Pass
billing.spec.ts
11
GET /api/billing — activeMembers counts OrgMembers
Seed OrgMember row via DB fixture; GET billing
activeMembers increments for org-level membership
Pass
billing.spec.ts
12
POST /api/billing/request-limit-increase
POST with kind/desiredValue/reason
status 200, row written to DB
Pass
billing.spec.ts
13
POST /api/billing/request-limit-increase — rejects unknown kind
POST with unknown kind string
status 400 or 422
Pass
billing.spec.ts
14
GET /api/billing — active trial reads plan=scale
Seed org.scaleUntil = future via DB; GET billing
plan=scale, scaleUntil is future ISO date
Pass
trial-early-subscribe.spec.ts
15
GET /api/billing — expired trial reads underlying plan
Seed org.scaleUntil = past, plan=free; GET billing
plan=free (not scale)
Pass
trial-early-subscribe.spec.ts
16
GET /api/billing — no trial has null scaleUntil
Seed org with no scaleUntil; GET billing
scaleUntil is null
Pass
trial-early-subscribe.spec.ts
17
GET /api/workspaces — 401 unauthenticated
GET with no auth
status 401
Pass
workspaces.spec.ts
18
GET /api/workspaces — returns only owned workspaces
Create two orgs; confirm no cross-org leakage
Only caller workspaces returned
Pass
workspaces.spec.ts
19
POST /api/workspaces — creates workspace
POST with name + mode
status 200, workspace slug returned, owner member seeded
Pass
workspaces.spec.ts
20
POST /api/workspaces — deduplicates slugs
Create two workspaces with same name
Second gets a unique slug (no 409)
Pass
workspaces.spec.ts
21
POST /api/workspaces — doc mode creates DocBody
POST with mode=doc
DocBody row exists in DB after creation
Pass
workspaces.spec.ts
22
DELETE /api/workspaces/[slug] — soft archives
DELETE a workspace; check DB row
archivedAt set, row survives, workspace.archived event emitted
Pass
doc-events-archive.spec.ts
23
Archived workspace hidden from list
Archive a workspace; GET /api/workspaces
Archived slug absent from list
Pass
doc-events-archive.spec.ts
24
Archived workspace returns 404 on GET
Archive; GET /api/workspaces/[slug]
status 404
Pass
doc-events-archive.spec.ts
25
Archived workspace refuses writes
Archive; PUT /api/workspaces/[slug]/doc
status 404
Pass
doc-events-archive.spec.ts
26
Rows CRUD — create/list/get
POST a row; GET list; verify returned
status 200, row in list with correct data
Pass
rows.spec.ts
27
Rows CRUD — PATCH merges partial update
PATCH with partial data field; verify untouched keys preserved
Merged correctly, no data loss
Pass
rows.spec.ts
28
Rows CRUD — row.sealed event fires
PATCH status to sealed
row.sealed event in DB event log
Pass
rows.spec.ts
29
Rows CRUD — DELETE removes row
DELETE a row; GET list
Row absent from list
Pass
rows.spec.ts
30
Rows bulk PATCH — merges atomically
PATCH /rows/bulk with multi-row updates
All rows updated in one transaction
Pass
rows-bulk.spec.ts
31
Rows bulk PATCH — rejects >500 updates
Send 501-item updates array
status 422
Pass
rows-bulk.spec.ts
32
GET /doc — returns empty content for new doc workspace
GET doc on fresh workspace
status 200, empty content
Pass
columns-doc.spec.ts
33
PUT /doc — updates body (last-write-wins)
PUT with content; GET back
Content round-trips correctly
Pass
columns-doc.spec.ts
34
PUT /doc refuses ops on table-mode workspace
PUT /doc on a table workspace
status 422 or 400
Pass
columns-doc.spec.ts
35
First PUT emits doc.created
PUT to fresh doc workspace (no prior DocBody)
doc.created event with chars/blocks/contentHash, no doc.updated
Pass
doc-events-archive.spec.ts
36
Second PUT emits doc.updated with deltas
Two sequential PUTs; check events
doc.updated has charsBefore/After/Delta, blocksBefore/After/Delta, updatedBy
Pass
doc-events-archive.spec.ts
37
New heading fires doc.heading_added
PUT with a heading node not in previous content
doc.heading_added event with level+text
Pass
doc-events-archive.spec.ts
38
New mention fires doc.mention_added
PUT with a mention node not in previous content
doc.mention_added event with id+label
Pass
doc-events-archive.spec.ts
39
doc-diff.summarize — empty doc returns zeros
Unit test: summarize({ type: "doc", content: [] })
chars=0, blocks=0, headings=[], mentions=[]
Pass
doc-diff.spec.ts
40
doc-diff.summarize — counts chars across nodes
Unit test: two paragraph nodes
chars = sum of all text node lengths
Pass
doc-diff.spec.ts
41
doc-diff.summarize — collects headings
Unit test: heading nodes with level+text
headings array has {level, text} entries
Pass
doc-diff.spec.ts
42
doc-diff.summarize — contentHash is deterministic
Unit test: same input twice
Both hashes identical
Pass
doc-diff.spec.ts
43
doc-diff.diff — text append gives positive charsDelta
Unit test: before/after with more text
charsDelta > 0, no headings/mentions added
Pass
doc-diff.spec.ts
44
MCP — 401 with no auth
POST /api/mcp with no Authorization header
status 401
Pass
mcp.spec.ts
45
MCP — accepts valid API key
POST /api/mcp with Bearer dk_ key
status 200, valid JSON-RPC response
Pass
mcp.spec.ts
46
MCP — accepts valid OAuth token
POST /api/mcp with Bearer dock_at_ token
status 200
Pass
mcp.spec.ts
47
MCP tools/list returns all 13 tools
POST tools/list; count and verify names
13 tools including create_support_ticket
Pass
mcp.spec.ts
48
MCP full row lifecycle via tools
create_row then list_rows then update_row then delete_row
Each step returns correct result, row absent after delete
Pass
mcp.spec.ts
49
MCP create_workspace blocked for agents
Call create_workspace with agent API key
JSON-RPC error -32602
Pass
mcp.spec.ts
50
GET webhooks — lists org webhooks
GET /api/orgs/[slug]/webhooks
status 200, array with secret preview
Pass
webhooks.spec.ts
51
POST webhook — returns secret once
POST to create; GET again
Full whsec_ on create, only preview on subsequent GET
Pass
webhooks.spec.ts
52
POST webhook — rejects invalid events
POST with bogus event name
status 400/422
Pass
webhooks.spec.ts
53
PATCH webhook — toggles active state
PATCH active=false; verify
active flips, delivery stops on inactive
Pass
webhooks.spec.ts
54
DELETE webhook — removes endpoint
DELETE; GET list
Endpoint absent from list
Pass
webhooks.spec.ts
55
OrgMember — can read org-visible workspace
Seed OrgMember row (no WorkspaceMember); GET workspace rows
status 200, rows returned
Pass
org-membership.spec.ts
56
OrgMember — cannot read private workspace
Private workspace; caller is OrgMember only
status 404
Pass
org-membership.spec.ts
57
Org invite — accept creates OrgMember
Create email-scoped invite; POST /api/org-invites/[token] with matching email
OrgMember row created
Pass
org-invites.spec.ts
58
Org invite — mismatched email rejected
Accept invite with wrong email
status 403
Pass
org-invites.spec.ts
59
Org invite — open-link enforces maxUses
Create open-link invite with maxUses=1; accept twice
Second accept 404s
Pass
org-invites.spec.ts
60
Member removal cascades WorkspaceMember rows
Delete OrgMember; check WorkspaceMember table
All workspace memberships removed
Pass
org-invites.spec.ts
61
Sole owner cannot be removed
DELETE /api/orgs/[slug]/members/[userId] on sole owner
status 400/422 blocked
Pass
org-invites.spec.ts
62
Smart default visibility — solo org defaults to private
POST workspace in single-member org
workspace.visibility=private
Pass
org-membership.spec.ts
63
Smart default visibility — team org defaults to org
POST workspace in 2+ OrgMember org
workspace.visibility=org
Pass
org-membership.spec.ts
64
Invite-only gate — unknown email waitlisted
POST /api/auth with unknown @example.com email
waitlisted=true, no token
Pass
waitlist-gate.spec.ts
65
Invite-only gate — @test.dock auto-bypassed
POST /api/auth with @test.dock email (no header)
status 200, token returned
Pass
waitlist-gate.spec.ts
66
Invite-only gate — bypass header works
POST with x-dock-test-bypass header and correct token
status 200, token echoed
Pass
waitlist-gate.spec.ts
67
Referral code lets new email through gate
POST /api/auth with valid ?ref= referral code
status 200, token returned, referral row written
Pass
waitlist-gate.spec.ts
68
Security headers present on marketing page
GET /; inspect response headers
CSP, X-Frame-Options, Referrer-Policy etc. present
Pass
security.spec.ts
69
SSRF guard rejects private IP webhooks
POST webhook URL with 127.0.0.1 / 10.x / 169.254.x
status 400 SSRF blocked
Pass
security.spec.ts
70
DELETE /api/me — 400 on missing confirmEmail
DELETE with empty body while authenticated
status 400
Pass
security.spec.ts
71
DELETE /api/me — 400 on wrong confirmEmail
DELETE with wrong email in body
status 400
Pass
security.spec.ts
72
DELETE /api/me — 200 and deletes on correct email
DELETE with matching confirmEmail
status 200, subsequent /api/me returns 401
Pass
security.spec.ts
73
Session rotation on magic-link verify
Verify new magic link; check old sessions
Old session cookie no longer authenticates
Pass
security.spec.ts
74
Agents cannot call data export
GET /api/me/export with API key (not session)
status 403
Pass
security.spec.ts
75
GET /changelog returns 200 with HTML
HTTP GET /changelog
status 200, body contains DOCTYPE html
Pass
changelog.spec.ts
76
GET /changelog has OG image meta
GET /changelog; check HTML body
og:image or opengraph-image present in head
Pass
changelog.spec.ts
77
GET /changelog/unknown-slug returns 404
GET /changelog/this-slug-does-not-exist
status 404
Pass
changelog.spec.ts
78
doc.updated renders remote-writer pill
E2E: agent writes doc via API while owner has tab open; check .doc-remote-writer-pill CSS class
Pill appears with agent name within 20s timeout
Skipped
realtime.spec.ts
79
COVERAGE: referrals.spec.ts (15 tests uncatalogued)
File exists at tests/api/referrals.spec.ts with 15 green tests: click tracking, attribution (ipHash/userAgent/referer), /invite/[code] landing, /api/referrals/me, activation (email verified + first API key), month credits on referrer/referee
Backfill 15 rows in this catalog tagged referrals.spec.ts. Referral program V1 is shipped per project_dock.md
Pending
referrals.spec.ts
80
COVERAGE: support.spec.ts (16 tests uncatalogued)
File exists at tests/api/support.spec.ts with 16 tests covering POST/GET /api/support, attachments via /api/support/upload, rate limit, GitHub issue mirror, kinds (bug/feature/billing/question/other)
Backfill 16 rows. Biggest coverage gap. Just used this endpoint to file support#43
Pending
support.spec.ts
81
COVERAGE: agent-invites.spec.ts (10 tests uncatalogued)
File exists with 10 tests covering AgentInvite creation, token acceptance, email-scoped vs open-link, expiry, revocation
Backfill 10 rows. Agent identity primitive, important gap
Pending
agent-invites.spec.ts
82
COVERAGE: invites-keys.spec.ts (6 tests uncatalogued)
File exists with 6 tests covering API key lifecycle: POST /api/keys, listing, revocation, per-workspace scoping, secret shown once
Backfill 6 rows. API key lifecycle is how agents authenticate, must be represented
Pending
invites-keys.spec.ts
83
COVERAGE: workspace-visibility.spec.ts (6 tests uncatalogued)
File exists with 6 tests covering visibility transitions (private / org / unlisted / public) and access matrix for each
Backfill 6 rows. workspace-access.ts is canonical per AGENTS.md, visibility tests anchor it
Pending
workspace-visibility.spec.ts
84
COVERAGE: org.spec.ts (6 tests uncatalogued)
File exists with 6 tests covering org CRUD, defaultOrgId, org profile, defaultWorkspaceVisibility
Backfill 6 rows
Pending
org.spec.ts
85
COVERAGE: comments-events.spec.ts (4 tests uncatalogued)
File exists with 4 tests covering row comments CRUD + comment events in the event log
Backfill 4 rows. Comments are how humans annotate rows (used this exact feature on this row)
Pending
comments-events.spec.ts
86
COVERAGE: oauth-bearer.spec.ts (4 tests uncatalogued)
File exists with 4 tests covering OAuth 2.1 bearer tokens: /oauth/register DCR, /oauth/token, refresh, token introspection
Backfill 4 rows. OAuth is how Claude.ai connector + CLI authenticate
Pending
oauth-bearer.spec.ts
87
COVERAGE: agents-overview.spec.ts (3 tests uncatalogued)
File exists with 3 tests covering GET /api/agents and GET /api/agents/[id]
Backfill 3 rows
Pending
agents-overview.spec.ts
88
COVERAGE: me-sessions.spec.ts (2 tests uncatalogued)
File exists with 2 tests covering GET /api/me/sessions and DELETE for logout-all
Backfill 2 rows
Pending
me-sessions.spec.ts
89
META: sheet drifted from tests/api/*.spec.ts on disk
As of 2026-04-21: sheet lists 78 tests across 15 spec files. Disk has 25 spec files (~150 tests). 10 files + 72 tests uncatalogued. Also columns-doc.spec.ts has 4 sibling column tests not listed (see comment on row 32)
Vega should treat tests/api/*.spec.ts as the source of truth. Next run should auto-ingest from disk (node: parse test(...) calls into rows) so the catalog stops drifting. Alternatively run a one-time backfill then keep a lint check in CI
Pending
(meta)
Vega Test Suite · Dock on Dock · Dock