Skip to content

tests(#487): 24 unit tests for cli/execute-handler.js#332

Open
javimosch wants to merge 1 commit into
masterfrom
mago/task-487
Open

tests(#487): 24 unit tests for cli/execute-handler.js#332
javimosch wants to merge 1 commit into
masterfrom
mago/task-487

Conversation

@javimosch

@javimosch javimosch commented Jun 27, 2026

Copy link
Copy Markdown
Owner

What

24 unit tests for cli/execute-handler.js covering all three exported functions.

Coverage

handleExecute

  • Forwards cmd, uFlags, config, and SERVER to execute()
  • Passes empty string as server when SERVER is falsy
  • onStreamEvent is null when adapterConfig is absent or stream is not "jsonl"
  • Calls makeStreamEmitter and forwards the result as onStreamEvent when stream === "jsonl"
  • writeLog receives the correct command string, args, status: "success", duration_ms, timestamp, and client_id (from getClientId())
  • Non-human mode: output called with the version: "1.0" envelope
  • Human mode + array ≤ 20: outputHumanTable called with full array and column map
  • Human mode + array > 20: sliced to 20 rows and "N more" logged to console
  • Human mode + object: each key-value pair logged via console.log
  • Human mode + nested object value: JSON.stringify applied
  • Error thrown by execute() propagates — output and writeLog are not called

handlePlan

  • No server: buildLocalPlan(cmd, args) called; result passed to output
  • No server + human mode: outputHumanPlan called instead of output
  • With server: fetch POST to /api/plans; result passed through annotateServerPlan; output called
  • With server + human mode: outputHumanPlan called with annotated plan
  • POST body contains command, args, and cmd
  • fetch throws → outputError({ code: 105, type: "integration_error", recoverable: true, ... })

handleExecutePlan

  • fetch POST to /api/plans/{planId}/execute
  • JSON result forwarded to output
  • fetch throws → outputError({ code: 105, ... }); output not called

How verified

npx jest __tests__/execute-handler.test.js --no-coverage
# Tests: 24 passed, 24 total — 0.233s

Closes #487 (mago task #487)

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for command execution and planning flows.
    • Verified output behavior in human and non-human modes, including tables, structured output, and error handling.
    • Covered server and local plan generation paths, plus plan execution requests and failure responses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new Jest test file __tests__/execute-handler.test.js with 449 lines covering handleExecute, handlePlan, and handleExecutePlan. Tests mock the executor and plan-runtime modules and use shared IO/cmd fixtures to assert argument forwarding, stream emitter wiring, output modes, error propagation, and fetch integration.

Changes

execute-handler test coverage

Layer / File(s) Summary
handleExecute test suite
__tests__/execute-handler.test.js
Assertions for argument forwarding, SERVER falsy fallback, onStreamEvent null vs jsonl emitter, structured envelope vs human-table output (20-row slicing + "and N more"), key/value logging, duration_ms/timestamp log fields, and execute() error propagation without calling output/log.
handlePlan test suite
__tests__/execute-handler.test.js
Assertions for local buildLocalPlan/outputHumanPlan path, server fetch POST URL and body shape, annotateServerPlan wiring, output mode branching, and fetch rejection producing io.outputError with code: 105, type: "integration_error", recoverable: true.
handleExecutePlan test suite
__tests__/execute-handler.test.js
Assertions for execute-endpoint URL with planId, successful JSON result forwarding to io.output, and fetch rejection producing io.outputError while ensuring io.output is not called.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • javimosch/supercli#204: Adds unit tests for makeStreamEmitter, which is directly exercised by the handleExecute jsonl stream emitter assertions in this PR.

Poem

🐇 Hop, hop, the tests now bloom,
Mocked executors fill the room,
Plans fetched near and server-far,
Each assertion like a star,
No output called on error's gloom—
The rabbit cheers with tail afloom! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the change: adding 24 unit tests for cli/execute-handler.js.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mago/task-487

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@__tests__/execute-handler.test.js`:
- Around line 305-374: Add a test in handlePlan for the non-OK fetch response
path, since fetch only rejects on network errors and 4xx/5xx responses can
currently slip through as success. In __tests__/execute-handler.test.js, mock
global.fetch to resolve with ok false and a JSON body/error payload, then assert
handlePlan calls io.outputError with the integration_error payload (similar to
the existing fetch-throws case) rather than io.output. Use the existing
handlePlan, makeIoPlan, and makeCmd helpers to keep the new case aligned with
the current server tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e1a4c66-7ed2-4c9a-917d-e9c4cafc8c9e

📥 Commits

Reviewing files that changed from the base of the PR and between afda2f7 and a9e0989.

📒 Files selected for processing (1)
  • __tests__/execute-handler.test.js

Comment on lines +305 to +374
test("with server: fetches /api/plans and outputs annotated plan", async () => {
const serverPlan = { plan_id: "sp1", steps: [] };
const annotated = { ...serverPlan, persisted: true, execution_mode: "server" };
annotateServerPlan.mockReturnValue(annotated);
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValue(serverPlan),
});
const io = makeIoPlan({ hasServer: true, humanMode: false });
const cmd = makeCmd();

await handlePlan(cmd, { q: "b" }, io);

expect(global.fetch).toHaveBeenCalledWith(
"https://srv.io/api/plans",
expect.objectContaining({ method: "POST" })
);
expect(annotateServerPlan).toHaveBeenCalledWith(serverPlan);
expect(io.output).toHaveBeenCalledWith(annotated);
});

test("with server + human mode: calls outputHumanPlan with annotated plan", async () => {
const annotated = { plan_id: "sp2", persisted: true, steps: [] };
annotateServerPlan.mockReturnValue(annotated);
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValue({}),
});
const io = makeIoPlan({ hasServer: true, humanMode: true });

await handlePlan(makeCmd(), {}, io);

expect(outputHumanPlan).toHaveBeenCalledWith(annotated);
expect(io.output).not.toHaveBeenCalled();
});

test("with server: POST body includes command and args", async () => {
annotateServerPlan.mockReturnValue({});
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValue({}),
});
const io = makeIoPlan({ hasServer: true });
const cmd = makeCmd();

await handlePlan(cmd, { limit: 10 }, io);

const [, opts] = global.fetch.mock.calls[0];
const body = JSON.parse(opts.body);
expect(body.command).toBe("ai.text.summarize");
expect(body.args).toEqual({ limit: 10 });
expect(body.cmd).toEqual(cmd);
});

test("with server + fetch throws: calls outputError with code 105", async () => {
global.fetch = jest.fn().mockRejectedValue(new Error("network failure"));
const io = makeIoPlan({ hasServer: true });

await handlePlan(makeCmd(), {}, io);

expect(io.outputError).toHaveBeenCalledWith(
expect.objectContaining({
code: 105,
type: "integration_error",
recoverable: true,
})
);
const err = io.outputError.mock.calls[0][0];
expect(err.message).toContain("network failure");
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In Node 18 / WHATWG fetch, does fetch reject on HTTP 4xx/5xx responses or only on network failures?

💡 Result:

In Node.js 18 and later (which implements the WHATWG Fetch standard), the fetch promise does not reject on HTTP 4xx or 5xx error responses [1][2]. The promise only rejects on network failures, such as DNS issues, connection refusal, TLS handshake errors, or when the request is aborted [1][2][3]. Because HTTP 4xx and 5xx responses are considered successful HTTP transactions, the fetch promise will resolve normally with a Response object [2][3]. To handle these HTTP error statuses, you must manually check the response.ok property (which is false for statuses outside the 200–299 range) or the response.status property [1][4]. Common practice involves creating a wrapper or a helper function to check the status code and throw an error manually if needed [5][2][6]. Example of manual error handling: async function safeFetch(url) { const response = await fetch(url); if (!response.ok) { throw new Error(HTTP error! Status: ${response.status}); } return response.json; }

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the handler and the test file, then inspect the relevant ranges.
git ls-files | rg '^(cli/execute-handler\.js|__tests__/execute-handler\.test\.js)$'

echo '--- execute-handler.js outline ---'
ast-grep outline cli/execute-handler.js --view expanded || true

echo '--- execute-handler.test.js outline ---'
ast-grep outline __tests__/execute-handler.test.js --view expanded || true

echo '--- execute-handler.js relevant lines ---'
sed -n '1,140p' cli/execute-handler.js | cat -n

echo '--- execute-handler.test.js relevant lines ---'
sed -n '250,420p' __tests__/execute-handler.test.js | cat -n

Repository: javimosch/supercli

Length of output: 10526


Add a non-OK response case for handlePlan.
fetch() only rejects on network failures, so a 4xx/5xx JSON response currently bypasses outputError and is treated as a successful plan. Cover that path here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@__tests__/execute-handler.test.js` around lines 305 - 374, Add a test in
handlePlan for the non-OK fetch response path, since fetch only rejects on
network errors and 4xx/5xx responses can currently slip through as success. In
__tests__/execute-handler.test.js, mock global.fetch to resolve with ok false
and a JSON body/error payload, then assert handlePlan calls io.outputError with
the integration_error payload (similar to the existing fetch-throws case) rather
than io.output. Use the existing handlePlan, makeIoPlan, and makeCmd helpers to
keep the new case aligned with the current server tests.

@javimosch

Copy link
Copy Markdown
Owner Author

Review — Head of Org Engineering: The PR adds a new test file __tests__/execute-handler.test.js that tests handleExecute, handlePlan, and handleExecutePlan — matching the PR's stated purpose. The file is syntactically valid JavaScript, touches only the new test file, and contains no secrets, destructive changes, or out-of-scope edits.

(approved — review-only mode; merge when ready.)

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