UNPKG

9.2 kBJavaScriptView Raw
1'use strict';
2/*
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18const assert = require('assert');
19const CachePolicy = require('..');
20
21describe('okhttp tests', function(){
22 it('responseCachingByResponseCode', function(){
23 // Test each documented HTTP/1.1 code, plus the first unused value in each range.
24 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
25
26 assertCached(false, 100);
27 assertCached(false, 101);
28 assertCached(false, 102);
29 assertCached(true, 200);
30 assertCached(false, 201);
31 assertCached(false, 202);
32 assertCached(true, 203);
33 assertCached(true, 204);
34 assertCached(false, 205);
35 assertCached(false, 206); //Electing to not cache partial responses
36 assertCached(false, 207);
37 assertCached(true, 300);
38 assertCached(true, 301);
39 assertCached(true, 302);
40 // assertCached(false, 303);
41 assertCached(false, 304);
42 assertCached(false, 305);
43 assertCached(false, 306);
44 assertCached(true, 307);
45 assertCached(true, 308);
46 assertCached(false, 400);
47 assertCached(false, 401);
48 assertCached(false, 402);
49 assertCached(false, 403);
50 assertCached(true, 404);
51 assertCached(true, 405);
52 assertCached(false, 406);
53 assertCached(false, 408);
54 assertCached(false, 409);
55 // the HTTP spec permits caching 410s, but the RI doesn't.
56 assertCached(true, 410);
57 assertCached(false, 411);
58 assertCached(false, 412);
59 assertCached(false, 413);
60 assertCached(true, 414);
61 assertCached(false, 415);
62 assertCached(false, 416);
63 assertCached(false, 417);
64 assertCached(false, 418);
65 assertCached(false, 429);
66
67 assertCached(false, 500);
68 assertCached(true, 501);
69 assertCached(false, 502);
70 assertCached(false, 503);
71 assertCached(false, 504);
72 assertCached(false, 505);
73 assertCached(false, 506);
74 });
75
76 function assertCached(shouldPut, responseCode) {
77 let expectedResponseCode = responseCode;
78
79 const mockResponse = {headers:{
80 "last-modified": formatDate(-1, 3600),
81 "expires": formatDate(1, 3600),
82 "www-authenticate": "challenge",
83 },
84 status: responseCode,
85 body: "ABCDE",
86 };
87 if (responseCode == 407) {
88 mockResponse.headers["proxy-authenticate"] = "Basic realm=\"protected area\"";
89 } else if (responseCode == 401) {
90 mockResponse.headers["www-authenticate"] = "Basic realm=\"protected area\"";
91 } else if (responseCode == 204 || responseCode == 205) {
92 mockResponse.body = ""; // We forbid bodies for 204 and 205.
93 }
94
95 const request = {url: "/", headers:{}};
96
97 const cache = new CachePolicy(request, mockResponse, {shared:false});
98
99 assert.equal(shouldPut, cache.storable());
100 }
101
102
103 it('defaultExpirationDateFullyCachedForLessThan24Hours', function() {
104 // last modified: 105 seconds ago
105 // served: 5 seconds ago
106 // default lifetime: (105 - 5) / 10 = 10 seconds
107 // expires: 10 seconds from served date = 5 seconds from now
108 const cache = new CachePolicy({headers:{}}, {headers:{
109 "last-modified": formatDate(-105, 1),
110 "date": formatDate(-5, 1),
111 },
112 body: "A"}, {shared:false});
113
114 assert(cache.timeToLive() > 4000);
115 });
116
117 it('defaultExpirationDateFullyCachedForMoreThan24Hours', function() {
118 // last modified: 105 days ago
119 // served: 5 days ago
120 // default lifetime: (105 - 5) / 10 = 10 days
121 // expires: 10 days from served date = 5 days from now
122 const cache = new CachePolicy({headers:{}}, {headers:{
123 "last-modified": formatDate(-105, 3600*24),
124 "date": formatDate(-5, 3600*24),
125 },
126 body: "A"}, {shared:false});
127
128 assert(cache.maxAge() >= 10*3600*24);
129 assert(cache.timeToLive()+1000 >= 5*3600*24);
130 });
131
132 it('maxAgeInThePastWithDateHeaderButNoLastModifiedHeader', function() {
133 // Chrome interprets max-age relative to the local clock. Both our cache
134 // and Firefox both use the earlier of the local and server's clock.
135 const cache = new CachePolicy({headers:{}}, {headers:{
136 "date": formatDate(-120, 1),
137 "cache-control": "max-age=60",
138 }}, {shared:false});
139
140 assert(cache.stale());
141 });
142
143 it('maxAgePreferredOverLowerSharedMaxAge', function() {
144 const cache = new CachePolicy({headers:{}}, {headers:{
145 "date": formatDate(-2, 60),
146 "cache-control": "s-maxage=60, max-age=180",
147 }}, {shared:false});
148
149 assert.equal(cache.maxAge(), 180);
150 });
151
152 it('maxAgePreferredOverHigherMaxAge', function() {
153 const cache = new CachePolicy({headers:{}}, {headers:{
154 "date": formatDate(-3, 60),
155 "cache-control": "s-maxage=60, max-age=180",
156 }}, {shared:false});
157
158 assert(cache.stale());
159 });
160
161 it('requestMethodOptionsIsNotCached', function() {
162 testRequestMethodNotCached("OPTIONS");
163 });
164
165 it('requestMethodPutIsNotCached', function() {
166 testRequestMethodNotCached("PUT");
167 });
168
169 it('requestMethodDeleteIsNotCached', function() {
170 testRequestMethodNotCached("DELETE");
171 });
172
173 it('requestMethodTraceIsNotCached', function() {
174 testRequestMethodNotCached("TRACE");
175 });
176
177 function testRequestMethodNotCached(method) {
178 // 1. seed the cache (potentially)
179 // 2. expect a cache hit or miss
180 const cache = new CachePolicy({method, headers:{}}, {headers:{
181 "expires": formatDate(1, 3600),
182 }}, {shared:false});
183
184 assert(cache.stale());
185 }
186
187 it('etagAndExpirationDateInTheFuture', function() {
188 const cache = new CachePolicy({headers:{}}, {headers:{
189 "etag": "v1",
190 "last-modified": formatDate(-2, 3600),
191 "expires": formatDate(1, 3600),
192 }}, {shared:false});
193
194 assert(cache.timeToLive() > 0);
195 });
196
197 it('clientSideNoStore', function() {
198 const cache = new CachePolicy({headers:{
199 "cache-control": "no-store",
200 }}, {headers:{
201 "cache-control": "max-age=60",
202 }}, {shared:false});
203
204 assert(!cache.storable());
205 });
206
207 it('requestMaxAge', function() {
208 const cache = new CachePolicy({headers:{}}, {headers:{
209 "last-modified": formatDate(-2, 3600),
210 "date": formatDate(-1, 60),
211 "expires": formatDate(1, 3600),
212 }}, {shared:false});
213
214 assert(!cache.stale());
215 assert(cache.age() >= 60);
216
217 assert(cache.satisfiesWithoutRevalidation({headers:{
218 "cache-control": "max-age=90",
219 }}));
220
221 assert(!cache.satisfiesWithoutRevalidation({headers:{
222 "cache-control": "max-age=30",
223 }}));
224 });
225
226 it('requestMinFresh', function() {
227 const cache = new CachePolicy({headers:{}}, {headers:{
228 "cache-control": "max-age=60",
229 }}, {shared:false});
230
231 assert(!cache.stale());
232
233 assert(!cache.satisfiesWithoutRevalidation({headers:{
234 "cache-control": "min-fresh=120",
235 }}));
236
237 assert(cache.satisfiesWithoutRevalidation({headers:{
238 "cache-control": "min-fresh=10",
239 }}));
240 });
241
242 it('requestMaxStale', function() {
243 const cache = new CachePolicy({headers:{}}, {headers:{
244 "cache-control": "max-age=120",
245 "date": formatDate(-4, 60),
246 }}, {shared:false});
247
248 assert(cache.stale());
249
250 assert(cache.satisfiesWithoutRevalidation({headers:{
251 "cache-control": "max-stale=180",
252 }}));
253
254 assert(cache.satisfiesWithoutRevalidation({headers:{
255 "cache-control": "max-stale",
256 }}));
257
258 assert(!cache.satisfiesWithoutRevalidation({headers:{
259 "cache-control": "max-stale=10",
260 }}));
261 });
262
263 it('requestMaxStaleNotHonoredWithMustRevalidate', function() {
264 const cache = new CachePolicy({headers:{}}, {headers:{
265 "cache-control": "max-age=120, must-revalidate",
266 "date": formatDate(-4, 60),
267 }}, {shared:false});
268
269 assert(cache.stale());
270
271 assert(!cache.satisfiesWithoutRevalidation({headers:{
272 "cache-control": "max-stale=180",
273 }}));
274
275 assert(!cache.satisfiesWithoutRevalidation({headers:{
276 "cache-control": "max-stale",
277 }}));
278 });
279
280 it('getHeadersDeletesCached100LevelWarnings', function() {
281 const cache = new CachePolicy({headers:{}}, {headers:{
282 "warning": "199 test danger, 200 ok ok",
283 }});
284
285 assert.equal("200 ok ok", cache.responseHeaders().warning);
286 });
287
288 it('doNotCachePartialResponse', function() {
289 const cache = new CachePolicy({headers:{}}, {
290 status: 206,
291 headers:{
292 "content-range": "bytes 100-100/200",
293 "cache-control": "max-age=60",
294 }});
295 assert(!cache.storable());
296 });
297
298 function formatDate(delta, unit) {
299 return new Date(Date.now() + delta*unit*1000).toUTCString();
300 }
301});