mirror of
https://github.com/morluto/rea.git
synced 2026-10-30 11:25:39 +00:00
* fix(cli): attribute keyed archive errors to archive argument * test(cli): assert input-error projection reference reuse
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import { mkdir, writeFile } from "node:fs/promises";
|
|
|
|
import { build } from "plist";
|
|
import { expect } from "vitest";
|
|
|
|
import { workspaceCliTest } from "../support/cli/workspaceCliFixture.js";
|
|
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
|
|
|
|
const archive = build({
|
|
$archiver: "NSKeyedArchiver",
|
|
$version: 100000,
|
|
$objects: ["$null", "leaf"],
|
|
$top: { root: { CF$UID: 1 } },
|
|
});
|
|
|
|
workspaceCliTest(
|
|
"names the archive argument when a bundle member is absent or noncanonical",
|
|
async ({ cli, workspace }) => {
|
|
const bundle = workspace.path("Static.app");
|
|
await mkdir(bundle);
|
|
await writeFile(
|
|
workspace.path("Static.app/Info.plist"),
|
|
build({ CFBundleIdentifier: "org.example.staticarchive" }),
|
|
);
|
|
await writeFile(workspace.path("Static.app/sample.plist"), archive);
|
|
for (const [selection, reason] of [
|
|
["absent.plist", "invalid_value"],
|
|
["../sample.plist", "invalid_format"],
|
|
] as const) {
|
|
const result = await cli.run({
|
|
arguments: ["inspect-keyed-archive", bundle, selection, "--json"],
|
|
});
|
|
expect(result.exitCode).toBe(1);
|
|
expect(result.json).toMatchObject({
|
|
code: "invalid_request",
|
|
category: "invalid_input",
|
|
recovery: {
|
|
kind: "inspect_input_contract",
|
|
operation: "inspect_keyed_archive",
|
|
},
|
|
details: {
|
|
operation: "inspect_keyed_archive",
|
|
issues: [{ path: ["archive"], reason }],
|
|
},
|
|
});
|
|
}
|
|
},
|
|
);
|
|
|
|
workspaceCliTest(
|
|
"retains the canonical selector field and recovery through public MCP",
|
|
async ({ cli, workspace }) => {
|
|
const path = workspace.path("sample.plist");
|
|
await writeFile(path, archive);
|
|
const call = await cli.sharedMcpCall!();
|
|
const opened = await call("open_binary", { path });
|
|
expect(opened.isError, JSON.stringify(opened.content)).not.toBe(true);
|
|
const rejected = await call("inspect_keyed_archive", {
|
|
path: "absent.plist",
|
|
});
|
|
expect(rejected.isError).toBe(true);
|
|
expect(parseMcpToolError(rejected).error).toMatchObject({
|
|
code: "invalid_request",
|
|
recovery: {
|
|
kind: "inspect_input_contract",
|
|
operation: "inspect_keyed_archive",
|
|
},
|
|
details: { issues: [{ path: ["path"], reason: "invalid_value" }] },
|
|
});
|
|
const valid = await call("inspect_keyed_archive", {});
|
|
expect(valid.isError, JSON.stringify(valid.content)).not.toBe(true);
|
|
expect(valid.structuredContent).toMatchObject({
|
|
normalized_result: { total_objects: 2 },
|
|
});
|
|
},
|
|
);
|