Skip to content

test(tools): HTTP contract tests for the 6 remaining tool handlers#4

Open
govindkavaturi-art wants to merge 1 commit intomainfrom
test/mcp-tool-handler-http-contracts
Open

test(tools): HTTP contract tests for the 6 remaining tool handlers#4
govindkavaturi-art wants to merge 1 commit intomainfrom
test/mcp-tool-handler-http-contracts

Conversation

@govindkavaturi-art
Copy link
Copy Markdown
Member

Summary

Before this PR, only `cueapi_pause_cue` and `cueapi_resume_cue` had dedicated handler tests. The other six tools (`create`, `list`, `get`, `delete`, `list_executions`, `report_outcome`) were only covered indirectly by the schema-assertion suite — nothing exercised the handler's actual request construction. A regression that renamed a field, built the wrong path, or dropped URL-encoding would ship with green CI.

Added: 17 contract tests across 6 suites

Each stubs `CueAPIClient.request` and asserts method, path, body, and query for representative arg combinations.

`cueapi_create_cue` (5)

POST /v1/cues with name + cron · 'at' replaces cron · `worker=true` omits callback_url · omits undefined optionals · forwards payload/timezone/description

`cueapi_list_cues` (2)

GET /v1/cues no query · status filter forwarded

`cueapi_get_cue` (2)

GET /v1/cues/{id} · URL-encodes cue_id with slashes + spaces

`cueapi_delete_cue` (2)

DELETE /v1/cues/{id} · URL-encodes cue_id

`cueapi_list_executions` (2)

GET /v1/executions no query · cue_id/status/limit/offset forwarded

`cueapi_report_outcome` (4)

POST /v1/executions/{id}/outcome with success · evidence (external_id, result_url, summary) forwarded · omits undefined evidence · URL-encodes execution_id

Refactor

`findTool` + `stubClient` moved from inside the pause/resume describe block to file-scope helpers so the new suites reuse them.

Verification

```
Test Files 4 passed (4)
Tests 62 passed (62)
```

Was 45/45 before this PR. Typecheck clean.

Test plan

Prior to this change only cueapi_pause_cue and cueapi_resume_cue
had dedicated handler tests. The other six tools
(create, list, get, delete, list_executions, report_outcome)
were only covered indirectly by the schema-assertion suite —
nothing exercised the handler's actual request construction. A
regression that e.g. renamed a field, built the wrong path, or
dropped URL-encoding would ship with green CI.

Added 17 contract tests across 6 describe blocks. Each stubs
CueAPIClient.request and asserts method, path, body, and query
for representative arg combinations:

cueapi_create_cue (5)
  - POST /v1/cues with name + cron
  - 'at' takes precedence over cron when both unset-as-expected
  - worker=true omits callback_url
  - omits optional fields left undefined
  - forwards payload/timezone/description when provided

cueapi_list_cues (2)
  - GET /v1/cues, no query
  - status filter forwarded

cueapi_get_cue (2)
  - GET /v1/cues/{id}
  - URL-encodes cue_id with slashes + spaces

cueapi_delete_cue (2)
  - DELETE /v1/cues/{id}
  - URL-encodes cue_id

cueapi_list_executions (2)
  - GET /v1/executions, no query
  - cue_id/status/limit/offset forwarded

cueapi_report_outcome (4)
  - POST /v1/executions/{id}/outcome with success flag
  - evidence (external_id, result_url, summary) forwarded
  - omits evidence fields left undefined
  - URL-encodes execution_id

Refactored findTool + stubClient out of the pause/resume describe
into file-scope helpers so the new suites reuse them.

Tests: 62/62 pass (was 45/45). Typecheck clean.
mikemolinet added a commit that referenced this pull request May 2, 2026
…im-next/heartbeat

Closes the receive-claim-process-complete loop for MCP-host agents that
want to consume worker-transport executions from in-session, alongside
the SEND side that 0.3.0 added with cueapi_fire_cue.

Five new tools:

- cueapi_get_execution(execution_id)
  Wraps GET /v1/executions/{id}. Single-row lookup; the natural
  follow-up to cueapi_fire_cue's returned execution_id.

- cueapi_list_claimable_executions(task_name?, agent?)
  Wraps GET /v1/executions/claimable with the task/agent QUERY PARAMS.
  Filtering MUST be server-side — client-side filter after fetch hits
  the LIMIT 50 starvation bug fixed in the 2026-04-25 prod incident
  (see app/routers/executions.py:122-131).

- cueapi_claim_execution(execution_id, worker_id)
  Wraps POST /v1/executions/{id}/claim. Atomic conditional UPDATE;
  returns 409 if already claimed.

- cueapi_claim_next_execution(worker_id, task_name?)
  Wraps POST /v1/executions/claim. Without task_name → single API
  call. With task_name → internal fan-out (filtered list_claimable →
  pick oldest → claim by ID), since the server's claim endpoint
  doesn't yet accept a task filter. Tiny race window between list
  and claim is bounded by the atomic claim returning 409 → caller
  retries.

- cueapi_execution_heartbeat(execution_id, worker_id)
  Wraps POST /v1/executions/{id}/heartbeat. Sends worker_id via
  the X-Worker-Id REQUEST HEADER (the server's actual transport for
  that field — declared as Header(None), not in the request body).
  worker_id is REQUIRED in the MCP schema even though the server
  permits omission, so misconfigured callers fail at the wrapper
  instead of silently bypassing race protection.

Internal change:

- CueAPIClient.request() gains optional extraHeaders parameter
  (~5 LoC). Defaults are merged first; extraHeaders override them;
  Authorization is set last so a caller can never accidentally
  clobber the bearer token. Used by execution_heartbeat today;
  available for any future endpoint that needs custom headers.

Deferred from this PR:

- report_outcome enum refinement (PRD v3 §"Cowork feedback
  dispositions" #4): server's OutcomeRequest only accepts success:
  bool — there's no outcome_state field, and 'timed_out' from the
  proposed enum isn't worker-reportable (server detects timeout via
  heartbeat lapse; if a worker can call the API, it didn't time
  out). Defer to a follow-up PR where we can resolve the
  timed_out semantics + the breaking-vs-additive call separately.
  Flagged back to PM for re-clarification.

All 65 tests pass (was 48; +17 net): 5 added to surface-coverage
list, 12 new HTTP-contract tests across 5 new describe blocks.
npm run build clean.

Supersedes #10 (cueapi_get_execution as a standalone PR — folded
into this batch).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant