2015-11-14 00:16:47 +01:00
|
|
|
/**
|
2017-01-11 16:24:33 +01:00
|
|
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
2015-11-14 00:16:47 +01:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
**/
|
|
|
|
|
|
|
|
var should = require("should");
|
|
|
|
var sinon = require("sinon");
|
|
|
|
var path = require("path");
|
2020-08-14 01:20:44 +02:00
|
|
|
var fs = require("fs-extra");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-08-20 17:17:24 +02:00
|
|
|
var NR_TEST_UTILS = require("nr-test-utils");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-08-20 17:17:24 +02:00
|
|
|
var loader = NR_TEST_UTILS.require("@node-red/registry/lib/loader");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-08-20 17:17:24 +02:00
|
|
|
var localfilesystem = NR_TEST_UTILS.require("@node-red/registry/lib/localfilesystem");
|
|
|
|
var registry = NR_TEST_UTILS.require("@node-red/registry/lib/registry");
|
|
|
|
|
|
|
|
var nodes = NR_TEST_UTILS.require("@node-red/registry");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-04-26 13:32:05 +02:00
|
|
|
var resourcesDir = path.resolve(path.join(__dirname,"resources","local"));
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
describe("red/nodes/registry/loader",function() {
|
|
|
|
var stubs = [];
|
|
|
|
before(function() {
|
|
|
|
sinon.stub(localfilesystem,"init");
|
|
|
|
});
|
|
|
|
after(function() {
|
|
|
|
localfilesystem.init.restore();
|
|
|
|
});
|
|
|
|
afterEach(function() {
|
|
|
|
while(stubs.length) {
|
|
|
|
stubs.pop().restore();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
describe("#load",function() {
|
|
|
|
it("load empty set without settings available", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};}));
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};}));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}});
|
2019-03-05 14:24:35 +01:00
|
|
|
loader.load(true).then(function() {
|
2016-10-10 14:27:43 +02:00
|
|
|
localfilesystem.getNodeFiles.called.should.be.true();
|
2019-03-05 14:24:35 +01:00
|
|
|
localfilesystem.getNodeFiles.lastCall.args[0].should.be.true();
|
2016-10-10 14:27:43 +02:00
|
|
|
registry.saveNodeList.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
|
|
|
})
|
|
|
|
});
|
|
|
|
it("load empty set with settings available triggers registery save", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};}));
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};}));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2019-03-05 14:24:35 +01:00
|
|
|
loader.load(true).then(function() {
|
2016-10-10 14:27:43 +02:00
|
|
|
registry.saveNodeList.called.should.be.true();
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - single node single file", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
2018-04-26 13:32:05 +02:00
|
|
|
"version": "1.2.3",
|
2015-11-14 00:16:47 +01:00
|
|
|
"nodes": {
|
|
|
|
"TestNode1": {
|
|
|
|
"file": path.join(resourcesDir,"TestNode1","TestNode1.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.load().then(function(result) {
|
2018-04-26 13:32:05 +02:00
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","1.2.3");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("id","node-red/TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("module","node-red");
|
|
|
|
module.nodes.TestNode1.should.have.property("name","TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("file");
|
|
|
|
module.nodes.TestNode1.should.have.property("template");
|
|
|
|
module.nodes.TestNode1.should.have.property("enabled",true);
|
|
|
|
module.nodes.TestNode1.should.have.property("loaded",true);
|
|
|
|
module.nodes.TestNode1.should.have.property("types");
|
|
|
|
module.nodes.TestNode1.types.should.have.a.length(1);
|
|
|
|
module.nodes.TestNode1.types[0].should.eql('test-node-1');
|
|
|
|
module.nodes.TestNode1.should.have.property("config");
|
2020-08-14 01:20:44 +02:00
|
|
|
module.nodes.TestNode1.config.should.not.eql("");
|
2018-04-26 13:32:05 +02:00
|
|
|
module.nodes.TestNode1.should.have.property("help");
|
2020-08-14 01:20:44 +02:00
|
|
|
module.nodes.TestNode1.help.should.have.property("en-US");
|
|
|
|
module.nodes.TestNode1.should.have.property("namespace","node-red");
|
|
|
|
|
|
|
|
nodes.registerType.calledOnce.should.be.true();
|
|
|
|
nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode1');
|
|
|
|
nodes.registerType.lastCall.args[1].should.eql('test-node-1');
|
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(function(err) {
|
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - ignore html if disableEditor true", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
|
|
|
"version": "1.2.3",
|
|
|
|
"nodes": {
|
|
|
|
"TestNode1": {
|
|
|
|
"file": path.join(resourcesDir,"TestNode1","TestNode1.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{disableEditor: true, available:function(){return true;}}});
|
|
|
|
loader.load().then(function(result) {
|
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","1.2.3");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("id","node-red/TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("module","node-red");
|
|
|
|
module.nodes.TestNode1.should.have.property("name","TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("file");
|
|
|
|
module.nodes.TestNode1.should.have.property("template");
|
|
|
|
module.nodes.TestNode1.should.have.property("enabled",true);
|
|
|
|
module.nodes.TestNode1.should.have.property("loaded",true);
|
|
|
|
// With disableEditor true, the types property is not populated by the
|
|
|
|
// html file - but instead is populated as nodes register themselves.
|
|
|
|
// But for this test, we have stubbed out registerType, so we won't get any types
|
|
|
|
// module.nodes.TestNode1.should.have.property("types");
|
|
|
|
// module.nodes.TestNode1.types.should.have.a.length(1);
|
|
|
|
// module.nodes.TestNode1.types[0].should.eql('test-node-1');
|
|
|
|
|
|
|
|
// With disableEditor set, config should be blank
|
|
|
|
module.nodes.TestNode1.should.have.property("config");
|
|
|
|
module.nodes.TestNode1.config.should.eql("");
|
|
|
|
|
|
|
|
// help should be an empty object
|
|
|
|
module.nodes.TestNode1.should.have.property("help");
|
|
|
|
module.nodes.TestNode1.help.should.eql({})
|
2018-04-26 13:32:05 +02:00
|
|
|
module.nodes.TestNode1.should.have.property("namespace","node-red");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2016-10-10 14:27:43 +02:00
|
|
|
nodes.registerType.calledOnce.should.be.true();
|
2016-04-28 12:23:42 +02:00
|
|
|
nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode1');
|
|
|
|
nodes.registerType.lastCall.args[1].should.eql('test-node-1');
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - multiple nodes single file", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
2018-04-26 13:32:05 +02:00
|
|
|
"version": "4.5.6",
|
2015-11-14 00:16:47 +01:00
|
|
|
"nodes": {
|
|
|
|
"MultipleNodes1": {
|
|
|
|
"file": path.join(resourcesDir,"MultipleNodes1","MultipleNodes1.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "MultipleNodes1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.load().then(function(result) {
|
2018-04-26 13:32:05 +02:00
|
|
|
|
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","4.5.6");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("MultipleNodes1");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("id","node-red/MultipleNodes1");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("module","node-red");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("name","MultipleNodes1");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("file");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("template");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("enabled",true);
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("loaded",true);
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("types");
|
|
|
|
module.nodes.MultipleNodes1.types.should.have.a.length(2);
|
|
|
|
module.nodes.MultipleNodes1.types[0].should.eql('test-node-multiple-1a');
|
|
|
|
module.nodes.MultipleNodes1.types[1].should.eql('test-node-multiple-1b');
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("config");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("help");
|
|
|
|
module.nodes.MultipleNodes1.should.have.property("namespace","node-red");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2016-10-10 14:27:43 +02:00
|
|
|
nodes.registerType.calledTwice.should.be.true();
|
2016-04-28 12:23:42 +02:00
|
|
|
nodes.registerType.firstCall.args[0].should.eql('node-red/MultipleNodes1');
|
|
|
|
nodes.registerType.firstCall.args[1].should.eql('test-node-multiple-1a');
|
|
|
|
nodes.registerType.secondCall.args[0].should.eql('node-red/MultipleNodes1');
|
|
|
|
nodes.registerType.secondCall.args[1].should.eql('test-node-multiple-1b');
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-04-26 13:32:05 +02:00
|
|
|
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - node with promise", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
2018-04-26 13:32:05 +02:00
|
|
|
"version":"2.4.6",
|
2015-11-14 00:16:47 +01:00
|
|
|
"nodes": {
|
|
|
|
"TestNode2": {
|
|
|
|
"file": path.join(resourcesDir,"TestNode2","TestNode2.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode2"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.load().then(function(result) {
|
2018-04-26 13:32:05 +02:00
|
|
|
|
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","2.4.6");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("TestNode2");
|
|
|
|
module.nodes.TestNode2.should.have.property("id","node-red/TestNode2");
|
|
|
|
module.nodes.TestNode2.should.have.property("module","node-red");
|
|
|
|
module.nodes.TestNode2.should.have.property("name","TestNode2");
|
|
|
|
module.nodes.TestNode2.should.have.property("file");
|
|
|
|
module.nodes.TestNode2.should.have.property("template");
|
|
|
|
module.nodes.TestNode2.should.have.property("enabled",true);
|
|
|
|
module.nodes.TestNode2.should.have.property("loaded",true);
|
|
|
|
module.nodes.TestNode2.should.have.property("types");
|
|
|
|
module.nodes.TestNode2.types.should.have.a.length(1);
|
|
|
|
module.nodes.TestNode2.types[0].should.eql('test-node-2');
|
|
|
|
module.nodes.TestNode2.should.have.property("config");
|
|
|
|
module.nodes.TestNode2.should.have.property("help");
|
|
|
|
module.nodes.TestNode2.should.have.property("namespace","node-red");
|
|
|
|
module.nodes.TestNode2.should.not.have.property('err');
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2016-10-10 14:27:43 +02:00
|
|
|
nodes.registerType.calledOnce.should.be.true();
|
2016-04-28 12:23:42 +02:00
|
|
|
nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode2');
|
|
|
|
nodes.registerType.lastCall.args[1].should.eql('test-node-2');
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - node with rejecting promise", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
2018-04-26 13:32:05 +02:00
|
|
|
"version":"1.2.3",
|
2015-11-14 00:16:47 +01:00
|
|
|
"nodes": {
|
|
|
|
"TestNode3": {
|
|
|
|
"file": path.join(resourcesDir,"TestNode3","TestNode3.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode3"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.load().then(function(result) {
|
2018-04-26 13:32:05 +02:00
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","1.2.3");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("TestNode3");
|
|
|
|
module.nodes.TestNode3.should.have.property("id","node-red/TestNode3");
|
|
|
|
module.nodes.TestNode3.should.have.property("module","node-red");
|
|
|
|
module.nodes.TestNode3.should.have.property("name","TestNode3");
|
|
|
|
module.nodes.TestNode3.should.have.property("file");
|
|
|
|
module.nodes.TestNode3.should.have.property("template");
|
|
|
|
module.nodes.TestNode3.should.have.property("enabled",true);
|
|
|
|
module.nodes.TestNode3.should.have.property("loaded",false);
|
|
|
|
module.nodes.TestNode3.should.have.property("types");
|
|
|
|
module.nodes.TestNode3.types.should.have.a.length(1);
|
|
|
|
module.nodes.TestNode3.types[0].should.eql('test-node-3');
|
|
|
|
module.nodes.TestNode3.should.have.property("config");
|
|
|
|
module.nodes.TestNode3.should.have.property("help");
|
|
|
|
module.nodes.TestNode3.should.have.property("namespace","node-red");
|
|
|
|
module.nodes.TestNode3.should.have.property('err','fail');
|
|
|
|
|
|
|
|
nodes.registerType.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("load core node files scanned by lfs - missing file", function(done) {
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["node-red"] = {
|
|
|
|
"name": "node-red",
|
2018-04-26 13:32:05 +02:00
|
|
|
"version":"1.2.3",
|
2015-11-14 00:16:47 +01:00
|
|
|
"nodes": {
|
|
|
|
"DoesNotExist": {
|
|
|
|
"file": path.join(resourcesDir,"doesnotexist"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "DoesNotExist"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.load().then(function(result) {
|
2018-04-26 13:32:05 +02:00
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","node-red");
|
|
|
|
module.should.have.property("version","1.2.3");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("DoesNotExist");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("id","node-red/DoesNotExist");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("module","node-red");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("name","DoesNotExist");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("file");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("template");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("enabled",true);
|
|
|
|
module.nodes.DoesNotExist.should.have.property("loaded",false);
|
|
|
|
module.nodes.DoesNotExist.should.have.property("types");
|
|
|
|
module.nodes.DoesNotExist.types.should.have.a.length(0);
|
2020-08-14 01:20:44 +02:00
|
|
|
module.nodes.DoesNotExist.should.have.property("config","");
|
|
|
|
module.nodes.DoesNotExist.should.have.property("help",{});
|
|
|
|
module.nodes.DoesNotExist.should.have.property("namespace","node-red");
|
2018-04-26 13:32:05 +02:00
|
|
|
module.nodes.DoesNotExist.should.have.property('err');
|
|
|
|
|
|
|
|
nodes.registerType.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
2016-11-16 23:46:01 +01:00
|
|
|
|
2020-08-28 17:36:11 +02:00
|
|
|
// it("load core node files scanned by lfs - missing html file", function(done) {
|
|
|
|
// // This is now an okay situation
|
|
|
|
// stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
|
|
|
|
// var result = {};
|
|
|
|
// result["node-red"] = {
|
|
|
|
// "name": "node-red",
|
|
|
|
// "version": "1.2.3",
|
|
|
|
// "nodes": {
|
|
|
|
// "DuffNode": {
|
|
|
|
// "file": path.join(resourcesDir,"DuffNode","DuffNode.js"),
|
|
|
|
// "module": "node-red",
|
|
|
|
// "name": "DuffNode"
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
// return result;
|
|
|
|
// }));
|
|
|
|
//
|
|
|
|
// stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
|
|
|
|
// stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
|
|
|
// // This module isn't already loaded
|
|
|
|
// stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
//
|
|
|
|
// stubs.push(sinon.stub(nodes,"registerType"));
|
|
|
|
// loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
|
|
|
// loader.load().then(function(result) {
|
|
|
|
//
|
|
|
|
// registry.addModule.called.should.be.true();
|
|
|
|
// var module = registry.addModule.lastCall.args[0];
|
|
|
|
// module.should.have.property("name","node-red");
|
|
|
|
// module.should.have.property("version","1.2.3");
|
|
|
|
// module.should.have.property("nodes");
|
|
|
|
// module.nodes.should.have.property("DuffNode");
|
|
|
|
// module.nodes.DuffNode.should.have.property("id","node-red/DuffNode");
|
|
|
|
// module.nodes.DuffNode.should.have.property("module","node-red");
|
|
|
|
// module.nodes.DuffNode.should.have.property("name","DuffNode");
|
|
|
|
// module.nodes.DuffNode.should.have.property("file");
|
|
|
|
// module.nodes.DuffNode.should.have.property("template");
|
|
|
|
// module.nodes.DuffNode.should.have.property("enabled",true);
|
|
|
|
// module.nodes.DuffNode.should.have.property("loaded",false);
|
|
|
|
// module.nodes.DuffNode.should.have.property("types");
|
|
|
|
// module.nodes.DuffNode.types.should.have.a.length(0);
|
|
|
|
// module.nodes.DuffNode.should.have.property("config","");
|
|
|
|
// module.nodes.DuffNode.should.have.property("help",{});
|
|
|
|
// module.nodes.DuffNode.should.have.property("namespace","node-red");
|
|
|
|
// module.nodes.DuffNode.should.have.property('err');
|
|
|
|
// module.nodes.DuffNode.err.should.endWith("DuffNode.html does not exist");
|
|
|
|
//
|
|
|
|
// nodes.registerType.called.should.be.false();
|
|
|
|
//
|
|
|
|
// done();
|
|
|
|
// }).catch(function(err) {
|
|
|
|
// done(err);
|
|
|
|
// });
|
|
|
|
// });
|
2015-11-14 00:16:47 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
describe("#addModule",function() {
|
|
|
|
it("throws error if settings unavailable", function() {
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
/*jshint immed: false */
|
|
|
|
(function(){
|
|
|
|
loader.addModule("test-module");
|
|
|
|
}).should.throw("Settings unavailable");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("returns rejected error if module already loaded", function(done) {
|
|
|
|
stubs.push(sinon.stub(registry,"getModuleInfo",function(){return{}}));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2018-04-24 16:01:49 +02:00
|
|
|
loader.addModule("test-module").catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
err.code.should.eql("module_already_loaded");
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it("returns rejected error if module not found", function(done) {
|
|
|
|
stubs.push(sinon.stub(registry,"getModuleInfo",function(){return null}));
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getModuleFiles",function() {
|
|
|
|
throw new Error("failure");
|
|
|
|
}));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2018-04-24 16:01:49 +02:00
|
|
|
loader.addModule("test-module").catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
err.message.should.eql("failure");
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it("loads module by name", function(done) {
|
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; }));
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["TestNodeModule"] = {
|
|
|
|
"name": "TestNodeModule",
|
|
|
|
"version": "1.2.3",
|
|
|
|
"nodes": {
|
|
|
|
"TestNode1": {
|
|
|
|
"file": path.join(resourcesDir,"TestNodeModule","node_modules","TestNodeModule","TestNodeModule.js"),
|
|
|
|
"module": "TestNodeModule",
|
|
|
|
"name": "TestNode1",
|
|
|
|
"version": "1.2.3"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.addModule("TestNodeModule").then(function(result) {
|
2020-11-25 20:07:30 +01:00
|
|
|
result.should.eql("TestNodeModule");
|
2018-04-26 13:32:05 +02:00
|
|
|
|
|
|
|
registry.addModule.called.should.be.true();
|
|
|
|
var module = registry.addModule.lastCall.args[0];
|
|
|
|
module.should.have.property("name","TestNodeModule");
|
|
|
|
module.should.have.property("version","1.2.3");
|
|
|
|
module.should.have.property("nodes");
|
|
|
|
module.nodes.should.have.property("TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("id","TestNodeModule/TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("module","TestNodeModule");
|
|
|
|
module.nodes.TestNode1.should.have.property("name","TestNode1");
|
|
|
|
module.nodes.TestNode1.should.have.property("file");
|
|
|
|
module.nodes.TestNode1.should.have.property("template");
|
|
|
|
module.nodes.TestNode1.should.have.property("enabled",true);
|
|
|
|
module.nodes.TestNode1.should.have.property("loaded",true);
|
|
|
|
module.nodes.TestNode1.should.have.property("types");
|
|
|
|
module.nodes.TestNode1.types.should.have.a.length(1);
|
|
|
|
module.nodes.TestNode1.types[0].should.eql('test-node-mod-1');
|
|
|
|
module.nodes.TestNode1.should.have.property("config");
|
|
|
|
module.nodes.TestNode1.should.have.property("help");
|
|
|
|
module.nodes.TestNode1.should.have.property("namespace","TestNodeModule");
|
|
|
|
module.nodes.TestNode1.should.not.have.property('err');
|
2015-11-14 00:16:47 +01:00
|
|
|
|
2016-10-10 14:27:43 +02:00
|
|
|
nodes.registerType.calledOnce.should.be.true();
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("skips module that fails version check", function(done) {
|
|
|
|
// This module isn't already loaded
|
|
|
|
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
|
|
|
|
stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; }));
|
|
|
|
stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){
|
|
|
|
var result = {};
|
|
|
|
result["TestNodeModule"] = {
|
|
|
|
"name": "TestNodeModule",
|
|
|
|
"version": "1.2.3",
|
|
|
|
"redVersion":"999.0.0",
|
|
|
|
"nodes": {
|
|
|
|
"TestNode1": {
|
|
|
|
"file": path.join(resourcesDir,"TestNodeModule","node_modules","TestNodeModule","TestNodeModule.js"),
|
|
|
|
"module": "TestNodeModule",
|
|
|
|
"name": "TestNode1",
|
|
|
|
"version": "1.2.3"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}));
|
|
|
|
|
|
|
|
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" }));
|
2018-04-26 13:32:05 +02:00
|
|
|
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
|
2015-11-14 00:16:47 +01:00
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
2018-04-26 13:32:05 +02:00
|
|
|
loader.init({log:{"_":function(){},warn:function(){}},nodes:nodes,version: function() { return "0.12.0"}, settings:{available:function(){return true;}}});
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.addModule("TestNodeModule").then(function(result) {
|
2020-11-25 20:07:30 +01:00
|
|
|
result.should.eql("TestNodeModule");
|
2018-04-26 13:32:05 +02:00
|
|
|
registry.addModule.called.should.be.false();
|
2016-10-10 14:27:43 +02:00
|
|
|
nodes.registerType.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it.skip('registers a message catalog');
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
describe("#loadNodeSet",function() {
|
|
|
|
it("no-ops the load if node is not enabled", function(done) {
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
|
|
|
loader.loadNodeSet({
|
|
|
|
"file": path.join(resourcesDir,"TestNode1","TestNode1.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode1",
|
|
|
|
"enabled": false
|
|
|
|
}).then(function(node) {
|
2016-10-10 14:27:43 +02:00
|
|
|
node.enabled.should.be.false();
|
|
|
|
nodes.registerType.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("handles node that errors on require", function(done) {
|
|
|
|
stubs.push(sinon.stub(nodes,"registerType"));
|
|
|
|
loader.loadNodeSet({
|
|
|
|
"file": path.join(resourcesDir,"TestNode4","TestNode4.js"),
|
|
|
|
"module": "node-red",
|
|
|
|
"name": "TestNode4",
|
|
|
|
"enabled": true
|
|
|
|
}).then(function(node) {
|
2016-10-10 14:27:43 +02:00
|
|
|
node.enabled.should.be.true();
|
|
|
|
nodes.registerType.called.should.be.false();
|
2015-11-14 00:16:47 +01:00
|
|
|
node.should.have.property('err');
|
2017-01-30 10:58:43 +01:00
|
|
|
node.err.toString().should.eql("Error: fail to require (line:1)");
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
done();
|
2018-04-24 16:01:49 +02:00
|
|
|
}).catch(function(err) {
|
2015-11-14 00:16:47 +01:00
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe("#getNodeHelp",function() {
|
|
|
|
it("returns preloaded help", function() {
|
|
|
|
loader.getNodeHelp({
|
|
|
|
help:{
|
|
|
|
en:"foo"
|
|
|
|
}
|
|
|
|
},"en").should.eql("foo");
|
|
|
|
});
|
|
|
|
it("loads help, caching result", function() {
|
|
|
|
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
|
|
|
|
return 'bar';
|
|
|
|
}))
|
|
|
|
var node = {
|
|
|
|
template: "/tmp/node/directory/file.html",
|
|
|
|
help:{
|
|
|
|
en:"foo"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
loader.getNodeHelp(node,"fr").should.eql("bar");
|
|
|
|
node.help['fr'].should.eql("bar");
|
2016-10-10 14:27:43 +02:00
|
|
|
fs.readFileSync.calledOnce.should.be.true();
|
2016-09-13 23:57:20 +02:00
|
|
|
fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html"));
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.getNodeHelp(node,"fr").should.eql("bar");
|
2016-10-10 14:27:43 +02:00
|
|
|
fs.readFileSync.calledOnce.should.be.true();
|
2015-11-14 00:16:47 +01:00
|
|
|
});
|
|
|
|
it("loads help, defaulting to en-US content", function() {
|
|
|
|
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
|
|
|
|
throw new Error("not found");
|
|
|
|
}))
|
|
|
|
var node = {
|
|
|
|
template: "/tmp/node/directory/file.html",
|
|
|
|
help:{}
|
|
|
|
};
|
|
|
|
node.help['en-US'] = 'foo';
|
|
|
|
|
|
|
|
loader.getNodeHelp(node,"fr").should.eql("foo");
|
|
|
|
node.help['fr'].should.eql("foo");
|
2016-10-10 14:27:43 +02:00
|
|
|
fs.readFileSync.calledOnce.should.be.true();
|
2016-09-13 23:57:20 +02:00
|
|
|
fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html"));
|
2015-11-14 00:16:47 +01:00
|
|
|
loader.getNodeHelp(node,"fr").should.eql("foo");
|
2016-10-10 14:27:43 +02:00
|
|
|
fs.readFileSync.calledOnce.should.be.true();
|
2015-11-14 00:16:47 +01:00
|
|
|
});
|
2017-01-19 08:55:57 +01:00
|
|
|
it("loads help, defaulting to en-US content for extra nodes", function() {
|
|
|
|
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
|
|
|
|
if (path.indexOf("en-US") >= 0) {
|
|
|
|
return 'bar';
|
|
|
|
}
|
|
|
|
throw new Error("not found");
|
|
|
|
}));
|
|
|
|
var node = {
|
|
|
|
template: "/tmp/node/directory/file.html",
|
|
|
|
help:{}
|
|
|
|
};
|
|
|
|
delete node.help['en-US'];
|
|
|
|
|
|
|
|
loader.getNodeHelp(node,"fr").should.eql("bar");
|
|
|
|
node.help['fr'].should.eql("bar");
|
|
|
|
fs.readFileSync.calledTwice.should.be.true();
|
|
|
|
fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html"));
|
|
|
|
fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html"));
|
|
|
|
loader.getNodeHelp(node,"fr").should.eql("bar");
|
|
|
|
fs.readFileSync.calledTwice.should.be.true();
|
|
|
|
});
|
2017-01-19 09:19:41 +01:00
|
|
|
it("fails to load en-US help content", function() {
|
|
|
|
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
|
|
|
|
throw new Error("not found");
|
|
|
|
}));
|
|
|
|
var node = {
|
|
|
|
template: "/tmp/node/directory/file.html",
|
|
|
|
help:{}
|
|
|
|
};
|
|
|
|
delete node.help['en-US'];
|
|
|
|
|
|
|
|
should.not.exist(loader.getNodeHelp(node,"en-US"));
|
|
|
|
should.not.exist(node.help['en-US']);
|
|
|
|
fs.readFileSync.calledTwice.should.be.true();
|
|
|
|
fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html"));
|
|
|
|
fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en/file.html"));
|
|
|
|
should.not.exist(loader.getNodeHelp(node,"en-US"));
|
|
|
|
fs.readFileSync.callCount.should.eql(4);
|
|
|
|
});
|
2015-11-14 00:16:47 +01:00
|
|
|
|
|
|
|
});
|
|
|
|
});
|