1import { createPasskeys } from "@clerk/electron/passkeys";
2import { afterEach, describe, expect, it, vi } from "vite-plus/test";
3
4const publicKeyOptions = {
5 allowCredentials: [],
6 challenge: new Uint8Array([1]),
7 rpId: "clerk.t3.codes",
8 timeout: 60_000,
9 userVerification: "preferred" as const,
10};
11
12const stubNativePasskeys = () => {
13 const get = vi.fn().mockResolvedValue({
14 ok: false,
15 error: { code: "cancelled", message: "user cancelled" },
16 });
17
18 vi.stubGlobal("location", { protocol: "t3code:", hostname: "app" });
19 vi.stubGlobal("window", {
20 PublicKeyCredential: vi.fn(),
21 __clerk_internal_electron_passkeys: {
22 platform: "darwin",
23 electronMajor: 41,
24 get,
25 },
26 });
27
28 return get;
29};
30
31describe("Electron passkeys", () => {
32 afterEach(() => {
33 vi.unstubAllGlobals();
34 });
35
36 it("does not send an autofill request to the native bridge", async () => {
37 const get = stubNativePasskeys();
38 const passkeys = createPasskeys();
39
40 const result = await passkeys.get({
41 publicKeyOptions,
42 conditionalUI: true,
43 });
44
45 expect(get).not.toHaveBeenCalled();
46 expect(result.error).toMatchObject({ code: "passkey_operation_aborted" });
47 });
48
49 it("sends an explicit passkey request to the native bridge", async () => {
50 const get = stubNativePasskeys();
51 const passkeys = createPasskeys();
52
53 await passkeys.get({
54 publicKeyOptions,
55 conditionalUI: false,
56 });
57
58 expect(get).toHaveBeenCalledOnce();
59 });
60});