diff options
Diffstat (limited to 'dom/cache/test/mochitest/test_cache_match_vary.js')
-rw-r--r-- | dom/cache/test/mochitest/test_cache_match_vary.js | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/dom/cache/test/mochitest/test_cache_match_vary.js b/dom/cache/test/mochitest/test_cache_match_vary.js new file mode 100644 index 0000000000..17b2184406 --- /dev/null +++ b/dom/cache/test/mochitest/test_cache_match_vary.js @@ -0,0 +1,545 @@ +/* global context testDone:true */ + +var requestURL = + "//mochi.test:8888/tests/dom/cache/test/mochitest/vary.sjs?" + context; +var name = "match-vary" + context; + +function checkResponse(r, response, responseText) { + ok(r !== response, "The objects should not be the same"); + is( + r.url, + response.url.replace("#fragment", ""), + "The URLs should be the same" + ); + is(r.status, response.status, "The status codes should be the same"); + is(r.type, response.type, "The response types should be the same"); + is(r.ok, response.ok, "Both responses should have succeeded"); + is( + r.statusText, + response.statusText, + "Both responses should have the same status text" + ); + is( + r.headers.get("Vary"), + response.headers.get("Vary"), + "Both responses should have the same Vary header" + ); + return r.text().then(function(text) { + is(text, responseText, "The response body should be correct"); + }); +} + +// Returns a Promise that will be resolved to an object with the following +// properties: +// * cache: A Cache object that contains one entry fetched with headers. +// * response: A Response object which is the result of fetching a request +// with the specified headers. +// * responseText: The body of the above response object. +function setupTest(headers) { + return setupTestMultipleEntries([headers]).then(function(test) { + return { + response: test.response[0], + responseText: test.responseText[0], + cache: test.cache, + }; + }); +} +function setupTestMultipleEntries(headers) { + ok(Array.isArray(headers), "headers should be an array"); + return new Promise(function(resolve, reject) { + var response, responseText, cache; + Promise.all( + headers.map(function(h) { + return fetch(requestURL, { headers: h }); + }) + ) + .then(function(res) { + response = res; + return Promise.all( + response.map(function(r) { + return r.text(); + }) + ); + }) + .then(function(text) { + responseText = text; + return caches.open(name); + }) + .then(function(c) { + cache = c; + return Promise.all( + headers.map(function(h) { + return c.add(new Request(requestURL, { headers: h })); + }) + ); + }) + .then(function() { + resolve({ response, responseText, cache }); + }) + .catch(function(err) { + reject(err); + }); + }); +} + +function testBasics() { + var test; + return setupTest({ WhatToVary: "Custom" }) + .then(function(t) { + test = t; + // Ensure that searching without specifying a Custom header succeeds. + return test.cache.match(requestURL); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that searching with a non-matching value for the Custom header fails. + return test.cache.match( + new Request(requestURL, { headers: { Custom: "foo=bar" } }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with an unknown Vary header should not succeed" + ); + // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds. + return test.cache.match( + new Request(requestURL, { headers: { Custom: "foo=bar" } }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }); +} + +function testBasicKeys() { + function checkRequest(reqs) { + is(reqs.length, 1, "One request expected"); + ok(reqs[0].url.includes(requestURL), "The correct request expected"); + ok( + reqs[0].headers.get("WhatToVary"), + "Custom", + "The correct request headers expected" + ); + } + var test; + return setupTest({ WhatToVary: "Custom" }) + .then(function(t) { + test = t; + // Ensure that searching without specifying a Custom header succeeds. + return test.cache.keys(requestURL); + }) + .then(function(r) { + return checkRequest(r); + }) + .then(function() { + // Ensure that searching with a non-matching value for the Custom header fails. + return test.cache.keys( + new Request(requestURL, { headers: { Custom: "foo=bar" } }) + ); + }) + .then(function(r) { + is( + r.length, + 0, + "Searching for a request with an unknown Vary header should not succeed" + ); + // Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds. + return test.cache.keys( + new Request(requestURL, { headers: { Custom: "foo=bar" } }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkRequest(r); + }); +} + +function testStar() { + function ensurePromiseRejected(promise) { + return promise.then( + function() { + ok(false, "Promise should be rejected"); + }, + function(err) { + is( + err.name, + "TypeError", + "Attempting to store a Response with a Vary:* header must fail" + ); + } + ); + } + return new Promise(function(resolve, reject) { + var cache; + caches.open(name).then(function(c) { + cache = c; + Promise.all([ + ensurePromiseRejected( + cache.add( + new Request(requestURL + "1", { headers: { WhatToVary: "*" } }) + ) + ), + ensurePromiseRejected( + cache.addAll([ + new Request(requestURL + "2", { headers: { WhatToVary: "*" } }), + requestURL + "3", + ]) + ), + ensurePromiseRejected( + fetch( + new Request(requestURL + "4", { headers: { WhatToVary: "*" } }) + ).then(function(response) { + return cache.put(requestURL + "4", response); + }) + ), + ensurePromiseRejected( + cache.add( + new Request(requestURL + "5", { + headers: { WhatToVary: "*,User-Agent" }, + }) + ) + ), + ensurePromiseRejected( + cache.addAll([ + new Request(requestURL + "6", { + headers: { WhatToVary: "*,User-Agent" }, + }), + requestURL + "7", + ]) + ), + ensurePromiseRejected( + fetch( + new Request(requestURL + "8", { + headers: { WhatToVary: "*,User-Agent" }, + }) + ).then(function(response) { + return cache.put(requestURL + "8", response); + }) + ), + ensurePromiseRejected( + cache.add( + new Request(requestURL + "9", { + headers: { WhatToVary: "User-Agent,*" }, + }) + ) + ), + ensurePromiseRejected( + cache.addAll([ + new Request(requestURL + "10", { + headers: { WhatToVary: "User-Agent,*" }, + }), + requestURL + "10", + ]) + ), + ensurePromiseRejected( + fetch( + new Request(requestURL + "11", { + headers: { WhatToVary: "User-Agent,*" }, + }) + ).then(function(response) { + return cache.put(requestURL + "11", response); + }) + ), + ]).then(reject, resolve); + }); + }); +} + +function testMatch() { + var test; + return setupTest({ WhatToVary: "Custom", Custom: "foo=bar" }) + .then(function(t) { + test = t; + // Ensure that searching with a different Custom header fails. + return test.cache.match( + new Request(requestURL, { headers: { Custom: "bar=baz" } }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with a non-matching Custom header should not succeed" + ); + // Ensure that searching with the same Custom header succeeds. + return test.cache.match( + new Request(requestURL, { headers: { Custom: "foo=bar" } }) + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }); +} + +function testInvalidHeaderName() { + var test; + return setupTest({ WhatToVary: "Foo/Bar, Custom-User-Agent" }) + .then(function(t) { + test = t; + // Ensure that searching with a different User-Agent header fails. + return test.cache.match( + new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with a non-matching Custom-User-Agent header should not succeed" + ); + // Ensure that searching with a different Custom-User-Agent header but with ignoreVary succeeds. + return test.cache.match( + new Request(requestURL, { headers: { "Custom-User-Agent": "MyUA" } }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that we do not mistakenly recognize the tokens in the invalid header name. + return test.cache.match( + new Request(requestURL, { headers: { Foo: "foobar" } }) + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }); +} + +function testMultipleHeaders() { + var test; + return setupTest({ WhatToVary: "Custom-Referer,\tCustom-Accept-Encoding" }) + .then(function(t) { + test = t; + // Ensure that searching with a different Referer header fails. + return test.cache.match( + new Request(requestURL, { + headers: { "Custom-Referer": "https://somesite.com/" }, + }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with a non-matching Custom-Referer header should not succeed" + ); + // Ensure that searching with a different Custom-Referer header but with ignoreVary succeeds. + return test.cache.match( + new Request(requestURL, { + headers: { "Custom-Referer": "https://somesite.com/" }, + }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that searching with a different Custom-Accept-Encoding header fails. + return test.cache.match( + new Request(requestURL, { + headers: { "Custom-Accept-Encoding": "myencoding" }, + }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed" + ); + // Ensure that searching with a different Custom-Accept-Encoding header but with ignoreVary succeeds. + return test.cache.match( + new Request(requestURL, { + headers: { "Custom-Accept-Encoding": "myencoding" }, + }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that searching with an empty Custom-Referer header succeeds. + return test.cache.match( + new Request(requestURL, { headers: { "Custom-Referer": "" } }) + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that searching with an empty Custom-Accept-Encoding header succeeds. + return test.cache.match( + new Request(requestURL, { headers: { "Custom-Accept-Encoding": "" } }) + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }) + .then(function() { + // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header fails. + return test.cache.match( + new Request(requestURL, { + headers: { + "Custom-Referer": "", + "Custom-Accept-Encoding": "myencoding", + }, + }) + ); + }) + .then(function(r) { + is( + typeof r, + "undefined", + "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed" + ); + // Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header and ignoreVary succeeds. + return test.cache.match( + new Request(requestURL, { + headers: { + "Custom-Referer": "", + "Custom-Accept-Encoding": "myencoding", + }, + }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return checkResponse(r, test.response, test.responseText); + }); +} + +function testMultipleCacheEntries() { + var test; + return setupTestMultipleEntries([ + { WhatToVary: "Accept-Language", "Accept-Language": "en-US" }, + { WhatToVary: "Accept-Language", "Accept-Language": "en-US, fa-IR" }, + ]) + .then(function(t) { + test = t; + return test.cache.matchAll(); + }) + .then(function(r) { + is(r.length, 2, "Two cache entries should be stored in the DB"); + // Ensure that searching without specifying an Accept-Language header fails. + return test.cache.matchAll(requestURL); + }) + .then(function(r) { + is( + r.length, + 0, + "Searching for a request without specifying an Accept-Language header should not succeed" + ); + // Ensure that searching without specifying an Accept-Language header but with ignoreVary succeeds. + return test.cache.matchAll(requestURL, { ignoreVary: true }); + }) + .then(function(r) { + return Promise.all([ + checkResponse(r[0], test.response[0], test.responseText[0]), + checkResponse(r[1], test.response[1], test.responseText[1]), + ]); + }) + .then(function() { + // Ensure that searching with Accept-Language: en-US succeeds. + return test.cache.matchAll( + new Request(requestURL, { headers: { "Accept-Language": "en-US" } }) + ); + }) + .then(function(r) { + is(r.length, 1, "One cache entry should be found"); + return checkResponse(r[0], test.response[0], test.responseText[0]); + }) + .then(function() { + // Ensure that searching with Accept-Language: en-US,fa-IR succeeds. + return test.cache.matchAll( + new Request(requestURL, { + headers: { "Accept-Language": "en-US, fa-IR" }, + }) + ); + }) + .then(function(r) { + is(r.length, 1, "One cache entry should be found"); + return checkResponse(r[0], test.response[1], test.responseText[1]); + }) + .then(function() { + // Ensure that searching with a valid Accept-Language header but with ignoreVary returns both entries. + return test.cache.matchAll( + new Request(requestURL, { headers: { "Accept-Language": "en-US" } }), + { ignoreVary: true } + ); + }) + .then(function(r) { + return Promise.all([ + checkResponse(r[0], test.response[0], test.responseText[0]), + checkResponse(r[1], test.response[1], test.responseText[1]), + ]); + }) + .then(function() { + // Ensure that searching with Accept-Language: fa-IR fails. + return test.cache.matchAll( + new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } }) + ); + }) + .then(function(r) { + is( + r.length, + 0, + "Searching for a request with a different Accept-Language header should not succeed" + ); + // Ensure that searching with Accept-Language: fa-IR but with ignoreVary should succeed. + return test.cache.matchAll( + new Request(requestURL, { headers: { "Accept-Language": "fa-IR" } }), + { ignoreVary: true } + ); + }) + .then(function(r) { + is(r.length, 2, "Two cache entries should be found"); + return Promise.all([ + checkResponse(r[0], test.response[0], test.responseText[0]), + checkResponse(r[1], test.response[1], test.responseText[1]), + ]); + }); +} + +// Make sure to clean up after each test step. +function step(testPromise) { + return testPromise.then( + function() { + caches.delete(name); + }, + function() { + caches.delete(name); + } + ); +} + +step(testBasics()) + .then(function() { + return step(testBasicKeys()); + }) + .then(function() { + return step(testStar()); + }) + .then(function() { + return step(testMatch()); + }) + .then(function() { + return step(testInvalidHeaderName()); + }) + .then(function() { + return step(testMultipleHeaders()); + }) + .then(function() { + return step(testMultipleCacheEntries()); + }) + .then(function() { + testDone(); + }); |