Plan — BJ-16: E2E Atlassian mock server#
Summary#
Add an embedded Node HTTP mock server to AgentSDE/agent-core-e2e covering the Bitbucket + Jira endpoints BJ-8 (#548) and BJ-9 (#549) call in their happy paths, plus OAuth token stubs, wired into Jest globalSetup / globalTeardown and exposed through BITBUCKET_* / JIRA_* base URL env overrides.
Files#
| File | Action | Description |
|---|---|---|
test/mocks/atlassian-mock-server.ts | create | AtlassianMockServer class: start()/stop()/url()/resetRequests()/getRequests(); Node http.createServer on port 0; route table for Bitbucket, Jira, OAuth. |
test/mocks/global-setup.ts | create | Boot singleton server, export port via global.__ATLASSIAN_MOCK__, set BITBUCKET_BASE_URL / JIRA_BASE_URL / BITBUCKET_OAUTH_URL / ATLASSIAN_OAUTH_URL env vars. |
test/mocks/global-teardown.ts | create | Call stop() on the singleton. |
test/mocks/atlassian-mock-server.spec.ts | create | Unit tests: boots, records requests, returns canned bodies, 404s unknown routes, OAuth stubs respond, reset clears log. |
jest.e2e.config.js | modify | Wire globalSetup / globalTeardown to the two new files. |
package.json | inspect | Confirm no new deps needed (uses built-in http). |
Steps#
- Implement
AtlassianMockServerwith port-0 binding, JSON body parsing, per-request recording (method, path, query, headers, body), and a dispatch table keyed by(METHOD, path-regex). - Add OAuth handlers for
POST /site/oauth2/access_tokenandPOST /oauth/tokenthat return{access_token, token_type:"bearer", expires_in:3600, refresh_token}regardless of input. - Add Bitbucket
/2.0/*handlers for the BJ-8 surface:postComment,editComment,createPR,mergePR,updatePRBranch,closePR, label add/remove,getFileContent,getPRFiles,createOrUpdateFile,createBranch,getDefaultBranchSha,deleteBranch,getCheckStatus,getReviewStatus— minimal canned bodies matching the Bitbucket Cloud v2 shape. - Add Jira
/ex/jira/{cloudId}/*handlers for the BJ-9 surface: issue get, comment post/edit,transitionslist + POST, labels, assignee, priority,issueLink,search(JQL) — minimal canned bodies matching Jira Cloud REST v3. - Return
404 {error: "unmocked route"}with a distinct log line for any unmatched request so missed coverage is visible in test output. - Add
global-setup.ts/global-teardown.tsthat boot one server for the run, publish its URL via env vars, and store the instance onglobalThisfor teardown. - Add
globalSetup+globalTeardownentries tojest.e2e.config.js(leave tier-specific configs untouched; they can opt in when Atlassian scenarios land). - Add unit spec covering: start/stop cleanliness, happy-path route responses, OAuth stub, unmocked-route 404,
resetRequests()behaviour, and request introspection shape.
Verification#
npm run test -- test/mocks/atlassian-mock-server.spec.tspasses locally.npm run lintpasses (zero warnings) andnpm run buildcompiles.- Existing tier1/tier2/tier2d runs remain green — no regression from added
globalSetuphooks (they are opt-in onjest.e2e.config.jsonly).
Risks#
- Mock response shapes may drift from real Atlassian APIs — mitigated by sourcing shapes from the BJ-8/BJ-9 service signatures and marking speculative fields with an inline comment referencing the upstream doc.
globalSetupruns once in Jest's controller process, so all workers share the server; per-testresetRequests()is the correct isolation boundary, not per-worker ports.
Open Questions#
- Should the mock also serve Confluence routes? Issue scopes it out for now; revisit if Wave 4 expands.