Skip to content

Commit 9593ed0

Browse files
committed
add tests for serverRequest
1 parent 2bf40a8 commit 9593ed0

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { vi, describe, test, expect, beforeEach } from 'vitest';
2+
import serverRequest from './index';
3+
import { ServerRequest, Status } from '@vue-skuilder/common';
4+
5+
// Create a minimal type that matches ServerRequest for testing
6+
type TestRequest = ServerRequest & {
7+
type: 'TEST_REQUEST';
8+
timeout?: number;
9+
};
10+
11+
describe('serverRequest', () => {
12+
let mockXHR: {
13+
open: ReturnType<typeof vi.fn>;
14+
send: ReturnType<typeof vi.fn>;
15+
setRequestHeader: ReturnType<typeof vi.fn>;
16+
withCredentials: boolean;
17+
onload?: () => void;
18+
ontimeout?: () => void;
19+
onerror?: () => void;
20+
readyState?: number;
21+
status?: number;
22+
responseText?: string;
23+
};
24+
25+
beforeEach(() => {
26+
mockXHR = {
27+
open: vi.fn(),
28+
send: vi.fn(),
29+
setRequestHeader: vi.fn(),
30+
withCredentials: false,
31+
};
32+
33+
global.XMLHttpRequest = vi.fn(() => mockXHR) as any;
34+
});
35+
36+
test('configures XMLHttpRequest correctly', async () => {
37+
// Set up the mock to do nothing on send
38+
mockXHR.send = vi.fn();
39+
40+
// Create a promise that resolves when onload is called
41+
const responsePromise = new Promise<void>((resolve) => {
42+
mockXHR.onload = () => resolve();
43+
});
44+
45+
// Start the request but don't wait for it
46+
const requestPromise = serverRequest<TestRequest>({ type: 'TEST_REQUEST' });
47+
48+
// Check that XMLHttpRequest was configured correctly
49+
expect(mockXHR.open).toHaveBeenCalledWith('POST', expect.any(String), true);
50+
expect(mockXHR.withCredentials).toBe(true);
51+
expect(mockXHR.setRequestHeader).toHaveBeenCalledWith('Content-Type', 'application/json');
52+
expect(mockXHR.timeout).toBe(7000);
53+
expect(mockXHR.send).toHaveBeenCalledWith(JSON.stringify({ type: 'TEST_REQUEST' }));
54+
55+
// Simulate successful response after validation
56+
mockXHR.responseText = JSON.stringify({ data: 'test', ok: true });
57+
mockXHR.onload && mockXHR.onload();
58+
59+
// Wait for the request to complete
60+
const result = await requestPromise;
61+
62+
// Verify the result
63+
expect(result.response).toEqual({ data: 'test', ok: true });
64+
});
65+
66+
test('handles successful response', async () => {
67+
const responseData = { status: Status.success, ok: true, data: { id: '123' } };
68+
69+
// Create a promise that will complete when onload is triggered
70+
const requestPromise = serverRequest<TestRequest>({ type: 'TEST_REQUEST' });
71+
72+
// Simulate a successful response
73+
mockXHR.responseText = JSON.stringify(responseData);
74+
mockXHR.onload && mockXHR.onload();
75+
76+
// Wait for the request to complete
77+
const result = await requestPromise;
78+
79+
// Verify the response was processed correctly
80+
expect(result.response).toEqual(responseData);
81+
});
82+
83+
test('handles JSON parse error in response', async () => {
84+
// Create a promise that will complete when onload is triggered
85+
const requestPromise = serverRequest<TestRequest>({ type: 'TEST_REQUEST' });
86+
87+
// Simulate an invalid JSON response
88+
mockXHR.responseText = 'Not valid JSON';
89+
mockXHR.onload && mockXHR.onload();
90+
91+
// Wait for the request to complete
92+
const result = await requestPromise;
93+
94+
// Verify error handling
95+
expect(result.response).toEqual({
96+
status: Status.error,
97+
ok: false,
98+
errorText: expect.stringContaining('Failed to parse response'),
99+
});
100+
});
101+
102+
test('handles request timeout', async () => {
103+
// Create a request with custom timeout
104+
const requestPromise = serverRequest<TestRequest>({
105+
type: 'TEST_REQUEST',
106+
timeout: 5000,
107+
});
108+
109+
// Verify timeout is set correctly
110+
expect(mockXHR.timeout).toBe(5000);
111+
112+
// Simulate timeout
113+
mockXHR.ontimeout && mockXHR.ontimeout();
114+
115+
// Wait for the request to complete
116+
const result = await requestPromise;
117+
118+
// Verify timeout handling
119+
expect(result.response).toEqual({
120+
status: Status.error,
121+
ok: false,
122+
errorText: 'Request timed out',
123+
});
124+
});
125+
126+
test('handles network error', async () => {
127+
// Create a request
128+
const requestPromise = serverRequest<TestRequest>({ type: 'TEST_REQUEST' });
129+
130+
// Simulate network error
131+
mockXHR.onerror && mockXHR.onerror();
132+
133+
// Wait for the request to complete
134+
const result = await requestPromise;
135+
136+
// Verify error handling
137+
expect(result.response).toEqual({
138+
status: Status.error,
139+
ok: false,
140+
errorText: 'Network error occurred',
141+
});
142+
});
143+
144+
test('handles exception during request setup', async () => {
145+
// Make XMLHttpRequest.open throw an error
146+
mockXHR.open = vi.fn().mockImplementation(() => {
147+
throw new Error('Connection refused');
148+
});
149+
150+
// Make the request which should catch the error
151+
const result = await serverRequest<TestRequest>({ type: 'TEST_REQUEST' });
152+
153+
// Verify error is caught and handled
154+
expect(result.response).toEqual({
155+
status: Status.error,
156+
ok: false,
157+
errorText: 'Connection refused',
158+
});
159+
});
160+
});

packages/vue/src/server/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import { ServerRequest } from '@vue-skuilder/common';
44

55
const SERVER = ENV.EXPRESS_SERVER_PROTOCOL + '://' + ENV.EXPRESS_SERVER_URL;
66

7+
/**
8+
* Makes an authenticated request to the express backend and returns the response.
9+
10+
* @param requestData
11+
* @returns
12+
*/
713
export default async function serverRequest<T extends ServerRequest>(requestData: T): Promise<T> {
814
return new Promise<T>((resolve) => {
915
try {

0 commit comments

Comments
 (0)