mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
WIP: separate runtime and api components
This commit is contained in:
@@ -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();
|
||||
|
@@ -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"});
|
||||
|
@@ -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")
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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("/")
|
||||
|
@@ -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();
|
||||
});
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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 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 "<script></script>";
|
||||
initNodes({
|
||||
api:{
|
||||
getNodeConfigs: function() {
|
||||
return "<script></script>";
|
||||
}
|
||||
},
|
||||
i18n: {
|
||||
determineLangFromHeaders: function(){}
|
||||
}
|
||||
});
|
||||
request(app)
|
||||
.get('/nodes')
|
||||
@@ -71,7 +90,6 @@ describe("nodes api", function() {
|
||||
.expect(200)
|
||||
.expect("<script></script>")
|
||||
.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":"<script></script>"}[id];
|
||||
initNodes({
|
||||
api:{
|
||||
getNodeConfig: function(id) {
|
||||
return {"node-red/123":"<script></script>"}[id];
|
||||
}
|
||||
},
|
||||
i18n: {
|
||||
determineLangFromHeaders: function(){}
|
||||
}
|
||||
});
|
||||
request(app)
|
||||
.get('/nodes/node-red/123')
|
||||
@@ -140,7 +174,6 @@ describe("nodes api", function() {
|
||||
.expect(200)
|
||||
.expect("<script></script>")
|
||||
.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;
|
||||
}
|
||||
|
@@ -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");
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@@ -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();
|
||||
|
@@ -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"]},
|
||||
|
@@ -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();
|
||||
});
|
||||
|
@@ -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;
|
@@ -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");
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user