Add unit tests for refactored API modules

This commit is contained in:
Nick O'Leary
2014-11-04 17:05:29 +00:00
parent 72f9471f2b
commit e7eb02fcb7
16 changed files with 1352 additions and 318 deletions

View File

@@ -0,0 +1,91 @@
/**
* Copyright 2014 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.
**/
var should = require("should");
var request = require('supertest');
var express = require('express');
var sinon = require('sinon');
var when = require('when');
var app = express();
var redNodes = require("../../../red/nodes");
var flows = require("../../../red/api/flows");
describe("flows api", function() {
var app;
before(function() {
app = express();
app.use(express.json());
app.get("/flows",flows.get);
app.post("/flows",flows.post);
});
it('returns flow', function(done) {
var getFlows = sinon.stub(redNodes,'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;
}
res.body.should.be.an.Array.and.have.lengthOf(3);
done();
});
});
it('sets flows', function(done) {
var setFlows = sinon.stub(redNodes,'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;
}
done();
});
});
it('returns error when set fails', function(done) {
var setFlows = sinon.stub(redNodes,'setFlows', function() {
return when.reject(new Error("test error"));
});
request(app)
.post('/flows')
.set('Accept', 'application/json')
.expect(500)
.end(function(err,res) {
setFlows.restore();
if (err) {
throw err;
}
res.text.should.eql("test error");
done();
});
});
});

View File

@@ -0,0 +1,93 @@
/**
* Copyright 2014 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.
**/
var should = require("should");
var request = require("supertest");
var express = require("express");
var fs = require("fs");
var path = require("path");
var settings = require("../../../red/settings");
var api = require("../../../red/api");
describe("api index", function() {
var app;
describe("disables editor", function() {
before(function() {
settings.init({disableEditor:true});
app = express();
api.init(app);
});
after(function() {
settings.reset();
});
it('does not serve the editor', function(done) {
request(app)
.get("/")
.expect(404,done)
});
it('does not serve icons', function(done) {
request(app)
.get("/icons/default.png")
.expect(404,done)
});
it('does not serve settings', function(done) {
request(app)
.get("/settings")
.expect(404,done)
});
});
describe("enables editor", function() {
before(function() {
settings.init({disableEditor:false});
app = express();
api.init(app);
});
after(function() {
settings.reset();
});
it('serves the editor', function(done) {
request(app)
.get("/")
.expect(200)
.end(function(err,res) {
if (err) {
return done(err);
}
// Index page should probably mention Node-RED somewhere
res.text.indexOf("Node-RED").should.not.eql(-1);
done();
});
});
it('serves icons', function(done) {
request(app)
.get("/icons/inject.png")
.expect("Content-Type", /image\/png/)
.expect(200,done)
});
it('serves settings', function(done) {
request(app)
.get("/settings")
.expect(200,done)
});
});
});

View File

