Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import { Context, Status } from '@tinkoff/request-core';
import { VALIDATE } from './constants';
import validate from './validate';
const validator = ({ response }) => {
if (response.error) {
return new Error(response.error);
}
};
const errorValidator = ({ error }) => {
return !!error.valid;
};
const plugin = validate({ validator, errorValidator });
const context = new Context();
context.setState = jest.fn(context.setState.bind(context));
context.updateExternalMeta = jest.fn(context.updateExternalMeta.bind(context));
describe('plugins/validate/validate', () => {
beforeEach(() => {
// @ts-ignore
context.setState.mockClear();
// @ts-ignore
context.updateExternalMeta.mockClear();
});
it('if validator returns undefined plugin should not return any state or call next callback', () => {
context.setState({ response: { a: 1 } });
(context.setState as jest.Mock).mockClear();
const next = jest.fn();
headers: {
'Content-type': 'application/json;',
},
},
})
);
fetch.mockResponse(mockResponse);
class MockedAgent {
requests() {}
destroy() {}
}
http({ agent: { http: new MockedAgent() as any, https: new MockedAgent() as any } }).init(
new Context({ request: { url: 'http://test.com/api' } }),
next,
null
);
await new Promise((res) => {
next.mockImplementation(res);
});
expect(mockResponse).toBeCalled();
expect(next).toHaveBeenLastCalledWith({
response,
status: Status.COMPLETE,
});
});
it('tries return from cache on error, but persist cache errors', () => {
const request = { url: 'test[123]//pf' };
const error = new Error('123');
const plugin = fallback({ getCacheKey, shouldExecute: true });
const context = new Context({ request, error });
const next = jest.fn();
mockPersistentCache.get.mockImplementation((_, cb) => cb(error));
context.updateExternalMeta = jest.fn(context.updateExternalMeta.bind(context));
plugin.error(context, next, null);
expect(getCacheKey).toHaveBeenLastCalledWith(request);
expect(mockPersistentCache.put).not.toHaveBeenCalled();
expect(mockPersistentCache.get).toHaveBeenLastCalledWith(encodeURIComponent(request.url), expect.any(Function));
expect(context.updateExternalMeta).not.toHaveBeenLastCalledWith(metaTypes.CACHE, { fromFallback: true });
expect(next).toHaveBeenLastCalledWith();
});
it('if shouldFallback returns false, do not use cache', () => {
const request = { url: 'test[123]//pf' };
const error = new Error('123');
const shouldFallback = jest.fn(() => false);
const plugin = fallback({ getCacheKey, shouldFallback, shouldExecute: true });
const context = new Context({ request, error });
const next = jest.fn();
context.updateExternalMeta = jest.fn(context.updateExternalMeta.bind(context));
plugin.error(context, next, null);
expect(shouldFallback).toHaveBeenCalledWith(context.getState());
expect(getCacheKey).not.toHaveBeenCalled();
expect(mockPersistentCache.put).not.toHaveBeenCalled();
expect(mockPersistentCache.get).not.toHaveBeenCalled();
expect(context.updateExternalMeta).not.toHaveBeenCalled();
expect(next).toHaveBeenLastCalledWith();
});
});
import { metaTypes } from '@tinkoff/request-cache-utils';
import memoryCache from './memory';
const mockLru = {
get: jest.fn(),
set: jest.fn(),
has: jest.fn(),
peek: jest.fn(),
};
jest.mock('lru-cache', () => () => mockLru);
const getCacheKey = jest.fn((req) => req.url);
const plugin = memoryCache({ getCacheKey });
const next = jest.fn();
const context = new Context({ request: { url: 'test' } });
context.updateMeta = jest.fn(context.updateMeta.bind(context));
describe('plugins/cache/memory', () => {
beforeEach(() => {
mockLru.get.mockClear();
mockLru.set.mockClear();
mockLru.has.mockClear();
mockLru.peek.mockClear();
next.mockClear();
context.setState({ meta: {} });
});
it('init, no cache value', () => {
mockLru.has.mockImplementation(() => false);
plugin.init(context, next, null);
it('baseUrl is not passed', () => {
const request = { url: 'test12313123/weawe' };
const context = new Context({ request });
plugin.init(context, next, null);
expect(transform).toHaveBeenCalledWith({
...request,
baseUrl,
});
expect(next).toHaveBeenCalledWith({
request: {
...request,
url: baseUrl + request.url,
},
});
});
it('save to cache on complete', () => {
const request = { url: 'test[123]//pf' };
const response = { a: 1, b: 2 };
const plugin = fallback({ getCacheKey, shouldExecute: true });
const context = new Context({ request, response });
plugin.complete(context, next, null);
expect(getCacheKey).toHaveBeenLastCalledWith(request);
expect(mockPersistentCache.put).toHaveBeenLastCalledWith(
encodeURIComponent(request.url),
response,
expect.any(Function)
);
expect(mockPersistentCache.get).not.toHaveBeenCalled();
});
import etagCache from './etag';
import { ETAG } from './constants';
const mockLru = {
get: jest.fn(),
set: jest.fn(),
has: jest.fn(),
peek: jest.fn(),
};
jest.mock('lru-cache', () => () => mockLru);
const getCacheKey = jest.fn((req) => req.url);
const plugin = etagCache({ getCacheKey });
const next = jest.fn();
const context = new Context({ request: { url: 'test' } });
context.updateExternalMeta = jest.fn(context.updateExternalMeta.bind(context));
context.updateInternalMeta = jest.fn(context.updateInternalMeta.bind(context));
describe('plugins/cache/etag', () => {
beforeEach(() => {
mockLru.get.mockClear();
mockLru.set.mockClear();
mockLru.has.mockClear();
mockLru.peek.mockClear();
next.mockClear();
(context as any).internalMeta = {};
(context.updateExternalMeta as any).mockClear();
(context.updateInternalMeta as any).mockClear();
});
beforeEach(() => {
next.mockClear();
context = new Context({ request: { url: 'test' } });
plugin = circuitBreaker({
failureThreshold: 5,
failureTimeout: 100,
openTimeout: 200,
halfOpenThreshold: 3,
});
});
beforeEach(() => {
context = new Context();
context.updateExternalMeta = jest.fn(context.updateExternalMeta.bind(context));
});