mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Improve unit test coverage
This commit is contained in:
parent
1419729458
commit
012e1cbcc5
@ -18,14 +18,6 @@ var apiUtils = require("../util");
|
|||||||
var express = require("express");
|
var express = require("express");
|
||||||
var runtimeAPI;
|
var runtimeAPI;
|
||||||
|
|
||||||
function getUsername(userObj) {
|
|
||||||
var username = '__default';
|
|
||||||
if ( userObj && userObj.name ) {
|
|
||||||
username = userObj.name;
|
|
||||||
}
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(_runtimeAPI) {
|
init: function(_runtimeAPI) {
|
||||||
runtimeAPI = _runtimeAPI;
|
runtimeAPI = _runtimeAPI;
|
||||||
|
@ -34,8 +34,8 @@ var defaultContext = {
|
|||||||
image: "red/images/node-red.svg"
|
image: "red/images/node-red.svg"
|
||||||
},
|
},
|
||||||
asset: {
|
asset: {
|
||||||
red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js",
|
red: "red/red.min.js",
|
||||||
main: (process.env.NODE_ENV == "development")? "red/main.js":"red/main.min.js",
|
main: "red/main.min.js",
|
||||||
vendorMonaco: ""
|
vendorMonaco: ""
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -94,6 +94,10 @@ module.exports = {
|
|||||||
init: function(settings, _runtimeAPI) {
|
init: function(settings, _runtimeAPI) {
|
||||||
runtimeAPI = _runtimeAPI;
|
runtimeAPI = _runtimeAPI;
|
||||||
themeContext = clone(defaultContext);
|
themeContext = clone(defaultContext);
|
||||||
|
if (process.env.NODE_ENV == "development") {
|
||||||
|
themeContext.asset.red = "red/red.js";
|
||||||
|
themeContext.asset.main = "red/main.js";
|
||||||
|
}
|
||||||
themeSettings = null;
|
themeSettings = null;
|
||||||
theme = settings.editorTheme || {};
|
theme = settings.editorTheme || {};
|
||||||
themeContext.asset.vendorMonaco = ((theme.codeEditor || {}).lib === "monaco") ? "vendor/monaco/monaco-bootstrap.js" : "";
|
themeContext.asset.vendorMonaco = ((theme.codeEditor || {}).lib === "monaco") ? "vendor/monaco/monaco-bootstrap.js" : "";
|
||||||
|
@ -150,4 +150,4 @@ module.exports = {
|
|||||||
getPluginConfigs,
|
getPluginConfigs,
|
||||||
getPluginList,
|
getPluginList,
|
||||||
exportPluginSettings
|
exportPluginSettings
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ var NR_TEST_UTILS = require("nr-test-utils");
|
|||||||
var comms = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/comms");
|
var comms = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/comms");
|
||||||
var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users");
|
var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users");
|
||||||
var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens");
|
var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens");
|
||||||
|
var Strategies = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/strategies");
|
||||||
var address = '127.0.0.1';
|
var address = '127.0.0.1';
|
||||||
var listenPort = 0; // use ephemeral port
|
var listenPort = 0; // use ephemeral port
|
||||||
|
|
||||||
@ -113,7 +113,6 @@ describe("api/editor/comms", function() {
|
|||||||
connections[0].send('topic3', 'correct');
|
connections[0].send('topic3', 'correct');
|
||||||
});
|
});
|
||||||
ws.on('message', function(msg) {
|
ws.on('message', function(msg) {
|
||||||
console.log(msg);
|
|
||||||
msg.should.equal('[{"topic":"topic3","data":"correct"}]');
|
msg.should.equal('[{"topic":"topic3","data":"correct"}]');
|
||||||
ws.close();
|
ws.close();
|
||||||
done();
|
done();
|
||||||
@ -343,6 +342,11 @@ describe("api/editor/comms", function() {
|
|||||||
var getUser;
|
var getUser;
|
||||||
var getToken;
|
var getToken;
|
||||||
var getUserToken;
|
var getUserToken;
|
||||||
|
var getUserTokenHeader;
|
||||||
|
var authenticateUserToken;
|
||||||
|
var onSessionExpiry;
|
||||||
|
var onSessionExpiryCallback;
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
getDefaultUser = sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
|
getDefaultUser = sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
|
||||||
getUser = sinon.stub(Users,"get").callsFake(function(username) {
|
getUser = sinon.stub(Users,"get").callsFake(function(username) {
|
||||||
@ -368,8 +372,19 @@ describe("api/editor/comms", function() {
|
|||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
getUserTokenHeader = sinon.stub(Users,"tokenHeader").callsFake(function() {
|
||||||
|
return "custom-header"
|
||||||
|
})
|
||||||
|
authenticateUserToken = sinon.stub(Strategies, "authenticateUserToken").callsFake(async function(req) {
|
||||||
|
var token = req.headers['custom-header'];
|
||||||
|
if (token === "knock-knock") {
|
||||||
|
return {user:"fred",scope:["*"]}
|
||||||
|
}
|
||||||
|
throw new Error("Invalid user");
|
||||||
|
})
|
||||||
|
onSessionExpiry = sinon.stub(Tokens,"onSessionExpiry").callsFake(function(cb) {
|
||||||
|
onSessionExpiryCallback = cb;
|
||||||
|
});
|
||||||
server = stoppable(http.createServer(function(req,res){app(req,res)}));
|
server = stoppable(http.createServer(function(req,res){app(req,res)}));
|
||||||
comms.init(server, {adminAuth:{}}, {comms: mockComms});
|
comms.init(server, {adminAuth:{}}, {comms: mockComms});
|
||||||
server.listen(listenPort, address);
|
server.listen(listenPort, address);
|
||||||
@ -385,6 +400,9 @@ describe("api/editor/comms", function() {
|
|||||||
getUser.restore();
|
getUser.restore();
|
||||||
getToken.restore();
|
getToken.restore();
|
||||||
getUserToken.restore();
|
getUserToken.restore();
|
||||||
|
getUserTokenHeader.restore();
|
||||||
|
authenticateUserToken.restore();
|
||||||
|
onSessionExpiry.restore();
|
||||||
comms.stop();
|
comms.stop();
|
||||||
server.stop(done);
|
server.stop(done);
|
||||||
});
|
});
|
||||||
@ -428,6 +446,32 @@ describe("api/editor/comms", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('allows connections that do authenticate - header-provided-token',function(done) {
|
||||||
|
var ws = new WebSocket(url,{
|
||||||
|
headers: { "custom-header": "knock-knock" }
|
||||||
|
});
|
||||||
|
var received = 0;
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.send('{"subscribe":"foo"}');
|
||||||
|
connections.should.have.length(1);
|
||||||
|
connections[0].send('foo', 'correct');
|
||||||
|
});
|
||||||
|
ws.on('message', function(msg) {
|
||||||
|
received++;
|
||||||
|
if (received == 1) {
|
||||||
|
msg.should.equal('[{"topic":"foo","data":"correct"}]');
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ws.on('close', function() {
|
||||||
|
try {
|
||||||
|
received.should.equal(1);
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
it('allows connections that do authenticate - user-provided-token',function(done) {
|
it('allows connections that do authenticate - user-provided-token',function(done) {
|
||||||
var ws = new WebSocket(url);
|
var ws = new WebSocket(url);
|
||||||
var received = 0;
|
var received = 0;
|
||||||
@ -475,6 +519,50 @@ describe("api/editor/comms", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('rejects connections for invalid token - header-provided-token',function(done) {
|
||||||
|
var ws = new WebSocket(url,{
|
||||||
|
headers: { "custom-header": "bad token" }
|
||||||
|
});
|
||||||
|
var received = 0;
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.send('{"subscribe":"foo"}');
|
||||||
|
});
|
||||||
|
ws.on('error', function() {
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it("expires websocket sessions", function(done) {
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
var received = 0;
|
||||||
|
ws.on('open', function() {
|
||||||
|
ws.send('{"auth":"1234"}');
|
||||||
|
});
|
||||||
|
ws.on('message', function(msg) {
|
||||||
|
received++;
|
||||||
|
if (received == 3) {
|
||||||
|
msg.should.equal('{"auth":"fail"}');
|
||||||
|
} else if (received == 1) {
|
||||||
|
msg.should.equal('{"auth":"ok"}');
|
||||||
|
ws.send('{"subscribe":"foo"}');
|
||||||
|
connections[0].send('foo', 'correct');
|
||||||
|
} else {
|
||||||
|
msg.should.equal('[{"topic":"foo","data":"correct"}]');
|
||||||
|
setTimeout(function() {
|
||||||
|
onSessionExpiryCallback({accessToken:"1234"})
|
||||||
|
},50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('close', function() {
|
||||||
|
try {
|
||||||
|
received.should.equal(3);
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('authentication required, anonymous enabled',function() {
|
describe('authentication required, anonymous enabled',function() {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var should = require("should");
|
var should = require("should");
|
||||||
|
var request = require("supertest");
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
@ -50,10 +51,36 @@ describe("api/editor/theme", function () {
|
|||||||
context.should.have.a.property("asset");
|
context.should.have.a.property("asset");
|
||||||
context.asset.should.have.a.property("red", "red/red.min.js");
|
context.asset.should.have.a.property("red", "red/red.min.js");
|
||||||
context.asset.should.have.a.property("main", "red/main.min.js");
|
context.asset.should.have.a.property("main", "red/main.min.js");
|
||||||
|
context.asset.should.have.a.property("vendorMonaco", "");
|
||||||
|
|
||||||
should.not.exist(theme.settings());
|
should.not.exist(theme.settings());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses non-minified js files when in dev mode", async function () {
|
||||||
|
const previousEnv = process.env.NODE_ENV;
|
||||||
|
try {
|
||||||
|
process.env.NODE_ENV = 'development'
|
||||||
|
theme.init({});
|
||||||
|
var context = await theme.context();
|
||||||
|
context.asset.should.have.a.property("red", "red/red.js");
|
||||||
|
context.asset.should.have.a.property("main", "red/main.js");
|
||||||
|
} finally {
|
||||||
|
process.env.NODE_ENV = previousEnv;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Adds monaco bootstrap when enabled", async function () {
|
||||||
|
theme.init({
|
||||||
|
editorTheme: {
|
||||||
|
codeEditor: {
|
||||||
|
lib: 'monaco'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var context = await theme.context();
|
||||||
|
context.asset.should.have.a.property("vendorMonaco", "vendor/monaco/monaco-bootstrap.js");
|
||||||
|
});
|
||||||
|
|
||||||
it("picks up custom theme", async function () {
|
it("picks up custom theme", async function () {
|
||||||
theme.init({
|
theme.init({
|
||||||
editorTheme: {
|
editorTheme: {
|
||||||
@ -64,7 +91,9 @@ describe("api/editor/theme", function () {
|
|||||||
icon: "/absolute/path/to/theme/tabicon",
|
icon: "/absolute/path/to/theme/tabicon",
|
||||||
colour: "#8f008f"
|
colour: "#8f008f"
|
||||||
},
|
},
|
||||||
css: "/absolute/path/to/custom/css/file.css",
|
css: [
|
||||||
|
"/absolute/path/to/custom/css/file.css"
|
||||||
|
],
|
||||||
scripts: "/absolute/path/to/script.js"
|
scripts: "/absolute/path/to/script.js"
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
@ -185,4 +214,62 @@ describe("api/editor/theme", function () {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("includes list of plugin themes", function(done) {
|
||||||
|
theme.init({},{
|
||||||
|
plugins: { getPluginsByType: _ => [{id:"theme-plugin"}] }
|
||||||
|
});
|
||||||
|
const app = theme.app();
|
||||||
|
request(app)
|
||||||
|
.get("/")
|
||||||
|
.end(function(err,res) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = JSON.parse(res.text);
|
||||||
|
response.should.have.property("themes");
|
||||||
|
response.themes.should.eql(["theme-plugin"])
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes theme plugin settings", async function () {
|
||||||
|
theme.init({
|
||||||
|
editorTheme: {
|
||||||
|
theme: 'test-theme'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
plugins: { getPlugin: t => {
|
||||||
|
return ({'test-theme':{
|
||||||
|
path: '/abosolute/path/to/plugin',
|
||||||
|
css: [
|
||||||
|
"path/to/custom/css/file1.css",
|
||||||
|
"/invalid/path/to/file2.css",
|
||||||
|
"../another/invalid/path/file3.css"
|
||||||
|
],
|
||||||
|
scripts: [
|
||||||
|
"path/to/custom/js/file1.js",
|
||||||
|
"/invalid/path/to/file2.js",
|
||||||
|
"../another/invalid/path/file3.js"
|
||||||
|
]
|
||||||
|
}})[t.id];
|
||||||
|
} }
|
||||||
|
});
|
||||||
|
|
||||||
|
theme.app();
|
||||||
|
|
||||||
|
var context = await theme.context();
|
||||||
|
context.should.have.a.property("page");
|
||||||
|
context.page.should.have.a.property("css");
|
||||||
|
context.page.css.should.have.lengthOf(1);
|
||||||
|
context.page.css[0].should.eql('theme/css/file1.css');
|
||||||
|
context.page.should.have.a.property("scripts");
|
||||||
|
context.page.scripts.should.have.lengthOf(1);
|
||||||
|
context.page.scripts[0].should.eql('theme/scripts/file1.js');
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -33,10 +33,21 @@ describe("api/editor/ui", function() {
|
|||||||
nodes: {
|
nodes: {
|
||||||
getIcon: function(opts) {
|
getIcon: function(opts) {
|
||||||
return new Promise(function(resolve,reject) {
|
return new Promise(function(resolve,reject) {
|
||||||
fs.readFile(NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.svg"), function(err,data) {
|
if (opts.icon === "icon.png") {
|
||||||
resolve(data);
|
fs.readFile(NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.svg"), function(err,data) {
|
||||||
})
|
resolve(data);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
getModuleResource: async function(opts) {
|
||||||
|
if (opts.module !== "test-module" || opts.path !== "a/path/text.txt") {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return "Some text data";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -110,6 +121,53 @@ describe("api/editor/ui", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
it('returns the default icon for invalid paths', function(done) {
|
||||||
|
var defaultIcon = fs.readFileSync(NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.svg"));
|
||||||
|
request(app)
|
||||||
|
.get("/icons/module/unreal.png")
|
||||||
|
.expect("Content-Type", /image\/svg/)
|
||||||
|
.expect(200)
|
||||||
|
.parse(binaryParser)
|
||||||
|
.end(function(err,res) {
|
||||||
|
if (err){
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
Buffer.isBuffer(res.body).should.be.true();
|
||||||
|
compareBuffers(res.body,defaultIcon);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe("module resource handler", function() {
|
||||||
|
before(function() {
|
||||||
|
app = express();
|
||||||
|
app.get(/^\/resources\/((?:@[^\/]+\/)?[^\/]+)\/(.+)$/,ui.moduleResource);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the requested resource', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get("/resources/test-module/a/path/text.txt")
|
||||||
|
.expect(200)
|
||||||
|
.end(function(err,res) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
res.text.should.eql('Some text data');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('404s invalid paths', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get("/resources/test-module/../a/path/text.txt")
|
||||||
|
.expect(404)
|
||||||
|
.end(function(err,res) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("editor ui handler", function() {
|
describe("editor ui handler", function() {
|
||||||
|
@ -150,6 +150,51 @@ test-module-config`)
|
|||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe("exportPluginSettings", function() {
|
||||||
|
it("exports plugin settings - default false", function() {
|
||||||
|
plugins.init({ "a-plugin": { a: 123, b:234, c: 345} });
|
||||||
|
plugins.registerPlugin("test-module/test-set","a-plugin",{
|
||||||
|
settings: {
|
||||||
|
a: { exportable: true },
|
||||||
|
b: {exportable: false },
|
||||||
|
d: { exportable: true, value: 456}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var exportedSet = {};
|
||||||
|
plugins.exportPluginSettings(exportedSet);
|
||||||
|
exportedSet.should.have.property("a-plugin");
|
||||||
|
// a is exportable
|
||||||
|
exportedSet["a-plugin"].should.have.property("a",123);
|
||||||
|
// b is explicitly not exportable
|
||||||
|
exportedSet["a-plugin"].should.not.have.property("b");
|
||||||
|
// c isn't listed and default false
|
||||||
|
exportedSet["a-plugin"].should.not.have.property("c");
|
||||||
|
// d has a default value
|
||||||
|
exportedSet["a-plugin"].should.have.property("d",456);
|
||||||
|
})
|
||||||
|
it("exports plugin settings - default true", function() {
|
||||||
|
plugins.init({ "a-plugin": { a: 123, b:234, c: 345} });
|
||||||
|
plugins.registerPlugin("test-module/test-set","a-plugin",{
|
||||||
|
settings: {
|
||||||
|
'*': { exportable: true },
|
||||||
|
a: { exportable: true },
|
||||||
|
b: {exportable: false },
|
||||||
|
d: { exportable: true, value: 456}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
var exportedSet = {};
|
||||||
|
plugins.exportPluginSettings(exportedSet);
|
||||||
|
exportedSet.should.have.property("a-plugin");
|
||||||
|
// a is exportable
|
||||||
|
exportedSet["a-plugin"].should.have.property("a",123);
|
||||||
|
// b is explicitly not exportable
|
||||||
|
exportedSet["a-plugin"].should.not.have.property("b");
|
||||||
|
// c isn't listed, but default true
|
||||||
|
exportedSet["a-plugin"].should.have.property("c");
|
||||||
|
// d has a default value
|
||||||
|
exportedSet["a-plugin"].should.have.property("d",456);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -574,4 +574,41 @@ describe("red/nodes/registry/registry",function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getModuleResource', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
typeRegistry.init(settings,{});
|
||||||
|
typeRegistry.addModule({
|
||||||
|
name: "test-module",version:"0.0.1",nodes: {
|
||||||
|
"test-name":{
|
||||||
|
id: "test-module/test-name",
|
||||||
|
module: "test-module",
|
||||||
|
name: "test-name",
|
||||||
|
enabled: true,
|
||||||
|
loaded: false,
|
||||||
|
config: "configA",
|
||||||
|
types: [ "test-a","test-b"],
|
||||||
|
file: "abc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
path: path.join(__dirname, "resources","examples")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('Returns valid resource path', function() {
|
||||||
|
const result = typeRegistry.getModuleResource("test-module","one.json");
|
||||||
|
should.exist(result);
|
||||||
|
result.should.eql(path.join(__dirname, "resources","examples","one.json"))
|
||||||
|
});
|
||||||
|
it('Returns null for path that tries to break out', function() {
|
||||||
|
// Note - this path exists, but we don't allow .. in the resolved path to
|
||||||
|
// avoid breaking out of the resources dir
|
||||||
|
const result = typeRegistry.getModuleResource("test-module","../../index_spec.js");
|
||||||
|
should.not.exist(result);
|
||||||
|
});
|
||||||
|
it('Returns null for path that does not exist', function() {
|
||||||
|
const result = typeRegistry.getModuleResource("test-module","two.json");
|
||||||
|
should.not.exist(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,13 +15,61 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
const should = require("should");
|
const should = require("should");
|
||||||
|
const sinon = require("sinon");
|
||||||
|
|
||||||
const NR_TEST_UTILS = require("nr-test-utils");
|
const NR_TEST_UTILS = require("nr-test-utils");
|
||||||
const registryUtil = NR_TEST_UTILS.require("@node-red/registry/lib/util");
|
const registryUtil = NR_TEST_UTILS.require("@node-red/registry/lib/util");
|
||||||
|
|
||||||
|
// Get the internal runtime api
|
||||||
|
const runtime = NR_TEST_UTILS.require("@node-red/runtime")._;
|
||||||
|
|
||||||
|
const i18n = NR_TEST_UTILS.require("@node-red/util").i18n;
|
||||||
|
|
||||||
describe("red/nodes/registry/util",function() {
|
describe("red/nodes/registry/util",function() {
|
||||||
describe("createNodeApi", function() {
|
describe("createNodeApi", function() {
|
||||||
it.skip("needs tests");
|
let i18n_;
|
||||||
|
let registerType;
|
||||||
|
let registerSubflow;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
i18n_ = sinon.stub(i18n,"_").callsFake(function() {
|
||||||
|
return Array.prototype.slice.call(arguments,0);
|
||||||
|
})
|
||||||
|
registerType = sinon.stub(runtime.nodes,"registerType");
|
||||||
|
registerSubflow = sinon.stub(runtime.nodes,"registerSubflow");
|
||||||
|
});
|
||||||
|
after(function() {
|
||||||
|
i18n_.restore();
|
||||||
|
registerType.restore();
|
||||||
|
registerSubflow.restore();
|
||||||
|
})
|
||||||
|
|
||||||
|
it("builds node-specific view of runtime api", function() {
|
||||||
|
registryUtil.init(runtime);
|
||||||
|
var result = registryUtil.createNodeApi({id: "my-node", namespace: "my-namespace"})
|
||||||
|
// Need a better strategy here.
|
||||||
|
// For now, validate the node-custom functions
|
||||||
|
|
||||||
|
var message = result._("message");
|
||||||
|
// This should prepend the node's namespace to the message
|
||||||
|
message.should.eql([ 'my-namespace:message' ]);
|
||||||
|
|
||||||
|
var nodeConstructor = () => {};
|
||||||
|
var nodeOpts = {};
|
||||||
|
result.nodes.registerType("type",nodeConstructor, nodeOpts);
|
||||||
|
registerType.called.should.be.true();
|
||||||
|
registerType.lastCall.args[0].should.eql("my-node")
|
||||||
|
registerType.lastCall.args[1].should.eql("type")
|
||||||
|
registerType.lastCall.args[2].should.eql(nodeConstructor)
|
||||||
|
registerType.lastCall.args[3].should.eql(nodeOpts)
|
||||||
|
|
||||||
|
var subflowDef = {};
|
||||||
|
result.nodes.registerSubflow(subflowDef);
|
||||||
|
registerSubflow.called.should.be.true();
|
||||||
|
registerSubflow.lastCall.args[0].should.eql("my-node")
|
||||||
|
registerSubflow.lastCall.args[1].should.eql(subflowDef)
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe("checkModuleAllowed", function() {
|
describe("checkModuleAllowed", function() {
|
||||||
function checkList(module, version, allowList, denyList) {
|
function checkList(module, version, allowList, denyList) {
|
||||||
|
Loading…
Reference in New Issue
Block a user