@@ -0,0 +1,259 @@
/**
* Copyright 2014 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.
**/
var should = require("should");
var request = require('supertest');
var express = require('express');
var when = require('when');
var app = express();
var RED = require("../../../red/red.js");
var storage = require("../../../red/storage");
var library = require("../../../red/api/library");
describe("library api", function() {
function initStorage(_flows,_libraryEntries) {
var flows = _flows;
var libraryEntries = _libraryEntries;
storage.init({
storageModule: {
init: function() {
return when.resolve();
},
getAllFlows: function() {
return when.resolve(flows);
},
getFlow: function(fn) {
if (flows[fn]) {
return when.resolve(flows[fn]);
} else {
return when.reject();
}
},
saveFlow: function(fn,data) {
flows[fn] = data;
return when.resolve();
},
getLibraryEntry: function(type,path) {
if (libraryEntries[type] && libraryEntries[type][path]) {
return when.resolve(libraryEntries[type][path]);
} else {
return when.reject();
}
},
saveLibraryEntry: function(type,path,meta,body) {
libraryEntries[type][path] = body;
return when.resolve();
}
}
});
}
describe("flows", function() {
var app;
before(function() {
app = express();
app.use(express.json());
app.get("/library/flows",library.getAll);
app.post(new RegExp("/library/flows\/(.*)"),library.post);
app.get(new RegExp("/library/flows\/(.*)"),library.get);
});
it('returns empty result', function(done) {
initStorage({});
request(app)
.get('/library/flows')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
res.body.should.not.have.property('f');
res.body.should.not.have.property('d');
done();
});
});
it('returns 404 for non-existent entry', function(done) {
initStorage({});
request(app)
.get('/library/flows/foo')
.expect(404)
.end(done);
});
it('can store and retrieve item', function(done) {
initStorage({});
var flow = '[]';
request(app)
.post('/library/flows/foo')
.set('Content-Type', 'text/plain')
.send(flow)
.expect(204).end(function (err, res) {
if (err) {
throw err;
}
request(app)
.get('/library/flows/foo')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
res.text.should.equal(flow);
done();
});
});
});
it('lists a stored item', function(done) {
initStorage({f:["bar"]});
request(app)
.get('/library/flows')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
res.body.should.have.property('f');
should.deepEqual(res.body.f,['bar']);
done();
});
});
it('returns 403 for malicious get attempt', function(done) {
initStorage({});
// 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.
request(app)
.get('/library/flows/../../../../../package')
.expect(403)
.end(done);
});
it('returns 403 for malicious post attempt', function(done) {
initStorage({});
// 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.
request(app)
.post('/library/flows/../../../../../package')
.expect(403)
.end(done);
});
});
describe("type", function() {
var app;
before(function() {
app = express();
app.use(express.json());
library.init(app);
RED.library.register("test");
});
it('returns empty result', function(done) {
initStorage({},{'test':{"":[]}});
request(app)
.get('/library/test')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
res.body.should.not.have.property('f');
done();
});
});
it('returns 404 for non-existent entry', function(done) {
initStorage({},{});
request(app)
.get('/library/test/foo')
.expect(404)
.end(done);
});
it('can store and retrieve item', function(done) {
initStorage({},{'test':{}});
var flow = '[]';
request(app)
.post('/library/test/foo')
.set('Content-Type', 'text/plain')
.send(flow)
.expect(204).end(function (err, res) {
if (err) {
throw err;
}
request(app)
.get('/library/test/foo')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
res.text.should.equal(flow);
done();
});
});
});
it('lists a stored item', function(done) {
initStorage({},{'test':{'':['abc','def']}});
request(app)
.get('/library/test')
.expect(200)
.end(function(err,res) {
if (err) {
throw err;
}
// This response isn't strictly accurate - but it
// verifies the api returns what storage gave it
should.deepEqual(res.body,['abc','def']);
done();
});
});
it('returns 403 for malicious access attempt', function(done) {
request(app)
.get('/library/test/../../../../../../../../../../etc/passwd')
.expect(403)
.end(done);
});
it('returns 403 for malicious access attempt', function(done) {
request(app)
.get('/library/test/..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\etc\\passwd')
.expect(403)
.end(done);
});
it('returns 403 for malicious access attempt', function(done) {
request(app)
.post('/library/test/../../../../../../../../../../etc/passwd')
.set('Content-Type', 'text/plain')
.send('root:x:0:0:root:/root:/usr/bin/tclsh')
.expect(403)
.end(done);
});
});
});

575
test/red/api/nodes_spec.js Normal file
View File

