AI Agents SDE Task Viewer
      • Context
      • Plan
      • Prd
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-556
  5. plan
  6. plan.md
plan.md(3.6 KB)· Apr 23, 2026· 3 min read
  • Summary
  • Files
  • Steps
  • Verification
  • Risks
  • Open Questions

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#

FileActionDescription
test/mocks/atlassian-mock-server.tscreateAtlassianMockServer class: start()/stop()/url()/resetRequests()/getRequests(); Node http.createServer on port 0; route table for Bitbucket, Jira, OAuth.
test/mocks/global-setup.tscreateBoot 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.tscreateCall stop() on the singleton.
test/mocks/atlassian-mock-server.spec.tscreateUnit tests: boots, records requests, returns canned bodies, 404s unknown routes, OAuth stubs respond, reset clears log.
jest.e2e.config.jsmodifyWire globalSetup / globalTeardown to the two new files.
package.jsoninspectConfirm no new deps needed (uses built-in http).

Steps#

  1. Implement AtlassianMockServer with port-0 binding, JSON body parsing, per-request recording (method, path, query, headers, body), and a dispatch table keyed by (METHOD, path-regex).
  2. Add OAuth handlers for POST /site/oauth2/access_token and POST /oauth/token that return {access_token, token_type:"bearer", expires_in:3600, refresh_token} regardless of input.
  3. 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.
  4. Add Jira /ex/jira/{cloudId}/* handlers for the BJ-9 surface: issue get, comment post/edit, transitions list + POST, labels, assignee, priority, issueLink, search (JQL) — minimal canned bodies matching Jira Cloud REST v3.
  5. Return 404 {error: "unmocked route"} with a distinct log line for any unmatched request so missed coverage is visible in test output.
  6. Add global-setup.ts / global-teardown.ts that boot one server for the run, publish its URL via env vars, and store the instance on globalThis for teardown.
  7. Add globalSetup + globalTeardown entries to jest.e2e.config.js (leave tier-specific configs untouched; they can opt in when Atlassian scenarios land).
  8. 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.ts passes locally.
  • npm run lint passes (zero warnings) and npm run build compiles.
  • Existing tier1/tier2/tier2d runs remain green — no regression from added globalSetup hooks (they are opt-in on jest.e2e.config.js only).

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.
  • globalSetup runs once in Jest's controller process, so all workers share the server; per-test resetRequests() 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.
ContextPrd