11import React from 'react' ;
2- import { fireEvent , screen , waitFor } from '@testing-library/react' ;
2+ import { fireEvent , screen } from '@testing-library/react' ;
33import { renderWithProvider } from '../../../../test/jest' ;
44import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard' ;
55import { openBlockExplorer } from '../../multichain/menu-items/view-explorer-menu-item' ;
6+ import { getBlockExplorerInfo } from '../../../helpers/utils/multichain/getBlockExplorerInfo' ;
67import { AddressQRCodeModal } from './address-qr-code-modal' ;
78
8- // Mock copy to clipboard hook
9+ // Import the mocked function
10+
11+ // Mock only the essential dependencies that the component actually uses
912jest . mock ( '../../../hooks/useCopyToClipboard' , ( ) => ( {
1013 useCopyToClipboard : jest . fn ( ) ,
1114} ) ) ;
1215
13- // Mock the openBlockExplorer function
1416jest . mock (
1517 '../../../components/multichain/menu-items/view-explorer-menu-item' ,
1618 ( ) => ( {
1719 openBlockExplorer : jest . fn ( ) ,
1820 } ) ,
1921) ;
2022
23+ jest . mock ( '../../../helpers/utils/multichain/getBlockExplorerInfo' , ( ) => ( {
24+ getBlockExplorerInfo : jest . fn ( ) ,
25+ } ) ) ;
26+
2127const mockUseCopyToClipboard = useCopyToClipboard as jest . MockedFunction <
2228 typeof useCopyToClipboard
2329> ;
2430const mockOpenBlockExplorer = openBlockExplorer as jest . Mock ;
2531
32+ const mockGetBlockExplorerInfo = getBlockExplorerInfo as jest . Mock ;
33+
2634describe ( 'AddressQRCodeModal' , ( ) => {
2735 beforeEach ( ( ) => {
2836 jest . clearAllMocks ( ) ;
2937 mockUseCopyToClipboard . mockReturnValue ( [ false , jest . fn ( ) , jest . fn ( ) ] ) ;
38+
39+ // Set up default mock return values
40+ mockGetBlockExplorerInfo . mockReturnValue ( null ) ;
3041 } ) ;
3142
3243 it ( 'should render the modal when isOpen is true' , ( ) => {
@@ -37,6 +48,7 @@ describe('AddressQRCodeModal', () => {
3748 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
3849 accountName = "Test Account"
3950 networkName = "Ethereum"
51+ chainId = "eip155:1"
4052 networkImageSrc = "./images/eth_logo.svg"
4153 /> ,
4254 ) ;
@@ -58,6 +70,7 @@ describe('AddressQRCodeModal', () => {
5870 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
5971 accountName = "Test Account"
6072 networkName = "Ethereum"
73+ chainId = "eip155:1"
6174 networkImageSrc = "./images/eth_logo.svg"
6275 /> ,
6376 ) ;
@@ -75,28 +88,33 @@ describe('AddressQRCodeModal', () => {
7588 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
7689 accountName = "Test Account"
7790 networkName = "Ethereum"
91+ chainId = "eip155:1"
7892 networkImageSrc = "./images/eth_logo.svg"
7993 /> ,
8094 ) ;
8195
82- // The address is displayed in segments: start + middle + end (0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc)
83- // Start: first 6 chars, End: last 5 chars
84- expect ( screen . getByText ( '0x0dcd' ) ) . toBeInTheDocument ( ) ; // First 6 chars
85- expect (
86- screen . getByText ( '5d886577d5081b0c52e242ef29e70be' ) ,
87- ) . toBeInTheDocument ( ) ;
96+ // The address is displayed in segments, so we check for the last 5 characters
8897 expect ( screen . getByText ( '3e7bc' ) ) . toBeInTheDocument ( ) ; // Last 5 chars
8998 expect ( screen . getByText ( 'Copy address' ) ) . toBeInTheDocument ( ) ;
9099 } ) ;
91100
92101 it ( 'should render the view on explorer button for Ethereum' , ( ) => {
102+ // Mock the getBlockExplorerInfo to return Ethereum explorer info
103+ mockGetBlockExplorerInfo . mockReturnValue ( {
104+ addressUrl :
105+ 'https://etherscan.io/address/0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' ,
106+ name : 'Etherscan' ,
107+ buttonText : 'View on Etherscan' ,
108+ } ) ;
109+
93110 renderWithProvider (
94111 < AddressQRCodeModal
95112 isOpen = { true }
96113 onClose = { jest . fn ( ) }
97114 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
98115 accountName = "Test Account"
99116 networkName = "Ethereum"
117+ chainId = "eip155:1"
100118 networkImageSrc = "./images/eth_logo.svg"
101119 /> ,
102120 ) ;
@@ -115,22 +133,20 @@ describe('AddressQRCodeModal', () => {
115133 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
116134 accountName = "Test Account"
117135 networkName = "Ethereum"
136+ chainId = "eip155:1"
118137 networkImageSrc = "./images/eth_logo.svg"
119138 /> ,
120139 ) ;
121140
122141 const copyButton = screen . getByText ( 'Copy address' ) ;
123142 fireEvent . click ( copyButton ) ;
124143
125- await waitFor ( ( ) => {
126- expect ( mockHandleCopy ) . toHaveBeenCalledWith (
127- '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' ,
128- ) ;
129- } ) ;
144+ expect ( mockHandleCopy ) . toHaveBeenCalledTimes ( 1 ) ;
130145 } ) ;
131146
132- it ( 'should show copy success state when copy is successful' , ( ) => {
133- mockUseCopyToClipboard . mockReturnValue ( [ true , jest . fn ( ) , jest . fn ( ) ] ) ;
147+ it ( 'should show copy success state when copy is successful' , async ( ) => {
148+ const mockHandleCopy = jest . fn ( ) ;
149+ mockUseCopyToClipboard . mockReturnValue ( [ true , mockHandleCopy , jest . fn ( ) ] ) ;
134150
135151 renderWithProvider (
136152 < AddressQRCodeModal
@@ -139,6 +155,7 @@ describe('AddressQRCodeModal', () => {
139155 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
140156 accountName = "Test Account"
141157 networkName = "Ethereum"
158+ chainId = "eip155:1"
142159 networkImageSrc = "./images/eth_logo.svg"
143160 /> ,
144161 ) ;
@@ -151,13 +168,21 @@ describe('AddressQRCodeModal', () => {
151168 it ( 'should navigate to the correct URL for Ethereum explorer when button is clicked' , ( ) => {
152169 const address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' ;
153170
171+ // Mock the getBlockExplorerInfo to return Ethereum explorer info
172+ mockGetBlockExplorerInfo . mockReturnValue ( {
173+ addressUrl : `https://etherscan.io/address/${ address } ` ,
174+ name : 'Etherscan' ,
175+ buttonText : 'View on Etherscan' ,
176+ } ) ;
177+
154178 renderWithProvider (
155179 < AddressQRCodeModal
156180 isOpen = { true }
157181 onClose = { jest . fn ( ) }
158182 address = { address }
159183 accountName = "Test Account"
160184 networkName = "Ethereum"
185+ chainId = "eip155:1"
161186 networkImageSrc = "./images/eth_logo.svg"
162187 /> ,
163188 ) ;
@@ -183,97 +208,104 @@ describe('AddressQRCodeModal', () => {
183208 address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
184209 accountName = "Test Account"
185210 networkName = "Ethereum"
211+ chainId = "eip155:1"
186212 networkImageSrc = "./images/eth_logo.svg"
187213 /> ,
188214 ) ;
189215
190- const closeButton = screen . getByRole ( 'button' , { name : ' Close' } ) ;
216+ const closeButton = screen . getByLabelText ( ' Close') ;
191217 fireEvent . click ( closeButton ) ;
192218
193- expect ( onClose ) . toHaveBeenCalled ( ) ;
219+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
194220 } ) ;
195221
196222 it ( 'should handle different network types and navigate to Solana explorer correctly' , ( ) => {
197- // Test Solana
198- const solanaAddress = 'Dh9ZYBBCdD5FjjgKpAi9w9GQvK4f8k3b8a8HHKhz7kLa' ;
223+ const address = '9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM' ;
224+
225+ // Mock the getBlockExplorerInfo to return Solana explorer info
226+ mockGetBlockExplorerInfo . mockReturnValue ( {
227+ addressUrl : `https://solscan.io/account/${ address } ` ,
228+ name : 'Solscan' ,
229+ buttonText : 'View on Solscan' ,
230+ } ) ;
231+
199232 renderWithProvider (
200233 < AddressQRCodeModal
201234 isOpen = { true }
202235 onClose = { jest . fn ( ) }
203- address = { solanaAddress }
204- accountName = "Solana Account"
236+ address = { address }
237+ accountName = "Test Account"
205238 networkName = "Solana"
239+ chainId = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
206240 networkImageSrc = "./images/sol_logo.svg"
207241 /> ,
208242 ) ;
209243
210- expect ( screen . getByText ( 'Solana Account / Solana' ) ) . toBeInTheDocument ( ) ;
211- expect ( screen . getByText ( 'Solana Address' ) ) . toBeInTheDocument ( ) ;
212- expect ( screen . getByText ( 'Dh9ZYB' ) ) . toBeInTheDocument ( ) ; // First 6 chars
213- expect ( screen . getByText ( 'z7kLa' ) ) . toBeInTheDocument ( ) ; // Last 5 chars
214-
215244 const explorerButton = screen . getByRole ( 'button' , {
216245 name : 'View on Solscan' ,
217246 } ) ;
218- expect ( explorerButton ) . toBeInTheDocument ( ) ;
219247
220248 fireEvent . click ( explorerButton ) ;
221249
222250 expect ( mockOpenBlockExplorer ) . toHaveBeenCalledTimes ( 1 ) ;
223251 expect ( mockOpenBlockExplorer . mock . calls [ 0 ] [ 0 ] ) . toBe (
224- `https://solscan.io/address /${ solanaAddress } ` ,
252+ `https://solscan.io/account /${ address } ` ,
225253 ) ;
226254 } ) ;
227255
228256 it ( 'should handle Bitcoin network and navigate to Bitcoin explorer correctly' , ( ) => {
229- const bitcoinAddress = 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh' ;
257+ const address = '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa' ;
258+
259+ // Mock the getBlockExplorerInfo to return Bitcoin explorer info
260+ mockGetBlockExplorerInfo . mockReturnValue ( {
261+ addressUrl : `https://blockstream.info/address/${ address } ` ,
262+ name : 'Blockstream' ,
263+ buttonText : 'View on Blockstream' ,
264+ } ) ;
265+
230266 renderWithProvider (
231267 < AddressQRCodeModal
232268 isOpen = { true }
233269 onClose = { jest . fn ( ) }
234- address = { bitcoinAddress }
235- accountName = "Bitcoin Account"
270+ address = { address }
271+ accountName = "Test Account"
236272 networkName = "Bitcoin"
273+ chainId = "bitcoin:0"
237274 networkImageSrc = "./images/btc_logo.svg"
238275 /> ,
239276 ) ;
240277
241- expect ( screen . getByText ( 'Bitcoin Account / Bitcoin' ) ) . toBeInTheDocument ( ) ;
242- expect ( screen . getByText ( 'Bitcoin Address' ) ) . toBeInTheDocument ( ) ;
243-
244278 const explorerButton = screen . getByRole ( 'button' , {
245279 name : 'View on Blockstream' ,
246280 } ) ;
247- expect ( explorerButton ) . toBeInTheDocument ( ) ;
248281
249282 fireEvent . click ( explorerButton ) ;
250283
251284 expect ( mockOpenBlockExplorer ) . toHaveBeenCalledTimes ( 1 ) ;
252285 expect ( mockOpenBlockExplorer . mock . calls [ 0 ] [ 0 ] ) . toBe (
253- `https://blockstream.info/address/${ bitcoinAddress } ` ,
286+ `https://blockstream.info/address/${ address } ` ,
254287 ) ;
255288 } ) ;
256289
257290 it ( 'should handle unknown network gracefully' , ( ) => {
291+ // Mock the getBlockExplorerInfo to return null for unknown network
292+ mockGetBlockExplorerInfo . mockReturnValue ( null ) ;
293+
258294 renderWithProvider (
259295 < AddressQRCodeModal
260296 isOpen = { true }
261297 onClose = { jest . fn ( ) }
262- address = "unknown_address_format "
298+ address = "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc "
263299 accountName = "Test Account"
264300 networkName = "Unknown Network"
301+ chainId = "unknown:123"
302+ networkImageSrc = "./images/unknown_logo.svg"
265303 /> ,
266304 ) ;
267305
306+ // Should not render explorer button for unknown network
268307 expect (
269- screen . getByText ( 'Test Account / Unknown Network' ) ,
270- ) . toBeInTheDocument ( ) ;
271- expect ( screen . getByText ( 'Unknown Network Address' ) ) . toBeInTheDocument ( ) ;
272- // Explorer button should not be rendered for unknown networks
273- expect (
274- screen . queryByRole ( 'button' , { name : / v i e w .* e x p l o r e r / iu } ) ,
308+ screen . queryByRole ( 'button' , { name : / V i e w o n / u } ) ,
275309 ) . not . toBeInTheDocument ( ) ;
276- // Make sure openBlockExplorer was not called
277- expect ( mockOpenBlockExplorer ) . not . toHaveBeenCalled ( ) ;
278310 } ) ;
279311} ) ;
0 commit comments