mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'dev' into pr_2570
This commit is contained in:
@@ -488,6 +488,77 @@ describe('inject node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should inject multiple properties ', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", props: [{p:"topic", v:"t1", vt:"str"}, {p:"payload", v:"foo", vt:"str"}, {p:"x", v: 10, "vt":"num"}, {p:"y", v: "x+2", "vt":"jsonata"}], wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "foo");
|
||||
msg.should.have.property("x", 10);
|
||||
msg.should.have.property("y", 12);
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
it('should inject multiple properties using legacy props if needed', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", payload:"123", payloadType:"num", topic:"foo", props: [{p:"topic", vt:"str"}, {p:"payload"}], wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "foo");
|
||||
msg.should.have.property("payload", 123);
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should report invalid JSONata expression', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", props: [{p:"topic", v:"t1", vt:"str"}, {p:"payload", v:"@", vt:"jsonata"}], wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.not.have.property("payload");
|
||||
count++;
|
||||
if (count == 2) {
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.on("call:error", function(err) {
|
||||
count++;
|
||||
if (count == 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('post', function() {
|
||||
it('should inject message', function(done) {
|
||||
helper.load(injectNode,
|
||||
|
@@ -53,7 +53,6 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should be loaded', function(done) {
|
||||
var flow = [{id:"n1", type:"function", name: "function" }];
|
||||
helper.load(functionNode, flow, function() {
|
||||
@@ -1336,6 +1335,46 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute initialization', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = global.get('X'); return msg;",initialize:"global.set('X','bar');"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property("payload", "bar");
|
||||
done();
|
||||
});
|
||||
n1.receive({payload: "foo"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should wait completion of initialization', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = global.get('X'); return msg;",initialize:"global.set('X', '-'); return new Promise((resolve, reject) => setTimeout(() => { global.set('X','bar'); resolve(); }, 500));"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property("payload", "bar");
|
||||
done();
|
||||
});
|
||||
n1.receive({payload: "foo"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute finalization', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[],func:"return msg;",finalize:"global.set('X','bar');"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var ctx = n1.context().global;
|
||||
helper.unload().then(function () {
|
||||
ctx.get('X').should.equal("bar");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logger', function () {
|
||||
it('should log an Info Message', function (done) {
|
||||
var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.log('test');"}];
|
||||
|
@@ -102,20 +102,20 @@ describe('trigger node', function() {
|
||||
function basicTest(type, val, rval) {
|
||||
it('should output 1st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
@@ -127,7 +127,7 @@ describe('trigger node', function() {
|
||||
|
||||
it('should output 2st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -136,17 +136,17 @@ describe('trigger node', function() {
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.property("payload", "foo");
|
||||
msg.should.have.property("payload", "foo");
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
@@ -378,6 +378,51 @@ describe('trigger node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle multiple other properties individually if asked to do so', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", topic:"foo", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
c += 1;
|
||||
if (c === 1) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "A");
|
||||
}
|
||||
else if (c === 2) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "B");
|
||||
}
|
||||
else if (c === 3) {
|
||||
msg.should.have.a.property("payload", 1);
|
||||
msg.should.have.a.property("foo", "C");
|
||||
}
|
||||
else if (c === 4) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "A");
|
||||
}
|
||||
else if (c === 5) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "B");
|
||||
}
|
||||
else if (c === 6) {
|
||||
msg.should.have.a.property("payload", 0);
|
||||
msg.should.have.a.property("foo", "C");
|
||||
done();
|
||||
}
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.emit("input", {payload:1,foo:"A"});
|
||||
n1.emit("input", {payload:2,foo:"B"});
|
||||
n1.emit("input", {payload:3,foo:"C"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from flow and global context variables', function(done) {
|
||||
var spy = sinon.stub(RED.util, 'evaluateNodeProperty',
|
||||
function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } }
|
||||
@@ -408,8 +453,8 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from persistable flow and global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow",
|
||||
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -442,11 +487,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "global",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "global",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -481,11 +526,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable flow context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "flow"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "flow"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -520,11 +565,11 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from multiple persistable flow & global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -818,6 +863,40 @@ describe('trigger node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to send 2nd message to a 2nd output', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"hello", op2:"world", duration:"50", outputs:2, wires:[["n2"],["n3"]] },
|
||||
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var n3 = helper.getNode("n3");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.a.property("payload", "hello");
|
||||
msg.should.have.a.property("topic", "test");
|
||||
c+=1;
|
||||
}
|
||||
else { done(err); }
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n3.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 1) {
|
||||
msg.should.have.a.property("payload", "world");
|
||||
msg.should.have.a.property("topic", "test");
|
||||
done();
|
||||
}
|
||||
else { done(err); }
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n1.emit("input", {payload:"go",topic:"test"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle string null as null', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"pay", op1:"null", op2:"null", duration:"40", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-undef */
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
@@ -70,12 +71,13 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert a simple csv string to a javascript object', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('payload', { a: 1, b: 2, c: 3, d: 4 });
|
||||
msg.should.have.property('columns', "a,b,c,d");
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
@@ -86,7 +88,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should remove quotes and whitespace from template', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:'"a", "b" , " c "," d " ', wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -102,12 +104,13 @@ describe('CSV node', function() {
|
||||
|
||||
it('should create column names if no template provided', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:'', wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('payload', { col1: 1, col2: 2, col3: 3, col4: 4 });
|
||||
msg.should.have.property('columns', "col1,col2,col3,col4");
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
@@ -118,12 +121,13 @@ describe('CSV node', function() {
|
||||
|
||||
it('should allow dropping of fields from the template', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,,,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('payload', { a: 1, d: 4 });
|
||||
msg.should.have.property('columns', 'a,d');
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
@@ -134,7 +138,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should leave numbers starting with 0, e and + as strings (except 0.)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -150,7 +154,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should not parse numbers when told not to do so', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", strings:false, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -166,7 +170,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should leave handle strings with scientific notation as numbers', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -181,44 +185,128 @@ describe('CSV node', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should allow quotes in the input', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
it('should allow quotes in the input (but drop blank strings)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g,h", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: '04', e: '-05', f: 'ab"cd', g: 'with,a,comma' });
|
||||
msg.should.have.property('payload', { a:1, b:-2, c:'+3', d:'04', f:'-05', g:'ab"cd', h:'with,a,comma' });
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = '"1","-2","+3","04","-05","ab""cd","with,a,comma"'+String.fromCharCode(10);
|
||||
var testString = '"1","-2","+3","04","","-05","ab""cd","with,a,comma"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow blank strings in the input if selected', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", include_empty_strings:true, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
msg.should.have.property('payload', { a: 1, b: '', c: '', d: '', e: '-05', f: 'ab"cd', g: 'with,a,comma' });
|
||||
//check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = '"1","","","","-05","ab""cd","with,a,comma"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow missing columns (nulls) in the input if selected', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", include_null_values:true, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
msg.should.have.property('payload', { a: 1, b: null, c: '+3', d: null, e: '-05', f: 'ab"cd', g: 'with,a,comma' });
|
||||
//check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = '"1",,"+3",,"-05","ab""cd","with,a,comma"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle cr and lf in the input', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
msg.should.have.property('payload', { a: "with a\nnew line", b: "and a\rcarriage return", c: "and why\r\nnot both"});
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = '"with a'+String.fromCharCode(10)+'new line","and a'+String.fromCharCode(13)+'carriage return","and why\r\nnot both"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should recover from an odd number of quotes in the input', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes" });
|
||||
//msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: 4, e: -5, f: 'ab"cd', g: 'with,a,comma' });
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
if (c == 0) {
|
||||
c = 1;
|
||||
msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes\n" });
|
||||
check_parts(msg, 0, 1);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property('payload', { a: "this is", b: "a normal", c: "line" });
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
n1.emit("input", {payload:'"this is","a normal","line"'});
|
||||
});
|
||||
});
|
||||
|
||||
it('should recover from an odd number of quotes in the input (2)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg)
|
||||
if (c == 0) {
|
||||
c = 1;
|
||||
msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes\nthis is,a normal,line" });
|
||||
check_parts(msg, 0, 1);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property('payload', { a: "this is", b: "another", c: "line" });
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10)+'"this is","a normal","line"'+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
n1.emit("input", {payload:'"this is","another","line"'});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to use the first line as a template', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrin:true, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -243,12 +331,13 @@ describe('CSV node', function() {
|
||||
|
||||
it('should be able to output multiple lines as one array', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", multi:"yes", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('payload', [ { a: 1, b: 2, c: 3, d: 4 },{ a: 5, b: -6, c: '07', d: '+8' },{ a: 9, b: 0, c: 'a', d: 'b' },{ a: 'c', b: 'd', c: 'e', d: 'f' } ]);
|
||||
msg.should.have.property('columns','a,b,c,d');
|
||||
msg.should.not.have.property('parts');
|
||||
done();
|
||||
});
|
||||
@@ -259,7 +348,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should handle numbers in strings but not IP addresses', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -275,7 +364,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should preserve parts property', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -319,7 +408,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should skip several lines from start if requested', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -333,9 +422,9 @@ describe('CSV node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip several lines from start then use next line as a tempate', function(done) {
|
||||
it('should skip several lines from start then use next line as a template', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrin:true, skip: 2, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -351,7 +440,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should skip several lines from start and correct parts', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -383,11 +472,13 @@ describe('CSV node', function() {
|
||||
n2.on("input", function(msg) {
|
||||
if (c === 0) {
|
||||
msg.should.have.property('payload', { w: 1, x: 2, y: 3, z: 4 });
|
||||
msg.should.have.property('columns', 'w,x,y,z');
|
||||
check_parts(msg, 0, 2);
|
||||
c += 1;
|
||||
}
|
||||
else {
|
||||
msg.should.have.property('payload', { w: 5, x: 6, y: 7, z: 8 });
|
||||
msg.should.have.property('columns', 'w,x,y,z');
|
||||
check_parts(msg, 1, 2);
|
||||
done();
|
||||
}
|
||||
@@ -411,7 +502,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert a simple object back to a csv', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,,e", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -429,7 +520,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert a simple object back to a csv with no template', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:" ", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -447,7 +538,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should handle a template with spaces in the property names', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b o,c p,,e", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -465,7 +556,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert an array of objects to a multi-line csv', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -483,7 +574,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert a simple array back to a csv', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -501,7 +592,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should convert an array of arrays back to a multi-line csv', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -519,7 +610,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should be able to include column names as first row', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrout:true, ret:"\r\n", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -535,9 +626,36 @@ describe('CSV node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to pass in column names', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"", hdrout:"once", ret:"\r\n", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function(msg) {
|
||||
count += 1;
|
||||
try {
|
||||
if (count === 1) {
|
||||
msg.should.have.property('payload', 'a,,b,a\r\n4,,3,4\r\n');
|
||||
}
|
||||
if (count === 3) {
|
||||
msg.should.have.property('payload', '4,,3,4\r\n');
|
||||
done()
|
||||
}
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
var testJson = [{ d: 1, b: 3, c: 2, a: 4 }];
|
||||
n1.emit("input", {payload:testJson, columns:"a,,b,a"});
|
||||
n1.emit("input", {payload:testJson});
|
||||
n1.emit("input", {payload:testJson});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle quotes and sub-properties', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -557,7 +675,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should just pass through if no payload provided', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -577,7 +695,7 @@ describe('CSV node', function() {
|
||||
|
||||
it('should warn if provided a number or boolean', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(csvNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
|
@@ -107,13 +107,18 @@ describe('BATCH node', function() {
|
||||
}
|
||||
}
|
||||
|
||||
function delayed_send(receiver, index, count, delay) {
|
||||
function delayed_send(receiver, index, count, delay, done) {
|
||||
if (index < count) {
|
||||
setTimeout(function() {
|
||||
receiver.receive({payload: index});
|
||||
delayed_send(receiver, index+1, count, delay);
|
||||
delayed_send(receiver, index+1, count, delay, done);
|
||||
}, delay);
|
||||
}
|
||||
else if(index === count) {
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function check_interval(flow, results, delay, done) {
|
||||
@@ -198,10 +203,28 @@ describe('BATCH node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle reset', function(done) {
|
||||
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 2, overlap: 0, interval: 0, allowEmptySequence: false, topics: [], wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(batchNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var results = [
|
||||
[0, 1],
|
||||
[4, 5]
|
||||
];
|
||||
check_data(n1, n2, results, done);
|
||||
n1.receive({payload:0});
|
||||
n1.receive({payload:1});
|
||||
n1.receive({payload:2});
|
||||
n1.receive({payload:3, reset: true});
|
||||
n1.receive({payload:4});
|
||||
n1.receive({payload:5});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mode: interval', function() {
|
||||
|
||||
it('should create seq. with interval', function(done) {
|
||||
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -265,10 +288,29 @@ describe('BATCH node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle reset', function(done) {
|
||||
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(batchNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var results = [
|
||||
[0, 1],
|
||||
[4, 5]
|
||||
];
|
||||
check_data(n1, n2, results, done);
|
||||
delayed_send(n1, 0, 3, 400, function () {
|
||||
setTimeout(function () {
|
||||
n1.receive({payload: "3", reset: true});
|
||||
delayed_send(n1, 4, 7, 400);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('mode: concat', function() {
|
||||
|
||||
it('should concat two seq. (series)', function(done) {
|
||||
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -355,6 +397,58 @@ describe('BATCH node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle reset', function(done) {
|
||||
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
try {
|
||||
helper.load(batchNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var results = [
|
||||
[2, 3, 0, 1]
|
||||
];
|
||||
check_data(n1, n2, results, done);
|
||||
var inputs0 = [
|
||||
["TB", 0, 0, 2],
|
||||
["TA", 1, 0, 2],
|
||||
];
|
||||
for(var data of inputs0) {
|
||||
var msg = {
|
||||
topic: data[0],
|
||||
payload: data[1],
|
||||
parts: {
|
||||
id: data[0],
|
||||
index: data[2],
|
||||
count: data[3]
|
||||
}
|
||||
};
|
||||
n1.receive(msg);
|
||||
}
|
||||
n1.receive({payload: undefined, reset: true});
|
||||
var inputs1 = [
|
||||
["TB", 0, 0, 2],
|
||||
["TB", 1, 1, 2],
|
||||
["TA", 2, 0, 2],
|
||||
["TA", 3, 1, 2]
|
||||
];
|
||||
for(var data of inputs1) {
|
||||
var msg = {
|
||||
topic: data[0],
|
||||
payload: data[1],
|
||||
parts: {
|
||||
id: data[0],
|
||||
index: data[2],
|
||||
count: data[3]
|
||||
}
|
||||
};
|
||||
n1.receive(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -447,117 +447,4 @@ describe('subflow', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should access env var type of subflow instance', function(done) {
|
||||
var flow = [
|
||||
{id:"t0", type:"tab", label:"", disabled:false, info:""},
|
||||
{id:"n1", x:10, y:10, z:"t0", type:"subflow:s1",
|
||||
env: [
|
||||
{name: "K", type: "str", value: "V"}
|
||||
],
|
||||
wires:[["n2"]]},
|
||||
{id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]},
|
||||
// Subflow
|
||||
{id:"s1", type:"subflow", name:"Subflow", info:"",
|
||||
in:[{
|
||||
x:10, y:10,
|
||||
wires:[ {id:"s1-n1"} ]
|
||||
}],
|
||||
out:[{
|
||||
x:10, y:10,
|
||||
wires:[ {id:"s1-n1", port:0} ]
|
||||
}]
|
||||
},
|
||||
{id:"s1-n1", x:10, y:10, z:"s1", type:"function",
|
||||
func:"msg.V = env.get('K_type'); return msg;",
|
||||
wires:[]}
|
||||
];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("V", "str");
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should access env var info of subflow instance', function(done) {
|
||||
var flow = [
|
||||
{id:"t0", type:"tab", label:"", disabled:false, info:""},
|
||||
{id:"n1", x:10, y:10, z:"t0", type:"subflow:s1",
|
||||
env: [
|
||||
{name: "K", type: "str", value: "V"}
|
||||
],
|
||||
wires:[["n2"]]},
|
||||
{id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]},
|
||||
// Subflow
|
||||
{id:"s1", type:"subflow", name:"Subflow", info:"",
|
||||
in:[{
|
||||
x:10, y:10,
|
||||
wires:[ {id:"s1-n1"} ]
|
||||
}],
|
||||
out:[{
|
||||
x:10, y:10,
|
||||
wires:[ {id:"s1-n1", port:0} ]
|
||||
}],
|
||||
env:[
|
||||
{
|
||||
name: "K", type: "str", value: "",
|
||||
ui: {
|
||||
hasUI: true,
|
||||
icon: "icon",
|
||||
labels: {
|
||||
"en-US": "label"
|
||||
},
|
||||
type: "input",
|
||||
inputTypes: {
|
||||
str: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{id:"s1-n1", x:10, y:10, z:"s1", type:"function",
|
||||
func:"msg.V = env.get('K_info'); return msg;",
|
||||
wires:[]}
|
||||
];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("V");
|
||||
var v = msg.V;
|
||||
v.should.have.property("name", "K");
|
||||
v.should.have.property("value", "V");
|
||||
v.should.have.property("type", "str");
|
||||
v.should.have.property("ui");
|
||||
var ui = v.ui;
|
||||
ui.should.have.property("hasUI", true);
|
||||
ui.should.have.property("icon", "icon");
|
||||
ui.should.have.property("type", "input");
|
||||
ui.should.have.property("labels");
|
||||
var labels = ui.labels;
|
||||
labels.should.have.property("en-US", "label");
|
||||
ui.should.have.property("inputTypes");
|
||||
var types = ui.inputTypes;
|
||||
types.should.have.property("str", true);
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo"});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -227,7 +227,7 @@ describe("api/admin/nodes", function() {
|
||||
});
|
||||
request(app)
|
||||
.post('/nodes')
|
||||
.send({module: 'foo',version:"1.2.3"})
|
||||
.send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
|
||||
.expect(200)
|
||||
.end(function(err,res) {
|
||||
if (err) {
|
||||
@@ -238,6 +238,7 @@ describe("api/admin/nodes", function() {
|
||||
res.body.nodes[0].should.have.property("id","123");
|
||||
opts.should.have.property("module","foo");
|
||||
opts.should.have.property("version","1.2.3");
|
||||
opts.should.have.property("url","https://example/foo-1.2.3.tgz");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -256,7 +257,7 @@ describe("api/admin/nodes", function() {
|
||||
});
|
||||
request(app)
|
||||
.post('/nodes')
|
||||
.send({module: 'foo',version:"1.2.3"})
|
||||
.send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
|
||||
.expect(400)
|
||||
.end(function(err,res) {
|
||||
if (err) {
|
||||
|
@@ -129,6 +129,61 @@ describe("api/auth/strategies", function() {
|
||||
})
|
||||
});
|
||||
|
||||
describe("Tokens Strategy", function() {
|
||||
it('Succeeds if tokens user enabled custom header',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function(token) {
|
||||
return when.resolve("tokens-"+token);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "x-test-token";
|
||||
});
|
||||
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
|
||||
strategies.tokensStrategy.success = function(user) {
|
||||
user.should.equal("tokens-1234");
|
||||
strategies.tokensStrategy.success = strategies.tokensStrategy._success;
|
||||
delete strategies.tokensStrategy._success;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"x-test-token":"1234"}});
|
||||
});
|
||||
it('Succeeds if tokens user enabled default header',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function(token) {
|
||||
return when.resolve("tokens-"+token);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "authorization";
|
||||
});
|
||||
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
|
||||
strategies.tokensStrategy.success = function(user) {
|
||||
user.should.equal("tokens-1234");
|
||||
strategies.tokensStrategy.success = strategies.tokensStrategy._success;
|
||||
delete strategies.tokensStrategy._success;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
|
||||
});
|
||||
it('Fails if tokens user not enabled',function(done) {
|
||||
var userTokens = sinon.stub(Users,"tokens",function() {
|
||||
return when.resolve(null);
|
||||
});
|
||||
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
|
||||
return "authorization";
|
||||
});
|
||||
strategies.tokensStrategy._fail = strategies.tokensStrategy.fail;
|
||||
strategies.tokensStrategy.fail = function(err) {
|
||||
err.should.equal(401);
|
||||
strategies.tokensStrategy.fail = strategies.tokensStrategy._fail;
|
||||
delete strategies.tokensStrategy._fail;
|
||||
done();
|
||||
};
|
||||
strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
|
||||
});
|
||||
afterEach(function() {
|
||||
Users.tokens.restore();
|
||||
Users.tokenHeader.restore();
|
||||
})
|
||||
});
|
||||
|
||||
describe("Bearer Strategy", function() {
|
||||
it('Rejects invalid token',function(done) {
|
||||
var getToken = sinon.stub(Tokens,"get",function(token) {
|
||||
|
@@ -227,4 +227,47 @@ describe("api/auth/users", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Initialised with tokens set as function',function() {
|
||||
before(function() {
|
||||
Users.init({
|
||||
type:"strategy",
|
||||
tokens: function(token) { return("Done-"+token); }
|
||||
});
|
||||
});
|
||||
after(function() {
|
||||
Users.init({});
|
||||
});
|
||||
describe('#tokens',function() {
|
||||
it('handles api.tokens being a function',function(done) {
|
||||
Users.should.have.property('tokens').which.is.a.Function();
|
||||
(Users.tokens("1234")).should.equal("Done-1234");
|
||||
(Users.tokenHeader()).should.equal("authorization");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Initialised with tokens set as function and tokenHeader set as token header name',function() {
|
||||
before(function() {
|
||||
Users.init({
|
||||
type:"strategy",
|
||||
tokens: function(token) { return("Done-"+token); },
|
||||
tokenHeader: "X-TEST-TOKEN"
|
||||
});
|
||||
});
|
||||
after(function() {
|
||||
Users.init({});
|
||||
});
|
||||
describe('#tokens',function() {
|
||||
it('handles api.tokens being a function and api.tokenHeader being a header name',function(done) {
|
||||
Users.should.have.property('tokens').which.is.a.Function();
|
||||
(Users.tokens("1234")).should.equal("Done-1234");
|
||||
Users.should.have.property('tokenHeader').which.is.a.Function();
|
||||
(Users.tokenHeader()).should.equal("x-test-token");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -121,6 +121,17 @@ describe('nodes/registry/installer', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("rejects when update requested to existing version and url", function(done) {
|
||||
sinon.stub(typeRegistry,"getModuleInfo", function() {
|
||||
return {
|
||||
version: "0.1.1"
|
||||
}
|
||||
});
|
||||
installer.installModule("this_wont_exist","0.1.1","https://example/foo-0.1.1.tgz").catch(function(err) {
|
||||
err.code.should.be.eql('module_already_loaded');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("rejects with generic error", function(done) {
|
||||
var res = {
|
||||
code: 1,
|
||||
@@ -201,6 +212,29 @@ describe('nodes/registry/installer', function() {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
it("succeeds when url is valid node-red module", function(done) {
|
||||
var nodeInfo = {nodes:{module:"foo",types:["a"]}};
|
||||
|
||||
var res = {
|
||||
code: 0,
|
||||
stdout:"",
|
||||
stderr:""
|
||||
}
|
||||
var p = Promise.resolve(res);
|
||||
p.catch((err)=>{});
|
||||
initInstaller(p)
|
||||
|
||||
var addModule = sinon.stub(registry,"addModule",function(md) {
|
||||
return when.resolve(nodeInfo);
|
||||
});
|
||||
|
||||
installer.installModule("this_wont_exist",null,"https://example/foo-0.1.1.tgz").then(function(info) {
|
||||
info.should.eql(nodeInfo);
|
||||
done();
|
||||
}).catch(function(err) {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
describe("uninstalls module", function() {
|
||||
|
@@ -150,7 +150,7 @@ describe('flows/util', function() {
|
||||
{id:"t1",type:"tab"}
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"missingTypes":[]};
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"groups":{},"missingTypes":[]};
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ describe('flows/util', function() {
|
||||
{id:"t1",type:"tab"}
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]};
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"groups":{},"missingTypes":[]};
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
@@ -173,7 +173,7 @@ describe('flows/util', function() {
|
||||
{id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t2":{"id":"t2","type":"tab"},"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}},"t2":{"id":"t2","type":"tab","subflows":{},"configs":{},"nodes":{"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}}}},"missingTypes":[]};
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t2":{"id":"t2","type":"tab"},"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}},"t2":{"id":"t2","type":"tab","subflows":{},"configs":{},"nodes":{"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}}}},"groups":{},"missingTypes":[]};
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
@@ -185,7 +185,7 @@ describe('flows/util', function() {
|
||||
{id:"sf1-1",x:10,y:10,z:"sf1",type:"test",wires:[]}
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[]},"sf1":{"id":"sf1","type":"subflow"},"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"subflows":{"sf1":{"id":"sf1","type":"subflow","configs":{},"nodes":{"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"instances":[{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}]}},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}}}},"missingTypes":[]};
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[]},"sf1":{"id":"sf1","type":"subflow"},"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"subflows":{"sf1":{"id":"sf1","type":"subflow","configs":{},"nodes":{"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"instances":[{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}]}},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}}}},"groups":{},"missingTypes":[]};
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
@@ -197,7 +197,7 @@ describe('flows/util', function() {
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
parsedConfig.missingTypes.should.eql(['missing']);
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"missingTypes":["missing"]};
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"groups":{},"missingTypes":["missing"]};
|
||||
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true();
|
||||
});
|
||||
|
||||
@@ -207,10 +207,20 @@ describe('flows/util', function() {
|
||||
{id:"cn",type:"test"},
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]};
|
||||
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"groups":{},"missingTypes":[]};
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
it('parses a flow including a group', function() {
|
||||
var originalConfig = [
|
||||
{id:"t1",type:"tab"},
|
||||
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||
{id:"g1",type:"group",z:"t1"}
|
||||
];
|
||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"g1":{"id":"g1","type":"group","z":"t1"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"groups":{"g1":{"id":"g1","type":"group","z":"t1"}},"missingTypes":[]}
|
||||
parsedConfig.should.eql(expectedConfig);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user