@@ -3,6 +3,7 @@ import { Button, Text, View } from 'react-native';
33import { fireEvent } from '@testing-library/react-native' ;
44import { ETHSignature } from '@keystonehq/bc-ur-registry-eth' ;
55import { HardwareWalletError } from '@metamask/hw-wallet-sdk' ;
6+ import { stringify as uuidStringify } from 'uuid' ;
67
78import renderWithProvider from '../../../../../util/test/renderWithProvider' ;
89import { typedSignV3ConfirmationState } from '../../../../../util/test/confirm-data-helpers' ;
@@ -32,9 +33,11 @@ jest.mock('../../../../../core/Engine', () => ({
3233} ) ) ;
3334
3435jest . mock ( 'uuid' , ( ) => ( {
35- stringify : jest . fn ( ) . mockReturnValue ( 'c95ecc76-d6e9-4a0a-afa3-31429bc80566' ) ,
36+ stringify : jest . fn ( ) ,
3637} ) ) ;
3738
39+ const mockUuidStringify = uuidStringify as jest . Mock ;
40+
3841const MockView = View ;
3942const MockText = Text ;
4043const MockButton = Button ;
@@ -204,7 +207,95 @@ describe('QRInfo', () => {
204207 expect ( mockSetScannerVisible ) . toHaveBeenCalledWith ( true ) ;
205208 } ) ;
206209
210+ it ( 'registers cleanup that clears QR scan retry handler on unmount' , ( ) => {
211+ const mockSetScannerVisible = jest . fn ( ) ;
212+ createQRHardwareHookSpy ( { setScannerVisible : mockSetScannerVisible } ) ;
213+ const { unmount } = renderWithProvider ( < QRInfo /> , {
214+ state : typedSignV3ConfirmationState ,
215+ } ) ;
216+
217+ unmount ( ) ;
218+
219+ expect ( mockSetQrScanRetryHandler ) . toHaveBeenCalledWith ( null ) ;
220+ } ) ;
221+
222+ it ( 'shows error when scanned signature request ID does not match pending request' , ( ) => {
223+ mockUuidStringify . mockReturnValue ( 'mismatched-uuid-value' ) ;
224+ jest . spyOn ( ETHSignature , 'fromCBOR' ) . mockReturnValue ( {
225+ getRequestId : ( ) => Buffer . from ( 'different-request-id' ) ,
226+ } as unknown as ETHSignature ) ;
227+ const mockSetScannerVisible = jest . fn ( ) ;
228+ createQRHardwareHookSpy ( {
229+ scannerVisible : true ,
230+ setScannerVisible : mockSetScannerVisible ,
231+ } ) ;
232+ const { getByText } = renderWithProvider ( < QRInfo /> , {
233+ state : typedSignV3ConfirmationState ,
234+ } ) ;
235+
236+ fireEvent . press ( getByText ( 'onScanSuccess' ) ) ;
237+
238+ expect ( mockSetScannerVisible ) . toHaveBeenCalledWith ( false ) ;
239+ expect ( mockQrKeyringBridge . resolvePendingScan ) . not . toHaveBeenCalled ( ) ;
240+ expect (
241+ getByText (
242+ "Incongruent transaction data. Please use your hardware wallet to sign the QR code below and tap 'Get Signature'." ,
243+ ) ,
244+ ) . toBeOnTheScreen ( ) ;
245+ } ) ;
246+
247+ it ( 'clears error message when error alert is pressed' , ( ) => {
248+ mockUuidStringify . mockReturnValue ( 'mismatched-uuid-value' ) ;
249+ jest . spyOn ( ETHSignature , 'fromCBOR' ) . mockReturnValue ( {
250+ getRequestId : ( ) => Buffer . from ( 'different-request-id' ) ,
251+ } as unknown as ETHSignature ) ;
252+ const mockSetScannerVisible = jest . fn ( ) ;
253+ createQRHardwareHookSpy ( {
254+ scannerVisible : true ,
255+ setScannerVisible : mockSetScannerVisible ,
256+ } ) ;
257+ const { getByText, queryByText } = renderWithProvider ( < QRInfo /> , {
258+ state : typedSignV3ConfirmationState ,
259+ } ) ;
260+
261+ fireEvent . press ( getByText ( 'onScanSuccess' ) ) ;
262+
263+ const errorText =
264+ "Incongruent transaction data. Please use your hardware wallet to sign the QR code below and tap 'Get Signature'." ;
265+ expect ( getByText ( errorText ) ) . toBeOnTheScreen ( ) ;
266+
267+ fireEvent . press ( getByText ( errorText ) ) ;
268+
269+ expect ( queryByText ( errorText ) ) . toBeNull ( ) ;
270+ } ) ;
271+
272+ it ( 'shows error when scanned signature has no request ID' , ( ) => {
273+ mockUuidStringify . mockReturnValue ( 'c95ecc76-d6e9-4a0a-afa3-31429bc80566' ) ;
274+ jest . spyOn ( ETHSignature , 'fromCBOR' ) . mockReturnValue ( {
275+ getRequestId : ( ) => null ,
276+ } as unknown as ETHSignature ) ;
277+ const mockSetScannerVisible = jest . fn ( ) ;
278+ createQRHardwareHookSpy ( {
279+ scannerVisible : true ,
280+ setScannerVisible : mockSetScannerVisible ,
281+ } ) ;
282+ const { getByText } = renderWithProvider ( < QRInfo /> , {
283+ state : typedSignV3ConfirmationState ,
284+ } ) ;
285+
286+ fireEvent . press ( getByText ( 'onScanSuccess' ) ) ;
287+
288+ expect ( mockSetScannerVisible ) . toHaveBeenCalledWith ( false ) ;
289+ expect ( mockQrKeyringBridge . resolvePendingScan ) . not . toHaveBeenCalled ( ) ;
290+ expect (
291+ getByText (
292+ "Incongruent transaction data. Please use your hardware wallet to sign the QR code below and tap 'Get Signature'." ,
293+ ) ,
294+ ) . toBeOnTheScreen ( ) ;
295+ } ) ;
296+
207297 it ( 'submits request when onScanSuccess is called by scanner' , ( ) => {
298+ mockUuidStringify . mockReturnValue ( 'c95ecc76-d6e9-4a0a-afa3-31429bc80566' ) ;
208299 jest . spyOn ( ETHSignature , 'fromCBOR' ) . mockReturnValue ( {
209300 getRequestId : ( ) => mockPendingScanRequest . request ?. requestId ,
210301 } as unknown as ETHSignature ) ;
0 commit comments