@@ -46,6 +46,29 @@ describe('sentryMiddleware', () => {
4646 } ) ;
4747 const setSDKProcessingMetadataMock = vi . fn ( ) ;
4848
49+ const DATA_COLLECTION_DEFAULTS = {
50+ userInfo : false ,
51+ cookies : true ,
52+ httpHeaders : { request : true , response : true } ,
53+ httpBodies : [ ] ,
54+ urlQueryParams : true ,
55+ graphQL : { document : true , variables : true } ,
56+ genAI : { inputs : true , outputs : true } ,
57+ databaseQueryData : true ,
58+ stackFrameVariables : true ,
59+ frameContextLines : 5 ,
60+ } ;
61+
62+ function mockClientWith ( dataCollection : Partial < typeof DATA_COLLECTION_DEFAULTS > ) : void {
63+ vi . spyOn ( SentryNode , 'getClient' ) . mockImplementation (
64+ ( ) =>
65+ ( {
66+ getOptions : ( ) => ( { } ) ,
67+ getDataCollectionOptions : ( ) => ( { ...DATA_COLLECTION_DEFAULTS , ...dataCollection } ) ,
68+ } ) as unknown as Client ,
69+ ) ;
70+ }
71+
4972 beforeEach ( ( ) => {
5073 vi . spyOn ( SentryNode , 'getCurrentScope' ) . mockImplementation ( ( ) => {
5174 return {
@@ -56,24 +79,7 @@ describe('sentryMiddleware', () => {
5679 } as any ;
5780 } ) ;
5881 vi . spyOn ( SentryNode , 'getActiveSpan' ) . mockImplementation ( getSpanMock ) ;
59- vi . spyOn ( SentryNode , 'getClient' ) . mockImplementation (
60- ( ) =>
61- ( {
62- getOptions : ( ) => ( { } ) ,
63- getDataCollectionOptions : ( ) => ( {
64- userInfo : false ,
65- cookies : true ,
66- httpHeaders : { request : true , response : true } ,
67- httpBodies : [ ] ,
68- urlQueryParams : true ,
69- graphQL : { document : true , variables : true } ,
70- genAI : { inputs : true , outputs : true } ,
71- databaseQueryData : true ,
72- stackFrameVariables : true ,
73- frameContextLines : 5 ,
74- } ) ,
75- } ) as unknown as Client ,
76- ) ;
82+ mockClientWith ( { userInfo : false } ) ;
7783 vi . spyOn ( SentryNode , 'getTraceMetaTags' ) . mockImplementation (
7884 ( ) => `
7985 <meta name="sentry-trace" content="123">
@@ -308,8 +314,22 @@ describe('sentryMiddleware', () => {
308314 } ) ;
309315 } ) ;
310316
311- it ( 'follows `dataCollection.userInfo` when `trackClientIp` is not set' , async ( ) => {
312- // The shared client mock resolves `userInfo` to `false`.
317+ it ( 'attaches the client IP when `trackClientIp` is unset and `dataCollection.userInfo` is on' , async ( ) => {
318+ mockClientWith ( { userInfo : true } ) ;
319+ const middleware = handleRequest ( ) ;
320+ const ctx = {
321+ ...DYNAMIC_REQUEST_CONTEXT ,
322+ } ;
323+
324+ // @ts -expect-error, a partial ctx object is fine here
325+ await middleware ( ctx , async ( ) => {
326+ expect ( SentryCore . getIsolationScope ( ) . getScopeData ( ) . user ?. ip_address ) . toBe ( '192.168.0.1' ) ;
327+ return nextResult ;
328+ } ) ;
329+ } ) ;
330+
331+ it ( 'does not attach a client IP when `trackClientIp` is unset and `dataCollection.userInfo` is off' , async ( ) => {
332+ mockClientWith ( { userInfo : false } ) ;
313333 const middleware = handleRequest ( ) ;
314334 const ctx = {
315335 ...DYNAMIC_REQUEST_CONTEXT ,
@@ -322,7 +342,8 @@ describe('sentryMiddleware', () => {
322342 } ) ;
323343 } ) ;
324344
325- it ( 'does not attach a client IP if `trackClientIp=false`' , async ( ) => {
345+ it ( 'lets `trackClientIp=false` win over `dataCollection.userInfo`' , async ( ) => {
346+ mockClientWith ( { userInfo : true } ) ;
326347 const middleware = handleRequest ( { trackClientIp : false } ) ;
327348 const ctx = {
328349 ...DYNAMIC_REQUEST_CONTEXT ,
0 commit comments