useKeycard_test.tsx
1 import { cleanup, render, renderHook, waitFor } from "@testing-library/react"; 2 import { expect } from "@std/expect"; 3 4 import { random256BigInt } from "@massmarket/utils"; 5 6 import { register, unregister } from "./happyDomSetup.ts"; 7 import { type KeycardRole, useKeycard } from "./useKeycard.ts"; 8 import { createShop, createWrapper } from "./_createWrapper.tsx"; 9 10 const denoTestOptions = { 11 sanitizeResources: false, 12 sanitizeOps: false, 13 }; 14 15 function testWrapper( 16 cb: (id: bigint, t: Deno.TestContext) => Promise<void> | void, 17 ) { 18 return async (_t: Deno.TestContext) => { 19 register(); 20 const shopId = random256BigInt(); 21 await createShop(shopId); 22 await cb(shopId, _t); 23 cleanup(); 24 await unregister(); 25 }; 26 } 27 28 Deno.test( 29 "Should enroll guest keycard", 30 denoTestOptions, 31 testWrapper(async (shopId, t) => { 32 await t.step("enroll merchant card", async () => { 33 const { result, unmount } = renderHook( 34 () => useKeycard({ role: "merchant" }), 35 { 36 wrapper: createWrapper(shopId), 37 }, 38 ); 39 await waitFor(() => { 40 expect(result.current.data?.role).toEqual("merchant"); 41 }); 42 unmount(); 43 }); 44 45 await t.step("enroll guest card", async () => { 46 const { result, unmount } = renderHook( 47 () => useKeycard({ role: "guest" }), 48 { 49 wrapper: createWrapper(shopId), 50 }, 51 ); 52 await waitFor(() => { 53 expect(result.current.data?.role).toEqual("guest"); 54 }); 55 unmount(); 56 }); 57 }), 58 ); 59 60 Deno.test( 61 "Hook should return error if keycard enrollment fails", 62 denoTestOptions, 63 testWrapper(async (shopId) => { 64 const wrapper = createWrapper(shopId); 65 // Enroll should fail since we didn't create a shop. 66 const { result } = renderHook(() => useKeycard(), { wrapper }); 67 await waitFor(() => { 68 expect(result.current.error).toBeDefined(); 69 expect(result.current.error).toBeInstanceOf(Error); 70 }); 71 }), 72 ); 73 74 Deno.test( 75 "Private keys should be the same when useKeycard is called concurrently.", 76 denoTestOptions, 77 testWrapper((shopId) => { 78 const wrapper = createWrapper(shopId); 79 const rendered = render(<TestComponent role="merchant" />, { wrapper }); 80 const component1Pk = rendered.getByTestId("component1-pk"); 81 const component2Pk = rendered.getByTestId("component2-pk"); 82 expect(component1Pk.textContent).toEqual(component2Pk.textContent); 83 }), 84 ); 85 86 const TestComponent = ({ role }: { role: KeycardRole }) => { 87 return ( 88 <div> 89 <ChildComponent /> 90 <ChildComponent2 role={role} /> 91 </div> 92 ); 93 }; 94 const ChildComponent = () => { 95 const { data } = useKeycard(); 96 return ( 97 <div> 98 <p data-testid="component1-pk">{data?.privateKey}</p> 99 <p data-testid="component1-role">{data?.role}</p> 100 </div> 101 ); 102 }; 103 const ChildComponent2 = ({ role }: { role: KeycardRole }) => { 104 const { data } = useKeycard({ role }); 105 return ( 106 <div> 107 <p data-testid="component2-pk">{data?.privateKey}</p> 108 <p data-testid="component2-role">{data?.role}</p> 109 </div> 110 ); 111 };