@@ -0,0 +1,575 @@
/**
* Copyright 2014 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.
**/
var should = require("should");
var request = require('supertest');
var express = require('express');
var sinon = require('sinon');
var when = require('when');
var app = express();
var redNodes = require("../../../red/nodes");
var server = require("../../../red/server");
var settings = require("../../../red/settings");
var nodes = require("../../../red/api/nodes");
describe("nodes api", function() {
var app;
before(function() {
app = express();
app.use(express.json());
app.get("/nodes",nodes.getAll);
app.post("/nodes",nodes.post);
app.get("/nodes/:id",nodes.get);
app.put("/nodes/:id",nodes.put);
app.delete("/nodes/:id",nodes.delete);
});
describe('get nodes', function() {
it('returns node list', function(done) {
var getNodeList = sinon.stub(redNodes,'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;
}
res.body.should.be.an.Array.and.have.lengthOf(3);
done();
});
});
it('returns node configs', function(done) {
var getNodeConfigs = sinon.stub(redNodes,'getNodeConfigs', function() {
return "<script></script>";
});
request(app)
.get('/nodes')
.set('Accept', 'text/html')
.expect(200)
.expect("<script></script>")
.end(function(err,res) {
getNodeConfigs.restore();
if (err) {
throw err;
}
done();
});
});
it('returns an individual node info', function(done) {
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
return {"123":{id:"123"}}[id];
});
request(app)
.get('/nodes/123')
.set('Accept', 'application/json')
.expect(200)
.end(function(err,res) {
getNodeInfo.restore();
if (err) {
throw err;
}
res.body.should.have.property("id","123");
done();
});
});
it('returns an individual node configs', function(done) {
var getNodeConfig = sinon.stub(redNodes,'getNodeConfig', function(id) {
return {"123":"<script></script>"}[id];
});
request(app)
.get('/nodes/123')
.set('Accept', 'text/html')
.expect(200)
.expect("<script></script>")
.end(function(err,res) {
getNodeConfig.restore();
if (err) {
throw err;
}
done();
});
});
it('returns 404 for unknown node', function(done) {
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo', function(id) {
return {"123":{id:"123"}}[id];
});
request(app)
.get('/nodes/456')
.set('Accept', 'application/json')
.expect(404)
.end(function(err,res) {
getNodeInfo.restore();
if (err) {
throw err;
}
done();
});
});
});
describe('install', function() {
it('returns 400 if settings are unavailable', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return false;
});
request(app)
.post('/nodes')
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
if (err) {
throw err;
}
done();
});
});
describe('by module', function() {
it('installs the module and returns node info', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return null;
});
var installModule = sinon.stub(server,'installModule', function() {
return when.resolve({id:"123"});
});
request(app)
.post('/nodes')
.send({module: 'foo'})
.expect(200)
.end(function(err,res) {
settingsAvailable.restore();
getNodeModuleInfo.restore();
installModule.restore();
if (err) {
throw err;
}
res.body.should.have.property("id","123");
done();
});
});
it('fails the install if already installed', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return {id:"123"};
});
var installModule = sinon.stub(server,'installModule', function() {
return when.resolve({id:"123"});
});
request(app)
.post('/nodes')
.send({module: 'foo'})
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
getNodeModuleInfo.restore();
installModule.restore();
if (err) {
throw err;
}
done();
});
});
it('fails the install if module error', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return null;
});
var installModule = sinon.stub(server,'installModule', function() {
return when.reject(new Error("test error"));
});
request(app)
.post('/nodes')
.send({module: 'foo'})
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
getNodeModuleInfo.restore();
installModule.restore();
if (err) {
throw err;
}
res.text.should.equal("Error: test error");
done();
});
});
it('fails the install if module not found', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return null;
});
var installModule = sinon.stub(server,'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();
getNodeModuleInfo.restore();
installModule.restore();
if (err) {
throw err;
}
done();
});
});
});
});
describe('delete', function() {
it('returns 400 if settings are unavailable', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return false;
});
request(app)
.del('/nodes/123')
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
if (err) {
throw err;
}
done();
});
});
describe('by module', function() {
it('uninstalls the module and returns node info', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
return null;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return {id:"123"};
});
var uninstallModule = sinon.stub(server,'uninstallModule', function() {
return when.resolve({id:"123"});
});
request(app)
.del('/nodes/foo')
.expect(200)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
getNodeModuleInfo.restore();
uninstallModule.restore();
if (err) {
throw err;
}
res.body.should.have.property("id","123");
done();
});
});
it('fails the uninstall if the module is not installed', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
return null;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return null;
});
request(app)
.del('/nodes/foo')
.expect(404)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
getNodeModuleInfo.restore();
if (err) {
throw err;
}
done();
});
});
it('fails the uninstall if the module is not installed', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
return null;
});
var getNodeModuleInfo = sinon.stub(redNodes,'getNodeModuleInfo',function(id) {
return {id:"123"};
});
var uninstallModule = sinon.stub(server,'uninstallModule', function() {
return when.reject(new Error("test error"));
});
request(app)
.del('/nodes/foo')
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
getNodeModuleInfo.restore();
uninstallModule.restore();
if (err) {
throw err;
}
res.text.should.equal("Error: test error");
done();
});
});
});
});
describe('enable/disable', function() {
it('returns 400 if settings are unavailable', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return false;
});
request(app)
.put('/nodes/123')
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
if (err) {
throw err;
}
done();
});
});
it('returns 400 for invalid payload', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
request(app)
.put('/nodes/foo')
.send({})
.expect(400)
.end(function(err,res) {
settingsAvailable.restore();
if (err) {
throw err;
}
res.text.should.equal("Invalid request");
done();
});
});
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;
});
request(app)
.put('/nodes/foo')
.send({enabled:false})
.expect(404)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
if (err) {
throw err;
}
done();
});
});
it('enables disabled node', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
return {id:"123",enabled: false};
});
var enableNode = sinon.stub(redNodes,'enableNode',function(id) {
return {id:"123",enabled: true,types:['a']};
});
request(app)
.put('/nodes/foo')
.send({enabled:true})
.expect(200)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
enableNode.restore();
if (err) {
throw err;
}
res.body.should.have.property("id","123");
res.body.should.have.property("enabled",true);
done();
});
});
it('disables enabled node', function(done) {
var settingsAvailable = sinon.stub(settings,'available', function() {
return true;
});
var getNodeInfo = sinon.stub(redNodes,'getNodeInfo',function(id) {
return {id:"123",enabled: true};
});
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
return {id:"123",enabled: false,types:['a']};
});
request(app)
.put('/nodes/foo')
.send({enabled:false})
.expect(200)
.end(function(err,res) {
settingsAvailable.restore();
getNodeInfo.restore();
disableNode.restore();
if (err) {
throw err;
}
res.body.should.have.property("id","123");
res.body.should.have.property("enabled",false);
done();
});
});
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 {id:"123",enabled: true,types:['a']};
});
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
return {id:"123",enabled: false,types:['a']};
});
request(app)
.put('/nodes/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;
}
enableNodeCalled.should.be.false;
disableNodeCalled.should.be.false;
res.body.should.have.property("id","123");
res.body.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 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 {id:"123",enabled: true,types:['a']};
});
var disableNode = sinon.stub(redNodes,'disableNode',function(id) {
return {id:"123",enabled: false,types:['a']};
});
request(app)
.put('/nodes/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;
}
enableNodeCalled.should.be.equal(state);
disableNodeCalled.should.be.equal(!state);
res.body.should.have.property("id","123");
res.body.should.have.property("enabled",state);
done();
});
}
it('already enabled', function(done) {
run(true,done);
});
it('already disabled', function(done) {
run(false,done);
});
});
});
});

