Merge pull request #10 from servisbot/MVP-6967-bugfix-for-array

Fix for when after from function or change is an array
This commit is contained in:
Steve Walsh 2021-07-09 10:24:45 +01:00 committed by GitHub
commit 0e933af5ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 15 deletions

View File

@ -6,4 +6,17 @@ To make a change to the node-red runtime being used by K4 avalanche:
3. PR into this branch 3. PR into this branch
4. Merge on approval 4. Merge on approval
5. Manually bump the package version 5. Manually bump the package version
6. Manually publish to NPM with `npm publish` 6. Manually publish to NPM with `npm publish` - Request creds from ops for this
# CHANGE-LOG
## 0.18.7-patch-9
2021-07-09
- Bug fix for when retuning a array out of a function node
## 0.18.7-patch-8
2021-07-08
- Added support to log out when organization variable was changed within function or change node

View File

@ -8,7 +8,7 @@ const variablesToCheck = [
]; ];
module.exports = class PayloadValidator { module.exports = class PayloadValidator {
constructor(_before) { constructor(_before, id) {
try { try {
const before = clone(_before); const before = clone(_before);
const { const {
@ -20,6 +20,9 @@ module.exports = class PayloadValidator {
organization, organization,
region region
} }
},
event: {
workers: [{ id: workerId }]
} }
} = before; } = before;
this.before = before; this.before = before;
@ -28,9 +31,11 @@ module.exports = class PayloadValidator {
this.conversationId = conversationId; this.conversationId = conversationId;
this.organization = organization; this.organization = organization;
this.region = region; this.region = region;
this.workerId = workerId.split(':::')[0];
this.nodeId = id.split(`${organization}-${this.workerId}-`)[1];
this.isValidBefore = true; this.isValidBefore = true;
} catch (e) { } catch (e) {
console.log('Error while instantiating class with invalid object'); console.log('Error while instantiating class with invalid object for');
console.log(e); console.log(e);
this.isValidBefore = false; this.isValidBefore = false;
} }
@ -40,13 +45,19 @@ module.exports = class PayloadValidator {
return location.split('.').reduce((p, c) => (p && p[c]) || null, object); return location.split('.').reduce((p, c) => (p && p[c]) || null, object);
} }
verify(after) { verify(_after) {
if (this.isValidBefore) { if (this.isValidBefore) {
try { try {
let after = _after;
if (Array.isArray(after)) {
after = after.find((msg) => !!msg);
}
variablesToCheck.forEach((location) => { variablesToCheck.forEach((location) => {
if (this.getValue(this.before, location) !== this.getValue(after, location)) { if (this.getValue(this.before, location) !== this.getValue(after, location)) {
const details = { const details = {
message: `msg.${location} changed from "${this.getValue(this.before, location)}" to "${this.getValue(after, location)}" for bot "${this.bot}"` message: `msg.${location} changed from "${this.getValue(this.before, location)}" to "${this.getValue(after, location)}" for bot "${this.bot}"`,
nodeId: this.nodeId,
workerId: this.workerId
}; };
this.logger.error(details.message); this.logger.error(details.message);
this.logger.app.platform.organization({ this.logger.app.platform.organization({

View File

@ -209,7 +209,7 @@ module.exports = function(RED) {
try { try {
this.on("input", function(msg) { this.on("input", function(msg) {
try { try {
const payloadValidator = new PayloadValidator(msg) const payloadValidator = new PayloadValidator(msg, this.id)
var start = process.hrtime(); var start = process.hrtime();
sandbox.msg = msg; sandbox.msg = msg;
const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 }); const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 });

View File

@ -229,7 +229,7 @@ module.exports = function(RED) {
} }
if (valid) { if (valid) {
this.on('input', function(msg) { this.on('input', function(msg) {
const payloadValidator = new PayloadValidator(msg) const payloadValidator = new PayloadValidator(msg, this.id)
for (var i=0; i<this.rules.length; i++) { for (var i=0; i<this.rules.length; i++) {
if (this.rules[i].t === "move") { if (this.rules[i].t === "move") {
var r = this.rules[i]; var r = this.rules[i];

View File

@ -1,4 +1,4 @@
module.exports = (org) => ({ module.exports = (org, workerId = 'worker-id') => ({
logger: { logger: {
metadata: { metadata: {
organization: org organization: org
@ -13,6 +13,7 @@ module.exports = (org) => ({
}, },
}, },
event: { event: {
workers:[{id: `${workerId}:::something:::else`}],
event: { event: {
organization: org, organization: org,
token: { token: {

View File

@ -5,13 +5,17 @@ const assert = require('assert');
describe.only('Unit: PayloadValidator', () => { describe.only('Unit: PayloadValidator', () => {
it('Should not log when no changes', () => { it('Should not log when no changes', () => {
const beforeEvent = orgEvent('before'); const nodeId = 'abc-id'
const payloadValidator = new PayloadValidator(beforeEvent); const workerId = 'worker-id'
const beforeEvent = orgEvent('before', workerId);
const payloadValidator = new PayloadValidator(beforeEvent, `before-${workerId}-${nodeId}`);
payloadValidator.verify(beforeEvent); payloadValidator.verify(beforeEvent);
}); });
it('Should warn when org is overwritten', () => { it('Should warn when org is overwritten', () => {
const beforeEvent = orgEvent('before'); const nodeId = 'abc-id'
const workerId = 'worker-id'
const beforeEvent = orgEvent('before', workerId);
errorLogStub = sinon.stub(); errorLogStub = sinon.stub();
appLogStub = sinon.stub(); appLogStub = sinon.stub();
beforeEvent.logger.error = errorLogStub; beforeEvent.logger.error = errorLogStub;
@ -21,7 +25,7 @@ describe.only('Unit: PayloadValidator', () => {
} }
}; };
const payloadValidator = new PayloadValidator(beforeEvent); const payloadValidator = new PayloadValidator(beforeEvent, `before-${workerId}-${nodeId}`);
const modifiedEvent = orgEvent('after'); const modifiedEvent = orgEvent('after');
@ -30,14 +34,24 @@ describe.only('Unit: PayloadValidator', () => {
assert(appLogStub.callCount === 4) assert(appLogStub.callCount === 4)
const [[log1], [log2], [log3], [log4]] = appLogStub.args const [[log1], [log2], [log3], [log4]] = appLogStub.args
assert(log1.details.message.includes('logger.metadata.organization')) assert(log1.details.message.includes('logger.metadata.organization'))
assert.strictEqual(log1.details.nodeId, nodeId)
assert.strictEqual(log1.details.workerId, workerId)
assert(log2.details.message.includes('payload.system.organization')) assert(log2.details.message.includes('payload.system.organization'))
assert.strictEqual(log2.details.nodeId, nodeId)
assert.strictEqual(log2.details.workerId, workerId)
assert(log3.details.message.includes('event.event.organization')) assert(log3.details.message.includes('event.event.organization'))
assert.strictEqual(log3.details.nodeId, nodeId)
assert.strictEqual(log3.details.workerId, workerId)
assert(log4.details.message.includes('event.event.token.contents.organization')) assert(log4.details.message.includes('event.event.token.contents.organization'))
assert.strictEqual(log4.details.nodeId, nodeId)
assert.strictEqual(log4.details.workerId, workerId)
}); });
it('Should warn when org is deleted', () => { it('Should warn when org is deleted', () => {
const beforeEvent = orgEvent('before'); const nodeId = 'abc-id'
const workerId = 'worker-id'
const beforeEvent = orgEvent('before', workerId);
errorLogStub = sinon.stub(); errorLogStub = sinon.stub();
appLogStub = sinon.stub(); appLogStub = sinon.stub();
beforeEvent.logger.error = errorLogStub; beforeEvent.logger.error = errorLogStub;
@ -47,7 +61,8 @@ describe.only('Unit: PayloadValidator', () => {
} }
}; };
const payloadValidator = new PayloadValidator(beforeEvent); const payloadValidator = new PayloadValidator(beforeEvent, `before-${workerId}-${nodeId}`);
delete beforeEvent.logger.metadata.organization; delete beforeEvent.logger.metadata.organization;
delete beforeEvent.payload.system.organization; delete beforeEvent.payload.system.organization;
@ -58,10 +73,69 @@ describe.only('Unit: PayloadValidator', () => {
assert(appLogStub.callCount === 4) assert(appLogStub.callCount === 4)
const [[log1], [log2], [log3], [log4]] = appLogStub.args const [[log1], [log2], [log3], [log4]] = appLogStub.args
assert(log1.details.message.includes('logger.metadata.organization')) assert(log1.details.message.includes('logger.metadata.organization'))
assert.strictEqual(log1.details.nodeId, nodeId)
assert.strictEqual(log1.details.workerId, workerId)
assert(log2.details.message.includes('payload.system.organization')) assert(log2.details.message.includes('payload.system.organization'))
assert.strictEqual(log2.details.nodeId, nodeId)
assert.strictEqual(log2.details.workerId, workerId)
assert(log3.details.message.includes('event.event.organization')) assert(log3.details.message.includes('event.event.organization'))
assert.strictEqual(log3.details.nodeId, nodeId)
assert.strictEqual(log3.details.workerId, workerId)
assert(log4.details.message.includes('event.event.token.contents.organization')) assert(log4.details.message.includes('event.event.token.contents.organization'))
assert.strictEqual(log4.details.nodeId, nodeId)
assert.strictEqual(log4.details.workerId, workerId)
}); });
it('Should handle when after is an array', () =>{
const nodeId = 'abc-id'
const workerId = 'worker-id'
const beforeEvent = orgEvent('before', workerId);
errorLogStub = sinon.stub();
appLogStub = sinon.stub();
beforeEvent.logger.error = errorLogStub;
beforeEvent.logger.app = {
platform:{
organization: appLogStub
}
};
const payloadValidator = new PayloadValidator(beforeEvent, `before-${workerId}-${nodeId}`);
const modifiedEvent = orgEvent('before');
modifiedEvent.logger.metadata.organization = 'after'
payloadValidator.verify([modifiedEvent]);
assert(errorLogStub.callCount === 1)
assert(appLogStub.callCount === 1)
const [[log1]] = appLogStub.args
assert(log1.details.message.includes('logger.metadata.organization'))
assert.strictEqual(log1.details.nodeId, nodeId)
assert.strictEqual(log1.details.workerId, workerId)
})
it('Should handle when after is an array in something other than first position', () =>{
const nodeId = 'abc-id'
const workerId = 'worker-id'
const beforeEvent = orgEvent('before', workerId);
errorLogStub = sinon.stub();
appLogStub = sinon.stub();
beforeEvent.logger.error = errorLogStub;
beforeEvent.logger.app = {
platform:{
organization: appLogStub
}
};
const payloadValidator = new PayloadValidator(beforeEvent, `before-${workerId}-${nodeId}`);
const modifiedEvent = orgEvent('before');
modifiedEvent.logger.metadata.organization = 'after'
payloadValidator.verify([null, null, modifiedEvent, null]);
assert(errorLogStub.callCount === 1)
assert(appLogStub.callCount === 1)
const [[log1]] = appLogStub.args
assert(log1.details.message.includes('logger.metadata.organization'))
assert.strictEqual(log1.details.nodeId, nodeId)
assert.strictEqual(log1.details.workerId, workerId)
})
it('Should not die when error', () => { it('Should not die when error', () => {
const beforeEvent = orgEvent('before'); const beforeEvent = orgEvent('before');
@ -80,4 +154,6 @@ describe.only('Unit: PayloadValidator', () => {
const payloadValidator = new PayloadValidator({}); const payloadValidator = new PayloadValidator({});
payloadValidator.verify({}); payloadValidator.verify({});
}); });
}); });