mirror of
https://github.com/morluto/rea
synced 2026-10-28 15:07:26 -04:00
1201c25542
* fix(ci): retire unused internal analysis declarations * test: use an admitted app bundle for provider routing (cherry picked from commit00aa17f12a) * test: keep bundle routing coverage outside oversized group (cherry picked from commit8658353b0d) * fix(ci): align regression fixtures with current admission contracts * test: bind extraction close fixtures to their ZIP digest (cherry picked from commit626d0250db) * test(cli): match typed analysis outcomes in function detail fixture * test(ghidra): preserve empty Java property separator framing * test(electron): retain unknown IPC ownership for native module gaps * fix(electron): share source-scoped call path identity * test(captures): assert safe source identity on SAZ refusal * test(apple): match root occurrence kind to inventory manifest * fix(examples): align directory root occurrence identity * test(electron): align equivalent fixture assertions with upstream * test(process): assert retained capture root identity * test(windows): declare the PE fixture optional header * test(ci): refresh owned registration and verifier fixtures * test(setup): use owned registrations for refresh fixtures * test(process): control unavailable ownership in CLI cleanup fixture * test(process): guard controlled compiler output arguments * test(setup): align equivalent entrypoint guards with upstream * test(process): release the cleanup target through an owned gate * test(ci): align semantic identities and owned fixture facts * test(pcap): retain the upstream DNS wire fixture branch * test(pcap): use the canonical wire ownership fixture * test(pcap): assert exact DNS wire query labels * test(ci): preserve admission and ownership fixture prerequisites * test(ci): align authenticated fixture and cleanup boundaries * test(windows): align native artifact fixtures with upstream * test(android): request complete evidence for inline MCP contracts * test: avoid pinning diagnostic wording * test: verify cleanup diagnostics at their source * test: strengthen evidence and cleanup checks * test: avoid pinning registration guidance --------- Co-authored-by: Plastic-time <Plastic-time@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
115 lines
4.6 KiB
TypeScript
115 lines
4.6 KiB
TypeScript
import { Cli } from "incur";
|
|
import pino from "pino";
|
|
import { stat } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect, it, vi } from "vitest";
|
|
|
|
import { inspectAnalysisView } from "../../../src/application/analysisView/AnalysisViewService.js";
|
|
import { registerCoreBinaryCommands } from "../../../src/cli/coreBinaryCommands.js";
|
|
import type { CliInstance } from "../../../src/cli/types.js";
|
|
import { CLI_COMMANDS } from "../../../src/cliCommandNames.js";
|
|
import { createEvidence } from "../../../src/domain/evidence.js";
|
|
import { functionDossierSchema } from "../../../src/domain/native/functionDossier.js";
|
|
import { ghidraFunctionDossier } from "../../../src/domain/ghidraValues.fixture.js";
|
|
import { ok } from "../../../src/domain/result.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
// A complete analyze_function Evidence as runDirectAnalysis would return it:
|
|
// subject-bound (so the summary view has an artifact) with a schema-valid dossier.
|
|
const cannedCompleteEvidence = () =>
|
|
createEvidence(
|
|
{ path: "/fixtures/native.exe", format: "pe", sha256: "a".repeat(64) },
|
|
{ id: "ghidra", name: "Ghidra", version: "12.1.4" },
|
|
{
|
|
operation: "analyze_function",
|
|
parameters: { procedure: "main" },
|
|
result: functionDossierSchema.parse(ghidraFunctionDossier()),
|
|
rawResult: null,
|
|
},
|
|
);
|
|
|
|
const harness = () => {
|
|
const runDirectAnalysis = vi.fn<
|
|
Parameters<typeof registerCoreBinaryCommands>[2]
|
|
>(async () => ok(cannedCompleteEvidence()));
|
|
const cli = Cli.create("rea-fn-detail-test", { version: "1", sync: false });
|
|
registerCoreBinaryCommands(
|
|
cli as unknown as CliInstance,
|
|
pino({ enabled: false }),
|
|
runDirectAnalysis,
|
|
{},
|
|
);
|
|
const command = Cli.toCommands.get(cli)?.get(CLI_COMMANDS.function);
|
|
if (command === undefined)
|
|
throw new Error("function command was not registered");
|
|
const argsSchema = Reflect.get(command, "args");
|
|
const optionsSchema = Reflect.get(command, "options");
|
|
const execute = Reflect.get(command, "run");
|
|
if (typeof execute !== "function")
|
|
throw new Error("function command has no run callback");
|
|
const invoke = (options: Record<string, unknown>): Promise<unknown> =>
|
|
execute({
|
|
args: (argsSchema as { parse(v: unknown): unknown }).parse({
|
|
path: "/fixtures/native.exe",
|
|
address: "main",
|
|
}),
|
|
options: (optionsSchema as { parse(v: unknown): unknown }).parse(options),
|
|
});
|
|
return { runDirectAnalysis, invoke };
|
|
};
|
|
|
|
it("defaults to the complete dossier and runs analysis", async () => {
|
|
const h = harness();
|
|
const out = (await h.invoke({})) as { operation?: string };
|
|
expect(h.runDirectAnalysis).toHaveBeenCalledOnce();
|
|
expect(out.operation).toBe("analyze_function");
|
|
expect(
|
|
(out as { normalized_result?: unknown }).normalized_result,
|
|
).toBeDefined();
|
|
});
|
|
|
|
it("rejects summary delivery without --evidence_output before any analysis", async () => {
|
|
const h = harness();
|
|
const out = await h.invoke({ detail: "summary" });
|
|
expect(h.runDirectAnalysis).not.toHaveBeenCalled();
|
|
expect(JSON.stringify(out)).toContain("evidence_output");
|
|
});
|
|
|
|
it("summary delivery returns the compact view and writes a bundle inspect-analysis-view pages", async () => {
|
|
const h = harness();
|
|
const directory = await createTestTempDirectory("rea-fn-detail-");
|
|
const destination = join(directory, "complete.json");
|
|
const out = (await h.invoke({
|
|
detail: "summary",
|
|
evidence_output: destination,
|
|
})) as {
|
|
summary: {
|
|
normalized_result: { kind: string; parent_evidence_id: string };
|
|
};
|
|
evidence_bundle: { path: string; bytes: number };
|
|
};
|
|
expect(h.runDirectAnalysis).toHaveBeenCalledOnce();
|
|
expect(out.summary.normalized_result.kind).toBe("summary");
|
|
expect(typeof out.summary.normalized_result.parent_evidence_id).toBe(
|
|
"string",
|
|
);
|
|
expect(out.evidence_bundle.bytes).toBeGreaterThan(0);
|
|
expect((await stat(destination)).size).toBeGreaterThan(0);
|
|
// The saved bundle is the evidence-file source inspect-analysis-view reads back.
|
|
const parentId = out.summary.normalized_result.parent_evidence_id;
|
|
const page = await inspectAnalysisView({
|
|
source: { kind: "evidence-file", path: destination, evidence_id: parentId },
|
|
view: { kind: "native", facet: "pseudocode", offset: 0, limit: 16 },
|
|
});
|
|
if (!page.ok) throw page.error;
|
|
expect(page.value.parameters).toMatchObject({ parent_evidence_id: parentId });
|
|
expect(page.value.normalized_result).toMatchObject({
|
|
kind: "native",
|
|
item: {
|
|
text: functionDossierSchema
|
|
.parse(ghidraFunctionDossier())
|
|
.pseudocode.slice(0, 16),
|
|
},
|
|
});
|
|
});
|