@@ -2,7 +2,12 @@ import type { Client } from '@sentry/core';
2
2
import * as SentryCore from '@sentry/core' ;
3
3
import type { IncomingMessage , ServerResponse } from 'http' ;
4
4
import { afterEach , beforeEach , describe , expect , test , vi } from 'vitest' ;
5
- import { wrapGetInitialPropsWithSentry , wrapGetServerSidePropsWithSentry } from '../../src/common' ;
5
+ import {
6
+ wrapGetInitialPropsWithSentry ,
7
+ wrapGetServerSidePropsWithSentry ,
8
+ wrapMiddlewareWithSentry ,
9
+ } from '../../src/common' ;
10
+ import type { EdgeRouteHandler } from '../../src/edge/types' ;
6
11
7
12
const startSpanManualSpy = vi . spyOn ( SentryCore , 'startSpanManual' ) ;
8
13
@@ -84,3 +89,102 @@ describe('data-fetching function wrappers should not create manual spans', () =>
84
89
expect ( mockSetAttribute ) . not . toHaveBeenCalled ( ) ;
85
90
} ) ;
86
91
} ) ;
92
+
93
+ describe ( 'wrapMiddlewareWithSentry' , ( ) => {
94
+ afterEach ( ( ) => {
95
+ vi . clearAllMocks ( ) ;
96
+ if ( '_sentryRewritesTunnelPath' in globalThis ) {
97
+ delete ( globalThis as any ) . _sentryRewritesTunnelPath ;
98
+ }
99
+ } ) ;
100
+
101
+ test ( 'should skip processing and return NextResponse.next() for tunnel route requests' , async ( ) => {
102
+ // Set up tunnel route in global
103
+ ( globalThis as any ) . _sentryRewritesTunnelPath = '/monitoring/tunnel' ;
104
+
105
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ) => ( { status : 200 } ) ) ;
106
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
107
+
108
+ // Create a mock Request that matches the tunnel route
109
+ const mockRequest = new Request ( 'https://example.com/monitoring/tunnel?o=123' ) ;
110
+
111
+ const result = await wrappedOriginal ( mockRequest ) ;
112
+
113
+ // Should skip calling the original function
114
+ expect ( origFunction ) . not . toHaveBeenCalled ( ) ;
115
+ expect ( result ) . toBeDefined ( ) ;
116
+ } ) ;
117
+
118
+ test ( 'should process normal request and call original function' , async ( ) => {
119
+ const mockReturnValue = { status : 200 } ;
120
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ..._args ) => mockReturnValue ) ;
121
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
122
+
123
+ const mockRequest = new Request ( 'https://example.com/api/users' , { method : 'GET' } ) ;
124
+
125
+ const result = await wrappedOriginal ( mockRequest ) ;
126
+
127
+ expect ( origFunction ) . toHaveBeenCalledWith ( mockRequest ) ;
128
+ expect ( result ) . toBe ( mockReturnValue ) ;
129
+ } ) ;
130
+
131
+ test ( 'should handle non-Request arguments' , async ( ) => {
132
+ const mockReturnValue = { status : 200 } ;
133
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ..._args ) => mockReturnValue ) ;
134
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
135
+
136
+ const mockArgs = { someProperty : 'value' } ;
137
+
138
+ const result = await wrappedOriginal ( mockArgs ) ;
139
+
140
+ expect ( origFunction ) . toHaveBeenCalledWith ( mockArgs ) ;
141
+ expect ( result ) . toBe ( mockReturnValue ) ;
142
+ } ) ;
143
+
144
+ test ( 'should handle errors in middleware function' , async ( ) => {
145
+ const testError = new Error ( 'Test middleware error' ) ;
146
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ..._args ) => {
147
+ throw testError ;
148
+ } ) ;
149
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
150
+
151
+ const mockRequest = new Request ( 'https://example.com/api/users' ) ;
152
+
153
+ await expect ( wrappedOriginal ( mockRequest ) ) . rejects . toThrow ( 'Test middleware error' ) ;
154
+ expect ( origFunction ) . toHaveBeenCalledWith ( mockRequest ) ;
155
+ } ) ;
156
+
157
+ test ( 'should not process tunnel route when no tunnel path is set' , async ( ) => {
158
+ if ( '_sentryRewritesTunnelPath' in globalThis ) {
159
+ delete ( globalThis as any ) . _sentryRewritesTunnelPath ;
160
+ }
161
+
162
+ const mockReturnValue = { status : 200 } ;
163
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ..._args ) => mockReturnValue ) ;
164
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
165
+
166
+ const mockRequest = new Request ( 'https://example.com/monitoring/tunnel/sentry?o=123' ) ;
167
+
168
+ const result = await wrappedOriginal ( mockRequest ) ;
169
+
170
+ // Should process normally since no tunnel path is configured
171
+ expect ( origFunction ) . toHaveBeenCalledWith ( mockRequest ) ;
172
+ expect ( result ) . toBe ( mockReturnValue ) ;
173
+ } ) ;
174
+
175
+ test ( 'should process request when tunnel path is set but request does not match' , async ( ) => {
176
+ ( globalThis as any ) . _sentryRewritesTunnelPath = '/monitoring/tunnel' ;
177
+
178
+ const mockReturnValue = { status : 200 } ;
179
+ const origFunction : EdgeRouteHandler = vi . fn ( async ( ..._args ) => mockReturnValue ) ;
180
+ const wrappedOriginal = wrapMiddlewareWithSentry ( origFunction ) ;
181
+
182
+ const mockRequest = new Request ( 'https://example.com/api/users' , { method : 'GET' } ) ;
183
+
184
+ const result = await wrappedOriginal ( mockRequest ) ;
185
+
186
+ // Should process normally since request doesn't match tunnel path
187
+ expect ( origFunction ) . toHaveBeenCalledWith ( mockRequest ) ;
188
+ expect ( result ) . toBe ( mockReturnValue ) ;
189
+ } ) ;
190
+ } ) ;
0 commit comments