axios-cache-interceptor/test/util/cache-predicate.test.ts
2023-06-08 13:21:29 -03:00

262 lines
6.9 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import type { CachedStorageValue } from '../../src/storage/types';
import { testCachePredicate } from '../../src/util/cache-predicate';
import { mockAxios } from '../mocks/axios';
import { createResponse } from '../utils';
describe('tests cache predicate object', () => {
it('tests some empty usage', () => {
const response = createResponse({ status: 200 });
expect(testCachePredicate(response, {})).toBeTruthy();
});
it('tests custom cased headers', async () => {
const response = createResponse({ headers: { 'Content-Type': 'application/json' } });
expect(
await testCachePredicate(response, {
containsHeaders: {
'Content-Type': (h) => h === 'application/json'
}
})
).toBeTruthy();
});
it('tests statusCheck with a predicate', async () => {
const response = createResponse({ status: 764 });
expect(
await testCachePredicate(response, {
statusCheck: (status) => status >= 200 && status <= 299
})
).toBeFalsy();
expect(
await testCachePredicate(response, {
statusCheck: (status) => status >= 760 && status <= 769
})
).toBeTruthy();
});
it('tests containsHeader header casing', async () => {
const response = createResponse({
headers: { 'content-type': 'application/json' }
});
expect(await testCachePredicate(response, {})).toBeTruthy();
expect(
await testCachePredicate(response, {
containsHeaders: { 'content-type': () => false }
})
).toBeFalsy();
expect(
await testCachePredicate(response, {
containsHeaders: { 'Content-Type': () => false }
})
).toBeFalsy();
expect(
await testCachePredicate(response, {
containsHeaders: { 'Content-Type': () => false }
})
).toBeFalsy();
});
it('tests containsHeader', async () => {
const response = createResponse({
headers: { 'content-type': 'application/json' }
});
const isJsonLowercase = await testCachePredicate(response, {
containsHeaders: { 'content-type': (h) => h === 'application/json' }
});
const isJsonContent = await testCachePredicate(response, {
containsHeaders: { 'Content-Type': (h) => h === 'application/json' }
});
const isXmlContent = await testCachePredicate(response, {
containsHeaders: { 'Content-Type': (h) => h === 'application/xml' }
});
expect(isXmlContent).toBeFalsy();
expect(isJsonLowercase).toBeTruthy();
expect(isJsonContent).toBeTruthy();
});
it('tests containsHeader with string predicate', async () => {
const response = createResponse({
headers: { 'content-type': 'application/json' }
});
const headerExists = await testCachePredicate(response, {
containsHeaders: { 'content-type': (header) => header === 'application/json' }
});
const isXmlContent = await testCachePredicate(response, {
containsHeaders: { 'Content-Type': (header) => header === 'application/xml' }
});
const isJsonContent = await testCachePredicate(response, {
containsHeaders: { 'Content-Type': (header) => header === 'application/json' }
});
expect(headerExists).toBeTruthy();
expect(isXmlContent).toBeFalsy();
expect(isJsonContent).toBeTruthy();
});
it('tests responseMatch', async () => {
const response = createResponse({
data: { a: true, b: 1 }
});
expect(
await testCachePredicate(response, {
responseMatch: ({ data }) => data && data.a === true && data.b === 1
})
).toBeTruthy();
expect(
await testCachePredicate(
response,
({ data }) => data && data.a === true && data.b === 1
)
).toBeTruthy();
expect(
await testCachePredicate(response, {
responseMatch: ({ data }) => data && (data.a !== true || data.b !== 1)
})
).toBeFalsy();
});
it('tests responseMath, containsHeaders with async functions', async () => {
const response = createResponse({
data: { a: true, b: 1 },
status: 399,
headers: { 'cache-control': 'no-cache' }
});
expect(
await testCachePredicate(response, {
containsHeaders: {
'cache-control': async (h) => {
await 0; // jumps to next nodejs event loop tick
return h !== 'no-cache';
}
}
})
).toBeFalsy();
expect(
await testCachePredicate(response, {
containsHeaders: {
'cache-control': async (header) => {
await 0; // jumps to next nodejs event loop tick
return header === 'no-cache';
}
}
})
).toBeTruthy();
expect(
await testCachePredicate(response, {
responseMatch: async ({ data }) => {
await 0; // jumps to next nodejs event loop tick
return data.a;
}
})
).toBeTruthy();
expect(
await testCachePredicate(response, {
responseMatch: async ({ data }) => {
await 0; // jumps to next nodejs event loop tick
return !data.a;
}
})
).toBeFalsy();
expect(
await testCachePredicate(response, {
statusCheck: async (status) => {
await 0; // jumps to next nodejs event loop tick
return status === 399;
}
})
);
expect(
await testCachePredicate(response, {
statusCheck: async (status) => {
await 0; // jumps to next nodejs event loop tick
return status !== 399;
}
})
);
});
it('tests generics and typescript types', async () => {
const axios = mockAxios();
const result = await axios.get<{ a: boolean; b: number }>('url', {
cache: {
ttl: ({ data }) => {
return data.b;
},
cachePredicate: {
responseMatch: ({ data }) => {
return data.a;
}
},
update: {
id: (
_,
{ data: { a, b }, headers, status, statusText }
): CachedStorageValue => {
return {
state: 'cached',
ttl: Number.MAX_SAFE_INTEGER,
createdAt: Date.now(),
data: {
headers,
status,
statusText,
data: { a, b }
}
};
}
}
}
});
expect(result).toBeDefined();
});
it('request have id no matter what', async () => {
const axios = mockAxios({
methods: ['post'] // only post
});
const req1 = await axios.post('url', { a: 1 });
const req2 = await axios.post('url', { a: 1 });
const req3 = await axios.get('url-2');
expect(req1.id).toBeDefined();
expect(req1.cached).toBe(false);
expect(req2.id).toBeDefined();
expect(req2.cached).toBe(true);
expect(req3.id).toBeDefined();
expect(req3.cached).toBe(false);
});
});