RelayClient_test.tsx
1 import "../happyDomSetup.ts"; 2 import { act, cleanup, render, screen, waitFor } from "@testing-library/react"; 3 import { expect } from "@std/expect"; 4 import { userEvent } from "@testing-library/user-event"; 5 import { discoverRelay, IRelayEndpoint } from "@massmarket/client"; 6 import { random256BigInt } from "@massmarket/utils"; 7 import { createClient, publicActions, walletActions, webSocket } from "viem"; 8 import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; 9 import { hardhat } from "viem/chains"; 10 import RelayClientTestPage from "./RelayClientTestPage.tsx"; 11 12 // Create a mock wallet client and account 13 const shopId = random256BigInt(); 14 const client = createClient({ 15 chain: hardhat, 16 transport: webSocket("ws://localhost:8545"), 17 }).extend(walletActions).extend(publicActions); 18 19 const pk = generatePrivateKey(); 20 const kc = privateKeyToAccount(pk); 21 22 Deno.test("RelayClientTester component connects to relay", { 23 sanitizeResources: false, 24 sanitizeOps: false, 25 }, async (t) => { 26 const relayEndpoint = await discoverRelay("ws://localhost:4444/v4"); 27 const user = userEvent.setup(); 28 29 await t.step("renders and connects to relay", async () => { 30 const { unmount } = render( 31 <RelayClientTestPage 32 relayEndpoint={relayEndpoint} 33 walletClient={client} 34 keycard={kc} 35 shopId={shopId} 36 />, 37 ); 38 39 // Check initial rendering 40 screen.getByTestId("relay-client-tester"); 41 42 // Wait for connection to be established 43 await waitFor(() => { 44 const status = screen.getByTestId("connection-status"); 45 expect(status.textContent).toContain("connected"); 46 const lastPingReceived = screen.getByTestId("stats-last-ping-received"); 47 expect(lastPingReceived.textContent).toContain("second"); 48 // make sure to align this timeout with PING_INTERVAL. Otherwise, the test will fail. 49 }, { timeout: 10000 }); 50 51 // Test disconnect functionality 52 await act(async () => { 53 const disconnectButton = screen.getByTestId("disconnect-button"); 54 await user.click(disconnectButton); 55 }); 56 57 // Verify disconnection 58 await waitFor(() => { 59 const status = screen.getByTestId("connection-status"); 60 expect(status.textContent).toContain("disconnected"); 61 }); 62 63 unmount(); 64 cleanup(); 65 }); 66 67 await t.step("handles connection errors", async () => { 68 const relayEndpoint: IRelayEndpoint = { 69 url: new URL("ws://localhost:57192/v99999"), 70 tokenId: 71 "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", 72 }; 73 const { unmount } = render( 74 <RelayClientTestPage 75 relayEndpoint={relayEndpoint} 76 walletClient={client} 77 keycard={kc} 78 shopId={shopId} 79 />, 80 ); 81 82 // Check that error is displayed 83 await waitFor(() => { 84 const error = screen.getByTestId("connection-error"); 85 expect(error.textContent).toContain( 86 "NetworkError: failed to connect to WebSocket", 87 ); 88 const lastPingReceived = screen.getByTestId("stats-last-ping-received"); 89 expect(lastPingReceived.textContent).toContain("Never"); 90 }); 91 92 unmount(); 93 cleanup(); 94 }); 95 });