mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
WIP: separate runtime and api components
This commit is contained in:
parent
923a46d304
commit
f43738446e
17
red.js
17
red.js
@ -25,7 +25,6 @@ var nopt = require("nopt");
|
|||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs-extra");
|
var fs = require("fs-extra");
|
||||||
var RED = require("./red/red.js");
|
var RED = require("./red/red.js");
|
||||||
var log = require("./red/log");
|
|
||||||
|
|
||||||
var server;
|
var server;
|
||||||
var app = express();
|
var app = express();
|
||||||
@ -205,7 +204,7 @@ function basicAuthMiddleware(user,pass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings.httpAdminRoot !== false && settings.httpAdminAuth) {
|
if (settings.httpAdminRoot !== false && settings.httpAdminAuth) {
|
||||||
RED.log.warn(log._("server.httpadminauth-deprecated"));
|
RED.log.warn(RED.log._("server.httpadminauth-deprecated"));
|
||||||
app.use(settings.httpAdminRoot, basicAuthMiddleware(settings.httpAdminAuth.user,settings.httpAdminAuth.pass));
|
app.use(settings.httpAdminRoot, basicAuthMiddleware(settings.httpAdminAuth.user,settings.httpAdminAuth.pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,10 +242,10 @@ RED.start().then(function() {
|
|||||||
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
|
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
|
||||||
server.on('error', function(err) {
|
server.on('error', function(err) {
|
||||||
if (err.errno === "EADDRINUSE") {
|
if (err.errno === "EADDRINUSE") {
|
||||||
RED.log.error(log._("server.unable-to-listen", {listenpath:getListenPath()}));
|
RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
|
||||||
RED.log.error(log._("server.port-in-use"));
|
RED.log.error(RED.log._("server.port-in-use"));
|
||||||
} else {
|
} else {
|
||||||
RED.log.error(log._("server.uncaught-exception"));
|
RED.log.error(RED.log._("server.uncaught-exception"));
|
||||||
if (err.stack) {
|
if (err.stack) {
|
||||||
RED.log.error(err.stack);
|
RED.log.error(err.stack);
|
||||||
} else {
|
} else {
|
||||||
@ -257,16 +256,16 @@ RED.start().then(function() {
|
|||||||
});
|
});
|
||||||
server.listen(settings.uiPort,settings.uiHost,function() {
|
server.listen(settings.uiPort,settings.uiHost,function() {
|
||||||
if (settings.httpAdminRoot === false) {
|
if (settings.httpAdminRoot === false) {
|
||||||
RED.log.info(log._("server.admin-ui-disabled"));
|
RED.log.info(RED.log._("server.admin-ui-disabled"));
|
||||||
}
|
}
|
||||||
process.title = 'node-red';
|
process.title = 'node-red';
|
||||||
RED.log.info(log._("server.now-running", {listenpath:getListenPath()}));
|
RED.log.info(RED.log._("server.now-running", {listenpath:getListenPath()}));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
RED.log.info(log._("server.headless-mode"));
|
RED.log.info(RED.log._("server.headless-mode"));
|
||||||
}
|
}
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
RED.log.error(log._("server.failed-to-start"));
|
RED.log.error(RED.log._("server.failed-to-start"));
|
||||||
if (err.stack) {
|
if (err.stack) {
|
||||||
RED.log.error(err.stack);
|
RED.log.error(err.stack);
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,7 +25,7 @@ var permissions = require("./permissions");
|
|||||||
var theme = require("../theme");
|
var theme = require("../theme");
|
||||||
|
|
||||||
var settings = null;
|
var settings = null;
|
||||||
var log = require("../../log");
|
var log = null
|
||||||
|
|
||||||
|
|
||||||
passport.use(strategies.bearerStrategy.BearerStrategy);
|
passport.use(strategies.bearerStrategy.BearerStrategy);
|
||||||
@ -36,11 +36,13 @@ var server = oauth2orize.createServer();
|
|||||||
|
|
||||||
server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange));
|
server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange));
|
||||||
|
|
||||||
function init(_settings,storage) {
|
function init(runtime) {
|
||||||
settings = _settings;
|
settings = runtime.settings;
|
||||||
|
log = runtime.log;
|
||||||
if (settings.adminAuth) {
|
if (settings.adminAuth) {
|
||||||
Users.init(settings.adminAuth);
|
Users.init(settings.adminAuth);
|
||||||
Tokens.init(settings.adminAuth,storage);
|
Tokens.init(settings.adminAuth,runtime.storage);
|
||||||
|
strategies.init(runtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ var Users = require("./users");
|
|||||||
var Clients = require("./clients");
|
var Clients = require("./clients");
|
||||||
var permissions = require("./permissions");
|
var permissions = require("./permissions");
|
||||||
|
|
||||||
var log = require("../../log");
|
var log;
|
||||||
|
|
||||||
var bearerStrategy = function (accessToken, done) {
|
var bearerStrategy = function (accessToken, done) {
|
||||||
// is this a valid token?
|
// is this a valid token?
|
||||||
@ -124,6 +124,9 @@ AnonymousStrategy.prototype.authenticate = function(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
log = runtime.log;
|
||||||
|
},
|
||||||
bearerStrategy: bearerStrategy,
|
bearerStrategy: bearerStrategy,
|
||||||
clientPasswordStrategy: clientPasswordStrategy,
|
clientPasswordStrategy: clientPasswordStrategy,
|
||||||
passwordTokenExchange: passwordTokenExchange,
|
passwordTokenExchange: passwordTokenExchange,
|
||||||
|
@ -14,10 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var log = require("../log");
|
var log;
|
||||||
var api = require("../nodes");
|
var api;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
log = runtime.log;
|
||||||
|
api = runtime.api;
|
||||||
|
},
|
||||||
get: function (req, res) {
|
get: function (req, res) {
|
||||||
// TODO: It should verify the given node id is of the type specified -
|
// TODO: It should verify the given node id is of the type specified -
|
||||||
// but that would add a dependency from this module to the
|
// but that would add a dependency from this module to the
|
||||||
|
@ -14,12 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var log = require("../log");
|
var log;
|
||||||
|
var redNodes;
|
||||||
var redNodes = require("../nodes");
|
var settings;
|
||||||
var settings = require("../settings");
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
settings = runtime.settings;
|
||||||
|
redNodes = runtime.api;
|
||||||
|
log = runtime.log;
|
||||||
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
log.audit({event: "flows.get"},req);
|
log.audit({event: "flows.get"},req);
|
||||||
res.json(redNodes.getFlows());
|
res.json(redNodes.getFlows());
|
||||||
|
149
red/api/index.js
149
red/api/index.js
@ -29,12 +29,12 @@ var theme = require("./theme");
|
|||||||
var locales = require("./locales");
|
var locales = require("./locales");
|
||||||
var credentials = require("./credentials");
|
var credentials = require("./credentials");
|
||||||
|
|
||||||
var log = require("../log");
|
|
||||||
|
|
||||||
var auth = require("./auth");
|
var auth = require("./auth");
|
||||||
var needsPermission = auth.needsPermission;
|
var needsPermission = auth.needsPermission;
|
||||||
|
|
||||||
var settings = require("../settings");
|
var log;
|
||||||
|
var adminApp;
|
||||||
|
var nodeApp;
|
||||||
|
|
||||||
var errorHandler = function(err,req,res,next) {
|
var errorHandler = function(err,req,res,next) {
|
||||||
if (err.message === "request entity too large") {
|
if (err.message === "request entity too large") {
|
||||||
@ -46,71 +46,92 @@ var errorHandler = function(err,req,res,next) {
|
|||||||
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
||||||
};
|
};
|
||||||
|
|
||||||
function init(adminApp,storage) {
|
function init(runtime) {
|
||||||
|
var settings = runtime.settings;
|
||||||
|
log = runtime.log;
|
||||||
|
if (settings.httpNodeRoot !== false) {
|
||||||
|
nodeApp = express();
|
||||||
|
}
|
||||||
|
if (settings.httpAdminRoot !== false) {
|
||||||
|
adminApp = express();
|
||||||
|
auth.init(runtime);
|
||||||
|
credentials.init(runtime);
|
||||||
|
flows.init(runtime);
|
||||||
|
info.init(runtime);
|
||||||
|
library.init(adminApp,runtime);
|
||||||
|
locales.init(runtime);
|
||||||
|
nodes.init(runtime);
|
||||||
|
|
||||||
auth.init(settings,storage);
|
// Editor
|
||||||
// Editor
|
if (!settings.disableEditor) {
|
||||||
if (!settings.disableEditor) {
|
ui.init(runtime);
|
||||||
ui.init(settings);
|
var editorApp = express();
|
||||||
var editorApp = express();
|
editorApp.get("/",ui.ensureSlash,ui.editor);
|
||||||
editorApp.get("/",ui.ensureSlash,ui.editor);
|
editorApp.get("/icons/:icon",ui.icon);
|
||||||
editorApp.get("/icons/:icon",ui.icon);
|
if (settings.editorTheme) {
|
||||||
if (settings.editorTheme) {
|
editorApp.use("/theme",theme.init(runtime));
|
||||||
editorApp.use("/theme",theme.init(settings));
|
}
|
||||||
|
editorApp.use("/",ui.editorResources);
|
||||||
|
adminApp.use(editorApp);
|
||||||
}
|
}
|
||||||
editorApp.use("/",ui.editorResources);
|
var maxApiRequestSize = settings.apiMaxLength || '1mb';
|
||||||
adminApp.use(editorApp);
|
adminApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
||||||
|
adminApp.use(bodyParser.urlencoded({limit:maxApiRequestSize,extended:true}));
|
||||||
|
|
||||||
|
adminApp.get("/auth/login",auth.login);
|
||||||
|
|
||||||
|
if (settings.adminAuth) {
|
||||||
|
//TODO: all passport references ought to be in ./auth
|
||||||
|
adminApp.use(passport.initialize());
|
||||||
|
adminApp.post("/auth/token",
|
||||||
|
auth.ensureClientSecret,
|
||||||
|
auth.authenticateClient,
|
||||||
|
auth.getToken,
|
||||||
|
auth.errorHandler
|
||||||
|
);
|
||||||
|
adminApp.post("/auth/revoke",needsPermission(""),auth.revoke);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flows
|
||||||
|
adminApp.get("/flows",needsPermission("flows.read"),flows.get);
|
||||||
|
adminApp.post("/flows",needsPermission("flows.write"),flows.post);
|
||||||
|
|
||||||
|
// Nodes
|
||||||
|
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll);
|
||||||
|
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post);
|
||||||
|
|
||||||
|
adminApp.get("/nodes/:mod",needsPermission("nodes.read"),nodes.getModule);
|
||||||
|
adminApp.put("/nodes/:mod",needsPermission("nodes.write"),nodes.putModule);
|
||||||
|
adminApp.delete("/nodes/:mod",needsPermission("nodes.write"),nodes.delete);
|
||||||
|
|
||||||
|
adminApp.get("/nodes/:mod/:set",needsPermission("nodes.read"),nodes.getSet);
|
||||||
|
adminApp.put("/nodes/:mod/:set",needsPermission("nodes.write"),nodes.putSet);
|
||||||
|
|
||||||
|
adminApp.get('/credentials/:type/:id', needsPermission("credentials.read"),credentials.get);
|
||||||
|
|
||||||
|
adminApp.get(/locales\/(.+)\/?$/,locales.get);
|
||||||
|
|
||||||
|
// Library
|
||||||
|
adminApp.post(new RegExp("/library/flows\/(.*)"),needsPermission("library.write"),library.post);
|
||||||
|
adminApp.get("/library/flows",needsPermission("library.read"),library.getAll);
|
||||||
|
adminApp.get(new RegExp("/library/flows\/(.*)"),needsPermission("library.read"),library.get);
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
adminApp.get("/settings",needsPermission("settings.read"),info.settings);
|
||||||
|
|
||||||
|
// Error Handler
|
||||||
|
adminApp.use(errorHandler);
|
||||||
}
|
}
|
||||||
var maxApiRequestSize = settings.apiMaxLength || '1mb';
|
|
||||||
adminApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
|
||||||
adminApp.use(bodyParser.urlencoded({limit:maxApiRequestSize,extended:true}));
|
|
||||||
|
|
||||||
adminApp.get("/auth/login",auth.login);
|
|
||||||
|
|
||||||
if (settings.adminAuth) {
|
|
||||||
//TODO: all passport references ought to be in ./auth
|
|
||||||
adminApp.use(passport.initialize());
|
|
||||||
adminApp.post("/auth/token",
|
|
||||||
auth.ensureClientSecret,
|
|
||||||
auth.authenticateClient,
|
|
||||||
auth.getToken,
|
|
||||||
auth.errorHandler
|
|
||||||
);
|
|
||||||
adminApp.post("/auth/revoke",needsPermission(""),auth.revoke);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flows
|
|
||||||
adminApp.get("/flows",needsPermission("flows.read"),flows.get);
|
|
||||||
adminApp.post("/flows",needsPermission("flows.write"),flows.post);
|
|
||||||
|
|
||||||
// Nodes
|
|
||||||
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll);
|
|
||||||
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post);
|
|
||||||
|
|
||||||
adminApp.get("/nodes/:mod",needsPermission("nodes.read"),nodes.getModule);
|
|
||||||
adminApp.put("/nodes/:mod",needsPermission("nodes.write"),nodes.putModule);
|
|
||||||
adminApp.delete("/nodes/:mod",needsPermission("nodes.write"),nodes.delete);
|
|
||||||
|
|
||||||
adminApp.get("/nodes/:mod/:set",needsPermission("nodes.read"),nodes.getSet);
|
|
||||||
adminApp.put("/nodes/:mod/:set",needsPermission("nodes.write"),nodes.putSet);
|
|
||||||
|
|
||||||
adminApp.get('/credentials/:type/:id', needsPermission("credentials.read"),credentials.get);
|
|
||||||
|
|
||||||
adminApp.get(/locales\/(.+)\/?$/,locales.get);
|
|
||||||
|
|
||||||
// Library
|
|
||||||
library.init(adminApp);
|
|
||||||
adminApp.post(new RegExp("/library/flows\/(.*)"),needsPermission("library.write"),library.post);
|
|
||||||
adminApp.get("/library/flows",needsPermission("library.read"),library.getAll);
|
|
||||||
adminApp.get(new RegExp("/library/flows\/(.*)"),needsPermission("library.read"),library.get);
|
|
||||||
|
|
||||||
// Settings
|
|
||||||
adminApp.get("/settings",needsPermission("settings.read"),info.settings);
|
|
||||||
|
|
||||||
// Error Handler
|
|
||||||
adminApp.use(errorHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: init
|
init: init,
|
||||||
|
library: {
|
||||||
|
register: library.register
|
||||||
|
},
|
||||||
|
auth: {
|
||||||
|
needsPermission: auth.needsPermission
|
||||||
|
},
|
||||||
|
adminApp: function() { return adminApp; },
|
||||||
|
nodeApp: function() { return nodeApp; }
|
||||||
};
|
};
|
||||||
|
@ -13,28 +13,30 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
var settings = require('../settings');
|
|
||||||
var theme = require("./theme");
|
var theme = require("./theme");
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
var settings;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
settings = runtime.settings;
|
||||||
|
},
|
||||||
settings: function(req,res) {
|
settings: function(req,res) {
|
||||||
var safeSettings = {
|
var safeSettings = {
|
||||||
httpNodeRoot: settings.httpNodeRoot,
|
httpNodeRoot: settings.httpNodeRoot,
|
||||||
version: settings.version,
|
version: settings.version,
|
||||||
user: req.user
|
user: req.user
|
||||||
}
|
}
|
||||||
|
|
||||||
var themeSettings = theme.settings();
|
var themeSettings = theme.settings();
|
||||||
if (themeSettings) {
|
if (themeSettings) {
|
||||||
safeSettings.editorTheme = themeSettings;
|
safeSettings.editorTheme = themeSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.isArray(settings.paletteCategories)) {
|
if (util.isArray(settings.paletteCategories)) {
|
||||||
safeSettings.paletteCategories = settings.paletteCategories;
|
safeSettings.paletteCategories = settings.paletteCategories;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json(safeSettings);
|
res.json(safeSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,8 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var redApp = null;
|
var redApp = null;
|
||||||
var storage = require("../storage");
|
var storage;
|
||||||
var log = require("../log");
|
var log;
|
||||||
|
|
||||||
var needsPermission = require("./auth").needsPermission;
|
var needsPermission = require("./auth").needsPermission;
|
||||||
|
|
||||||
function createLibrary(type) {
|
function createLibrary(type) {
|
||||||
@ -70,8 +69,10 @@ function createLibrary(type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(app) {
|
init: function(app,runtime) {
|
||||||
redApp = app;
|
redApp = app;
|
||||||
|
log = runtime.log;
|
||||||
|
storage = runtime.storage;
|
||||||
},
|
},
|
||||||
register: createLibrary,
|
register: createLibrary,
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ module.exports = {
|
|||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.warn(log._("api.library.error-load-flow",{path:req.params[0],message:err.toString()}));
|
log.warn(log._("api.library.error-load-flow",{path:req.params[0],message:err.toString()}));
|
||||||
if (err.code === 'forbidden') {
|
if (err.code === 'forbidden') {
|
||||||
log.audit({event: "library.get",type:"flow",path:req.params[0],error:"forbidden"},req);
|
log.audit({event: "library.get",type:"flow",path:req.params[0],error:"forbidden"},req);
|
||||||
res.status(403).end();
|
res.status(403).end();
|
||||||
return;
|
return;
|
||||||
|
@ -13,9 +13,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
var i18n = require("../i18n");
|
var i18n;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
i18n = runtime.i18n;
|
||||||
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
var namespace = req.params[0];
|
var namespace = req.params[0];
|
||||||
namespace = namespace.replace(/\.json$/,"");
|
namespace = namespace.replace(/\.json$/,"");
|
||||||
|
@ -13,16 +13,22 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
var redNodes = require("../nodes");
|
|
||||||
var comms = require("../comms");
|
|
||||||
var log = require("../log");
|
|
||||||
var i18n = require("../i18n");
|
|
||||||
|
|
||||||
var when = require("when");
|
var when = require("when");
|
||||||
|
var redNodes;
|
||||||
var settings = require("../settings");
|
var comms;
|
||||||
|
var log;
|
||||||
|
var i18n;
|
||||||
|
var settings;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init: function(runtime) {
|
||||||
|
redNodes = runtime.api;
|
||||||
|
comms = runtime.comms;
|
||||||
|
log = runtime.log;
|
||||||
|
i18n = runtime.i18n;
|
||||||
|
settings = runtime.settings;
|
||||||
|
},
|
||||||
getAll: function(req,res) {
|
getAll: function(req,res) {
|
||||||
if (req.get("accept") == "application/json") {
|
if (req.get("accept") == "application/json") {
|
||||||
log.audit({event: "nodes.list.get"},req);
|
log.audit({event: "nodes.list.get"},req);
|
||||||
|
@ -53,7 +53,8 @@ function serveFile(app,baseUrl,file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(settings) {
|
init: function(runtime) {
|
||||||
|
var settings = runtime.settings;
|
||||||
var i;
|
var i;
|
||||||
var url;
|
var url;
|
||||||
themeContext = clone(defaultContext);
|
themeContext = clone(defaultContext);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2013, 2014 IBM Corp.
|
* Copyright 2013, 2015 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,26 +21,26 @@ var theme = require("./theme");
|
|||||||
|
|
||||||
var Mustache = require("mustache");
|
var Mustache = require("mustache");
|
||||||
|
|
||||||
var events = require("../events");
|
|
||||||
var settings;
|
|
||||||
|
|
||||||
var icon_paths = [path.resolve(__dirname + '/../../public/icons')];
|
var icon_paths = [path.resolve(__dirname + '/../../public/icons')];
|
||||||
var iconCache = {};
|
var iconCache = {};
|
||||||
//TODO: create a default icon
|
//TODO: create a default icon
|
||||||
var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png');
|
var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png');
|
||||||
|
|
||||||
events.on("node-icon-dir",function(dir) {
|
|
||||||
icon_paths.push(path.resolve(dir));
|
|
||||||
});
|
|
||||||
|
|
||||||
var templateDir = path.resolve(__dirname+"/../../editor/templates");
|
var templateDir = path.resolve(__dirname+"/../../editor/templates");
|
||||||
var editorTemplate;
|
var editorTemplate;
|
||||||
|
|
||||||
|
function nodeIconDir(dir) {
|
||||||
|
icon_paths.push(path.resolve(dir));
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(_settings) {
|
init: function(runtime) {
|
||||||
settings = _settings;
|
|
||||||
editorTemplate = fs.readFileSync(path.join(templateDir,"index.mst"),"utf8");
|
editorTemplate = fs.readFileSync(path.join(templateDir,"index.mst"),"utf8");
|
||||||
Mustache.parse(editorTemplate);
|
Mustache.parse(editorTemplate);
|
||||||
|
// TODO: this allows init to be called multiple times without
|
||||||
|
// registering multiple instances of the listener.
|
||||||
|
// It isn't.... ideal.
|
||||||
|
runtime.events.removeListener("node-icon-dir",nodeIconDir);
|
||||||
|
runtime.events.on("node-icon-dir",nodeIconDir);
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureSlash: function(req,res,next) {
|
ensureSlash: function(req,res,next) {
|
||||||
|
80
red/red.js
80
red/red.js
@ -14,22 +14,18 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var server = require("./server");
|
|
||||||
var nodes = require("./nodes");
|
|
||||||
var library = require("./api/library");
|
|
||||||
var comms = require("./comms");
|
|
||||||
var log = require("./log");
|
|
||||||
var util = require("./util");
|
|
||||||
var i18n = require("./i18n");
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var settings = require("./settings");
|
|
||||||
var credentials = require("./nodes/credentials");
|
|
||||||
var auth = require("./api/auth");
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var events = require("events");
|
|
||||||
|
var runtime = require("./runtime");
|
||||||
|
var api = require("./api");
|
||||||
|
|
||||||
process.env.NODE_RED_HOME = process.env.NODE_RED_HOME || path.resolve(__dirname+"/..");
|
process.env.NODE_RED_HOME = process.env.NODE_RED_HOME || path.resolve(__dirname+"/..");
|
||||||
|
|
||||||
|
var nodeApp = null;
|
||||||
|
var adminApp = null;
|
||||||
|
var server = null;
|
||||||
|
|
||||||
function checkBuild() {
|
function checkBuild() {
|
||||||
var editorFile = path.resolve(path.join(__dirname,"..","public","red","red.min.js"));
|
var editorFile = path.resolve(path.join(__dirname,"..","public","red","red.min.js"));
|
||||||
try {
|
try {
|
||||||
@ -43,40 +39,44 @@ function checkBuild() {
|
|||||||
|
|
||||||
var RED = {
|
var RED = {
|
||||||
init: function(httpServer,userSettings) {
|
init: function(httpServer,userSettings) {
|
||||||
|
server = httpServer;
|
||||||
|
|
||||||
if (!userSettings.SKIP_BUILD_CHECK) {
|
if (!userSettings.SKIP_BUILD_CHECK) {
|
||||||
checkBuild();
|
checkBuild();
|
||||||
}
|
}
|
||||||
userSettings.version = this.version();
|
runtime.init(httpServer,userSettings);
|
||||||
log.init(userSettings);
|
if (userSettings.httpAdminRoot !== false || userSettings.httpNodeRoot !== false) {
|
||||||
settings.init(userSettings);
|
api.init(runtime);
|
||||||
server.init(httpServer,settings);
|
adminApp = api.adminApp();
|
||||||
return server.app;
|
nodeApp = api.nodeApp();
|
||||||
},
|
|
||||||
start: server.start,
|
|
||||||
stop: server.stop,
|
|
||||||
nodes: nodes,
|
|
||||||
library: { register: library.register },
|
|
||||||
credentials: credentials,
|
|
||||||
events: events,
|
|
||||||
log: log,
|
|
||||||
comms: comms,
|
|
||||||
settings:settings,
|
|
||||||
util: util,
|
|
||||||
auth: {
|
|
||||||
needsPermission: auth.needsPermission
|
|
||||||
},
|
|
||||||
version: function () {
|
|
||||||
var p = require(path.join(process.env.NODE_RED_HOME,"package.json")).version;
|
|
||||||
/* istanbul ignore else */
|
|
||||||
if (fs.existsSync(path.join(process.env.NODE_RED_HOME,".git"))) {
|
|
||||||
p += "-git";
|
|
||||||
}
|
}
|
||||||
return p;
|
|
||||||
|
if (adminApp === null) {
|
||||||
|
adminApp = {
|
||||||
|
get:function(){},
|
||||||
|
post: function(){},
|
||||||
|
put: function(){},
|
||||||
|
delete: function(){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return runtime.app;
|
||||||
},
|
},
|
||||||
get app() { console.log("Deprecated use of RED.app - use RED.httpAdmin instead"); return server.app },
|
start: runtime.start,
|
||||||
get httpAdmin() { return server.app },
|
stop: runtime.stop,
|
||||||
get httpNode() { return server.nodeApp },
|
nodes: runtime.api,
|
||||||
get server() { return server.server }
|
events: runtime.events,
|
||||||
|
log: runtime.log,
|
||||||
|
comms: runtime.comms,
|
||||||
|
settings:runtime.settings,
|
||||||
|
util: runtime.util,
|
||||||
|
version: runtime.version,
|
||||||
|
library: api.library,
|
||||||
|
auth: api.auth,
|
||||||
|
|
||||||
|
get app() { console.log("Deprecated use of RED.app - use RED.httpAdmin instead"); return runtime.app },
|
||||||
|
get httpAdmin() { return adminApp },
|
||||||
|
get httpNode() { return nodeApp },
|
||||||
|
get server() { return server }
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = RED;
|
module.exports = RED;
|
||||||
|
@ -37,9 +37,9 @@ function init(_server,_settings) {
|
|||||||
|
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
var Tokens = require("./api/auth/tokens");
|
var Tokens = require("../api/auth/tokens");
|
||||||
var Users = require("./api/auth/users");
|
var Users = require("../api/auth/users");
|
||||||
var Permissions = require("./api/auth/permissions");
|
var Permissions = require("../api/auth/permissions");
|
||||||
if (!settings.disableEditor) {
|
if (!settings.disableEditor) {
|
||||||
Users.default().then(function(anonymousUser) {
|
Users.default().then(function(anonymousUser) {
|
||||||
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
|
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
|
@ -24,11 +24,11 @@ var supportedLangs = [];
|
|||||||
|
|
||||||
var resourceMap = {
|
var resourceMap = {
|
||||||
"runtime": {
|
"runtime": {
|
||||||
basedir: path.resolve(__dirname+"/../locales"),
|
basedir: path.resolve(__dirname+"/../../locales"),
|
||||||
file:"runtime.json"
|
file:"runtime.json"
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
basedir: path.resolve(__dirname+"/../locales"),
|
basedir: path.resolve(__dirname+"/../../locales"),
|
||||||
file: "editor.json"
|
file: "editor.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var express = require('express');
|
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
var redNodes = require("./nodes");
|
var redNodes = require("./nodes");
|
||||||
@ -22,23 +21,27 @@ var comms = require("./comms");
|
|||||||
var storage = require("./storage");
|
var storage = require("./storage");
|
||||||
var log = require("./log");
|
var log = require("./log");
|
||||||
var i18n = require("./i18n");
|
var i18n = require("./i18n");
|
||||||
|
var events = require("./events");
|
||||||
var app = null;
|
var settings = require("./settings");
|
||||||
var nodeApp = null;
|
var path = require('path');
|
||||||
var server = null;
|
var fs = require("fs");
|
||||||
var settings = null;
|
|
||||||
|
|
||||||
var runtimeMetricInterval = null;
|
var runtimeMetricInterval = null;
|
||||||
|
|
||||||
|
function init(server,userSettings) {
|
||||||
|
userSettings.version = version();
|
||||||
|
log.init(userSettings);
|
||||||
|
settings.init(userSettings);
|
||||||
|
comms.init(server,settings);
|
||||||
|
}
|
||||||
|
|
||||||
function init(_server,_settings) {
|
function version() {
|
||||||
server = _server;
|
var p = require(path.join(process.env.NODE_RED_HOME,"package.json")).version;
|
||||||
settings = _settings;
|
/* istanbul ignore else */
|
||||||
|
if (fs.existsSync(path.join(process.env.NODE_RED_HOME,".git"))) {
|
||||||
comms.init(_server,_settings);
|
p += "-git";
|
||||||
|
}
|
||||||
nodeApp = express();
|
return p;
|
||||||
app = express();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
@ -46,9 +49,6 @@ function start() {
|
|||||||
.then(function() { return storage.init(settings)})
|
.then(function() { return storage.init(settings)})
|
||||||
.then(function() { return settings.load(storage)})
|
.then(function() { return settings.load(storage)})
|
||||||
.then(function() {
|
.then(function() {
|
||||||
if (settings.httpAdminRoot !== false) {
|
|
||||||
require("./api").init(app,storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log.metric()) {
|
if (log.metric()) {
|
||||||
runtimeMetricInterval = setInterval(function() {
|
runtimeMetricInterval = setInterval(function() {
|
||||||
@ -141,12 +141,19 @@ function stop() {
|
|||||||
comms.stop();
|
comms.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverAPI = module.exports = {
|
var runtime = module.exports = {
|
||||||
init: init,
|
init: init,
|
||||||
start: start,
|
start: start,
|
||||||
stop: stop,
|
stop: stop,
|
||||||
|
|
||||||
get app() { return app },
|
version: version,
|
||||||
get nodeApp() { return nodeApp },
|
|
||||||
get server() { return server }
|
log: log,
|
||||||
|
i18n: i18n,
|
||||||
|
settings: settings,
|
||||||
|
storage: storage,
|
||||||
|
comms: comms,
|
||||||
|
events: events,
|
||||||
|
api: redNodes,
|
||||||
|
util: require("./util")
|
||||||
}
|
}
|
@ -18,8 +18,6 @@ var when = require("when");
|
|||||||
|
|
||||||
var log = require("../log");
|
var log = require("../log");
|
||||||
|
|
||||||
var needsPermission = require("../api/auth").needsPermission;
|
|
||||||
|
|
||||||
var credentialCache = {};
|
var credentialCache = {};
|
||||||
var storage = null;
|
var storage = null;
|
||||||
var credentialsDef = {};
|
var credentialsDef = {};
|
@ -36,9 +36,7 @@ events.on("node-locales-dir", function(info) {
|
|||||||
function init(_settings) {
|
function init(_settings) {
|
||||||
settings = _settings;
|
settings = _settings;
|
||||||
localfilesystem.init(settings);
|
localfilesystem.init(settings);
|
||||||
|
RED = require('../../../red');
|
||||||
RED = require('../../red');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function load(defaultNodesDir,disableNodePathScan) {
|
function load(defaultNodesDir,disableNodePathScan) {
|
@ -22,7 +22,7 @@ var events = require("../../events");
|
|||||||
var log = require("../../log");
|
var log = require("../../log");
|
||||||
|
|
||||||
var settings;
|
var settings;
|
||||||
var defaultNodesDir = path.resolve(path.join(__dirname,"..","..","..","nodes"));
|
var defaultNodesDir = path.resolve(path.join(__dirname,"..","..","..","..","nodes"));
|
||||||
var disableNodePathScan = false;
|
var disableNodePathScan = false;
|
||||||
|
|
||||||
function init(_settings,_defaultNodesDir,_disableNodePathScan) {
|
function init(_settings,_defaultNodesDir,_disableNodePathScan) {
|
||||||
@ -133,7 +133,7 @@ function scanDirForNodesModules(dir,moduleName) {
|
|||||||
* @return a list of node modules: {dir,package}
|
* @return a list of node modules: {dir,package}
|
||||||
*/
|
*/
|
||||||
function scanTreeForNodesModules(moduleName) {
|
function scanTreeForNodesModules(moduleName) {
|
||||||
var dir = __dirname+"/../../nodes";
|
var dir = __dirname+"/../../../../nodes";
|
||||||
var results = [];
|
var results = [];
|
||||||
var userDir;
|
var userDir;
|
||||||
|
|
@ -256,7 +256,7 @@ function getFullNodeInfo(typeOrId) {
|
|||||||
var module = moduleConfigs[getModule(id)];
|
var module = moduleConfigs[getModule(id)];
|
||||||
if (module) {
|
if (module) {
|
||||||
return module.nodes[getNode(id)];
|
return module.nodes[getNode(id)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -292,7 +292,7 @@ function getModuleList() {
|
|||||||
//}
|
//}
|
||||||
//return list;
|
//return list;
|
||||||
return moduleConfigs;
|
return moduleConfigs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModuleInfo(module) {
|
function getModuleInfo(module) {
|
||||||
@ -358,7 +358,7 @@ function getNodeConfig(id,lang) {
|
|||||||
if (config) {
|
if (config) {
|
||||||
var result = config.config;
|
var result = config.config;
|
||||||
result += loader.getNodeHelp(config,lang||"en-US")
|
result += loader.getNodeHelp(config,lang||"en-US")
|
||||||
|
|
||||||
//if (config.script) {
|
//if (config.script) {
|
||||||
// result += '<script type="text/javascript">'+config.script+'</script>';
|
// result += '<script type="text/javascript">'+config.script+'</script>';
|
||||||
//}
|
//}
|
||||||
@ -490,9 +490,9 @@ var registry = module.exports = {
|
|||||||
addNodeSet: addNodeSet,
|
addNodeSet: addNodeSet,
|
||||||
enableNodeSet: enableNodeSet,
|
enableNodeSet: enableNodeSet,
|
||||||
disableNodeSet: disableNodeSet,
|
disableNodeSet: disableNodeSet,
|
||||||
|
|
||||||
removeModule: removeModule,
|
removeModule: removeModule,
|
||||||
|
|
||||||
getNodeInfo: getNodeInfo,
|
getNodeInfo: getNodeInfo,
|
||||||
getFullNodeInfo: getFullNodeInfo,
|
getFullNodeInfo: getFullNodeInfo,
|
||||||
getNodeList: getNodeList,
|
getNodeList: getNodeList,
|
@ -24,12 +24,14 @@ var auth = require("../../../../red/api/auth");
|
|||||||
var Users = require("../../../../red/api/auth/users");
|
var Users = require("../../../../red/api/auth/users");
|
||||||
var Tokens = require("../../../../red/api/auth/tokens");
|
var Tokens = require("../../../../red/api/auth/tokens");
|
||||||
|
|
||||||
var settings = require("../../../../red/settings");
|
|
||||||
|
|
||||||
|
|
||||||
describe("api auth middleware",function() {
|
describe("api auth middleware",function() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe("ensureClientSecret", function() {
|
describe("ensureClientSecret", function() {
|
||||||
|
before(function() {
|
||||||
|
auth.init({settings:{},log:{audit:function(){}}})
|
||||||
|
});
|
||||||
it("leaves client_secret alone if not present",function(done) {
|
it("leaves client_secret alone if not present",function(done) {
|
||||||
var req = {
|
var req = {
|
||||||
body: {
|
body: {
|
||||||
@ -83,7 +85,7 @@ describe("api auth middleware",function() {
|
|||||||
Users.init.restore();
|
Users.init.restore();
|
||||||
});
|
});
|
||||||
it("returns login details - credentials", function(done) {
|
it("returns login details - credentials", function(done) {
|
||||||
auth.init({adminAuth:{}},null);
|
auth.init({settings:{adminAuth:{}},log:{audit:function(){}}})
|
||||||
auth.login(null,{json: function(resp) {
|
auth.login(null,{json: function(resp) {
|
||||||
resp.should.have.a.property("type","credentials");
|
resp.should.have.a.property("type","credentials");
|
||||||
resp.should.have.a.property("prompts");
|
resp.should.have.a.property("prompts");
|
||||||
@ -92,7 +94,7 @@ describe("api auth middleware",function() {
|
|||||||
}});
|
}});
|
||||||
});
|
});
|
||||||
it("returns login details - none", function(done) {
|
it("returns login details - none", function(done) {
|
||||||
auth.init({},null);
|
auth.init({settings:{},log:{audit:function(){}}})
|
||||||
auth.login(null,{json: function(resp) {
|
auth.login(null,{json: function(resp) {
|
||||||
resp.should.eql({});
|
resp.should.eql({});
|
||||||
done();
|
done();
|
||||||
|
@ -24,8 +24,10 @@ var Tokens = require("../../../../red/api/auth/tokens");
|
|||||||
var Clients = require("../../../../red/api/auth/clients");
|
var Clients = require("../../../../red/api/auth/clients");
|
||||||
|
|
||||||
describe("Auth strategies", function() {
|
describe("Auth strategies", function() {
|
||||||
|
before(function() {
|
||||||
|
strategies.init({log:{audit:function(){}}})
|
||||||
|
});
|
||||||
describe("Password Token Exchange", function() {
|
describe("Password Token Exchange", function() {
|
||||||
|
|
||||||
var userAuthentication;
|
var userAuthentication;
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
if (userAuthentication) {
|
if (userAuthentication) {
|
||||||
@ -49,7 +51,7 @@ describe("Auth strategies", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Handles scope overreach',function(done) {
|
it('Handles scope overreach',function(done) {
|
||||||
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
|
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
|
||||||
return when.resolve({username:"user",permissions:"read"});
|
return when.resolve({username:"user",permissions:"read"});
|
||||||
|
@ -20,8 +20,6 @@ var express = require('express');
|
|||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
|
|
||||||
var nodeApi = require("../../../red/nodes");
|
|
||||||
var credentials = require("../../../red/api/credentials");
|
var credentials = require("../../../red/api/credentials");
|
||||||
|
|
||||||
describe('credentials api', function() {
|
describe('credentials api', function() {
|
||||||
@ -30,26 +28,26 @@ describe('credentials api', function() {
|
|||||||
before(function() {
|
before(function() {
|
||||||
app = express();
|
app = express();
|
||||||
app.get('/credentials/:type/:id',credentials.get);
|
app.get('/credentials/:type/:id',credentials.get);
|
||||||
|
credentials.init({
|
||||||
sinon.stub(nodeApi,"getCredentials",function(id) {
|
log:{audit:function(){}},
|
||||||
if (id === "n1") {
|
api:{
|
||||||
return {user1:"abc",password1:"123"};
|
getCredentials: function(id) {
|
||||||
} else {
|
if (id === "n1") {
|
||||||
return null;
|
return {user1:"abc",password1:"123"};
|
||||||
}
|
} else {
|
||||||
});
|
return null;
|
||||||
sinon.stub(nodeApi,"getCredentialDefinition",function(type) {
|
}
|
||||||
if (type === "known-type") {
|
},
|
||||||
return {user1:{type:"text"},password1:{type:"password"}};
|
getCredentialDefinition:function(type) {
|
||||||
} else {
|
if (type === "known-type") {
|
||||||
return null;
|
return {user1:{type:"text"},password1:{type:"password"}};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
after(function() {
|
|
||||||
nodeApi.getCredentials.restore();
|
|
||||||
nodeApi.getCredentialDefinition.restore();
|
|
||||||
})
|
|
||||||
it('returns empty credentials if unknown type',function(done) {
|
it('returns empty credentials if unknown type',function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/credentials/unknown-type/n1")
|
.get("/credentials/unknown-type/n1")
|
||||||
|
@ -21,8 +21,6 @@ var bodyParser = require('body-parser');
|
|||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
var redNodes = require("../../../red/nodes");
|
|
||||||
|
|
||||||
var flows = require("../../../red/api/flows");
|
var flows = require("../../../red/api/flows");
|
||||||
|
|
||||||
describe("flows api", function() {
|
describe("flows api", function() {
|
||||||
@ -37,15 +35,17 @@ describe("flows api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns flow', function(done) {
|
it('returns flow', function(done) {
|
||||||
var getFlows = sinon.stub(redNodes,'getFlows', function() {
|
flows.init({
|
||||||
return [1,2,3];
|
log:{warn:function(){},_:function(){},audit:function(){}},
|
||||||
|
api:{
|
||||||
|
getFlows: function() { return [1,2,3]; }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/flows')
|
.get('/flows')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getFlows.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -55,15 +55,17 @@ describe("flows api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets flows', function(done) {
|
it('sets flows', function(done) {
|
||||||
var setFlows = sinon.stub(redNodes,'setFlows', function() {
|
flows.init({
|
||||||
return when.resolve();
|
log:{warn:function(){},_:function(){},audit:function(){}},
|
||||||
|
api:{
|
||||||
|
setFlows: function() { return when.resolve(); }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/flows')
|
.post('/flows')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(204)
|
.expect(204)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
setFlows.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -71,15 +73,17 @@ describe("flows api", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('returns error when set fails', function(done) {
|
it('returns error when set fails', function(done) {
|
||||||
var setFlows = sinon.stub(redNodes,'setFlows', function() {
|
flows.init({
|
||||||
return when.reject(new Error("expected error"));
|
log:{warn:function(){},_:function(){},audit:function(){}},
|
||||||
|
api:{
|
||||||
|
setFlows: function() { return when.reject(new Error("expected error")); }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/flows')
|
.post('/flows')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(500)
|
.expect(500)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
setFlows.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var should = require("should");
|
var should = require("should");
|
||||||
|
var sinon = require("sinon");
|
||||||
var request = require("supertest");
|
var request = require("supertest");
|
||||||
var express = require("express");
|
var express = require("express");
|
||||||
var when = require("when");
|
var when = require("when");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var settings = require("../../../red/settings");
|
|
||||||
var api = require("../../../red/api");
|
var api = require("../../../red/api");
|
||||||
|
|
||||||
describe("api index", function() {
|
describe("api index", function() {
|
||||||
@ -28,12 +28,13 @@ describe("api index", function() {
|
|||||||
|
|
||||||
describe("disables editor", function() {
|
describe("disables editor", function() {
|
||||||
before(function() {
|
before(function() {
|
||||||
settings.init({disableEditor:true});
|
|
||||||
app = express();
|
app = express();
|
||||||
api.init(app);
|
api.init(app,{
|
||||||
});
|
settings:{disableEditor:true},
|
||||||
after(function() {
|
api:{
|
||||||
settings.reset();
|
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not serve the editor', function(done) {
|
it('does not serve the editor', function(done) {
|
||||||
@ -54,14 +55,25 @@ describe("api index", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("can serve auth", function() {
|
describe("can serve auth", function() {
|
||||||
|
var mockList = [
|
||||||
|
'ui','nodes','flows','library','info','theme','locales','credentials'
|
||||||
|
]
|
||||||
before(function() {
|
before(function() {
|
||||||
//settings.init({disableEditor:true});
|
mockList.forEach(function(m) {
|
||||||
settings.init({adminAuth:{type: "credentials",users:[],default:{permissions:"read"}}});
|
sinon.stub(require("../../../red/api/"+m),"init",function(){});
|
||||||
app = express();
|
});
|
||||||
api.init(app,{getSessions:function(){return when.resolve({})}});
|
|
||||||
});
|
});
|
||||||
after(function() {
|
after(function() {
|
||||||
settings.reset();
|
mockList.forEach(function(m) {
|
||||||
|
require("../../../red/api/"+m).init.restore();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
before(function() {
|
||||||
|
app = express();
|
||||||
|
api.init(app,{
|
||||||
|
settings:{adminAuth:{type: "credentials",users:[],default:{permissions:"read"}}},
|
||||||
|
storage:{getSessions:function(){return when.resolve({})}}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it now serves auth', function(done) {
|
it('it now serves auth', function(done) {
|
||||||
@ -77,15 +89,29 @@ describe("api index", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("enables editor", function() {
|
describe("enables editor", function() {
|
||||||
|
|
||||||
|
var mockList = [
|
||||||
|
'nodes','flows','library','info','theme','locales','credentials'
|
||||||
|
]
|
||||||
before(function() {
|
before(function() {
|
||||||
settings.init({disableEditor:false});
|
mockList.forEach(function(m) {
|
||||||
app = express();
|
sinon.stub(require("../../../red/api/"+m),"init",function(){});
|
||||||
api.init(app);
|
});
|
||||||
});
|
});
|
||||||
after(function() {
|
after(function() {
|
||||||
settings.reset();
|
mockList.forEach(function(m) {
|
||||||
|
require("../../../red/api/"+m).init.restore();
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
app = express();
|
||||||
|
api.init(app,{
|
||||||
|
log:{audit:function(){}},
|
||||||
|
settings:{disableEditor:false},
|
||||||
|
events:{on:function(){},removeListener:function(){}}
|
||||||
|
});
|
||||||
|
});
|
||||||
it('serves the editor', function(done) {
|
it('serves the editor', function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get("/")
|
.get("/")
|
||||||
|
@ -21,30 +21,26 @@ var sinon = require('sinon');
|
|||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
var settings = require("../../../red/settings");
|
|
||||||
var info = require("../../../red/api/info");
|
var info = require("../../../red/api/info");
|
||||||
|
|
||||||
var theme = require("../../../red/api/theme");
|
var theme = require("../../../red/api/theme");
|
||||||
|
|
||||||
describe("info api", function() {
|
describe("info api", function() {
|
||||||
describe("settings handler", function() {
|
describe("settings handler", function() {
|
||||||
before(function() {
|
before(function() {
|
||||||
var userSettings = {
|
|
||||||
foo: 123,
|
|
||||||
httpNodeRoot: "testHttpNodeRoot",
|
|
||||||
version: "testVersion",
|
|
||||||
paletteCategories :["red","blue","green"]
|
|
||||||
}
|
|
||||||
settings.init(userSettings);
|
|
||||||
|
|
||||||
sinon.stub(theme,"settings",function() { return { test: 456 };});
|
sinon.stub(theme,"settings",function() { return { test: 456 };});
|
||||||
|
info.init({
|
||||||
|
settings: {
|
||||||
|
foo: 123,
|
||||||
|
httpNodeRoot: "testHttpNodeRoot",
|
||||||
|
version: "testVersion",
|
||||||
|
paletteCategories :["red","blue","green"]
|
||||||
|
}
|
||||||
|
})
|
||||||
app = express();
|
app = express();
|
||||||
app.get("/settings",info.settings);
|
app.get("/settings",info.settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function() {
|
||||||
settings.reset();
|
|
||||||
theme.settings.restore();
|
theme.settings.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,19 +21,18 @@ var bodyParser = require('body-parser');
|
|||||||
|
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
var app = express();
|
var app;
|
||||||
var RED = require("../../../red/red.js");
|
|
||||||
var storage = require("../../../red/storage");
|
|
||||||
var library = require("../../../red/api/library");
|
var library = require("../../../red/api/library");
|
||||||
var auth = require("../../../red/api/auth");
|
var auth = require("../../../red/api/auth");
|
||||||
|
|
||||||
describe("library api", function() {
|
describe("library api", function() {
|
||||||
|
|
||||||
function initStorage(_flows,_libraryEntries) {
|
function initLibrary(_flows,_libraryEntries) {
|
||||||
var flows = _flows;
|
var flows = _flows;
|
||||||
var libraryEntries = _libraryEntries;
|
var libraryEntries = _libraryEntries;
|
||||||
storage.init({
|
library.init(app,{
|
||||||
storageModule: {
|
log:{audit:function(){},_:function(){},warn:function(){}},
|
||||||
|
storage: {
|
||||||
init: function() {
|
init: function() {
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
},
|
},
|
||||||
@ -43,15 +42,29 @@ describe("library api", function() {
|
|||||||
getFlow: function(fn) {
|
getFlow: function(fn) {
|
||||||
if (flows[fn]) {
|
if (flows[fn]) {
|
||||||
return when.resolve(flows[fn]);
|
return when.resolve(flows[fn]);
|
||||||
|
} else if (fn.indexOf("..")!==-1) {
|
||||||
|
var err = new Error();
|
||||||
|
err.code = 'forbidden';
|
||||||
|
return when.reject(err);
|
||||||
} else {
|
} else {
|
||||||
return when.reject();
|
return when.reject();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
saveFlow: function(fn,data) {
|
saveFlow: function(fn,data) {
|
||||||
|
if (fn.indexOf("..")!==-1) {
|
||||||
|
var err = new Error();
|
||||||
|
err.code = 'forbidden';
|
||||||
|
return when.reject(err);
|
||||||
|
}
|
||||||
flows[fn] = data;
|
flows[fn] = data;
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
},
|
},
|
||||||
getLibraryEntry: function(type,path) {
|
getLibraryEntry: function(type,path) {
|
||||||
|
if (path.indexOf("..")!==-1) {
|
||||||
|
var err = new Error();
|
||||||
|
err.code = 'forbidden';
|
||||||
|
return when.reject(err);
|
||||||
|
}
|
||||||
if (libraryEntries[type] && libraryEntries[type][path]) {
|
if (libraryEntries[type] && libraryEntries[type][path]) {
|
||||||
return when.resolve(libraryEntries[type][path]);
|
return when.resolve(libraryEntries[type][path]);
|
||||||
} else {
|
} else {
|
||||||
@ -59,6 +72,11 @@ describe("library api", function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
saveLibraryEntry: function(type,path,meta,body) {
|
saveLibraryEntry: function(type,path,meta,body) {
|
||||||
|
if (path.indexOf("..")!==-1) {
|
||||||
|
var err = new Error();
|
||||||
|
err.code = 'forbidden';
|
||||||
|
return when.reject(err);
|
||||||
|
}
|
||||||
libraryEntries[type][path] = body;
|
libraryEntries[type][path] = body;
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
}
|
}
|
||||||
@ -67,8 +85,6 @@ describe("library api", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("flows", function() {
|
describe("flows", function() {
|
||||||
var app;
|
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
app = express();
|
app = express();
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
@ -77,7 +93,7 @@ describe("library api", function() {
|
|||||||
app.get(new RegExp("/library/flows\/(.*)"),library.get);
|
app.get(new RegExp("/library/flows\/(.*)"),library.get);
|
||||||
});
|
});
|
||||||
it('returns empty result', function(done) {
|
it('returns empty result', function(done) {
|
||||||
initStorage({},{flows:{}});
|
initLibrary({},{flows:{}});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/flows')
|
.get('/library/flows')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
@ -92,7 +108,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for non-existent entry', function(done) {
|
it('returns 404 for non-existent entry', function(done) {
|
||||||
initStorage({},{flows:{}});
|
initLibrary({},{flows:{}});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/flows/foo')
|
.get('/library/flows/foo')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
@ -101,7 +117,7 @@ describe("library api", function() {
|
|||||||
|
|
||||||
|
|
||||||
it('can store and retrieve item', function(done) {
|
it('can store and retrieve item', function(done) {
|
||||||
initStorage({},{flows:{}});
|
initLibrary({},{flows:{}});
|
||||||
var flow = '[]';
|
var flow = '[]';
|
||||||
request(app)
|
request(app)
|
||||||
.post('/library/flows/foo')
|
.post('/library/flows/foo')
|
||||||
@ -125,7 +141,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('lists a stored item', function(done) {
|
it('lists a stored item', function(done) {
|
||||||
initStorage({f:["bar"]});
|
initLibrary({f:["bar"]});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/flows')
|
.get('/library/flows')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
@ -140,7 +156,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 403 for malicious get attempt', function(done) {
|
it('returns 403 for malicious get attempt', function(done) {
|
||||||
initStorage({});
|
initLibrary({});
|
||||||
// without the userDir override the malicious url would be
|
// without the userDir override the malicious url would be
|
||||||
// http://127.0.0.1:1880/library/flows/../../package to
|
// http://127.0.0.1:1880/library/flows/../../package to
|
||||||
// obtain package.json from the node-red root.
|
// obtain package.json from the node-red root.
|
||||||
@ -150,7 +166,7 @@ describe("library api", function() {
|
|||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
it('returns 403 for malicious post attempt', function(done) {
|
it('returns 403 for malicious post attempt', function(done) {
|
||||||
initStorage({});
|
initLibrary({});
|
||||||
// without the userDir override the malicious url would be
|
// without the userDir override the malicious url would be
|
||||||
// http://127.0.0.1:1880/library/flows/../../package to
|
// http://127.0.0.1:1880/library/flows/../../package to
|
||||||
// obtain package.json from the node-red root.
|
// obtain package.json from the node-red root.
|
||||||
@ -162,18 +178,17 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("type", function() {
|
describe("type", function() {
|
||||||
var app;
|
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
|
|
||||||
app = express();
|
app = express();
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
library.init(app);
|
initLibrary({},{});
|
||||||
auth.init({});
|
auth.init({settings:{}});
|
||||||
RED.library.register("test");
|
library.register("test");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns empty result', function(done) {
|
it('returns empty result', function(done) {
|
||||||
initStorage({},{'test':{"":[]}});
|
initLibrary({},{'test':{"":[]}});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/test')
|
.get('/library/test')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
@ -187,7 +202,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for non-existent entry', function(done) {
|
it('returns 404 for non-existent entry', function(done) {
|
||||||
initStorage({},{});
|
initLibrary({},{});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/test/foo')
|
.get('/library/test/foo')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
@ -195,7 +210,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can store and retrieve item', function(done) {
|
it('can store and retrieve item', function(done) {
|
||||||
initStorage({},{'test':{}});
|
initLibrary({},{'test':{}});
|
||||||
var flow = {text:"test content"};
|
var flow = {text:"test content"};
|
||||||
request(app)
|
request(app)
|
||||||
.post('/library/test/foo')
|
.post('/library/test/foo')
|
||||||
@ -219,7 +234,7 @@ describe("library api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('lists a stored item', function(done) {
|
it('lists a stored item', function(done) {
|
||||||
initStorage({},{'test':{'a':['abc','def']}});
|
initLibrary({},{'test':{'a':['abc','def']}});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/library/test/a')
|
.get('/library/test/a')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2015 IBM Corp.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
describe("locales api", function() {
|
||||||
|
it.skip("works",function(){});
|
||||||
|
});
|
@ -21,7 +21,6 @@ var bodyParser = require('body-parser');
|
|||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
|
|
||||||
var redNodes = require("../../../red/nodes");
|
|
||||||
var settings = require("../../../red/settings");
|
var settings = require("../../../red/settings");
|
||||||
|
|
||||||
var nodes = require("../../../red/api/nodes");
|
var nodes = require("../../../red/api/nodes");
|
||||||
@ -29,6 +28,16 @@ var nodes = require("../../../red/api/nodes");
|
|||||||
describe("nodes api", function() {
|
describe("nodes api", function() {
|
||||||
|
|
||||||
var app;
|
var app;
|
||||||
|
function initNodes(runtime) {
|
||||||
|
runtime.log = {
|
||||||
|
audit:function(e){},//console.log(e)},
|
||||||
|
_:function(){},
|
||||||
|
info: function(){},
|
||||||
|
warn: function(){}
|
||||||
|
}
|
||||||
|
runtime.comms = { publish:function(){}}
|
||||||
|
nodes.init(runtime);
|
||||||
|
}
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
app = express();
|
app = express();
|
||||||
@ -44,15 +53,18 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('get nodes', function() {
|
describe('get nodes', function() {
|
||||||
it('returns node list', function(done) {
|
it('returns node list', function(done) {
|
||||||
var getNodeList = sinon.stub(redNodes,'getNodeList', function() {
|
initNodes({
|
||||||
return [1,2,3];
|
api:{
|
||||||
|
getNodeList: function() {
|
||||||
|
return [1,2,3];
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes')
|
.get('/nodes')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeList.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -62,8 +74,15 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns node configs', function(done) {
|
it('returns node configs', function(done) {
|
||||||
var getNodeConfigs = sinon.stub(redNodes,'getNodeConfigs', function() {
|
initNodes({
|
||||||
return "<script></script>";
|
api:{
|
||||||
|
getNodeConfigs: function() {
|
||||||
|
return "<script></script>";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
determineLangFromHeaders: function(){}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes')
|
.get('/nodes')
|
||||||
@ -71,7 +90,6 @@ describe("nodes api", function() {
|
|||||||
.expect(200)
|
.expect(200)
|
||||||
.expect("<script></script>")
|
.expect("<script></script>")
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeConfigs.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -80,14 +98,17 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns node module info', function(done) {
|
it('returns node module info', function(done) {
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getModuleInfo', function(id) {
|
initNodes({
|
||||||
return {"node-red":{name:"node-red"}}[id];
|
api:{
|
||||||
|
getModuleInfo: function(id) {
|
||||||
|
return {"node-red":{name:"node-red"}}[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes/node-red')
|
.get('/nodes/node-red')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -97,14 +118,17 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for unknown module', function(done) {
|
it('returns 404 for unknown module', function(done) {
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getModuleInfo', function(id) {
|
initNodes({
|
||||||
return {"node-red":{name:"node-red"}}[id];
|
api:{
|
||||||
|
getModuleInfo: function(id) {
|
||||||
|
return {"node-red":{name:"node-red"}}[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes/node-blue')
|
.get('/nodes/node-blue')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -113,15 +137,18 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns individual node info', function(done) {
|
it('returns individual node info', function(done) {
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
|
initNodes({
|
||||||
return {"node-red/123":{id:"node-red/123"}}[id];
|
api:{
|
||||||
|
getNodeInfo: function(id) {
|
||||||
|
return {"node-red/123":{id:"node-red/123"}}[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes/node-red/123')
|
.get('/nodes/node-red/123')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -131,8 +158,15 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns individual node configs', function(done) {
|
it('returns individual node configs', function(done) {
|
||||||
var getNodeConfig = sinon.stub(redNodes,'getNodeConfig', function(id) {
|
initNodes({
|
||||||
return {"node-red/123":"<script></script>"}[id];
|
api:{
|
||||||
|
getNodeConfig: function(id) {
|
||||||
|
return {"node-red/123":"<script></script>"}[id];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
determineLangFromHeaders: function(){}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes/node-red/123')
|
.get('/nodes/node-red/123')
|
||||||
@ -140,7 +174,6 @@ describe("nodes api", function() {
|
|||||||
.expect(200)
|
.expect(200)
|
||||||
.expect("<script></script>")
|
.expect("<script></script>")
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeConfig.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -149,15 +182,18 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for unknown node', function(done) {
|
it('returns 404 for unknown node', function(done) {
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
|
initNodes({
|
||||||
return {"node-red/123":{id:"node-red/123"}}[id];
|
api:{
|
||||||
|
getNodeInfo: function(id) {
|
||||||
|
return {"node-red/123":{id:"node-red/123"}}[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.get('/nodes/node-red/456')
|
.get('/nodes/node-red/456')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
getNodeInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -169,14 +205,13 @@ describe("nodes api", function() {
|
|||||||
describe('install', function() {
|
describe('install', function() {
|
||||||
|
|
||||||
it('returns 400 if settings are unavailable', function(done) {
|
it('returns 400 if settings are unavailable', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return false;
|
settings:{available:function(){return false}}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -185,15 +220,14 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 400 if request is invalid', function(done) {
|
it('returns 400 if request is invalid', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({})
|
.send({})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -203,26 +237,23 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('by module', function() {
|
describe('by module', function() {
|
||||||
it('installs the module and returns module info', function(done) {
|
it('installs the module and returns module info', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return null; },
|
||||||
|
installModule: function() {
|
||||||
|
return when.resolve({
|
||||||
|
name:"foo",
|
||||||
|
nodes:[{id:"123"}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo');
|
|
||||||
getModuleInfo.onCall(0).returns(null);
|
|
||||||
var installModule = sinon.stub(redNodes,'installModule', function() {
|
|
||||||
return when.resolve({
|
|
||||||
name:"foo",
|
|
||||||
nodes:[{id:"123"}]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo'})
|
.send({module: 'foo'})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
installModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -234,24 +265,20 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails the install if already installed', function(done) {
|
it('fails the install if already installed', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return {nodes:{id:"123"}}; },
|
||||||
|
installModule: function() {
|
||||||
|
return when.resolve({id:"123"});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return {nodes:{id:"123"}};
|
|
||||||
});
|
|
||||||
var installModule = sinon.stub(redNodes,'installModule', function() {
|
|
||||||
return when.resolve({id:"123"});
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo'})
|
.send({module: 'foo'})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
installModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -260,24 +287,20 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails the install if module error', function(done) {
|
it('fails the install if module error', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return null },
|
||||||
|
installModule: function() {
|
||||||
|
return when.reject(new Error("test error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
var installModule = sinon.stub(redNodes,'installModule', function() {
|
|
||||||
return when.reject(new Error("test error"));
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo'})
|
.send({module: 'foo'})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
installModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -286,26 +309,22 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('fails the install if module not found', function(done) {
|
it('fails the install if module not found', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return null },
|
||||||
|
installModule: function() {
|
||||||
|
var err = new Error("test error");
|
||||||
|
err.code = 404;
|
||||||
|
return when.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
var installModule = sinon.stub(redNodes,'installModule', function() {
|
|
||||||
var err = new Error("test error");
|
|
||||||
err.code = 404;
|
|
||||||
return when.reject(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo'})
|
.send({module: 'foo'})
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
installModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -319,6 +338,10 @@ describe("nodes api", function() {
|
|||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var settingsAvailable = sinon.stub(settings,'available', function() {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
initNodes({
|
||||||
|
settings:{available:function(){return false}}
|
||||||
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.del('/nodes/123')
|
.del('/nodes/123')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
@ -333,27 +356,18 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('by module', function() {
|
describe('by module', function() {
|
||||||
it('uninstalls the module', function(done) {
|
it('uninstalls the module', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return {nodes:[{id:"123"}]} },
|
||||||
|
getNodeInfo: function() { return null },
|
||||||
|
uninstallModule: function() { return when.resolve({id:"123"});}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return {nodes:[{id:"123"}]};
|
|
||||||
});
|
|
||||||
var uninstallModule = sinon.stub(redNodes,'uninstallModule', function() {
|
|
||||||
return when.resolve({id:"123"});
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.del('/nodes/foo')
|
.del('/nodes/foo')
|
||||||
.expect(204)
|
.expect(204)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
uninstallModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -362,23 +376,17 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails the uninstall if the module is not installed', function(done) {
|
it('fails the uninstall if the module is not installed', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return null },
|
||||||
|
getNodeInfo: function() { return null }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.del('/nodes/foo')
|
.del('/nodes/foo')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -387,27 +395,18 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails the uninstall if the module is not installed', function(done) {
|
it('fails the uninstall if the module is not installed', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function(id) { return {nodes:[{id:"123"}]} },
|
||||||
|
getNodeInfo: function() { return null },
|
||||||
|
uninstallModule: function() { return when.reject(new Error("test error"));}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return {nodes:[{id:"123"}]};
|
|
||||||
});
|
|
||||||
var uninstallModule = sinon.stub(redNodes,'uninstallModule', function() {
|
|
||||||
return when.reject(new Error("test error"));
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.del('/nodes/foo')
|
.del('/nodes/foo')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
uninstallModule.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -421,14 +420,13 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('enable/disable', function() {
|
describe('enable/disable', function() {
|
||||||
it('returns 400 if settings are unavailable', function(done) {
|
it('returns 400 if settings are unavailable', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return false;
|
settings:{available:function(){return false}}
|
||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/123')
|
.put('/nodes/123')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -437,16 +435,14 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 400 for invalid node payload', function(done) {
|
it('returns 400 for invalid node payload', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red/foo')
|
.put('/nodes/node-red/foo')
|
||||||
.send({})
|
.send({})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -456,16 +452,14 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 400 for invalid module payload', function(done) {
|
it('returns 400 for invalid module payload', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/foo')
|
.put('/nodes/foo')
|
||||||
.send({})
|
.send({})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -476,11 +470,11 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for unknown node', function(done) {
|
it('returns 404 for unknown node', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
});
|
api:{
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
getNodeInfo: function() { return null }
|
||||||
return null;
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
@ -488,8 +482,6 @@ describe("nodes api", function() {
|
|||||||
.send({enabled:false})
|
.send({enabled:false})
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -498,11 +490,11 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns 404 for unknown module', function(done) {
|
it('returns 404 for unknown module', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
});
|
api:{
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
getModuleInfo: function(id) { return null }
|
||||||
return null;
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
@ -510,8 +502,6 @@ describe("nodes api", function() {
|
|||||||
.send({enabled:false})
|
.send({enabled:false})
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -520,24 +510,18 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('enables disabled node', function(done) {
|
it('enables disabled node', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getNodeInfo: function() { return {id:"123",enabled: false} },
|
||||||
|
enableNode: function() { return when.resolve({id:"123",enabled: true,types:['a']}); }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return {id:"123",enabled: false};
|
|
||||||
});
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
|
|
||||||
return when.resolve({id:"123",enabled: true,types:['a']});
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red/foo')
|
.put('/nodes/node-red/foo')
|
||||||
.send({enabled:true})
|
.send({enabled:true})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
enableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -549,24 +533,18 @@ describe("nodes api", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('disables enabled node', function(done) {
|
it('disables enabled node', function(done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
initNodes({
|
||||||
return true;
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getNodeInfo: function() { return {id:"123",enabled: true} },
|
||||||
|
disableNode: function() { return when.resolve({id:"123",enabled: false,types:['a']}); }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return {id:"123",enabled: true};
|
|
||||||
});
|
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
|
|
||||||
return when.resolve({id:"123",enabled: false,types:['a']});
|
|
||||||
});
|
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red/foo')
|
.put('/nodes/node-red/foo')
|
||||||
.send({enabled:false})
|
.send({enabled:false})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -579,31 +557,24 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('no-ops if already in the right state', function() {
|
describe('no-ops if already in the right state', function() {
|
||||||
function run(state,done) {
|
function run(state,done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) });
|
||||||
return true;
|
var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) });
|
||||||
});
|
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return {id:"123",enabled: state};
|
|
||||||
});
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
|
|
||||||
return when.resolve({id:"123",enabled: true,types:['a']});
|
|
||||||
});
|
|
||||||
|
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
|
initNodes({
|
||||||
return when.resolve({id:"123",enabled: false,types:['a']});
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getNodeInfo: function() { return {id:"123",enabled: state} },
|
||||||
|
enableNode: enableNode,
|
||||||
|
disableNode: disableNode
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red/foo')
|
.put('/nodes/node-red/foo')
|
||||||
.send({enabled:state})
|
.send({enabled:state})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
var enableNodeCalled = enableNode.called;
|
var enableNodeCalled = enableNode.called;
|
||||||
var disableNodeCalled = disableNode.called;
|
var disableNodeCalled = disableNode.called;
|
||||||
enableNode.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -625,31 +596,24 @@ describe("nodes api", function() {
|
|||||||
|
|
||||||
describe('does not no-op if err on node', function() {
|
describe('does not no-op if err on node', function() {
|
||||||
function run(state,done) {
|
function run(state,done) {
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) });
|
||||||
return true;
|
var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) });
|
||||||
});
|
|
||||||
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
|
|
||||||
return {id:"123",enabled: state, err:"foo" };
|
|
||||||
});
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
|
|
||||||
return when.resolve({id:"123",enabled: true,types:['a']});
|
|
||||||
});
|
|
||||||
|
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
|
initNodes({
|
||||||
return when.resolve({id:"123",enabled: false,types:['a']});
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getNodeInfo: function() { return {id:"123",enabled: state, err:"foo"} },
|
||||||
|
enableNode: enableNode,
|
||||||
|
disableNode: disableNode
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red/foo')
|
.put('/nodes/node-red/foo')
|
||||||
.send({enabled:state})
|
.send({enabled:state})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getNodeInfo.restore();
|
|
||||||
var enableNodeCalled = enableNode.called;
|
var enableNodeCalled = enableNode.called;
|
||||||
var disableNodeCalled = disableNode.called;
|
var disableNodeCalled = disableNode.called;
|
||||||
enableNode.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -672,14 +636,7 @@ describe("nodes api", function() {
|
|||||||
it('enables disabled module', function(done) {
|
it('enables disabled module', function(done) {
|
||||||
var n1 = {id:"123",enabled:false,types:['a']};
|
var n1 = {id:"123",enabled:false,types:['a']};
|
||||||
var n2 = {id:"456",enabled:false,types:['b']};
|
var n2 = {id:"456",enabled:false,types:['b']};
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var enableNode = sinon.stub();
|
||||||
return true;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(name) {
|
|
||||||
return {name:"node-red", nodes:[n1, n2]};
|
|
||||||
});
|
|
||||||
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode');
|
|
||||||
enableNode.onFirstCall().returns((function() {
|
enableNode.onFirstCall().returns((function() {
|
||||||
n1.enabled = true;
|
n1.enabled = true;
|
||||||
return when.resolve(n1);
|
return when.resolve(n1);
|
||||||
@ -689,15 +646,19 @@ describe("nodes api", function() {
|
|||||||
return when.resolve(n2);
|
return when.resolve(n2);
|
||||||
})());
|
})());
|
||||||
enableNode.returns(null);
|
enableNode.returns(null);
|
||||||
|
initNodes({
|
||||||
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} },
|
||||||
|
enableNode: enableNode
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red')
|
.put('/nodes/node-red')
|
||||||
.send({enabled:true})
|
.send({enabled:true})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
enableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -713,14 +674,7 @@ describe("nodes api", function() {
|
|||||||
it('disables enabled module', function(done) {
|
it('disables enabled module', function(done) {
|
||||||
var n1 = {id:"123",enabled:true,types:['a']};
|
var n1 = {id:"123",enabled:true,types:['a']};
|
||||||
var n2 = {id:"456",enabled:true,types:['b']};
|
var n2 = {id:"456",enabled:true,types:['b']};
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var disableNode = sinon.stub();
|
||||||
return true;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(name) {
|
|
||||||
return {name:"node-red", nodes:[n1, n2]};
|
|
||||||
});
|
|
||||||
|
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode');
|
|
||||||
disableNode.onFirstCall().returns((function() {
|
disableNode.onFirstCall().returns((function() {
|
||||||
n1.enabled = false;
|
n1.enabled = false;
|
||||||
return when.resolve(n1);
|
return when.resolve(n1);
|
||||||
@ -730,15 +684,19 @@ describe("nodes api", function() {
|
|||||||
return when.resolve(n2);
|
return when.resolve(n2);
|
||||||
})());
|
})());
|
||||||
disableNode.returns(null);
|
disableNode.returns(null);
|
||||||
|
initNodes({
|
||||||
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} },
|
||||||
|
disableNode: disableNode
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red')
|
.put('/nodes/node-red')
|
||||||
.send({enabled:false})
|
.send({enabled:false})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -754,32 +712,30 @@ describe("nodes api", function() {
|
|||||||
describe('no-ops if a node in module already in the right state', function() {
|
describe('no-ops if a node in module already in the right state', function() {
|
||||||
function run(state,done) {
|
function run(state,done) {
|
||||||
var node = {id:"123",enabled:state,types:['a']};
|
var node = {id:"123",enabled:state,types:['a']};
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var enableNode = sinon.spy(function(id) {
|
||||||
return true;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return {name:"node-red", nodes:[node]};
|
|
||||||
});
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
|
|
||||||
node.enabled = true;
|
node.enabled = true;
|
||||||
return when.resolve(node);
|
return when.resolve(node);
|
||||||
});
|
});
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
|
var disableNode = sinon.spy(function(id) {
|
||||||
node.enabled = false;
|
node.enabled = false;
|
||||||
return when.resolve(node);
|
return when.resolve(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
initNodes({
|
||||||
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function() { return {name:"node-red", nodes:[node]}; },
|
||||||
|
enableNode: enableNode,
|
||||||
|
disableNode: disableNode
|
||||||
|
}
|
||||||
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red')
|
.put('/nodes/node-red')
|
||||||
.send({enabled:state})
|
.send({enabled:state})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
var enableNodeCalled = enableNode.called;
|
var enableNodeCalled = enableNode.called;
|
||||||
var disableNodeCalled = disableNode.called;
|
var disableNodeCalled = disableNode.called;
|
||||||
enableNode.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -803,32 +759,31 @@ describe("nodes api", function() {
|
|||||||
describe('does not no-op if err on a node in module', function() {
|
describe('does not no-op if err on a node in module', function() {
|
||||||
function run(state,done) {
|
function run(state,done) {
|
||||||
var node = {id:"123",enabled:state,types:['a'],err:"foo"};
|
var node = {id:"123",enabled:state,types:['a'],err:"foo"};
|
||||||
var settingsAvailable = sinon.stub(settings,'available', function() {
|
var enableNode = sinon.spy(function(id) {
|
||||||
return true;
|
|
||||||
});
|
|
||||||
var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
|
|
||||||
return {name:"node-red", nodes:[node]};
|
|
||||||
});
|
|
||||||
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
|
|
||||||
node.enabled = true;
|
node.enabled = true;
|
||||||
return when.resolve(node);
|
return when.resolve(node);
|
||||||
});
|
});
|
||||||
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
|
var disableNode = sinon.spy(function(id) {
|
||||||
node.enabled = false;
|
node.enabled = false;
|
||||||
return when.resolve(node);
|
return when.resolve(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
initNodes({
|
||||||
|
settings:{available:function(){return true}},
|
||||||
|
api:{
|
||||||
|
getModuleInfo: function() { return {name:"node-red", nodes:[node]}; },
|
||||||
|
enableNode: enableNode,
|
||||||
|
disableNode: disableNode
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
request(app)
|
request(app)
|
||||||
.put('/nodes/node-red')
|
.put('/nodes/node-red')
|
||||||
.send({enabled:state})
|
.send({enabled:state})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
settingsAvailable.restore();
|
|
||||||
getModuleInfo.restore();
|
|
||||||
var enableNodeCalled = enableNode.called;
|
var enableNodeCalled = enableNode.called;
|
||||||
var disableNodeCalled = disableNode.called;
|
var disableNodeCalled = disableNode.called;
|
||||||
enableNode.restore();
|
|
||||||
disableNode.restore();
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,13 @@ describe("theme handler", function() {
|
|||||||
sinon.stub(fs,"statSync",function() { return true; });
|
sinon.stub(fs,"statSync",function() { return true; });
|
||||||
});
|
});
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
theme.init({});
|
theme.init({settings:{}});
|
||||||
fs.statSync.restore();
|
fs.statSync.restore();
|
||||||
});
|
});
|
||||||
it("applies the default theme", function() {
|
it("applies the default theme", function() {
|
||||||
var result = theme.init({});
|
var result = theme.init({settings:{}});
|
||||||
should.not.exist(result);
|
should.not.exist(result);
|
||||||
|
|
||||||
var context = theme.context();
|
var context = theme.context();
|
||||||
context.should.have.a.property("page");
|
context.should.have.a.property("page");
|
||||||
context.page.should.have.a.property("title","Node-RED");
|
context.page.should.have.a.property("title","Node-RED");
|
||||||
@ -45,12 +45,12 @@ describe("theme handler", function() {
|
|||||||
context.should.have.a.property("header");
|
context.should.have.a.property("header");
|
||||||
context.header.should.have.a.property("title","Node-RED");
|
context.header.should.have.a.property("title","Node-RED");
|
||||||
context.header.should.have.a.property("image","red/images/node-red.png");
|
context.header.should.have.a.property("image","red/images/node-red.png");
|
||||||
|
|
||||||
should.not.exist(theme.settings());
|
should.not.exist(theme.settings());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("picks up custom theme", function() {
|
it("picks up custom theme", function() {
|
||||||
var result = theme.init({
|
var result = theme.init({settings:{
|
||||||
editorTheme: {
|
editorTheme: {
|
||||||
page: {
|
page: {
|
||||||
title: "Test Page Title",
|
title: "Test Page Title",
|
||||||
@ -61,13 +61,13 @@ describe("theme handler", function() {
|
|||||||
title: "Test Header Title",
|
title: "Test Header Title",
|
||||||
image: "/absolute/path/to/header/image" // or null to remove image
|
image: "/absolute/path/to/header/image" // or null to remove image
|
||||||
},
|
},
|
||||||
|
|
||||||
deployButton: {
|
deployButton: {
|
||||||
type:"simple",
|
type:"simple",
|
||||||
label:"Save",
|
label:"Save",
|
||||||
icon: "/absolute/path/to/deploy/button/image" // or null to remove image
|
icon: "/absolute/path/to/deploy/button/image" // or null to remove image
|
||||||
},
|
},
|
||||||
|
|
||||||
menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list
|
menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list
|
||||||
"menu-item-import-library": false,
|
"menu-item-import-library": false,
|
||||||
"menu-item-export-library": false,
|
"menu-item-export-library": false,
|
||||||
@ -77,27 +77,27 @@ describe("theme handler", function() {
|
|||||||
url: "http://example.com"
|
url: "http://example.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
userMenu: false, // Hide the user-menu even if adminAuth is enabled
|
userMenu: false, // Hide the user-menu even if adminAuth is enabled
|
||||||
|
|
||||||
login: {
|
login: {
|
||||||
image: "/absolute/path/to/login/page/big/image" // a 256x256 image
|
image: "/absolute/path/to/login/page/big/image" // a 256x256 image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}});
|
||||||
should.exist(result);
|
should.exist(result);
|
||||||
|
|
||||||
var context = theme.context();
|
var context = theme.context();
|
||||||
context.should.have.a.property("page");
|
context.should.have.a.property("page");
|
||||||
context.page.should.have.a.property("title","Test Page Title");
|
context.page.should.have.a.property("title","Test Page Title");
|
||||||
context.should.have.a.property("header");
|
context.should.have.a.property("header");
|
||||||
context.header.should.have.a.property("title","Test Header Title");
|
context.header.should.have.a.property("title","Test Header Title");
|
||||||
|
|
||||||
var settings = theme.settings();
|
var settings = theme.settings();
|
||||||
settings.should.have.a.property("deployButton");
|
settings.should.have.a.property("deployButton");
|
||||||
settings.should.have.a.property("userMenu");
|
settings.should.have.a.property("userMenu");
|
||||||
settings.should.have.a.property("menu");
|
settings.should.have.a.property("menu");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -20,14 +20,17 @@ var express = require("express");
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
|
||||||
var events = require("../../../red/events");
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
var events = new EventEmitter();
|
||||||
var ui = require("../../../red/api/ui");
|
var ui = require("../../../red/api/ui");
|
||||||
|
|
||||||
|
|
||||||
describe("ui api", function() {
|
describe("ui api", function() {
|
||||||
var app;
|
var app;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
ui.init({events:events});
|
||||||
|
});
|
||||||
describe("slash handler", function() {
|
describe("slash handler", function() {
|
||||||
before(function() {
|
before(function() {
|
||||||
app = express();
|
app = express();
|
||||||
|
@ -959,7 +959,7 @@ describe('Flow', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("moves any existing error object sideways",function(){
|
it("moves any existing error object sideways",function(done){
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
{id:"t1",type:"tab"},
|
{id:"t1",type:"tab"},
|
||||||
{id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]},
|
{id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]},
|
||||||
|
@ -145,7 +145,7 @@ describe("red/nodes/index", function() {
|
|||||||
var registry = require("../../../red/nodes/registry");
|
var registry = require("../../../red/nodes/registry");
|
||||||
var randomNodeInfo = {id:"5678",types:["random"]};
|
var randomNodeInfo = {id:"5678",types:["random"]};
|
||||||
|
|
||||||
before(function() {
|
beforeEach(function() {
|
||||||
sinon.stub(registry,"getNodeInfo",function(id) {
|
sinon.stub(registry,"getNodeInfo",function(id) {
|
||||||
if (id == "test") {
|
if (id == "test") {
|
||||||
return {id:"1234",types:["test"]};
|
return {id:"1234",types:["test"]};
|
||||||
@ -159,7 +159,7 @@ describe("red/nodes/index", function() {
|
|||||||
return randomNodeInfo;
|
return randomNodeInfo;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
after(function() {
|
afterEach(function() {
|
||||||
registry.getNodeInfo.restore();
|
registry.getNodeInfo.restore();
|
||||||
registry.disableNode.restore();
|
registry.disableNode.restore();
|
||||||
});
|
});
|
||||||
|
@ -20,18 +20,23 @@ var sinon = require("sinon");
|
|||||||
var comms = require("../../red/comms");
|
var comms = require("../../red/comms");
|
||||||
var redNodes = require("../../red/nodes");
|
var redNodes = require("../../red/nodes");
|
||||||
var api = require("../../red/api");
|
var api = require("../../red/api");
|
||||||
var server = require("../../red/server");
|
var runtime = require("../../red/runtime");
|
||||||
var storage = require("../../red/storage");
|
var storage = require("../../red/storage");
|
||||||
var settings = require("../../red/settings");
|
var settings = require("../../red/settings");
|
||||||
var log = require("../../red/log");
|
var log = require("../../red/log");
|
||||||
|
|
||||||
describe("red/server", function() {
|
describe("red/runtime", function() {
|
||||||
var commsMessages = [];
|
var commsMessages = [];
|
||||||
var commsPublish;
|
var commsPublish;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
commsMessages = [];
|
commsMessages = [];
|
||||||
});
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
if (console.log.restore) {
|
||||||
|
console.log.restore();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
commsPublish = sinon.stub(comms,"publish", function(topic,msg,retained) {
|
commsPublish = sinon.stub(comms,"publish", function(topic,msg,retained) {
|
||||||
@ -42,26 +47,48 @@ describe("red/server", function() {
|
|||||||
commsPublish.restore();
|
commsPublish.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("initialises components", function() {
|
describe("init", function() {
|
||||||
var commsInit = sinon.stub(comms,"init",function() {});
|
var commsInit;
|
||||||
var dummyServer = {};
|
var apiInit;
|
||||||
server.init(dummyServer,{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
beforeEach(function() {
|
||||||
|
commsInit = sinon.stub(comms,"init",function() {});
|
||||||
|
apiInit = sinon.stub(api,"init",function() {});
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
commsInit.restore();
|
||||||
|
apiInit.restore();
|
||||||
|
})
|
||||||
|
|
||||||
commsInit.called.should.be.true;
|
it("initialises components", function() {
|
||||||
|
var dummyServer = {};
|
||||||
|
runtime.init(dummyServer,{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
|
commsInit.called.should.be.true;
|
||||||
|
apiInit.called.should.be.true;
|
||||||
|
|
||||||
should.exist(server.app);
|
should.exist(runtime.app);
|
||||||
should.exist(server.nodeApp);
|
should.exist(runtime.nodeApp);
|
||||||
|
|
||||||
server.server.should.equal(dummyServer);
|
runtime.server.should.equal(dummyServer);
|
||||||
|
});
|
||||||
|
|
||||||
commsInit.restore();
|
it("doesn't init api if httpAdminRoot set to false",function() {
|
||||||
|
|
||||||
|
var dummyServer = {};
|
||||||
|
runtime.init(dummyServer,{testSettings: true, httpAdminRoot:false, load:function() { return when.resolve();}});
|
||||||
|
commsInit.called.should.be.true;
|
||||||
|
apiInit.called.should.be.false;
|
||||||
|
|
||||||
|
should.exist(runtime.app);
|
||||||
|
should.exist(runtime.nodeApp);
|
||||||
|
|
||||||
|
runtime.server.should.equal(dummyServer);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("start",function() {
|
describe("start",function() {
|
||||||
var commsInit;
|
var commsInit;
|
||||||
var storageInit;
|
var storageInit;
|
||||||
var settingsLoad;
|
var settingsLoad;
|
||||||
var apiInit;
|
|
||||||
var logMetric;
|
var logMetric;
|
||||||
var logWarn;
|
var logWarn;
|
||||||
var logInfo;
|
var logInfo;
|
||||||
@ -77,7 +104,6 @@ describe("red/server", function() {
|
|||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
commsInit = sinon.stub(comms,"init",function() {});
|
commsInit = sinon.stub(comms,"init",function() {});
|
||||||
storageInit = sinon.stub(storage,"init",function(settings) {return when.resolve();});
|
storageInit = sinon.stub(storage,"init",function(settings) {return when.resolve();});
|
||||||
apiInit = sinon.stub(api,"init",function() {});
|
|
||||||
logMetric = sinon.stub(log,"metric",function() { return false; });
|
logMetric = sinon.stub(log,"metric",function() { return false; });
|
||||||
logWarn = sinon.stub(log,"warn",function() { });
|
logWarn = sinon.stub(log,"warn",function() { });
|
||||||
logInfo = sinon.stub(log,"info",function() { });
|
logInfo = sinon.stub(log,"info",function() { });
|
||||||
@ -92,7 +118,6 @@ describe("red/server", function() {
|
|||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
commsInit.restore();
|
commsInit.restore();
|
||||||
storageInit.restore();
|
storageInit.restore();
|
||||||
apiInit.restore();
|
|
||||||
logMetric.restore();
|
logMetric.restore();
|
||||||
logWarn.restore();
|
logWarn.restore();
|
||||||
logInfo.restore();
|
logInfo.restore();
|
||||||
@ -112,10 +137,11 @@ describe("red/server", function() {
|
|||||||
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
|
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
|
||||||
].filter(cb);
|
].filter(cb);
|
||||||
});
|
});
|
||||||
server.init({},{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
runtime.init({},{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
server.start().then(function() {
|
sinon.stub(console,"log");
|
||||||
|
runtime.start().then(function() {
|
||||||
|
console.log.restore();
|
||||||
try {
|
try {
|
||||||
apiInit.calledOnce.should.be.true;
|
|
||||||
storageInit.calledOnce.should.be.true;
|
storageInit.calledOnce.should.be.true;
|
||||||
redNodesInit.calledOnce.should.be.true;
|
redNodesInit.calledOnce.should.be.true;
|
||||||
redNodesLoad.calledOnce.should.be.true;
|
redNodesLoad.calledOnce.should.be.true;
|
||||||
@ -142,10 +168,11 @@ describe("red/server", function() {
|
|||||||
].filter(cb);
|
].filter(cb);
|
||||||
});
|
});
|
||||||
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return when.resolve();});
|
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return when.resolve();});
|
||||||
server.init({},{testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
runtime.init({},{testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
server.start().then(function() {
|
sinon.stub(console,"log");
|
||||||
|
runtime.start().then(function() {
|
||||||
|
console.log.restore();
|
||||||
try {
|
try {
|
||||||
apiInit.calledOnce.should.be.true;
|
|
||||||
logWarn.calledWithMatch("Failed to register 2 node types");
|
logWarn.calledWithMatch("Failed to register 2 node types");
|
||||||
logWarn.calledWithMatch("Missing node modules");
|
logWarn.calledWithMatch("Missing node modules");
|
||||||
logWarn.calledWithMatch(" - module: typeA, typeB");
|
logWarn.calledWithMatch(" - module: typeA, typeB");
|
||||||
@ -167,11 +194,11 @@ describe("red/server", function() {
|
|||||||
{ err:"errored",name:"errName" } // error
|
{ err:"errored",name:"errName" } // error
|
||||||
].filter(cb);
|
].filter(cb);
|
||||||
});
|
});
|
||||||
server.init({},{testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
runtime.init({},{testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
server.start().then(function() {
|
sinon.stub(console,"log");
|
||||||
|
runtime.start().then(function() {
|
||||||
|
console.log.restore();
|
||||||
try {
|
try {
|
||||||
apiInit.calledOnce.should.be.true;
|
|
||||||
logWarn.neverCalledWithMatch("Failed to register 1 node type");
|
logWarn.neverCalledWithMatch("Failed to register 1 node type");
|
||||||
logWarn.calledWithMatch("[errName] errored");
|
logWarn.calledWithMatch("[errName] errored");
|
||||||
done();
|
done();
|
||||||
@ -187,11 +214,12 @@ describe("red/server", function() {
|
|||||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
||||||
logMetric.restore();
|
logMetric.restore();
|
||||||
logMetric = sinon.stub(log,"metric",function() { return true; });
|
logMetric = sinon.stub(log,"metric",function() { return true; });
|
||||||
server.init({},{testSettings: true, runtimeMetricInterval:400, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
runtime.init({},{testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return when.resolve();}});
|
||||||
server.start().then(function() {
|
sinon.stub(console,"log");
|
||||||
|
runtime.start().then(function() {
|
||||||
|
console.log.restore();
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
try {
|
try {
|
||||||
apiInit.calledOnce.should.be.true;
|
|
||||||
logLog.args.should.have.lengthOf(3);
|
logLog.args.should.have.lengthOf(3);
|
||||||
logLog.args[0][0].should.have.property("level",log.METRIC);
|
logLog.args[0][0].should.have.property("level",log.METRIC);
|
||||||
logLog.args[0][0].should.have.property("event","runtime.memory.rss");
|
logLog.args[0][0].should.have.property("event","runtime.memory.rss");
|
||||||
@ -203,35 +231,22 @@ describe("red/server", function() {
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
done(err);
|
done(err);
|
||||||
} finally {
|
} finally {
|
||||||
server.stop();
|
runtime.stop();
|
||||||
commsStop.restore();
|
commsStop.restore();
|
||||||
stopFlows.restore();
|
stopFlows.restore();
|
||||||
}
|
}
|
||||||
},500);
|
},300);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("doesn't init api if httpAdminRoot set to false",function(done) {
|
|
||||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
|
||||||
server.init({},{testSettings: true, httpAdminRoot:false, load:function() { return when.resolve();}});
|
|
||||||
server.start().then(function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
try {
|
|
||||||
apiInit.calledOnce.should.be.false;
|
|
||||||
done();
|
|
||||||
} catch(err) {
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
},500);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("stops components", function() {
|
it("stops components", function() {
|
||||||
var commsStop = sinon.stub(comms,"stop",function() {} );
|
var commsStop = sinon.stub(comms,"stop",function() {} );
|
||||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
||||||
|
|
||||||
server.stop();
|
runtime.stop();
|
||||||
|
|
||||||
commsStop.called.should.be.true;
|
commsStop.called.should.be.true;
|
||||||
stopFlows.called.should.be.true;
|
stopFlows.called.should.be.true;
|
@ -20,11 +20,11 @@ var settings = require("../../red/settings");
|
|||||||
|
|
||||||
|
|
||||||
describe("red/settings", function() {
|
describe("red/settings", function() {
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
settings.reset();
|
settings.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wraps the user settings as read-only properties', function() {
|
it('wraps the user settings as read-only properties', function() {
|
||||||
var userSettings = {
|
var userSettings = {
|
||||||
a: 123,
|
a: 123,
|
||||||
@ -32,22 +32,22 @@ describe("red/settings", function() {
|
|||||||
c: [1,2,3]
|
c: [1,2,3]
|
||||||
}
|
}
|
||||||
settings.init(userSettings);
|
settings.init(userSettings);
|
||||||
|
|
||||||
settings.available().should.be.false;
|
settings.available().should.be.false;
|
||||||
|
|
||||||
settings.a.should.equal(123);
|
settings.a.should.equal(123);
|
||||||
settings.b.should.equal("test");
|
settings.b.should.equal("test");
|
||||||
settings.c.should.be.an.Array.with.lengthOf(3);
|
settings.c.should.be.an.Array.with.lengthOf(3);
|
||||||
|
|
||||||
settings.get("a").should.equal(123);
|
settings.get("a").should.equal(123);
|
||||||
settings.get("b").should.equal("test");
|
settings.get("b").should.equal("test");
|
||||||
settings.get("c").should.be.an.Array.with.lengthOf(3);
|
settings.get("c").should.be.an.Array.with.lengthOf(3);
|
||||||
|
|
||||||
/*jshint immed: false */
|
/*jshint immed: false */
|
||||||
(function() {
|
(function() {
|
||||||
settings.a = 456;
|
settings.a = 456;
|
||||||
}).should.throw();
|
}).should.throw();
|
||||||
|
|
||||||
settings.c.push(5);
|
settings.c.push(5);
|
||||||
settings.c.should.be.an.Array.with.lengthOf(4);
|
settings.c.should.be.an.Array.with.lengthOf(4);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ describe("red/settings", function() {
|
|||||||
(function() {
|
(function() {
|
||||||
settings.set("a",456);
|
settings.set("a",456);
|
||||||
}).should.throw();
|
}).should.throw();
|
||||||
|
|
||||||
/*jshint immed: false */
|
/*jshint immed: false */
|
||||||
(function() {
|
(function() {
|
||||||
settings.set("a",456);
|
settings.set("a",456);
|
||||||
@ -70,9 +70,9 @@ describe("red/settings", function() {
|
|||||||
(function() {
|
(function() {
|
||||||
settings.set("unknown",456);
|
settings.set("unknown",456);
|
||||||
}).should.throw();
|
}).should.throw();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads global settings from storage', function(done) {
|
it('loads global settings from storage', function(done) {
|
||||||
var userSettings = {
|
var userSettings = {
|
||||||
a: 123,
|
a: 123,
|
||||||
@ -94,7 +94,7 @@ describe("red/settings", function() {
|
|||||||
settings.init(userSettings);
|
settings.init(userSettings);
|
||||||
|
|
||||||
settings.available().should.be.false;
|
settings.available().should.be.false;
|
||||||
|
|
||||||
/*jshint immed: false */
|
/*jshint immed: false */
|
||||||
(function() {
|
(function() {
|
||||||
settings.get("unknown");
|
settings.get("unknown");
|
||||||
@ -117,7 +117,7 @@ describe("red/settings", function() {
|
|||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('removes persistent settings when reset', function() {
|
it('removes persistent settings when reset', function() {
|
||||||
var userSettings = {
|
var userSettings = {
|
||||||
a: 123,
|
a: 123,
|
||||||
@ -125,18 +125,18 @@ describe("red/settings", function() {
|
|||||||
c: [1,2,3]
|
c: [1,2,3]
|
||||||
}
|
}
|
||||||
settings.init(userSettings);
|
settings.init(userSettings);
|
||||||
|
|
||||||
settings.available().should.be.false;
|
settings.available().should.be.false;
|
||||||
|
|
||||||
settings.should.have.property("a",123);
|
settings.should.have.property("a",123);
|
||||||
settings.should.have.property("b","test");
|
settings.should.have.property("b","test");
|
||||||
settings.c.should.be.an.Array.with.lengthOf(3);
|
settings.c.should.be.an.Array.with.lengthOf(3);
|
||||||
|
|
||||||
settings.reset();
|
settings.reset();
|
||||||
|
|
||||||
settings.should.not.have.property("a");
|
settings.should.not.have.property("a");
|
||||||
settings.should.not.have.property("d");
|
settings.should.not.have.property("d");
|
||||||
settings.should.not.have.property("c");
|
settings.should.not.have.property("c");
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user