OLD | NEW |
| (Empty) |
1 importScripts('worker-testharness.js'); | |
2 importScripts('/resources/testharness-helpers.js'); | |
3 importScripts('override_assert_object_equals.js'); | |
4 | |
5 // A set of Request/Response pairs to be used with prepopulated_cache_test(). | |
6 var simple_entries = [ | |
7 { | |
8 name: 'a', | |
9 request: new Request('http://example.com/a'), | |
10 response: new Response('') | |
11 }, | |
12 | |
13 { | |
14 name: 'b', | |
15 request: new Request('http://example.com/b'), | |
16 response: new Response('') | |
17 }, | |
18 | |
19 { | |
20 name: 'a_with_query', | |
21 request: new Request('http://example.com/a?q=r'), | |
22 response: new Response('') | |
23 }, | |
24 | |
25 { | |
26 name: 'A', | |
27 request: new Request('http://example.com/A'), | |
28 response: new Response('') | |
29 }, | |
30 | |
31 { | |
32 name: 'a_https', | |
33 request: new Request('https://example.com/a'), | |
34 response: new Response('') | |
35 }, | |
36 | |
37 { | |
38 name: 'a_org', | |
39 request: new Request('http://example.org/a'), | |
40 response: new Response('') | |
41 }, | |
42 | |
43 { | |
44 name: 'cat', | |
45 request: new Request('http://example.com/cat'), | |
46 response: new Response('') | |
47 }, | |
48 | |
49 { | |
50 name: 'catmandu', | |
51 request: new Request('http://example.com/catmandu'), | |
52 response: new Response('') | |
53 }, | |
54 | |
55 { | |
56 name: 'cat_num_lives', | |
57 request: new Request('http://example.com/cat?lives=9'), | |
58 response: new Response('') | |
59 }, | |
60 | |
61 { | |
62 name: 'cat_in_the_hat', | |
63 request: new Request('http://example.com/cat/in/the/hat'), | |
64 response: new Response('') | |
65 }, | |
66 | |
67 { | |
68 name: 'secret_cat', | |
69 request: new Request('http://tom:jerry@example.com/cat'), | |
70 response: new Response('') | |
71 }, | |
72 | |
73 { | |
74 name: 'top_secret_cat', | |
75 request: new Request('http://tom:j3rry@example.com/cat'), | |
76 response: new Response('') | |
77 } | |
78 ]; | |
79 | |
80 // A set of Request/Response pairs to be used with prepopulated_cache_test(). | |
81 // These contain a mix of test cases that use Vary headers. | |
82 var vary_entries = [ | |
83 { | |
84 name: 'vary_cookie_is_cookie', | |
85 request: new Request('http://example.com/c', | |
86 {headers: {'Cookies': 'is-for-cookie'}}), | |
87 response: new Response('', | |
88 {headers: {'Vary': 'Cookies'}}) | |
89 }, | |
90 | |
91 { | |
92 name: 'vary_cookie_is_good', | |
93 request: new Request('http://example.com/c', | |
94 {headers: {'Cookies': 'is-good-enough-for-me'}}), | |
95 response: new Response('', | |
96 {headers: {'Vary': 'Cookies'}}) | |
97 }, | |
98 | |
99 { | |
100 name: 'vary_cookie_absent', | |
101 request: new Request('http://example.com/c'), | |
102 response: new Response('', | |
103 {headers: {'Vary': 'Cookies'}}) | |
104 }, | |
105 | |
106 { | |
107 name: 'vary_wildcard', | |
108 request: new Request('http://example.com/c', | |
109 {headers: {'Cookies': 'x', 'X-Key': '1'}}), | |
110 response: new Response('', | |
111 {headers: {'Vary': '*'}}) | |
112 } | |
113 ]; | |
114 | |
115 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
116 return cache.matchAll('not-present-in-the-cache') | |
117 .then(function(result) { | |
118 assert_array_equivalent( | |
119 result, [], | |
120 'Cache.matchAll should resolve with an empty array on failure.'); | |
121 }); | |
122 }, 'Cache.matchAll with no matching entries'); | |
123 | |
124 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
125 return cache.match('not-present-in-the-cache') | |
126 .then(function(result) { | |
127 assert_equals(result, undefined, | |
128 'Cache.match failures should resolve with undefined.'); | |
129 }); | |
130 }, 'Cache.match with no matching entries'); | |
131 | |
132 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
133 return cache.matchAll(entries.a.request.url) | |
134 .then(function(result) { | |
135 assert_array_objects_equals(result, [entries.a.response], | |
136 'Cache.matchAll should match by URL.'); | |
137 }); | |
138 }, 'Cache.matchAll with URL'); | |
139 | |
140 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
141 return cache.match(entries.a.request.url) | |
142 .then(function(result) { | |
143 assert_object_equals(result, entries.a.response, | |
144 'Cache.match should match by URL.'); | |
145 }); | |
146 }, 'Cache.match with URL'); | |
147 | |
148 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
149 return cache.matchAll(entries.a.request) | |
150 .then(function(result) { | |
151 assert_array_objects_equals( | |
152 result, [entries.a.response], | |
153 'Cache.matchAll should match by Request.'); | |
154 }); | |
155 }, 'Cache.matchAll with Request'); | |
156 | |
157 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
158 return cache.match(entries.a.request) | |
159 .then(function(result) { | |
160 assert_object_equals(result, entries.a.response, | |
161 'Cache.match should match by Request.'); | |
162 }); | |
163 }, 'Cache.match with Request'); | |
164 | |
165 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
166 return cache.matchAll(new Request(entries.a.request.url)) | |
167 .then(function(result) { | |
168 assert_array_objects_equals( | |
169 result, [entries.a.response], | |
170 'Cache.matchAll should match by Request.'); | |
171 }); | |
172 }, 'Cache.matchAll with new Request'); | |
173 | |
174 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
175 return cache.match(new Request(entries.a.request.url)) | |
176 .then(function(result) { | |
177 assert_object_equals(result, entries.a.response, | |
178 'Cache.match should match by Request.'); | |
179 }); | |
180 }, 'Cache.match with new Request'); | |
181 | |
182 cache_test(function(cache) { | |
183 var request = new Request('https://example.com/foo', { | |
184 method: 'POST', | |
185 body: 'Hello world!' | |
186 }); | |
187 var response = new Response('Booyah!', { | |
188 status: 200, | |
189 headers: {'Content-Type': 'text/plain'} | |
190 }); | |
191 | |
192 return cache.put(request.clone(), response.clone()) | |
193 .then(function() { | |
194 assert_false( | |
195 request.bodyUsed, | |
196 '[https://fetch.spec.whatwg.org/#concept-body-used-flag] ' + | |
197 'Request.bodyUsed flag should be initially false.'); | |
198 }) | |
199 .then(function() { | |
200 return cache.match(request); | |
201 }) | |
202 .then(function(result) { | |
203 assert_false(request.bodyUsed, | |
204 'Cache.match should not consume Request body.'); | |
205 }); | |
206 }, 'Cache.match with Request containing non-empty body'); | |
207 | |
208 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
209 return cache.matchAll(entries.a.request, | |
210 {ignoreSearch: true}) | |
211 .then(function(result) { | |
212 assert_array_equivalent( | |
213 result, | |
214 [ | |
215 entries.a.response, | |
216 entries.a_with_query.response | |
217 ], | |
218 'Cache.matchAll with ignoreSearch should ignore the ' + | |
219 'search parameters of cached request.'); | |
220 }); | |
221 }, | |
222 'Cache.matchAll with ignoreSearch option (request with no search ' + | |
223 'parameters)'); | |
224 | |
225 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
226 return cache.match(entries.a.request, | |
227 {ignoreSearch: true}) | |
228 .then(function(result) { | |
229 assert_object_in_array( | |
230 result, | |
231 [ | |
232 entries.a.response, | |
233 entries.a_with_query.response | |
234 ], | |
235 'Cache.match with ignoreSearch should ignore the ' + | |
236 'search parameters of cached request.'); | |
237 }); | |
238 }, | |
239 'Cache.match with ignoreSearch option (request with no search ' + | |
240 'parameters)'); | |
241 | |
242 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
243 return cache.matchAll(entries.a_with_query.request, | |
244 {ignoreSearch: true}) | |
245 .then(function(result) { | |
246 assert_array_equivalent( | |
247 result, | |
248 [ | |
249 entries.a.response, | |
250 entries.a_with_query.response | |
251 ], | |
252 'Cache.matchAll with ignoreSearch should ignore the ' + | |
253 'search parameters of request.'); | |
254 }); | |
255 }, | |
256 'Cache.matchAll with ignoreSearch option (request with search parameter)'); | |
257 | |
258 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
259 return cache.match(entries.a_with_query.request, | |
260 {ignoreSearch: true}) | |
261 .then(function(result) { | |
262 assert_object_in_array( | |
263 result, | |
264 [ | |
265 entries.a.response, | |
266 entries.a_with_query.response | |
267 ], | |
268 'Cache.match with ignoreSearch should ignore the ' + | |
269 'search parameters of request.'); | |
270 }); | |
271 }, | |
272 'Cache.match with ignoreSearch option (request with search parameter)'); | |
273 | |
274 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
275 return cache.matchAll(entries.cat.request.url + '#mouse') | |
276 .then(function(result) { | |
277 assert_array_equivalent( | |
278 result, | |
279 [ | |
280 entries.cat.response, | |
281 ], | |
282 'Cache.matchAll should ignore URL fragment.'); | |
283 }); | |
284 }, 'Cache.matchAll with URL containing fragment'); | |
285 | |
286 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
287 return cache.match(entries.cat.request.url + '#mouse') | |
288 .then(function(result) { | |
289 assert_object_equals(result, entries.cat.response, | |
290 'Cache.match should ignore URL fragment.'); | |
291 }); | |
292 }, 'Cache.match with URL containing fragment'); | |
293 | |
294 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
295 return cache.matchAll('http') | |
296 .then(function(result) { | |
297 assert_array_equivalent( | |
298 result, [], | |
299 'Cache.matchAll should treat query as a URL and not ' + | |
300 'just a string fragment.'); | |
301 }); | |
302 }, 'Cache.matchAll with string fragment "http" as query'); | |
303 | |
304 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
305 return cache.match('http') | |
306 .then(function(result) { | |
307 assert_equals( | |
308 result, undefined, | |
309 'Cache.match should treat query as a URL and not ' + | |
310 'just a string fragment.'); | |
311 }); | |
312 }, 'Cache.match with string fragment "http" as query'); | |
313 | |
314 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
315 return cache.matchAll(entries.secret_cat.request.url) | |
316 .then(function(result) { | |
317 assert_array_equivalent( | |
318 result, [entries.secret_cat.response], | |
319 'Cache.matchAll should not ignore embedded credentials'); | |
320 }); | |
321 }, 'Cache.matchAll with URL containing credentials'); | |
322 | |
323 prepopulated_cache_test(simple_entries, function(cache, entries) { | |
324 return cache.match(entries.secret_cat.request.url) | |
325 .then(function(result) { | |
326 assert_object_equals( | |
327 result, entries.secret_cat.response, | |
328 'Cache.match should not ignore embedded credentials'); | |
329 }); | |
330 }, 'Cache.match with URL containing credentials'); | |
331 | |
332 prepopulated_cache_test(vary_entries, function(cache, entries) { | |
333 return cache.matchAll('http://example.com/c') | |
334 .then(function(result) { | |
335 assert_array_equivalent( | |
336 result, | |
337 [ | |
338 entries.vary_wildcard.response, | |
339 entries.vary_cookie_absent.response | |
340 ], | |
341 'Cache.matchAll should exclude matches if a vary header is ' + | |
342 'missing in the query request, but is present in the cached ' + | |
343 'request.'); | |
344 }) | |
345 | |
346 .then(function() { | |
347 return cache.matchAll( | |
348 new Request('http://example.com/c', | |
349 {headers: {'Cookies': 'none-of-the-above'}})); | |
350 }) | |
351 .then(function(result) { | |
352 assert_array_equivalent( | |
353 result, | |
354 [ | |
355 entries.vary_wildcard.response | |
356 ], | |
357 'Cache.matchAll should exclude matches if a vary header is ' + | |
358 'missing in the cached request, but is present in the query ' + | |
359 'request.'); | |
360 }) | |
361 | |
362 .then(function() { | |
363 return cache.matchAll( | |
364 new Request('http://example.com/c', | |
365 {headers: {'Cookies': 'is-for-cookie'}})); | |
366 }) | |
367 .then(function(result) { | |
368 assert_array_equivalent( | |
369 result, | |
370 [entries.vary_cookie_is_cookie.response], | |
371 'Cache.matchAll should match the entire header if a vary header ' + | |
372 'is present in both the query and cached requests.'); | |
373 }); | |
374 }, 'Cache.matchAll with responses containing "Vary" header'); | |
375 | |
376 prepopulated_cache_test(vary_entries, function(cache, entries) { | |
377 return cache.match('http://example.com/c') | |
378 .then(function(result) { | |
379 assert_object_in_array( | |
380 result, | |
381 [ | |
382 entries.vary_wildcard.response, | |
383 entries.vary_cookie_absent.response | |
384 ], | |
385 'Cache.match should honor "Vary" header.'); | |
386 }); | |
387 }, 'Cache.match with responses containing "Vary" header'); | |
388 | |
389 prepopulated_cache_test(vary_entries, function(cache, entries) { | |
390 return cache.matchAll('http://example.com/c', | |
391 {ignoreVary: true}) | |
392 .then(function(result) { | |
393 assert_array_equivalent( | |
394 result, | |
395 [ | |
396 entries.vary_cookie_is_cookie.response, | |
397 entries.vary_cookie_is_good.response, | |
398 entries.vary_cookie_absent.response, | |
399 entries.vary_wildcard.response | |
400 ], | |
401 'Cache.matchAll should honor "ignoreVary" parameter.'); | |
402 }); | |
403 }, 'Cache.matchAll with "ignoreVary" parameter'); | |
404 | |
405 cache_test(function(cache) { | |
406 var request = new Request('http://example.com'); | |
407 var response; | |
408 var request_url = new URL('simple.txt', location.href).href; | |
409 return fetch(request_url) | |
410 .then(function(fetch_result) { | |
411 response = fetch_result; | |
412 assert_equals( | |
413 response.url, request_url, | |
414 '[https://fetch.spec.whatwg.org/#dom-response-url] ' + | |
415 'Reponse.url should return the URL of the response.'); | |
416 return cache.put(request, response.clone()); | |
417 }) | |
418 .then(function() { | |
419 return cache.match(request.url); | |
420 }) | |
421 .then(function(result) { | |
422 assert_object_equals( | |
423 result, response, | |
424 'Cache.match should return a Response object that has the same ' + | |
425 'properties as the stored response.'); | |
426 return cache.match(response.url); | |
427 }) | |
428 .then(function(result) { | |
429 assert_equals( | |
430 result, undefined, | |
431 'Cache.match should not match cache entry based on response URL.'); | |
432 }); | |
433 }, 'Cache.match with Request and Response objects with different URLs'); | |
434 | |
435 cache_test(function(cache) { | |
436 var request_url = new URL('simple.txt', location.href).href; | |
437 return fetch(request_url) | |
438 .then(function(fetch_result) { | |
439 return cache.put(new Request(request_url), fetch_result); | |
440 }) | |
441 .then(function() { | |
442 return cache.match(request_url); | |
443 }) | |
444 .then(function(result) { | |
445 return result.text(); | |
446 }) | |
447 .then(function(body_text) { | |
448 assert_equals(body_text, 'a simple text file\n', | |
449 'Cache.match should return a Response object with a ' + | |
450 'valid body.'); | |
451 }) | |
452 .then(function() { | |
453 return cache.match(request_url); | |
454 }) | |
455 .then(function(result) { | |
456 return result.text(); | |
457 }) | |
458 .then(function(body_text) { | |
459 assert_equals(body_text, 'a simple text file\n', | |
460 'Cache.match should return a Response object with a ' + | |
461 'valid body each time it is called.'); | |
462 }); | |
463 }, 'Cache.match invoked multiple times for the same Request/Response'); | |
464 | |
465 // Helpers --- | |
466 | |
467 // Run |test_function| with a Cache object as its only parameter. Prior to the | |
468 // call, the Cache is populated by cache entries from |entries|. The latter is | |
469 // expected to be an Object mapping arbitrary keys to objects of the form | |
470 // {request: <Request object>, response: <Response object>}. There's no | |
471 // guarantee on the order in which entries will be added to the cache. | |
472 // | |
473 // |test_function| should return a Promise that can be used with promise_test. | |
474 function prepopulated_cache_test(entries, test_function, description) { | |
475 cache_test(function(cache) { | |
476 var p = Promise.resolve(); | |
477 var hash = {}; | |
478 entries.forEach(function(entry) { | |
479 p = p.then(function() { | |
480 return cache.put(entry.request.clone(), | |
481 entry.response.clone()) | |
482 .catch(function(e) { | |
483 assert_unreached('Test setup failed for entry ' + | |
484 entry.name + ': ' + e); | |
485 }); | |
486 }); | |
487 hash[entry.name] = entry; | |
488 }); | |
489 p = p.then(function() { | |
490 assert_equals(Object.keys(hash).length, entries.length); | |
491 }); | |
492 | |
493 return p.then(function() { | |
494 return test_function(cache, hash); | |
495 }); | |
496 }, description); | |
497 } | |
OLD | NEW |