1
- import { RewriteFrames } from '@sentry/integrations' ;
2
1
import * as SentryNode from '@sentry/node' ;
3
2
import { getCurrentHub , NodeClient } from '@sentry/node' ;
4
3
import { Integration } from '@sentry/types' ;
5
4
import { getGlobalObject , logger } from '@sentry/utils' ;
6
5
import * as domain from 'domain' ;
7
6
8
7
import { init } from '../src/index.server' ;
9
- import { NextjsOptions } from '../src/utils/nextjsOptions' ;
10
8
11
9
const { Integrations } = SentryNode ;
12
10
@@ -18,6 +16,10 @@ const global = getGlobalObject();
18
16
const nodeInit = jest . spyOn ( SentryNode , 'init' ) ;
19
17
const loggerLogSpy = jest . spyOn ( logger , 'log' ) ;
20
18
19
+ function findIntegrationByName ( integrations : Integration [ ] = [ ] , name : string ) : Integration | undefined {
20
+ return integrations . find ( integration => integration . name === name ) ;
21
+ }
22
+
21
23
describe ( 'Server init()' , ( ) => {
22
24
afterEach ( ( ) => {
23
25
jest . clearAllMocks ( ) ;
@@ -49,7 +51,14 @@ describe('Server init()', () => {
49
51
} ,
50
52
autoSessionTracking : false ,
51
53
environment : 'test' ,
52
- integrations : [ expect . any ( RewriteFrames ) ] ,
54
+
55
+ // Integrations are tested separately, and we can't be more specific here without depending on the order in
56
+ // which integrations appear in the array, which we can't guarantee.
57
+ //
58
+ // TODO: If we upgrde to Jest 28+, we can follow Jest's example matcher and create an
59
+ // `expect.ArrayContainingInAnyOrder`. See
60
+ // https://github.com/facebook/jest/blob/main/examples/expect-extend/toBeWithinRange.ts.
61
+ integrations : expect . any ( Array ) ,
53
62
} ) ,
54
63
) ;
55
64
} ) ;
@@ -133,82 +142,93 @@ describe('Server init()', () => {
133
142
} ) ;
134
143
135
144
describe ( 'integrations' , ( ) => {
136
- it ( 'adds RewriteFrames integration by default' , ( ) => {
145
+ // Options passed by `@sentry/nextjs`'s `init` to `@sentry/node`'s `init` after modifying them
146
+ type ModifiedInitOptions = { integrations : Integration [ ] } ;
147
+
148
+ it ( 'adds default integrations' , ( ) => {
137
149
init ( { } ) ;
138
150
139
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
140
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 1 ) ;
141
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
142
- expect ( integrations [ 0 ] ) . toEqual ( expect . any ( RewriteFrames ) ) ;
151
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
152
+ const rewriteFramesIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'RewriteFrames' ) ;
153
+
154
+ expect ( rewriteFramesIntegration ) . toBeDefined ( ) ;
143
155
} ) ;
144
156
145
- it ( 'adds Http integration by default if tracesSampleRate is set' , ( ) => {
146
- init ( { tracesSampleRate : 1.0 } ) ;
157
+ it ( 'supports passing unrelated integrations through options' , ( ) => {
158
+ init ( { integrations : [ new Integrations . Console ( ) ] } ) ;
159
+
160
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
161
+ const consoleIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Console' ) ;
147
162
148
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
149
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 2 ) ;
150
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
151
- expect ( integrations [ 1 ] ) . toEqual ( expect . any ( Integrations . Http ) ) ;
163
+ expect ( consoleIntegration ) . toBeDefined ( ) ;
152
164
} ) ;
153
165
154
- it ( 'adds Http integration by default if tracesSampler is set' , ( ) => {
155
- init ( { tracesSampler : ( ) => true } ) ;
166
+ describe ( '`Http` integration' , ( ) => {
167
+ it ( 'adds `Http` integration with tracing enabled if `tracesSampleRate` is set' , ( ) => {
168
+ init ( { tracesSampleRate : 1.0 } ) ;
156
169
157
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
158
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 2 ) ;
159
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
160
- expect ( integrations [ 1 ] ) . toEqual ( expect . any ( Integrations . Http ) ) ;
161
- } ) ;
170
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
171
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
162
172
163
- it ( 'adds Http integration with tracing true' , ( ) => {
164
- init ( { tracesSampleRate : 1.0 } ) ;
165
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
166
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 2 ) ;
173
+ expect ( httpIntegration ) . toBeDefined ( ) ;
174
+ expect ( httpIntegration ) . toEqual ( expect . objectContaining ( { _tracing : true } ) ) ;
175
+ } ) ;
167
176
168
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
169
- expect ( ( integrations [ 1 ] as any ) . _tracing ) . toBe ( true ) ;
170
- } ) ;
177
+ it ( 'adds `Http` integration with tracing enabled if `tracesSampler` is set' , ( ) => {
178
+ init ( { tracesSampler : ( ) => true } ) ;
171
179
172
- it ( 'supports passing integration through options' , ( ) => {
173
- init ( { tracesSampleRate : 1.0 , integrations : [ new Integrations . Console ( ) ] } ) ;
174
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
175
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 3 ) ;
176
-
177
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
178
- expect ( integrations ) . toEqual ( [
179
- expect . any ( Integrations . Console ) ,
180
- expect . any ( RewriteFrames ) ,
181
- expect . any ( Integrations . Http ) ,
182
- ] ) ;
183
- } ) ;
180
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
181
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
182
+
183
+ expect ( httpIntegration ) . toBeDefined ( ) ;
184
+ expect ( httpIntegration ) . toEqual ( expect . objectContaining ( { _tracing : true } ) ) ;
185
+ } ) ;
186
+
187
+ it ( 'does not add `Http` integration if tracing not enabled in SDK' , ( ) => {
188
+ init ( { } ) ;
184
189
185
- describe ( 'custom Http integration' , ( ) => {
186
- it ( 'sets tracing to true if tracesSampleRate is set' , ( ) => {
190
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
191
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
192
+
193
+ expect ( httpIntegration ) . toBeUndefined ( ) ;
194
+ } ) ;
195
+
196
+ it ( 'forces `_tracing = true` if `tracesSampleRate` is set' , ( ) => {
187
197
init ( {
188
198
tracesSampleRate : 1.0 ,
189
199
integrations : [ new Integrations . Http ( { tracing : false } ) ] ,
190
200
} ) ;
191
201
192
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
193
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 2 ) ;
194
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
195
- expect ( integrations [ 0 ] as InstanceType < typeof Integrations . Http > ) . toEqual (
196
- expect . objectContaining ( { _breadcrumbs : true , _tracing : true , name : 'Http' } ) ,
197
- ) ;
202
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
203
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
204
+
205
+ expect ( httpIntegration ) . toBeDefined ( ) ;
206
+ expect ( httpIntegration ) . toEqual ( expect . objectContaining ( { _tracing : true } ) ) ;
198
207
} ) ;
199
208
200
- it ( 'sets tracing to true if tracesSampler is set' , ( ) => {
209
+ it ( 'forces `_tracing = true` if ` tracesSampler` is set' , ( ) => {
201
210
init ( {
202
211
tracesSampler : ( ) => true ,
203
212
integrations : [ new Integrations . Http ( { tracing : false } ) ] ,
204
213
} ) ;
205
214
206
- const nodeInitOptions : NextjsOptions = nodeInit . mock . calls [ 0 ] [ 0 ] ! ;
207
- expect ( nodeInitOptions . integrations ) . toHaveLength ( 2 ) ;
208
- const integrations = nodeInitOptions . integrations as Integration [ ] ;
209
- expect ( integrations [ 0 ] as InstanceType < typeof Integrations . Http > ) . toEqual (
210
- expect . objectContaining ( { _breadcrumbs : true , _tracing : true , name : 'Http' } ) ,
211
- ) ;
215
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
216
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
217
+
218
+ expect ( httpIntegration ) . toBeDefined ( ) ;
219
+ expect ( httpIntegration ) . toEqual ( expect . objectContaining ( { _tracing : true } ) ) ;
220
+ } ) ;
221
+
222
+ it ( 'does not force `_tracing = true` if tracing not enabled in SDK' , ( ) => {
223
+ init ( {
224
+ integrations : [ new Integrations . Http ( { tracing : false } ) ] ,
225
+ } ) ;
226
+
227
+ const nodeInitOptions = nodeInit . mock . calls [ 0 ] [ 0 ] as ModifiedInitOptions ;
228
+ const httpIntegration = findIntegrationByName ( nodeInitOptions . integrations , 'Http' ) ;
229
+
230
+ expect ( httpIntegration ) . toBeDefined ( ) ;
231
+ expect ( httpIntegration ) . toEqual ( expect . objectContaining ( { _tracing : false } ) ) ;
212
232
} ) ;
213
233
} ) ;
214
234
} ) ;
0 commit comments