mirror of
https://github.com/iconify/iconify.git
synced 2024-11-18 18:45:10 +00:00
Switch api-redundancy package tests to vitest
This commit is contained in:
parent
859a77b4bf
commit
97e9677fa4
@ -18,9 +18,7 @@
|
||||
"lint": "eslint src/*.ts",
|
||||
"prebuild": "pnpm run lint",
|
||||
"build": "tsup src/index.ts --dts --format esm,cjs",
|
||||
"test:jest": "jest --runInBand",
|
||||
"test:jasmine": "cross-env NODE_OPTIONS=--experimental-vm-modules jasmine",
|
||||
"test": "pnpm run test:jest && pnpm run test:jasmine"
|
||||
"test": "vitest --config vitest.config.mjs"
|
||||
},
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
@ -36,10 +34,7 @@
|
||||
"@typescript-eslint/parser": "^5.28.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.18.0",
|
||||
"eslint-plugin-jasmine": "^4.1.3",
|
||||
"jasmine": "^4.2.1",
|
||||
"jest": "28.0.0-alpha.11",
|
||||
"ts-jest": "28.0.0-next.3",
|
||||
"tsup": "^5.12.9"
|
||||
"tsup": "^5.12.9",
|
||||
"vitest": "^0.17.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,116 +0,0 @@
|
||||
import { initRedundancy } from '@iconify/api-redundancy';
|
||||
|
||||
describe('Redundancy class', () => {
|
||||
it('Simple query', (done) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local', // Will fail
|
||||
'https://api-backup1.local', // Success
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 100,
|
||||
});
|
||||
|
||||
// Premade responses
|
||||
const responses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
let doneCallbackCalled = false;
|
||||
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
||||
|
||||
// Make URI from resource + payload
|
||||
const uri = resource + payload;
|
||||
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(2);
|
||||
expect(doneCallbackCalled).toEqual(true);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1); // Should have changed to 1 after query
|
||||
done();
|
||||
});
|
||||
},
|
||||
(data) => {
|
||||
expect(data).toEqual('foo');
|
||||
doneCallbackCalled = true;
|
||||
}
|
||||
);
|
||||
|
||||
// Test find()
|
||||
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
||||
query
|
||||
);
|
||||
expect(redundancy.find((item) => item().status === 'pending')).toEqual(
|
||||
query
|
||||
);
|
||||
});
|
||||
|
||||
it('Different start index', (done) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local',
|
||||
'https://api-backup1.local',
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 3000,
|
||||
index: 1,
|
||||
});
|
||||
|
||||
// Premade responses
|
||||
const responses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
||||
|
||||
// Make URI from resource + payload
|
||||
const uri = resource + payload;
|
||||
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(1);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1);
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Test find()
|
||||
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
||||
query
|
||||
);
|
||||
expect(redundancy.find((item) => item().status === 'pending')).toEqual(
|
||||
query
|
||||
);
|
||||
});
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": ["**/*[sS]pec.?(m)js"],
|
||||
"helpers": ["helpers/**/*.?(m)js"],
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
@ -3,461 +3,473 @@ import type { QueryModuleResponse } from '../src/query';
|
||||
import { sendQuery } from '../src/query';
|
||||
|
||||
describe('Advanced queries with multiple resources', () => {
|
||||
it('Simple query, time out on first, success on second after third is called, ignore third (~70ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 50,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Simple query, time out on first, success on second after third is called, ignore third (~70ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 50,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let secondCallback: QueryModuleResponse;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let secondCallback: QueryModuleResponse;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed 3 times
|
||||
expect(sentQuery).toBeLessThan(3);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
// Query should be executed 3 times
|
||||
expect(sentQuery).toBeLessThan(3);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Fail in 20ms
|
||||
setTimeout(() => {
|
||||
// Status should not have changed
|
||||
const status = getStatus();
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Fail
|
||||
callback('next', true);
|
||||
}, 20);
|
||||
return;
|
||||
// Fail in 20ms
|
||||
setTimeout(() => {
|
||||
// Status should not have changed
|
||||
const status = getStatus();
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
case 2:
|
||||
// Only second query should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Fail
|
||||
callback('next', true);
|
||||
}, 20);
|
||||
return;
|
||||
|
||||
// Save item
|
||||
secondCallback = callback;
|
||||
return;
|
||||
case 2:
|
||||
// Only second query should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
case 3:
|
||||
// 2nd and 3rd queries should be pending
|
||||
expect(status.queriesSent).toEqual(3);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
// Save item
|
||||
secondCallback = callback;
|
||||
return;
|
||||
|
||||
// Complete second item
|
||||
secondCallback('success', result);
|
||||
return;
|
||||
case 3:
|
||||
// 2nd and 3rd queries should be pending
|
||||
expect(status.queriesSent).toEqual(3);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
// Complete second item
|
||||
secondCallback('success', result);
|
||||
return;
|
||||
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(3);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(3);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// 20ms from first query failing, 50ms from delay between second and third
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 50 && diff < 90).toEqual(true);
|
||||
|
||||
fulfill(true);
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(3);
|
||||
);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(3);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// 20ms from first query failing, 50ms from delay between second and third
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 50 && diff < 90).toEqual(true);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Multiple delayed responses (~100ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result1 = {};
|
||||
const result2 = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 50,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Multiple delayed responses (~100ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result1 = {};
|
||||
const result2 = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 50,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
|
||||
// Complete first item in 20ms (70ms from start), then second item
|
||||
setTimeout(() => {
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
|
||||
firstCallback('success', result1);
|
||||
|
||||
// Complete second item in 30 ms
|
||||
// Complete first item in 20ms (70ms from start), then second item
|
||||
setTimeout(() => {
|
||||
// Should not change anything because query is already complete
|
||||
callback('success', result2);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
|
||||
// Finish test
|
||||
done();
|
||||
}, 30);
|
||||
}, 20);
|
||||
return;
|
||||
firstCallback('success', result1);
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
// Complete second item in 30 ms
|
||||
setTimeout(() => {
|
||||
// Should not change anything because query is already complete
|
||||
callback('success', result2);
|
||||
|
||||
// Finish test
|
||||
fulfill(true);
|
||||
}, 30);
|
||||
}, 20);
|
||||
return;
|
||||
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result1);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// 50ms delay between queries, 20ms delay by test timer
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 50 && diff < 90).toEqual(true);
|
||||
|
||||
// Do not finish: second item is still pending
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result1);
|
||||
expect(error).toBeUndefined();
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// 50ms delay between queries, 20ms delay by test timer
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 50 && diff < 90).toEqual(true);
|
||||
|
||||
// Do not finish: second item is still pending
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Ignored response after time out (~150ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 100,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Ignored response after time out (~150ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 100,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
let completeCount = 0;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
let completeCount = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
return;
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Bump couneter
|
||||
completeCount++;
|
||||
switch (completeCount) {
|
||||
case 1:
|
||||
// First call: time out
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
return;
|
||||
|
||||
// 25ms delay between queries * 2 + 100ms timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Send data from first query, which should be ignored because dataAfterTimeout is false
|
||||
firstCallback('success', result);
|
||||
// Bump couneter
|
||||
completeCount++;
|
||||
switch (completeCount) {
|
||||
case 1:
|
||||
// First call: time out
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Complete test
|
||||
done();
|
||||
})();
|
||||
return;
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
default:
|
||||
done('Callback should have been called only once');
|
||||
// 25ms delay between queries * 2 + 100ms timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
|
||||
// Send data from first query, which should be ignored because dataAfterTimeout is false
|
||||
firstCallback('success', result);
|
||||
|
||||
// Complete test
|
||||
fulfill(true);
|
||||
})();
|
||||
return;
|
||||
|
||||
default:
|
||||
reject(
|
||||
'Callback should have been called only once'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Response after time out (~150ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 100,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: true,
|
||||
};
|
||||
it('Response after time out (~150ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 100,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: true,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
let completeCount = 0;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
let firstCallback: QueryModuleResponse;
|
||||
let completeCount = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
// Query should be executed 2 times
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Tests specific to each query
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// First query
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
// Store callback
|
||||
firstCallback = callback;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
return;
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Bump couneter
|
||||
completeCount++;
|
||||
switch (completeCount) {
|
||||
case 1:
|
||||
// First call: time out
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
case 2:
|
||||
// Both queries should be pending
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(2);
|
||||
return;
|
||||
|
||||
// 25ms delay between queries * 2 + 100ms timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Send data from first query
|
||||
firstCallback('success', result);
|
||||
})();
|
||||
return;
|
||||
// Bump couneter
|
||||
completeCount++;
|
||||
switch (completeCount) {
|
||||
case 1:
|
||||
// First call: time out
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
case 2:
|
||||
// Second call: data
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// 25ms delay between queries * 2 + 100ms timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
|
||||
// Same as few lines above
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
// Send data from first query
|
||||
firstCallback('success', result);
|
||||
})();
|
||||
return;
|
||||
|
||||
// Done
|
||||
done();
|
||||
})();
|
||||
return;
|
||||
case 2:
|
||||
// Second call: data
|
||||
((): void => {
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
default:
|
||||
done('Callback should have been called only twice');
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Same as few lines above
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff > 130 && diff < 170).toEqual(true);
|
||||
|
||||
// Done
|
||||
fulfill(true);
|
||||
})();
|
||||
return;
|
||||
|
||||
default:
|
||||
reject(
|
||||
'Callback should have been called only twice'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,312 +2,324 @@ import type { RedundancyConfig } from '../src/config';
|
||||
import { sendQuery } from '../src/query';
|
||||
|
||||
describe('Basic queries', () => {
|
||||
it('Empty query', (done) => {
|
||||
const payload = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources: [],
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Empty query', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources: [],
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
() => {
|
||||
done('Query should not be called when resources list is empty');
|
||||
},
|
||||
(data, error) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
() => {
|
||||
reject(
|
||||
'Query should not be called when resources list is empty'
|
||||
);
|
||||
},
|
||||
(data, error) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Should be almost instant: no items in queue
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
// Should be almost instant: no items in queue
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Simple query', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['test1'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Simple query', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['test1'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Complete
|
||||
callback('success', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
// Complete
|
||||
callback('success', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Failing query', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Failing query', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
|
||||
// Fail
|
||||
callback('next', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
// Fail
|
||||
callback('next', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toEqual(result);
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toEqual(result);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(40);
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(40);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Timed out query (~300ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Timed out query (~300ms)', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = false;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
|
||||
// Do not do anything
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
// Do not do anything
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Should have been config.rotate + config.timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(250);
|
||||
// Should have been config.rotate + config.timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(250);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Abort query', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Abort query', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
let sentQuery = false;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
let sentQuery = false;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual(resources[0]);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
// Make sure query was executed only once
|
||||
expect(sentQuery).toEqual(false);
|
||||
sentQuery = true;
|
||||
|
||||
// Abort
|
||||
callback('abort', 404);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
// Abort
|
||||
callback('abort', 404);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(true);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBe(404);
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBe(404);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,366 +2,376 @@ import type { RedundancyConfig } from '../src/config';
|
||||
import { sendQuery } from '../src/query';
|
||||
|
||||
describe('Multiple resources', () => {
|
||||
it('Simple query, success on first attempt', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Simple query, success on first attempt', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual('api1');
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(resource).toEqual('api1');
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed only once because it should finish before second attempt
|
||||
expect(sentQuery).toEqual(0);
|
||||
sentQuery++;
|
||||
// Query should be executed only once because it should finish before second attempt
|
||||
expect(sentQuery).toEqual(0);
|
||||
sentQuery++;
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(1);
|
||||
|
||||
// Complete
|
||||
callback('success', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(1);
|
||||
// Complete
|
||||
callback('success', result);
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure query was sent
|
||||
expect(sentQuery).toEqual(1);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(1);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
// Should be almost instant
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeLessThan(50);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
});
|
||||
|
||||
it('Simple query, time out on first, success on second (~100ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed twice
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// All queries should be pending
|
||||
expect(status.queriesSent).toEqual(sentQuery);
|
||||
expect(status.queriesPending).toEqual(sentQuery);
|
||||
|
||||
// Time out first, complete second
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// Do nothing, let it time out
|
||||
return;
|
||||
|
||||
case 2:
|
||||
// Send result
|
||||
callback('success', result);
|
||||
return;
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
fulfill(true);
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Delay between first and second queries
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(50);
|
||||
expect(diff).toBeLessThan(150);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Time out all queries (~100ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Simple query, time out on first, success on second (~100ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const result = {};
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 200,
|
||||
rotate: 100,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload, callback) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Query should be executed twice
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
// Query should be executed twice
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// All queries should be pending
|
||||
expect(status.queriesSent).toEqual(sentQuery);
|
||||
expect(status.queriesPending).toEqual(sentQuery);
|
||||
// All queries should be pending
|
||||
expect(status.queriesSent).toEqual(sentQuery);
|
||||
expect(status.queriesPending).toEqual(sentQuery);
|
||||
|
||||
// Add abort functions
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
case 2:
|
||||
// Do not send anything
|
||||
return;
|
||||
// Time out first, complete second
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
// Do nothing, let it time out
|
||||
return;
|
||||
|
||||
default:
|
||||
done('This code should not have been reached');
|
||||
case 2:
|
||||
// Send result
|
||||
callback('success', result);
|
||||
return;
|
||||
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Validate data
|
||||
expect(data).toEqual(result);
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('completed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Delay between first and second queries
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(50);
|
||||
expect(diff).toBeLessThan(150);
|
||||
|
||||
fulfill(true);
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// rotate * 2 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(90);
|
||||
expect(diff).toBeLessThan(120);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Start with second resource (~100ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 1,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Time out all queries (~100ms)', () => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 0,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Resource order should be: 1, 0
|
||||
expect(resource).not.toEqual(resources[sentQuery]);
|
||||
expect(resource).toEqual(resources[1 - sentQuery]);
|
||||
// Query should be executed twice
|
||||
expect(sentQuery).toBeLessThan(2);
|
||||
expect(resource).toEqual(resources[sentQuery]);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.payload).toEqual(payload);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
|
||||
// rotate * 2 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(90);
|
||||
expect(diff).toBeLessThan(120);
|
||||
// All queries should be pending
|
||||
expect(status.queriesSent).toEqual(sentQuery);
|
||||
expect(status.queriesPending).toEqual(sentQuery);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
// Add abort functions
|
||||
switch (sentQuery) {
|
||||
case 1:
|
||||
case 2:
|
||||
// Do not send anything
|
||||
return;
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
default:
|
||||
reject('This code should not have been reached');
|
||||
}
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
isSync = false;
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('failed');
|
||||
expect(status.queriesSent).toEqual(2);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// rotate * 2 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(90);
|
||||
expect(diff).toBeLessThan(120);
|
||||
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
it('Start with last resource (~150ms)', (done) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3', 'api4'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 3,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
it('Start with second resource (~100ms)', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 1,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
let sentQuery = 0;
|
||||
const startTime = Date.now();
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
const startTime = Date.now();
|
||||
let sentQuery = 0;
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Resource order should be: 3, 0, 1, 2
|
||||
expect(resource).not.toEqual(resources[sentQuery]);
|
||||
// Resource order should be: 1, 0
|
||||
expect(resource).not.toEqual(resources[sentQuery]);
|
||||
expect(resource).toEqual(resources[1 - sentQuery]);
|
||||
|
||||
const expectedIndex = sentQuery === 0 ? 3 : sentQuery - 1;
|
||||
expect(resource).toEqual(resources[expectedIndex]);
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(2);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(4);
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
// rotate * 2 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(90);
|
||||
expect(diff).toBeLessThan(120);
|
||||
|
||||
// rotate * 4 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(140);
|
||||
expect(diff).toBeLessThan(170);
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
|
||||
isSync = false;
|
||||
it('Start with last resource (~150ms)', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const payload = {};
|
||||
const resources = ['api1', 'api2', 'api3', 'api4'];
|
||||
const config: RedundancyConfig = {
|
||||
resources,
|
||||
index: 3,
|
||||
timeout: 50,
|
||||
rotate: 25,
|
||||
random: false,
|
||||
dataAfterTimeout: false,
|
||||
};
|
||||
|
||||
// Tracking
|
||||
let isSync = true;
|
||||
let sentQuery = 0;
|
||||
const startTime = Date.now();
|
||||
|
||||
// Send query
|
||||
const getStatus = sendQuery(
|
||||
config,
|
||||
payload,
|
||||
(resource, queryPayload) => {
|
||||
expect(isSync).toEqual(false);
|
||||
expect(queryPayload).toEqual(payload);
|
||||
|
||||
// Resource order should be: 3, 0, 1, 2
|
||||
expect(resource).not.toEqual(resources[sentQuery]);
|
||||
|
||||
const expectedIndex = sentQuery === 0 ? 3 : sentQuery - 1;
|
||||
expect(resource).toEqual(resources[expectedIndex]);
|
||||
|
||||
// Bump counter
|
||||
sentQuery++;
|
||||
},
|
||||
(data, error) => {
|
||||
// Make sure queries were sent
|
||||
expect(sentQuery).toEqual(4);
|
||||
|
||||
// Validate data
|
||||
expect(data).toBeUndefined();
|
||||
expect(error).toBeUndefined();
|
||||
|
||||
// rotate * 4 + timeout
|
||||
const diff = Date.now() - startTime;
|
||||
expect(diff).toBeGreaterThan(140);
|
||||
expect(diff).toBeLessThan(170);
|
||||
|
||||
fulfill(true);
|
||||
}
|
||||
);
|
||||
|
||||
// Check status
|
||||
const status = getStatus();
|
||||
expect(status.status).toEqual('pending');
|
||||
expect(status.queriesSent).toEqual(0);
|
||||
expect(status.queriesPending).toEqual(0);
|
||||
|
||||
isSync = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,116 +3,120 @@ import { initRedundancy } from '../src/index';
|
||||
type DummyResponses = Record<string, string>;
|
||||
|
||||
describe('Redundancy class', () => {
|
||||
it('Simple query', (done) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local', // Will fail
|
||||
'https://api-backup1.local', // Success
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 100,
|
||||
});
|
||||
it('Simple query', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local', // Will fail
|
||||
'https://api-backup1.local', // Success
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 100,
|
||||
});
|
||||
|
||||
// Premade responses
|
||||
const responses: DummyResponses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
let doneCallbackCalled = false;
|
||||
// Premade responses
|
||||
const responses: DummyResponses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
let doneCallbackCalled = false;
|
||||
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
||||
|
||||
// Make URI from resource + payload
|
||||
const uri = (resource as string) + (payload as string);
|
||||
// Make URI from resource + payload
|
||||
const uri = (resource as string) + (payload as string);
|
||||
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(2);
|
||||
expect(doneCallbackCalled).toEqual(true);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1); // Should have changed to 1 after query
|
||||
fulfill(true);
|
||||
});
|
||||
},
|
||||
(data) => {
|
||||
expect(data).toEqual('foo');
|
||||
doneCallbackCalled = true;
|
||||
}
|
||||
);
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(2);
|
||||
expect(doneCallbackCalled).toEqual(true);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1); // Should have changed to 1 after query
|
||||
done();
|
||||
});
|
||||
},
|
||||
(data) => {
|
||||
expect(data).toEqual('foo');
|
||||
doneCallbackCalled = true;
|
||||
}
|
||||
);
|
||||
|
||||
// Test find()
|
||||
expect(
|
||||
redundancy.find((item) => (item().payload as string) === '/foo')
|
||||
).toEqual(query);
|
||||
expect(redundancy.find((item) => item().status === 'pending')).toEqual(
|
||||
query
|
||||
);
|
||||
// Test find()
|
||||
expect(
|
||||
redundancy.find((item) => (item().payload as string) === '/foo')
|
||||
).toEqual(query);
|
||||
expect(
|
||||
redundancy.find((item) => item().status === 'pending')
|
||||
).toEqual(query);
|
||||
});
|
||||
});
|
||||
|
||||
it('Different start index', (done) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local',
|
||||
'https://api-backup1.local',
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 3000,
|
||||
index: 1,
|
||||
});
|
||||
it('Different start index', () => {
|
||||
return new Promise((fulfill) => {
|
||||
const redundancy = initRedundancy({
|
||||
resources: [
|
||||
'https://api.local',
|
||||
'https://api-backup1.local',
|
||||
'https://api-backup2.local',
|
||||
],
|
||||
rotate: 20,
|
||||
timeout: 3000,
|
||||
index: 1,
|
||||
});
|
||||
|
||||
// Premade responses
|
||||
const responses: DummyResponses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
// Premade responses
|
||||
const responses: DummyResponses = {
|
||||
'https://api-backup1.local/foo': 'foo',
|
||||
};
|
||||
let counter = 0;
|
||||
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
||||
const query = redundancy.query(
|
||||
'/foo',
|
||||
(resource, payload, callback) => {
|
||||
counter++;
|
||||
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
||||
|
||||
// Make URI from resource + payload
|
||||
const uri = (resource as string) + (payload as string);
|
||||
// Make URI from resource + payload
|
||||
const uri = (resource as string) + (payload as string);
|
||||
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
// Get fake data if it exists
|
||||
if (responses[uri] === void 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(1);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1);
|
||||
fulfill(true);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Do something with "data", simulate instant callback
|
||||
callback('success', responses[uri]);
|
||||
|
||||
// Complete test
|
||||
setTimeout(() => {
|
||||
expect(counter).toEqual(1);
|
||||
expect(query().status).toEqual('completed');
|
||||
expect(redundancy.getIndex()).toEqual(1);
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Test find()
|
||||
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
||||
query
|
||||
);
|
||||
expect(redundancy.find((item) => item().status === 'pending')).toEqual(
|
||||
query
|
||||
);
|
||||
// Test find()
|
||||
expect(
|
||||
redundancy.find((item) => item().payload === '/foo')
|
||||
).toEqual(query);
|
||||
expect(
|
||||
redundancy.find((item) => item().status === 'pending')
|
||||
).toEqual(query);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
9
packages/api-redundancy/vitest.config.mjs
Normal file
9
packages/api-redundancy/vitest.config.mjs
Normal file
@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
watch: false,
|
||||
include: ['**/tests/*-test.ts'],
|
||||
},
|
||||
});
|
20808
pnpm-lock.yaml
20808
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user