183
test/red/api/ui_spec.js Normal file
View File

@@ -0,0 +1,183 @@
/**
* Copyright 2014 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.
**/
var should = require("should");
var request = require("supertest");
var express = require("express");
var fs = require("fs");
var path = require("path");
var settings = require("../../../red/settings");
var events = require("../../../red/events");
var ui = require("../../../red/api/ui");
describe("ui api", function() {
var app;
describe("slash handler", function() {
before(function() {
app = express();
app.get("/foo",ui.ensureSlash,function(req,res) { res.send(200);});
});
it('redirects if the path does not end in a slash',function(done) {
request(app)
.get('/foo')
.expect(301,done);
});
it('does not redirect if the path ends in a slash',function(done) {
request(app)
.get('/foo/')
.expect(200,done);
});
});
describe("icon handler", function() {
before(function() {
app = express();
app.get("/icons/:icon",ui.icon);
});
function binaryParser(res, callback) {
res.setEncoding('binary');
res.data = '';
res.on('data', function (chunk) {
res.data += chunk;
});
res.on('end', function () {
callback(null, new Buffer(res.data, 'binary'));
});
}
function compareBuffers(b1,b2) {
b1.length.should.equal(b2.length);
for (var i=0;i<b1.length;i++) {
b1[i].should.equal(b2[i]);
}
}
it('returns the default icon when getting an unknown icon', function(done) {
var defaultIcon = fs.readFileSync(path.resolve(__dirname+'/../../../public/icons/arrow-in.png'));
request(app)
.get("/icons/youwonthaveme.png")
.expect("Content-Type", /image\/png/)
.expect(200)
.parse(binaryParser)
.end(function(err,res) {
if (err){
return done(err);
}
Buffer.isBuffer(res.body).should.be.true;
compareBuffers(res.body,defaultIcon);
done();
});
});
it('returns a known icon', function(done) {
var injectIcon = fs.readFileSync(path.resolve(__dirname+'/../../../public/icons/inject.png'));
request(app)
.get("/icons/inject.png")
.expect("Content-Type", /image\/png/)
.expect(200)
.parse(binaryParser)
.end(function(err, res){
if (err){
return done(err);
}
Buffer.isBuffer(res.body).should.be.true;
compareBuffers(res.body,injectIcon);
done();
});
});
it('returns a registered icon' , function(done) {
var testIcon = fs.readFileSync(path.resolve(__dirname+'/../../resources/icons/test_icon.png'));
events.emit("node-icon-dir", path.resolve(__dirname+'/../../resources/icons'));
request(app)
.get("/icons/test_icon.png")
.expect("Content-Type", /image\/png/)
.expect(200)
.parse(binaryParser)
.end(function(err, res){
if (err){
return done(err);
}
Buffer.isBuffer(res.body).should.be.true;
compareBuffers(res.body,testIcon);
done();
});
});
});
describe("settings handler", function() {
before(function() {
var userSettings = {
foo: 123,
httpNodeRoot: "testHttpNodeRoot",
version: "testVersion"
}
settings.init(userSettings);
app = express();
app.get("/settings",ui.settings);
//app.use("/",ui.editor);
});
after(function() {
settings.reset();
});
it('returns the filtered settings', function(done) {
request(app)
.get("/settings")
.expect(200)
.end(function(err,res) {
if (err) {
return done(err);
}
res.body.should.have.property("httpNodeRoot","testHttpNodeRoot");
res.body.should.have.property("version","testVersion");
res.body.should.not.have.property("foo",123);
done();
});
});
});
describe("editor ui handler", function() {
before(function() {
app = express();
app.use("/",ui.editor);
});
it('serves the editor', function(done) {
request(app)
.get("/")
.expect(200)
.end(function(err,res) {
if (err) {
return done(err);
}
// Index page should probably mention Node-RED somewhere
res.text.indexOf("Node-RED").should.not.eql(-1);
done();
});
});
});
});