Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skillz/ims-process-review/scripts/atlassian-request.test.mjs

Raw
import assert from "node:assert/strict";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { test } from "node:test";
import {
	nextPageUrl,
	parseArgs,
	requestJson,
	resolveRequestUrl,
	runRequest,
	selectConnection,
} from "./atlassian-request.mjs";

function response(body, status = 200, headers = { "content-type": "application/json" }) {
	return new Response(typeof body === "string" ? body : JSON.stringify(body), { status, headers });
}

test("parses GET defaults and pagination options", () => {
	assert.deepEqual(parseArgs(["/wiki/api/v2/pages", "--paginate", "--max-pages", "4", "--profile", "work"]), {
		method: "GET",
		path: "/wiki/api/v2/pages",
		bodyFile: undefined,
		profile: "work",
		paginate: true,
		maxPages: 4,
		allowMutation: false,
	});
});

test("requires explicit mutation permission", () => {
	assert.throws(() => parseArgs(["POST", "/wiki/api/v2/pages"]), /requires --allow-mutation/);
	assert.equal(parseArgs(["POST", "/wiki/api/v2/pages", "--allow-mutation"]).method, "POST");
	assert.throws(() => parseArgs(["GET", "/x", "--body", "body.json"]), /GET does not accept --body/);
	assert.throws(() => parseArgs(["PATCH", "/x", "--allow-mutation", "--paginate"]), /--paginate requires GET/);
});

test("selects profiles with environment overrides", () => {
	const profiles = [
		{ name: "one", base_url: "https://one.example/", email: "one@example.com" },
		{ name: "two", base_url: "https://two.example/", email: "two@example.com", is_default: true },
	];
	assert.deepEqual(selectConnection(profiles), { baseUrl: "https://two.example/", email: "two@example.com" });
	assert.deepEqual(selectConnection(profiles, "one"), { baseUrl: "https://one.example/", email: "one@example.com" });
	assert.deepEqual(selectConnection([], undefined, {
		ATLASSIAN_BASE_URL: "https://env.example/",
		ATLASSIAN_EMAIL: "env@example.com",
	}), { baseUrl: "https://env.example/", email: "env@example.com" });
	assert.throws(() => selectConnection(profiles, "missing"), /Unknown Atlassian profile/);
});

test("keeps credentials on the configured HTTPS origin", () => {
	assert.equal(resolveRequestUrl("/wiki/api/v2/pages", "https://site.example/").href, "https://site.example/wiki/api/v2/pages");
	assert.throws(() => resolveRequestUrl("https://evil.example/x", "https://site.example/"), /Refusing to send/);
	assert.throws(() => resolveRequestUrl("/x", "http://site.example/"), /Refusing non-HTTPS/);
	assert.equal(resolveRequestUrl("/x", "http://127.0.0.1:1234/").href, "http://127.0.0.1:1234/x");
});

test("sends authenticated GET and parses JSON", async () => {
	let observed;
	const result = await runRequest(
		parseArgs(["/wiki/api/v2/pages/1"]),
		{ baseUrl: "https://site.example/", email: "person@example.com" },
		"secret",
		async (url, init) => {
			observed = { url: url.href, init };
			return response({ id: "1" });
		},
	);
	assert.deepEqual(result, { id: "1" });
	assert.equal(observed.url, "https://site.example/wiki/api/v2/pages/1");
	assert.equal(observed.init.method, "GET");
	assert.equal(observed.init.headers.Authorization, `Basic ${Buffer.from("person@example.com:secret").toString("base64")}`);
	assert.equal(observed.init.redirect, "manual");
});

test("sends JSON body files for explicitly allowed mutations", async (t) => {
	const dir = mkdtempSync(path.join(tmpdir(), "atlassian-request-"));
	t.after(() => rmSync(dir, { recursive: true, force: true }));
	const bodyFile = path.join(dir, "body.json");
	writeFileSync(bodyFile, '{"value": 1}\n');
	let observed;
	const options = parseArgs(["POST", "/wiki/api/v2/pages", "--body", bodyFile, "--allow-mutation"]);
	const result = await runRequest(options, { baseUrl: "https://site.example/", email: "person@example.com" }, "secret", async (_url, init) => {
		observed = init;
		return response({ created: true }, 201);
	});
	assert.deepEqual(result, { created: true });
	assert.equal(observed.body, '{"value":1}');
	assert.equal(observed.headers["Content-Type"], "application/json");
});

test("follows linked pagination and returns complete response pages", async () => {
	const seen = [];
	const result = await runRequest(
		parseArgs(["/wiki/api/v2/pages?limit=1", "--paginate"]),
		{ baseUrl: "https://site.example/", email: "person@example.com" },
		"secret",
		async (url) => {
			seen.push(url.href);
			return seen.length === 1
				? response({ results: [{ id: "1" }], _links: { next: "/wiki/api/v2/pages?limit=1&cursor=next" } })
				: response({ results: [{ id: "2" }], _links: {} });
		},
	);
	assert.equal(result.length, 2);
	assert.deepEqual(result.flatMap((page) => page.results), [{ id: "1" }, { id: "2" }]);
	assert.equal(seen[1], "https://site.example/wiki/api/v2/pages?limit=1&cursor=next");
});

test("recognizes numeric and token pagination", () => {
	assert.equal(nextPageUrl({ startAt: 0, maxResults: 50, total: 51 }, new URL("https://site.example/rest?startAt=0")).href, "https://site.example/rest?startAt=50");
	assert.equal(nextPageUrl({ nextPageToken: "abc", isLast: false }, new URL("https://site.example/rest")).href, "https://site.example/rest?nextPageToken=abc");
	assert.equal(nextPageUrl({ startAt: 50, maxResults: 50, total: 51 }, new URL("https://site.example/rest")), undefined);
});

test("fails instead of returning partial pagination", async () => {
	const options = parseArgs(["/wiki/api/v2/pages", "--paginate", "--max-pages", "1"]);
	await assert.rejects(
		runRequest(options, { baseUrl: "https://site.example/", email: "person@example.com" }, "secret", async () => response({ _links: { next: "/next" } })),
		/Pagination exceeded/,
	);
});

test("reports HTTP failures, rejects redirects, and preserves text responses", async () => {
	await assert.rejects(requestJson(new URL("https://site.example/x"), { method: "GET" }, async () => response("denied", 403, { "content-type": "text/plain" })), /HTTP 403\ndenied/);
	await assert.rejects(requestJson(new URL("https://site.example/x"), { method: "GET" }, async () => response("", 302)), /redirect 302 refused/);
	assert.equal(await requestJson(new URL("https://site.example/x"), { method: "GET" }, async () => response("plain", 200, { "content-type": "text/plain" })), "plain");
});