@v4fire/core
Version:
V4Fire core library
397 lines (396 loc) • 12.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _async = _interopRequireDefault(require("../../../../../core/async"));
var _request = _interopRequireWildcard(require("../../../../../core/request"));
var _composition = require("../../../../../core/request/engines/composition");
var _server = require("../../../../../core/request/engines/composition/test/server");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
describe('core/request/engines/composition as request engine', () => {
let server;
let api;
beforeAll(async () => {
api = _request.globalOpts.api;
_request.globalOpts.api = undefined;
server = await (0, _server.createServer)(4444);
});
beforeEach(() => {
server.clearHandles();
server.handles.json1.response(200, {
test: 1
});
});
afterAll(() => {
_request.globalOpts.api = api;
server.destroy();
});
it('calling dropCache on the engine should trigger dropCache on all created providers', async () => {
let r;
const engine = (0, _composition.compositionEngine)([{
request: () => r = (0, _request.default)(server.url('json/1')),
as: 'result'
}]);
await (0, _request.default)('', {
engine
}).data;
const requestResponseObject = await r,
spy = jest.spyOn(requestResponseObject, 'dropCache');
expect(spy).toHaveBeenCalledTimes(0);
engine.dropCache();
expect(spy).toHaveBeenCalledTimes(1);
});
it('a request without failCompositionOnError option should not throw an error', async () => {
server.handles.json1.responseOnce(500, {});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val'
}]);
let result, error;
try {
result = await (0, _request.default)('', {
engine
}).data;
} catch (err) {
error = err;
}
expect(result).toEqual({});
expect(error).toBeUndefined();
});
it('should throw an error in a request with failCompositionOnError', async () => {
server.handles.json1.responseOnce(500, {});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val',
failCompositionOnError: true
}]);
let result, error;
try {
result = await (0, _request.default)('', {
engine
}).data;
} catch (err) {
error = err;
}
const {
details
} = error;
expect(result).toBeUndefined();
expect(error).toBeInstanceOf(_request.RequestError);
expect(details.response.status).toBe(500);
expect(details.response.ok).toBe(false);
});
it('a request should be prevented if the requestFilter returns false', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
requestFilter: () => false
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const data = await (0, _request.default)('', {
engine
}).data;
expect(data).toEqual({
val2: {
test: 2
}
});
});
it('a request should be delayed until the requestFilter promise resolves', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
let resolver;
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
requestFilter: () => new Promise(res => resolver = res)
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const r = (0, _request.default)('', {
engine
});
await new _async.default().sleep(16);
expect(server.handles.json1.calls).toHaveLength(0);
expect(server.handles.json2.calls).toHaveLength(1);
resolver();
const data = await r.data;
expect(data).toEqual({
val1: {
test: 1
},
val2: {
test: 2
}
});
expect(server.handles.json1.calls).toHaveLength(1);
expect(server.handles.json2.calls).toHaveLength(1);
});
it('a request should be prevented if the requestFilter promise resolves with a result of false', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
let resolver;
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
requestFilter: () => new Promise(res => resolver = res)
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const r = (0, _request.default)('', {
engine
});
await new _async.default().sleep(16);
expect(server.handles.json1.calls).toHaveLength(0);
expect(server.handles.json2.calls).toHaveLength(1);
resolver(false);
const data = await r.data;
expect(data).toEqual({
val2: {
test: 2
}
});
expect(server.handles.json1.calls).toHaveLength(0);
expect(server.handles.json2.calls).toHaveLength(1);
});
it('a request should be made if the requestFilter returns true', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
requestFilter: () => true
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const data = await (0, _request.default)('', {
engine
}).data;
expect(data).toEqual({
val1: {
test: 1
},
val2: {
test: 2
}
});
});
it('a request should be made if the requestFilter promise resolves with a result of true', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
let resolver;
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
requestFilter: () => new Promise(res => resolver = res)
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const r = (0, _request.default)('', {
engine
});
await new _async.default().sleep(16);
expect(server.handles.json1.calls).toHaveLength(0);
expect(server.handles.json2.calls).toHaveLength(1);
resolver(true);
const data = await r.data;
expect(data).toEqual({
val1: {
test: 1
},
val2: {
test: 2
}
});
expect(server.handles.json1.calls).toHaveLength(1);
expect(server.handles.json2.calls).toHaveLength(1);
});
it('should return an AggregateError containing errors from all requests configured with failCompositionOnError set to true', async () => {
server.handles.json1.response(500, {});
server.handles.json2.response(401, {});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: 'val1',
failCompositionOnError: true
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2',
failCompositionOnError: true
}], {
aggregateErrors: true
});
let result, error;
try {
result = await (0, _request.default)('', {
engine
}).data;
} catch (err) {
error = err;
}
const error1 = error.errors[0],
error2 = error.errors[1];
const details1 = error1.details,
details2 = error2.details;
expect(result).toBeUndefined();
expect(error).toBeInstanceOf(AggregateError);
expect(error.errors).toHaveLength(2);
expect(error1).toBeInstanceOf(_request.RequestError);
expect(details1.response.status).toBe(500);
expect(error2).toBeInstanceOf(_request.RequestError);
expect(details2.response.status).toBe(401);
});
it('should spread result if spread is specified in "as"', async () => {
server.handles.json1.response(200, {
test: 1
});
server.handles.json2.response(200, {
test: 2
});
const engine = (0, _composition.compositionEngine)([{
request: () => (0, _request.default)(server.url('json/1')),
as: _composition.compositionEngineSpreadResult,
requestFilter: () => true
}, {
request: () => (0, _request.default)(server.url('json/2')),
as: 'val2'
}]);
const data = await (0, _request.default)('', {
engine
}).data;
expect(data).toEqual({
test: 1,
val2: {
test: 2
}
});
});
describe('caching strategy is set to "never"', () => {
test('should always call the request functions', async () => {
server.handles.json1.responseOnce(200, {
test: 1
}).responseOnce(200, {
test: 3
});
server.handles.json2.responseOnce(200, {
test: 2
}).responseOnce(200, {
test: 4
});
const request1 = jest.fn(({
boundRequest
}) => boundRequest((0, _request.default)(server.url('json/1')))),
request2 = jest.fn(({
boundRequest
}) => boundRequest((0, _request.default)(server.url('json/2'))));
const engine = (0, _composition.compositionEngine)([{
request: request1,
as: 'val1'
}, {
request: request2,
as: 'val2'
}]);
const r = (0, _request.default)({
engine,
cacheStrategy: 'never'
});
const data1 = await r('').data,
data2 = await r('').data;
expect(data1).toEqual({
val1: {
test: 1
},
val2: {
test: 2
}
});
expect(data2).toEqual({
val1: {
test: 3
},
val2: {
test: 4
}
});
expect(request1).toHaveBeenCalledTimes(2);
expect(request2).toHaveBeenCalledTimes(2);
});
});
describe('when a request created in the request function has a cacheStrategy of "queue"', () => {
test('the engine should cache the request and avoid making duplicate requests', async () => {
server.handles.json1.responseOnce(200, {
test: 1
}).responseOnce(200, {
test: 3
});
server.handles.json2.responseOnce(200, {
test: 2
}).responseOnce(200, {
test: 4
});
const request1 = jest.fn(() => (0, _request.default)(server.url('json/1'), {
cacheStrategy: 'queue'
})),
request2 = jest.fn(() => (0, _request.default)(server.url('json/2')));
const engine = (0, _composition.compositionEngine)([{
request: request1,
as: 'val1'
}, {
request: request2,
as: 'val2'
}]);
const r = (0, _request.default)({
engine,
cacheStrategy: 'never'
});
const data1 = await r('').data,
data2 = await r('').data;
expect(data1).toEqual({
val1: {
test: 1
},
val2: {
test: 2
}
});
expect(data2).toEqual({
val1: {
test: 1
},
val2: {
test: 4
}
});
expect(request1).toHaveBeenCalledTimes(2);
expect(request2).toHaveBeenCalledTimes(2);
expect(server.handles.json1.calls).toHaveLength(1);
expect(server.handles.json2.calls).toHaveLength(2);
});
});
});