diff --git a/red/nodes/registry.js b/red/nodes/registry.js index c738fca19..40ec01e4a 100644 --- a/red/nodes/registry.js +++ b/red/nodes/registry.js @@ -63,6 +63,7 @@ function getNodeFiles(dir) { /** * Scans the node_modules path for nodes + * @param moduleName the name of the module to be found * @return a list of node modules: {dir,package} */ function scanTreeForNodesModules(moduleName) { @@ -230,13 +231,21 @@ function init(_settings) { /** * Loads all palette nodes + * @param defaultNodesDir optional parameter, when set, it overrides the default location + * of nodeFiles * @return a promise that resolves to a list of any errors encountered loading nodes */ -function load() { +function load(defaultNodesDir) { return when.promise(function(resolve,reject) { // Find all of the nodes to load - var nodeFiles = getNodeFiles(__dirname+"/../../nodes"); + var nodeFiles; + if(defaultNodesDir) { + nodeFiles = getNodeFiles(path.resolve(defaultNodesDir)); + } else { + nodeFiles = getNodeFiles(__dirname+"/../../nodes"); + } + if (settings.nodesDir) { var dir = settings.nodesDir; if (typeof settings.nodesDir == "string") { @@ -320,4 +329,3 @@ module.exports = { } } - diff --git a/test/red/nodes/registry_spec.js b/test/red/nodes/registry_spec.js index 38dde7a5c..4c7dc2c20 100644 --- a/test/red/nodes/registry_spec.js +++ b/test/red/nodes/registry_spec.js @@ -29,6 +29,129 @@ describe('NodeRegistry', function() { should.strictEqual(n,newNode); }); -}) - +}); +describe('NodeRegistry', function() { + it('does not accept incorrect nodesDir',function(done) { + var typeRegistry = require("../../../red/nodes/registry"); + var settings = { + nodesDir : "wontexist" + } + + typeRegistry.init(null); + typeRegistry.load().then(function(){ + try { + should.fail(null, null, "Loading of non-existing nodesDir should never succeed"); + } catch (err) { + done(err); + } + }).catch(function(e) { // successful test, failed promise + done(); + }); + }); + + it('fails to load additional node files from invalid nodesDir',function(done) { + var typeRegistry = require("../../../red/nodes/registry"); + var settings = { + nodesDir : "wontexist" + } + + typeRegistry.init(settings); + typeRegistry.load().then(function(){ + try { + should.fail(null, null, "Loading of non-existing nodesDir should never succeed"); + } catch (err) { + done(err); + } + }).catch(function(e) { // successful test, failed promise + done(); + }); + }); +}); + +/* + * This test does the following: + * 1) injects settings that tell the registry to load its default nodes from + * tempNoNodesContainedDir that contains no valid nodes => this means that no default nodes are loaded + * 2) We only load a single node we pre-deploy into tempDir + * 3) This node (fakeNodeJS = reads "fake Node JavaScript"), when exported automatically creates a known + * file + * 4) We can assert that this file exists and make the loading test pass/fail + */ +describe("getNodeFiles", function() { + var fs = require('fs-extra'); + var path = require('path'); + + var tempDir = path.join(__dirname,".tmp/"); + var fakeNodeJS = tempDir + "testNode.js"; // when exported, this fake node creates a file we can assert on + + var nodeInjectedFileName = "testInjected"; + var nodeInjectedFilePath = path.join(tempDir, nodeInjectedFileName); + + var tempNoNodesContainedDir = path.join(__dirname,".noNodes/"); + + beforeEach(function(done) { + fs.remove(tempDir,function(err) { + fs.mkdirSync(tempDir); + var fileContents = "var fs = require('fs');\n" + + "var path = require('path');\n" + + "var tempFile = path.join(__dirname, \"" + nodeInjectedFileName + "\");\n" + + "\n" + + "module.exports = function(RED) {\n" + + " fs.writeFileSync(tempFile, \"Test passes if this file has been written.\");\n" + + "}\n"; + fs.writeFileSync(fakeNodeJS, fileContents); + fs.remove(tempNoNodesContainedDir,function(err) { + fs.mkdirSync(tempNoNodesContainedDir); + done(); + }); + }); + }); + afterEach(function(done) { + fs.exists(tempNoNodesContainedDir, function(exists) { + if(exists) { + fs.removeSync(tempNoNodesContainedDir); + } + }); + fs.exists(nodeInjectedFilePath, function(exists) { + if(exists) { + fs.unlinkSync(nodeInjectedFilePath); + } + }); + fs.exists(fakeNodeJS, function(exists) { + if(exists) { + fs.unlinkSync(fakeNodeJS); + } + fs.remove(tempDir, done); + }); + }); + + it('loads additional node files from specified external nodesDir',function(done) { + var typeRegistry = require("../../../red/nodes/registry"); + var settings = { + nodesDir : tempDir + } + + typeRegistry.init(settings); + + typeRegistry.load(tempNoNodesContainedDir).then(function(){ + fs.exists(nodeInjectedFilePath, function(exists) { + if(exists) { + done(); + } else { + try { + should.fail(null, null, nodeInjectedFilePath + " should be created by registered test node."); + } catch(err) { + done(err) + } + } + }); + }).catch(function(e) { + try { + should.fail(null, null, "Loading of nodesDir should succeed"); + } catch (err) { + done(err); + } + }); + }); +});