diff --git a/red.js b/red.js
index b877e6bae..6162addae 100755
--- a/red.js
+++ b/red.js
@@ -25,7 +25,6 @@ var nopt = require("nopt");
var path = require("path");
var fs = require("fs-extra");
var RED = require("./red/red.js");
-var log = require("./red/log");
var server;
var app = express();
@@ -205,7 +204,7 @@ function basicAuthMiddleware(user,pass) {
}
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));
}
@@ -243,10 +242,10 @@ RED.start().then(function() {
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
server.on('error', function(err) {
if (err.errno === "EADDRINUSE") {
- RED.log.error(log._("server.unable-to-listen", {listenpath:getListenPath()}));
- RED.log.error(log._("server.port-in-use"));
+ RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
+ RED.log.error(RED.log._("server.port-in-use"));
} else {
- RED.log.error(log._("server.uncaught-exception"));
+ RED.log.error(RED.log._("server.uncaught-exception"));
if (err.stack) {
RED.log.error(err.stack);
} else {
@@ -257,16 +256,16 @@ RED.start().then(function() {
});
server.listen(settings.uiPort,settings.uiHost,function() {
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';
- RED.log.info(log._("server.now-running", {listenpath:getListenPath()}));
+ RED.log.info(RED.log._("server.now-running", {listenpath:getListenPath()}));
});
} else {
- RED.log.info(log._("server.headless-mode"));
+ RED.log.info(RED.log._("server.headless-mode"));
}
}).otherwise(function(err) {
- RED.log.error(log._("server.failed-to-start"));
+ RED.log.error(RED.log._("server.failed-to-start"));
if (err.stack) {
RED.log.error(err.stack);
} else {
diff --git a/red/api/auth/index.js b/red/api/auth/index.js
index ea69c6dbc..1152ce76e 100644
--- a/red/api/auth/index.js
+++ b/red/api/auth/index.js
@@ -25,7 +25,7 @@ var permissions = require("./permissions");
var theme = require("../theme");
var settings = null;
-var log = require("../../log");
+var log = null
passport.use(strategies.bearerStrategy.BearerStrategy);
@@ -36,11 +36,13 @@ var server = oauth2orize.createServer();
server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange));
-function init(_settings,storage) {
- settings = _settings;
+function init(runtime) {
+ settings = runtime.settings;
+ log = runtime.log;
if (settings.adminAuth) {
Users.init(settings.adminAuth);
- Tokens.init(settings.adminAuth,storage);
+ Tokens.init(settings.adminAuth,runtime.storage);
+ strategies.init(runtime);
}
}
diff --git a/red/api/auth/strategies.js b/red/api/auth/strategies.js
index 6a61b77e0..247d24d2e 100644
--- a/red/api/auth/strategies.js
+++ b/red/api/auth/strategies.js
@@ -26,7 +26,7 @@ var Users = require("./users");
var Clients = require("./clients");
var permissions = require("./permissions");
-var log = require("../../log");
+var log;
var bearerStrategy = function (accessToken, done) {
// is this a valid token?
@@ -124,6 +124,9 @@ AnonymousStrategy.prototype.authenticate = function(req) {
}
module.exports = {
+ init: function(runtime) {
+ log = runtime.log;
+ },
bearerStrategy: bearerStrategy,
clientPasswordStrategy: clientPasswordStrategy,
passwordTokenExchange: passwordTokenExchange,
diff --git a/red/api/credentials.js b/red/api/credentials.js
index f2cc601e8..ae3123b3b 100644
--- a/red/api/credentials.js
+++ b/red/api/credentials.js
@@ -14,10 +14,14 @@
* limitations under the License.
**/
-var log = require("../log");
-var api = require("../nodes");
+var log;
+var api;
module.exports = {
+ init: function(runtime) {
+ log = runtime.log;
+ api = runtime.api;
+ },
get: function (req, res) {
// TODO: It should verify the given node id is of the type specified -
// but that would add a dependency from this module to the
diff --git a/red/api/flows.js b/red/api/flows.js
index 72cc6ae9f..9167f3e8d 100644
--- a/red/api/flows.js
+++ b/red/api/flows.js
@@ -14,12 +14,16 @@
* limitations under the License.
**/
-var log = require("../log");
-
-var redNodes = require("../nodes");
-var settings = require("../settings");
+var log;
+var redNodes;
+var settings;
module.exports = {
+ init: function(runtime) {
+ settings = runtime.settings;
+ redNodes = runtime.api;
+ log = runtime.log;
+ },
get: function(req,res) {
log.audit({event: "flows.get"},req);
res.json(redNodes.getFlows());
diff --git a/red/api/index.js b/red/api/index.js
index a01fca399..e2cc5f92a 100644
--- a/red/api/index.js
+++ b/red/api/index.js
@@ -29,12 +29,12 @@ var theme = require("./theme");
var locales = require("./locales");
var credentials = require("./credentials");
-var log = require("../log");
-
var auth = require("./auth");
var needsPermission = auth.needsPermission;
-var settings = require("../settings");
+var log;
+var adminApp;
+var nodeApp;
var errorHandler = function(err,req,res,next) {
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()});
};
-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
- if (!settings.disableEditor) {
- ui.init(settings);
- var editorApp = express();
- editorApp.get("/",ui.ensureSlash,ui.editor);
- editorApp.get("/icons/:icon",ui.icon);
- if (settings.editorTheme) {
- editorApp.use("/theme",theme.init(settings));
+ // Editor
+ if (!settings.disableEditor) {
+ ui.init(runtime);
+ var editorApp = express();
+ editorApp.get("/",ui.ensureSlash,ui.editor);
+ editorApp.get("/icons/:icon",ui.icon);
+ if (settings.editorTheme) {
+ editorApp.use("/theme",theme.init(runtime));
+ }
+ editorApp.use("/",ui.editorResources);
+ adminApp.use(editorApp);
}
- editorApp.use("/",ui.editorResources);
- adminApp.use(editorApp);
+ 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
+ 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 = {
- init: init
+ init: init,
+ library: {
+ register: library.register
+ },
+ auth: {
+ needsPermission: auth.needsPermission
+ },
+ adminApp: function() { return adminApp; },
+ nodeApp: function() { return nodeApp; }
};
diff --git a/red/api/info.js b/red/api/info.js
index 6cdd20b94..a9f79a0d4 100644
--- a/red/api/info.js
+++ b/red/api/info.js
@@ -13,28 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
-var settings = require('../settings');
var theme = require("./theme");
-
var util = require('util');
+var settings;
module.exports = {
+ init: function(runtime) {
+ settings = runtime.settings;
+ },
settings: function(req,res) {
var safeSettings = {
httpNodeRoot: settings.httpNodeRoot,
version: settings.version,
user: req.user
}
-
+
var themeSettings = theme.settings();
if (themeSettings) {
safeSettings.editorTheme = themeSettings;
}
-
+
if (util.isArray(settings.paletteCategories)) {
safeSettings.paletteCategories = settings.paletteCategories;
}
-
+
res.json(safeSettings);
}
}
diff --git a/red/api/library.js b/red/api/library.js
index a257b4fe6..a73c1dd47 100644
--- a/red/api/library.js
+++ b/red/api/library.js
@@ -15,9 +15,8 @@
**/
var redApp = null;
-var storage = require("../storage");
-var log = require("../log");
-
+var storage;
+var log;
var needsPermission = require("./auth").needsPermission;
function createLibrary(type) {
@@ -70,8 +69,10 @@ function createLibrary(type) {
}
}
module.exports = {
- init: function(app) {
+ init: function(app,runtime) {
redApp = app;
+ log = runtime.log;
+ storage = runtime.storage;
},
register: createLibrary,
@@ -90,7 +91,7 @@ module.exports = {
}).otherwise(function(err) {
if (err) {
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);
res.status(403).end();
return;
diff --git a/red/api/locales.js b/red/api/locales.js
index 28dc37f99..53520f221 100644
--- a/red/api/locales.js
+++ b/red/api/locales.js
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
-var i18n = require("../i18n");
-
+var i18n;
module.exports = {
+ init: function(runtime) {
+ i18n = runtime.i18n;
+ },
get: function(req,res) {
var namespace = req.params[0];
namespace = namespace.replace(/\.json$/,"");
diff --git a/red/api/nodes.js b/red/api/nodes.js
index 47e42be32..8153fcadb 100644
--- a/red/api/nodes.js
+++ b/red/api/nodes.js
@@ -13,16 +13,22 @@
* See the License for the specific language governing permissions and
* 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 settings = require("../settings");
+var redNodes;
+var comms;
+var log;
+var i18n;
+var settings;
module.exports = {
+ init: function(runtime) {
+ redNodes = runtime.api;
+ comms = runtime.comms;
+ log = runtime.log;
+ i18n = runtime.i18n;
+ settings = runtime.settings;
+ },
getAll: function(req,res) {
if (req.get("accept") == "application/json") {
log.audit({event: "nodes.list.get"},req);
diff --git a/red/api/theme.js b/red/api/theme.js
index c3de9a86e..1104976ee 100644
--- a/red/api/theme.js
+++ b/red/api/theme.js
@@ -53,7 +53,8 @@ function serveFile(app,baseUrl,file) {
}
module.exports = {
- init: function(settings) {
+ init: function(runtime) {
+ var settings = runtime.settings;
var i;
var url;
themeContext = clone(defaultContext);
diff --git a/red/api/ui.js b/red/api/ui.js
index 9bdca4f56..01fbc7007 100644
--- a/red/api/ui.js
+++ b/red/api/ui.js
@@ -1,5 +1,5 @@
/**
- * Copyright 2013, 2014 IBM Corp.
+ * Copyright 2013, 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.
@@ -21,26 +21,26 @@ var theme = require("./theme");
var Mustache = require("mustache");
-var events = require("../events");
-var settings;
-
var icon_paths = [path.resolve(__dirname + '/../../public/icons')];
var iconCache = {};
//TODO: create a default icon
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 editorTemplate;
+function nodeIconDir(dir) {
+ icon_paths.push(path.resolve(dir));
+}
+
module.exports = {
- init: function(_settings) {
- settings = _settings;
+ init: function(runtime) {
editorTemplate = fs.readFileSync(path.join(templateDir,"index.mst"),"utf8");
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) {
diff --git a/red/red.js b/red/red.js
index c96888224..aead539fa 100644
--- a/red/red.js
+++ b/red/red.js
@@ -14,22 +14,18 @@
* 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 settings = require("./settings");
-var credentials = require("./nodes/credentials");
-var auth = require("./api/auth");
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+"/..");
+var nodeApp = null;
+var adminApp = null;
+var server = null;
+
function checkBuild() {
var editorFile = path.resolve(path.join(__dirname,"..","public","red","red.min.js"));
try {
@@ -43,40 +39,44 @@ function checkBuild() {
var RED = {
init: function(httpServer,userSettings) {
+ server = httpServer;
+
if (!userSettings.SKIP_BUILD_CHECK) {
checkBuild();
}
- userSettings.version = this.version();
- log.init(userSettings);
- settings.init(userSettings);
- server.init(httpServer,settings);
- return server.app;
- },
- 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";
+ runtime.init(httpServer,userSettings);
+ if (userSettings.httpAdminRoot !== false || userSettings.httpNodeRoot !== false) {
+ api.init(runtime);
+ adminApp = api.adminApp();
+ nodeApp = api.nodeApp();
}
- 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 },
- get httpAdmin() { return server.app },
- get httpNode() { return server.nodeApp },
- get server() { return server.server }
+ start: runtime.start,
+ stop: runtime.stop,
+ nodes: runtime.api,
+ 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;
diff --git a/red/comms.js b/red/runtime/comms.js
similarity index 97%
rename from red/comms.js
rename to red/runtime/comms.js
index d5df4ef7f..59c8d0e11 100644
--- a/red/comms.js
+++ b/red/runtime/comms.js
@@ -37,9 +37,9 @@ function init(_server,_settings) {
function start() {
- var Tokens = require("./api/auth/tokens");
- var Users = require("./api/auth/users");
- var Permissions = require("./api/auth/permissions");
+ var Tokens = require("../api/auth/tokens");
+ var Users = require("../api/auth/users");
+ var Permissions = require("../api/auth/permissions");
if (!settings.disableEditor) {
Users.default().then(function(anonymousUser) {
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
diff --git a/red/events.js b/red/runtime/events.js
similarity index 100%
rename from red/events.js
rename to red/runtime/events.js
diff --git a/red/i18n.js b/red/runtime/i18n.js
similarity index 97%
rename from red/i18n.js
rename to red/runtime/i18n.js
index 83e5fd273..eaa9189f0 100644
--- a/red/i18n.js
+++ b/red/runtime/i18n.js
@@ -24,11 +24,11 @@ var supportedLangs = [];
var resourceMap = {
"runtime": {
- basedir: path.resolve(__dirname+"/../locales"),
+ basedir: path.resolve(__dirname+"/../../locales"),
file:"runtime.json"
},
"editor": {
- basedir: path.resolve(__dirname+"/../locales"),
+ basedir: path.resolve(__dirname+"/../../locales"),
file: "editor.json"
}
}
diff --git a/red/server.js b/red/runtime/index.js
similarity index 86%
rename from red/server.js
rename to red/runtime/index.js
index ced1652ec..85935660b 100644
--- a/red/server.js
+++ b/red/runtime/index.js
@@ -14,7 +14,6 @@
* limitations under the License.
**/
-var express = require('express');
var when = require('when');
var redNodes = require("./nodes");
@@ -22,23 +21,27 @@ var comms = require("./comms");
var storage = require("./storage");
var log = require("./log");
var i18n = require("./i18n");
-
-var app = null;
-var nodeApp = null;
-var server = null;
-var settings = null;
+var events = require("./events");
+var settings = require("./settings");
+var path = require('path');
+var fs = require("fs");
var runtimeMetricInterval = null;
+function init(server,userSettings) {
+ userSettings.version = version();
+ log.init(userSettings);
+ settings.init(userSettings);
+ comms.init(server,settings);
+}
-function init(_server,_settings) {
- server = _server;
- settings = _settings;
-
- comms.init(_server,_settings);
-
- nodeApp = express();
- app = express();
+function version() {
+ 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;
}
function start() {
@@ -46,9 +49,6 @@ function start() {
.then(function() { return storage.init(settings)})
.then(function() { return settings.load(storage)})
.then(function() {
- if (settings.httpAdminRoot !== false) {
- require("./api").init(app,storage);
- }
if (log.metric()) {
runtimeMetricInterval = setInterval(function() {
@@ -141,12 +141,19 @@ function stop() {
comms.stop();
}
-var serverAPI = module.exports = {
+var runtime = module.exports = {
init: init,
start: start,
stop: stop,
- get app() { return app },
- get nodeApp() { return nodeApp },
- get server() { return server }
+ version: version,
+
+ log: log,
+ i18n: i18n,
+ settings: settings,
+ storage: storage,
+ comms: comms,
+ events: events,
+ api: redNodes,
+ util: require("./util")
}
diff --git a/red/log.js b/red/runtime/log.js
similarity index 100%
rename from red/log.js
rename to red/runtime/log.js
diff --git a/red/nodes/Node.js b/red/runtime/nodes/Node.js
similarity index 100%
rename from red/nodes/Node.js
rename to red/runtime/nodes/Node.js
diff --git a/red/nodes/credentials.js b/red/runtime/nodes/credentials.js
similarity index 98%
rename from red/nodes/credentials.js
rename to red/runtime/nodes/credentials.js
index 57a0da054..aeab852b6 100644
--- a/red/nodes/credentials.js
+++ b/red/runtime/nodes/credentials.js
@@ -18,8 +18,6 @@ var when = require("when");
var log = require("../log");
-var needsPermission = require("../api/auth").needsPermission;
-
var credentialCache = {};
var storage = null;
var credentialsDef = {};
diff --git a/red/nodes/flows/Flow.js b/red/runtime/nodes/flows/Flow.js
similarity index 100%
rename from red/nodes/flows/Flow.js
rename to red/runtime/nodes/flows/Flow.js
diff --git a/red/nodes/flows/index.js b/red/runtime/nodes/flows/index.js
similarity index 100%
rename from red/nodes/flows/index.js
rename to red/runtime/nodes/flows/index.js
diff --git a/red/nodes/flows/util.js b/red/runtime/nodes/flows/util.js
similarity index 100%
rename from red/nodes/flows/util.js
rename to red/runtime/nodes/flows/util.js
diff --git a/red/nodes/index.js b/red/runtime/nodes/index.js
similarity index 100%
rename from red/nodes/index.js
rename to red/runtime/nodes/index.js
diff --git a/red/nodes/registry/deprecated.js b/red/runtime/nodes/registry/deprecated.js
similarity index 100%
rename from red/nodes/registry/deprecated.js
rename to red/runtime/nodes/registry/deprecated.js
diff --git a/red/nodes/registry/index.js b/red/runtime/nodes/registry/index.js
similarity index 100%
rename from red/nodes/registry/index.js
rename to red/runtime/nodes/registry/index.js
diff --git a/red/nodes/registry/installer.js b/red/runtime/nodes/registry/installer.js
similarity index 100%
rename from red/nodes/registry/installer.js
rename to red/runtime/nodes/registry/installer.js
diff --git a/red/nodes/registry/loader.js b/red/runtime/nodes/registry/loader.js
similarity index 99%
rename from red/nodes/registry/loader.js
rename to red/runtime/nodes/registry/loader.js
index 265abe71f..2cc57fc41 100644
--- a/red/nodes/registry/loader.js
+++ b/red/runtime/nodes/registry/loader.js
@@ -36,9 +36,7 @@ events.on("node-locales-dir", function(info) {
function init(_settings) {
settings = _settings;
localfilesystem.init(settings);
-
- RED = require('../../red');
-
+ RED = require('../../../red');
}
function load(defaultNodesDir,disableNodePathScan) {
diff --git a/red/nodes/registry/localfilesystem.js b/red/runtime/nodes/registry/localfilesystem.js
similarity index 99%
rename from red/nodes/registry/localfilesystem.js
rename to red/runtime/nodes/registry/localfilesystem.js
index 92998dbf5..28d8bf5d4 100644
--- a/red/nodes/registry/localfilesystem.js
+++ b/red/runtime/nodes/registry/localfilesystem.js
@@ -22,7 +22,7 @@ var events = require("../../events");
var log = require("../../log");
var settings;
-var defaultNodesDir = path.resolve(path.join(__dirname,"..","..","..","nodes"));
+var defaultNodesDir = path.resolve(path.join(__dirname,"..","..","..","..","nodes"));
var disableNodePathScan = false;
function init(_settings,_defaultNodesDir,_disableNodePathScan) {
@@ -133,7 +133,7 @@ function scanDirForNodesModules(dir,moduleName) {
* @return a list of node modules: {dir,package}
*/
function scanTreeForNodesModules(moduleName) {
- var dir = __dirname+"/../../nodes";
+ var dir = __dirname+"/../../../../nodes";
var results = [];
var userDir;
diff --git a/red/nodes/registry/registry.js b/red/runtime/nodes/registry/registry.js
similarity index 99%
rename from red/nodes/registry/registry.js
rename to red/runtime/nodes/registry/registry.js
index 886be8767..ebd7d4cf0 100644
--- a/red/nodes/registry/registry.js
+++ b/red/runtime/nodes/registry/registry.js
@@ -256,7 +256,7 @@ function getFullNodeInfo(typeOrId) {
var module = moduleConfigs[getModule(id)];
if (module) {
return module.nodes[getNode(id)];
- }
+ }
}
return null;
}
@@ -292,7 +292,7 @@ function getModuleList() {
//}
//return list;
return moduleConfigs;
-
+
}
function getModuleInfo(module) {
@@ -358,7 +358,7 @@ function getNodeConfig(id,lang) {
if (config) {
var result = config.config;
result += loader.getNodeHelp(config,lang||"en-US")
-
+
//if (config.script) {
// result += '';
//}
@@ -490,9 +490,9 @@ var registry = module.exports = {
addNodeSet: addNodeSet,
enableNodeSet: enableNodeSet,
disableNodeSet: disableNodeSet,
-
+
removeModule: removeModule,
-
+
getNodeInfo: getNodeInfo,
getFullNodeInfo: getFullNodeInfo,
getNodeList: getNodeList,
diff --git a/red/settings.js b/red/runtime/settings.js
similarity index 100%
rename from red/settings.js
rename to red/runtime/settings.js
diff --git a/red/storage/index.js b/red/runtime/storage/index.js
similarity index 100%
rename from red/storage/index.js
rename to red/runtime/storage/index.js
diff --git a/red/storage/localfilesystem.js b/red/runtime/storage/localfilesystem.js
similarity index 100%
rename from red/storage/localfilesystem.js
rename to red/runtime/storage/localfilesystem.js
diff --git a/red/util.js b/red/runtime/util.js
similarity index 100%
rename from red/util.js
rename to red/runtime/util.js
diff --git a/test/red/api/auth/index_spec.js b/test/red/api/auth/index_spec.js
index bb6a33be2..1dd8119e5 100644
--- a/test/red/api/auth/index_spec.js
+++ b/test/red/api/auth/index_spec.js
@@ -24,12 +24,14 @@ var auth = require("../../../../red/api/auth");
var Users = require("../../../../red/api/auth/users");
var Tokens = require("../../../../red/api/auth/tokens");
-var settings = require("../../../../red/settings");
-
-
describe("api auth middleware",function() {
+
+
describe("ensureClientSecret", function() {
+ before(function() {
+ auth.init({settings:{},log:{audit:function(){}}})
+ });
it("leaves client_secret alone if not present",function(done) {
var req = {
body: {
@@ -83,7 +85,7 @@ describe("api auth middleware",function() {
Users.init.restore();
});
it("returns login details - credentials", function(done) {
- auth.init({adminAuth:{}},null);
+ auth.init({settings:{adminAuth:{}},log:{audit:function(){}}})
auth.login(null,{json: function(resp) {
resp.should.have.a.property("type","credentials");
resp.should.have.a.property("prompts");
@@ -92,7 +94,7 @@ describe("api auth middleware",function() {
}});
});
it("returns login details - none", function(done) {
- auth.init({},null);
+ auth.init({settings:{},log:{audit:function(){}}})
auth.login(null,{json: function(resp) {
resp.should.eql({});
done();
diff --git a/test/red/api/auth/strategies_spec.js b/test/red/api/auth/strategies_spec.js
index 3e46db0c0..5dc6fb7c0 100644
--- a/test/red/api/auth/strategies_spec.js
+++ b/test/red/api/auth/strategies_spec.js
@@ -24,8 +24,10 @@ var Tokens = require("../../../../red/api/auth/tokens");
var Clients = require("../../../../red/api/auth/clients");
describe("Auth strategies", function() {
+ before(function() {
+ strategies.init({log:{audit:function(){}}})
+ });
describe("Password Token Exchange", function() {
-
var userAuthentication;
afterEach(function() {
if (userAuthentication) {
@@ -49,7 +51,7 @@ describe("Auth strategies", function() {
}
});
});
-
+
it('Handles scope overreach',function(done) {
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
return when.resolve({username:"user",permissions:"read"});
diff --git a/test/red/api/credentials_spec.js b/test/red/api/credentials_spec.js
index 70e62c796..b4fc14e48 100644
--- a/test/red/api/credentials_spec.js
+++ b/test/red/api/credentials_spec.js
@@ -20,8 +20,6 @@ var express = require('express');
var sinon = require('sinon');
var when = require('when');
-
-var nodeApi = require("../../../red/nodes");
var credentials = require("../../../red/api/credentials");
describe('credentials api', function() {
@@ -30,26 +28,26 @@ describe('credentials api', function() {
before(function() {
app = express();
app.get('/credentials/:type/:id',credentials.get);
-
- sinon.stub(nodeApi,"getCredentials",function(id) {
- if (id === "n1") {
- 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"}};
- } else {
- return null;
+ credentials.init({
+ log:{audit:function(){}},
+ api:{
+ getCredentials: function(id) {
+ if (id === "n1") {
+ return {user1:"abc",password1:"123"};
+ } else {
+ return null;
+ }
+ },
+ getCredentialDefinition:function(type) {
+ if (type === "known-type") {
+ 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) {
request(app)
.get("/credentials/unknown-type/n1")
diff --git a/test/red/api/flows_spec.js b/test/red/api/flows_spec.js
index f2b7fe2e9..a39806eb3 100644
--- a/test/red/api/flows_spec.js
+++ b/test/red/api/flows_spec.js
@@ -21,8 +21,6 @@ var bodyParser = require('body-parser');
var sinon = require('sinon');
var when = require('when');
-var redNodes = require("../../../red/nodes");
-
var flows = require("../../../red/api/flows");
describe("flows api", function() {
@@ -37,15 +35,17 @@ describe("flows api", function() {
});
it('returns flow', function(done) {
- var getFlows = sinon.stub(redNodes,'getFlows', function() {
- return [1,2,3];
+ flows.init({
+ log:{warn:function(){},_:function(){},audit:function(){}},
+ api:{
+ getFlows: function() { return [1,2,3]; }
+ }
});
request(app)
.get('/flows')
.set('Accept', 'application/json')
.expect(200)
.end(function(err,res) {
- getFlows.restore();
if (err) {
throw err;
}
@@ -55,15 +55,17 @@ describe("flows api", function() {
});
it('sets flows', function(done) {
- var setFlows = sinon.stub(redNodes,'setFlows', function() {
- return when.resolve();
+ flows.init({
+ log:{warn:function(){},_:function(){},audit:function(){}},
+ api:{
+ setFlows: function() { return when.resolve(); }
+ }
});
request(app)
.post('/flows')
.set('Accept', 'application/json')
.expect(204)
.end(function(err,res) {
- setFlows.restore();
if (err) {
throw err;
}
@@ -71,15 +73,17 @@ describe("flows api", function() {
});
});
it('returns error when set fails', function(done) {
- var setFlows = sinon.stub(redNodes,'setFlows', function() {
- return when.reject(new Error("expected error"));
+ flows.init({
+ log:{warn:function(){},_:function(){},audit:function(){}},
+ api:{
+ setFlows: function() { return when.reject(new Error("expected error")); }
+ }
});
request(app)
.post('/flows')
.set('Accept', 'application/json')
.expect(500)
.end(function(err,res) {
- setFlows.restore();
if (err) {
throw err;
}
diff --git a/test/red/api/index_spec.js b/test/red/api/index_spec.js
index 4117ae6a5..d53633a4a 100644
--- a/test/red/api/index_spec.js
+++ b/test/red/api/index_spec.js
@@ -15,12 +15,12 @@
**/
var should = require("should");
+var sinon = require("sinon");
var request = require("supertest");
var express = require("express");
var when = require("when");
var fs = require("fs");
var path = require("path");
-var settings = require("../../../red/settings");
var api = require("../../../red/api");
describe("api index", function() {
@@ -28,12 +28,13 @@ describe("api index", function() {
describe("disables editor", function() {
before(function() {
- settings.init({disableEditor:true});
app = express();
- api.init(app);
- });
- after(function() {
- settings.reset();
+ api.init(app,{
+ settings:{disableEditor:true},
+ api:{
+
+ }
+ });
});
it('does not serve the editor', function(done) {
@@ -54,14 +55,25 @@ describe("api index", function() {
});
describe("can serve auth", function() {
+ var mockList = [
+ 'ui','nodes','flows','library','info','theme','locales','credentials'
+ ]
before(function() {
- //settings.init({disableEditor:true});
- settings.init({adminAuth:{type: "credentials",users:[],default:{permissions:"read"}}});
- app = express();
- api.init(app,{getSessions:function(){return when.resolve({})}});
+ mockList.forEach(function(m) {
+ sinon.stub(require("../../../red/api/"+m),"init",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) {
@@ -77,15 +89,29 @@ describe("api index", function() {
});
describe("enables editor", function() {
+
+ var mockList = [
+ 'nodes','flows','library','info','theme','locales','credentials'
+ ]
before(function() {
- settings.init({disableEditor:false});
- app = express();
- api.init(app);
+ mockList.forEach(function(m) {
+ sinon.stub(require("../../../red/api/"+m),"init",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) {
request(app)
.get("/")
diff --git a/test/red/api/info_spec.js b/test/red/api/info_spec.js
index f7124c661..2d522a576 100644
--- a/test/red/api/info_spec.js
+++ b/test/red/api/info_spec.js
@@ -21,30 +21,26 @@ var sinon = require('sinon');
var when = require('when');
var app = express();
-var settings = require("../../../red/settings");
var info = require("../../../red/api/info");
-
var theme = require("../../../red/api/theme");
describe("info api", function() {
describe("settings handler", 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 };});
-
+ info.init({
+ settings: {
+ foo: 123,
+ httpNodeRoot: "testHttpNodeRoot",
+ version: "testVersion",
+ paletteCategories :["red","blue","green"]
+ }
+ })
app = express();
app.get("/settings",info.settings);
});
after(function() {
- settings.reset();
theme.settings.restore();
});
diff --git a/test/red/api/library_spec.js b/test/red/api/library_spec.js
index 46561be74..50713a58e 100644
--- a/test/red/api/library_spec.js
+++ b/test/red/api/library_spec.js
@@ -21,19 +21,18 @@ var bodyParser = require('body-parser');
var when = require('when');
-var app = express();
-var RED = require("../../../red/red.js");
-var storage = require("../../../red/storage");
+var app;
var library = require("../../../red/api/library");
var auth = require("../../../red/api/auth");
describe("library api", function() {
- function initStorage(_flows,_libraryEntries) {
+ function initLibrary(_flows,_libraryEntries) {
var flows = _flows;
var libraryEntries = _libraryEntries;
- storage.init({
- storageModule: {
+ library.init(app,{
+ log:{audit:function(){},_:function(){},warn:function(){}},
+ storage: {
init: function() {
return when.resolve();
},
@@ -43,15 +42,29 @@ describe("library api", function() {
getFlow: function(fn) {
if (flows[fn]) {
return when.resolve(flows[fn]);
+ } else if (fn.indexOf("..")!==-1) {
+ var err = new Error();
+ err.code = 'forbidden';
+ return when.reject(err);
} else {
return when.reject();
}
},
saveFlow: function(fn,data) {
+ if (fn.indexOf("..")!==-1) {
+ var err = new Error();
+ err.code = 'forbidden';
+ return when.reject(err);
+ }
flows[fn] = data;
return when.resolve();
},
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]) {
return when.resolve(libraryEntries[type][path]);
} else {
@@ -59,6 +72,11 @@ describe("library api", function() {
}
},
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;
return when.resolve();
}
@@ -67,8 +85,6 @@ describe("library api", function() {
}
describe("flows", function() {
- var app;
-
before(function() {
app = express();
app.use(bodyParser.json());
@@ -77,7 +93,7 @@ describe("library api", function() {
app.get(new RegExp("/library/flows\/(.*)"),library.get);
});
it('returns empty result', function(done) {
- initStorage({},{flows:{}});
+ initLibrary({},{flows:{}});
request(app)
.get('/library/flows')
.expect(200)
@@ -92,7 +108,7 @@ describe("library api", function() {
});
it('returns 404 for non-existent entry', function(done) {
- initStorage({},{flows:{}});
+ initLibrary({},{flows:{}});
request(app)
.get('/library/flows/foo')
.expect(404)
@@ -101,7 +117,7 @@ describe("library api", function() {
it('can store and retrieve item', function(done) {
- initStorage({},{flows:{}});
+ initLibrary({},{flows:{}});
var flow = '[]';
request(app)
.post('/library/flows/foo')
@@ -125,7 +141,7 @@ describe("library api", function() {
});
it('lists a stored item', function(done) {
- initStorage({f:["bar"]});
+ initLibrary({f:["bar"]});
request(app)
.get('/library/flows')
.expect(200)
@@ -140,7 +156,7 @@ describe("library api", function() {
});
it('returns 403 for malicious get attempt', function(done) {
- initStorage({});
+ initLibrary({});
// without the userDir override the malicious url would be
// http://127.0.0.1:1880/library/flows/../../package to
// obtain package.json from the node-red root.
@@ -150,7 +166,7 @@ describe("library api", function() {
.end(done);
});
it('returns 403 for malicious post attempt', function(done) {
- initStorage({});
+ initLibrary({});
// without the userDir override the malicious url would be
// http://127.0.0.1:1880/library/flows/../../package to
// obtain package.json from the node-red root.
@@ -162,18 +178,17 @@ describe("library api", function() {
});
describe("type", function() {
- var app;
-
before(function() {
+
app = express();
app.use(bodyParser.json());
- library.init(app);
- auth.init({});
- RED.library.register("test");
+ initLibrary({},{});
+ auth.init({settings:{}});
+ library.register("test");
});
it('returns empty result', function(done) {
- initStorage({},{'test':{"":[]}});
+ initLibrary({},{'test':{"":[]}});
request(app)
.get('/library/test')
.expect(200)
@@ -187,7 +202,7 @@ describe("library api", function() {
});
it('returns 404 for non-existent entry', function(done) {
- initStorage({},{});
+ initLibrary({},{});
request(app)
.get('/library/test/foo')
.expect(404)
@@ -195,7 +210,7 @@ describe("library api", function() {
});
it('can store and retrieve item', function(done) {
- initStorage({},{'test':{}});
+ initLibrary({},{'test':{}});
var flow = {text:"test content"};
request(app)
.post('/library/test/foo')
@@ -219,7 +234,7 @@ describe("library api", function() {
});
it('lists a stored item', function(done) {
- initStorage({},{'test':{'a':['abc','def']}});
+ initLibrary({},{'test':{'a':['abc','def']}});
request(app)
.get('/library/test/a')
.expect(200)
diff --git a/test/red/api/locales_spec.js b/test/red/api/locales_spec.js
index e69de29bb..31d5fd673 100644
--- a/test/red/api/locales_spec.js
+++ b/test/red/api/locales_spec.js
@@ -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(){});
+});
diff --git a/test/red/api/nodes_spec.js b/test/red/api/nodes_spec.js
index f82e39a65..695d8b669 100644
--- a/test/red/api/nodes_spec.js
+++ b/test/red/api/nodes_spec.js
@@ -21,7 +21,6 @@ var bodyParser = require('body-parser');
var sinon = require('sinon');
var when = require('when');
-var redNodes = require("../../../red/nodes");
var settings = require("../../../red/settings");
var nodes = require("../../../red/api/nodes");
@@ -29,6 +28,16 @@ var nodes = require("../../../red/api/nodes");
describe("nodes api", function() {
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() {
app = express();
@@ -44,15 +53,18 @@ describe("nodes api", function() {
describe('get nodes', function() {
it('returns node list', function(done) {
- var getNodeList = sinon.stub(redNodes,'getNodeList', function() {
- return [1,2,3];
+ initNodes({
+ api:{
+ getNodeList: function() {
+ return [1,2,3];
+ }
+ }
});
request(app)
.get('/nodes')
.set('Accept', 'application/json')
.expect(200)
.end(function(err,res) {
- getNodeList.restore();
if (err) {
throw err;
}
@@ -62,8 +74,15 @@ describe("nodes api", function() {
});
it('returns node configs', function(done) {
- var getNodeConfigs = sinon.stub(redNodes,'getNodeConfigs', function() {
- return "";
+ initNodes({
+ api:{
+ getNodeConfigs: function() {
+ return "";
+ }
+ },
+ i18n: {
+ determineLangFromHeaders: function(){}
+ }
});
request(app)
.get('/nodes')
@@ -71,7 +90,6 @@ describe("nodes api", function() {
.expect(200)
.expect("")
.end(function(err,res) {
- getNodeConfigs.restore();
if (err) {
throw err;
}
@@ -80,14 +98,17 @@ describe("nodes api", function() {
});
it('returns node module info', function(done) {
- var getNodeInfo = sinon.stub(redNodes,'getModuleInfo', function(id) {
- return {"node-red":{name:"node-red"}}[id];
+ initNodes({
+ api:{
+ getModuleInfo: function(id) {
+ return {"node-red":{name:"node-red"}}[id];
+ }
+ }
});
request(app)
.get('/nodes/node-red')
.expect(200)
.end(function(err,res) {
- getNodeInfo.restore();
if (err) {
throw err;
}
@@ -97,14 +118,17 @@ describe("nodes api", function() {
});
it('returns 404 for unknown module', function(done) {
- var getNodeInfo = sinon.stub(redNodes,'getModuleInfo', function(id) {
- return {"node-red":{name:"node-red"}}[id];
+ initNodes({
+ api:{
+ getModuleInfo: function(id) {
+ return {"node-red":{name:"node-red"}}[id];
+ }
+ }
});
request(app)
.get('/nodes/node-blue')
.expect(404)
.end(function(err,res) {
- getNodeInfo.restore();
if (err) {
throw err;
}
@@ -113,15 +137,18 @@ describe("nodes api", function() {
});
it('returns individual node info', function(done) {
- var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
- return {"node-red/123":{id:"node-red/123"}}[id];
+ initNodes({
+ api:{
+ getNodeInfo: function(id) {
+ return {"node-red/123":{id:"node-red/123"}}[id];
+ }
+ }
});
request(app)
.get('/nodes/node-red/123')
.set('Accept', 'application/json')
.expect(200)
.end(function(err,res) {
- getNodeInfo.restore();
if (err) {
throw err;
}
@@ -131,8 +158,15 @@ describe("nodes api", function() {
});
it('returns individual node configs', function(done) {
- var getNodeConfig = sinon.stub(redNodes,'getNodeConfig', function(id) {
- return {"node-red/123":""}[id];
+ initNodes({
+ api:{
+ getNodeConfig: function(id) {
+ return {"node-red/123":""}[id];
+ }
+ },
+ i18n: {
+ determineLangFromHeaders: function(){}
+ }
});
request(app)
.get('/nodes/node-red/123')
@@ -140,7 +174,6 @@ describe("nodes api", function() {
.expect(200)
.expect("")
.end(function(err,res) {
- getNodeConfig.restore();
if (err) {
throw err;
}
@@ -149,15 +182,18 @@ describe("nodes api", function() {
});
it('returns 404 for unknown node', function(done) {
- var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
- return {"node-red/123":{id:"node-red/123"}}[id];
+ initNodes({
+ api:{
+ getNodeInfo: function(id) {
+ return {"node-red/123":{id:"node-red/123"}}[id];
+ }
+ }
});
request(app)
.get('/nodes/node-red/456')
.set('Accept', 'application/json')
.expect(404)
.end(function(err,res) {
- getNodeInfo.restore();
if (err) {
throw err;
}
@@ -169,14 +205,13 @@ describe("nodes api", function() {
describe('install', function() {
it('returns 400 if settings are unavailable', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return false;
+ initNodes({
+ settings:{available:function(){return false}}
});
request(app)
.post('/nodes')
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
if (err) {
throw err;
}
@@ -185,15 +220,14 @@ describe("nodes api", function() {
});
it('returns 400 if request is invalid', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ settings:{available:function(){return true}}
});
request(app)
.post('/nodes')
.send({})
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
if (err) {
throw err;
}
@@ -203,26 +237,23 @@ describe("nodes api", function() {
describe('by module', function() {
it('installs the module and returns module info', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.post('/nodes')
.send({module: 'foo'})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- installModule.restore();
if (err) {
throw err;
}
@@ -234,24 +265,20 @@ describe("nodes api", function() {
});
it('fails the install if already installed', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.post('/nodes')
.send({module: 'foo'})
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- installModule.restore();
if (err) {
throw err;
}
@@ -260,24 +287,20 @@ describe("nodes api", function() {
});
it('fails the install if module error', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.post('/nodes')
.send({module: 'foo'})
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- installModule.restore();
if (err) {
throw err;
}
@@ -286,26 +309,22 @@ describe("nodes api", function() {
});
});
it('fails the install if module not found', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.post('/nodes')
.send({module: 'foo'})
.expect(404)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- installModule.restore();
if (err) {
throw err;
}
@@ -319,6 +338,10 @@ describe("nodes api", function() {
var settingsAvailable = sinon.stub(settings,'available', function() {
return false;
});
+ initNodes({
+ settings:{available:function(){return false}}
+ });
+
request(app)
.del('/nodes/123')
.expect(400)
@@ -333,27 +356,18 @@ describe("nodes api", function() {
describe('by module', function() {
it('uninstalls the module', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.del('/nodes/foo')
.expect(204)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
- getModuleInfo.restore();
- uninstallModule.restore();
if (err) {
throw err;
}
@@ -362,23 +376,17 @@ describe("nodes api", function() {
});
it('fails the uninstall if the module is not installed', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.del('/nodes/foo')
.expect(404)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
- getModuleInfo.restore();
if (err) {
throw err;
}
@@ -387,27 +395,18 @@ describe("nodes api", function() {
});
it('fails the uninstall if the module is not installed', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.del('/nodes/foo')
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
- getModuleInfo.restore();
- uninstallModule.restore();
if (err) {
throw err;
}
@@ -421,14 +420,13 @@ describe("nodes api", function() {
describe('enable/disable', function() {
it('returns 400 if settings are unavailable', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return false;
+ initNodes({
+ settings:{available:function(){return false}}
});
request(app)
.put('/nodes/123')
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
if (err) {
throw err;
}
@@ -437,16 +435,14 @@ describe("nodes api", function() {
});
it('returns 400 for invalid node payload', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ settings:{available:function(){return true}}
});
-
request(app)
.put('/nodes/node-red/foo')
.send({})
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
if (err) {
throw err;
}
@@ -456,16 +452,14 @@ describe("nodes api", function() {
});
it('returns 400 for invalid module payload', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ settings:{available:function(){return true}}
});
-
request(app)
.put('/nodes/foo')
.send({})
.expect(400)
.end(function(err,res) {
- settingsAvailable.restore();
if (err) {
throw err;
}
@@ -476,11 +470,11 @@ describe("nodes api", function() {
});
it('returns 404 for unknown node', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
- return null;
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getNodeInfo: function() { return null }
+ }
});
request(app)
@@ -488,8 +482,6 @@ describe("nodes api", function() {
.send({enabled:false})
.expect(404)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
if (err) {
throw err;
}
@@ -498,11 +490,11 @@ describe("nodes api", function() {
});
it('returns 404 for unknown module', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
- return null;
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getModuleInfo: function(id) { return null }
+ }
});
request(app)
@@ -510,8 +502,6 @@ describe("nodes api", function() {
.send({enabled:false})
.expect(404)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
if (err) {
throw err;
}
@@ -520,24 +510,18 @@ describe("nodes api", function() {
});
it('enables disabled node', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.put('/nodes/node-red/foo')
.send({enabled:true})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
- enableNode.restore();
if (err) {
throw err;
}
@@ -549,24 +533,18 @@ describe("nodes api", function() {
});
it('disables enabled node', function(done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
+ initNodes({
+ 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)
.put('/nodes/node-red/foo')
.send({enabled:false})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
- disableNode.restore();
if (err) {
throw err;
}
@@ -579,31 +557,24 @@ describe("nodes api", function() {
describe('no-ops if already in the right state', function() {
function run(state,done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- 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 enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) });
+ var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) });
- var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
- return when.resolve({id:"123",enabled: false,types:['a']});
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getNodeInfo: function() { return {id:"123",enabled: state} },
+ enableNode: enableNode,
+ disableNode: disableNode
+ }
});
-
request(app)
.put('/nodes/node-red/foo')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
var enableNodeCalled = enableNode.called;
var disableNodeCalled = disableNode.called;
- enableNode.restore();
- disableNode.restore();
if (err) {
throw err;
}
@@ -625,31 +596,24 @@ describe("nodes api", function() {
describe('does not no-op if err on node', function() {
function run(state,done) {
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- 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 enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) });
+ var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) });
- var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
- return when.resolve({id:"123",enabled: false,types:['a']});
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getNodeInfo: function() { return {id:"123",enabled: state, err:"foo"} },
+ enableNode: enableNode,
+ disableNode: disableNode
+ }
});
-
request(app)
.put('/nodes/node-red/foo')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getNodeInfo.restore();
var enableNodeCalled = enableNode.called;
var disableNodeCalled = disableNode.called;
- enableNode.restore();
- disableNode.restore();
if (err) {
throw err;
}
@@ -672,14 +636,7 @@ describe("nodes api", function() {
it('enables disabled module', function(done) {
var n1 = {id:"123",enabled:false,types:['a']};
var n2 = {id:"456",enabled:false,types:['b']};
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(name) {
- return {name:"node-red", nodes:[n1, n2]};
- });
-
- var enableNode = sinon.stub(redNodes,'enableNode');
+ var enableNode = sinon.stub();
enableNode.onFirstCall().returns((function() {
n1.enabled = true;
return when.resolve(n1);
@@ -689,15 +646,19 @@ describe("nodes api", function() {
return when.resolve(n2);
})());
enableNode.returns(null);
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} },
+ enableNode: enableNode
+ }
+ });
request(app)
.put('/nodes/node-red')
.send({enabled:true})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- enableNode.restore();
if (err) {
throw err;
}
@@ -713,14 +674,7 @@ describe("nodes api", function() {
it('disables enabled module', function(done) {
var n1 = {id:"123",enabled:true,types:['a']};
var n2 = {id:"456",enabled:true,types:['b']};
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(name) {
- return {name:"node-red", nodes:[n1, n2]};
- });
-
- var disableNode = sinon.stub(redNodes,'disableNode');
+ var disableNode = sinon.stub();
disableNode.onFirstCall().returns((function() {
n1.enabled = false;
return when.resolve(n1);
@@ -730,15 +684,19 @@ describe("nodes api", function() {
return when.resolve(n2);
})());
disableNode.returns(null);
+ initNodes({
+ settings:{available:function(){return true}},
+ api:{
+ getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} },
+ disableNode: disableNode
+ }
+ });
request(app)
.put('/nodes/node-red')
.send({enabled:false})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
- disableNode.restore();
if (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() {
function run(state,done) {
var node = {id:"123",enabled:state,types:['a']};
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
- return {name:"node-red", nodes:[node]};
- });
- var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
+ var enableNode = sinon.spy(function(id) {
node.enabled = true;
return when.resolve(node);
});
- var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
+ var disableNode = sinon.spy(function(id) {
node.enabled = false;
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)
.put('/nodes/node-red')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
var enableNodeCalled = enableNode.called;
var disableNodeCalled = disableNode.called;
- enableNode.restore();
- disableNode.restore();
if (err) {
throw err;
}
@@ -803,32 +759,31 @@ describe("nodes api", function() {
describe('does not no-op if err on a node in module', function() {
function run(state,done) {
var node = {id:"123",enabled:state,types:['a'],err:"foo"};
- var settingsAvailable = sinon.stub(settings,'available', function() {
- return true;
- });
- var getModuleInfo = sinon.stub(redNodes,'getModuleInfo',function(id) {
- return {name:"node-red", nodes:[node]};
- });
- var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
+ var enableNode = sinon.spy(function(id) {
node.enabled = true;
return when.resolve(node);
});
- var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
+ var disableNode = sinon.spy(function(id) {
node.enabled = false;
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)
.put('/nodes/node-red')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
- settingsAvailable.restore();
- getModuleInfo.restore();
var enableNodeCalled = enableNode.called;
var disableNodeCalled = disableNode.called;
- enableNode.restore();
- disableNode.restore();
if (err) {
throw err;
}
diff --git a/test/red/api/theme_spec.js b/test/red/api/theme_spec.js
index 6421bdbdd..00d400965 100644
--- a/test/red/api/theme_spec.js
+++ b/test/red/api/theme_spec.js
@@ -31,13 +31,13 @@ describe("theme handler", function() {
sinon.stub(fs,"statSync",function() { return true; });
});
afterEach(function() {
- theme.init({});
+ theme.init({settings:{}});
fs.statSync.restore();
});
it("applies the default theme", function() {
- var result = theme.init({});
+ var result = theme.init({settings:{}});
should.not.exist(result);
-
+
var context = theme.context();
context.should.have.a.property("page");
context.page.should.have.a.property("title","Node-RED");
@@ -45,12 +45,12 @@ describe("theme handler", function() {
context.should.have.a.property("header");
context.header.should.have.a.property("title","Node-RED");
context.header.should.have.a.property("image","red/images/node-red.png");
-
+
should.not.exist(theme.settings());
});
-
+
it("picks up custom theme", function() {
- var result = theme.init({
+ var result = theme.init({settings:{
editorTheme: {
page: {
title: "Test Page Title",
@@ -61,13 +61,13 @@ describe("theme handler", function() {
title: "Test Header Title",
image: "/absolute/path/to/header/image" // or null to remove image
},
-
+
deployButton: {
type:"simple",
label:"Save",
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-item-import-library": false,
"menu-item-export-library": false,
@@ -77,27 +77,27 @@ describe("theme handler", function() {
url: "http://example.com"
}
},
-
+
userMenu: false, // Hide the user-menu even if adminAuth is enabled
-
+
login: {
image: "/absolute/path/to/login/page/big/image" // a 256x256 image
- }
+ }
}
- });
+ }});
should.exist(result);
-
+
var context = theme.context();
context.should.have.a.property("page");
context.page.should.have.a.property("title","Test Page Title");
context.should.have.a.property("header");
context.header.should.have.a.property("title","Test Header Title");
-
+
var settings = theme.settings();
settings.should.have.a.property("deployButton");
settings.should.have.a.property("userMenu");
settings.should.have.a.property("menu");
-
+
});
-});
\ No newline at end of file
+});
diff --git a/test/red/api/ui_spec.js b/test/red/api/ui_spec.js
index b076c57e4..f68be04a4 100644
--- a/test/red/api/ui_spec.js
+++ b/test/red/api/ui_spec.js
@@ -20,14 +20,17 @@ var express = require("express");
var fs = require("fs");
var path = require("path");
-var events = require("../../../red/events");
+var EventEmitter = require('events').EventEmitter;
+var events = new EventEmitter();
var ui = require("../../../red/api/ui");
describe("ui api", function() {
var app;
-
+ before(function() {
+ ui.init({events:events});
+ });
describe("slash handler", function() {
before(function() {
app = express();
diff --git a/test/red/nodes/flows/Flow_spec.js b/test/red/nodes/flows/Flow_spec.js
index 727351930..5fca9fea7 100644
--- a/test/red/nodes/flows/Flow_spec.js
+++ b/test/red/nodes/flows/Flow_spec.js
@@ -959,7 +959,7 @@ describe('Flow', function() {
done();
});
});
- it("moves any existing error object sideways",function(){
+ it("moves any existing error object sideways",function(done){
var config = flowUtils.parseConfig([
{id:"t1",type:"tab"},
{id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]},
diff --git a/test/red/nodes/index_spec.js b/test/red/nodes/index_spec.js
index 3815e6795..a6c349f14 100644
--- a/test/red/nodes/index_spec.js
+++ b/test/red/nodes/index_spec.js
@@ -145,7 +145,7 @@ describe("red/nodes/index", function() {
var registry = require("../../../red/nodes/registry");
var randomNodeInfo = {id:"5678",types:["random"]};
- before(function() {
+ beforeEach(function() {
sinon.stub(registry,"getNodeInfo",function(id) {
if (id == "test") {
return {id:"1234",types:["test"]};
@@ -159,7 +159,7 @@ describe("red/nodes/index", function() {
return randomNodeInfo;
});
});
- after(function() {
+ afterEach(function() {
registry.getNodeInfo.restore();
registry.disableNode.restore();
});
diff --git a/test/red/server_spec.js b/test/red/runtime_spec.js
similarity index 77%
rename from test/red/server_spec.js
rename to test/red/runtime_spec.js
index 3211d3b3d..91d58bc89 100644
--- a/test/red/server_spec.js
+++ b/test/red/runtime_spec.js
@@ -20,18 +20,23 @@ var sinon = require("sinon");
var comms = require("../../red/comms");
var redNodes = require("../../red/nodes");
var api = require("../../red/api");
-var server = require("../../red/server");
+var runtime = require("../../red/runtime");
var storage = require("../../red/storage");
var settings = require("../../red/settings");
var log = require("../../red/log");
-describe("red/server", function() {
+describe("red/runtime", function() {
var commsMessages = [];
var commsPublish;
beforeEach(function() {
commsMessages = [];
});
+ afterEach(function() {
+ if (console.log.restore) {
+ console.log.restore();
+ }
+ })
before(function() {
commsPublish = sinon.stub(comms,"publish", function(topic,msg,retained) {
@@ -42,26 +47,48 @@ describe("red/server", function() {
commsPublish.restore();
});
- it("initialises components", function() {
- var commsInit = sinon.stub(comms,"init",function() {});
- var dummyServer = {};
- server.init(dummyServer,{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
+ describe("init", function() {
+ var commsInit;
+ var apiInit;
+ 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(server.nodeApp);
+ should.exist(runtime.app);
+ 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() {
var commsInit;
var storageInit;
var settingsLoad;
- var apiInit;
var logMetric;
var logWarn;
var logInfo;
@@ -77,7 +104,6 @@ describe("red/server", function() {
beforeEach(function() {
commsInit = sinon.stub(comms,"init",function() {});
storageInit = sinon.stub(storage,"init",function(settings) {return when.resolve();});
- apiInit = sinon.stub(api,"init",function() {});
logMetric = sinon.stub(log,"metric",function() { return false; });
logWarn = sinon.stub(log,"warn",function() { });
logInfo = sinon.stub(log,"info",function() { });
@@ -92,7 +118,6 @@ describe("red/server", function() {
afterEach(function() {
commsInit.restore();
storageInit.restore();
- apiInit.restore();
logMetric.restore();
logWarn.restore();
logInfo.restore();
@@ -112,10 +137,11 @@ describe("red/server", function() {
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
].filter(cb);
});
- server.init({},{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
- server.start().then(function() {
+ runtime.init({},{testSettings: true, httpAdminRoot:"/", load:function() { return when.resolve();}});
+ sinon.stub(console,"log");
+ runtime.start().then(function() {
+ console.log.restore();
try {
- apiInit.calledOnce.should.be.true;
storageInit.calledOnce.should.be.true;
redNodesInit.calledOnce.should.be.true;
redNodesLoad.calledOnce.should.be.true;
@@ -142,10 +168,11 @@ describe("red/server", function() {
].filter(cb);
});
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return when.resolve();});
- server.init({},{testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
- server.start().then(function() {
+ runtime.init({},{testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
+ sinon.stub(console,"log");
+ runtime.start().then(function() {
+ console.log.restore();
try {
- apiInit.calledOnce.should.be.true;
logWarn.calledWithMatch("Failed to register 2 node types");
logWarn.calledWithMatch("Missing node modules");
logWarn.calledWithMatch(" - module: typeA, typeB");
@@ -167,11 +194,11 @@ describe("red/server", function() {
{ err:"errored",name:"errName" } // error
].filter(cb);
});
- server.init({},{testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
- server.start().then(function() {
-
+ runtime.init({},{testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return when.resolve();}});
+ sinon.stub(console,"log");
+ runtime.start().then(function() {
+ console.log.restore();
try {
- apiInit.calledOnce.should.be.true;
logWarn.neverCalledWithMatch("Failed to register 1 node type");
logWarn.calledWithMatch("[errName] errored");
done();
@@ -187,11 +214,12 @@ describe("red/server", function() {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
logMetric.restore();
logMetric = sinon.stub(log,"metric",function() { return true; });
- server.init({},{testSettings: true, runtimeMetricInterval:400, httpAdminRoot:"/", load:function() { return when.resolve();}});
- server.start().then(function() {
+ runtime.init({},{testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return when.resolve();}});
+ sinon.stub(console,"log");
+ runtime.start().then(function() {
+ console.log.restore();
setTimeout(function() {
try {
- apiInit.calledOnce.should.be.true;
logLog.args.should.have.lengthOf(3);
logLog.args[0][0].should.have.property("level",log.METRIC);
logLog.args[0][0].should.have.property("event","runtime.memory.rss");
@@ -203,35 +231,22 @@ describe("red/server", function() {
} catch(err) {
done(err);
} finally {
- server.stop();
+ runtime.stop();
commsStop.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() {
var commsStop = sinon.stub(comms,"stop",function() {} );
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
- server.stop();
+ runtime.stop();
commsStop.called.should.be.true;
stopFlows.called.should.be.true;
diff --git a/test/red/settings_spec.js b/test/red/settings_spec.js
index 7e7e3f4b2..bf1b05df5 100644
--- a/test/red/settings_spec.js
+++ b/test/red/settings_spec.js
@@ -20,11 +20,11 @@ var settings = require("../../red/settings");
describe("red/settings", function() {
-
+
afterEach(function() {
settings.reset();
});
-
+
it('wraps the user settings as read-only properties', function() {
var userSettings = {
a: 123,
@@ -32,22 +32,22 @@ describe("red/settings", function() {
c: [1,2,3]
}
settings.init(userSettings);
-
+
settings.available().should.be.false;
-
+
settings.a.should.equal(123);
settings.b.should.equal("test");
settings.c.should.be.an.Array.with.lengthOf(3);
-
+
settings.get("a").should.equal(123);
settings.get("b").should.equal("test");
settings.get("c").should.be.an.Array.with.lengthOf(3);
-
+
/*jshint immed: false */
(function() {
settings.a = 456;
}).should.throw();
-
+
settings.c.push(5);
settings.c.should.be.an.Array.with.lengthOf(4);
@@ -55,7 +55,7 @@ describe("red/settings", function() {
(function() {
settings.set("a",456);
}).should.throw();
-
+
/*jshint immed: false */
(function() {
settings.set("a",456);
@@ -70,9 +70,9 @@ describe("red/settings", function() {
(function() {
settings.set("unknown",456);
}).should.throw();
-
+
});
-
+
it('loads global settings from storage', function(done) {
var userSettings = {
a: 123,
@@ -94,7 +94,7 @@ describe("red/settings", function() {
settings.init(userSettings);
settings.available().should.be.false;
-
+
/*jshint immed: false */
(function() {
settings.get("unknown");
@@ -117,7 +117,7 @@ describe("red/settings", function() {
done(err);
});
});
-
+
it('removes persistent settings when reset', function() {
var userSettings = {
a: 123,
@@ -125,18 +125,18 @@ describe("red/settings", function() {
c: [1,2,3]
}
settings.init(userSettings);
-
+
settings.available().should.be.false;
-
+
settings.should.have.property("a",123);
settings.should.have.property("b","test");
settings.c.should.be.an.Array.with.lengthOf(3);
-
+
settings.reset();
-
+
settings.should.not.have.property("a");
settings.should.not.have.property("d");
settings.should.not.have.property("c");
-
+
});
});