mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			498 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			498 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * Copyright JS Foundation and other contributors, http://js.foundation
 | |
|  *
 | |
|  * 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 bodyParser = require('body-parser');
 | |
| var sinon = require('sinon');
 | |
| 
 | |
| var NR_TEST_UTILS = require("nr-test-utils");
 | |
| 
 | |
| var nodes = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/nodes");
 | |
| var apiUtil = NR_TEST_UTILS.require("@node-red/editor-api/lib/util");
 | |
| 
 | |
| describe("api/admin/nodes", function() {
 | |
| 
 | |
|     var app;
 | |
|     before(function() {
 | |
|         app = express();
 | |
|         app.use(bodyParser.json());
 | |
|         app.get("/nodes",nodes.getAll);
 | |
|         app.post("/nodes",nodes.post);
 | |
|         app.get(/\/nodes\/messages/,nodes.getModuleCatalogs);
 | |
|         app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,nodes.getModuleCatalog);
 | |
|         app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.getModule);
 | |
|         app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.putModule);
 | |
|         app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.getSet);
 | |
|         app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.putSet);
 | |
|         app.get("/getIcons",nodes.getIcons);
 | |
|         app.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.delete);
 | |
|         sinon.stub(apiUtil,"determineLangFromHeaders").callsFake(function() {
 | |
|             return "en-US";
 | |
|         });
 | |
|     });
 | |
|     after(function() {
 | |
|         apiUtil.determineLangFromHeaders.restore();
 | |
|     })
 | |
| 
 | |
