164 lines
6.7 KiB
JavaScript
164 lines
6.7 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import { skillHome } from "./helpers/cli.mjs";
|
|
|
|
const cliShared = await import(pathToFileURL(path.join(skillHome, "scripts", "lib", "cli-shared.mjs")).href);
|
|
const outputContract = await import(pathToFileURL(path.join(skillHome, "scripts", "lib", "output-contract.mjs")).href);
|
|
const runtimePaths = await import(pathToFileURL(path.join(skillHome, "scripts", "lib", "runtime-paths.mjs")).href);
|
|
const authShared = await import(pathToFileURL(path.join(skillHome, "scripts", "lib", "auth-shared.mjs")).href);
|
|
|
|
test("cli-shared parses flags and csv values for agent-built commands", () => {
|
|
assert.deepEqual(
|
|
cliShared.parseArgs([
|
|
"ignored-position",
|
|
"--query",
|
|
"--select",
|
|
"opportunityId,",
|
|
"customerName",
|
|
"--render-sql",
|
|
"--limit",
|
|
"10",
|
|
]),
|
|
{
|
|
query: "true",
|
|
select: "opportunityId, customerName",
|
|
"render-sql": "true",
|
|
limit: "10",
|
|
}
|
|
);
|
|
|
|
const fallback = ["default"];
|
|
assert.equal(cliShared.splitCsv("", fallback), fallback);
|
|
assert.deepEqual(cliShared.splitCsv(" opportunityId, , customerName , bookingValue "), [
|
|
"opportunityId",
|
|
"customerName",
|
|
"bookingValue",
|
|
]);
|
|
});
|
|
|
|
test("output-contract formats display money while preserving API metrics defaults", () => {
|
|
const payload = outputContract.preparePayloadForOutput({
|
|
columns: ["opportunityId", "bookingValue", "workloadAmount"],
|
|
request: {
|
|
query: {
|
|
measure: [{ fieldName: "bookingValue", outputName: "totalBooking" }],
|
|
},
|
|
},
|
|
records: [
|
|
{
|
|
opportunityId: "OPP-1",
|
|
bookingValue: 1234567,
|
|
workloadAmount: "90,000",
|
|
totalBooking: 5000,
|
|
note: "unchanged",
|
|
},
|
|
],
|
|
summary: {
|
|
totalBookingValue: 1234567,
|
|
nested: { workloadAmount: 23000 },
|
|
},
|
|
});
|
|
|
|
assert.equal(payload.records[0].bookingValue, "1.234k");
|
|
assert.equal(payload.records[0].workloadAmount, "90k");
|
|
assert.equal(payload.records[0].totalBooking, "5k");
|
|
assert.equal(payload.records[0].note, "unchanged");
|
|
assert.equal(payload.summary.totalBookingValue, "1.234k");
|
|
assert.equal(payload.summary.nested.workloadAmount, "23k");
|
|
assert.equal(payload.apiMetrics.totalRowsPulledFromApi, 0);
|
|
});
|
|
|
|
test("output-contract normalizes Oracle cells and warnings", () => {
|
|
assert.equal(outputContract.normalizeCell("02-MAY-26"), "2026-05-02");
|
|
assert.equal(outputContract.normalizeCell("31-DEC-99"), "1999-12-31");
|
|
assert.equal(outputContract.normalizeCell("__CODEX_NULL__"), null);
|
|
assert.equal(outputContract.normalizeCell(undefined), null);
|
|
|
|
assert.deepEqual(
|
|
outputContract.mapRows(["closeDate", "amount"], [["02-MAY-2026", "__CODEX_NULL__"]]),
|
|
[{ closeDate: "2026-05-02", amount: null }]
|
|
);
|
|
|
|
const warnings = outputContract.buildWarnings({
|
|
requestedLimit: 10,
|
|
recordsCount: 10,
|
|
customSql: true,
|
|
customSqlColumnsResolved: false,
|
|
});
|
|
assert.equal(warnings.length, 2);
|
|
assert.match(warnings[0], /matches the requested limit/);
|
|
assert.match(warnings[1], /Custom SQL records are returned as raw row arrays/);
|
|
});
|
|
|
|
test("runtime-paths routes final and temporary outputs under the workspace skill folder", () => {
|
|
const workspaceRoot = path.join("/tmp", "kov-runtime-contracts");
|
|
const runtimeHome = path.join(workspaceRoot, "knowledge-one-view-cli", "runtime-test");
|
|
const normalizedRuntimeHome = path.join(workspaceRoot, "knowledge-one-view-cli", "runtime");
|
|
|
|
assert.equal(runtimePaths.resolveRuntimeHome(runtimeHome), normalizedRuntimeHome);
|
|
assert.equal(
|
|
runtimePaths.resolveOutputFilePath("final.json", runtimeHome),
|
|
path.join(workspaceRoot, "knowledge-one-view-cli", "output", "final.json")
|
|
);
|
|
assert.equal(
|
|
runtimePaths.resolveOutputFilePath("tmp-render.json", runtimeHome),
|
|
path.join(workspaceRoot, "knowledge-one-view-cli", "tmp", "tmp-render.json")
|
|
);
|
|
assert.equal(
|
|
runtimePaths.resolveOutputFilePath("reports/final.json", runtimeHome),
|
|
path.join(workspaceRoot, "knowledge-one-view-cli", "reports", "final.json")
|
|
);
|
|
});
|
|
|
|
test("runtime-paths refuses to infer a workspace inside .codex", () => {
|
|
assert.throws(
|
|
() => runtimePaths.resolveWorkspaceRoot(path.join(runtimePaths.CODEX_HOME, "skills", "knowledge-one-view-cli")),
|
|
/Cannot infer a workspace root/
|
|
);
|
|
});
|
|
|
|
test("auth-shared builds cookie headers with domain, path, secure, and expiry rules", () => {
|
|
const now = Math.floor(Date.now() / 1000);
|
|
const header = authShared.cookieHeaderFor("https://salesintelligence-dv.oracle.com/analytics/saw.dll", [
|
|
{ name: "root", value: "1", domain: ".oracle.com", path: "/", secure: true, expires: -1 },
|
|
{ name: "deep", value: "2", domain: "salesintelligence-dv.oracle.com", path: "/analytics", secure: true, expires: now + 60 },
|
|
{ name: "expired", value: "3", domain: "oracle.com", path: "/", secure: true, expires: now - 60 },
|
|
{ name: "httpOnly", value: "4", domain: "oracle.com", path: "/", secure: true, expires: -1 },
|
|
{ name: "wrong", value: "5", domain: "example.com", path: "/", secure: true, expires: -1 },
|
|
{ name: "insecureOnly", value: "6", domain: "oracle.com", path: "/", secure: false, expires: -1 },
|
|
]);
|
|
|
|
assert.equal(header, "deep=2; root=1; httpOnly=4; insecureOnly=6");
|
|
});
|
|
|
|
test("auth-shared splits and merges Set-Cookie headers", () => {
|
|
assert.deepEqual(
|
|
authShared.splitSetCookieHeader("a=1; Expires=Wed, 21 Oct 2030 07:28:00 GMT; Path=/, b=2; Path=/analytics; HttpOnly; SameSite=None; Secure"),
|
|
[
|
|
"a=1; Expires=Wed, 21 Oct 2030 07:28:00 GMT; Path=/",
|
|
"b=2; Path=/analytics; HttpOnly; SameSite=None; Secure",
|
|
]
|
|
);
|
|
|
|
const state = { cookies: [{ name: "a", value: "old", domain: "oracle.com", path: "/", expires: -1 }] };
|
|
const changed = authShared.mergeCookiesFromHeader(
|
|
state,
|
|
"https://salesintelligence-dv.oracle.com/analytics/saw.dll",
|
|
"a=1; Domain=.oracle.com; Path=/, b=2; Path=/analytics; HttpOnly; SameSite=None; Secure"
|
|
);
|
|
|
|
assert.equal(changed, true);
|
|
assert.equal(state.cookies.length, 2);
|
|
assert.equal(state.cookies.find((cookie) => cookie.name === "a").value, "1");
|
|
assert.equal(state.cookies.find((cookie) => cookie.name === "b").sameSite, "None");
|
|
assert.equal(state.cookies.find((cookie) => cookie.name === "b").httpOnly, true);
|
|
});
|
|
|
|
test("auth-shared classifies refresh-required errors", () => {
|
|
assert.equal(authShared.isAuthRefreshRequiredError(new Error("Request redirected to Oracle sign-in")), true);
|
|
assert.equal(authShared.isAuthRefreshRequiredError(new Error("Could not find auth state at /tmp/auth-state.json")), true);
|
|
assert.equal(authShared.isAuthRefreshRequiredError(new Error("Unsupported --limit abc")), false);
|
|
});
|