Skip to content

Commit ccec612

Browse files
committed
add tests
1 parent a23f2ca commit ccec612

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* @vitest-environment jsdom
3+
*/
4+
5+
import type { Client } from '@sentry/core';
6+
import * as sentryCore from '@sentry/core';
7+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8+
import { diagnoseSdkConnectivity } from '../src/diagnose-sdk';
9+
10+
// Mock the @sentry/core module
11+
vi.mock('@sentry/core', async requireActual => {
12+
return {
13+
...((await requireActual()) as any),
14+
getClient: vi.fn(),
15+
};
16+
});
17+
18+
// Mock global fetch
19+
const mockFetch = vi.fn();
20+
global.fetch = mockFetch;
21+
22+
describe('diagnoseSdkConnectivity', () => {
23+
const mockGetClient = sentryCore.getClient as any;
24+
25+
beforeEach(() => {
26+
vi.clearAllMocks();
27+
});
28+
29+
afterEach(() => {
30+
vi.clearAllMocks();
31+
});
32+
33+
it('returns "no-client-active" when no client is active', async () => {
34+
mockGetClient.mockReturnValue(undefined);
35+
36+
const result = await diagnoseSdkConnectivity();
37+
38+
expect(result).toBe('no-client-active');
39+
expect(mockFetch).not.toHaveBeenCalled();
40+
});
41+
42+
it('returns "no-dsn-configured" when client.getDsn() returns undefined', async () => {
43+
const mockClient: Partial<Client> = {
44+
getDsn: vi.fn().mockReturnValue(undefined),
45+
};
46+
mockGetClient.mockReturnValue(mockClient);
47+
48+
const result = await diagnoseSdkConnectivity();
49+
50+
expect(result).toBe('no-dsn-configured');
51+
expect(mockClient.getDsn).toHaveBeenCalled();
52+
expect(mockFetch).not.toHaveBeenCalled();
53+
});
54+
55+
it('returns "sentry-unreachable" when fetch throws an error', async () => {
56+
const mockClient: Partial<Client> = {
57+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
58+
};
59+
mockGetClient.mockReturnValue(mockClient);
60+
mockFetch.mockRejectedValue(new Error('Network error'));
61+
62+
const result = await diagnoseSdkConnectivity();
63+
64+
expect(result).toBe('sentry-unreachable');
65+
expect(mockClient.getDsn).toHaveBeenCalled();
66+
expect(mockFetch).toHaveBeenCalledWith(
67+
'https://o447951.ingest.sentry.io/api/4509632503087104/envelope/?sentry_version=7&sentry_key=c1dfb07d783ad5325c245c1fd3725390&sentry_client=sentry.javascript.browser%2F1.33.7',
68+
{
69+
body: '{}',
70+
method: 'POST',
71+
mode: 'cors',
72+
credentials: 'omit',
73+
},
74+
);
75+
});
76+
77+
it('returns "sentry-unreachable" when fetch throws a TypeError (common for network issues)', async () => {
78+
const mockClient: Partial<Client> = {
79+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
80+
};
81+
mockGetClient.mockReturnValue(mockClient);
82+
mockFetch.mockRejectedValue(new TypeError('Failed to fetch'));
83+
84+
const result = await diagnoseSdkConnectivity();
85+
86+
expect(result).toBe('sentry-unreachable');
87+
expect(mockClient.getDsn).toHaveBeenCalled();
88+
expect(mockFetch).toHaveBeenCalled();
89+
});
90+
91+
it('returns undefined when connectivity check succeeds', async () => {
92+
const mockClient: Partial<Client> = {
93+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
94+
};
95+
mockGetClient.mockReturnValue(mockClient);
96+
mockFetch.mockResolvedValue(new Response('{}', { status: 200 }));
97+
98+
const result = await diagnoseSdkConnectivity();
99+
100+
expect(result).toBeUndefined();
101+
expect(mockClient.getDsn).toHaveBeenCalled();
102+
expect(mockFetch).toHaveBeenCalledWith(
103+
'https://o447951.ingest.sentry.io/api/4509632503087104/envelope/?sentry_version=7&sentry_key=c1dfb07d783ad5325c245c1fd3725390&sentry_client=sentry.javascript.browser%2F1.33.7',
104+
{
105+
body: '{}',
106+
method: 'POST',
107+
mode: 'cors',
108+
credentials: 'omit',
109+
},
110+
);
111+
});
112+
113+
it('returns undefined even when fetch returns an error status (4xx, 5xx)', async () => {
114+
const mockClient: Partial<Client> = {
115+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
116+
};
117+
mockGetClient.mockReturnValue(mockClient);
118+
// Mock a 403 response (expected since the DSN is disabled)
119+
mockFetch.mockResolvedValue(new Response('Forbidden', { status: 403 }));
120+
121+
const result = await diagnoseSdkConnectivity();
122+
123+
// The function only cares about fetch not throwing, not the response status
124+
expect(result).toBeUndefined();
125+
expect(mockClient.getDsn).toHaveBeenCalled();
126+
expect(mockFetch).toHaveBeenCalled();
127+
});
128+
129+
it('uses the correct test endpoint URL', async () => {
130+
const mockClient: Partial<Client> = {
131+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
132+
};
133+
mockGetClient.mockReturnValue(mockClient);
134+
mockFetch.mockResolvedValue(new Response('{}', { status: 200 }));
135+
136+
await diagnoseSdkConnectivity();
137+
138+
expect(mockFetch).toHaveBeenCalledWith(
139+
'https://o447951.ingest.sentry.io/api/4509632503087104/envelope/?sentry_version=7&sentry_key=c1dfb07d783ad5325c245c1fd3725390&sentry_client=sentry.javascript.browser%2F1.33.7',
140+
expect.objectContaining({
141+
body: '{}',
142+
method: 'POST',
143+
mode: 'cors',
144+
credentials: 'omit',
145+
}),
146+
);
147+
});
148+
149+
it('uses correct fetch options', async () => {
150+
const mockClient: Partial<Client> = {
151+
getDsn: vi.fn().mockReturnValue('https://[email protected]/123'),
152+
};
153+
mockGetClient.mockReturnValue(mockClient);
154+
mockFetch.mockResolvedValue(new Response('{}', { status: 200 }));
155+
156+
await diagnoseSdkConnectivity();
157+
158+
expect(mockFetch).toHaveBeenCalledWith(expect.any(String), {
159+
body: '{}',
160+
method: 'POST',
161+
mode: 'cors',
162+
credentials: 'omit',
163+
});
164+
});
165+
});

0 commit comments

Comments
 (0)