Files
diegosouzapw--omniroute/tests/unit/m365-connection-4042.test.ts
2026-07-13 13:39:12 +08:00

132 lines
5.3 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
// #4042 — M365 Copilot (individual) connection helpers: credential resolution,
// WS URL building, token redaction, and prompt flattening. Pure functions, no
// live socket — the round-trip is the separate Rule #18 validation gate.
import {
M365_INDIVIDUAL_DEFAULTS,
newChatSessionId,
resolveConnectionParams,
buildWsUrl,
redactWsUrl,
buildPrompt,
} from "../../open-sse/executors/copilot-m365-connection.ts";
// ── Credential resolution ────────────────────────────────────────────────
test("resolveConnectionParams errors when the access_token is missing", () => {
const r = resolveConnectionParams(undefined);
assert.ok("error" in r);
assert.match((r as { error: string }).error, /access_token/i);
});
test("resolveConnectionParams errors when the Chathub path is missing", () => {
const r = resolveConnectionParams({ apiKey: "tok" });
assert.ok("error" in r);
assert.match((r as { error: string }).error, /Chathub path/i);
});
test("resolveConnectionParams reads token from apiKey and path from providerSpecificData", () => {
const r = resolveConnectionParams({
apiKey: "opaque-jwe-token",
providerSpecificData: { chathubPath: "user-oid@tenant-id" },
});
assert.ok(!("error" in r));
const p = r as { host: string; chathubPath: string; accessToken: string };
assert.equal(p.accessToken, "opaque-jwe-token");
assert.equal(p.chathubPath, "user-oid@tenant-id");
assert.equal(p.host, M365_INDIVIDUAL_DEFAULTS.host);
});
test("resolveConnectionParams accepts access_token in providerSpecificData and a custom host", () => {
const r = resolveConnectionParams({
providerSpecificData: {
access_token: "tok2",
userTenant: "u@t",
host: "substrate.svc.cloud.microsoft",
},
});
assert.ok(!("error" in r));
const p = r as { host: string; chathubPath: string; accessToken: string };
assert.equal(p.accessToken, "tok2");
assert.equal(p.chathubPath, "u@t");
assert.equal(p.host, "substrate.svc.cloud.microsoft");
});
test("resolveConnectionParams parses the pasted OmniRoute credential line", () => {
const r = resolveConnectionParams({
apiKey: "access_token=tok3; chathubPath=redacted-account@redacted-tenant",
});
assert.ok(!("error" in r));
const p = r as { chathubPath: string; accessToken: string };
assert.equal(p.accessToken, "tok3");
assert.equal(p.chathubPath, "redacted-account@redacted-tenant");
});
test("resolveConnectionParams parses a pasted Chathub WebSocket URL", () => {
const r = resolveConnectionParams({
apiKey:
"wss://substrate.office.com/m365Copilot/Chathub/redacted-account%40redacted-tenant?access_token=tok4&source=officeweb",
});
assert.ok(!("error" in r));
const p = r as { chathubPath: string; accessToken: string };
assert.equal(p.accessToken, "tok4");
assert.equal(p.chathubPath, "redacted-account@redacted-tenant");
});
// ── WS URL building ──────────────────────────────────────────────────────
test("buildWsUrl targets the substrate Chathub with the individual-tier query", () => {
const url = buildWsUrl({ host: "substrate.office.com", chathubPath: "u@t", accessToken: "TOK" });
assert.ok(url.startsWith("wss://substrate.office.com/m365Copilot/Chathub/u@t?"));
const qs = new URLSearchParams(url.split("?")[1]);
assert.equal(qs.get("licenseType"), "Starter");
assert.equal(qs.get("agent"), "web");
assert.equal(qs.get("scenario"), "OfficeWebPaidConsumerCopilot");
assert.equal(qs.get("source"), "officeweb");
assert.ok(qs.get("variants")?.includes("feature.bizchatfluxv3"));
assert.equal(qs.get("access_token"), "TOK");
// chatsessionid == XRoutingParameterSessionKey == clientrequestid (same value)
const sid = qs.get("chatsessionid");
assert.ok(sid && /^[0-9a-f]{32}$/.test(sid));
assert.equal(qs.get("XRoutingParameterSessionKey"), sid);
assert.equal(qs.get("clientrequestid"), sid);
});
test("redactWsUrl strips the access_token so the URL is safe to log", () => {
const url = buildWsUrl({ host: "substrate.office.com", chathubPath: "u@t", accessToken: "SECRET" });
const redacted = redactWsUrl(url);
assert.ok(!redacted.includes("SECRET"), "token must not survive redaction");
assert.match(redacted, /access_token=REDACTED/);
});
test("newChatSessionId is 32 lowercase hex chars", () => {
const id = newChatSessionId();
assert.match(id, /^[0-9a-f]{32}$/);
assert.notEqual(newChatSessionId(), id);
});
// ── Prompt flattening ────────────────────────────────────────────────────
test("buildPrompt returns the last user message", () => {
const prompt = buildPrompt({
messages: [
{ role: "user", content: "first" },
{ role: "user", content: "second" },
],
});
assert.equal(prompt, "second");
});
test("buildPrompt prepends system instructions", () => {
const prompt = buildPrompt({
messages: [
{ role: "system", content: "Be terse." },
{ role: "user", content: "hi" },
],
});
assert.match(prompt, /\[System Instructions\]\nBe terse\.\n\nhi$/);
});