Initial Commit
This commit is contained in:
98
packages/identity/auth/macos-keychain/tests/otel.test.ts
Normal file
98
packages/identity/auth/macos-keychain/tests/otel.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import { type CommandExecutor, MacOSKeychainBridge } from "../src/index.js";
|
||||
|
||||
// The default @opentelemetry/api ships a NoopMeterProvider; we exercise the
|
||||
// meter API and assert no throw. The bridge instruments every CRUD call with
|
||||
// keychain.ops_total + keychain.cli_duration_ms (plus keychain.items_returned
|
||||
// on listItems). Asserting on counter values requires registering an SDK
|
||||
// MeterProvider, which is out-of-scope for the package's runtime — the
|
||||
// instrumentation contract here is "we always call the meter API in the right
|
||||
// shape". A future @suaveplan/opentelemetry-test-harness fixture will assert
|
||||
// recorded values without changing this test.
|
||||
|
||||
describe("OTel instrumentation", () => {
|
||||
it("addItem records on the ops counter without throwing", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const stub: CommandExecutor = async () => ({
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
});
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
await expect(
|
||||
bridge.addItem({ service: "svc", account: "user", password: "p" })
|
||||
).resolves.toEqual({ success: true });
|
||||
});
|
||||
|
||||
it("findItem records on the ops counter without throwing", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const stub: CommandExecutor = async () => ({
|
||||
stdout: "",
|
||||
stderr: 'password: "p"',
|
||||
exitCode: 0,
|
||||
});
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
await expect(bridge.findItem("svc", "user")).resolves.toMatchObject({
|
||||
password: "p",
|
||||
});
|
||||
});
|
||||
|
||||
it("updateItem records the delete + add invocations", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
let n = 0;
|
||||
const stub: CommandExecutor = async () => {
|
||||
n += 1;
|
||||
return { stdout: "", stderr: "", exitCode: 0 };
|
||||
};
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
await bridge.updateItem("svc", "user", "newp");
|
||||
expect(n).toBe(2);
|
||||
});
|
||||
|
||||
it("deleteItem records on the ops counter without throwing", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const stub: CommandExecutor = async () => ({
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
});
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
await expect(bridge.deleteItem("svc", "user")).resolves.toEqual({
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("listItems records the items_returned histogram", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const dump = `keychain: "/x"
|
||||
"svce"<blob>="svc"
|
||||
"acct"<blob>="alice"`;
|
||||
const stub: CommandExecutor = async () => ({
|
||||
stdout: dump,
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
});
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
const entries = await bridge.listItems();
|
||||
expect(entries).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("records on the ops counter even when the call fails", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const stub: CommandExecutor = async () => ({
|
||||
stdout: "",
|
||||
stderr: "could not be found",
|
||||
exitCode: 44,
|
||||
});
|
||||
const bridge = new MacOSKeychainBridge({}, stub);
|
||||
await expect(bridge.findItem("svc", "user")).rejects.toMatchObject({
|
||||
code: "KEYCHAIN.NOT_FOUND",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user