| 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 |