← Files DataARCHIVED FILE
tests/inline-sources.test.mjs
22.4 KB · Sep 30, 2026 · 23:19 UTC
import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { readFileSync } from "node:fs";
import { mkdtemp, readFile, rm, stat, symlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { promisify } from "node:util";
import { DATA_PLUGIN_ROOT, defaultInlineCacheDir } from "../skills/visualize-data/scripts/inline-chart-build.mjs";
import { normalizeInlineChartInput } from "../skills/visualize-data/scripts/inline-chart-input.mjs";
import { normalizeInlineSourcesInput } from "../skills/visualize-data/scripts/inline-sources-input.mjs";
import { renderInlineSources } from "../skills/visualize-data/scripts/render-inline-sources.mjs";
const exec = promisify(execFile);
const fixture = () => JSON.parse(readFileSync(new URL("../skills/visualize-data/assets/inline-sources-example.json", import.meta.url)));
const first = (input) => input.items[0].queries[0];
const sourceOnly = () => ({ schemaVersion: 1, items: [{ id: "context", title: "What does the release note say?", queries: [{
id: "release-note", source: { label: "Supplied release note", links: [{ label: "Release note", href: "https://example.com/releases" }] },
}] }] });
test("finding assumptions retain their own scope without inventing defaults", () => {
const input = sourceOnly();
assert.equal(normalizeInlineSourcesInput(input).items[0].assumptions, undefined);
input.items[0].assumptions = [" Release means the documented rollout. ", "Release means the documented rollout."];
input.items[1] = { ...structuredClone(input.items[0]), id: "other", assumptions: [] };
const actual = normalizeInlineSourcesInput(input);
assert.deepEqual(actual.items[0].assumptions, ["Release means the documented rollout."]);
assert.equal(actual.items[1].assumptions, undefined);
assert.deepEqual(actual, normalizeInlineSourcesInput(actual));
});
test("receipts reject confidence fields and unsafe assumptions", () => {
for (const confidence of [null, "high", { level: "med", reason: "A gap." }, { level: 96, reason: "A score." },
{ level: "high" }, { level: "low", reason: " " }, { level: "high", reason: "x".repeat(2001) },
{ level: "high", reason: "A score.", score: .96 },
{ level: "low", reason: "api_key = 'not-for-sharing'" },
{ level: "low", reason: "See https://example.com/path?token=private" }]) {
const input = sourceOnly(); input.items[0].confidence = confidence;
assert.throws(() => normalizeInlineSourcesInput(input), /confidence|credentials|unsafe source URL/u);
}
for (const assumptions of [null, "Not an array", [" "], ["x".repeat(2001)], Array(21).fill("A"),
["api_key = 'not-for-sharing'"], ["See https://example.com/path?token=private"]]) {
const input = sourceOnly(); input.items[0].assumptions = assumptions;
assert.throws(() => normalizeInlineSourcesInput(input), /assumptions|credentials|unsafe source URL/u);
}
});
test("receipt source roles resolve only to their own projected source identities", () => {
const input = sourceOnly();
first(input).sourceRoles = [{ kind: "link", label: "Release note", role: "Records the release timing." }];
const actual = first(normalizeInlineSourcesInput(input));
assert.deepEqual(actual.sourceRoles, [{ kind: "link", label: "Release note",
href: "https://example.com/releases", role: "Records the release timing." }]);
for (const role of [
{ kind: "table", label: "Release note", role: "Wrong kind." },
{ kind: "link", label: "Other source", role: "Unrelated source." },
{ kind: "link", label: "Release note", href: "https://example.com/other", role: "Wrong URL." },
{ kind: "link", label: "Release note", role: "x".repeat(1_001) },
{ kind: "link", label: "Release note", role: "api_key = 'not-for-sharing'" },
{ kind: "link", label: "Release note", role: "See https://example.com/path?token=private" },
]) {
first(input).sourceRoles = [role];
assert.throws(() => normalizeInlineSourcesInput(input), /sourceRole|credentials|unsafe source URL/u);
}
first(input).sourceRoles = [actual.sourceRoles[0], actual.sourceRoles[0]];
assert.throws(() => normalizeInlineSourcesInput(input), /repeat a source identity/u);
first(input).sourceRoles = [{ kind: "link", label: "Release note", role: "Ambiguous identity." }];
first(input).source.links.push({ label: "Release note", href: "https://example.com/another-release" });
assert.throws(() => normalizeInlineSourcesInput(input), /exactly one source/u);
});
test("receipt source roles cannot refer to a different query or leak across cards", () => {
const input = sourceOnly();
const other = structuredClone(input.items[0]);
other.id = "other";
other.queries[0].source.links = [{ label: "Other note", href: "https://example.com/other" }];
other.queries[0].sourceRoles = [{ kind: "link", label: "Other note", role: "A separate finding." }];
input.items.push(other);
const result = normalizeInlineSourcesInput(input);
assert.equal(first(result).sourceRoles, undefined);
assert.equal(result.items[1].queries[0].sourceRoles[0].role, "A separate finding.");
first(input).sourceRoles = other.queries[0].sourceRoles;
assert.throws(() => normalizeInlineSourcesInput(input), /own query/u);
});
test("receipt accepts source-only answers without fabricating rows, SQL, dates or evidence", () => {
const input = sourceOnly();
first(input).summary = "The supplied note records a required setup step, not its effect on activation.";
const value = normalizeInlineSourcesInput(input);
const query = first(value);
assert.equal(query.summary, first(input).summary);
assert.equal(query.rows, undefined);
assert.equal(query.source.sql, undefined);
assert.equal(query.source.executedAt, undefined);
assert.equal(query.capturedAt, undefined);
assert.equal(query.reportingPeriod, undefined);
assert.deepEqual(query.source.evidenceFlow, []);
assert.equal(query.source.links[0].href, "https://example.com/releases");
});
test("receipt carries table usage snapshots through disclosure without exposing private notes", () => {
const input = sourceOnly();
const trust = {
provider: "BigQuery", queryCount: 0, uniqueUsers: 0, windowDays: 30,
usageAsOf: "2026-09-04T00:00:00Z",
lastQueriedAt: "2026-08-01T12:00:00Z",
usageNote: "Non-cache-hit queries visible in this project and region.",
};
first(input).source.tables = [{ name: "analytics.reviewed.daily", trust }, "analytics.unknown.daily"];
const normalized = normalizeInlineSourcesInput(input);
assert.deepEqual(first(normalized).source.tables, [
{ name: "analytics.reviewed.daily", trust }, { name: "analytics.unknown.daily" },
]);
assert.deepEqual(normalizeInlineSourcesInput(normalized), normalized);
trust.usageNote = "api_key = 'not-for-sharing'";
assert.throws(() => normalizeInlineSourcesInput(input), /credentials/u);
});
test("receipt retains exact SQL, Python, calculations and safe links automatically", () => {
const input = fixture();
first(input).source.sql = "\n SELECT activated\nFROM weekly;\n";
first(input).source.links = [{ label: "Recorded query", href: "https://example.com/query/123" }];
first(input).methods.push({ language: "python", code: "\nrate = activated / eligible\n" });
first(input).source.metricDefinitions[0].calculationSummary = "Divide activated by eligible in August 2026.";
first(input).source.evidenceFlow[0].kind = "source";
first(input).source.evidenceFlow[0].showInReceipt = false;
const query = first(normalizeInlineSourcesInput(input));
assert.equal(query.source.metricDefinitions[0].calculationSummary, "Divide activated by eligible in August 2026.");
assert.equal(query.source.evidenceFlow[0].kind, "source");
assert.equal(query.source.evidenceFlow[0].showInReceipt, false, "Disclosure does not delete the recorded audit event");
const unsafeAudit = structuredClone(input);
first(unsafeAudit).source.evidenceFlow[0].detail = "api_key = 'not-for-sharing'";
assert.throws(() => normalizeInlineSourcesInput(unsafeAudit), /credentials/u,
"Hidden audit metadata must still pass the same disclosure safety checks");
const unsafeSummary = structuredClone(input);
first(unsafeSummary).source.metricDefinitions[0].calculationSummary = "api_key = 'not-for-sharing'";
assert.throws(() => normalizeInlineSourcesInput(unsafeSummary), /credentials/u);
const unknownKind = structuredClone(input);
first(unknownKind).source.evidenceFlow[0].kind = "toString";
assert.equal(first(normalizeInlineSourcesInput(unknownKind)).source.evidenceFlow[0].kind, undefined);
assert.equal(query.source.sql, first(input).source.sql);
assert.deepEqual(query.methods, first(input).methods);
assert.equal(query.source.links[0].href, "https://example.com/query/123");
const chart = { schemaVersion: 1, title: "Activation", chart: { type: "bar", x: "week", y: "activated" },
rows: first(input).rows, source: first(input).source };
const normalizedChart = normalizeInlineChartInput(chart, { includeSql: true });
assert.equal(normalizedChart.query.source.sql, first(input).source.sql);
assert.deepEqual(normalizedChart.query.source.links, []);
});
test("provider query links survive receipt projection and honor chart disclosure options", () => {
const input = fixture();
const href = "https://acme.cloud.databricks.com/sql/editor/123?o=456";
first(input).source.queryUrl = href;
const normalized = normalizeInlineSourcesInput(input);
assert.equal(first(normalized).source.queryUrl, href);
assert.equal(first(normalizeInlineSourcesInput(normalized)).source.queryUrl, href,
"The recorded destination survives repeated receipt normalization");
const chart = { schemaVersion: 1, title: "Activation", chart: { type: "bar", x: "week", y: "activated" },
rows: first(input).rows, source: first(input).source };
for (const options of [{}, { includeSql: true }, { includeSourceUrls: true }]) {
assert.equal(normalizeInlineChartInput(chart, options).query.source.queryUrl, undefined,
"A query link requires disclosure of both SQL and source URLs");
}
assert.equal(normalizeInlineChartInput(chart, { includeSql: true, includeSourceUrls: true }).query.source.queryUrl, href);
first(input).source.queryUrl = `${href}&token=private`;
assert.throws(() => normalizeInlineSourcesInput(input), /credentials|access tokens/u);
first(input).source.queryUrl = `${href}&unapproved=state`;
assert.equal(first(normalizeInlineSourcesInput(input)).source.queryUrl, undefined);
});
test("receipt scopes each card's definitions and projects only approved row fields", () => {
const input = fixture();
first(input).rows[0].email = "excluded@example.test";
first(input).source.privateToolOutput = "not part of the receipt";
first(input).source.metricDefinitions.push({ label: "Private measure", definition: "Other card only.", componentIds: ["other"] });
const second = structuredClone(input.items[0]);
second.id = "other"; second.title = "A second finding";
second.queries[0].rows = [{ week: "2026-08-17", activated: 3, eligible: 7 }];
input.items.push(second);
const value = normalizeInlineSourcesInput(input);
assert.equal(value.items.length, 2);
assert.equal(first(value).source.metricDefinitions.length, 1);
assert.deepEqual(value.items[1].queries[0].source.metricDefinitions.map(({ label }) => label), ["Private measure"]);
assert.equal(first(value).rows[0].activated, 240);
assert.equal(value.items[1].queries[0].rows[0].activated, 3);
assert.doesNotMatch(JSON.stringify(value), /excluded@example|privateToolOutput/u);
assert.deepEqual(first(value).source.filters, ["Plan: all plans"]);
});
test("one finding retains distinct source summaries, methods, SQL, rows and qualifications", () => {
const input = fixture();
first(input).summary = "Weekly activation counts.";
const other = structuredClone(first(input));
other.id = "other-snapshot";
other.summary = "A different cohort; do not combine its denominator with the first source.";
other.source.label = "Other cohort";
other.source.sql = "SELECT activated, eligible FROM other_cohort";
other.source.caveats = ["Different cohort."];
other.reportingPeriod = "September 2026";
other.rows = [{ week: "2026-09-01", activated: 3, eligible: 10 }];
other.methods = [{ language: "python", code: "\nrate = 3 / 10\n" }];
input.items[0].queries.push(other);
const value = normalizeInlineSourcesInput(input);
assert.equal(value.items.length, 1);
const [a, b] = value.items[0].queries;
assert.equal(a.rows[0].activated, 240);
assert.deepEqual(b.rows, other.rows);
assert.equal(b.source.sql, other.source.sql);
assert.equal(b.reportingPeriod, other.reportingPeriod);
assert.deepEqual(b.source.caveats, other.source.caveats);
assert.deepEqual(b.methods, other.methods);
assert.equal(b.summary, other.summary);
assert.notEqual(a.summary, b.summary);
});
test("Python floor division is not a source URL and recorded literals retain URL checks", () => {
const input = fixture();
for (const code of ["half = total//2", "buckets = total // width", "total //= 2", "half = (a + b)//2",
"rows = values[1:]//2\nsource = 'https://example.com/data'", "url = r'''https://example.com/data'''\ncount = total//2"]) {
first(input).methods = [{ language: "python", code }];
assert.equal(first(normalizeInlineSourcesInput(input)).methods[0].code, code);
}
for (const code of ["url = '//example.com/data'", 'url = "//example.com/data"',
"url = '''//example.com/data'''", 'url = """//example.com/data"""',
"# //example.com/data\nhalf = total//2", "url = 'https://example.com/data?token=private'",
"https://example.com/data?token=private\nhalf = total//2"]) {
first(input).methods = [{ language: "python", code }];
assert.throws(() => normalizeInlineSourcesInput(input), /unsafe source URL|credentials/u);
}
});
test("receipt timestamps reject impossible calendar dates without normalizing recorded values", () => {
for (const field of ["capturedAt", "executedAt"]) {
const input = fixture();
const set = (value) => {
if (field === "capturedAt") first(input).capturedAt = value;
else first(input).source.executedAt = value;
};
for (const value of ["2026-02-30T00:00:00Z", "2026-02-29T00:00:00Z", "1900-02-29T00:00:00Z",
"2026-04-31T00:00:00+03:00", "2026-00-01T00:00:00Z", "2026-01-00T00:00:00Z", "2026-13-01T00:00:00Z"]) {
set(value);
assert.throws(() => normalizeInlineSourcesInput(input), /calendar date|timezone|recorded timestamp/u);
}
for (const value of ["2024-02-29T00:00:00Z", "2000-02-29T23:59:59.123456-08:00", "2026-01-01T00:00:00+14:00"]) {
set(value);
const actual = first(normalizeInlineSourcesInput(input));
assert.equal(field === "capturedAt" ? actual.capturedAt : actual.source.executedAt, value);
}
}
});
test("receipt distinguishes reporting window, execution, capture, empty results, and partial previews", () => {
const input = fixture();
const query = first(input);
query.source.executedAt = "2026-08-18T10:00:00-07:00";
query.capturedAt = "2026-08-18T17:02:00Z";
query.preview = { kind: "partial", note: "First two recorded rows.", totalRows: 20 };
const actual = first(normalizeInlineSourcesInput(input));
assert.equal(actual.reportingPeriod, query.reportingPeriod);
assert.equal(actual.source.executedAt, query.source.executedAt);
assert.equal(actual.capturedAt, query.capturedAt);
assert.deepEqual(actual.preview, query.preview);
query.rows = [];
delete query.preview;
assert.deepEqual(first(normalizeInlineSourcesInput(input)).rows, []);
});
test("receipt projects approved labeled columns without changing recorded fields or values", () => {
const input = fixture();
const query = first(input);
query.columns = ["year", { field: "anomaly", label: "Annual anomaly (°C)", ignored: "not projected" }];
query.rows = [{ year: 2025, anomaly: 1.19, excluded: "not approved" }];
const actual = first(normalizeInlineSourcesInput(input));
assert.deepEqual(actual.columns, [{ field: "year" }, { field: "anomaly", label: "Annual anomaly (°C)" }]);
assert.deepEqual(actual.rows, [{ year: 2025, anomaly: 1.19 }]);
assert.deepEqual(normalizeInlineSourcesInput(normalizeInlineSourcesInput(input)), normalizeInlineSourcesInput(input));
for (const columns of [
["year", { field: "year", label: "Duplicate" }],
[{ field: "anomaly", label: " " }],
[{ field: "anomaly", label: "x".repeat(201) }],
[{ field: "missing", label: "Unknown" }],
[{ field: "email", label: "Innocuous label" }],
[{ field: "anomaly", label: "api_key = 'not-for-sharing'" }],
]) {
query.columns = columns;
assert.throws(() => normalizeInlineSourcesInput(input), /column|credentials/u);
}
});
test("receipt rejects ambiguous IDs, unknown fields, malformed preview claims and oversize evidence", () => {
const cases = [
[(input) => input.items.push(structuredClone(input.items[0])), /item IDs/u],
[(input) => input.items[0].queries.push(structuredClone(first(input))), /query IDs/u],
[(input) => first(input).columns.push("missing"), /missing/u],
[(input) => delete first(input).columns, /approved preview columns/u],
[(input) => first(input).preview = { kind: "partial", note: "Some rows", totalRows: 1 }, /totalRows/u],
[(input) => first(input).capturedAt = "2026-08-18", /timezone/u],
[(input) => first(input).source.executedAt = "2026-08-18", /timezone/u],
[(input) => first(input).methods = [{ language: "bash", code: "echo no" }], /language/u],
[(input) => first(input).summary = " ", /summary/u],
[(input) => first(input).summary = "x".repeat(2_001), /summary/u],
[(input) => first(input).rows = Array.from({ length: 2_001 }, () => first(input).rows[0]), /2|2000/u],
[(input) => { input.items.push({ ...structuredClone(input.items[0]), id: "other" });
input.items.forEach((item) => item.queries[0].rows = Array.from({ length: 1_100 }, () => ({ week: "2026-08-03", activated: 1, eligible: 2 }))); }, /complete receipt/u],
];
for (const [mutate, pattern] of cases) {
const input = fixture(); mutate(input);
assert.throws(() => normalizeInlineSourcesInput(input), pattern);
}
});
test("receipt rejects credential-bearing evidence and direct contact/payment preview fields", () => {
for (const mutate of [
(input) => first(input).source.links = [{ href: "https://example.com/query?access_token=secret" }],
(input) => first(input).source.sql = "SELECT 'x'; -- api_key = 'not-for-sharing'",
(input) => first(input).methods = [{ language: "python", code: "password = 'not-for-sharing'" }],
(input) => first(input).source.caveats = ["postgres://user:password@host/db"],
(input) => first(input).summary = "api_key = 'not-for-sharing'",
(input) => { first(input).columns.push("email"); first(input).rows[0].email = "contact@example.test"; },
(input) => { first(input).columns.push("creditCard"); first(input).rows[0].creditCard = "4111111111111111"; },
]) {
const input = fixture(); mutate(input);
assert.throws(() => normalizeInlineSourcesInput(input), /credentials|identifiers/u);
}
for (const field of ["e-mail", "e_mail", "eMail", "contact e--mail"]) {
for (const column of [field, { field, label: "Reviewed value" }]) {
const input = sourceOnly();
Object.assign(first(input), { columns: [column], rows: [{ [field]: "contact@example.test" }] });
assert.throws(() => normalizeInlineSourcesInput(input), /identifiers/u, `Reject contact field ${field}`);
}
}
const input = sourceOnly();
first(input).source.links.push({ label: "Unsafe", href: "javascript:alert(1)" });
assert.equal(first(normalizeInlineSourcesInput(input)).source.links.length, 1);
});
test("receipt renderer delivers a bounded, escaped, private fragment without a chart or extra answer", async () => {
const directory = await mkdtemp(join(tmpdir(), "data-sources-test-"));
try {
const input = fixture();
input.items[0].title = "</script><img src=x onerror=alert(1)> $&";
const output = join(directory, "answer-sources.html");
const result = await renderInlineSources({ input, output });
const html = await readFile(result.path, "utf8");
assert.equal(result.prebuilt, true);
assert.equal(result.itemCount, 1);
assert.ok(result.bytes < 1_000_000);
assert.equal((await stat(output)).mode & 0o777, 0o600);
const payloads = [...html.matchAll(/<script type="application\/json"[^>]*>([\s\S]*?)<\/script>/gu)];
assert.equal(payloads.length, 1);
const payload = JSON.parse(payloads[0][1]);
assert.equal(payload.items[0].title, input.items[0].title);
assert.equal(payload.kind, "sources");
assert.equal(payload.component, undefined);
assert.doesNotMatch(html, /<img src=x|__INLINE_|mountInlineChart\(/u);
assert.match(html, /CodexDataSourcesReceipt\.mountSourcesReceipt/u);
} finally { await rm(directory, { recursive: true, force: true }); }
});
test("receipt shares the existing plugin/cache/symlink output protection", async () => {
const input = sourceOnly();
await assert.rejects(renderInlineSources({ input, output: join(DATA_PLUGIN_ROOT, "private-sources.html") }), /outside the installed/u);
// CI overrides the legacy cache path; check the same active cache as the renderer.
const cacheDir = process.env.DATA_INLINE_CACHE_DIR || defaultInlineCacheDir();
await assert.rejects(renderInlineSources({ input, output: join(cacheDir, "private-sources.html") }), /shared renderer cache/u);
const directory = await mkdtemp(join(tmpdir(), "data-sources-path-"));
try {
const original = join(directory, "original.html");
await writeFile(original, "preserve");
const output = join(directory, "linked-sources.html");
await symlink(original, output);
await assert.rejects(renderInlineSources({ input, output }), /symlinked/u);
assert.equal(await readFile(original, "utf8"), "preserve");
} finally { await rm(directory, { recursive: true, force: true }); }
});
test("fresh-process receipt generation needs no npm, dependency cache or network", async () => {
const directory = await mkdtemp(join(tmpdir(), "data-sources-offline-"));
try {
const input = join(directory, "input.json");
await writeFile(input, JSON.stringify(sourceOnly()));
const { stdout } = await exec(process.execPath, [join(DATA_PLUGIN_ROOT, "skills/visualize-data/scripts/render-inline-sources.mjs"),
"--input", input, "--output", join(directory, "offline-sources.html")], {
cwd: directory, env: { PATH: directory, NODE_PATH: "", NODE_OPTIONS: "", npm_config_offline: "true" },
});
assert.equal(JSON.parse(stdout).prebuilt, true);
} finally { await rm(directory, { recursive: true, force: true }); }
});
SHA-256: 4a96894e9dd7ffbfeed2e5f1126e1c3bcf74421bce13033fbed69d419d2948f4