Skip to content

Commit a340b5c

Browse files
author
Luca Forstner
committed
Add test to check if Router.events.off was called
1 parent 53b5021 commit a340b5c

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

packages/nextjs/test/performance/client.test.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Transaction } from '@sentry/types';
12
import { getGlobalObject } from '@sentry/utils';
23
import { JSDOM } from 'jsdom';
34
import { NEXT_DATA as NextData } from 'next/dist/next-server/lib/utils';
@@ -16,18 +17,24 @@ const globalObject = getGlobalObject<
1617
const originalBuildManifest = globalObject.__BUILD_MANIFEST;
1718
const originalBuildManifestRoutes = globalObject.__BUILD_MANIFEST?.sortedPages;
1819

20+
let eventHandlers: { [eventName: string]: Set<(...args: any[]) => void> } = {};
21+
1922
jest.mock('next/router', () => {
20-
const eventHandlers: { [eventName: string]: ((...args: any[]) => void)[] } = {};
2123
return {
2224
default: {
2325
events: {
2426
on(type: string, handler: (...args: any[]) => void) {
25-
if (eventHandlers[type]) {
26-
eventHandlers[type].push(handler);
27-
} else {
28-
eventHandlers[type] = [handler];
27+
if (!eventHandlers[type]) {
28+
eventHandlers[type] = new Set();
2929
}
30+
31+
eventHandlers[type].add(handler);
3032
},
33+
off: jest.fn((type: string, handler: (...args: any[]) => void) => {
34+
if (eventHandlers[type]) {
35+
eventHandlers[type].delete(handler);
36+
}
37+
}),
3138
emit(type: string, ...eventArgs: any[]) {
3239
if (eventHandlers[type]) {
3340
eventHandlers[type].forEach(eventHandler => {
@@ -40,6 +47,18 @@ jest.mock('next/router', () => {
4047
};
4148
});
4249

50+
function createMockStartTransaction() {
51+
return jest.fn(
52+
() =>
53+
({
54+
startChild: () => ({
55+
finish: () => undefined,
56+
}),
57+
finish: () => undefined,
58+
} as Transaction),
59+
);
60+
}
61+
4362
describe('nextRouterInstrumentation', () => {
4463
const originalGlobalDocument = getGlobalObject<Window>().document;
4564
const originalGlobalLocation = getGlobalObject<Window>().location;
@@ -94,6 +113,12 @@ describe('nextRouterInstrumentation', () => {
94113
if ((global as any).__BUILD_MANIFEST) {
95114
(global as any).__BUILD_MANIFEST.sortedPages = originalBuildManifestRoutes;
96115
}
116+
117+
// Clear all event handlers
118+
eventHandlers = {};
119+
120+
// Necessary to clear all Router.events.off() mock call numbers
121+
jest.clearAllMocks();
97122
});
98123

99124
describe('pageload transactions', () => {
@@ -187,7 +212,7 @@ describe('nextRouterInstrumentation', () => {
187212
])(
188213
'creates a pageload transaction (#%#)',
189214
(url, route, query, props, hasNextData, expectedStartTransactionArgument) => {
190-
const mockStartTransaction = jest.fn();
215+
const mockStartTransaction = createMockStartTransaction();
191216
setUpNextPage({ url, route, query, props, hasNextData });
192217
nextRouterInstrumentation(mockStartTransaction);
193218
expect(mockStartTransaction).toHaveBeenCalledTimes(1);
@@ -196,7 +221,7 @@ describe('nextRouterInstrumentation', () => {
196221
);
197222

198223
it('does not create a pageload transaction if option not given', () => {
199-
const mockStartTransaction = jest.fn();
224+
const mockStartTransaction = createMockStartTransaction();
200225
setUpNextPage({ url: 'https://example.com/', route: '/', hasNextData: false });
201226
nextRouterInstrumentation(mockStartTransaction, false);
202227
expect(mockStartTransaction).toHaveBeenCalledTimes(0);
@@ -225,7 +250,7 @@ describe('nextRouterInstrumentation', () => {
225250
])(
226251
'should create a parameterized transaction on route change (%s)',
227252
(targetLocation, expectedTransactionName, expectedTransactionSource) => {
228-
const mockStartTransaction = jest.fn();
253+
const mockStartTransaction = createMockStartTransaction();
229254

230255
setUpNextPage({
231256
url: 'https://example.com/home',
@@ -261,11 +286,17 @@ describe('nextRouterInstrumentation', () => {
261286
}),
262287
}),
263288
);
289+
290+
Router.events.emit('routeChangeComplete', targetLocation);
291+
// eslint-disable-next-line @typescript-eslint/unbound-method
292+
expect(Router.events.off).toHaveBeenCalledWith('routeChangeComplete', expect.anything());
293+
// eslint-disable-next-line @typescript-eslint/unbound-method
294+
expect(Router.events.off).toHaveBeenCalledTimes(1);
264295
},
265296
);
266297

267298
it('should not create transaction when navigation transactions are disabled', () => {
268-
const mockStartTransaction = jest.fn();
299+
const mockStartTransaction = createMockStartTransaction();
269300

270301
setUpNextPage({
271302
url: 'https://example.com/home',

0 commit comments

Comments
 (0)