Files
morluto 60149282fc test: strengthen integration oracles and verification (#8295)
* test: strengthen integration oracles and verification

* test: bound lifecycle gates and strengthen workflow checks

* test: verify complete paged and extracted results

* test: preserve bytecode and cancellation evidence

* test: strengthen retained evidence and fixture cleanup

* test: require cross-projection bridge identities

* test: retain fixture owners through cleanup failures

* test: verify graph examples and project selectors

* test: tighten provider and lifecycle regressions

* test: consolidate hex coverage and bound cutter cleanup

* test: bound subprocess output waits and strengthen graph checks

* test: check mcp recovery and preserve cleanup owners

* test: verify structured mcp argument failures

* test: preserve artifact cleanup and gdb limit evidence

* test: preserve evidence identities and bound provider gates

* test: retain browser and comparison cleanup owners

* test: bound startup and strengthen fixture oracles

* test: bound lifecycle gates and verify recovered evidence

* test: verify public outcomes and lifecycle ownership

* test: assert precise evidence and release lifecycle gates

* test: verify selected facts and bound cleanup waits

* test: check retained evidence and decoded records

* test: verify final reports and retain cleanup ownership

* test: bound reviewed startup gates and retain cleanup

* test: verify PE errors and preserve MCP cleanup

* test: preserve MCP fixture cleanup ownership

* test: release provider gates before late startup
2026-11-01 00:15:28 +08:00

128 lines
5.0 KiB
TypeScript

import { expect } from "vitest";
import { cliTest } from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { writeFixtureFiles } from "../../support/javascriptApplicationFixture.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { analysisViewResultSchema } from "../../../src/domain/analysisView/analysisView.js";
cliTest(
"retains constant window preferences and inferred source provenance through CLI, MCP and fact views",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-window-options-");
await writeFixtureFiles(root, {
"main.js": [
'throw new Error("Static input must never execute");',
'const { BrowserWindow } = require("electron");',
"function open() {",
' const prefs = {nodeIntegration: true, contextIsolation: false, preload: "./preload.js"};',
" const options = {webPreferences: prefs};",
' if (linux) options.icon = "icon.png";',
" new BrowserWindow(options);",
" const escaped = {webPreferences: {sandbox: true}};",
" patch(escaped); new BrowserWindow(escaped);",
" new BrowserWindow({webPreferences: {sandbox: true}});",
"}",
].join("\n"),
"preload.js": "// Inert preload source",
});
const cliResponse = await cli.run({
arguments: ["analyze-javascript-application", root, "--format", "json"],
});
expect(cliResponse.exitCode, JSON.stringify(cliResponse.json)).toBe(0);
const cliResult = javascriptApplicationAnalysisResultSchema.parse(
parseEvidence(cliResponse.json).normalized_result,
);
const { call } = await connectLocalToolsMcp();
const response = await call("analyze_javascript_application", {
input_path: root,
format: "directory",
});
expect(response.isError).not.toBe(true);
const parent = parseEvidence(response.structuredContent);
const result = javascriptApplicationAnalysisResultSchema.parse(
parent.normalized_result,
);
expect(result.graph).toEqual(cliResult.graph);
expect(result.summary).toEqual(cliResult.summary);
expect(result.summary).toMatchObject({
browser_windows: 3,
explicit_web_preferences: 4,
preload_entrypoints: 1,
});
const windows = result.graph.nodes.filter(
(node) => node.kind === "browser-window",
);
const resolved = windows.find(
(node) =>
node.observations[0]?.properties.resolution_sources !== undefined,
);
expect(resolved?.observations[0]).toMatchObject({
properties: {
source_path: "main.js",
options_status: "object-literal",
web_preferences: expect.arrayContaining([
{
name: "nodeIntegration",
value: { status: "literal", value: true, expression: null },
},
{
name: "contextIsolation",
value: { status: "literal", value: false, expression: null },
},
{
name: "preload",
value: {
status: "literal",
value: "./preload.js",
expression: null,
},
},
]),
resolution_sources: [
{ source: "main.js", start: { line: 5 } },
{ source: "main.js", start: { line: 4 } },
],
},
evidence: {
state: "inferred",
authority: "static-relationship-inference",
location: { value: { source: "main.js", start: { line: 7 } } },
},
});
expect(
windows.filter(
(node) =>
node.observations[0]?.properties.web_preferences_status === "dynamic",
),
).toHaveLength(1);
expect(
windows.filter(
(node) => node.observations[0]?.evidence.state === "observed",
),
).toHaveLength(2);
const viewResponse = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent.evidence_id },
view: {
kind: "javascript-facts",
where: { paths: ["main.js"], kinds: ["browser-window"] },
property_keys: ["web_preferences", "resolution_sources"],
},
});
expect(viewResponse.isError).not.toBe(true);
const view = analysisViewResultSchema.parse(
parseEvidence(viewResponse.structuredContent).normalized_result,
);
if (view.kind !== "javascript-facts") throw new Error("Expected fact view");
expect(view.rows).toHaveLength(3);
const row = view.rows.find((row) => row.node_id === resolved?.node_id);
expect(row?.evidence).toEqual(resolved?.observations[0]?.evidence);
expect(row?.properties).toEqual({
web_preferences: resolved?.observations[0]?.properties.web_preferences,
resolution_sources:
resolved?.observations[0]?.properties.resolution_sources,
});
},
);