Separated put response into /nodes/:mod and /nodes/:mod/:set

Updated put tests
This commit is contained in:
Anna Thomas 2014-11-21 10:36:32 +00:00
parent d614b7c39f
commit 56cb985de9
4 changed files with 299 additions and 20 deletions

View File

@ -53,10 +53,11 @@ function init(adminApp) {
adminApp.post("/nodes",nodes.post);
adminApp.get("/nodes/:mod",nodes.getModule);
adminApp.put("/nodes/:id",nodes.put);
adminApp.put("/nodes/:mod",nodes.putModule);
adminApp.delete("/nodes/:id",nodes.delete);
adminApp.get("/nodes/:mod/:set",nodes.getSet);
adminApp.put("/nodes/:mod/:set",nodes.putSet);
// Plugins
adminApp.get("/plugins",plugins.getAll);

View File

@ -122,7 +122,7 @@ module.exports = {
}
},
put: function(req,res) {
putSet: function(req,res) {
if (!settings.available()) {
res.send(400,new Error("Settings unavailable").toString());
return;
@ -133,9 +133,9 @@ module.exports = {
return;
}
try {
var info;
var id = req.params.id;
var id = req.params.mod+"/"+req.params.set;
var node = redNodes.getNodeInfo(id);
var info;
if (!node) {
res.send(404);
} else if (!node.err && node.enabled === body.enabled) {
@ -161,5 +161,50 @@ module.exports = {
} catch(err) {
res.send(400,err.toString());
}
},
putModule: function(req,res) {
if (!settings.available()) {
res.send(400,new Error("Settings unavailable").toString());
return;
}
var body = req.body;
if (!body.hasOwnProperty("enabled")) {
res.send(400,"Invalid request");
return;
}
try {
var mod = req.params.mod;
var module = redNodes.getModuleInfo(mod);
if (!module) {
res.send(404);
return;
}
var nodes = module.nodes;
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
var info;
if (node.err || node.enabled !== body.enabled) {
if (body.enabled) {
info = redNodes.enableNode(node.id);
} else {
info = redNodes.disableNode(node.id);
}
if (info.enabled === body.enabled && !info.err) {
comms.publish("node/"+(body.enabled?"enabled":"disabled"),info,false);
util.log("[red] "+(body.enabled?"Enabled":"Disabled")+" node types:");
for (var j = 0; j < info.types.length; j++) {
util.log("[red] - " + info.types[j]);
}
} else if (body.enabled && info.err) {
util.log("[red] Failed to enable node:");
util.log("[red] - "+info.name+" : "+info.err);
}
}
}
res.json(module);
} catch(err) {
res.send(400,err.toString());
}
}
};

View File

@ -149,8 +149,9 @@ var registry = (function() {
return filterNodeInfo(nodeConfigs[nodeTypeToId[typeOrId]]);
} else if (nodeConfigs[typeOrId]) {
return filterNodeInfo(nodeConfigs[typeOrId]);
} else {
return null;
}
return null;
},
getNodeList: function() {
var list = [];
@ -179,15 +180,20 @@ var registry = (function() {
return list;
},
getModuleInfo: function(module) {
var nodes = nodeModules[module].nodes;
var m = {
name: module,
nodes: []
};
for (var i = 0; i < nodes.length; ++i) {
m.nodes.push(filterNodeInfo(nodeConfigs[module+"/"+nodes[i]]));
if (nodeModules[module]) {
var nodes = nodeModules[module].nodes;
var m = {
name: module,
version: "TODO",
nodes: []
};
for (var i = 0; i < nodes.length; ++i) {
m.nodes.push(filterNodeInfo(nodeConfigs[module+"/"+nodes[i]]));
}
return m;
} else {
return null;
}
return m;
},
registerNodeConstructor: function(type,constructor) {
if (nodeConstructors[type]) {

View File

@ -38,7 +38,8 @@ describe("nodes api", function() {
app.post("/nodes",nodes.post);
app.get("/nodes/:mod",nodes.getModule);
app.get("/nodes/:mod/:set",nodes.getSet);
app.put("/nodes/:id",nodes.put);
app.put("/nodes/:mod",nodes.putModule);
app.put("/nodes/:mod/:set",nodes.putSet);
app.delete("/nodes/:id",nodes.delete);
});
@ -433,7 +434,27 @@ describe("nodes api", function() {
});
});
it('returns 400 for invalid payload', function(done) {
it('returns 400 for invalid node payload', function(done) {
var settingsAvailable = sinon.stub(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;
}
res.text.should.equal("Invalid request");
done();
});
});
it('returns 400 for invalid module payload', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
@ -452,6 +473,7 @@ describe("nodes api", function() {
done();
});
});
it('returns 404 for unknown node', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
@ -461,7 +483,7 @@ describe("nodes api", function() {
});
request(app)
.put('/nodes/foo')
.put('/nodes/node-red/foo')
.send({enabled:false})
.expect(404)
.end(function(err,res) {
@ -474,6 +496,28 @@ 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;
});
request(app)
.put('/nodes/node-blue')
.send({enabled:false})
.expect(404)
.end(function(err,res) {
settingsAvailable.restore();
getModuleInfo.restore();
if (err) {
throw err;
}
done();
});
});
it('enables disabled node', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
@ -486,7 +530,7 @@ describe("nodes api", function() {
});
request(app)
.put('/nodes/foo')
.put('/nodes/node-red/foo')
.send({enabled:true})
.expect(200)
.end(function(err,res) {
@ -502,6 +546,7 @@ describe("nodes api", function() {
done();
});
});
it('disables enabled node', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
@ -514,7 +559,7 @@ describe("nodes api", function() {
});
request(app)
.put('/nodes/foo')
.put('/nodes/node-red/foo')
.send({enabled:false})
.expect(200)
.end(function(err,res) {
@ -530,6 +575,7 @@ describe("nodes api", function() {
done();
});
});
describe('no-ops if already in the right state', function() {
function run(state,done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
@ -547,7 +593,7 @@ describe("nodes api", function() {
});
request(app)
.put('/nodes/foo')
.put('/nodes/node-red/foo')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
@ -575,6 +621,7 @@ describe("nodes api", function() {
run(false,done);
});
});
describe('does not no-op if err on node', function() {
function run(state,done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
@ -592,7 +639,7 @@ describe("nodes api", function() {
});
request(app)
.put('/nodes/foo')
.put('/nodes/node-red/foo')
.send({enabled:state})
.expect(200)
.end(function(err,res) {
@ -620,6 +667,186 @@ describe("nodes api", function() {
run(false,done);
});
});
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');
enableNode.onFirstCall().returns((function() {
n1.enabled = true;
return n1;
})());
enableNode.onSecondCall().returns((function() {
n2.enabled = true;
return n2;
})());
enableNode.returns(null);
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;
}
res.body.should.have.property("name","node-red");
res.body.should.have.property("nodes");
res.body.nodes[0].should.have.property("enabled",true);
res.body.nodes[1].should.have.property("enabled",true);
done();
});
});
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');
disableNode.onFirstCall().returns((function() {
n1.enabled = false;
return n1;
})());
disableNode.onSecondCall().returns((function() {
n2.enabled = false;
return n2;
})());
disableNode.returns(null);
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;
}
res.body.should.have.property("name","node-red");
res.body.should.have.property("nodes");
res.body.nodes[0].should.have.property("enabled",false);
res.body.nodes[1].should.have.property("enabled",false);
done();
});
});
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) {
node.enabled = true;
return node;
});
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
node.enabled = false;
return node;
});
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;
}
enableNodeCalled.should.be.false;
disableNodeCalled.should.be.false;
res.body.should.have.property("name","node-red");
res.body.should.have.property("nodes");
res.body.nodes[0].should.have.property("enabled",state);
done();
});
}
it('already enabled', function(done) {
run(true,done);
});
it('already disabled', function(done) {
run(false,done);
});
});
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) {
node.enabled = true;
return node;
});
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
node.enabled = false;
return node;
});
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;
}
enableNodeCalled.should.be.equal(state);
disableNodeCalled.should.be.equal(!state);
res.body.should.have.property("name","node-red");
res.body.should.have.property("nodes");
res.body.nodes[0].should.have.property("enabled",state);
done();
});
}
it('already enabled', function(done) {
run(true,done);
});
it('already disabled', function(done) {
run(false,done);
});
});
});