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