diff options
Diffstat (limited to 'deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test')
8 files changed, 1198 insertions, 0 deletions
diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/misctest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/misctest.js new file mode 100644 index 0000000000..643567d962 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/misctest.js @@ -0,0 +1,33 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + + +describe('Other', function() { + it('Thaw wrong object', function() { + assert.throws(() => { + CachePolicy.fromObject({}); + }); + }); + + it('Missing headers', function() { + assert.throws(() => { + new CachePolicy({}); + }); + assert.throws(() => { + new CachePolicy({headers:{}}, {}); + }); + + const cache = new CachePolicy({headers:{}}, {headers:{}}); + assert.throws(() => { + cache.satisfiesWithoutRevalidation({}); + }); + assert.throws(() => { + cache.revalidatedPolicy({}); + }); + assert.throws(() => { + cache.revalidatedPolicy({headers:{}}, {}); + }); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/okhttptest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/okhttptest.js new file mode 100644 index 0000000000..315f114ae8 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/okhttptest.js @@ -0,0 +1,301 @@ +'use strict'; +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const assert = require('assert'); +const CachePolicy = require('..'); + +describe('okhttp tests', function(){ + it('responseCachingByResponseCode', function(){ + // Test each documented HTTP/1.1 code, plus the first unused value in each range. + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + + assertCached(false, 100); + assertCached(false, 101); + assertCached(false, 102); + assertCached(true, 200); + assertCached(false, 201); + assertCached(false, 202); + assertCached(true, 203); + assertCached(true, 204); + assertCached(false, 205); + assertCached(false, 206); //Electing to not cache partial responses + assertCached(false, 207); + assertCached(true, 300); + assertCached(true, 301); + assertCached(true, 302); + // assertCached(false, 303); + assertCached(false, 304); + assertCached(false, 305); + assertCached(false, 306); + assertCached(true, 307); + assertCached(true, 308); + assertCached(false, 400); + assertCached(false, 401); + assertCached(false, 402); + assertCached(false, 403); + assertCached(true, 404); + assertCached(true, 405); + assertCached(false, 406); + assertCached(false, 408); + assertCached(false, 409); + // the HTTP spec permits caching 410s, but the RI doesn't. + assertCached(true, 410); + assertCached(false, 411); + assertCached(false, 412); + assertCached(false, 413); + assertCached(true, 414); + assertCached(false, 415); + assertCached(false, 416); + assertCached(false, 417); + assertCached(false, 418); + assertCached(false, 429); + + assertCached(false, 500); + assertCached(true, 501); + assertCached(false, 502); + assertCached(false, 503); + assertCached(false, 504); + assertCached(false, 505); + assertCached(false, 506); + }); + + function assertCached(shouldPut, responseCode) { + let expectedResponseCode = responseCode; + + const mockResponse = {headers:{ + "last-modified": formatDate(-1, 3600), + "expires": formatDate(1, 3600), + "www-authenticate": "challenge", + }, + status: responseCode, + body: "ABCDE", + }; + if (responseCode == 407) { + mockResponse.headers["proxy-authenticate"] = "Basic realm=\"protected area\""; + } else if (responseCode == 401) { + mockResponse.headers["www-authenticate"] = "Basic realm=\"protected area\""; + } else if (responseCode == 204 || responseCode == 205) { + mockResponse.body = ""; // We forbid bodies for 204 and 205. + } + + const request = {url: "/", headers:{}}; + + const cache = new CachePolicy(request, mockResponse, {shared:false}); + + assert.equal(shouldPut, cache.storable()); + } + + + it('defaultExpirationDateFullyCachedForLessThan24Hours', function() { + // last modified: 105 seconds ago + // served: 5 seconds ago + // default lifetime: (105 - 5) / 10 = 10 seconds + // expires: 10 seconds from served date = 5 seconds from now + const cache = new CachePolicy({headers:{}}, {headers:{ + "last-modified": formatDate(-105, 1), + "date": formatDate(-5, 1), + }, + body: "A"}, {shared:false}); + + assert(cache.timeToLive() > 4000); + }); + + it('defaultExpirationDateFullyCachedForMoreThan24Hours', function() { + // last modified: 105 days ago + // served: 5 days ago + // default lifetime: (105 - 5) / 10 = 10 days + // expires: 10 days from served date = 5 days from now + const cache = new CachePolicy({headers:{}}, {headers:{ + "last-modified": formatDate(-105, 3600*24), + "date": formatDate(-5, 3600*24), + }, + body: "A"}, {shared:false}); + + assert(cache.maxAge() >= 10*3600*24); + assert(cache.timeToLive()+1000 >= 5*3600*24); + }); + + it('maxAgeInThePastWithDateHeaderButNoLastModifiedHeader', function() { + // Chrome interprets max-age relative to the local clock. Both our cache + // and Firefox both use the earlier of the local and server's clock. + const cache = new CachePolicy({headers:{}}, {headers:{ + "date": formatDate(-120, 1), + "cache-control": "max-age=60", + }}, {shared:false}); + + assert(cache.stale()); + }); + + it('maxAgePreferredOverLowerSharedMaxAge', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "date": formatDate(-2, 60), + "cache-control": "s-maxage=60, max-age=180", + }}, {shared:false}); + + assert.equal(cache.maxAge(), 180); + }); + + it('maxAgePreferredOverHigherMaxAge', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "date": formatDate(-3, 60), + "cache-control": "s-maxage=60, max-age=180", + }}, {shared:false}); + + assert(cache.stale()); + }); + + it('requestMethodOptionsIsNotCached', function() { + testRequestMethodNotCached("OPTIONS"); + }); + + it('requestMethodPutIsNotCached', function() { + testRequestMethodNotCached("PUT"); + }); + + it('requestMethodDeleteIsNotCached', function() { + testRequestMethodNotCached("DELETE"); + }); + + it('requestMethodTraceIsNotCached', function() { + testRequestMethodNotCached("TRACE"); + }); + + function testRequestMethodNotCached(method) { + // 1. seed the cache (potentially) + // 2. expect a cache hit or miss + const cache = new CachePolicy({method, headers:{}}, {headers:{ + "expires": formatDate(1, 3600), + }}, {shared:false}); + + assert(cache.stale()); + } + + it('etagAndExpirationDateInTheFuture', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "etag": "v1", + "last-modified": formatDate(-2, 3600), + "expires": formatDate(1, 3600), + }}, {shared:false}); + + assert(cache.timeToLive() > 0); + }); + + it('clientSideNoStore', function() { + const cache = new CachePolicy({headers:{ + "cache-control": "no-store", + }}, {headers:{ + "cache-control": "max-age=60", + }}, {shared:false}); + + assert(!cache.storable()); + }); + + it('requestMaxAge', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "last-modified": formatDate(-2, 3600), + "date": formatDate(-1, 60), + "expires": formatDate(1, 3600), + }}, {shared:false}); + + assert(!cache.stale()); + assert(cache.age() >= 60); + + assert(cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-age=90", + }})); + + assert(!cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-age=30", + }})); + }); + + it('requestMinFresh', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "cache-control": "max-age=60", + }}, {shared:false}); + + assert(!cache.stale()); + + assert(!cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "min-fresh=120", + }})); + + assert(cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "min-fresh=10", + }})); + }); + + it('requestMaxStale', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "cache-control": "max-age=120", + "date": formatDate(-4, 60), + }}, {shared:false}); + + assert(cache.stale()); + + assert(cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-stale=180", + }})); + + assert(cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-stale", + }})); + + assert(!cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-stale=10", + }})); + }); + + it('requestMaxStaleNotHonoredWithMustRevalidate', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "cache-control": "max-age=120, must-revalidate", + "date": formatDate(-4, 60), + }}, {shared:false}); + + assert(cache.stale()); + + assert(!cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-stale=180", + }})); + + assert(!cache.satisfiesWithoutRevalidation({headers:{ + "cache-control": "max-stale", + }})); + }); + + it('getHeadersDeletesCached100LevelWarnings', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "warning": "199 test danger, 200 ok ok", + }}); + + assert.equal("200 ok ok", cache.responseHeaders().warning); + }); + + it('doNotCachePartialResponse', function() { + const cache = new CachePolicy({headers:{}}, { + status: 206, + headers:{ + "content-range": "bytes 100-100/200", + "cache-control": "max-age=60", + }}); + assert(!cache.storable()); + }); + + function formatDate(delta, unit) { + return new Date(Date.now() + delta*unit*1000).toUTCString(); + } +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/requesttest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/requesttest.js new file mode 100644 index 0000000000..f668556ff8 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/requesttest.js @@ -0,0 +1,61 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +const publicCacheableResponse = {headers:{'cache-control': 'public, max-age=222'}}; +const cacheableResponse = {headers:{'cache-control': 'max-age=111'}}; + +describe('Request properties', function() { + it('No store kills cache', function() { + const cache = new CachePolicy({method:'GET',headers:{'cache-control':'no-store'}}, publicCacheableResponse); + assert(cache.stale()); + assert(!cache.storable()); + }); + + it('POST not cacheable by default', function() { + const cache = new CachePolicy({method:'POST',headers:{}}, {headers:{'cache-control': 'public'}}); + assert(cache.stale()); + assert(!cache.storable()); + }); + + it('POST cacheable explicitly', function() { + const cache = new CachePolicy({method:'POST',headers:{}}, publicCacheableResponse); + assert(!cache.stale()); + assert(cache.storable()); + }); + + it('Public cacheable auth is OK', function() { + const cache = new CachePolicy({method:'GET',headers:{'authorization': 'test'}}, publicCacheableResponse); + assert(!cache.stale()); + assert(cache.storable()); + }); + + it('Proxy cacheable auth is OK', function() { + const cache = new CachePolicy({method:'GET',headers:{'authorization': 'test'}}, {headers:{'cache-control':'max-age=0,s-maxage=12'}}); + assert(!cache.stale()); + assert(cache.storable()); + + const cache2 = CachePolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject()))); + assert(cache2 instanceof CachePolicy); + assert(!cache2.stale()); + assert(cache2.storable()); + }); + + it('Private auth is OK', function() { + const cache = new CachePolicy({method:'GET',headers:{'authorization': 'test'}}, cacheableResponse, {shared:false}); + assert(!cache.stale()); + assert(cache.storable()); + }); + + it('Revalidated auth is OK', function() { + const cache = new CachePolicy({headers:{'authorization': 'test'}}, {headers:{'cache-control':'max-age=88,must-revalidate'}}); + assert(cache.storable()); + }); + + it('Auth prevents caching by default', function() { + const cache = new CachePolicy({method:'GET',headers:{'authorization': 'test'}}, cacheableResponse); + assert(cache.stale()); + assert(!cache.storable()); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/responsetest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/responsetest.js new file mode 100644 index 0000000000..763910b82c --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/responsetest.js @@ -0,0 +1,385 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +const req = {method:'GET', headers:{}}; + +describe('Response headers', function() { + it('simple miss', function() { + const cache = new CachePolicy(req, {headers:{}}); + assert(cache.stale()); + }); + + it('simple hit', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': 'public, max-age=999999'}}); + assert(!cache.stale()); + assert.equal(cache.maxAge(), 999999); + }); + + it('weird syntax', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': ',,,,max-age = 456 ,'}}); + assert(!cache.stale()); + assert.equal(cache.maxAge(), 456); + + const cache2 = CachePolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject()))); + assert(cache2 instanceof CachePolicy); + assert(!cache2.stale()); + assert.equal(cache2.maxAge(), 456); + }); + + it('quoted syntax', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': ' max-age = "678" '}}); + assert(!cache.stale()); + assert.equal(cache.maxAge(), 678); + }); + + it('IIS', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': 'private, public, max-age=259200'}}, {shared:false}); + assert(!cache.stale()); + assert.equal(cache.maxAge(), 259200); + }); + + it('pre-check tolerated', function() { + const cc = 'pre-check=0, post-check=0, no-store, no-cache, max-age=100'; + const cache = new CachePolicy(req, {headers:{'cache-control': cc}}); + assert(cache.stale()); + assert(!cache.storable()); + assert.equal(cache.maxAge(), 0); + assert.equal(cache.responseHeaders()['cache-control'], cc); + }); + + it('pre-check poison', function() { + const origCC = 'pre-check=0, post-check=0, no-cache, no-store, max-age=100, custom, foo=bar'; + const res = {headers:{'cache-control': origCC, pragma: 'no-cache'}}; + const cache = new CachePolicy(req, res, {ignoreCargoCult:true}); + assert(!cache.stale()); + assert(cache.storable()); + assert.equal(cache.maxAge(), 100); + + const cc = cache.responseHeaders()['cache-control']; + assert(!/pre-check/.test(cc), cc); + assert(!/post-check/.test(cc), cc); + assert(!/no-store/.test(cc), cc); + + assert(/max-age=100/.test(cc)); + assert(/custom(,|$)/.test(cc)); + assert(/foo=bar/.test(cc)); + + assert.equal(res.headers['cache-control'], origCC); + assert(res.headers['pragma']); + assert(!cache.responseHeaders()['pragma']); + }); + + it('pre-check poison undefined header', function() { + const origCC = 'pre-check=0, post-check=0, no-cache, no-store'; + const res = {headers:{'cache-control': origCC, expires: 'yesterday!'}}; + const cache = new CachePolicy(req, res, {ignoreCargoCult:true}); + assert(cache.stale()); + assert(cache.storable()); + assert.equal(cache.maxAge(), 0); + + const cc = cache.responseHeaders()['cache-control']; + assert(!cc); + + assert(res.headers['expires']); + assert(!cache.responseHeaders()['expires']); + }); + + it('cache with expires', function() { + const cache = new CachePolicy(req, {headers:{ + 'date': new Date().toGMTString(), + 'expires': new Date(Date.now() + 2000).toGMTString(), + }}); + assert(!cache.stale()); + assert.equal(2, cache.maxAge()); + }); + + it('cache expires no date', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control': 'public', + 'expires': new Date(Date.now()+3600*1000).toGMTString(), + }}); + assert(!cache.stale()); + assert(cache.maxAge() > 3595); + assert(cache.maxAge() < 3605); + }); + + it('Ages', function() { + let now = 1000; + class TimeTravellingPolicy extends CachePolicy { + now() { + return now; + } + } + const cache = new TimeTravellingPolicy(req, {headers:{ + 'cache-control':'max-age=100', + 'age': '50', + }}); + assert(cache.storable()); + + assert.equal(50*1000, cache.timeToLive()); + assert(!cache.stale()); + now += 48*1000; + assert.equal(2*1000, cache.timeToLive()); + assert(!cache.stale()); + now += 5*1000; + assert(cache.stale()); + assert.equal(0, cache.timeToLive()); + }); + + it('Age can make stale', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control':'max-age=100', + 'age': '101', + }}); + assert(cache.stale()); + assert(cache.storable()); + }); + + it('Age not always stale', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control':'max-age=20', + 'age': '15', + }}); + assert(!cache.stale()); + assert(cache.storable()); + }); + + it('Bogus age ignored', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control':'max-age=20', + 'age': 'golden', + }}); + assert(!cache.stale()); + assert(cache.storable()); + }); + + it('cache old files', function() { + const cache = new CachePolicy(req, {headers:{ + 'date': new Date().toGMTString(), + 'last-modified': 'Mon, 07 Mar 2016 11:52:56 GMT', + }}); + assert(!cache.stale()); + assert(cache.maxAge() > 100); + }); + + it('immutable simple hit', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': 'immutable, max-age=999999'}}); + assert(!cache.stale()); + assert.equal(cache.maxAge(), 999999); + }); + + it('immutable can expire', function() { + const cache = new CachePolicy(req, {headers:{'cache-control': 'immutable, max-age=0'}}); + assert(cache.stale()); + assert.equal(cache.maxAge(), 0); + }); + + it('cache immutable files', function() { + const cache = new CachePolicy(req, {headers:{ + 'date': new Date().toGMTString(), + 'cache-control':'immutable', + 'last-modified': new Date().toGMTString(), + }}); + assert(!cache.stale()); + assert(cache.maxAge() > 100); + }); + + it('immutable can be off', function() { + const cache = new CachePolicy(req, {headers:{ + 'date': new Date().toGMTString(), + 'cache-control':'immutable', + 'last-modified': new Date().toGMTString(), + }}, {immutableMinTimeToLive: 0}); + assert(cache.stale()); + assert.equal(cache.maxAge(), 0); + }); + + it('pragma: no-cache', function() { + const cache = new CachePolicy(req, {headers:{ + 'pragma': 'no-cache', + 'last-modified': 'Mon, 07 Mar 2016 11:52:56 GMT', + }}); + assert(cache.stale()); + }); + + it('no-store', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control': 'no-store, public, max-age=1', + }}); + assert(cache.stale()); + assert.equal(0, cache.maxAge()); + }); + + it('observe private cache', function() { + const privateHeader = { + 'cache-control': 'private, max-age=1234', + }; + const proxyCache = new CachePolicy(req, {headers:privateHeader}); + assert(proxyCache.stale()); + assert.equal(0, proxyCache.maxAge()); + + const uaCache = new CachePolicy(req, {headers:privateHeader}, {shared:false}); + assert(!uaCache.stale()); + assert.equal(1234, uaCache.maxAge()); + }); + + it('don\'t share cookies', function() { + const cookieHeader = { + 'set-cookie': 'foo=bar', + 'cache-control': 'max-age=99', + }; + const proxyCache = new CachePolicy(req, {headers:cookieHeader}, {shared:true}); + assert(proxyCache.stale()); + assert.equal(0, proxyCache.maxAge()); + + const uaCache = new CachePolicy(req, {headers:cookieHeader}, {shared:false}); + assert(!uaCache.stale()); + assert.equal(99, uaCache.maxAge()); + }); + + it('do share cookies if immutable', function() { + const cookieHeader = { + 'set-cookie': 'foo=bar', + 'cache-control': 'immutable, max-age=99', + }; + const proxyCache = new CachePolicy(req, {headers:cookieHeader}, {shared:true}); + assert(!proxyCache.stale()); + assert.equal(99, proxyCache.maxAge()); + }); + + it('cache explicitly public cookie', function() { + const cookieHeader = { + 'set-cookie': 'foo=bar', + 'cache-control': 'max-age=5, public', + }; + const proxyCache = new CachePolicy(req, {headers:cookieHeader}, {shared:true}); + assert(!proxyCache.stale()); + assert.equal(5, proxyCache.maxAge()); + }); + + it('miss max-age=0', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control': 'public, max-age=0', + }}); + assert(cache.stale()); + assert.equal(0, cache.maxAge()); + }); + + it('uncacheable 503', function() { + const cache = new CachePolicy(req, { + status: 503, + headers:{ + 'cache-control': 'public, max-age=1000', + }}); + assert(cache.stale()); + assert.equal(0, cache.maxAge()); + }); + + it('cacheable 301', function() { + const cache = new CachePolicy(req, { + status: 301, + headers:{ + 'last-modified': 'Mon, 07 Mar 2016 11:52:56 GMT', + }}); + assert(!cache.stale()); + }); + + it('uncacheable 303', function() { + const cache = new CachePolicy(req, { + status: 303, + headers:{ + 'last-modified': 'Mon, 07 Mar 2016 11:52:56 GMT', + }}); + assert(cache.stale()); + assert.equal(0, cache.maxAge()); + }); + + it('cacheable 303', function() { + const cache = new CachePolicy(req, { + status: 303, + headers:{ + 'cache-control': 'max-age=1000', + }}); + assert(!cache.stale()); + }); + + it('uncacheable 412', function() { + const cache = new CachePolicy(req, { + status: 412, + headers:{ + 'cache-control': 'public, max-age=1000', + }}); + assert(cache.stale()); + assert.equal(0, cache.maxAge()); + }); + + it('expired expires cached with max-age', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control': 'public, max-age=9999', + 'expires': 'Sat, 07 May 2016 15:35:18 GMT', + }}); + assert(!cache.stale()); + assert.equal(9999, cache.maxAge()); + }); + + it('expired expires cached with s-maxage', function() { + const sMaxAgeHeaders = { + 'cache-control': 'public, s-maxage=9999', + 'expires': 'Sat, 07 May 2016 15:35:18 GMT', + }; + const proxyCache = new CachePolicy(req, {headers:sMaxAgeHeaders}); + assert(!proxyCache.stale()); + assert.equal(9999, proxyCache.maxAge()); + + const uaCache = new CachePolicy(req, {headers:sMaxAgeHeaders}, {shared:false}); + assert(uaCache.stale()); + assert.equal(0, uaCache.maxAge()); + }); + + it('max-age wins over future expires', function() { + const cache = new CachePolicy(req, {headers:{ + 'cache-control': 'public, max-age=333', + 'expires': new Date(Date.now()+3600*1000).toGMTString(), + }}); + assert(!cache.stale()); + assert.equal(333, cache.maxAge()); + }); + + it('remove hop headers', function() { + let now = 10000; + class TimeTravellingPolicy extends CachePolicy { + now() { + return now; + } + } + + const res = {headers:{ + 'te': 'deflate', + 'date': 'now', + 'custom': 'header', + 'oompa': 'lumpa', + 'connection': 'close, oompa, header', + 'age': '10', + 'cache-control': 'public, max-age=333', + }}; + const cache = new TimeTravellingPolicy(req, res); + + now += 1005; + const h = cache.responseHeaders(); + assert(!h.connection); + assert(!h.te); + assert(!h.oompa); + assert.equal(h['cache-control'], 'public, max-age=333'); + assert.equal(h.date, 'now', "date must stay the same for expires, age, etc"); + assert.equal(h.custom, 'header'); + assert.equal(h.age, '11'); + assert.equal(res.headers.age, '10'); + + const cache2 = TimeTravellingPolicy.fromObject(JSON.parse(JSON.stringify(cache.toObject()))); + assert(cache2 instanceof TimeTravellingPolicy); + const h2 = cache2.responseHeaders(); + assert.deepEqual(h, h2); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/revalidatetest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/revalidatetest.js new file mode 100644 index 0000000000..9dc737718d --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/revalidatetest.js @@ -0,0 +1,181 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +const simpleRequest = { + method:'GET', + headers:{ + host:'www.w3c.org', + connection: 'close', + 'x-custom': 'yes', + }, + url:'/Protocols/rfc2616/rfc2616-sec14.html', +}; +function simpleRequestBut(overrides) { + return Object.assign({}, simpleRequest, overrides); +} + +const cacheableResponse = {headers:{'cache-control':'max-age=111'}}; +const etaggedResponse = {headers:Object.assign({'etag':'"123456789"'},cacheableResponse.headers)}; +const lastModifiedResponse = {headers:Object.assign({'last-modified':'Tue, 15 Nov 1994 12:45:26 GMT'},cacheableResponse.headers)}; +const multiValidatorResponse = {headers:Object.assign({},etaggedResponse.headers,lastModifiedResponse.headers)}; +const alwaysVariableResponse = {headers:Object.assign({'vary':'*'},cacheableResponse.headers)}; + +function assertHeadersPassed(headers) { + assert.strictEqual(headers.connection, undefined); + assert.strictEqual(headers['x-custom'], 'yes'); +} +function assertNoValidators(headers) { + assert.strictEqual(headers['if-none-match'], undefined); + assert.strictEqual(headers['if-modified-since'], undefined); +} + +describe('Can be revalidated?', function() { + it('ok if method changes to HEAD', function(){ + const cache = new CachePolicy(simpleRequest,etaggedResponse); + const headers = cache.revalidationHeaders(simpleRequestBut({method:'HEAD'})); + assertHeadersPassed(headers); + assert.equal(headers['if-none-match'], '"123456789"'); + }); + + it('not if method mismatch (other than HEAD)', function(){ + const cache = new CachePolicy(simpleRequest,etaggedResponse); + const incomingRequest = simpleRequestBut({method:'POST'}); + const headers = cache.revalidationHeaders(incomingRequest); + assertHeadersPassed(headers); + assertNoValidators(headers); + }); + + it('not if url mismatch', function(){ + const cache = new CachePolicy(simpleRequest,etaggedResponse); + const incomingRequest = simpleRequestBut({url:'/yomomma'}); + const headers = cache.revalidationHeaders(incomingRequest); + assertHeadersPassed(headers); + assertNoValidators(headers); + }); + + it('not if host mismatch', function(){ + const cache = new CachePolicy(simpleRequest,etaggedResponse); + const incomingRequest = simpleRequestBut({headers:{host:'www.w4c.org'}}); + const headers = cache.revalidationHeaders(incomingRequest); + assertNoValidators(headers); + assert.strictEqual(headers['x-custom'], undefined); + }); + + it('not if vary fields prevent', function(){ + const cache = new CachePolicy(simpleRequest,alwaysVariableResponse); + const headers = cache.revalidationHeaders(simpleRequest); + assertHeadersPassed(headers); + assertNoValidators(headers); + }); + + it('when entity tag validator is present', function() { + const cache = new CachePolicy(simpleRequest, etaggedResponse); + const headers = cache.revalidationHeaders(simpleRequest); + assertHeadersPassed(headers); + assert.equal(headers['if-none-match'], '"123456789"'); + }); + + it('skips weak validtors on post', function() { + const postReq = simpleRequestBut({method:'POST', headers:{'if-none-match': 'W/"weak", "strong", W/"weak2"'}}); + const cache = new CachePolicy(postReq, multiValidatorResponse); + const headers = cache.revalidationHeaders(postReq); + assert.equal(headers['if-none-match'], '"strong", "123456789"'); + assert.strictEqual(undefined, headers['if-modified-since']); + }); + + it('skips weak validtors on post 2', function() { + const postReq = simpleRequestBut({method:'POST', headers:{'if-none-match': 'W/"weak"'}}); + const cache = new CachePolicy(postReq, lastModifiedResponse); + const headers = cache.revalidationHeaders(postReq); + assert.strictEqual(undefined, headers['if-none-match']); + assert.strictEqual(undefined, headers['if-modified-since']); + }); + + it('merges validtors', function() { + const postReq = simpleRequestBut({headers:{'if-none-match': 'W/"weak", "strong", W/"weak2"'}}); + const cache = new CachePolicy(postReq, multiValidatorResponse); + const headers = cache.revalidationHeaders(postReq); + assert.equal(headers['if-none-match'], 'W/"weak", "strong", W/"weak2", "123456789"'); + assert.equal('Tue, 15 Nov 1994 12:45:26 GMT', headers['if-modified-since']); + }); + + it('when last-modified validator is present', function() { + const cache = new CachePolicy(simpleRequest, lastModifiedResponse); + const headers = cache.revalidationHeaders(simpleRequest); + assertHeadersPassed(headers); + assert.equal(headers['if-modified-since'], 'Tue, 15 Nov 1994 12:45:26 GMT'); + assert(!/113/.test(headers.warning)); + }); + + it('not without validators', function() { + const cache = new CachePolicy(simpleRequest, cacheableResponse); + const headers = cache.revalidationHeaders(simpleRequest); + assertHeadersPassed(headers); + assertNoValidators(headers); + assert(!/113/.test(headers.warning)); + }) + + it('113 added', function() { + const veryOldResponse = { + headers: { + age: 3600*72, + 'last-modified': 'Tue, 15 Nov 1994 12:45:26 GMT', + }, + }; + + const cache = new CachePolicy(simpleRequest, veryOldResponse); + const headers = cache.responseHeaders(simpleRequest); + assert(/113/.test(headers.warning)); + }) + +}); + +describe('Validation request', function(){ + it('removes warnings', function() { + const cache = new CachePolicy({headers:{}}, {headers:{ + "warning": "199 test danger", + }}); + + assert.strictEqual(undefined, cache.responseHeaders().warning); + }); + + it('must contain any etag', function(){ + const cache = new CachePolicy(simpleRequest,multiValidatorResponse); + const expected = multiValidatorResponse.headers.etag; + const actual = cache.revalidationHeaders(simpleRequest)['if-none-match']; + assert.equal(actual,expected); + }); + + it('merges etags', function(){ + const cache = new CachePolicy(simpleRequest, etaggedResponse); + const expected = `"foo", "bar", ${etaggedResponse.headers.etag}`; + const headers = cache.revalidationHeaders(simpleRequestBut({headers:{ + host:'www.w3c.org', + 'if-none-match': '"foo", "bar"', + }})); + assert.equal(headers['if-none-match'],expected); + }); + + it('should send the Last-Modified value', function(){ + const cache = new CachePolicy(simpleRequest,multiValidatorResponse); + const expected = multiValidatorResponse.headers['last-modified']; + const actual = cache.revalidationHeaders(simpleRequest)['if-modified-since']; + assert.equal(actual,expected); + }); + + it('should not send the Last-Modified value for POST', function(){ + const postReq = {method:'POST', headers:{'if-modified-since':'yesterday'}}; + const cache = new CachePolicy(postReq, lastModifiedResponse); + const actual = cache.revalidationHeaders(postReq)['if-modified-since']; + assert.equal(actual, undefined); + }); + + it('should not send the Last-Modified value for range requests', function(){ + const rangeReq = {method:'GET', headers:{'accept-ranges':'1-3', 'if-modified-since':'yesterday'}}; + const cache = new CachePolicy(rangeReq, lastModifiedResponse); + const actual = cache.revalidationHeaders(rangeReq)['if-modified-since']; + assert.equal(actual, undefined); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/satisfytest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/satisfytest.js new file mode 100644 index 0000000000..3131ee73d0 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/satisfytest.js @@ -0,0 +1,64 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +describe('Satisfies', function() { + it('when URLs match', function() { + const policy = new CachePolicy({url:'/',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(policy.satisfiesWithoutRevalidation({url:'/',headers:{}})); + }); + + it('when expires is present', function() { + const policy = new CachePolicy({headers:{}}, {status:302,headers:{'expires':new Date(Date.now()+2000).toGMTString()}}); + assert(policy.satisfiesWithoutRevalidation({headers:{}})); + }); + + it('not when URLs mismatch', function() { + const policy = new CachePolicy({url:'/foo',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(!policy.satisfiesWithoutRevalidation({url:'/foo?bar',headers:{}})); + }); + + it('when methods match', function() { + const policy = new CachePolicy({method:'GET',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(policy.satisfiesWithoutRevalidation({method:'GET',headers:{}})); + }); + + it('not when hosts mismatch', function() { + const policy = new CachePolicy({headers:{'host':'foo'}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(policy.satisfiesWithoutRevalidation({headers:{'host':'foo'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'host':'foofoo'}})); + }); + + it('when methods match HEAD', function() { + const policy = new CachePolicy({method:'HEAD',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(policy.satisfiesWithoutRevalidation({method:'HEAD',headers:{}})); + }); + + it('not when methods mismatch', function() { + const policy = new CachePolicy({method:'POST',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(!policy.satisfiesWithoutRevalidation({method:'GET',headers:{}})); + }); + + it('not when methods mismatch HEAD', function() { + const policy = new CachePolicy({method:'HEAD',headers:{}}, {status:200,headers:{'cache-control':'max-age=2'}}); + assert(!policy.satisfiesWithoutRevalidation({method:'GET',headers:{}})); + }); + + it('not when proxy revalidating', function() { + const policy = new CachePolicy({headers:{}}, {status:200,headers:{'cache-control':'max-age=2, proxy-revalidate '}}); + assert(!policy.satisfiesWithoutRevalidation({headers:{}})); + }); + + it('when not a proxy revalidating', function() { + const policy = new CachePolicy({headers:{}}, {status:200,headers:{'cache-control':'max-age=2, proxy-revalidate '}}, {shared:false}); + assert(policy.satisfiesWithoutRevalidation({headers:{}})); + }); + + it('not when no-cache requesting', function() { + const policy = new CachePolicy({headers:{}}, {headers:{'cache-control':'max-age=2'}}); + assert(policy.satisfiesWithoutRevalidation({headers:{'cache-control':'fine'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'cache-control':'no-cache'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'pragma':'no-cache'}})); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/updatetest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/updatetest.js new file mode 100644 index 0000000000..6d498c86e3 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/updatetest.js @@ -0,0 +1,98 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +const simpleRequest = { + method:'GET', + headers:{ + host:'www.w3c.org', + connection: 'close', + }, + url:'/Protocols/rfc2616/rfc2616-sec14.html', +}; +function withHeaders(request, headers) { + return Object.assign({}, request, { + headers: Object.assign({}, request.headers, headers), + }); +} + +const cacheableResponse = {headers:{'cache-control':'max-age=111'}}; +const etaggedResponse = {headers:Object.assign({'etag':'"123456789"'},cacheableResponse.headers)}; +const weakTaggedResponse = {headers:Object.assign({'etag':'W/"123456789"'},cacheableResponse.headers)}; +const lastModifiedResponse = {headers:Object.assign({'last-modified':'Tue, 15 Nov 1994 12:45:26 GMT'},cacheableResponse.headers)}; +const multiValidatorResponse = {headers:Object.assign({},etaggedResponse.headers,lastModifiedResponse.headers)}; + +function notModifiedResponseHeaders(firstRequest, firstResponse, secondRequest, secondResponse) { + const cache = new CachePolicy(firstRequest, firstResponse); + const headers = cache.revalidationHeaders(secondRequest); + const {policy:newCache, modified} = cache.revalidatedPolicy({headers}, secondResponse); + if (modified) { + return false; + } + return newCache.responseHeaders(); +} + +function assertUpdates(firstRequest, firstResponse, secondRequest, secondResponse) { + const headers = notModifiedResponseHeaders(firstRequest, withHeaders(firstResponse, {'foo': 'original', 'x-other':'original'}), + secondRequest, withHeaders(secondResponse, {'foo': 'updated', 'x-ignore-new':'ignoreme'})); + assert(headers); + assert.equal(headers['foo'], 'updated'); + assert.equal(headers['x-other'], 'original'); + assert.strictEqual(headers['x-ignore-new'], undefined); + assert.strictEqual(headers['etag'], secondResponse.headers.etag); +} + +describe('Update revalidated', function() { + it('Matching etags are updated', function(){ + assertUpdates(simpleRequest, etaggedResponse, simpleRequest, etaggedResponse); + }); + + it('Matching weak etags are updated', function(){ + assertUpdates(simpleRequest, weakTaggedResponse, simpleRequest, weakTaggedResponse); + }); + + it('Matching lastmod are updated', function(){ + assertUpdates(simpleRequest, lastModifiedResponse, simpleRequest, lastModifiedResponse); + }); + + it('Both matching are updated', function(){ + assertUpdates(simpleRequest, multiValidatorResponse, simpleRequest, multiValidatorResponse); + }); + + it('Checks status', function(){ + const response304 = Object.assign({}, multiValidatorResponse, {status:304}); + const response200 = Object.assign({}, multiValidatorResponse, {status:200}); + assertUpdates(simpleRequest, multiValidatorResponse, simpleRequest, response304); + assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, response200)); + }); + + it('Last-mod ignored if etag is wrong', function(){ + assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, withHeaders(multiValidatorResponse, {'etag':'bad'}))); + assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, withHeaders(multiValidatorResponse, {'etag':'W/bad'}))); + }); + + it('Ignored if validator is missing', function(){ + assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, cacheableResponse)); + assert(!notModifiedResponseHeaders(simpleRequest, weakTaggedResponse, simpleRequest, cacheableResponse)); + assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, cacheableResponse)); + }); + + it('Skips update of content-length', function(){ + const etaggedResponseWithLenght1 = withHeaders(etaggedResponse, {'content-length':1}); + const etaggedResponseWithLenght2 = withHeaders(etaggedResponse, {'content-length':2}); + const headers = notModifiedResponseHeaders(simpleRequest, etaggedResponseWithLenght1, simpleRequest, etaggedResponseWithLenght2); + assert.equal(1, headers['content-length']); + }); + + it('Ignored if validator is different', function(){ + assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, etaggedResponse)); + assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, weakTaggedResponse)); + assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, lastModifiedResponse)); + }); + + it('Ignored if validator doesn\'t match', function(){ + assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, withHeaders(etaggedResponse, {etag:'"other"'})), "bad etag"); + assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, withHeaders(lastModifiedResponse, {'last-modified':'dunno'})), "bad lastmod"); + }); +}); diff --git a/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/varytest.js b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/varytest.js new file mode 100644 index 0000000000..9d5cfb2325 --- /dev/null +++ b/deps/npm/node_modules/npm-profile/node_modules/make-fetch-happen/node_modules/http-cache-semantics/test/varytest.js @@ -0,0 +1,75 @@ +'use strict'; + +const assert = require('assert'); +const CachePolicy = require('..'); + +describe('Vary', function() { + it('Basic', function() { + const policy = new CachePolicy({headers:{'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'weather'}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'weather': 'nice'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'weather': 'bad'}})); + }); + + it("* doesn't match", function() { + const policy = new CachePolicy({headers:{'weather': 'ok'}}, {headers:{'cache-control':'max-age=5','vary':'*'}}); + + assert(!policy.satisfiesWithoutRevalidation({headers:{'weather': 'ok'}})); + }); + + it("* is stale", function() { + const policy1 = new CachePolicy({headers:{'weather': 'ok'}}, {headers:{'cache-control':'public,max-age=99', 'vary':'*'}}); + const policy2 = new CachePolicy({headers:{'weather': 'ok'}}, {headers:{'cache-control':'public,max-age=99', 'vary':'weather'}}); + + assert(policy1.stale()); + assert(!policy2.stale()); + }); + + it('Values are case-sensitive', function() { + const policy = new CachePolicy({headers:{'weather': 'BAD'}}, {headers:{'cache-control':'max-age=5','vary':'Weather'}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'weather': 'BAD'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'weather': 'bad'}})); + }); + + it('Irrelevant headers ignored', function() { + const policy = new CachePolicy({headers:{'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'moon-phase'}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'weather': 'bad'}})); + assert(policy.satisfiesWithoutRevalidation({headers:{'sun': 'shining'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'moon-phase': 'full'}})); + }); + + it('Absence is meaningful', function() { + const policy = new CachePolicy({headers:{'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'moon-phase, weather'}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'weather': 'nice'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'weather': 'nice', 'moon-phase': ''}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{}})); + }); + + it('All values must match', function() { + const policy = new CachePolicy({headers:{'sun': 'shining', 'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'weather, sun'}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'sun': 'shining', 'weather': 'nice'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'sun': 'shining', 'weather': 'bad'}})); + }); + + it('Whitespace is OK', function() { + const policy = new CachePolicy({headers:{'sun': 'shining', 'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':' weather , sun '}}); + + assert(policy.satisfiesWithoutRevalidation({headers:{'sun': 'shining', 'weather': 'nice'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'weather': 'nice'}})); + assert(!policy.satisfiesWithoutRevalidation({headers:{'sun': 'shining'}})); + }); + + it('Order is irrelevant', function() { + const policy1 = new CachePolicy({headers:{'sun': 'shining', 'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'weather, sun'}}); + const policy2 = new CachePolicy({headers:{'sun': 'shining', 'weather': 'nice'}}, {headers:{'cache-control':'max-age=5','vary':'sun, weather'}}); + + assert(policy1.satisfiesWithoutRevalidation({headers:{'weather': 'nice', 'sun': 'shining'}})); + assert(policy1.satisfiesWithoutRevalidation({headers:{'sun': 'shining', 'weather': 'nice'}})); + assert(policy2.satisfiesWithoutRevalidation({headers:{'weather': 'nice', 'sun': 'shining'}})); + assert(policy2.satisfiesWithoutRevalidation({headers:{'sun': 'shining', 'weather': 'nice'}})); + }); +}); |