Files
rea/tests/boundary/cli/jebCli.test.ts
T
morluto ece277b30b fix(jeb): retain requested operation during metadata probes
Pass the caller operation into the shared client-information producer and consume its parsed facts during inspection. Remove duplicate metadata parsing and the forwarding wrapper.

Refs #4597. Baseline real CLI/MCP controls failed for three requested operations; all 51 affected tests and static checks now pass. The endpoint is simulated; real JEB refusal behavior is unverified.
2026-10-17 05:54:18 +08:00

134 lines
4.1 KiB
TypeScript

import { expect, it } from "vitest";
import { serveCli } from "./cliServeHarness.js";
import { createTestCli } from "../../support/cli/cliFixture.js";
import { createTestProcessRegistry } from "../../support/process/processFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
startJebMcpFixture,
jebPrimaryResponses,
} from "../../fixtures/jebMcp.js";
const jebEnvironment = {
REA_JEB_MCP_URL: "http://127.0.0.1:1/mcp",
};
const serve = async (
argv: readonly string[],
): Promise<{ readonly stdout: string; readonly exitCode: number }> =>
serveCli(argv, jebEnvironment);
it("reports an unreachable engine endpoint with recovery guidance", async () => {
const result = await serve(["inspect-jeb-client", "--json"]);
expect(result.stdout).toContain("capability_unavailable");
expect(result.stdout).toContain("REA_JEB_MCP_URL");
});
it("validates decompile item input before contacting the engine", async () => {
const result = await serve(["decompile-jeb-item", "", "method", "--json"]);
expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout)).toMatchObject({
code: "VALIDATION_ERROR",
fieldErrors: [
{
code: "too_small",
path: "item-address",
},
],
});
});
it.each([
{ setting: "REA_JEB_MCP_URL", value: "http://localhost:8425/mcp" },
{ setting: "REA_JEB_MCP_TIMEOUT_MS", value: "1.5" },
])(
"reports invalid $setting without breaking other commands",
async ({ setting, value }) => {
const environment = { [setting]: value };
const jeb = await serveCli(["inspect-jeb-client", "--json"], environment);
expect(JSON.parse(jeb.stdout)).toMatchObject({
code: "configuration_invalid",
details: { settings: [{ setting }] },
});
const capabilities = await serveCli(
["capabilities", "--json"],
environment,
);
expect(capabilities.exitCode).toBe(0);
expect(JSON.parse(capabilities.stdout)).toMatchObject({
capabilities: expect.any(Array),
});
},
);
it.each(
[
{
operation: "list_jeb_units",
tool: "list_units",
argv: ["list-jeb-units", "--count", "2", "--json"],
},
{
operation: "decompile_jeb_item",
tool: "decompile_code_item",
argv: [
"decompile-jeb-item",
"LSample;->value()I",
"method",
"--unit-path",
"sample.dex",
"--json",
],
},
{
operation: "open_jeb_project",
tool: "open_project",
argv: ["open-jeb-project", "sample.apk", "--json"],
},
].flatMap((request) =>
["metadata-refusal", "primary-refusal", "success"].map((stage) => ({
...request,
stage,
})),
),
)(
"preserves $operation attribution and primary payload with $stage",
async ({ operation, tool, argv, stage }) => {
const fixture = await startJebMcpFixture((name) =>
(stage === "metadata-refusal" && name === "get_client_information") ||
(stage === "primary-refusal" && name === tool)
? { success: false, message: "Selected stage refused" }
: jebPrimaryResponses[name]!,
);
const processes = createTestProcessRegistry();
const cli = createTestCli(processes);
try {
const home = await createTestTempDirectory("rea-jeb-attribution-cli-");
const result = await cli.run({
arguments: argv,
environment: { HOME: home, REA_JEB_MCP_URL: fixture.endpoint },
timeoutMs: 10_000,
});
const output = JSON.parse(result.stdout);
if (stage === "success") {
expect(result.exitCode).toBe(0);
expect(output.operation).toBe(operation);
expect(output.raw_result).toEqual(jebPrimaryResponses[tool]);
} else {
expect(result.exitCode).toBe(1);
expect(output).toMatchObject({
code: "unsupported_target",
details: { operation, reason: "Selected stage refused" },
});
expect(output.message).toContain(operation);
}
expect(fixture.calls).toEqual(
stage === "primary-refusal" ? [tool] : [tool, "get_client_information"],
);
} finally {
await processes.shutdown();
await fixture.close();
}
},
);