Skip to content

Commit a2cfaea

Browse files
committed
test: request-event redirect
1 parent fcf83ef commit a2cfaea

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { describe, it, expect, vi } from 'vitest';
2+
import { createRequestEvent } from './request-event';
3+
import { RedirectMessage } from './redirect-handler';
4+
import type { ServerRequestEvent, QwikSerializer } from './types';
5+
6+
const mockQwikSerializer: QwikSerializer = {
7+
_deserializeData: vi.fn(),
8+
_serializeData: vi.fn(),
9+
_verifySerializable: vi.fn(),
10+
};
11+
12+
function createMockServerRequestEvent(url = 'http://localhost:3000/test'): ServerRequestEvent {
13+
const mockRequest = new Request(url);
14+
15+
return {
16+
mode: 'server',
17+
url: new URL(url),
18+
locale: undefined,
19+
platform: {},
20+
request: mockRequest,
21+
env: {
22+
get: vi.fn(),
23+
},
24+
getClientConn: vi.fn(() => ({ ip: '127.0.0.1' })),
25+
getWritableStream: vi.fn(() => {
26+
const writer = {
27+
write: vi.fn(),
28+
close: vi.fn(),
29+
};
30+
return {
31+
getWriter: () => writer,
32+
locked: false,
33+
pipeTo: vi.fn(),
34+
} as any;
35+
}),
36+
};
37+
}
38+
39+
describe('request-event redirect', () => {
40+
it('should not cache redirects by default', () => {
41+
const serverRequestEv = createMockServerRequestEvent();
42+
const requestEv = createRequestEvent(
43+
serverRequestEv,
44+
null,
45+
[],
46+
true,
47+
'/',
48+
mockQwikSerializer,
49+
vi.fn()
50+
);
51+
52+
requestEv.headers.set('Cache-Control', 'max-age=3600, public');
53+
54+
const result = requestEv.redirect(301, '/new-location');
55+
56+
expect(result).toBeInstanceOf(RedirectMessage);
57+
expect(requestEv.headers.get('Location')).toBe('/new-location');
58+
expect(requestEv.headers.get('Cache-Control')).toBeNull();
59+
expect(requestEv.status()).toBe(301);
60+
});
61+
62+
it('should set Cache-Control to no-store for redirects with status > 301', () => {
63+
const serverRequestEv = createMockServerRequestEvent();
64+
const requestEv = createRequestEvent(
65+
serverRequestEv,
66+
null,
67+
[],
68+
true,
69+
'/',
70+
mockQwikSerializer,
71+
vi.fn()
72+
);
73+
74+
const result = requestEv.redirect(307, '/new-location');
75+
76+
expect(result).toBeInstanceOf(RedirectMessage);
77+
expect(requestEv.headers.get('Location')).toBe('/new-location');
78+
expect(requestEv.headers.get('Cache-Control')).toBe('no-store');
79+
expect(requestEv.status()).toBe(307);
80+
});
81+
82+
it('should fix invalid redirect URLs with multiple slashes', () => {
83+
const serverRequestEv = createMockServerRequestEvent();
84+
const requestEv = createRequestEvent(
85+
serverRequestEv,
86+
null,
87+
[],
88+
true,
89+
'/',
90+
mockQwikSerializer,
91+
vi.fn()
92+
);
93+
94+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
95+
96+
const result = requestEv.redirect(302, '/path//with///multiple////slashes');
97+
98+
expect(result).toBeInstanceOf(RedirectMessage);
99+
expect(requestEv.headers.get('Location')).toBe('/path/with/multiple/slashes');
100+
expect(consoleSpy).toHaveBeenCalledWith(
101+
'Redirect URL /path//with///multiple////slashes is invalid, fixing to /path/with/multiple/slashes'
102+
);
103+
});
104+
105+
it('should throw error when trying to redirect after headers are sent', () => {
106+
const serverRequestEv = createMockServerRequestEvent();
107+
const requestEv = createRequestEvent(
108+
serverRequestEv,
109+
null,
110+
[],
111+
true,
112+
'/',
113+
mockQwikSerializer,
114+
vi.fn()
115+
);
116+
117+
// Trigger getWritableStream to simulate headers being sent
118+
requestEv.getWritableStream();
119+
120+
expect(() => {
121+
requestEv.redirect(302, '/should-fail');
122+
}).toThrow('Response already sent');
123+
});
124+
});

0 commit comments

Comments
 (0)