UNPKG

@reown/appkit-scaffold-ui

Version:

The full stack toolkit to build onchain app UX.

221 lines • 8.48 kB
import { expect as expectChai, fixture, html } from '@open-wc/testing'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { ChainController, RouterController, SwapController } from '@reown/appkit-controllers'; import { W3mSwapPreviewView } from '../../src/views/w3m-swap-preview-view/index.js'; const mockToken = { address: 'eip155:1:0x123', symbol: 'TEST', name: 'Test Token', quantity: { numeric: '100', decimals: '18' }, decimals: 18, logoUri: 'https://example.com/icon.png', price: 10, value: 1000 }; const mockChainState = { activeChain: 'eip155', activeCaipNetwork: { id: 1, name: 'Ethereum', chainNamespace: 'eip155', caipNetworkId: 'eip155:1', nativeCurrency: { name: 'Ethereum', symbol: 'ETH', decimals: 18 }, rpcUrls: { default: { http: ['https://ethereum.rpc.com'] } } }, activeCaipAddress: 'eip155:1:0x123456789abcdef123456789abcdef123456789a', chains: new Map(), universalAdapter: { connectionControllerClient: { connectWalletConnect: vi.fn(), connectExternal: vi.fn(), reconnectExternal: vi.fn(), checkInstalled: vi.fn(), disconnect: vi.fn(), disconnectConnector: vi.fn(), signMessage: vi.fn(), sendTransaction: vi.fn(), estimateGas: vi.fn(), parseUnits: vi.fn(), formatUnits: vi.fn(), writeContract: vi.fn(), writeSolanaTransaction: vi.fn(), getEnsAddress: vi.fn(), getEnsAvatar: vi.fn(), grantPermissions: vi.fn(), revokePermissions: vi.fn(), getCapabilities: vi.fn(), walletGetAssets: vi.fn(), updateBalance: vi.fn() } }, noAdapters: false, isSwitchingNamespace: false }; const mockSwapState = { initializing: false, initialized: true, loadingQuote: false, loadingPrices: false, loadingTransaction: false, loadingApprovalTransaction: false, loadingBuildTransaction: false, fetchError: false, switchingTokens: false, approvalTransaction: undefined, swapTransaction: { data: '0x123', to: '0x456', gas: BigInt(21000), gasPrice: BigInt(1000000000), value: BigInt(0), toAmount: '10' }, transactionError: undefined, sourceToken: mockToken, sourceTokenAmount: '1', sourceTokenPriceInUSD: 10, toToken: { ...mockToken, symbol: 'USDT' }, toTokenAmount: '10', toTokenPriceInUSD: 1, networkPrice: '0', networkBalanceInUSD: '0', networkTokenSymbol: '', inputError: undefined, slippage: 0.5, tokens: [mockToken], suggestedTokens: undefined, popularTokens: undefined, foundTokens: undefined, myTokensWithBalance: [mockToken], tokensPriceMap: {}, gasFee: '0', gasPriceInUSD: 2, priceImpact: undefined, maxSlippage: undefined, providerFee: undefined }; const mockAccountState = { balanceSymbol: 'ETH', address: '0x123', currentTab: 0, addressLabels: new Map() }; describe('W3mSwapPreviewView', () => { beforeEach(() => { class MockIntersectionObserver { constructor(callback) { this.callback = callback; this.root = null; this.rootMargin = '0px'; this.thresholds = [0]; } observe() { this.callback([ { isIntersecting: true, intersectionRatio: 1, boundingClientRect: {}, intersectionRect: {}, rootBounds: null, target: document.createElement('div'), time: Date.now() } ], this); } unobserve() { } disconnect() { } takeRecords() { return []; } } global.IntersectionObserver = MockIntersectionObserver; vi.spyOn(SwapController, 'state', 'get').mockReturnValue(mockSwapState); vi.spyOn(ChainController, 'state', 'get').mockReturnValue(mockChainState); vi.spyOn(ChainController, 'getAccountData').mockReturnValue(mockAccountState); vi.spyOn(SwapController, 'getTransaction').mockImplementation(async () => mockSwapState.swapTransaction); vi.spyOn(SwapController, 'sendTransactionForApproval').mockImplementation(async () => undefined); vi.spyOn(SwapController, 'sendTransactionForSwap').mockImplementation(async () => undefined); vi.spyOn(RouterController, 'goBack').mockImplementation(() => { }); }); afterEach(() => { vi.clearAllMocks(); }); it('should render initial state with token details', async () => { const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); await element.updateComplete; const tokenButtons = element.shadowRoot?.querySelectorAll('wui-token-button'); expectChai(tokenButtons?.length).to.equal(2); const sourceTokenButton = tokenButtons?.[0]; expectChai(sourceTokenButton?.getAttribute('text')).to.include('TEST'); expectChai(sourceTokenButton?.getAttribute('imageSrc')).to.equal(mockToken.logoUri); const toTokenButton = tokenButtons?.[1]; expectChai(toTokenButton?.getAttribute('text')).to.include('USDT'); }); it('should handle approval transaction', async () => { const approvalTransaction = { data: '0x789', to: '0xabc', gas: BigInt(21000), gasPrice: BigInt(1000000000), value: BigInt(0), toAmount: '10' }; vi.spyOn(SwapController, 'state', 'get').mockReturnValue({ ...mockSwapState, approvalTransaction }); const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); await element.updateComplete; const actionButton = element.shadowRoot?.querySelector('.action-button'); expectChai(actionButton?.textContent?.trim()).to.include('Approve'); await actionButton?.click(); await element.updateComplete; expect(SwapController.sendTransactionForApproval).toHaveBeenCalledWith(approvalTransaction); }); it('should handle swap transaction', async () => { const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); await element.updateComplete; const actionButton = element.shadowRoot?.querySelector('.action-button'); expectChai(actionButton?.textContent?.trim()).to.include('Swap'); await actionButton?.click(); await element.updateComplete; expect(SwapController.sendTransactionForSwap).toHaveBeenCalledWith(mockSwapState.swapTransaction); }); it('should handle cancel action', async () => { const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); await element.updateComplete; const cancelButton = element.shadowRoot?.querySelector('.cancel-button'); await cancelButton?.click(); await element.updateComplete; expect(RouterController.goBack).toHaveBeenCalled(); }); it('should show loading state', async () => { vi.spyOn(SwapController, 'state', 'get').mockReturnValue({ ...mockSwapState, loadingTransaction: true }); const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); await element.updateComplete; const actionButton = element.shadowRoot?.querySelector('.action-button'); expectChai(actionButton?.hasAttribute('loading')).to.be.true; expectChai(actionButton?.hasAttribute('disabled')).to.be.true; }); it('should cleanup interval on disconnect', async () => { const element = await fixture(html `<w3m-swap-preview-view></w3m-swap-preview-view>`); const clearIntervalSpy = vi.spyOn(window, 'clearInterval'); element.disconnectedCallback(); expect(clearIntervalSpy).toHaveBeenCalled(); }); }); //# sourceMappingURL=w3m-swap-preview-view.test.js.map