|     describe('get nodes', function() {
 | |
|         it('returns node list', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getNodeList: function() {
 | |
|                         return Promise.resolve([1,2,3]);
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes')
 | |
|                 .set('Accept', 'application/json')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.be.an.Array();
 | |
|                     res.body.should.have.lengthOf(3);
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('returns node configs', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getNodeConfigs: function() {
 | |
|                         return Promise.resolve("<script></script>");
 | |
|                     }
 | |
|                 },
 | |
|                 i18n: {
 | |
|                     determineLangFromHeaders: function(){}
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes')
 | |
|                 .set('Accept', 'text/html')
 | |
|                 .expect(200)
 | |
|                 .expect("<script></script>")
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('returns node module info', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getModuleInfo: function(opts) {
 | |
|                         return Promise.resolve({"node-red":{name:"node-red"}}[opts.module]);
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/node-red')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("name","node-red");
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('returns 404 for unknown module', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getModuleInfo: function(opts) {
 | |
|                         var errInstance = new Error("Not Found");
 | |
|                         errInstance.code = "not_found";
 | |
|                         errInstance.status = 404;
 | |
|                         var p = Promise.reject(errInstance);
 | |
|                         p.catch(()=>{});
 | |
|                         return p;
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/node-blue')
 | |
|                 .expect(404)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('returns individual node info', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getNodeInfo: function(opts) {
 | |
|                         return Promise.resolve({"node-red/123":{id:"node-red/123"}}[opts.id]);
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/node-red/123')
 | |
|                 .set('Accept', 'application/json')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("id","node-red/123");
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('returns individual node configs', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getNodeConfig: function(opts) {
 | |
|                         return Promise.resolve({"node-red/123":"<script></script>"}[opts.id]);
 | |
|                     }
 | |
|                 },
 | |
|                 i18n: {
 | |
|                     determineLangFromHeaders: function(){}
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/node-red/123')
 | |
|                 .set('Accept', 'text/html')
 | |
|                 .expect(200)
 | |
|                 .expect("<script></script>")
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|         it('returns 404 for unknown node', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getNodeInfo: function(opts) {
 | |
|                         var errInstance = new Error("Not Found");
 | |
|                         errInstance.code = "not_found";
 | |
|                         errInstance.status = 404;
 | |
|                         var p = Promise.reject(errInstance);
 | |
|                         p.catch(()=>{});
 | |
|                         return p;
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/node-red/456')
 | |
|                 .set('Accept', 'application/json')
 | |
|                 .expect(404)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     describe('install', function() {
 | |
|         it('installs the module and returns module info', function(done) {
 | |
|             var opts;
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     addModule: function(_opts) {
 | |
|                         opts = _opts;
 | |
|                         return Promise.resolve({
 | |
|                             name:"foo",
 | |
|                             nodes:[{id:"123"}]
 | |
|                         });
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|             .post('/nodes')
 | |
|             .send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
 | |
|             .expect(200)
 | |
|             .end(function(err,res) {
 | |
|                 if (err) {
 | |
|                     throw err;
 | |
|                 }
 | |
|                 res.body.should.have.property("name","foo");
 | |
|                 res.body.should.have.property("nodes");
 | |
|                 res.body.nodes[0].should.have.property("id","123");
 | |
|                 opts.should.have.property("module","foo");
 | |
|                 opts.should.have.property("version","1.2.3");
 | |
|                 opts.should.have.property("url","https://example/foo-1.2.3.tgz");
 | |
|                 done();
 | |
|             });
 | |
|         });
 | |
|         it('returns error', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     addModule: function(opts) {
 | |
|                         var errInstance = new Error("Message");
 | |
|                         errInstance.code = "random_error";
 | |
|                         errInstance.status = 400;
 | |
|                         var p = Promise.reject(errInstance);
 | |
|                         p.catch(()=>{});
 | |
|                         return p;
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .post('/nodes')
 | |
|                 .send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
 | |
|                 .expect(400)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.a.property('code','random_error');
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
|     describe('delete', function() {
 | |
|         it('uninstalls the module', function(done) {
 | |
|             var opts;
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     removeModule: function(_opts) {
 | |
|                         opts = _opts;
 | |
|                         return Promise.resolve();
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|             .del('/nodes/123')
 | |
|             .expect(204)
 | |
|             .end(function(err,res) {
 | |
|                 if (err) {
 | |
|                     throw err;
 | |
|                 }
 | |
|                 opts.should.have.property("module","123");
 | |
|                 done();
 | |
|             });
 | |
|         });
 | |
|         it('returns error', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     removeModule: function(opts) {
 | |
|                         var errInstance = new Error("Message");
 | |
|                         errInstance.code = "random_error";
 | |
|                         errInstance.status = 400;
 | |
|                         var p = Promise.reject(errInstance);
 | |
|                         p.catch(()=>{});
 | |
|                         return p;
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .del('/nodes/123')
 | |
|                 .expect(400)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.a.property('code','random_error');
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     describe('enable/disable node set', function() {
 | |
|         it('returns 400 for invalid request payload', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     setNodeSetState: function(opts) {return Promise.resolve()}
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .put('/nodes/node-red/foo')
 | |
|                 .send({})
 | |
|                 .expect(400)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("code","invalid_request");
 | |
|                     res.body.should.have.property("message","Invalid request");
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         it('sets node state and returns node info', function(done) {
 | |
|             var opts;
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     setNodeSetState: function(_opts) {
 | |
|                         opts = _opts;
 | |
|                         return Promise.resolve({id:"123",enabled: true });
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
| 
 | |
|             request(app)
 | |
|                 .put('/nodes/node-red/foo')
 | |
|                 .send({enabled:true})
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("id","123");
 | |
|                     res.body.should.have.property("enabled",true);
 | |
|                     opts.should.have.property("enabled",true);
 | |
|                     opts.should.have.property("id","node-red/foo");
 | |
| 
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
|     describe('enable/disable module' ,function() {
 | |
|         it('returns 400 for invalid request payload', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     setModuleState: function(opts) {return Promise.resolve()}
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .put('/nodes/node-red')
 | |
|                 .send({})
 | |
|                 .expect(400)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("code","invalid_request");
 | |
|                     res.body.should.have.property("message","Invalid request");
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|         it('sets module state and returns module info', function(done) {
 | |
|             var opts;
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     setModuleState: function(_opts) {
 | |
|                         opts = _opts;
 | |
|                         return Promise.resolve({name:"node-red"});
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
| 
 | |
|             request(app)
 | |
|                 .put('/nodes/node-red')
 | |
|                 .send({enabled:true})
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("name","node-red");
 | |
|                     opts.should.have.property("enabled",true);
 | |
|                     opts.should.have.property("module","node-red");
 | |
| 
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     describe('get icons', function() {
 | |
|         it('returns icon list', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getIconList: function() {
 | |
|                         return Promise.resolve({module:[1,2,3]});
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/getIcons')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.have.property("module");
 | |
|                     res.body.module.should.be.an.Array();
 | |
|                     res.body.module.should.have.lengthOf(3);
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     describe('get module messages', function() {
 | |
|         it('returns message catalog', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getModuleCatalog: function(opts) {
 | |
|                         return Promise.resolve({a:123});
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/module/set/messages')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.eql({a:123});
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|         it('returns all node catalogs', function(done) {
 | |
|             nodes.init({
 | |
|                 settings: {},
 | |
|                 nodes:{
 | |
|                     getModuleCatalogs: function(opts) {
 | |
|                         return Promise.resolve({a:1});
 | |
|                     }
 | |
|                 }
 | |
|             });
 | |
|             request(app)
 | |
|                 .get('/nodes/messages')
 | |
|                 .expect(200)
 | |
|                 .end(function(err,res) {
 | |
|                     if (err) {
 | |
|                         throw err;
 | |
|                     }
 | |
|                     res.body.should.eql({a:1});
 | |
|                     done();
 | |
|                 });
 | |
|         });
 | |
|     })
 | |
| });
 |