-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathuseWeb3Status.test.ts
More file actions
160 lines (139 loc) · 5.55 KB
/
Copy pathuseWeb3Status.test.ts
File metadata and controls
160 lines (139 loc) · 5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import { renderHook } from '@testing-library/react'
import { createElement } from 'react'
import type { Address } from 'viem'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { useWeb3StatusConnected } from '@/src/components/sharedComponents/WalletStatusVerifier'
import { useWeb3Status } from './useWeb3Status'
const mockDisconnect = vi.fn()
const mockSwitchChain = vi.fn()
vi.mock('wagmi', () => ({
useConnection: vi.fn(() => ({
address: undefined,
chainId: undefined,
isConnected: false,
isConnecting: false,
})),
useChainId: vi.fn(() => 1),
useSwitchChain: vi.fn(() => ({ isPending: false, mutate: mockSwitchChain })),
usePublicClient: vi.fn(() => undefined),
useWalletClient: vi.fn(() => ({ data: undefined })),
useBalance: vi.fn(() => ({ data: undefined })),
useDisconnect: vi.fn(() => ({ mutate: mockDisconnect })),
}))
vi.mock('@/src/hooks/useWalletStatus', () => ({
useWalletStatus: vi.fn(() => ({
isReady: false,
needsConnect: true,
needsChainSwitch: false,
targetChain: { id: 1, name: 'Ethereum' },
targetChainId: 1,
switchChain: vi.fn(),
})),
}))
vi.mock('@/src/providers/Web3Provider', () => ({
ConnectWalletButton: () =>
createElement('button', { type: 'button', 'data-testid': 'connect-wallet-button' }, 'Connect'),
}))
import * as wagmi from 'wagmi'
import { WalletStatusVerifier } from '@/src/components/sharedComponents/WalletStatusVerifier'
const { useWalletStatus } = await import('@/src/hooks/useWalletStatus')
const mockedUseWalletStatus = vi.mocked(useWalletStatus)
type MockAccount = ReturnType<typeof wagmi.useConnection>
type MockSwitchChain = ReturnType<typeof wagmi.useSwitchChain>
describe('useWeb3Status', () => {
beforeEach(() => {
mockDisconnect.mockClear()
mockSwitchChain.mockClear()
})
it('returns disconnected state when no wallet connected', () => {
const { result } = renderHook(() => useWeb3Status())
expect(result.current.isWalletConnected).toBe(false)
expect(result.current.address).toBeUndefined()
expect(result.current.walletChainId).toBeUndefined()
})
it('returns connected state with wallet address', () => {
const mock = {
address: '0xabc123' as Address,
chainId: 1,
isConnected: true,
isConnecting: false,
} as unknown as MockAccount
vi.mocked(wagmi.useConnection).mockReturnValueOnce(mock)
const { result } = renderHook(() => useWeb3Status())
expect(result.current.isWalletConnected).toBe(true)
expect(result.current.address).toBe('0xabc123')
})
it('sets isWalletSynced true when wallet chainId matches app chainId', () => {
const mock = {
address: '0xabc123' as Address,
chainId: 1,
isConnected: true,
isConnecting: false,
} as unknown as MockAccount
vi.mocked(wagmi.useConnection).mockReturnValueOnce(mock)
vi.mocked(wagmi.useChainId).mockReturnValueOnce(1)
const { result } = renderHook(() => useWeb3Status())
expect(result.current.isWalletSynced).toBe(true)
})
it('sets isWalletSynced false when wallet chainId differs from app chainId', () => {
const mock = {
address: '0xabc123' as Address,
chainId: 137,
isConnected: true,
isConnecting: false,
} as unknown as MockAccount
vi.mocked(wagmi.useConnection).mockReturnValueOnce(mock)
vi.mocked(wagmi.useChainId).mockReturnValueOnce(1)
const { result } = renderHook(() => useWeb3Status())
expect(result.current.isWalletSynced).toBe(false)
})
it('sets switchingChain when useSwitchChain is pending', () => {
const mock = { isPending: true, switchChain: mockSwitchChain } as unknown as MockSwitchChain
vi.mocked(wagmi.useSwitchChain).mockReturnValueOnce(mock)
const { result } = renderHook(() => useWeb3Status())
expect(result.current.switchingChain).toBe(true)
})
it('exposes disconnect function', () => {
const { result } = renderHook(() => useWeb3Status())
result.current.disconnect()
expect(mockDisconnect).toHaveBeenCalled()
})
it('calls switchChain with chainId when switchChain action is invoked', () => {
const { result } = renderHook(() => useWeb3Status())
result.current.switchChain(137)
expect(mockSwitchChain).toHaveBeenCalledWith({ chainId: 137 })
})
it('exposes appChainId from useChainId', () => {
vi.mocked(wagmi.useChainId).mockReturnValueOnce(42161)
const { result } = renderHook(() => useWeb3Status())
expect(result.current.appChainId).toBe(42161)
})
})
describe('useWeb3StatusConnected', () => {
it('throws when wallet is not connected', () => {
expect(() => renderHook(() => useWeb3StatusConnected())).toThrow(
'useWeb3StatusConnected must be used inside a <WalletStatusVerifier> component.',
)
})
it('returns status when wallet is connected', () => {
mockedUseWalletStatus.mockReturnValue({
isReady: true,
needsConnect: false,
needsChainSwitch: false,
targetChain: { id: 1, name: 'Ethereum' } as ReturnType<typeof useWalletStatus>['targetChain'],
targetChainId: 1,
switchChain: vi.fn(),
})
vi.mocked(wagmi.useConnection).mockReturnValueOnce({
address: '0xdeadbeef' as Address,
chainId: 1,
isConnected: true,
isConnecting: false,
} as unknown as ReturnType<typeof wagmi.useAccount>)
const wrapper = ({ children }: { children: React.ReactNode }) =>
createElement(WalletStatusVerifier, null, children)
const { result } = renderHook(() => useWeb3StatusConnected(), { wrapper })
expect(result.current.address).toBe('0xdeadbeef')
expect(result.current.isWalletConnected).toBe(true)
})
})