@reown/appkit-scaffold-ui
Version:
The full stack toolkit to build onchain app UX.
240 lines • 11.9 kB
JavaScript
import { fixture } from '@open-wc/testing';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { html } from 'lit';
import { ApiController, ChainController, ConnectorController, RouterController, StorageUtil } from '@reown/appkit-controllers';
import { W3mConnectRecentWidget } from '../../src/partials/w3m-connect-recent-widget';
describe('W3mConnectRecentWidget', () => {
const mockRecentWallets = [
{ id: 'recent1', name: 'Recent Wallet 1', chains: ['eip155:1'] },
{ id: 'recent2', name: 'Recent Wallet 2', chains: ['eip155:1'] }
];
const mockConnectors = [
{ id: 'connector1', name: 'Connector 1' },
{ id: 'recent1', name: 'Recent Wallet 1' }
];
let subscribeCallback;
beforeEach(() => {
subscribeCallback = vi.fn();
vi.clearAllMocks();
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(mockRecentWallets);
vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: mockConnectors
});
vi.spyOn(ConnectorController, 'subscribeKey').mockImplementation((_, callback) => {
subscribeCallback = callback;
return () => undefined;
});
});
afterEach(() => {
vi.clearAllMocks();
});
it('should render filtered recent wallets when there are matching connectors', async () => {
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(1);
const walletName = walletElements?.[0]?.getAttribute('name');
expect(walletName).toBe('Recent Wallet 2');
});
it('should render all recent wallets when there are no matching connectors', async () => {
vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: [{ id: 'connector1', name: 'Connector 1' }]
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Recent Wallet 1');
expect(walletNames).toContain('Recent Wallet 2');
});
it('should not render widget when there are no recent wallets', async () => {
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue([]);
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
expect(element.style.display).toBe('none');
expect(element.shadowRoot?.querySelector('wui-flex')).toBeNull();
});
it('should handle wallet click and navigate to connecting view', async () => {
const routerSpy = vi.spyOn(RouterController, 'push');
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElement = element.shadowRoot?.querySelector('wui-list-wallet');
walletElement?.click();
expect(routerSpy).toHaveBeenCalledWith('ConnectingWalletConnect', {
wallet: mockRecentWallets[1]
});
});
it('should respect tabIdx property', async () => {
const element = await fixture(html `<w3m-connect-recent-widget .tabIdx=${2}></w3m-connect-recent-widget>`);
const walletElement = element.shadowRoot?.querySelector('wui-list-wallet');
expect(walletElement?.getAttribute('tabIdx')).toBe('2');
});
it('should update when connectors change', async () => {
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
expect(element.shadowRoot?.querySelectorAll('wui-list-wallet').length).toBe(1);
vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: [{ id: 'connector1', name: 'Connector 1' }]
});
subscribeCallback([{ id: 'connector1', name: 'Connector 1' }]);
await element.updateComplete;
expect(element.shadowRoot?.querySelectorAll('wui-list-wallet').length).toBe(2);
});
it('should filter wallets by EIP-155 chain namespace', async () => {
const eip155Wallets = [
{
id: 'eth1',
name: 'Ethereum Wallet',
chains: ['eip155:1', 'eip155:137']
},
{ id: 'eth2', name: 'Polygon Wallet', chains: ['eip155:137'] }
];
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(eip155Wallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Ethereum Wallet');
expect(walletNames).toContain('Polygon Wallet');
});
it('should filter wallets by Solana chain namespace', async () => {
const solanaWallets = [
{
id: 'sol1',
name: 'Solana Wallet',
chains: ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']
},
{
id: 'sol2',
name: 'Solana Wallet 2',
chains: ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']
}
];
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(solanaWallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'solana'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Solana Wallet');
expect(walletNames).toContain('Solana Wallet 2');
});
it('should filter wallets by Bitcoin chain namespace', async () => {
const bitcoinWallets = [
{ id: 'btc1', name: 'Bitcoin Wallet', chains: ['bip122:0'] },
{ id: 'btc2', name: 'Bitcoin Wallet 2', chains: ['bip122:0'] }
];
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(bitcoinWallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'bip122'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Bitcoin Wallet');
expect(walletNames).toContain('Bitcoin Wallet 2');
});
it('should only show wallets matching the active chain namespace', async () => {
const mixedWallets = [
{ id: 'eth1', name: 'Ethereum Wallet', chains: ['eip155:1'] },
{
id: 'sol1',
name: 'Solana Wallet',
chains: ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']
},
{ id: 'btc1', name: 'Bitcoin Wallet', chains: ['bip122:0'] }
];
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(mixedWallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'solana'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(1);
const walletName = walletElements?.[0]?.getAttribute('name');
expect(walletName).toBe('Solana Wallet');
});
it('should filter out excluded wallets by rdns', async () => {
const recentWallets = [
{
id: 'excluded1',
name: 'Excluded Wallet 1',
rdns: 'io.excluded.wallet1',
chains: ['eip155:1']
},
{
id: 'included1',
name: 'Included Wallet 1',
rdns: 'io.included.wallet1',
chains: ['eip155:1']
},
{
id: 'included2',
name: 'Included Wallet 2',
rdns: 'io.included.wallet2',
chains: ['eip155:1']
}
];
const excludedWallets = [{ rdns: 'io.excluded.wallet1', name: 'Excluded Wallet 1' }];
vi.spyOn(ApiController.state, 'excludedWallets', 'get').mockReturnValue(excludedWallets);
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(recentWallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Included Wallet 1');
expect(walletNames).toContain('Included Wallet 2');
expect(walletNames).not.toContain('Excluded Wallet 1');
});
it('should filter out wallets excluded by name', async () => {
const recentWallets = [
{
id: 'excluded1',
name: 'Excluded Wallet 1',
rdns: 'io.wallet1',
chains: ['eip155:1']
},
{
id: 'excluded2',
name: 'Excluded Wallet 2',
rdns: 'io.wallet2',
chains: ['eip155:1']
},
{
id: 'included1',
name: 'Included Wallet 1',
rdns: 'io.wallet3',
chains: ['eip155:1']
}
];
const excludedWallets = [{ rdns: '', name: 'Excluded Wallet 2' }];
vi.spyOn(ApiController.state, 'excludedWallets', 'get').mockReturnValue(excludedWallets);
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(recentWallets);
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const element = await fixture(html `<w3m-connect-recent-widget></w3m-connect-recent-widget>`);
const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet');
expect(walletElements?.length).toBe(2);
const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'));
expect(walletNames).toContain('Excluded Wallet 1');
expect(walletNames).toContain('Included Wallet 1');
expect(walletNames).not.toContain('Excluded Wallet 2');
});
});
//# sourceMappingURL=w3m-connect-recent-widget.test.js.map