repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/intellij/__tests__/settings.test.ts
Rawimport { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { createTestSession, type TestSession } from "../../../test/harness";
import intellijExtension from "../index";
type Case = { user?: unknown; project?: unknown; untrusted?: boolean };
describe("intellij.url resolution", () => {
let t: TestSession | undefined;
let root: string | undefined;
afterEach(() => {
t?.dispose();
t = undefined;
if (root) rmSync(root, { recursive: true, force: true });
root = undefined;
});
async function run(input: Case, command: string) {
root = mkdtempSync(path.join(tmpdir(), "pi-ext-intellij-settings-"));
const write = (dir: string, value: unknown) => {
mkdirSync(dir, { recursive: true });
writeFileSync(
path.join(dir, "settings.json"),
JSON.stringify({ intellij: { url: value } }),
);
};
if ("user" in input)
write(path.join(root, ".test-home/.pi/agent"), input.user);
if ("project" in input) write(path.join(root, ".pi"), input.project);
t = await createTestSession({
cwd: root,
extensionFactories: [intellijExtension],
});
if (input.untrusted) t.session.settingsManager.setProjectTrusted(false);
const [extension] = t.session.extensionRunner.extensions;
await extension.commands
.get("intellij")
.handler(command, t.session.extensionRunner.createCommandContext());
return t.events.uiCallsFor("notify").at(-1)?.args;
}
it.each([
["none", {}, "none"],
["user", { user: "http://127.0.0.1:1/user" }, "http://127.0.0.1:1/user"],
[
"project over user",
{ user: "http://127.0.0.1:1/user", project: "http://127.0.0.1:1/proj" },
"http://127.0.0.1:1/proj",
],
[
"untrusted project ignored",
{
user: "http://127.0.0.1:1/user",
project: "http://127.0.0.1:1/proj",
untrusted: true,
},
"http://127.0.0.1:1/user",
],
] satisfies [string, Case, string][])(
"status shows %s",
async (_name, input, endpoint) => {
const [message, level] = (await run(input, "status")) ?? [];
expect(message).toContain(`endpoint: ${endpoint}\n`);
expect(level).toBe("info");
},
);
const invalid = [
["project", { user: "http://127.0.0.1:1/user", project: 1 }],
["user", { user: true }],
] satisfies [string, Case][];
it.each(invalid)(
"status rejects non-string %s value without falling through",
async (source, input) => {
expect(await run(input, "status")).toEqual([
expect.stringContaining(
`endpoint: unavailable (Invalid intellij.url from ${source} settings)`,
),
"warning",
]);
},
);
it.each(invalid)(
"connect rejects non-string %s value without falling through",
async (source, input) => {
expect(await run(input, "connect")).toEqual([
expect.stringMatching(
new RegExp(`^Invalid intellij\\.url from ${source} settings\\. `),
),
"warning",
]);
},
);
});