Kevin Foniciello 75aa9cfefd
feat: add stale flag in request return object (#843)
* feature: added stale flag in request return object

* feature: added stale flag in request return object

* feat: added stale flag in request return object

* feat: added stale flag in request return object

* chore: fixed lint issues
2024-08-03 20:52:56 -03:00

186 lines
4.7 KiB
TypeScript

import assert from 'node:assert';
import { describe, it } from 'node:test';
import { Axios } from 'axios';
import { buildStorage, canStale, isStorage, mustRevalidate } from '../../src/storage/build.js';
import { buildMemoryStorage } from '../../src/storage/memory.js';
import type { AxiosStorage, CachedStorageValue, StorageValue } from '../../src/storage/types.js';
import { buildWebStorage } from '../../src/storage/web-api.js';
import { localStorage } from '../dom.js';
import { mockAxios } from '../mocks/axios.js';
describe('General storage functions', () => {
it('isStorage() function', () => {
assert.equal(isStorage(void 0), false);
assert.equal(isStorage(1), false);
assert.equal(isStorage('a'), false);
assert.equal(isStorage({}), false);
assert.equal(isStorage(Axios), false);
assert.equal(
isStorage(() => 0),
false
);
assert.equal(isStorage(null), false);
assert.equal(isStorage(undefined), false);
assert.equal(isStorage({ a: 1, b: 'a' }), false);
assert.ok(isStorage(buildMemoryStorage()));
assert.ok(isStorage(buildWebStorage(localStorage)));
});
it('setupCache() without proper storage', () => {
assert.throws(() => mockAxios({ storage: {} as AxiosStorage }));
});
it('Normal request workflow will always have a currentRequest', async () => {
const memory: Record<string, StorageValue> = {};
const symbol = 'unique identifier for all requests';
const storage = buildStorage({
find(key, cr) {
//@ts-expect-error ignore
assert.ok(cr[symbol]);
return memory[key];
},
set(key, value, cr) {
//@ts-expect-error ignore
assert.ok(cr[symbol]);
memory[key] = value;
},
remove(key, cr) {
//@ts-expect-error ignore
assert.ok(cr[symbol]);
delete memory[key];
},
clear() {
for (const key in memory) {
delete memory[key];
}
}
});
const axios = mockAxios({ storage });
// Defines symbol to be used in all requests
//@ts-expect-error ignore
axios.defaults[symbol] = true;
const req1 = axios.get('https://api.example.com/');
const req2 = axios.get('https://api.example.com/');
const [res1, res2] = await Promise.all([req1, req2]);
assert.equal(res1.status, 200);
assert.equal(res1.cached, false);
assert.equal(res1.stale, undefined);
assert.equal(res2.status, 200);
assert.ok(res2.cached);
assert.equal(res2.stale, false);
assert.equal(res1.id, res2.id);
const cache = await axios.storage.get(res1.id, {
// sample of a request config. Just to the test pass.
//@ts-expect-error ignore
[symbol]: true
});
assert.equal(cache.state, 'cached');
});
it('canStale() function with normal timestamps', () => {
// ttl + staleTtl + createdAt = future
assert.ok(
canStale({
data: {
headers: {},
data: true,
status: 200,
statusText: 'OK'
},
createdAt: Date.now(),
state: 'cached',
ttl: 1000,
staleTtl: 1000
})
);
// ttl + staleTtl + createdAt = past
assert.equal(
canStale({
data: {
headers: {},
data: true,
status: 200,
statusText: 'OK'
},
createdAt: Date.now() - 2001,
state: 'cached',
ttl: 1000,
staleTtl: 1000
}),
false
);
// createdAt + ttl + (0 staleTtl) = future
assert.equal(
canStale({
data: {
headers: {},
data: true,
status: 200,
statusText: 'OK'
},
createdAt: Date.now(),
state: 'cached',
ttl: 9999999,
staleTtl: 0
}),
false
);
// createdAt + ttl = past, + staleTtl = future
assert.ok(
canStale({
data: {
headers: {},
data: true,
status: 200,
statusText: 'OK'
},
createdAt: Date.now(),
state: 'cached',
ttl: 0,
staleTtl: 1000
})
);
});
it('canStale() function with MustRevalidate', () => {
// Normal request, without must-revalidate
const entry: CachedStorageValue = {
data: {
headers: {
'Cache-Control': 'max-age=1'
},
data: true,
status: 200,
statusText: 'OK'
},
createdAt: Date.now(),
state: 'cached',
ttl: 1000,
staleTtl: 1000
};
assert.ok(canStale(entry));
assert.equal(mustRevalidate(entry), false);
// Now with must-revalidate
entry.data.headers['cache-control'] = 'must-revalidate, max-age=1';
assert.equal(canStale(entry), true);
assert.equal(mustRevalidate(entry), true);
});
});