1- import * as Sentry from '@sentry/react-native' ;
21import { defaultStackParser , makeFetchTransport } from '@sentry/react' ;
32import * as SentryReactNativeModule from '@sentry/react-native' ;
4- import { reportError , setSentryExtraAttribute } from './sentryIntegration' ;
5-
6- jest . mock ( '@sentry/react-native' , ( ) => {
7- const scope = {
8- setClient : jest . fn ( ) ,
9- addBreadcrumb : jest . fn ( ) ,
10- captureException : jest . fn ( ) ,
11- setExtra : jest . fn ( ) ,
12- } ;
13- return {
14- ReactNativeClient : jest . fn ( ) . mockImplementation ( ( ) => ( {
15- init : jest . fn ( ) ,
16- captureException : jest . fn ( ) ,
17- } ) ) ,
18- Scope : jest . fn ( ) . mockImplementation ( ( ) => scope ) ,
3+ import {
4+ __internal_reset_sentry_scope ,
5+ initSentry ,
6+ reportError ,
7+ } from './sentryIntegration' ;
8+ import logger from './logger' ;
199
20- // Only for internal testing
21- __test_getScope : ( ) => scope ,
10+ jest . mock ( 'react-native' , ( ) => {
11+ return {
12+ Platform : {
13+ OS : 'android' ,
14+ Version : '10.1.2' ,
15+ } ,
2216 } ;
2317} ) ;
2418
25- describe ( 'sentryScope ' , ( ) => {
19+ describe ( 'sentryIntegration ' , ( ) => {
2620 let addBreadcrumbMock : jest . Mock ;
2721 let captureExceptionMock : jest . Mock ;
22+ let setTagsMock : jest . Mock ;
23+ let ReactNativeClientSpy : jest . SpyInstance ;
24+ let ScopeSpy : jest . SpyInstance ;
2825
2926 beforeEach ( ( ) => {
3027 addBreadcrumbMock = jest . fn ( ) ;
3128 captureExceptionMock = jest . fn ( ) ;
32- jest . spyOn ( SentryReactNativeModule , 'Scope' ) . mockReturnValue ( {
29+ setTagsMock = jest . fn ( ) ;
30+ ScopeSpy = jest . spyOn ( SentryReactNativeModule , 'Scope' ) . mockReturnValue ( {
3331 setClient : jest . fn ( ) ,
32+ init : jest . fn ( ) ,
3433 addBreadcrumb : addBreadcrumbMock ,
3534 captureException : captureExceptionMock ,
35+ setTags : setTagsMock ,
3636 } as any ) ;
37+
38+ ReactNativeClientSpy = jest
39+ . spyOn ( SentryReactNativeModule , 'ReactNativeClient' )
40+ . mockImplementation (
41+ ( ) =>
42+ ( {
43+ init : jest . fn ( ) ,
44+ } ) as any
45+ ) ;
46+
47+ jest . spyOn ( logger , 'error' ) . mockImplementation ( ( ) => { } ) ;
48+ jest . spyOn ( logger , 'warn' ) . mockImplementation ( ( ) => { } ) ;
3749 } ) ;
3850
3951 afterEach ( ( ) => {
4052 jest . restoreAllMocks ( ) ;
4153 jest . resetAllMocks ( ) ;
54+ __internal_reset_sentry_scope ( ) ;
55+ } ) ;
56+
57+ it ( 'should not initialise sentry scope if already initialised' , ( ) => {
58+ initSentry ( { propertyId : 'test-id' } ) ;
59+ initSentry ( { propertyId : 'test-id' } ) ;
60+
61+ expect ( logger . warn ) . toHaveBeenCalledWith ( 'Sentry already initialized' ) ;
62+ expect ( ReactNativeClientSpy ) . toHaveBeenCalledTimes ( 1 ) ;
63+ expect ( ScopeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
4264 } ) ;
4365
4466 it ( 'should initialise sentry scope with correct options' , ( ) => {
45- expect ( Sentry . ReactNativeClient ) . toHaveBeenCalledWith ( {
67+ initSentry ( { propertyId : 'test-id' } ) ;
68+
69+ expect ( ReactNativeClientSpy ) . toHaveBeenCalledWith ( {
4670 attachStacktrace : true ,
4771 autoInitializeNativeSdk : false ,
4872 dsn :
'https://[email protected] /8' , @@ -57,52 +81,58 @@ describe('sentryScope', () => {
5781 enableStallTracking : true ,
5882 enableUserInteractionTracing : false ,
5983 enableWatchdogTerminationTracking : false ,
84+ environment : 'development' ,
6085 maxQueueSize : 30 ,
6186 parentSpanIsAlwaysRootSpan : true ,
6287 patchGlobalPromise : true ,
6388 sendClientReports : true ,
64- integrations : [ ] ,
89+ integrations : undefined ,
6590 stackParser : defaultStackParser ,
6691 transport : makeFetchTransport ,
6792 } ) ;
93+
94+ expect ( setTagsMock ) . toHaveBeenCalledWith ( {
95+ OS : 'android' ,
96+ platformVersion : '10.1.2' ,
97+ propertyId : 'test-id' ,
98+ } ) ;
6899 } ) ;
69100
70101 describe ( 'reportError' , ( ) => {
71102 it ( 'should add breadcrumb with message if provided' , ( ) => {
103+ initSentry ( { propertyId : 'test-id' } ) ;
72104 const err = new Error ( 'test' ) ;
73105 const msg = 'test message' ;
74- // @ts -ignore
75- const { addBreadcrumb, captureException } = Sentry . __test_getScope ( ) ;
106+
76107 reportError ( err , { msg } ) ;
77108
78- expect ( addBreadcrumb ) . toHaveBeenCalledWith ( {
109+ expect ( addBreadcrumbMock ) . toHaveBeenCalledWith ( {
79110 category : 'Error' ,
80111 message : msg ,
81112 level : 'log' ,
82113 } ) ;
83- expect ( captureException ) . toHaveBeenCalledWith ( err ) ;
114+ expect ( captureExceptionMock ) . toHaveBeenCalledWith ( err ) ;
84115 } ) ;
85116
86117 it ( 'should not add breadcrumb if message is not provided' , ( ) => {
118+ initSentry ( { propertyId : 'test-id' } ) ;
87119 const err = new Error ( 'test' ) ;
88- // @ts -ignore
89- const { addBreadcrumb, captureException } = Sentry . __test_getScope ( ) ;
120+
90121 reportError ( err ) ;
91122
92- expect ( addBreadcrumb ) . not . toHaveBeenCalled ( ) ;
93- expect ( captureException ) . toHaveBeenCalledWith ( err ) ;
123+ expect ( addBreadcrumbMock ) . not . toHaveBeenCalled ( ) ;
124+ expect ( captureExceptionMock ) . toHaveBeenCalledWith ( err ) ;
94125 } ) ;
95- } ) ;
96126
97- describe ( 'setSentryExtraAttribute' , ( ) => {
98- it ( 'should set extra attribute' , ( ) => {
99- const key = 'testKey' ;
100- const value = 'testValue' ;
101- // @ts -ignore
102- const { setExtra } = Sentry . __test_getScope ( ) ;
103- setSentryExtraAttribute ( key , value ) ;
127+ it ( 'should not throw error when reportError is called before initSentry' , ( ) => {
128+ const err = new Error ( 'test' ) ;
129+ const msg = 'test message' ;
130+
131+ reportError ( err , { msg } ) ;
104132
105- expect ( setExtra ) . toHaveBeenCalledWith ( key , value ) ;
133+ expect ( logger . error ) . toHaveBeenCalledWith ( { err } , msg ) ;
134+ expect ( addBreadcrumbMock ) . not . toHaveBeenCalled ( ) ;
135+ expect ( captureExceptionMock ) . not . toHaveBeenCalledWith ( err ) ;
106136 } ) ;
107137 } ) ;
108138} ) ;
0 commit comments