Skip to content

Commit c174908

Browse files
committed
tests: added unit tests
1 parent 85bb357 commit c174908

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { GLOBAL_OBJ } from '@sentry/core';
2+
import { beforeEach, describe, expect, it, vi } from 'vitest';
3+
import { waitUntil } from '../../../src/common/utils/responseEnd';
4+
5+
vi.mock('@sentry/core', async () => {
6+
const actual = await vi.importActual('@sentry/core');
7+
return {
8+
...actual,
9+
debug: {
10+
log: vi.fn(),
11+
},
12+
flush: vi.fn(),
13+
vercelWaitUntil: vi.fn(),
14+
};
15+
});
16+
17+
describe('responseEnd utils', () => {
18+
beforeEach(() => {
19+
vi.clearAllMocks();
20+
// Clear Cloudflare context
21+
const cfContextSymbol = Symbol.for('__cloudflare-context__');
22+
(GLOBAL_OBJ as any)[cfContextSymbol] = undefined;
23+
// Clear Vercel context
24+
const vercelContextSymbol = Symbol.for('@vercel/request-context');
25+
(GLOBAL_OBJ as any)[vercelContextSymbol] = undefined;
26+
});
27+
28+
describe('waitUntil', () => {
29+
it('should use cloudflareWaitUntil when Cloudflare context is available', async () => {
30+
const cfContextSymbol = Symbol.for('__cloudflare-context__');
31+
const cfWaitUntilMock = vi.fn();
32+
(GLOBAL_OBJ as any)[cfContextSymbol] = {
33+
ctx: {
34+
waitUntil: cfWaitUntilMock,
35+
},
36+
};
37+
38+
const testTask = Promise.resolve('test');
39+
waitUntil(testTask);
40+
41+
expect(cfWaitUntilMock).toHaveBeenCalledWith(testTask);
42+
expect(cfWaitUntilMock).toHaveBeenCalledTimes(1);
43+
44+
// Should not call vercelWaitUntil when Cloudflare is available
45+
const { vercelWaitUntil } = await import('@sentry/core');
46+
expect(vercelWaitUntil).not.toHaveBeenCalled();
47+
});
48+
49+
it('should use vercelWaitUntil when Cloudflare context is not available', async () => {
50+
const { vercelWaitUntil } = await import('@sentry/core');
51+
const testTask = Promise.resolve('test');
52+
53+
waitUntil(testTask);
54+
55+
expect(vercelWaitUntil).toHaveBeenCalledWith(testTask);
56+
expect(vercelWaitUntil).toHaveBeenCalledTimes(1);
57+
});
58+
59+
it('should prefer Cloudflare over Vercel when both are available', async () => {
60+
// Set up Cloudflare context
61+
const cfContextSymbol = Symbol.for('__cloudflare-context__');
62+
const cfWaitUntilMock = vi.fn();
63+
(GLOBAL_OBJ as any)[cfContextSymbol] = {
64+
ctx: {
65+
waitUntil: cfWaitUntilMock,
66+
},
67+
};
68+
69+
// Set up Vercel context
70+
const vercelWaitUntilMock = vi.fn();
71+
(GLOBAL_OBJ as any)[Symbol.for('@vercel/request-context')] = {
72+
get: () => ({ waitUntil: vercelWaitUntilMock }),
73+
};
74+
75+
const testTask = Promise.resolve('test');
76+
waitUntil(testTask);
77+
78+
// Should use Cloudflare
79+
expect(cfWaitUntilMock).toHaveBeenCalledWith(testTask);
80+
expect(cfWaitUntilMock).toHaveBeenCalledTimes(1);
81+
82+
// Should not use Vercel
83+
const { vercelWaitUntil } = await import('@sentry/core');
84+
expect(vercelWaitUntil).not.toHaveBeenCalled();
85+
});
86+
87+
it('should handle errors gracefully when waitUntil is called with a rejected promise', async () => {
88+
const { vercelWaitUntil } = await import('@sentry/core');
89+
const testTask = Promise.reject(new Error('test error'));
90+
91+
// Should not throw synchronously
92+
expect(() => waitUntil(testTask)).not.toThrow();
93+
expect(vercelWaitUntil).toHaveBeenCalledWith(testTask);
94+
95+
// Prevent unhandled rejection in test
96+
testTask.catch(() => {});
97+
});
98+
});
99+
});

0 commit comments

Comments
 (0)