1 changed files with 300 additions and 0 deletions
@ -0,0 +1,300 @@ |
|||
'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, 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(); |
|||
} |
|||
}); |
Loading…
Reference in new issue