78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
// @integration — Darwin only. Skipped in CI; excluded from coverage.
|
|
import { afterEach, describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { MacOSKeychainBridge } from "../src/index.js";
|
|
|
|
const isDarwin = process.platform === "darwin";
|
|
// Test files exempt from §13 banned-pattern .skip rule because the platform
|
|
// guard is the documented way to skip Darwin-only integration in CI.
|
|
const itDarwin = isDarwin ? it : it.skip;
|
|
|
|
describe("MacOSKeychainBridge integration (real /usr/bin/security)", () => {
|
|
const SERVICE = "@suaveplan/macos-keychain.integration-test";
|
|
const ACCOUNT = "vitest-runner";
|
|
const bridge = new MacOSKeychainBridge();
|
|
|
|
afterEach(async () => {
|
|
if (!isDarwin) return;
|
|
try {
|
|
await bridge.deleteItem(SERVICE, ACCOUNT);
|
|
} catch {
|
|
// tolerate already-clean state
|
|
}
|
|
});
|
|
|
|
itDarwin("adds and finds an item", { timeout: 30_000 }, async () => {
|
|
await bridge.addItem({
|
|
service: SERVICE,
|
|
account: ACCOUNT,
|
|
password: "real-secret",
|
|
});
|
|
const item = await bridge.findItem(SERVICE, ACCOUNT);
|
|
expect(item.password).toBe("real-secret");
|
|
});
|
|
|
|
itDarwin(
|
|
"itemExists returns true after add and false after delete",
|
|
{
|
|
timeout: 30_000,
|
|
},
|
|
async () => {
|
|
await bridge.addItem({
|
|
service: SERVICE,
|
|
account: ACCOUNT,
|
|
password: "x",
|
|
});
|
|
expect(await bridge.itemExists(SERVICE, ACCOUNT)).toBe(true);
|
|
await bridge.deleteItem(SERVICE, ACCOUNT);
|
|
expect(await bridge.itemExists(SERVICE, ACCOUNT)).toBe(false);
|
|
}
|
|
);
|
|
|
|
itDarwin("updates the stored password", { timeout: 30_000 }, async () => {
|
|
await bridge.addItem({
|
|
service: SERVICE,
|
|
account: ACCOUNT,
|
|
password: "v1",
|
|
});
|
|
await bridge.updateItem(SERVICE, ACCOUNT, "v2");
|
|
const item = await bridge.findItem(SERVICE, ACCOUNT);
|
|
expect(item.password).toBe("v2");
|
|
});
|
|
|
|
itDarwin(
|
|
"listItems surfaces the added item",
|
|
{
|
|
timeout: 30_000,
|
|
},
|
|
async () => {
|
|
await bridge.addItem({
|
|
service: SERVICE,
|
|
account: ACCOUNT,
|
|
password: "list-me",
|
|
});
|
|
const entries = await bridge.listItems(SERVICE);
|
|
expect(entries.some((e) => e.account === ACCOUNT)).toBe(true);
|
|
}
|
|
);
|
|
});
|