11import type { Span } from '@sentry/core' ;
22import { getActiveSpan , getCurrentScope , spanToJSON , startSpanManual } from '@sentry/core' ;
3- import type { AppState , AppStateStatus } from 'react-native' ;
3+ import type { AppStateStatus } from 'react-native' ;
4+ import { AppState } from 'react-native' ;
45import type { ScopeWithMaybeSpan } from '../../src/js/tracing/span' ;
56import { SCOPE_SPAN_FIELD , startIdleNavigationSpan } from '../../src/js/tracing/span' ;
67import { NATIVE } from '../../src/js/wrapper' ;
@@ -11,36 +12,39 @@ type MockAppState = {
1112 listener : ( newState : AppStateStatus ) => void ;
1213 removeSubscription : jest . Func ;
1314} ;
14- const mockedAppState : AppState & MockAppState = {
15- removeSubscription : jest . fn ( ) ,
16- listener : jest . fn ( ) ,
17- isAvailable : true ,
18- currentState : 'active' ,
19- addEventListener : ( _ , listener ) => {
20- mockedAppState . listener = listener ;
21- return {
22- remove : mockedAppState . removeSubscription ,
23- } ;
24- } ,
25- setState : ( state : AppStateStatus ) => {
26- mockedAppState . currentState = state ;
27- mockedAppState . listener ( state ) ;
28- } ,
29- } ;
30- jest . mock ( 'react-native/Libraries/AppState/AppState' , ( ) => mockedAppState ) ;
15+ jest . mock ( 'react-native' , ( ) => {
16+ const mockedAppState : AppState & MockAppState = {
17+ removeSubscription : jest . fn ( ) ,
18+ listener : jest . fn ( ) ,
19+ isAvailable : true ,
20+ currentState : 'active' ,
21+ addEventListener : jest . fn ( ) ,
22+ setState : ( state : AppStateStatus ) => {
23+ mockedAppState . currentState = state ;
24+ mockedAppState . listener ( state ) ;
25+ } ,
26+ } ;
27+ return {
28+ AppState : mockedAppState ,
29+ Platform : { OS : 'ios' } ,
30+ NativeModules : {
31+ RNSentry : { }
32+ }
33+ } ;
34+ } ) ;
35+
36+ const mockedAppState = AppState as jest . Mocked < typeof AppState & MockAppState > ;
3137
3238describe ( 'startIdleNavigationSpan' , ( ) => {
3339 beforeEach ( ( ) => {
3440 jest . useFakeTimers ( ) ;
3541 NATIVE . enableNative = true ;
3642 mockedAppState . isAvailable = true ;
3743 mockedAppState . currentState = 'active' ;
38- mockedAppState . addEventListener = ( _ , listener ) => {
44+ ( mockedAppState . addEventListener as jest . Mock ) . mockImplementation ( ( _ , listener ) => {
3945 mockedAppState . listener = listener ;
40- return {
41- remove : mockedAppState . removeSubscription ,
42- } ;
43- } ;
46+ return { remove : mockedAppState . removeSubscription } ;
47+ } ) ;
4448 setupTestClient ( ) ;
4549 } ) ;
4650
@@ -66,9 +70,9 @@ describe('startIdleNavigationSpan', () => {
6670
6771 it ( 'Does not crash when AppState is not available' , async ( ) => {
6872 mockedAppState . isAvailable = false ;
69- mockedAppState . addEventListener = ( ( ) : void => {
73+ ( mockedAppState . addEventListener as jest . Mock ) . mockImplementation ( ( ) => {
7074 return undefined ;
71- } ) as unknown as ( typeof mockedAppState ) [ 'addEventListener' ] ; // RN Web can return undefined
75+ } ) ;
7276
7377 startIdleNavigationSpan ( {
7478 name : 'test' ,
@@ -94,7 +98,7 @@ describe('startIdleNavigationSpan', () => {
9498
9599 // Verify it's a non-recording span
96100 expect ( span ) . toBeDefined ( ) ;
97- expect ( span . constructor . name ) . toBe ( 'SentryNonRecordingSpan' ) ;
101+ expect ( span ? .constructor . name ) . toBe ( 'SentryNonRecordingSpan' ) ;
98102
99103 // No AppState listener should be set up for non-recording spans
100104 expect ( mockedAppState . removeSubscription ) . not . toHaveBeenCalled ( ) ;
@@ -140,7 +144,7 @@ describe('startIdleNavigationSpan', () => {
140144 name : 'test' ,
141145 } ) ;
142146
143- firstSpan . end ( ) ;
147+ firstSpan ? .end ( ) ;
144148
145149 const secondSpan = startIdleNavigationSpan ( {
146150 name : 'test' ,
0 commit comments