Skip to content

Commit a271f4a

Browse files
committed
test: add test coverage on autoConnectCore
1 parent 41d42ca commit a271f4a

File tree

2 files changed

+140
-20
lines changed

2 files changed

+140
-20
lines changed

packages/thirdweb/src/wallets/connection/autoConnectCore.test.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1+
import { beforeEach } from "node:test";
12
import { isAddress } from "ethers6";
23
import { describe, expect, it, vi } from "vitest";
34
import { MockStorage } from "~test/mocks/storage.js";
45
import { TEST_CLIENT } from "~test/test-clients.js";
56
import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
67
import { createWalletAdapter } from "../../adapters/wallet-adapter.js";
78
import { ethereum } from "../../chains/chain-definitions/ethereum.js";
9+
import { AUTH_TOKEN_LOCAL_STORAGE_NAME } from "../in-app/core/constants/settings.js";
10+
import { getUrlToken } from "../in-app/web/lib/get-url-token.js";
811
import { createConnectionManager } from "../manager/index.js";
912
import type { WalletId } from "../wallet-types.js";
1013
import { autoConnectCore, handleWalletConnection } from "./autoConnectCore.js";
1114

15+
vi.mock("../in-app/web/lib/get-url-token.ts");
16+
1217
describe("useAutoConnectCore", () => {
1318
const mockStorage = new MockStorage();
1419
const manager = createConnectionManager(mockStorage);
1520

21+
beforeEach(() => {
22+
vi.resetAllMocks();
23+
});
24+
1625
it("should return a useQuery result", async () => {
26+
vi.mocked(getUrlToken).mockReturnValue({});
1727
const wallet = createWalletAdapter({
1828
adaptedAccount: TEST_ACCOUNT_A,
1929
client: TEST_CLIENT,
@@ -45,6 +55,8 @@ describe("useAutoConnectCore", () => {
4555
});
4656

4757
it("should return `false` if there's no lastConnectedWalletIds", async () => {
58+
vi.mocked(getUrlToken).mockReturnValue({});
59+
4860
const wallet = createWalletAdapter({
4961
adaptedAccount: TEST_ACCOUNT_A,
5062
client: TEST_CLIENT,
@@ -76,6 +88,8 @@ describe("useAutoConnectCore", () => {
7688
});
7789

7890
it("should call onTimeout on ... timeout", async () => {
91+
vi.mocked(getUrlToken).mockReturnValue({});
92+
7993
const wallet = createWalletAdapter({
8094
adaptedAccount: TEST_ACCOUNT_A,
8195
client: TEST_CLIENT,
@@ -124,6 +138,113 @@ describe("useAutoConnectCore", () => {
124138
expect(infoSpy).toHaveBeenCalledWith("TIMEOUTTED");
125139
warnSpy.mockRestore();
126140
});
141+
142+
it("should handle auth cookie storage correctly", async () => {
143+
const mockAuthCookie = "mock-auth-cookie";
144+
const wallet = createWalletAdapter({
145+
adaptedAccount: TEST_ACCOUNT_A,
146+
client: TEST_CLIENT,
147+
chain: ethereum,
148+
onDisconnect: () => {},
149+
switchChain: () => {},
150+
});
151+
vi.mocked(getUrlToken).mockReturnValue({
152+
authCookie: mockAuthCookie,
153+
walletId: wallet.id,
154+
});
155+
156+
await autoConnectCore({
157+
storage: mockStorage,
158+
props: {
159+
wallets: [wallet],
160+
client: TEST_CLIENT,
161+
},
162+
createWalletFn: () => wallet,
163+
manager,
164+
});
165+
166+
const storedCookie = await mockStorage.getItem(
167+
AUTH_TOKEN_LOCAL_STORAGE_NAME(TEST_CLIENT.clientId),
168+
);
169+
expect(storedCookie).toBe(mockAuthCookie);
170+
});
171+
172+
it("should handle error when manager connection fails", async () => {
173+
const wallet1 = createWalletAdapter({
174+
adaptedAccount: TEST_ACCOUNT_A,
175+
client: TEST_CLIENT,
176+
chain: ethereum,
177+
onDisconnect: () => {},
178+
switchChain: () => {},
179+
});
180+
181+
mockStorage.setItem("thirdweb:active-wallet-id", wallet1.id);
182+
mockStorage.setItem(
183+
"thirdweb:connected-wallet-ids",
184+
JSON.stringify([wallet1.id]),
185+
);
186+
187+
const addConnectedWalletSpy = vi
188+
.spyOn(manager, "connect")
189+
.mockRejectedValue(new Error("Connection failed"));
190+
191+
await autoConnectCore({
192+
storage: mockStorage,
193+
props: {
194+
wallets: [wallet1],
195+
client: TEST_CLIENT,
196+
},
197+
createWalletFn: () => wallet1,
198+
manager,
199+
});
200+
expect(addConnectedWalletSpy).toHaveBeenCalled();
201+
});
202+
203+
it("should connect multiple wallets correctly", async () => {
204+
const wallet1 = createWalletAdapter({
205+
adaptedAccount: TEST_ACCOUNT_A,
206+
client: TEST_CLIENT,
207+
chain: ethereum,
208+
onDisconnect: () => {},
209+
switchChain: () => {},
210+
});
211+
212+
const wallet2 = createWalletAdapter({
213+
adaptedAccount: { ...TEST_ACCOUNT_A, address: "0x123" },
214+
client: TEST_CLIENT,
215+
chain: ethereum,
216+
onDisconnect: () => {},
217+
switchChain: () => {},
218+
});
219+
wallet2.id = "io.metamask" as unknown as "adapter";
220+
221+
mockStorage.setItem("thirdweb:active-wallet-id", wallet1.id);
222+
mockStorage.setItem(
223+
"thirdweb:connected-wallet-ids",
224+
JSON.stringify([wallet1.id, wallet2.id]),
225+
);
226+
227+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
228+
const addConnectedWalletSpy = vi.spyOn(manager, "addConnectedWallet");
229+
230+
await autoConnectCore({
231+
storage: mockStorage,
232+
props: {
233+
wallets: [wallet1, wallet2],
234+
client: TEST_CLIENT,
235+
},
236+
createWalletFn: () => wallet1,
237+
manager,
238+
});
239+
240+
expect(addConnectedWalletSpy).toHaveBeenCalledWith(wallet2);
241+
242+
expect(warnSpy).toHaveBeenCalled();
243+
expect(warnSpy).toHaveBeenCalledWith(
244+
"Error auto connecting wallet:",
245+
"Connection failed",
246+
);
247+
});
127248
});
128249

129250
describe("handleWalletConnection", () => {

packages/thirdweb/src/wallets/connection/autoConnectCore.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -100,26 +100,26 @@ export const autoConnectCore = async ({
100100
createWalletFn(lastActiveWalletId));
101101

102102
if (activeWallet) {
103-
try {
104-
manager.activeWalletConnectionStatusStore.setValue("connecting"); // only set connecting status if we are connecting the last active EOA
105-
await timeoutPromise(
106-
handleWalletConnection({
107-
wallet: activeWallet,
108-
client: props.client,
109-
lastConnectedChain,
110-
authResult,
111-
}),
112-
{
113-
ms: timeout,
114-
message: `AutoConnect timeout: ${timeout}ms limit exceeded.`,
115-
},
116-
).catch((err) => {
117-
console.warn(err.message);
118-
if (props.onTimeout) {
119-
props.onTimeout();
120-
}
121-
});
103+
manager.activeWalletConnectionStatusStore.setValue("connecting"); // only set connecting status if we are connecting the last active EOA
104+
await timeoutPromise(
105+
handleWalletConnection({
106+
wallet: activeWallet,
107+
client: props.client,
108+
lastConnectedChain,
109+
authResult,
110+
}),
111+
{
112+
ms: timeout,
113+
message: `AutoConnect timeout: ${timeout}ms limit exceeded.`,
114+
},
115+
).catch((err) => {
116+
console.warn(err.message);
117+
if (props.onTimeout) {
118+
props.onTimeout();
119+
}
120+
});
122121

122+
try {
123123
// connected wallet could be activeWallet or smart wallet
124124
const connectedWallet = await (connectOverride
125125
? connectOverride(activeWallet)
@@ -154,7 +154,6 @@ export const autoConnectCore = async ({
154154
const otherWallets = availableWallets.filter(
155155
(w) => w.id !== lastActiveWalletId && lastConnectedWalletIds.includes(w.id),
156156
);
157-
158157
for (const wallet of otherWallets) {
159158
try {
160159
await handleWalletConnection({

0 commit comments

Comments
 (0)