Files
reverse-engineering-anything/tests/boundary/browser/cdpBrowserProvider.responseUtf8.test.ts
T
morluto 79805f244a fix(web): preserve JSON identity and coverage contracts
Decode base64 JSON body bytes at the shape owner without replacement characters. Keep incomplete request correspondence unknown and use explicitly complete authored inventories for positive comparison controls. Repair semantic truncation and storage fixtures to satisfy their owning contracts without weakening assertions.
2026-10-24 08:01:25 +08:00

159 lines
4.8 KiB
TypeScript

import { expect, it } from "vitest";
import { CdpBrowserProvider } from "../../../src/browser/CdpBrowserProvider.js";
import { inspectWebPageInputSchema } from "../../../src/domain/browserObservation.js";
import { startFakeCdpBrowser } from "../../fixtures/fakeCdpBrowser.js";
import { trackBrowser } from "./cdpBrowserProvider.support.js";
it.each([
{
name: "invalid UTF-8 property name",
body: Buffer.from([123, 34, 255, 34, 58, 116, 114, 117, 101, 125]),
property: null,
},
{
name: "invalid UTF-8 string value",
body: Buffer.from([123, 34, 107, 34, 58, 34, 255, 34, 125]),
property: null,
},
{
name: "overlong UTF-8 property name",
body: Buffer.from([123, 34, 192, 175, 34, 58, 116, 114, 117, 101, 125]),
property: null,
},
{
name: "valid UTF-8 property name",
body: Buffer.from('{"é":true}'),
property: "é",
},
{
name: "literal replacement-character property name",
body: Buffer.from('{"�":true}'),
property: "�",
},
])("preserves JSON-shape uncertainty for $name", async ({ body, property }) => {
const browser = await startFakeCdpBrowser({
eventsBeforeReply: ["Network.enable"],
commandEvents(command, origin) {
if (command.method !== "Network.enable") return [];
const session =
command.sessionId === undefined ? {} : { sessionId: command.sessionId };
return [false, true].flatMap((hasRequestShape) => {
const requestId = hasRequestShape
? "request-and-response"
: "response-only";
const url = `${origin}/${requestId}`;
return [
{
...session,
method: "Network.requestWillBeSent",
params: {
requestId,
request: {
url,
method: hasRequestShape ? "POST" : "GET",
...(hasRequestShape
? {
headers: { "Content-Type": "application/json" },
postData: '{"request":true}',
}
: {}),
},
initiator: { type: "other" },
},
},
{
...session,
method: "Network.responseReceived",
params: {
requestId,
response: { url, status: 200, mimeType: "application/json" },
},
},
{
...session,
method: "Network.loadingFinished",
params: { requestId, encodedDataLength: body.length },
},
];
});
},
commandResult(command) {
return command.method === "Network.getResponseBody"
? { body: body.toString("base64"), base64Encoded: true }
: undefined;
},
});
trackBrowser(browser);
const result = await new CdpBrowserProvider().inspectPage(
inspectWebPageInputSchema.parse({
cdp_endpoint: browser.endpoint,
allowed_origins: [browser.allowedOrigin],
target_id: "allowed-page",
observation_ms: 0,
include_json_body_shapes: true,
}),
);
if (!result.ok) throw result.error;
const requests = result.value.network.requests;
expect(requests).toHaveLength(2);
for (const request of requests) {
const hasRequestShape = request.request_id === "request-and-response";
expect(request).toMatchObject({
url: `${browser.allowedOrigin}/${request.request_id}`,
status: 200,
mime_type: "application/json",
encoded_data_length: body.length,
body_shapes: {
status:
property === null
? hasRequestShape
? "partial"
: "unavailable"
: "included",
request: hasRequestShape ? expect.any(Object) : null,
response:
property === null
? null
: {
root_type: "object",
node_count: 2,
max_depth_observed: 1,
properties: [
{
path: [{ kind: "property", name: property }],
types: ["boolean"],
observations: 1,
},
],
},
},
});
}
expect(
browser.commands.filter(
(command) => command.method === "Network.getResponseBody",
),
).toHaveLength(2);
if (property === null) {
expect(result.value.completeness.unavailable_sections).toContain(
"json_body_shapes",
);
expect(result.value.completeness.excluded).toContainEqual({
section: "json_body_shapes",
reason: "provider_unavailable",
count: null,
});
} else {
expect(result.value.completeness.unavailable_sections).not.toContain(
"json_body_shapes",
);
}
expect(result.value.completeness.excluded).not.toContainEqual(
expect.objectContaining({
section: "json_body_shapes",
reason: "invalid_protocol_value",
}),
);
});