mirror of https://github.com/lukechilds/got.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
5.7 KiB
197 lines
5.7 KiB
import test from 'ava';
|
|
import getStream from 'get-stream';
|
|
import got from '../';
|
|
import {createServer} from './helpers/server';
|
|
|
|
let s;
|
|
|
|
test.before('setup', async () => {
|
|
s = await createServer();
|
|
|
|
let noStoreIndex = 0;
|
|
s.on('/no-store', (req, res) => {
|
|
noStoreIndex++;
|
|
res.setHeader('Cache-Control', 'public, no-cache, no-store');
|
|
res.end(noStoreIndex.toString());
|
|
});
|
|
|
|
let cacheIndex = 0;
|
|
s.on('/cache', (req, res) => {
|
|
cacheIndex++;
|
|
res.setHeader('Cache-Control', 'public, max-age=60');
|
|
res.end(cacheIndex.toString());
|
|
});
|
|
|
|
s.on('/last-modified', (req, res) => {
|
|
res.setHeader('Cache-Control', 'public, max-age=0');
|
|
res.setHeader('Last-Modified', 'Wed, 21 Oct 2015 07:28:00 GMT');
|
|
let responseBody = 'last-modified';
|
|
|
|
if (req.headers['if-modified-since'] === 'Wed, 21 Oct 2015 07:28:00 GMT') {
|
|
res.statusCode = 304;
|
|
responseBody = null;
|
|
}
|
|
|
|
res.end(responseBody);
|
|
});
|
|
|
|
s.on('/etag', (req, res) => {
|
|
res.setHeader('Cache-Control', 'public, max-age=0');
|
|
res.setHeader('ETag', '33a64df551425fcc55e4d42a148795d9f25f89d4');
|
|
let responseBody = 'etag';
|
|
|
|
if (req.headers['if-none-match'] === '33a64df551425fcc55e4d42a148795d9f25f89d4') {
|
|
res.statusCode = 304;
|
|
responseBody = null;
|
|
}
|
|
|
|
res.end(responseBody);
|
|
});
|
|
|
|
let cacheThenNoStoreIndex = 0;
|
|
s.on('/cache-then-no-store-on-revalidate', (req, res) => {
|
|
const cc = cacheThenNoStoreIndex === 0 ? 'public, max-age=0' : 'public, no-cache, no-store';
|
|
cacheThenNoStoreIndex++;
|
|
res.setHeader('Cache-Control', cc);
|
|
res.end('cache-then-no-store-on-revalidate');
|
|
});
|
|
|
|
await s.listen(s.port);
|
|
});
|
|
|
|
test('Non cacheable responses are not cached', async t => {
|
|
const endpoint = '/no-store';
|
|
const cache = new Map();
|
|
|
|
const firstResponseInt = parseInt((await got(s.url + endpoint, {cache})).body, 10);
|
|
const secondResponseInt = parseInt((await got(s.url + endpoint, {cache})).body, 10);
|
|
|
|
t.is(cache.size, 0);
|
|
t.true(firstResponseInt < secondResponseInt);
|
|
});
|
|
|
|
test('Cacheable responses are cached', async t => {
|
|
const endpoint = '/cache';
|
|
const cache = new Map();
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache});
|
|
const secondResponse = await got(s.url + endpoint, {cache});
|
|
|
|
t.is(cache.size, 1);
|
|
t.is(firstResponse.body, secondResponse.body);
|
|
});
|
|
|
|
test('Stream responses are cached', async t => {
|
|
const endpoint = '/cache';
|
|
const cache = new Map();
|
|
|
|
const firstResponseBody = await getStream(got.stream(s.url + endpoint, {cache}));
|
|
const secondResponseBody = await getStream(got.stream(s.url + endpoint, {cache}));
|
|
|
|
t.is(cache.size, 1);
|
|
t.is(firstResponseBody, secondResponseBody);
|
|
});
|
|
|
|
test('Binary responses are cached', async t => {
|
|
const endpoint = '/cache';
|
|
const cache = new Map();
|
|
const encoding = null;
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache, encoding});
|
|
const secondResponse = await got(s.url + endpoint, {cache, encoding});
|
|
|
|
t.is(cache.size, 1);
|
|
t.true(firstResponse.body instanceof Buffer);
|
|
t.is(firstResponse.body.toString(), secondResponse.body.toString());
|
|
});
|
|
|
|
test('TTL is passed to cache', async t => {
|
|
const endpoint = '/cache';
|
|
const store = new Map();
|
|
const cache = {
|
|
get: store.get.bind(store),
|
|
set: (key, val, ttl) => {
|
|
t.true(typeof ttl === 'number');
|
|
t.true(ttl > 0);
|
|
return store.set(key, val, ttl);
|
|
},
|
|
delete: store.delete.bind(store)
|
|
};
|
|
|
|
t.plan(2);
|
|
|
|
await got(s.url + endpoint, {cache});
|
|
});
|
|
|
|
test('Cached response is re-encoded to current encoding option', async t => {
|
|
const endpoint = '/cache';
|
|
const cache = new Map();
|
|
const firstEncoding = 'base64';
|
|
const secondEncoding = 'hex';
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache, encoding: firstEncoding});
|
|
const secondResponse = await got(s.url + endpoint, {cache, encoding: secondEncoding});
|
|
|
|
const expectedSecondResponseBody = Buffer.from(firstResponse.body, firstEncoding).toString(secondEncoding);
|
|
|
|
t.is(cache.size, 1);
|
|
t.is(secondResponse.body, expectedSecondResponseBody);
|
|
});
|
|
|
|
test('Stale cache entries with Last-Modified headers are revalidated', async t => {
|
|
const endpoint = '/last-modified';
|
|
const cache = new Map();
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache});
|
|
const secondResponse = await got(s.url + endpoint, {cache});
|
|
|
|
t.is(cache.size, 1);
|
|
t.is(firstResponse.statusCode, 200);
|
|
t.is(secondResponse.statusCode, 304);
|
|
t.is(firstResponse.body, 'last-modified');
|
|
t.is(firstResponse.body, secondResponse.body);
|
|
});
|
|
|
|
test('Stale cache entries with ETag headers are revalidated', async t => {
|
|
const endpoint = '/etag';
|
|
const cache = new Map();
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache});
|
|
const secondResponse = await got(s.url + endpoint, {cache});
|
|
|
|
t.is(cache.size, 1);
|
|
t.is(firstResponse.statusCode, 200);
|
|
t.is(secondResponse.statusCode, 304);
|
|
t.is(firstResponse.body, 'etag');
|
|
t.is(firstResponse.body, secondResponse.body);
|
|
});
|
|
|
|
test('Stale cache entries that can\'t be revalidate are deleted from cache', async t => {
|
|
const endpoint = '/cache-then-no-store-on-revalidate';
|
|
const cache = new Map();
|
|
|
|
const firstResponse = await got(s.url + endpoint, {cache});
|
|
t.is(cache.size, 1);
|
|
const secondResponse = await got(s.url + endpoint, {cache, log: true});
|
|
|
|
t.is(cache.size, 0);
|
|
t.is(firstResponse.statusCode, 200);
|
|
t.is(secondResponse.statusCode, 200);
|
|
t.is(firstResponse.body, 'cache-then-no-store-on-revalidate');
|
|
t.is(firstResponse.body, secondResponse.body);
|
|
});
|
|
|
|
test('Response objects have fromCache property set correctly', async t => {
|
|
const endpoint = '/cache';
|
|
const cache = new Map();
|
|
|
|
const response = await got(s.url + endpoint, {cache});
|
|
const cachedResponse = await got(s.url + endpoint, {cache});
|
|
|
|
t.false(response.fromCache);
|
|
t.true(cachedResponse.fromCache);
|
|
});
|
|
|
|
test.after('cleanup', async () => {
|
|
await s.close();
|
|
});
|
|
|