Skip to content

Commit 2c6342c

Browse files
committed
Added tests
1 parent 4902d86 commit 2c6342c

File tree

4 files changed

+593
-1
lines changed

4 files changed

+593
-1
lines changed

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is generated by scripts/exportVersion.js
2-
export const SDK_VERSION = '17.13.1-canary.4';
2+
export const SDK_VERSION = '7.13.1';
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/**
2+
* Tests for CJS fetchWrapper implementation
3+
*/
4+
5+
// Import types are only used for dynamic imports in tests, so we don't import them here
6+
// The functions are imported dynamically within each test to ensure proper module isolation
7+
8+
// Mock the dynamic import to avoid actually importing node-fetch
9+
const mockNodeFetch = {
10+
default: jest.fn().mockName('mockFetch'),
11+
Request: jest.fn().mockName('mockRequest'),
12+
Response: jest.fn().mockName('mockResponse'),
13+
};
14+
15+
// Mock the Function constructor used for dynamic imports
16+
const mockDynamicImport = jest.fn().mockResolvedValue(mockNodeFetch);
17+
global.Function = jest.fn().mockImplementation(() => mockDynamicImport);
18+
19+
// Mock global objects for test environment detection
20+
const originalGlobal = global;
21+
22+
describe('fetchWrapper-cjs', () => {
23+
beforeEach(() => {
24+
jest.clearAllMocks();
25+
// Reset the module cache by clearing the nodeFetchModule cache
26+
// This is done by reimporting the module
27+
jest.resetModules();
28+
// Setup mocked Function constructor
29+
global.Function = jest.fn().mockImplementation(() => mockDynamicImport);
30+
// Reset mock implementation
31+
mockDynamicImport.mockResolvedValue(mockNodeFetch);
32+
});
33+
34+
describe('getFetch', () => {
35+
it('should return global.fetch when in test environment', async () => {
36+
const mockGlobalFetch = jest.fn().mockName('globalFetch');
37+
(global as any).fetch = mockGlobalFetch;
38+
39+
const { getFetch } = await import('../../src/utils/fetchWrapper-cjs.js');
40+
const fetch = await getFetch();
41+
42+
expect(fetch).toBe(mockGlobalFetch);
43+
});
44+
45+
it('should use dynamic import when global.fetch is not available', async () => {
46+
// Remove global.fetch
47+
delete (global as any).fetch;
48+
49+
const { getFetch } = await import('../../src/utils/fetchWrapper-cjs.js');
50+
const fetch = await getFetch();
51+
52+
expect(fetch).toBe(mockNodeFetch.default);
53+
});
54+
55+
it('should return a function', async () => {
56+
delete (global as any).fetch;
57+
58+
const { getFetch } = await import('../../src/utils/fetchWrapper-cjs.js');
59+
const fetch = await getFetch();
60+
61+
expect(typeof fetch).toBe('function');
62+
});
63+
64+
it('should handle Function constructor usage', async () => {
65+
delete (global as any).fetch;
66+
67+
const { getFetch } = await import('../../src/utils/fetchWrapper-cjs.js');
68+
await getFetch();
69+
70+
// Verify Function constructor was called
71+
expect(global.Function).toHaveBeenCalled();
72+
});
73+
});
74+
75+
describe('getRequest', () => {
76+
it('should return global.Request when in test environment', async () => {
77+
const mockGlobalRequest = jest.fn().mockName('globalRequest');
78+
(global as any).Request = mockGlobalRequest;
79+
80+
const { getRequest } = await import(
81+
'../../src/utils/fetchWrapper-cjs.js'
82+
);
83+
const Request = await getRequest();
84+
85+
expect(Request).toBe(mockGlobalRequest);
86+
});
87+
88+
it('should use dynamic import when global.Request is not available', async () => {
89+
delete (global as any).Request;
90+
91+
const { getRequest } = await import(
92+
'../../src/utils/fetchWrapper-cjs.js'
93+
);
94+
const Request = await getRequest();
95+
96+
expect(Request).toBe(mockNodeFetch.Request);
97+
});
98+
99+
it('should return a function', async () => {
100+
delete (global as any).Request;
101+
102+
const { getRequest } = await import(
103+
'../../src/utils/fetchWrapper-cjs.js'
104+
);
105+
const Request = await getRequest();
106+
107+
expect(typeof Request).toBe('function');
108+
});
109+
});
110+
111+
describe('getResponse', () => {
112+
it('should return global.Response when in test environment', async () => {
113+
const mockGlobalResponse = jest.fn().mockName('globalResponse');
114+
(global as any).Response = mockGlobalResponse;
115+
116+
const { getResponse } = await import(
117+
'../../src/utils/fetchWrapper-cjs.js'
118+
);
119+
const Response = await getResponse();
120+
121+
expect(Response).toBe(mockGlobalResponse);
122+
});
123+
124+
it('should use dynamic import when global.Response is not available', async () => {
125+
delete (global as any).Response;
126+
127+
const { getResponse } = await import(
128+
'../../src/utils/fetchWrapper-cjs.js'
129+
);
130+
const Response = await getResponse();
131+
132+
expect(Response).toBe(mockNodeFetch.Response);
133+
});
134+
135+
it('should return a function', async () => {
136+
delete (global as any).Response;
137+
138+
const { getResponse } = await import(
139+
'../../src/utils/fetchWrapper-cjs.js'
140+
);
141+
const Response = await getResponse();
142+
143+
expect(typeof Response).toBe('function');
144+
});
145+
});
146+
147+
describe('mixed environment scenarios', () => {
148+
it('should prefer global objects when available, fall back to dynamic import for missing ones', async () => {
149+
const mockGlobalFetch = jest.fn().mockName('globalFetch');
150+
(global as any).fetch = mockGlobalFetch;
151+
delete (global as any).Request;
152+
delete (global as any).Response;
153+
154+
const { getFetch, getRequest, getResponse } = await import(
155+
'../../src/utils/fetchWrapper-cjs.js'
156+
);
157+
158+
const fetch = await getFetch();
159+
const Request = await getRequest();
160+
const Response = await getResponse();
161+
162+
// fetch should use global
163+
expect(fetch).toBe(mockGlobalFetch);
164+
165+
// Request and Response should use dynamic import
166+
expect(Request).toBe(mockNodeFetch.Request);
167+
expect(Response).toBe(mockNodeFetch.Response);
168+
});
169+
170+
it('should handle undefined global object gracefully', async () => {
171+
// Simulate environment where global might be undefined
172+
const originalGlobal = global;
173+
(global as any) = undefined;
174+
175+
const { getFetch } = await import('../../src/utils/fetchWrapper-cjs.js');
176+
const fetch = await getFetch();
177+
178+
expect(fetch).toBe(mockNodeFetch.default);
179+
180+
// Restore global
181+
(global as any) = originalGlobal;
182+
});
183+
});
184+
185+
describe('Type exports', () => {
186+
it('should export types as any for CJS compatibility', () => {
187+
// This test ensures that the types are properly exported as 'any'
188+
// The actual type checking happens at compile time
189+
expect(true).toBe(true);
190+
});
191+
});
192+
193+
afterEach(() => {
194+
// Clean up global modifications
195+
delete (global as any).fetch;
196+
delete (global as any).Request;
197+
delete (global as any).Response;
198+
// Restore original Function constructor if needed
199+
if (originalGlobal.Function) {
200+
global.Function = originalGlobal.Function;
201+
}
202+
});
203+
});
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* Tests for ESM fetchWrapper implementation
3+
*/
4+
5+
import {
6+
getFetch,
7+
getRequest,
8+
getResponse,
9+
} from '../../src/utils/fetchWrapper-esm.js';
10+
11+
describe('fetchWrapper-esm', () => {
12+
describe('getFetch', () => {
13+
it('should return the node-fetch function', async () => {
14+
const fetch = await getFetch();
15+
expect(typeof fetch).toBe('function');
16+
// The actual function name might vary, just check it's a function
17+
expect(fetch).toBeDefined();
18+
});
19+
20+
it('should return the same fetch function on multiple calls', async () => {
21+
const fetch1 = await getFetch();
22+
const fetch2 = await getFetch();
23+
expect(fetch1).toBe(fetch2);
24+
});
25+
26+
it('should be able to make a basic fetch request', async () => {
27+
const fetch = await getFetch();
28+
29+
// We can't actually make HTTP requests in tests, but we can verify
30+
// the fetch function has the expected interface
31+
expect(fetch).toBeDefined();
32+
expect(typeof fetch).toBe('function');
33+
});
34+
});
35+
36+
describe('getRequest', () => {
37+
it('should return the Request constructor', async () => {
38+
const Request = await getRequest();
39+
expect(typeof Request).toBe('function');
40+
// The actual function name might vary, just check it's a constructor
41+
expect(Request).toBeDefined();
42+
});
43+
44+
it('should return the same Request constructor on multiple calls', async () => {
45+
const Request1 = await getRequest();
46+
const Request2 = await getRequest();
47+
expect(Request1).toBe(Request2);
48+
});
49+
50+
it('should be able to create a Request instance', async () => {
51+
const RequestConstructor = await getRequest();
52+
const request = new RequestConstructor('https://example.com', {
53+
method: 'POST',
54+
headers: {
55+
'Content-Type': 'application/json',
56+
},
57+
body: JSON.stringify({ test: 'data' }),
58+
});
59+
60+
expect(request).toBeInstanceOf(RequestConstructor);
61+
expect(request.url).toBe('https://example.com/');
62+
expect(request.method).toBe('POST');
63+
expect(request.headers.get('content-type')).toBe('application/json');
64+
});
65+
66+
it('should create Request with different HTTP methods', async () => {
67+
const RequestConstructor = await getRequest();
68+
69+
const getReq = new RequestConstructor('https://example.com', {
70+
method: 'GET',
71+
});
72+
const postReq = new RequestConstructor('https://example.com', {
73+
method: 'POST',
74+
});
75+
const putReq = new RequestConstructor('https://example.com', {
76+
method: 'PUT',
77+
});
78+
const deleteReq = new RequestConstructor('https://example.com', {
79+
method: 'DELETE',
80+
});
81+
82+
expect(getReq.method).toBe('GET');
83+
expect(postReq.method).toBe('POST');
84+
expect(putReq.method).toBe('PUT');
85+
expect(deleteReq.method).toBe('DELETE');
86+
});
87+
88+
it('should handle Request with custom headers', async () => {
89+
const RequestConstructor = await getRequest();
90+
const request = new RequestConstructor('https://example.com', {
91+
headers: {
92+
Authorization: 'Bearer token',
93+
'X-Custom-Header': 'custom-value',
94+
},
95+
});
96+
97+
expect(request.headers.get('authorization')).toBe('Bearer token');
98+
expect(request.headers.get('x-custom-header')).toBe('custom-value');
99+
});
100+
});
101+
102+
describe('getResponse', () => {
103+
it('should return the Response constructor', async () => {
104+
const Response = await getResponse();
105+
expect(typeof Response).toBe('function');
106+
// The actual function name might vary, just check it's a constructor
107+
expect(Response).toBeDefined();
108+
});
109+
110+
it('should return the same Response constructor on multiple calls', async () => {
111+
const Response1 = await getResponse();
112+
const Response2 = await getResponse();
113+
expect(Response1).toBe(Response2);
114+
});
115+
116+
it('should be able to create a Response instance', async () => {
117+
const ResponseConstructor = await getResponse();
118+
const response = new ResponseConstructor('{"test": "data"}', {
119+
status: 200,
120+
statusText: 'OK',
121+
headers: {
122+
'Content-Type': 'application/json',
123+
},
124+
});
125+
126+
// Check that response has the expected properties instead of instanceof check
127+
expect(response.status).toBeDefined();
128+
expect(response.headers).toBeDefined();
129+
expect(response.status).toBe(200);
130+
expect(response.statusText).toBe('OK');
131+
expect(response.headers.get('content-type')).toBe('application/json');
132+
133+
const json = await response.json();
134+
expect(json).toEqual({ test: 'data' });
135+
});
136+
137+
it('should create Response with different status codes', async () => {
138+
const ResponseConstructor = await getResponse();
139+
140+
const okResponse = new ResponseConstructor('OK', { status: 200 });
141+
const notFoundResponse = new ResponseConstructor('Not Found', {
142+
status: 404,
143+
});
144+
const serverErrorResponse = new ResponseConstructor('Server Error', {
145+
status: 500,
146+
});
147+
148+
expect(okResponse.status).toBe(200);
149+
expect(okResponse.ok).toBe(true);
150+
151+
expect(notFoundResponse.status).toBe(404);
152+
expect(notFoundResponse.ok).toBe(false);
153+
154+
expect(serverErrorResponse.status).toBe(500);
155+
expect(serverErrorResponse.ok).toBe(false);
156+
});
157+
158+
it('should handle Response with different content types', async () => {
159+
const ResponseConstructor = await getResponse();
160+
161+
const jsonResponse = new ResponseConstructor('{"key": "value"}', {
162+
headers: { 'Content-Type': 'application/json' },
163+
});
164+
165+
const textResponse = new ResponseConstructor('plain text', {
166+
headers: { 'Content-Type': 'text/plain' },
167+
});
168+
169+
expect(jsonResponse.headers.get('content-type')).toBe('application/json');
170+
expect(textResponse.headers.get('content-type')).toBe('text/plain');
171+
172+
const jsonData = await jsonResponse.json();
173+
expect(jsonData).toEqual({ key: 'value' });
174+
175+
const textData = await textResponse.text();
176+
expect(textData).toBe('plain text');
177+
});
178+
});
179+
180+
describe('Type exports', () => {
181+
it('should have proper TypeScript types available', () => {
182+
// This test ensures that the types are properly exported
183+
// The actual type checking happens at compile time
184+
expect(true).toBe(true);
185+
});
186+
});
187+
});

0 commit comments

Comments
 (0)