/ packages / react-hooks / useKeycard_test.tsx
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  };