test_cache_match_vary.js (16802B)
1 /* global context testDone:true */ 2 3 var requestURL = 4 "//mochi.test:8888/tests/dom/cache/test/mochitest/vary.sjs?" + context; 5 var name = "match-vary" + context; 6 7 function checkResponse(r, response, responseText) { 8 ok(r !== response, "The objects should not be the same"); 9 is( 10 r.url, 11 response.url.replace("#fragment", ""), 12 "The URLs should be the same" 13 ); 14 is(r.status, response.status, "The status codes should be the same"); 15 is(r.type, response.type, "The response types should be the same"); 16 is(r.ok, response.ok, "Both responses should have succeeded"); 17 is( 18 r.statusText, 19 response.statusText, 20 "Both responses should have the same status text" 21 ); 22 is( 23 r.headers.get("Vary"), 24 response.headers.get("Vary"), 25 "Both responses should have the same Vary header" 26 ); 27 return r.text().then(function (text) { 28 is(text, responseText, "The response body should be correct"); 29 }); 30 } 31 32 // Returns a Promise that will be resolved to an object with the following 33 // properties: 34 // * cache: A Cache object that contains one entry fetched with headers. 35 // * response: A Response object which is the result of fetching a request 36 // with the specified headers. 37 // * responseText: The body of the above response object. 38 function setupTest(headers) { 39 return setupTestMultipleEntries([headers]).then(function (test) { 40 return { 41 response: test.response[0], 42 responseText: test.responseText[0], 43 cache: test.cache, 44 }; 45 }); 46 } 47 function setupTestMultipleEntries(headers) { 48 ok(Array.isArray(headers), "headers should be an array"); 49 return new Promise(function (resolve, reject) { 50 var response, responseText, cache; 51 Promise.all( 52 headers.map(function (h) { 53 return fetch(requestURL, { headers: h }); 54 }) 55 ) 56 .then(function (res) { 57 response = res; 58 return Promise.all( 59 response.map(function (r) { 60 return r.text(); 61 }) 62 ); 63 }) 64 .then(function (text) { 65 responseText = text; 66 return caches.open(name); 67 }) 68 .then(function (c) { 69 cache = c; 70 return Promise.all( 71 headers.map(function (h) { 72 return c.add(new Request(requestURL, { headers: h })); 73 }) 74 ); 75 }) 76 .then(function () { 77 resolve({ response, responseText, cache }); 78 }) 79 .catch(function (err) { 80 reject(err); 81 }); 82 }); 83 } 84 85 function testBasics() { 86 var test; 87 return setupTest({ WhatToVary: "Custom" }) 88 .then(function (t) { 89 test = t; 90 // Ensure that searching without specifying a Custom header succeeds. 91 return test.cache.match(requestURL); 92 }) 93 .then(function (r) { 94 return checkResponse(r, test.response, test.responseText); 95 }) 96 .then(function () { 97 // Ensure that searching with a non-matching value for the Custom header fails. 98 return test.cache.match( 99 new Request(requestURL, { headers: { Custom: "foo=bar" } }) 100 ); 101 }) 102 .then(function (r) { 103 is( 104 typeof r, 105 "undefined", 106 "Searching for a request with an unknown Vary header should not succeed" 107 ); 108 // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds. 109 return test.cache.match( 110 new Request(requestURL, { headers: { Custom: "foo=bar" } }), 111 { ignoreVary: true } 112 ); 113 }) 114 .then(function (r) { 115 return checkResponse(r, test.response, test.responseText); 116 }); 117 } 118 119 function testBasicKeys() { 120 function checkRequest(reqs) { 121 is(reqs.length, 1, "One request expected"); 122 ok(reqs[0].url.includes(requestURL), "The correct request expected"); 123 ok( 124 reqs[0].headers.get("WhatToVary"), 125 "Custom", 126 "The correct request headers expected" 127 ); 128 } 129 var test; 130 return setupTest({ WhatToVary: "Custom" }) 131 .then(function (t) { 132 test = t; 133 // Ensure that searching without specifying a Custom header succeeds. 134 return test.cache.keys(requestURL); 135 }) 136 .then(function (r) { 137 return checkRequest(r); 138 }) 139 .then(function () { 140 // Ensure that searching with a non-matching value for the Custom header fails. 141 return test.cache.keys( 142 new Request(requestURL, { headers: { Custom: "foo=bar" } }) 143 ); 144 }) 145 .then(function (r) { 146 is( 147 r.length, 148 0, 149 "Searching for a request with an unknown Vary header should not succeed" 150 ); 151 // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds. 152 return test.cache.keys( 153 new Request(requestURL, { headers: { Custom: "foo=bar" } }), 154 { ignoreVary: true } 155 ); 156 }) 157 .then(function (r) { 158 return checkRequest(r); 159 }); 160 } 161 162 function testStar() { 163 function ensurePromiseRejected(promise) { 164 return promise.then( 165 function () { 166 ok(false, "Promise should be rejected"); 167 }, 168 function (err) { 169 is( 170 err.name, 171 "TypeError", 172 "Attempting to store a Response with a Vary:* header must fail" 173 ); 174 } 175 ); 176 } 177 return new Promise(function (resolve, reject) { 178 var cache; 179 caches.open(name).then(function (c) { 180 cache = c; 181 Promise.all([ 182 ensurePromiseRejected( 183 cache.add( 184 new Request(requestURL + "1", { headers: { WhatToVary: "*" } }) 185 ) 186 ), 187 ensurePromiseRejected( 188 cache.addAll([ 189 new Request(requestURL + "2", { headers: { WhatToVary: "*" } }), 190 requestURL + "3", 191 ]) 192 ), 193 ensurePromiseRejected( 194 fetch( 195 new Request(requestURL + "4", { headers: { WhatToVary: "*" } }) 196 ).then(function (response) { 197 return cache.put(requestURL + "4", response); 198 }) 199 ), 200 ensurePromiseRejected( 201 cache.add( 202 new Request(requestURL + "5", { 203 headers: { WhatToVary: "*,User-Agent" }, 204 }) 205 ) 206 ), 207 ensurePromiseRejected( 208 cache.addAll([ 209 new Request(requestURL + "6", { 210 headers: { WhatToVary: "*,User-Agent" }, 211 }), 212 requestURL + "7", 213 ]) 214 ), 215 ensurePromiseRejected( 216 fetch( 217 new Request(requestURL + "8", { 218 headers: { WhatToVary: "*,User-Agent" }, 219 }) 220 ).then(function (response) { 221 return cache.put(requestURL + "8", response); 222 }) 223 ), 224 ensurePromiseRejected( 225 cache.add( 226 new Request(requestURL + "9", { 227 headers: { WhatToVary: "User-Agent,*" }, 228 }) 229 ) 230 ), 231 ensurePromiseRejected( 232 cache.addAll([ 233 new Request(requestURL + "10", { 234 headers: { WhatToVary: "User-Agent,*" }, 235 }), 236 requestURL + "10", 237 ]) 238 ), 239 ensurePromiseRejected( 240 fetch( 241 new Request(requestURL + "11", { 242 headers: { WhatToVary: "User-Agent,*" }, 243 }) 244 ).then(function (response) { 245 return cache.put(requestURL + "11", response); 246 }) 247 ), 248 ]).then(reject, resolve); 249 }); 250 }); 251 } 252 253 function testMatch() { 254 var test; 255 return setupTest({ WhatToVary: "Custom", Custom: "foo=bar" }) 256 .then(function (t) { 257 test = t; 258 // Ensure that searching with a different Custom header fails. 259 return test.cache.match( 260 new Request(requestURL, { headers: { Custom: "bar=baz" } }) 261 ); 262 }) 263 .then(function (r) { 264 is( 265 typeof r, 266 "undefined", 267 "Searching for a request with a non-matching Custom header should not succeed" 268 ); 269 // Ensure that searching with the same Custom header succeeds. 270 return test.cache.match( 271 new Request(requestURL, { headers: { Custom: "foo=bar" } }) 272 ); 273 }) 274 .then(function (r) { 275 return checkResponse(r, test.response, test.responseText); 276 }); 277 } 278 279 function testInvalidHeaderName() { 280 var test; 281 return setupTest({ WhatToVary: "Foo/Bar, Custom-User-Agent" }) 282 .then(function (t) { 283 test = t; 284 // Ensure that searching with a different User-Agent header fails. 285 return test.cache.match( 286 new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } }) 287 ); 288 }) 289 .then(function (r) { 290 is( 291 typeof r, 292 "undefined", 293 "Searching for a request with a non-matching Custom-User-Agent header should not succeed" 294 ); 295 // Ensure that searching with a different Custom-User-Agent header but with ignoreVary succeeds. 296 return test.cache.match( 297 new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } }), 298 { ignoreVary: true } 299 ); 300 }) 301 .then(function (r) { 302 return checkResponse(r, test.response, test.responseText); 303 }) 304 .then(function () { 305 // Ensure that we do not mistakenly recognize the tokens in the invalid header name. 306 return test.cache.match( 307 new Request(requestURL, { headers: { Foo: "foobar" } }) 308 ); 309 }) 310 .then(function (r) { 311 return checkResponse(r, test.response, test.responseText); 312 }); 313 } 314 315 function testMultipleHeaders() { 316 var test; 317 return setupTest({ WhatToVary: "Custom-Referer,\tCustom-Accept-Encoding" }) 318 .then(function (t) { 319 test = t; 320 // Ensure that searching with a different Referer header fails. 321 return test.cache.match( 322 new Request(requestURL, { 323 headers: { "Custom-Referer": "https://somesite.com/" }, 324 }) 325 ); 326 }) 327 .then(function (r) { 328 is( 329 typeof r, 330 "undefined", 331 "Searching for a request with a non-matching Custom-Referer header should not succeed" 332 ); 333 // Ensure that searching with a different Custom-Referer header but with ignoreVary succeeds. 334 return test.cache.match( 335 new Request(requestURL, { 336 headers: { "Custom-Referer": "https://somesite.com/" }, 337 }), 338 { ignoreVary: true } 339 ); 340 }) 341 .then(function (r) { 342 return checkResponse(r, test.response, test.responseText); 343 }) 344 .then(function () { 345 // Ensure that searching with a different Custom-Accept-Encoding header fails. 346 return test.cache.match( 347 new Request(requestURL, { 348 headers: { "Custom-Accept-Encoding": "myencoding" }, 349 }) 350 ); 351 }) 352 .then(function (r) { 353 is( 354 typeof r, 355 "undefined", 356 "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed" 357 ); 358 // Ensure that searching with a different Custom-Accept-Encoding header but with ignoreVary succeeds. 359 return test.cache.match( 360 new Request(requestURL, { 361 headers: { "Custom-Accept-Encoding": "myencoding" }, 362 }), 363 { ignoreVary: true } 364 ); 365 }) 366 .then(function (r) { 367 return checkResponse(r, test.response, test.responseText); 368 }) 369 .then(function () { 370 // Ensure that searching with an empty Custom-Referer header succeeds. 371 return test.cache.match( 372 new Request(requestURL, { headers: { "Custom-Referer": "" } }) 373 ); 374 }) 375 .then(function (r) { 376 return checkResponse(r, test.response, test.responseText); 377 }) 378 .then(function () { 379 // Ensure that searching with an empty Custom-Accept-Encoding header succeeds. 380 return test.cache.match( 381 new Request(requestURL, { headers: { "Custom-Accept-Encoding": "" } }) 382 ); 383 }) 384 .then(function (r) { 385 return checkResponse(r, test.response, test.responseText); 386 }) 387 .then(function () { 388 // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header fails. 389 return test.cache.match( 390 new Request(requestURL, { 391 headers: { 392 "Custom-Referer": "", 393 "Custom-Accept-Encoding": "myencoding", 394 }, 395 }) 396 ); 397 }) 398 .then(function (r) { 399 is( 400 typeof r, 401 "undefined", 402 "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed" 403 ); 404 // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header and ignoreVary succeeds. 405 return test.cache.match( 406 new Request(requestURL, { 407 headers: { 408 "Custom-Referer": "", 409 "Custom-Accept-Encoding": "myencoding", 410 }, 411 }), 412 { ignoreVary: true } 413 ); 414 }) 415 .then(function (r) { 416 return checkResponse(r, test.response, test.responseText); 417 }); 418 } 419 420 function testMultipleCacheEntries() { 421 var test; 422 return setupTestMultipleEntries([ 423 { WhatToVary: "Accept-Language", "Accept-Language": "en-US" }, 424 { WhatToVary: "Accept-Language", "Accept-Language": "en-US, fa-IR" }, 425 ]) 426 .then(function (t) { 427 test = t; 428 return test.cache.matchAll(); 429 }) 430 .then(function (r) { 431 is(r.length, 2, "Two cache entries should be stored in the DB"); 432 // Ensure that searching without specifying an Accept-Language header fails. 433 return test.cache.matchAll(requestURL); 434 }) 435 .then(function (r) { 436 is( 437 r.length, 438 0, 439 "Searching for a request without specifying an Accept-Language header should not succeed" 440 ); 441 // Ensure that searching without specifying an Accept-Language header but with ignoreVary succeeds. 442 return test.cache.matchAll(requestURL, { ignoreVary: true }); 443 }) 444 .then(function (r) { 445 return Promise.all([ 446 checkResponse(r[0], test.response[0], test.responseText[0]), 447 checkResponse(r[1], test.response[1], test.responseText[1]), 448 ]); 449 }) 450 .then(function () { 451 // Ensure that searching with Accept-Language: en-US succeeds. 452 return test.cache.matchAll( 453 new Request(requestURL, { headers: { "Accept-Language": "en-US" } }) 454 ); 455 }) 456 .then(function (r) { 457 is(r.length, 1, "One cache entry should be found"); 458 return checkResponse(r[0], test.response[0], test.responseText[0]); 459 }) 460 .then(function () { 461 // Ensure that searching with Accept-Language: en-US,fa-IR succeeds. 462 return test.cache.matchAll( 463 new Request(requestURL, { 464 headers: { "Accept-Language": "en-US, fa-IR" }, 465 }) 466 ); 467 }) 468 .then(function (r) { 469 is(r.length, 1, "One cache entry should be found"); 470 return checkResponse(r[0], test.response[1], test.responseText[1]); 471 }) 472 .then(function () { 473 // Ensure that searching with a valid Accept-Language header but with ignoreVary returns both entries. 474 return test.cache.matchAll( 475 new Request(requestURL, { headers: { "Accept-Language": "en-US" } }), 476 { ignoreVary: true } 477 ); 478 }) 479 .then(function (r) { 480 return Promise.all([ 481 checkResponse(r[0], test.response[0], test.responseText[0]), 482 checkResponse(r[1], test.response[1], test.responseText[1]), 483 ]); 484 }) 485 .then(function () { 486 // Ensure that searching with Accept-Language: fa-IR fails. 487 return test.cache.matchAll( 488 new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } }) 489 ); 490 }) 491 .then(function (r) { 492 is( 493 r.length, 494 0, 495 "Searching for a request with a different Accept-Language header should not succeed" 496 ); 497 // Ensure that searching with Accept-Language: fa-IR but with ignoreVary should succeed. 498 return test.cache.matchAll( 499 new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } }), 500 { ignoreVary: true } 501 ); 502 }) 503 .then(function (r) { 504 is(r.length, 2, "Two cache entries should be found"); 505 return Promise.all([ 506 checkResponse(r[0], test.response[0], test.responseText[0]), 507 checkResponse(r[1], test.response[1], test.responseText[1]), 508 ]); 509 }); 510 } 511 512 // Make sure to clean up after each test step. 513 function step(testPromise) { 514 return testPromise.then( 515 function () { 516 caches.delete(name); 517 }, 518 function () { 519 caches.delete(name); 520 } 521 ); 522 } 523 524 step(testBasics()) 525 .then(function () { 526 return step(testBasicKeys()); 527 }) 528 .then(function () { 529 return step(testStar()); 530 }) 531 .then(function () { 532 return step(testMatch()); 533 }) 534 .then(function () { 535 return step(testInvalidHeaderName()); 536 }) 537 .then(function () { 538 return step(testMultipleHeaders()); 539 }) 540 .then(function () { 541 return step(testMultipleCacheEntries()); 542 }) 543 .then(function () { 544 testDone(); 545 });