UNPKG

@gemini-wallet/core

Version:

Core SDK for Gemini Wallet integration with popup communication

162 lines (134 loc) 5.39 kB
import { describe, expect, test, mock } from "bun:test"; import { GeminiWalletProvider } from "./provider"; import { GeminiStorage } from "@/storage"; import type { GeminiProviderConfig } from "@/types"; describe("GeminiProviderConfig", () => { const createMockConfig = (overrides: Partial<GeminiProviderConfig> = {}): GeminiProviderConfig => ({ appMetadata: { name: "Test App", description: "Test Description", url: "https://test.com", icons: [] }, chain: { id: 1 }, storage: new GeminiStorage(), ...overrides }); test("should preserve user's onDisconnectCallback and call provider cleanup", async () => { const userDisconnectCallback = mock(); let providerDisconnectCalled = false; const provider = new GeminiWalletProvider(createMockConfig({ onDisconnectCallback: userDisconnectCallback })); // Mock the provider disconnect to track if it's called const originalDisconnect = provider.disconnect; provider.disconnect = async () => { providerDisconnectCalled = true; return originalDisconnect.call(provider); }; // Simulate disconnect through the wallet's callback mechanism // @ts-ignore - accessing private property for testing if (provider.wallet?.communicator) { // @ts-ignore - accessing private property for testing provider.wallet.communicator.onDisconnectCallback?.(); } expect(userDisconnectCallback).toHaveBeenCalledTimes(1); expect(providerDisconnectCalled).toBe(true); }); test("should handle missing user onDisconnectCallback gracefully", async () => { let providerDisconnectCalled = false; const provider = new GeminiWalletProvider(createMockConfig({ // No onDisconnectCallback provided })); // Mock the provider disconnect to track if it's called const originalDisconnect = provider.disconnect; provider.disconnect = async () => { providerDisconnectCalled = true; return originalDisconnect.call(provider); }; // Simulate disconnect through the wallet's callback mechanism // @ts-ignore - accessing private property for testing if (provider.wallet?.communicator) { // @ts-ignore - accessing private property for testing provider.wallet.communicator.onDisconnectCallback?.(); } expect(providerDisconnectCalled).toBe(true); }); test("should store complete config internally", () => { const config = createMockConfig({ appMetadata: { name: "Custom App", description: "Custom Description", url: "https://custom.com", icons: ["icon1.png", "icon2.png"] }, chain: { id: 42161, rpcUrl: "https://custom-rpc.example.com" } }); const provider = new GeminiWalletProvider(config); expect(provider).toBeDefined(); // @ts-ignore - accessing private property for testing expect(provider.config).toEqual(config); }); test("should pass config correctly to wallet constructor", () => { const customStorage = new GeminiStorage(); const config = createMockConfig({ chain: { id: 137, // Polygon rpcUrl: "https://polygon-rpc.example.com" }, storage: customStorage }); const provider = new GeminiWalletProvider(config); expect(provider).toBeDefined(); // @ts-ignore - accessing private property for testing expect(provider.wallet?.storage).toBe(customStorage); }); test("should handle wallet recreation with preserved user callback", async () => { const userDisconnectCallback = mock(); let providerDisconnectCallCount = 0; const provider = new GeminiWalletProvider(createMockConfig({ onDisconnectCallback: userDisconnectCallback })); // Mock the provider disconnect to count calls const originalDisconnect = provider.disconnect; provider.disconnect = async () => { providerDisconnectCallCount++; return originalDisconnect.call(provider); }; // Set wallet to undefined to trigger recreation // @ts-ignore - accessing private property for testing provider.wallet = undefined; // Simulate eth_requestAccounts which recreates wallet try { await provider.request({ method: "eth_requestAccounts" }); } catch (error) { // Expected to fail in test environment, but wallet should be recreated } // Verify wallet was recreated // @ts-ignore - accessing private property for testing expect(provider.wallet).toBeDefined(); // Test that the recreated wallet still has the user callback // @ts-ignore - accessing private property for testing if (provider.wallet?.communicator) { // @ts-ignore - accessing private property for testing provider.wallet.communicator.onDisconnectCallback?.(); } expect(userDisconnectCallback).toHaveBeenCalled(); expect(providerDisconnectCallCount).toBeGreaterThan(0); }); test("should support custom chain configuration", () => { const customChain = { id: 8453, // Base rpcUrl: "https://base-mainnet.example.com" }; const provider = new GeminiWalletProvider(createMockConfig({ chain: customChain })); expect(provider).toBeDefined(); // @ts-ignore - accessing private property for testing expect(provider.config.chain).toEqual(customChain); }); });