Skip to content
File

Blob: src/workerd/api/tests/http-test-ts.ts

typescript162 lines
1// Copyright (c) 2024 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5import assert from 'node:assert';
6import util from 'node:util';
7 
8export default {
9 async fetch() {
10 return new Response(null, { status: 404 });
11 },
12};
13 
14async function assertRequestCacheThrowsError(
15 cacheHeader: RequestCache,
16 errorName: string = 'Error',
17 errorMessage: string = "The 'cache' field on 'RequestInitializerDict' is not implemented."
18) {
19 assert.throws(
20 () => {
21 const header = { cache: cacheHeader };
22 const req: RequestInit = header;
23 new Request('https://example.org', req);
24 },
25 {
26 name: errorName,
27 message: errorMessage,
28 }
29 );
30}
31 
32async function assertFetchCacheRejectsError(
33 cacheHeader: RequestCache,
34 errorName: string = 'Error',
35 errorMessage: string = "The 'cache' field on 'RequestInitializerDict' is not implemented."
36) {
37 await assert.rejects(
38 (async () => {
39 const header = { cache: cacheHeader };
40 const req: RequestInit = header;
41 await fetch('https://example.org', req);
42 })(),
43 {
44 name: errorName,
45 message: errorMessage,
46 }
47 );
48}
49 
50// Test that the Request constructor accepts a Request object as the second parameter.
51// This validates the TypeScript type definitions are correct.
52// Reference: https://github.com/cloudflare/workerd/issues/5940
53export const requestConstructorWithRequestAsInit = {
54 async test() {
55 // Create an original request
56 const originalRequest = new Request('https://example.com/original', {
57 method: 'POST',
58 headers: { 'X-Custom-Header': 'test-value' },
59 });
60 
61 // TypeScript should allow passing a Request as the second parameter
62 const newRequest = new Request(
63 'https://example.com/new-url',
64 originalRequest
65 );
66 
67 assert.strictEqual(newRequest.url, 'https://example.com/new-url');
68 assert.strictEqual(newRequest.method, 'POST');
69 assert.strictEqual(newRequest.headers.get('X-Custom-Header'), 'test-value');
70 
71 // Also test with clone() which is a common pattern
72 const clonedAsInit = new Request(
73 'https://example.com/another-url',
74 originalRequest.clone()
75 );
76 assert.strictEqual(clonedAsInit.url, 'https://example.com/another-url');
77 assert.strictEqual(clonedAsInit.method, 'POST');
78 },
79};
80 
81export const cacheMode = {
82 async test(_ctrl: any, env: any, _ctx: any) {
83 const allowedCacheModes: Set<RequestCache> = new Set([
84 'default',
85 'force-cache',
86 'no-cache',
87 'no-store',
88 'only-if-cached',
89 'reload',
90 ]);
91 assert.strictEqual('cache' in Request.prototype, env.CACHE_ENABLED);
92 {
93 const req = new Request('https://example.org', {});
94 assert.strictEqual(req.cache, undefined);
95 }
96 
97 var enabledCacheModes: Set<RequestCache> = new Set();
98 
99 if (env.CACHE_ENABLED) {
100 enabledCacheModes.add('no-store');
101 }
102 if (env.NO_CACHE_ENABLED) {
103 enabledCacheModes.add('no-cache');
104 }
105 if (env.RELOAD_ENABLED) {
106 enabledCacheModes.add('reload');
107 }
108 
109 const failureCacheModes = allowedCacheModes.difference(enabledCacheModes);
110 for (const cacheMode of failureCacheModes) {
111 if (!env.CACHE_ENABLED) {
112 await assertRequestCacheThrowsError(cacheMode);
113 await assertFetchCacheRejectsError(cacheMode);
114 } else {
115 await assertRequestCacheThrowsError(
116 cacheMode,
117 'TypeError',
118 'Unsupported cache mode: ' + cacheMode
119 );
120 await assertFetchCacheRejectsError(
121 cacheMode,
122 'TypeError',
123 'Unsupported cache mode: ' + cacheMode
124 );
125 }
126 }
127 for (const cacheMode of enabledCacheModes) {
128 {
129 const req = new Request('https://example.org', { cache: cacheMode });
130 assert.strictEqual(req.cache, cacheMode);
131 }
132 {
133 const response = await env.SERVICE.fetch(
134 'http://placeholder/not-found',
135 { cache: cacheMode }
136 );
137 assert.strictEqual(
138 util.inspect(response),
139 `Response {
140 status: 404,
141 statusText: 'Not Found',
142 headers: Headers(0) { [immutable]: true },
143 ok: false,
144 redirected: false,
145 url: 'http://placeholder/not-found',
146 webSocket: null,
147 cf: undefined,
148 type: 'default',
149 body: ReadableStream {
150 locked: false,
151 [state]: 'readable',
152 [supportsBYOB]: true,
153 [length]: 0n
154 },
155 bodyUsed: false
156}`
157 );
158 }
159 }
160 },
161};