@condor-labs/ec-events-gateway
Version:
Client to send events to events gateway API
450 lines (360 loc) • 14.2 kB
JavaScript
const Joi = require('joi');
const { expect } = require('chai');
const sinon = require('sinon');
const validate = require('../validate');
const constants = require('../utils/constants');
const {
PAYLOAD_LARGE,
PAYLOAD_REQUIRED,
PAYLOAD_VALID,
BAD_PAYLOAD,
INVALID_SCHEMA,
MESSAGE_ATTRIBUTES
} = constants;
describe('Validate module', () => {
describe('When validateSize function is called', () => {
let stringifyStub = {};
let byteLengthStub = {};
const payload = {
someKey: 'some value'
};
const kilobytes = 100000000;
beforeEach(done => {
stringifyStub = sinon.stub(JSON, 'stringify').returns(payload);
byteLengthStub = sinon.stub(Buffer, 'byteLength');
done();
});
afterEach(done => {
stringifyStub.restore();
byteLengthStub.restore();
done();
});
it('Should calls JSON.stringify function once with the right params', done => {
validate.validateSize(payload);
expect(stringifyStub.calledOnce).to.be.true;
expect(stringifyStub.calledWith(payload)).to.be.true;
done();
});
it('Should calls Buffer.byteLength function once with the right params', done => {
validate.validateSize(payload);
expect(byteLengthStub.calledOnce).to.be.true;
expect(byteLengthStub.calledWith(payload, 'utf8')).to.be.true;
done();
});
it('Should return an object with the right properties when kilobytes exceed the maximum allowed', done => {
constants.MAX_PAYLOAD_SIZE = 100;
byteLengthStub.returns(kilobytes);
const expectedResult = {
error: true,
message: PAYLOAD_LARGE
};
const result = validate.validateSize(payload);
expect(typeof result).to.be.equal('object');
expect(result).to.be.deep.equal(expectedResult);
expect(Array.isArray(result)).to.be.false;
done();
});
it('Should return an object with the right properties when kilobytes exceed the maximum allowed', done => {
constants.MAX_PAYLOAD_SIZE = 100;
byteLengthStub.returns(100);
const expectedResult = {
error: false,
message: PAYLOAD_VALID
};
const result = validate.validateSize(payload);
expect(typeof result).to.be.equal('object');
expect(result).to.be.deep.equal(expectedResult);
expect(Array.isArray(result)).to.be.false;
done();
});
it('Should return an object with the right properties when kilobytes exceed the maximum allowed', done => {
constants.MAX_PAYLOAD_SIZE = 100;
byteLengthStub.throws(new Error('some error'));
const expectedResult = {
error: true,
message: BAD_PAYLOAD
};
const result = validate.validateSize(payload);
expect(typeof result).to.be.equal('object');
expect(result).to.be.deep.equal(expectedResult);
expect(Array.isArray(result)).to.be.false;
done();
});
});
describe('When isSchema function is called', () => {
let keysStub = {};
beforeEach(() => {
keysStub = sinon.stub(Object, 'keys')
});
afterEach(() => {
keysStub.restore();
});
it('Should returns false when schema parameter is not defined', () => {
const result = validate.isSchema();
expect(result).to.be.false;
});
it('Should calls Object.keys function once with the right param', () => {
keysStub.callsFake(() => ({ length: 1 }))
const schema = { someKey: 'some value' };
validate.isSchema(schema);
expect(keysStub.calledOnce).to.be.true;
expect(keysStub.calledWith(schema)).to.be.true;
});
it('Should calls function once with the right param', () => {
keysStub.callsFake(() => ({ length: 1 }))
const schema = { someKey: 'some value' };
validate.isSchema(schema);
expect(keysStub.calledOnce).to.be.true;
expect(keysStub.calledWith(schema)).to.be.true;
});
it('Should returns false when the schema passed as param does not have any key', () => {
keysStub.restore();
const schema = {};
const result = validate.isSchema(schema);
expect(result).to.be.false;
});
it('Should returns false when the first key of the schema passed as param is not an object', () => {
const schema = { someKey: 'some value' };
keysStub.returns(['someKey']);
const result = validate.isSchema(schema);
expect(result).to.be.false;
});
it('Should returns false when the schema passed as param is not a valid joi schema', () => {
const schema = {
someKey: {
child: true
}
};
keysStub.returns(['someKey']);
const result = validate.isSchema(schema);
expect(result).to.be.false;
});
it('Should return true when the schema passed as parameter is a Joi valid schema', () => {
keysStub.restore();
const schema = {
type: Joi.string().required(),
data: Joi.object(),
topic: Joi.string().required()
};
const result = validate.isSchema(schema);
expect(result).to.be.true;
});
});
describe('When validateSchema function is called', () => {
let isSchemaStub = {};
let unhandledErrorStub = {};
beforeEach(() => {
isSchemaStub = sinon.stub(validate, 'isSchema');
unhandledErrorStub = sinon.stub(constants, 'unhandledError');
});
afterEach(() => {
isSchemaStub.restore();
unhandledErrorStub.restore();
});
it('Should calls isSchema function once with the right params', () => {
const schema = {
type: 'Joi.string().required()'
};
validate.validateSchema(schema);
expect(isSchemaStub.calledOnce).to.be.true;
expect(isSchemaStub.calledWith(schema)).to.be.true;
});
it(`Should returns an object with an error property and the message ${INVALID_SCHEMA} when schema param is not a valid object`, () => {
isSchemaStub.returns(false);
const expectedResult = { error: INVALID_SCHEMA };
const schema = {
type: 'Joi.string().required()'
};
const result = validate.validateSchema(schema);
expect(result).to.be.deep.equal(expectedResult);
});
it(`Should returns true when schema param is a valid joi object`, () => {
isSchemaStub.returns(true);
const schema = {
type: Joi.string().required()
};
const result = validate.validateSchema(schema);
expect(result).to.be.true;
});
it('Should calls unhandledError function once with the right param and returns an object with an error property', () => {
const error = new Error('an error occurred');
isSchemaStub.returns(false);
isSchemaStub.throws(error);
const schema = {
type: Joi.string().required()
};
validate.validateSchema(schema);
expect(unhandledErrorStub.calledOnce).to.be.true;
expect(unhandledErrorStub.calledWith(error.message)).to.be.true;
});
});
describe('When validateParams function is called', () => {
let validateSchemaStub = {};
let unhandledErrorStub = {};
beforeEach(() => {
validateSchemaStub = sinon.stub(validate, 'validateSchema');
unhandledErrorStub = sinon.stub(constants, 'unhandledError');
});
afterEach(() => {
validateSchemaStub.restore();
unhandledErrorStub.restore();
});
it(`Should return an object with an error propery and the message ${PAYLOAD_REQUIRED} when data parameter is not defined`, () => {
const expectedResult = { error: PAYLOAD_REQUIRED };
const result = validate.validateParams();
expect(result).to.be.deep.equal(expectedResult);
});
it('Should calls validateSchema once with the right params when clientSchema is defined', () => {
validateSchemaStub.returns({});
const data = { someKey: 'some data' };
const clientSchema = { someKey: Joi.string() };
validate.validateParams(data, clientSchema);
expect(validateSchemaStub.calledOnce).to.be.true;
expect(validateSchemaStub.calledWith(clientSchema)).to.be.true;
});
it('Should return an object with an error property when validateSchema return any error', () => {
const error = { error: 'any error' };
validateSchemaStub.returns(error);
const data = 'some data';
const clientSchema = { someKey: 'some value' };
const result = validate.validateParams(data, clientSchema);
expect(result).to.be.deep.equal(error);
});
it('Should the joi response when the schema is invalid', () => {
const expectedResult = [{ "context": { "label": "value", "type": "object", "value": "some data" }, "message": "\"value\" must be of type object", "path": [], "type": "object.base" }]
const data = 'some data';
const clientSchema = {
destination: Joi.string().required()
};
const result = validate.validateParams(data, clientSchema);
expect(result).to.be.deep.equal(expectedResult);
});
it('Should return null when no error occurs validating parameters', () => {
const data = { type: "type", topic: "topic", data: {} };
const result = validate.validateParams(data);
expect(result).to.be.equal(null);
});
it('Should return errors details when an error occurs validating parameters', () => {
const validation = {
error: {
details: [{ "context": { "label": "value", "type": "object", "value": "some data" }, "message": "\"value\" must be of type object", "path": [], "type": "object.base" }]
}
};
const data = 'some data';
const result = validate.validateParams(data);
expect(result).to.be.deep.equal(validation.error.details);
});
it('Should calls unhandledError function once with the right param and returns an object with an error property', () => {
const error = new Error('an error occurred');
validateSchemaStub.throws(error);
const schema = { someKey: Joi.string() }
const data = 'some data';
validate.validateParams(data, schema);
expect(unhandledErrorStub.calledOnce).to.be.true;
expect(unhandledErrorStub.calledWith(error.message)).to.be.true;
});
});
describe('When validateData function is called', () => {
let unhandledErrorStub = {};
let validateSizeStub = {}
beforeEach(() => {
unhandledErrorStub = sinon.stub(constants, 'unhandledError');
validateSizeStub = sinon.stub(validate, 'validateSize');
});
afterEach(() => {
unhandledErrorStub.restore();
validateSizeStub.restore();
});
it(`Should returns an object with an error property with the message ${PAYLOAD_REQUIRED} when data parameter is not defined`, () => {
validateSizeStub.returns({});
const expectedResult = { error: PAYLOAD_REQUIRED };
const result = validate.validateData();
expect(result).to.be.deep.equal(expectedResult);
});
it('Should calls validateSize function once with the right params when data parameter is specified', () => {
validateSizeStub.returns({});
const data = 'some data';
validate.validateData(data);
expect(validateSizeStub.calledOnce).to.be.true;
expect(validateSizeStub.calledWith(data)).to.be.true;
});
it('Should returns an object with an error property when validateSize returns an error', () => {
const validateSizeError = { error: true, message: 'some error' };
validateSizeStub.returns(validateSizeError);
const data = 'some data';
const result = validate.validateData(data);
expect(result).to.be.deep.equal({ error: validateSizeError.message });
});
it('#validateData When data is valid for data schema', () => {
const data = {
topic: "topic",
message: {},
messageAttributes: {
name: "name",
type: "type",
dataType: "dataType"
}
};
const result = validate.validateData(data);
expect(result).to.be.equal(null);
});
it('Should return null when no error occurs validating parameters', () => {
const data = {
topic: "topic",
message: {},
messageAttributes: {
name: "name",
type: "type",
dataType: "dataType"
}
};
const result = validate.validateData(data);
expect(result).to.be.equal(null);
});
it('Should return errors details when an error occurs validating parameters', done => {
const validation = {
error: {
details: [{ "context": { "label": "value", "type": "object", "value": "some data" }, "message": "\"value\" must be of type object", "path": [], "type": "object.base" }]
}
};
const data = 'some data';
const result = validate.validateData(data);
expect(result).to.be.deep.equal(validation.error.details);
done();
});
it('Should calls unhandledError function once with the right param and returns an object with an error property', () => {
const error = new Error('an error occurred');
const objectStub = sinon.stub(Joi, 'object')
objectStub.throws(error);
const data = 'some data';
validate.validateData(data);
expect(unhandledErrorStub.calledOnce).to.be.true;
expect(unhandledErrorStub.calledWith(error.message)).to.be.true;
objectStub.restore();
});
});
describe('When formatData is called', () => {
it('Should returns an object with the right properties', done => {
const data = {
type: 'some type',
topic: 'some topic',
data: {
someKey: 'some value'
}
};
const messageAttributes = Object.assign(MESSAGE_ATTRIBUTES, {
type: data.type
});
const expectedResult = {
topic: data.topic,
message: data.data,
messageAttributes
};
const result = validate.formatData(data);
expect(typeof result === 'object').to.be.true;
expect(Array.isArray(result)).to.be.false;
expect(result).to.be.deep.equal(expectedResult);
done();
});
});
});