1 | 'use strict';
|
2 |
|
3 | const assert = require('assert');
|
4 | const CachePolicy = require('..');
|
5 |
|
6 | const simpleRequest = {
|
7 | method:'GET',
|
8 | headers:{
|
9 | host:'www.w3c.org',
|
10 | connection: 'close',
|
11 | },
|
12 | url:'/Protocols/rfc2616/rfc2616-sec14.html',
|
13 | };
|
14 | function withHeaders(request, headers) {
|
15 | return Object.assign({}, request, {
|
16 | headers: Object.assign({}, request.headers, headers),
|
17 | });
|
18 | }
|
19 |
|
20 | const cacheableResponse = {headers:{'cache-control':'max-age=111'}};
|
21 | const etaggedResponse = {headers:Object.assign({'etag':'"123456789"'},cacheableResponse.headers)};
|
22 | const weakTaggedResponse = {headers:Object.assign({'etag':'W/"123456789"'},cacheableResponse.headers)};
|
23 | const lastModifiedResponse = {headers:Object.assign({'last-modified':'Tue, 15 Nov 1994 12:45:26 GMT'},cacheableResponse.headers)};
|
24 | const multiValidatorResponse = {headers:Object.assign({},etaggedResponse.headers,lastModifiedResponse.headers)};
|
25 |
|
26 | function notModifiedResponseHeaders(firstRequest, firstResponse, secondRequest, secondResponse) {
|
27 | const cache = new CachePolicy(firstRequest, firstResponse);
|
28 | const headers = cache.revalidationHeaders(secondRequest);
|
29 | const {policy:newCache, modified} = cache.revalidatedPolicy({headers}, secondResponse);
|
30 | if (modified) {
|
31 | return false;
|
32 | }
|
33 | return newCache.responseHeaders();
|
34 | }
|
35 |
|
36 | function assertUpdates(firstRequest, firstResponse, secondRequest, secondResponse) {
|
37 | const headers = notModifiedResponseHeaders(firstRequest, withHeaders(firstResponse, {'foo': 'original', 'x-other':'original'}),
|
38 | secondRequest, withHeaders(secondResponse, {'foo': 'updated', 'x-ignore-new':'ignoreme'}));
|
39 | assert(headers);
|
40 | assert.equal(headers['foo'], 'updated');
|
41 | assert.equal(headers['x-other'], 'original');
|
42 | assert.strictEqual(headers['x-ignore-new'], undefined);
|
43 | assert.strictEqual(headers['etag'], secondResponse.headers.etag);
|
44 | }
|
45 |
|
46 | describe('Update revalidated', function() {
|
47 | it('Matching etags are updated', function(){
|
48 | assertUpdates(simpleRequest, etaggedResponse, simpleRequest, etaggedResponse);
|
49 | });
|
50 |
|
51 | it('Matching weak etags are updated', function(){
|
52 | assertUpdates(simpleRequest, weakTaggedResponse, simpleRequest, weakTaggedResponse);
|
53 | });
|
54 |
|
55 | it('Matching lastmod are updated', function(){
|
56 | assertUpdates(simpleRequest, lastModifiedResponse, simpleRequest, lastModifiedResponse);
|
57 | });
|
58 |
|
59 | it('Both matching are updated', function(){
|
60 | assertUpdates(simpleRequest, multiValidatorResponse, simpleRequest, multiValidatorResponse);
|
61 | });
|
62 |
|
63 | it('Checks status', function(){
|
64 | const response304 = Object.assign({}, multiValidatorResponse, {status:304});
|
65 | const response200 = Object.assign({}, multiValidatorResponse, {status:200});
|
66 | assertUpdates(simpleRequest, multiValidatorResponse, simpleRequest, response304);
|
67 | assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, response200));
|
68 | });
|
69 |
|
70 | it('Last-mod ignored if etag is wrong', function(){
|
71 | assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, withHeaders(multiValidatorResponse, {'etag':'bad'})));
|
72 | assert(!notModifiedResponseHeaders(simpleRequest, multiValidatorResponse, simpleRequest, withHeaders(multiValidatorResponse, {'etag':'W/bad'})));
|
73 | });
|
74 |
|
75 | it('Ignored if validator is missing', function(){
|
76 | assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, cacheableResponse));
|
77 | assert(!notModifiedResponseHeaders(simpleRequest, weakTaggedResponse, simpleRequest, cacheableResponse));
|
78 | assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, cacheableResponse));
|
79 | });
|
80 |
|
81 | it('Skips update of content-length', function(){
|
82 | const etaggedResponseWithLenght1 = withHeaders(etaggedResponse, {'content-length':1});
|
83 | const etaggedResponseWithLenght2 = withHeaders(etaggedResponse, {'content-length':2});
|
84 | const headers = notModifiedResponseHeaders(simpleRequest, etaggedResponseWithLenght1, simpleRequest, etaggedResponseWithLenght2);
|
85 | assert.equal(1, headers['content-length']);
|
86 | });
|
87 |
|
88 | it('Ignored if validator is different', function(){
|
89 | assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, etaggedResponse));
|
90 | assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, weakTaggedResponse));
|
91 | assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, lastModifiedResponse));
|
92 | });
|
93 |
|
94 | it('Ignored if validator doesn\'t match', function(){
|
95 | assert(!notModifiedResponseHeaders(simpleRequest, etaggedResponse, simpleRequest, withHeaders(etaggedResponse, {etag:'"other"'})), "bad etag");
|
96 | assert(!notModifiedResponseHeaders(simpleRequest, lastModifiedResponse, simpleRequest, withHeaders(lastModifiedResponse, {'last-modified':'dunno'})), "bad lastmod");
|
97 | });
|
98 | });
|