import { describe, expect, it } from "@effect/vitest"; import { Effect, Redacted } from "effect"; // oxlint-disable-next-line executor/no-vitest-import -- boundary: vi.mock/vi.hoisted must come from vitest itself for mock hoisting to resolve import { vi } from "vitest"; import { ProviderItemId } from "@executor-js/sdk"; const keyring = vi.hoisted(() => { // The bytes the OS keychain would have received. Asserting on these instead // of on a `get` round-trip is what catches a `set` that stored the wrong // thing but reads back consistently. const stored = new Map(); const key = (serviceName: string, account: string) => `${serviceName} ${account}`; return { stored, key, getPassword: vi.fn((serviceName: string, account: string) => Effect.succeed(stored.get(key(serviceName, account)) ?? null), ), setPassword: vi.fn((serviceName: string, account: string, value: string) => Effect.sync(() => { stored.set(key(serviceName, account), value); }), ), deletePassword: vi.fn((serviceName: string, account: string) => Effect.sync(() => stored.delete(key(serviceName, account))), ), }; }); vi.mock("./keyring", () => ({ getPassword: keyring.getPassword, setPassword: keyring.setPassword, deletePassword: keyring.deletePassword, })); const { makeKeychainProvider } = await import("./provider"); const SERVICE = "executor-test-provider"; describe("keychain credential provider", () => { // A `set` that forgot to unwrap would hand the keychain the literal // "" — `Redacted`'s toString renders that rather than throwing — and // a `get` round-trip would still look self-consistent. it.effect("writes the real secret to the keychain for both string and Redacted input", () => Effect.gen(function* () { keyring.stored.clear(); const provider = makeKeychainProvider(SERVICE); yield* provider.set!(ProviderItemId.make("plain"), "sk_plain_written"); yield* provider.set!(ProviderItemId.make("wrapped"), Redacted.make("sk_wrapped_written")); expect(keyring.stored.get(keyring.key(SERVICE, "plain"))).toBe("sk_plain_written"); expect(keyring.stored.get(keyring.key(SERVICE, "wrapped"))).toBe("sk_wrapped_written"); expect([...keyring.stored.values()]).not.toContain(""); }), ); it.effect("returns stored values as Redacted and absence as null", () => Effect.gen(function* () { keyring.stored.clear(); const provider = makeKeychainProvider(SERVICE); yield* provider.set!(ProviderItemId.make("token"), "sk_round_trip"); const found = yield* provider.get(ProviderItemId.make("token")); expect(found).not.toBeNull(); expect(Redacted.isRedacted(found)).toBe(true); expect(found === null ? null : Redacted.value(found)).toBe("sk_round_trip"); expect(yield* provider.get(ProviderItemId.make("absent"))).toBeNull(); expect(yield* provider.has!(ProviderItemId.make("token"))).toBe(true); expect(yield* provider.has!(ProviderItemId.make("absent"))).toBe(false); }), ); // An empty secret is a value, not an absence. it.effect("round-trips an empty value as present", () => Effect.gen(function* () { keyring.stored.clear(); const provider = makeKeychainProvider(SERVICE); yield* provider.set!(ProviderItemId.make("empty"), Redacted.make("")); expect(keyring.stored.get(keyring.key(SERVICE, "empty"))).toBe(""); const found = yield* provider.get(ProviderItemId.make("empty")); expect(found).not.toBeNull(); expect(found === null ? null : Redacted.value(found)).toBe(""); }), ); });