open-consul/ui-v2/tests/unit/utils/dom/event-source/blocking-test.js
John Cowen 45a2fa5a01 UI: Add blocking cursor validation and more straightforward throttle (#5470)
More recommendations for blocking queries clients was added here:

https://github.com/hashicorp/consul/pull/5358

This commit mainly adds cursor/index validation/correction based on
these recommendations (plus tests)

The recommendations also suggest that clients should include rate
limiting. Because of this, we've moved the throttling out of Consul UI
specific code and into Blocking Query specific code. Currently the 'rate
limiting' in this commit only adds a sleep to every iteration of the
loop, which is not the recommended approach, but the code here organizes
the throttling functionality into something we can work with later to
provide something more apt.
2019-05-01 18:22:21 +00:00

149 lines
3.9 KiB
JavaScript

import domEventSourceBlocking, {
validateCursor,
create5xxBackoff,
} from 'consul-ui/utils/dom/event-source/blocking';
import { module } from 'qunit';
import test from 'ember-sinon-qunit/test-support/test';
module('Unit | Utility | dom/event-source/blocking');
const createEventSource = function() {
return class {
constructor(cb) {
this.readyState = 1;
this.source = cb;
this.source.apply(this, arguments);
}
addEventListener() {}
removeEventListener() {}
dispatchEvent() {}
close() {}
};
};
const createPromise = function(resolve = function() {}) {
class PromiseMock {
constructor(cb = function() {}) {
cb(resolve);
}
then(cb) {
setTimeout(() => cb.bind(this)(), 0);
return this;
}
catch(cb) {
cb({ message: 'error' });
return this;
}
}
PromiseMock.resolve = function() {
return new PromiseMock();
};
return PromiseMock;
};
test('it creates an BlockingEventSource class implementing EventSource', function(assert) {
const EventSource = createEventSource();
const BlockingEventSource = domEventSourceBlocking(EventSource, function() {});
assert.ok(BlockingEventSource instanceof Function);
const source = new BlockingEventSource(function() {
return createPromise().resolve();
});
assert.ok(source instanceof EventSource);
});
test("the 5xx backoff continues to throw when it's not a 5xx", function(assert) {
const backoff = create5xxBackoff();
[
undefined,
null,
new Error(),
{ errors: [] },
{ errors: [{ status: '0' }] },
{ errors: [{ status: 501 }] },
{ errors: [{ status: '401' }] },
{ errors: [{ status: '500' }] },
{ errors: [{ status: '5' }] },
{ errors: [{ status: '50' }] },
{ errors: [{ status: '5000' }] },
{ errors: [{ status: '5050' }] },
].forEach(function(item) {
assert.throws(function() {
backoff(item);
});
});
});
test('the 5xx backoff returns a resolve promise on a 5xx (apart from 500)', function(assert) {
[
{ errors: [{ status: '501' }] },
{ errors: [{ status: '503' }] },
{ errors: [{ status: '504' }] },
{ errors: [{ status: '524' }] },
].forEach(item => {
const timeout = this.stub().callsArg(0);
const resolve = this.stub().withArgs(item);
const Promise = createPromise(resolve);
const backoff = create5xxBackoff(undefined, Promise, timeout);
const promise = backoff(item);
assert.ok(promise instanceof Promise, 'a promise was returned');
assert.ok(resolve.calledOnce, 'the promise was resolved with the correct arguments');
assert.ok(timeout.calledOnce, 'timeout was called once');
});
});
test("the cursor validation always returns undefined if the cursor can't be parsed to an integer", function(assert) {
['null', null, '', undefined].forEach(item => {
const actual = validateCursor(item);
assert.equal(actual, undefined);
});
});
test('the cursor validation always returns a cursor greater than zero', function(assert) {
[
{
cursor: 0,
expected: 1,
},
{
cursor: -10,
expected: 1,
},
{
cursor: -1,
expected: 1,
},
{
cursor: -1000,
expected: 1,
},
{
cursor: 10,
expected: 10,
},
].forEach(item => {
const actual = validateCursor(item.cursor);
assert.equal(actual, item.expected, 'cursor is greater than zero');
});
});
test('the cursor validation resets to 1 if its less than the previous cursor', function(assert) {
[
{
previous: 100,
cursor: 99,
expected: 1,
},
{
previous: 100,
cursor: -10,
expected: 1,
},
{
previous: 100,
cursor: 0,
expected: 1,
},
{
previous: 100,
cursor: 101,
expected: 101,
},
].forEach(item => {
const actual = validateCursor(item.cursor, item.previous);
assert.equal(actual, item.expected);
});
});