Skip to content

Commit 76e4815

Browse files
committed
Add unit tests
1 parent e40883a commit 76e4815

File tree

3 files changed

+104
-5
lines changed

3 files changed

+104
-5
lines changed

packages/nextjs/src/edge/withSentryAPI.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ export function withSentryAPI<H extends EdgeRouteHandler>(
1313
return async function (this: unknown, ...args: Parameters<H>): Promise<ReturnType<H>> {
1414
const req = args[0];
1515

16-
const isCalledByUser = getCurrentHub().getScope()?.getTransaction();
16+
const activeSpan = !!getCurrentHub().getScope()?.getSpan();
1717

1818
const wrappedHandler = withEdgeWrapping(handler, {
1919
spanDescription:
20-
isCalledByUser || !(req instanceof Request)
20+
activeSpan || !(req instanceof Request)
2121
? `handler (${parameterizedRoute})`
2222
: `${req.method} ${parameterizedRoute}`,
23-
spanOp: isCalledByUser ? 'function' : 'http.server',
23+
spanOp: activeSpan ? 'function' : 'http.server',
2424
mechanismFunctionName: 'withSentryAPI',
2525
});
2626

packages/nextjs/test/edge/edgeWrapperUtils.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import * as sentryTracing from '@sentry/tracing';
33

44
import { withEdgeWrapping } from '../../src/edge/utils/edgeWrapperUtils';
55

6-
jest.spyOn(sentryTracing, 'hasTracingEnabled').mockImplementation(() => true);
7-
86
// @ts-ignore Request does not exist on type Global
97
const origRequest = global.Request;
108
// @ts-ignore Response does not exist on type Global
@@ -29,6 +27,12 @@ afterAll(() => {
2927
global.Response = origResponse;
3028
});
3129

30+
beforeEach(() => {
31+
jest.clearAllMocks();
32+
jest.resetAllMocks();
33+
jest.spyOn(sentryTracing, 'hasTracingEnabled').mockImplementation(() => true);
34+
});
35+
3236
describe('withEdgeWrapping', () => {
3337
it('should return a function that calls the passed function', async () => {
3438
const origFunctionReturnValue = new Response();
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import * as coreSdk from '@sentry/core';
2+
import * as sentryTracing from '@sentry/tracing';
3+
4+
import { withSentryAPI } from '../../src/edge';
5+
6+
// @ts-ignore Request does not exist on type Global
7+
const origRequest = global.Request;
8+
// @ts-ignore Response does not exist on type Global
9+
const origResponse = global.Response;
10+
11+
// @ts-ignore Request does not exist on type Global
12+
global.Request = class Request {
13+
headers = {
14+
get() {
15+
return null;
16+
},
17+
};
18+
19+
method = 'POST';
20+
};
21+
22+
// @ts-ignore Response does not exist on type Global
23+
global.Response = class Request {};
24+
25+
afterAll(() => {
26+
// @ts-ignore Request does not exist on type Global
27+
global.Request = origRequest;
28+
// @ts-ignore Response does not exist on type Global
29+
global.Response = origResponse;
30+
});
31+
32+
beforeEach(() => {
33+
jest.resetAllMocks();
34+
jest.restoreAllMocks();
35+
jest.spyOn(sentryTracing, 'hasTracingEnabled').mockImplementation(() => true);
36+
});
37+
38+
describe('withSentryAPI', () => {
39+
it('should return a function that starts a transaction with the correct name when there is no active transaction and a request is being passed', async () => {
40+
const startTransactionSpy = jest.spyOn(coreSdk, 'startTransaction');
41+
42+
const origFunctionReturnValue = new Response();
43+
const origFunction = jest.fn(_req => origFunctionReturnValue);
44+
45+
const wrappedFunction = withSentryAPI(origFunction, '/user/[userId]/post/[postId]');
46+
47+
const request = new Request('https://sentry.io/');
48+
await wrappedFunction(request);
49+
expect(startTransactionSpy).toHaveBeenCalledTimes(1);
50+
expect(startTransactionSpy).toHaveBeenCalledWith(
51+
expect.objectContaining({
52+
metadata: { source: 'route' },
53+
name: 'POST /user/[userId]/post/[postId]',
54+
op: 'http.server',
55+
}),
56+
{ request },
57+
);
58+
});
59+
60+
it('should return a function that should not start a transaction when there is no active span and no request is being passed', async () => {
61+
const startTransactionSpy = jest.spyOn(coreSdk, 'startTransaction');
62+
63+
const origFunctionReturnValue = new Response();
64+
const origFunction = jest.fn(() => origFunctionReturnValue);
65+
66+
const wrappedFunction = withSentryAPI(origFunction, '/user/[userId]/post/[postId]');
67+
68+
await wrappedFunction();
69+
expect(startTransactionSpy).not.toHaveBeenCalled();
70+
});
71+
72+
it('should return a function that starts a span on the current transaction with the correct description when there is an active transaction and no request is being passed', async () => {
73+
const testTransaction = coreSdk.startTransaction({ name: 'testTransaction' });
74+
coreSdk.getCurrentHub().getScope()?.setSpan(testTransaction);
75+
76+
const startChildSpy = jest.spyOn(testTransaction, 'startChild');
77+
78+
const origFunctionReturnValue = new Response();
79+
const origFunction = jest.fn(() => origFunctionReturnValue);
80+
81+
const wrappedFunction = withSentryAPI(origFunction, '/user/[userId]/post/[postId]');
82+
83+
await wrappedFunction();
84+
expect(startChildSpy).toHaveBeenCalledTimes(1);
85+
expect(startChildSpy).toHaveBeenCalledWith(
86+
expect.objectContaining({
87+
description: 'handler (/user/[userId]/post/[postId])',
88+
op: 'function',
89+
}),
90+
);
91+
92+
testTransaction.finish();
93+
coreSdk.getCurrentHub().getScope()?.setSpan(undefined);
94+
});
95+
});

0 commit comments

Comments
 (0)