mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
Pass the array describing the validation errors occuring with the InvalidMessage error throw and print it to the console.
196 lines
6.5 KiB
JavaScript
196 lines
6.5 KiB
JavaScript
const assert = require('assert').strict;
|
|
const events = require('events');
|
|
|
|
const link = require("lib/link");
|
|
const errors = require("lib/errors");
|
|
const schema = require("lib/schema");
|
|
const mock = require("../../mock");
|
|
|
|
|
|
describe("lib/link/link", function() {
|
|
describe("class Link", function() {
|
|
let testConnector;
|
|
let testLink;
|
|
|
|
before(function() {
|
|
testConnector = new mock.MockConnector();
|
|
testLink = new link.Link('source', 'target', testConnector);
|
|
testLink.setValidator('simple', schema.compile({
|
|
properties: {
|
|
"data": {
|
|
type: 'object',
|
|
properties: {
|
|
"string": { type: 'string' },
|
|
},
|
|
},
|
|
},
|
|
}));
|
|
});
|
|
|
|
it("should close connector on invalid messages", function() {
|
|
testConnector.sentMessages = [];
|
|
testConnector.emit('message', { invalid: true });
|
|
assert.deepEqual(
|
|
testConnector.sentMessages,
|
|
[{
|
|
seq: testConnector._seq - 1,
|
|
type: 'close',
|
|
data: { reason: "Invalid message: Malformed" },
|
|
}]
|
|
);
|
|
});
|
|
|
|
it("should disconnect on close", function() {
|
|
testConnector.disconnectCalled = false;
|
|
testConnector.emit('message', { seq: 1, type: 'close', data: { reason: "test" }});
|
|
assert(testConnector.disconnectCalled, "disconnect was not called");
|
|
});
|
|
|
|
it("should emitt error processing message to connector", async function() {
|
|
testLink.setHandler('throws', () => { throw new Error("Handler error"); }, () => true);
|
|
let result = events.once(testConnector, 'message');
|
|
testConnector.emit('message', { seq: 1, type: 'throws', data: {}});
|
|
await assert.rejects(result, new Error("Handler error"));
|
|
});
|
|
|
|
describe(".setValidator()", function() {
|
|
it("should set the validator", function() {
|
|
testLink.setValidator('test', () => true);
|
|
assert(testLink._validators.has('test'), "validator was not added");
|
|
});
|
|
it("should throw on duplicated validator", function() {
|
|
assert.throws(
|
|
() => testLink.setValidator('test', () => true),
|
|
new Error("test already has a validator")
|
|
);
|
|
});
|
|
});
|
|
|
|
describe(".setHandler()", function() {
|
|
it("should throw if validator is not passed", function() {
|
|
assert.throws(
|
|
() => testLink.setHandler('no_validator_test', (message) => {}),
|
|
new Error("validator is required")
|
|
);
|
|
});
|
|
it("should set the handler", function() {
|
|
let handler = (message) => {};
|
|
testLink.setHandler('handler_test', handler, (message) => true);
|
|
assert.equal(testLink._handlers.get('handler_test'), handler);
|
|
});
|
|
it("should throw on duplicated handler", function() {
|
|
assert.throws(
|
|
() => testLink.setHandler('handler_test', (message) => {}),
|
|
new Error("handler_test already has a handler")
|
|
);
|
|
});
|
|
});
|
|
|
|
describe(".processMessage()", function() {
|
|
it("should throw on invalid message", function() {
|
|
assert.throws(
|
|
() => testLink.processMessage({ data: "invalid message" }),
|
|
{ message: "Malformed" }
|
|
);
|
|
});
|
|
it("should throw on message without validator", function() {
|
|
assert.throws(
|
|
() => testLink.processMessage({ seq: 1, type: 'no_validator', data: {} }),
|
|
new errors.InvalidMessage("No validator for no_validator on source-target")
|
|
);
|
|
});
|
|
it("should throw on message failing validation", function() {
|
|
assert.throws(
|
|
() => testLink.processMessage({ seq: 1, type: 'simple', data: { string: 1 }}),
|
|
{ message: "Validation failed for simple" }
|
|
);
|
|
});
|
|
it("should throw on unhandled message", function() {
|
|
assert.throws(
|
|
() => testLink.processMessage({ seq: 1, type: 'simple', data: { string: "a" }}),
|
|
new errors.InvalidMessage("Unhandled message simple")
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("._processHandler()", function() {
|
|
it("should call the handler", function() {
|
|
let handled = [];
|
|
testLink.setHandler('handled', (message) => handled.push(message), (message) => true)
|
|
testLink._processHandler({ seq: 1, type: 'handled', data: { test: "foo" } });
|
|
assert.deepEqual(handled, [{ seq: 1, type: 'handled', data: { test: "foo" } }]);
|
|
});
|
|
it("should return true if handled", function() {
|
|
let result = testLink._processHandler({ seq: 1, type: 'handled', data: {} });
|
|
assert.equal(result, true);
|
|
});
|
|
it("should return false if not handled", function() {
|
|
let result = testLink._processHandler({ seq: 1, type: 'not_handled', data: {} });
|
|
assert.equal(result, false);
|
|
});
|
|
});
|
|
|
|
describe("._processWaiters()", function() {
|
|
it("should call waiters", async function() {
|
|
let waiter = new Promise(resolve => {
|
|
testLink._waiters.set('test', [{ resolve, data: {} }]);
|
|
});
|
|
assert(
|
|
testLink._processWaiters({ type: 'test', seq: 4, data: {} }),
|
|
"Waiter was not processed"
|
|
);
|
|
assert.deepEqual(await waiter, { type: 'test', seq: 4, data: {} });
|
|
});
|
|
it("should filter on data", async function() {
|
|
let waiter = new Promise(resolve => {
|
|
testLink._waiters.set('test', [{ resolve, data: { a: 1, b: 2 } }]);
|
|
});
|
|
assert(
|
|
!testLink._processWaiters({ type: 'test', seq: 4, data: {} }),
|
|
"Incorrectly matched empty message"
|
|
);
|
|
assert(
|
|
!testLink._processWaiters({ type: 'test', seq: 4, data: { a: 1, b: 0 } }),
|
|
"Incorrectly matched message with wrong data"
|
|
);
|
|
assert(
|
|
testLink._processWaiters({ type: 'test', seq: 4, data: { a: 1, b: 2, c: 3 } }),
|
|
"Did not match correct message"
|
|
);
|
|
assert.deepEqual(await waiter, { type: 'test', seq: 4, data: { a: 1, b: 2, c: 3 } });
|
|
});
|
|
});
|
|
|
|
describe(".waitFor()", function() {
|
|
before(function() {
|
|
testLink.setValidator('waiter', (message) => true);
|
|
});
|
|
|
|
it("should throw on missing validator", async function() {
|
|
await assert.rejects(
|
|
testLink.waitFor('no_validator', {}),
|
|
new Error("No validator for no_validator on source-target")
|
|
);
|
|
});
|
|
it("should wait for a given message", async function() {
|
|
let result = testLink.waitFor('waiter', {});
|
|
assert(
|
|
testLink._processWaiters({ type: 'waiter', seq: 5, data: {} }),
|
|
"Did not proccess waiter"
|
|
);
|
|
assert.deepEqual(await result, { type: 'waiter', seq: 5, data: {} });
|
|
});
|
|
it("should handle multiple waiters", async function() {
|
|
let result1 = testLink.waitFor('waiter', {});
|
|
let result2 = testLink.waitFor('waiter', {});
|
|
assert(
|
|
testLink._processWaiters({ type: 'waiter', seq: 5, data: {} }),
|
|
"Did not proccess waiter"
|
|
);
|
|
assert.deepEqual(await result1, { type: 'waiter', seq: 5, data: {} });
|
|
assert.deepEqual(await result2, { type: 'waiter', seq: 5, data: {} });
|
|
});
|
|
});
|
|
});
|
|
});
|