mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'master' into dev
This commit is contained in:
@@ -541,13 +541,17 @@ describe('exec node', function() {
|
||||
var n2 = helper.getNode("n2");
|
||||
var n3 = helper.getNode("n3");
|
||||
var n4 = helper.getNode("n4");
|
||||
var payload = "";
|
||||
n2.on("input", function(msg) {
|
||||
//console.log(msg);
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.a.String();
|
||||
msg.payload.should.equal(expected);
|
||||
done();
|
||||
payload += msg.payload;
|
||||
if (payload.endsWith("\n")) {
|
||||
payload.should.equal(expected);
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
@@ -567,6 +571,7 @@ describe('exec node', function() {
|
||||
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
|
||||
expected = "12345 deg C\n";
|
||||
}
|
||||
var payload = "";
|
||||
|
||||
helper.load(execNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
@@ -578,8 +583,11 @@ describe('exec node', function() {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.a.String();
|
||||
msg.payload.should.equal(expected);
|
||||
done();
|
||||
payload += msg.payload;
|
||||
if (payload.endsWith("\n")) {
|
||||
payload.should.equal(expected);
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
@@ -661,8 +669,16 @@ describe('exec node', function() {
|
||||
};
|
||||
|
||||
n2.on("input", function(msg) {
|
||||
messages[0] = msg;
|
||||
completeTest();
|
||||
var payload = msg.payload;
|
||||
if (messages[0]) {
|
||||
messages[0].payload += payload;
|
||||
}
|
||||
else {
|
||||
messages[0] = msg;
|
||||
}
|
||||
if (payload.endsWith("\n")) {
|
||||
completeTest();
|
||||
}
|
||||
});
|
||||
n4.on("input", function(msg) {
|
||||
messages[1] = msg;
|
||||
@@ -869,8 +885,16 @@ describe('exec node', function() {
|
||||
};
|
||||
|
||||
n2.on("input", function(msg) {
|
||||
messages[0] = msg;
|
||||
completeTest();
|
||||
var payload = msg.payload;
|
||||
if (messages[0]) {
|
||||
messages[0].payload += payload;
|
||||
}
|
||||
else {
|
||||
messages[0] = msg;
|
||||
}
|
||||
if (payload.endsWith("\n")) {
|
||||
completeTest();
|
||||
}
|
||||
});
|
||||
n4.on("input", function(msg) {
|
||||
messages[1] = msg;
|
||||
|
@@ -87,6 +87,57 @@ describe('CSV node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert a simple string to a javascript object with | separator (no template)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", sep:"|", 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) {
|
||||
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();
|
||||
});
|
||||
var testString = "1|2|3|4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert a simple string to a javascript object with tab separator (with template)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", sep:"\t", temp:"A,B,,D", 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) {
|
||||
msg.should.have.property('payload', { A: 1, B: 2, D: 4 });
|
||||
msg.should.have.property('columns', "A,B,D");
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = "1\t2\t3\t4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert a simple string to a javascript object with space separator (with spaced template)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", sep:" ", temp:"A, B, , D", 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) {
|
||||
msg.should.have.property('payload', { A: 1, B: 2, D: 4 });
|
||||
msg.should.have.property('columns', "A,B,D");
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = "1 2 3 4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
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"} ];
|
||||
@@ -170,6 +221,58 @@ describe('CSV node', function() {
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow passing in a template as first line of CSV (not comma)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:";", 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) {
|
||||
msg.should.have.property('payload', { a: 1, "b b":2, "c;c":3, "d, d": 4 });
|
||||
msg.should.have.property('columns', 'a,b b,c;c,"d, d"');
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = 'a;b b;"c;c";" d, d "'+"\n"+"1;2;3;4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow passing in a template as first line of CSV (special char /)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:"/", 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) {
|
||||
msg.should.have.property('payload', { a: 1, "b b":2, "c/c":3, "d, d": 4 });
|
||||
msg.should.have.property('columns', 'a,b b,c/c,"d, d"');
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = 'a/b b/"c/c"/" d, d "'+"\n"+"1/2/3/4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow passing in a template as first line of CSV (special char \\)', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:"\\", 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) {
|
||||
msg.should.have.property('payload', { a: 1, "b b":2, "c\\c":3, "d, d": 4 });
|
||||
msg.should.have.property('columns', 'a,b b,c\\c,"d, d"');
|
||||
check_parts(msg, 0, 1);
|
||||
done();
|
||||
});
|
||||
var testString = 'a\\b b\\"c\\c"\\" d, d "'+"\n"+"1\\2\\3\\4"+String.fromCharCode(10);
|
||||
n1.emit("input", {payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
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"} ];
|
||||
@@ -609,6 +712,24 @@ describe('CSV node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert a simple object back to a tsv using a tab as a separator', function(done) {
|
||||
var flow = [ { id:"n1", type:"csv", temp:"", sep:"\t", 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) {
|
||||
try {
|
||||
msg.should.have.property('payload', '1\tfoo\t"ba""r"\tdi,ng\n');
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
var testJson = { d:1, b:"foo", c:"ba\"r", a:"di,ng" };
|
||||
n1.emit("input", {payload:testJson});
|
||||
});
|
||||
});
|
||||
|
||||
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"} ];
|
||||
|
@@ -36,102 +36,96 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
index.clearRegistry();
|
||||
});
|
||||
|
||||
it('loads provided credentials',function(done) {
|
||||
it('loads provided credentials',function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
});
|
||||
|
||||
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
|
||||
return credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
credentials.get("a").should.have.property('b',1);
|
||||
credentials.get("a").should.have.property('c',2);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('adds a new credential',function(done) {
|
||||
it('adds a new credential',function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
});
|
||||
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
return credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
credentials.dirty().should.be.false();
|
||||
should.not.exist(credentials.get("b"));
|
||||
credentials.add("b",{"foo":"bar"}).then(function() {
|
||||
return credentials.add("b",{"foo":"bar"}).then(function() {
|
||||
credentials.get("b").should.have.property("foo","bar");
|
||||
credentials.dirty().should.be.true();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
it('deletes an existing credential',function(done) {
|
||||
it('deletes an existing credential',function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
});
|
||||
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
return credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||
credentials.dirty().should.be.false();
|
||||
credentials.delete("a");
|
||||
should.not.exist(credentials.get("a"));
|
||||
credentials.dirty().should.be.true();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('exports the credentials, clearing dirty flag', function(done) {
|
||||
it('exports the credentials, clearing dirty flag', function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
});
|
||||
var creds = {"a":{"b":1,"c":2}};
|
||||
credentials.load(creds).then(function() {
|
||||
credentials.add("b",{"foo":"bar"}).then(function() {
|
||||
credentials.dirty().should.be.true();
|
||||
credentials.export().then(function(exported) {
|
||||
exported.should.eql(creds);
|
||||
credentials.dirty().should.be.false();
|
||||
done();
|
||||
})
|
||||
});
|
||||
return credentials.load(creds).then(function() {
|
||||
return credentials.add("b",{"foo":"bar"})
|
||||
}).then(function() {
|
||||
credentials.dirty().should.be.true();
|
||||
return credentials.export().then(function(exported) {
|
||||
exported.should.eql(creds);
|
||||
credentials.dirty().should.be.false();
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
describe("#clean",function() {
|
||||
it("removes credentials of unknown nodes",function(done) {
|
||||
it("removes credentials of unknown nodes",function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
settings: encryptionDisabledSettings,
|
||||
nodes: { getType: () => function(){} }
|
||||
});
|
||||
var creds = {"a":{"b":1,"c":2},"b":{"d":3}};
|
||||
credentials.load(creds).then(function() {
|
||||
return credentials.load(creds).then(function() {
|
||||
credentials.dirty().should.be.false();
|
||||
should.exist(credentials.get("a"));
|
||||
should.exist(credentials.get("b"));
|
||||
credentials.clean([{id:"b"}]).then(function() {
|
||||
return credentials.clean([{id:"b"}]).then(function() {
|
||||
credentials.dirty().should.be.true();
|
||||
should.not.exist(credentials.get("a"));
|
||||
should.exist(credentials.get("b"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
it("extracts credentials of known nodes",function(done) {
|
||||
it("extracts credentials of known nodes",function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
settings: encryptionDisabledSettings,
|
||||
nodes: { getType: () => function(){} }
|
||||
});
|
||||
credentials.register("testNode",{"b":"text","c":"password"})
|
||||
var creds = {"a":{"b":1,"c":2}};
|
||||
var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}];
|
||||
credentials.load(creds).then(function() {
|
||||
return credentials.load(creds).then(function() {
|
||||
credentials.dirty().should.be.false();
|
||||
credentials.clean(newConfig).then(function() {
|
||||
return credentials.clean(newConfig).then(function() {
|
||||
credentials.dirty().should.be.true();
|
||||
credentials.get("a").should.have.property('b',"newBValue");
|
||||
credentials.get("a").should.have.property('c',"newCValue");
|
||||
should.not.exist(newConfig[0].credentials);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -139,12 +133,13 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
|
||||
});
|
||||
|
||||
it('warns if a node has no credential definition', function(done) {
|
||||
it('warns if a node has no credential definition', function() {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
settings: encryptionDisabledSettings,
|
||||
nodes: { getType: () => function(){} }
|
||||
});
|
||||
credentials.load({}).then(function() {
|
||||
return credentials.load({}).then(function() {
|
||||
var node = {id:"node",type:"test",credentials:{
|
||||
user1:"newUser",
|
||||
password1:"newPassword"
|
||||
@@ -154,14 +149,14 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
log.warn.called.should.be.true();
|
||||
should.not.exist(node.credentials);
|
||||
log.warn.restore();
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('extract credential updates in the provided node', function(done) {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
settings: encryptionDisabledSettings,
|
||||
nodes: { getType: () => function(){} }
|
||||
});
|
||||
var defintion = {
|
||||
user1:{type:"text"},
|
||||
@@ -205,7 +200,8 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
it('extract ignores node without credentials', function(done) {
|
||||
credentials.init({
|
||||
log: log,
|
||||
settings: encryptionDisabledSettings
|
||||
settings: encryptionDisabledSettings,
|
||||
nodes: { getType: () => function(){} }
|
||||
});
|
||||
credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() {
|
||||
var node = {id:"node",type:"test"};
|
||||
@@ -233,7 +229,8 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
delete settings[key];
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
},
|
||||
nodes: { getType: () => function(){} }
|
||||
}
|
||||
it('migrates to encrypted and generates default key', function(done) {
|
||||
settings = {};
|
||||
@@ -341,7 +338,7 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
it('migrates from default key to user key', function(done) {
|
||||
it('migrates from default key to user key', function() {
|
||||
settings = {
|
||||
_credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a",
|
||||
credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee"
|
||||
@@ -349,21 +346,20 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
// {"node":{user1:"abc",password1:"123"}}
|
||||
var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"};
|
||||
credentials.init(runtime);
|
||||
credentials.load(cryptedFlows).then(function() {
|
||||
return credentials.load(cryptedFlows).then(function() {
|
||||
credentials.dirty().should.be.true();
|
||||
should.exist(credentials.get("node"));
|
||||
credentials.export().then(function(result) {
|
||||
return credentials.export().then(function(result) {
|
||||
result.should.have.a.property("$");
|
||||
settings.should.not.have.a.property("_credentialSecret");
|
||||
|
||||
// reset everything - but with _credentialSecret still set
|
||||
credentials.init(runtime);
|
||||
// load the freshly encrypted version
|
||||
credentials.load(result).then(function() {
|
||||
return credentials.load(result).then(function() {
|
||||
should.exist(credentials.get("node"));
|
||||
credentials.get("node").should.have.a.property("user1","abc");
|
||||
credentials.get("node").should.have.a.property("password1","123");
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -459,7 +455,8 @@ describe('red/runtime/nodes/credentials', function() {
|
||||
set: function(key,value) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
},
|
||||
nodes: { getType: () => function(){} }
|
||||
}
|
||||
// {"node":{user1:"abc",password1:"123"}}
|
||||
credentials.init(runtime);
|
||||
|
Reference in New Issue
Block a user