74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
/**
|
|
* Unit tests for the Jira / Confluence / GitLab REST helpers.
|
|
* The lib modules are pure (no pi API), so we inject a mocked `fetchImpl`.
|
|
* Run with: node --experimental-strip-types test/api.test.ts
|
|
*/
|
|
process.env.PI_KIT_AUDIT_OFF = "1";
|
|
process.env.JIRA_TOKEN = "t-jira";
|
|
process.env.CONFLUENCE_TOKEN = "t-conf";
|
|
process.env.GITLAB_TOKEN = "t-glab";
|
|
|
|
import { buildUrl, requireToken, ApiError } from "../extensions/lib/atlassian.ts";
|
|
import { jiraBaseUrl, issueGet } from "../extensions/lib/jira.ts";
|
|
import { gitlabBaseUrl, projectId } from "../extensions/lib/gitlab.ts";
|
|
import { confluenceBaseUrl } from "../extensions/lib/confluence.ts";
|
|
|
|
let fails = 0;
|
|
function check(name: string, cond: boolean) {
|
|
console.log(`${cond ? "PASS" : "FAIL"} ${name}`);
|
|
if (!cond) fails++;
|
|
}
|
|
|
|
function okFetch(jsonBody: unknown): typeof fetch {
|
|
return (async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => jsonBody,
|
|
})) as any;
|
|
}
|
|
|
|
async function main() {
|
|
// --- atlassian helpers ---
|
|
check("buildUrl: appends query, drops empties", buildUrl("https://x/", "/a", { q: "1", e: undefined }) === "https://x/a?q=1");
|
|
check("buildUrl: no query when none", buildUrl("https://x", "/a") === "https://x/a");
|
|
check("requireToken: returns value", requireToken("JIRA_TOKEN", "h") === "t-jira");
|
|
check("requireToken: throws on missing", (() => {
|
|
try { requireToken("NO_SUCH_VAR_ZZZ", "h"); return false; } catch (e) { return e instanceof ApiError; }
|
|
})());
|
|
|
|
// --- config resolution (needs a real company.json present) ---
|
|
check("jiraBaseUrl resolves", typeof jiraBaseUrl() === "string" && jiraBaseUrl() !== "");
|
|
check("gitlabBaseUrl ends with api/v4", gitlabBaseUrl().endsWith("/api/v4"));
|
|
check("confluenceBaseUrl resolves", typeof confluenceBaseUrl() === "string" && confluenceBaseUrl() !== "");
|
|
|
|
// --- gitlab project id encoding ---
|
|
check("projectId encodes namespaces", projectId("grp/repo") === "grp%2Frepo");
|
|
check("projectId passes through numeric id", projectId("42") === "42");
|
|
|
|
// --- issueGet through a mocked fetch (field mapping) ---
|
|
const issueUrl = await issueGetByKey("PROJ-123");
|
|
check("issueGet hits /rest/api/2/issue/<key>", issueUrl.includes("/rest/api/2/issue/"));
|
|
|
|
console.log(fails === 0 ? "\nALL PASS" : `\n${fails} FAILED`);
|
|
process.exit(fails === 0 ? 0 : 1);
|
|
}
|
|
|
|
async function issueGetByKey(key: string): Promise<string> {
|
|
// Capture the URL by injecting a mocked fetch into the issueGet call path.
|
|
// We temporarily swap global.fetch.
|
|
const realFetch = globalThis.fetch;
|
|
let captured = "";
|
|
globalThis.fetch = (async (input: any) => {
|
|
captured = String(input);
|
|
return { ok: true, status: 200, json: async () => ({ key, fields: { summary: "s", status: { name: "Done" } } }) };
|
|
}) as any;
|
|
try {
|
|
await issueGet(key);
|
|
} finally {
|
|
globalThis.fetch = realFetch;
|
|
}
|
|
return captured;
|
|
}
|
|
|
|
main();
|