/** * 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. **/ const should = require("should"); const sinon = require("sinon"); const NR_TEST_UTILS = require("nr-test-utils"); const registryUtil = NR_TEST_UTILS.require("@node-red/registry/lib/util"); // Get the internal runtime api const runtime = NR_TEST_UTILS.require("@node-red/runtime")._; const i18n = NR_TEST_UTILS.require("@node-red/util").i18n; describe("red/nodes/registry/util",function() { describe("createNodeApi", function() { let i18n_; let registerType; let registerSubflow; before(function() { i18n_ = sinon.stub(i18n,"_").callsFake(function() { return Array.prototype.slice.call(arguments,0); }) registerType = sinon.stub(runtime.nodes,"registerType"); registerSubflow = sinon.stub(runtime.nodes,"registerSubflow"); }); after(function() { i18n_.restore(); registerType.restore(); registerSubflow.restore(); }) it("builds node-specific view of runtime api", function() { registryUtil.init(runtime); var result = registryUtil.createNodeApi({id: "my-node", namespace: "my-namespace"}) // Need a better strategy here. // For now, validate the node-custom functions var message = result._("message"); // This should prepend the node's namespace to the message message.should.eql([ 'my-namespace:message' ]); var nodeConstructor = () => {}; var nodeOpts = {}; result.nodes.registerType("type",nodeConstructor, nodeOpts); registerType.called.should.be.true(); registerType.lastCall.args[0].should.eql("my-node") registerType.lastCall.args[1].should.eql("type") registerType.lastCall.args[2].should.eql(nodeConstructor) registerType.lastCall.args[3].should.eql(nodeOpts) var subflowDef = {}; result.nodes.registerSubflow(subflowDef); registerSubflow.called.should.be.true(); registerSubflow.lastCall.args[0].should.eql("my-node") registerSubflow.lastCall.args[1].should.eql(subflowDef) }); }); describe("checkModuleAllowed", function() { function checkList(module, version, allowList, denyList) { return registryUtil.checkModuleAllowed( module, version, registryUtil.parseModuleList(allowList), registryUtil.parseModuleList(denyList) ) } it("allows module with no allow/deny list provided", function() { checkList("abc","1.2.3",[],[]).should.be.true(); }) it("defaults allow to * when only deny list is provided", function() { checkList("abc","1.2.3",["*"],["def"]).should.be.true(); checkList("def","1.2.3",["*"],["def"]).should.be.false(); }) it("uses most specific matching rule", function() { checkList("abc","1.2.3",["ab*"],["a*"]).should.be.true(); checkList("def","1.2.3",["d*"],["de*"]).should.be.false(); }) it("checks version string using semver rules", function() { // Deny checkList("abc","1.2.3",["abc@1.2.2"],["*"]).should.be.false(); checkList("abc","1.2.3",["abc@1.2.4"],["*"]).should.be.false(); checkList("abc","1.2.3",["abc@>1.2.3"],["*"]).should.be.false(); checkList("abc","1.2.3",["abc@>=1.2.3"],["abc"]).should.be.false(); checkList("node-red-contrib-foo","1.2.3",["*"],["*contrib*"]).should.be.false(); // Allow checkList("abc","1.2.3",["abc@1.2.3"],["*"]).should.be.true(); checkList("abc","1.2.3",["abc@<1.2.4"],["*"]).should.be.true(); checkList("abc","1.2.3",["abc"],["abc@>1.2.3"]).should.be.true(); checkList("abc","1.2.3",["abc"],["abc@<1.2.3||>1.2.3"]).should.be.true(); checkList("node-red-contrib-foo","1.2.3",["*contrib*"],["*"]).should.be.true(); }) }) });