Skip to content

Commit

Permalink
test(react): wrap state updates in act() with async/await (#336)
Browse files Browse the repository at this point in the history
Fix React testing warnings by properly wrapping state updates and effects
in `act()` with `async`/`await`. This ensures all state updates and side
effects complete before making assertions.

- Make test functions async where needed
- Wrap renders and state updates in `act(async () => {...})`
- Add small delays where needed for effects to complete
- Fix `setActive` and `setActiveAccount` test implementation
- Simplify store state change test assertions
  • Loading branch information
drichar authored Jan 17, 2025
1 parent fe252c9 commit 6bcfc67
Showing 1 changed file with 48 additions and 62 deletions.
110 changes: 48 additions & 62 deletions packages/use-wallet-react/src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const mockMagicAuth = new MagicAuth({
})

describe('WalletProvider', () => {
it('provides the wallet context to its children', () => {
it('provides the wallet context to its children', async () => {
const TestComponent = () => {
const { wallets } = useWallet()
return <h1>{wallets ? 'Context provided' : 'No context'}</h1>
Expand All @@ -84,11 +84,13 @@ describe('WalletProvider', () => {
wallets: [WalletId.DEFLY]
})

render(
<WalletProvider manager={walletManager}>
<TestComponent />
</WalletProvider>
)
await act(async () => {
render(
<WalletProvider manager={walletManager}>
<TestComponent />
</WalletProvider>
)
})

expect(screen.getByText('Context provided')).toBeInTheDocument()
})
Expand Down Expand Up @@ -120,7 +122,7 @@ describe('WalletProvider', () => {
expect(mockResumeSessions).toHaveBeenCalled()
})

it('updates algodClient when setAlgodClient is called', () => {
it('updates algodClient when setAlgodClient is called', async () => {
const newAlgodClient = new algosdk.Algodv2('mock-token', 'https://mock-server', '')
const TestComponent = () => {
const { setAlgodClient } = useWallet()
Expand All @@ -134,11 +136,13 @@ describe('WalletProvider', () => {
wallets: [WalletId.DEFLY]
})

render(
<WalletProvider manager={walletManager}>
<TestComponent />
</WalletProvider>
)
await act(async () => {
render(
<WalletProvider manager={walletManager}>
<TestComponent />
</WalletProvider>
)
})

expect(walletManager.algodClient).toBe(newAlgodClient)
})
Expand Down Expand Up @@ -220,9 +224,14 @@ describe('useWallet', () => {
)
})

it('initializes wallets and active wallet correctly', () => {
it('initializes wallets and active wallet correctly', async () => {
const { result } = renderHook(() => useWallet(), { wrapper })

await act(async () => {
// Wait for any initial effects to complete
await new Promise((resolve) => setTimeout(resolve, 0))
})

expect(result.current.wallets).toEqual(mockWallets)
expect(result.current.activeWallet).toBeNull()
expect(result.current.activeAccount).toBeNull()
Expand Down Expand Up @@ -254,17 +263,27 @@ describe('useWallet', () => {
expect(mocks.disconnect).toHaveBeenCalled()
})

it('calls setActive and setActiveAccount correctly', () => {
it('calls setActive and setActiveAccount correctly', async () => {
const { result } = renderHook(() => useWallet(), { wrapper })

// Simulate calling setActive and setActiveAccount
act(() => {
result.current.wallets[0].setActive()
result.current.wallets[0].setActiveAccount('some-address')
await act(async () => {
// Get the Defly wallet from wallets array
const deflyWallet = result.current.wallets.find((w) => w.id === WalletId.DEFLY)
if (!deflyWallet) throw new Error('Defly wallet not found')

deflyWallet.setActive()
})

expect(mocks.setActive).toHaveBeenCalled()
expect(mocks.setActiveAccount).toHaveBeenCalledWith('some-address')

await act(async () => {
const deflyWallet = result.current.wallets.find((w) => w.id === WalletId.DEFLY)
if (!deflyWallet) throw new Error('Defly wallet not found')

deflyWallet.setActiveAccount('test-address')
})

expect(mocks.setActiveAccount).toHaveBeenCalledWith('test-address')
})

it('calls signTransactions and transactionSigner correctly', async () => {
Expand Down Expand Up @@ -302,57 +321,24 @@ describe('useWallet', () => {
expect(mocks.transactionSigner).toHaveBeenCalledWith([], [])
})

it('updates wallets when store state changes', () => {
it('updates wallets when store state changes', async () => {
const { result } = renderHook(() => useWallet(), { wrapper })

// Mock a state change in the store
act(() => {
await act(async () => {
mockStore.setState((state) => ({
...state,
wallets: {
[WalletId.DEFLY]: {
accounts: [
{
name: 'Defly Account 1',
address: 'address1'
},
{
name: 'Defly Account 2',
address: 'address2'
}
],
activeAccount: {
name: 'Defly Account 1',
address: 'address1'
}
accounts: [{ name: 'Account 1', address: 'address1' }],
activeAccount: { name: 'Account 1', address: 'address1' }
}
},
activeWallet: WalletId.DEFLY
}))
})

expect(result.current.wallets).toEqual([
{
...mockWallets[0],
accounts: [
{
name: 'Defly Account 1',
address: 'address1'
},
{
name: 'Defly Account 2',
address: 'address2'
}
],
activeAccount: {
name: 'Defly Account 1',
address: 'address1'
},
isConnected: true,
isActive: true
},
mockWallets[1]
])
expect(result.current.activeWallet?.id).toBe(WalletId.DEFLY)
expect(result.current.activeAddress).toBe('address1')
})

it('integrates correctly with a React component', () => {
Expand Down Expand Up @@ -454,11 +440,11 @@ describe('useWallet', () => {
expect(getByTestId('active-address')).toHaveTextContent(JSON.stringify('address1'))
})

it('calls setAlgodClient correctly', () => {
it('calls setAlgodClient correctly', async () => {
const newAlgodClient = new algosdk.Algodv2('mock-token', 'https://mock-server', '')
const { result } = renderHook(() => useWallet(), { wrapper })

act(() => {
await act(async () => {
result.current.setAlgodClient(newAlgodClient)
})

Expand Down Expand Up @@ -495,13 +481,13 @@ describe('useWallet', () => {
expect(result.current.isReady).toBe(true)
})

it('updates isReady when manager status changes', () => {
it('updates isReady when manager status changes', async () => {
const { result } = renderHook(() => useWallet(), { wrapper })

expect(result.current.isReady).toBe(false)

// Simulate manager status change
act(() => {
await act(async () => {
mockStore.setState((state) => ({
...state,
managerStatus: 'ready'
Expand Down

0 comments on commit 6bcfc67

Please sign in to comment.