diff --git a/red/api/auth/index.js b/red/api/auth/index.js index 2ed55528c..f3a8624f3 100644 --- a/red/api/auth/index.js +++ b/red/api/auth/index.js @@ -34,11 +34,11 @@ var server = oauth2orize.createServer(); server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange)); -function init(_settings) { +function init(_settings,storage) { settings = _settings; if (settings.adminAuth) { Users.init(settings.adminAuth); - Tokens.init(settings) + Tokens.init(storage); } } diff --git a/red/api/auth/tokens/index.js b/red/api/auth/tokens.js similarity index 62% rename from red/api/auth/tokens/index.js rename to red/api/auth/tokens.js index b5c5bc61f..32f20a88f 100644 --- a/red/api/auth/tokens/index.js +++ b/red/api/auth/tokens.js @@ -15,7 +15,6 @@ **/ var when = require("when"); -var Sessions; function generateToken(length) { var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890"; @@ -27,30 +26,18 @@ function generateToken(length) { } -var sessionModule; - -function moduleSelector(aSettings) { - var toReturn; - if (aSettings.sessionStorageModule) { - if (typeof aSettings.sessionStorageModule === "string") { - // TODO: allow storage modules to be specified by absolute path - toReturn = require("./"+aSettings.sessionStorageModule); - } else { - toReturn = aSettings.sessionStorageModule; - } - } else { - toReturn = require("./localfilesystem"); - } - return toReturn; -} +var storage; +var sessions = {}; module.exports = { - init: function(settings) { - sessionModule = moduleSelector(settings); - sessionModule.init(settings); + init: function(_storage) { + storage = _storage; + return storage.getSessions().then(function(_sessions) { + sessions = _sessions||{}; + }); }, get: function(token) { - return sessionModule.get(token); + return when.resolve(sessions[token]); }, create: function(user,client,scope) { var accessToken = generateToken(128); @@ -60,14 +47,16 @@ module.exports = { scope:scope, accessToken: accessToken, }; - return sessionModule.create(accessToken,session).then(function() { + sessions[accessToken] = session; + return storage.saveSessions(sessions).then(function() { return { accessToken: accessToken, } }); }, revoke: function(token) { - return sessionModule.delete(token); + delete sessions[token]; + return storage.saveSessions(sessions); } } diff --git a/red/api/auth/tokens/localfilesystem.js b/red/api/auth/tokens/localfilesystem.js deleted file mode 100644 index e6bde4ec6..000000000 --- a/red/api/auth/tokens/localfilesystem.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2015 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 fs = require('fs'); -var when = require('when'); -var nodeFn = require('when/node/function'); -var fspath = require("path"); - -var settings; -var sessionsFile; - -var sessions = {}; - -/** - * Write content to a file using UTF8 encoding. - * This forces a fsync before completing to ensure - * the write hits disk. - */ -function writeFile(path,content) { - return when.promise(function(resolve,reject) { - var stream = fs.createWriteStream(path); - stream.on('open',function(fd) { - stream.end(content,'utf8',function() { - fs.fsync(fd,resolve); - }); - }); - stream.on('error',function(err) { - reject(err); - }); - }); -} - -var api = module.exports = { - init: function(_settings) { - settings = _settings; - var userDir = settings.userDir || process.env.NODE_RED_HOME; - sessionsFile = fspath.join(userDir,".sessions.json"); - - try { - sessions = JSON.parse(fs.readFileSync(sessionsFile,'utf8')); - } catch(err) { - sessions = {}; - } - - return when.resolve(); - }, - - get: function(token) { - return when.resolve(sessions[token]); - }, - create: function(token,session) { - sessions[token] = session; - return writeFile(sessionsFile,JSON.stringify(sessions)); - }, - delete: function(token) { - delete sessions[token]; - return writeFile(sessionsFile,JSON.stringify(sessions)); - } -} diff --git a/red/api/index.js b/red/api/index.js index aadf861a8..7585405c7 100644 --- a/red/api/index.js +++ b/red/api/index.js @@ -36,9 +36,9 @@ var errorHandler = function(err,req,res,next) { res.send(400,err.toString()); }; -function init(adminApp) { +function init(adminApp,storage) { - auth.init(settings); + auth.init(settings,storage); // Editor if (!settings.disableEditor) { diff --git a/red/server.js b/red/server.js index a2b7c55b7..46c312706 100644 --- a/red/server.js +++ b/red/server.js @@ -41,17 +41,16 @@ function init(_server,_settings) { nodeApp = express(); app = express(); - - if (settings.httpAdminRoot !== false) { - require("./api").init(app); - } } function start() { - var defer = when.defer(); - - storage.init(settings).then(function() { - settings.load(storage).then(function() { + return storage.init(settings) + .then(settings.load(storage)) + .then(function() { + if (settings.httpAdminRoot !== false) { + require("./api").init(app,storage); + } + if (log.metric()) { runtimeMetricInterval = setInterval(function() { reportMetrics(); @@ -105,19 +104,12 @@ function start() { redNodes.cleanModuleList(); } } - defer.resolve(); - redNodes.loadFlows(); }).otherwise(function(err) { console.log(err); }); comms.start(); - }); - }).otherwise(function(err) { - defer.reject(err); }); - - return defer.promise; } diff --git a/red/storage/index.js b/red/storage/index.js index d3d27bb51..28311c2ec 100644 --- a/red/storage/index.js +++ b/red/storage/index.js @@ -1,5 +1,5 @@ /** - * Copyright 2013, 2014 IBM Corp. + * Copyright 2013, 2015 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ var storageModuleInterface = { try { storageModule = moduleSelector(settings); settingsAvailable = storageModule.hasOwnProperty("getSettings") && storageModule.hasOwnProperty("saveSettings"); - sessionsAvailable = storageModule.hasOwnProperty("getUserSessions") && storageModule.hasOwnProperty("saveUserSessions"); + sessionsAvailable = storageModule.hasOwnProperty("getSessions") && storageModule.hasOwnProperty("saveSessions"); } catch (e) { return when.reject(e); } @@ -76,6 +76,20 @@ var storageModuleInterface = { return when.resolve(); } }, + getSessions: function() { + if (sessionsAvailable) { + return storageModule.getSessions(); + } else { + return when.resolve(null); + } + }, + saveSessions: function(sessions) { + if (sessionsAvailable) { + return storageModule.saveSessions(sessions); + } else { + return when.resolve(); + } + }, /* Library Functions */ getAllFlows: function() { diff --git a/red/storage/localfilesystem.js b/red/storage/localfilesystem.js index 7c02f3444..f61f325c4 100644 --- a/red/storage/localfilesystem.js +++ b/red/storage/localfilesystem.js @@ -32,6 +32,7 @@ var flowsFileBackup; var credentialsFile; var credentialsFileBackup; var oldCredentialsFile; +var sessionsFile; var libDir; var libFlowsDir; var globalSettingsFile; @@ -191,6 +192,8 @@ var localfilesystem = { flowsFileBackup = fspath.join(ffDir,"."+ffName+".backup"); + sessionsFile = fspath.join(settings.userDir,".sessions.json"); + libDir = fspath.join(settings.userDir,"lib"); libFlowsDir = fspath.join(libDir,"flows"); @@ -288,6 +291,26 @@ var localfilesystem = { saveSettings: function(settings) { return writeFile(globalSettingsFile,JSON.stringify(settings,null,1)); }, + getSessions: function() { + if (fs.existsSync(sessionsFile)) { + return nodeFn.call(fs.readFile,sessionsFile,'utf8').then(function(data) { + if (data) { + try { + return JSON.parse(data); + } catch(err) { + log.info("Corrupted sessions file - resetting"); + return {}; + } + } else { + return {}; + } + }); + } + return when.resolve({}); + }, + saveSessions: function(sessions) { + return writeFile(sessionsFile,JSON.stringify(sessions)); + }, getAllFlows: function() { return listFiles(libFlowsDir); diff --git a/test/red/api/auth/tokens/index_spec.js b/test/red/api/auth/tokens/index_spec.js deleted file mode 100644 index 8c797f2a6..000000000 --- a/test/red/api/auth/tokens/index_spec.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright 2015 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 when = require("when"); -var sinon = require("sinon"); - - -var Tokens = require("../../../../../red/api/auth/tokens"); - - -describe("Tokens", function() { - describe("#init",function() { - var module = require("module"); - var originalLoader; - beforeEach(function() { - originalLoader = module._load; - }); - afterEach(function() { - module._load = originalLoader; - }); - - it('loads default storage plugin', function(done) { - module._load = function(name) { - name.should.equal("./localfilesystem"); - return {init: function(settings) {done()}}; - } - try { - Tokens.init({}); - } catch(err) { - done(err); - } - }); - it('loads the specified storage plugin', function(done) { - module._load = function(name) { - name.should.equal("./aTestExample"); - return {init: function(settings) {done()}}; - } - try { - Tokens.init({sessionStorageModule:"aTestExample"}); - } catch(err) { - done(err); - } - }); - - it('uses the provided storage plugin', function(done) { - Tokens.init({sessionStorageModule:{init:function(settings){done()}}}); - }); - }); - - - describe("#get",function() { - it('returns a valid token', function(done) { - Tokens.init({sessionStorageModule:{ - init:function(settings){}, - get: function(token) { - return when.resolve({user:"fred"}); - } - }}); - - Tokens.get("1234").then(function(token) { - try { - token.should.have.a.property("user","fred"); - done(); - } catch(err) { - done(err); - } - }); - }); - - it('returns null for an invalid token', function(done) { - Tokens.init({sessionStorageModule:{ - init:function(settings){}, - get: function(token) { - return when.resolve(null); - } - }}); - - Tokens.get("1234").then(function(token) { - try { - should.not.exist(token); - done(); - } catch(err) { - done(err); - } - }); - }); - }); - - describe("#create",function() { - it('creates a token', function(done) { - var sessionStorageModule = { - init:function(settings){}, - create: sinon.stub().returns(when.resolve()) - }; - Tokens.init({sessionStorageModule:sessionStorageModule}); - Tokens.create("user","client","scope").then(function(token) { - try { - sessionStorageModule.create.called.should.be.true; - token.should.have.a.property('accessToken',sessionStorageModule.create.args[0][0]); - sessionStorageModule.create.args[0][1].should.have.a.property('user','user'); - sessionStorageModule.create.args[0][1].should.have.a.property('client','client'); - sessionStorageModule.create.args[0][1].should.have.a.property('scope','scope'); - done(); - } catch(err) { - done(err); - } - }); - }); - }); - - describe("#revoke", function() { - it('revokes a token', function(done) { - var deletedToken; - Tokens.init({sessionStorageModule:{ - init:function(settings){}, - delete: function(token) { - deletedToken = token; - return when.resolve(null); - } - }}); - - Tokens.revoke("1234").then(function() { - try { - deletedToken.should.equal("1234"); - done(); - } catch(err) { - done(err); - } - }); - }); - }); - -}); \ No newline at end of file diff --git a/test/red/api/auth/tokens/localfilesystem_spec.js b/test/red/api/auth/tokens/localfilesystem_spec.js deleted file mode 100644 index dce3b8e07..000000000 --- a/test/red/api/auth/tokens/localfilesystem_spec.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright 2015 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 when = require("when"); -var sinon = require("sinon"); - -var fs = require('fs-extra'); -var path = require('path'); - -var localfilesystem = require("../../../../../red/api/auth/tokens/localfilesystem.js"); - - -describe("Tokens localfilesystem", function() { - var userDir = path.join(__dirname,".testUserHome"); - beforeEach(function(done) { - fs.remove(userDir,function(err) { - fs.mkdir(userDir,done); - }); - }); - afterEach(function(done) { - fs.remove(userDir,done); - }); - - it("initialise when no session file exists",function(done) { - localfilesystem.init({userDir:userDir}).then(function() { - localfilesystem.get("1234").then(function(token) { - should.not.exist(token); - done(); - }); - }); - }); - - it("initialises when session file exists", function(done) { - var sessions = {"1234":{"user":"nol","client":"node-red-admin","scope":["*"],"accessToken":"1234"}}; - fs.writeFileSync(path.join(userDir,".sessions.json"),JSON.stringify(sessions),"utf8"); - - localfilesystem.init({userDir:userDir}).then(function() { - localfilesystem.get("1234").then(function(token) { - token.should.eql(sessions['1234']); - done(); - }); - }); - }); - - it("writes new tokens to the session file",function(done) { - var sessions = {"1234":{"user":"nol","client":"node-red-admin","scope":["*"],"accessToken":"1234"}}; - fs.writeFileSync(path.join(userDir,".sessions.json"),JSON.stringify(sessions),"utf8"); - - localfilesystem.init({userDir:userDir}).then(function() { - localfilesystem.create("5678",{ - user:"fred", - client:"client", - scope:["read"], - accessToken:"5678" - }).then(function() { - var newSessions = JSON.parse(fs.readFileSync(path.join(userDir,".sessions.json"),"utf8")); - newSessions.should.have.a.property("1234"); - newSessions.should.have.a.property("5678"); - done(); - }); - }); - }); - - it("deletes tokens from the session file",function(done) { - var sessions = { - "1234":{"user":"nol","client":"node-red-admin","scope":["*"],"accessToken":"1234"}, - "5678":{"user":"fred","client":"client","scope":["read"],"accessToken":"5678"} - }; - fs.writeFileSync(path.join(userDir,".sessions.json"),JSON.stringify(sessions),"utf8"); - - localfilesystem.init({userDir:userDir}).then(function() { - localfilesystem.delete("5678").then(function() { - var newSessions = JSON.parse(fs.readFileSync(path.join(userDir,".sessions.json"),"utf8")); - newSessions.should.have.a.property("1234"); - newSessions.should.not.have.a.property("5678"); - done(); - }); - }); - }); - - -}); diff --git a/test/red/api/auth/tokens_spec.js b/test/red/api/auth/tokens_spec.js new file mode 100644 index 000000000..2be83a250 --- /dev/null +++ b/test/red/api/auth/tokens_spec.js @@ -0,0 +1,127 @@ +/** + * Copyright 2015 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 when = require("when"); +var sinon = require("sinon"); + +var Tokens = require("../../../../red/api/auth/tokens"); + + +describe("Tokens", function() { + describe("#init",function() { + it('loads sessions', function(done) { + Tokens.init({ + getSessions:function() { + done(); + return when.resolve(); + } + }); + }); + }); + + + describe("#get",function() { + it('returns a valid token', function(done) { + Tokens.init({ + getSessions:function() { + return when.resolve({"1234":{"user":"fred"}}); + } + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + token.should.have.a.property("user","fred"); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('returns null for an invalid token', function(done) { + Tokens.init({ + getSessions:function() { + return when.resolve({}); + } + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + should.not.exist(token); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + + describe("#create",function() { + it('creates a token', function(done) { + var savedSession; + Tokens.init({ + getSessions:function() { + return when.resolve({}); + }, + saveSessions:function(sess) { + savedSession = sess; + return when.resolve(); + } + }); + Tokens.create("user","client","scope").then(function(token) { + try { + should.exist(savedSession); + var sessionKeys = Object.keys(savedSession); + sessionKeys.should.have.lengthOf(1); + + token.should.have.a.property('accessToken',sessionKeys[0]); + savedSession[sessionKeys[0]].should.have.a.property('user','user'); + savedSession[sessionKeys[0]].should.have.a.property('client','client'); + savedSession[sessionKeys[0]].should.have.a.property('scope','scope'); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + describe("#revoke", function() { + it('revokes a token', function(done) { + var savedSession; + Tokens.init({ + getSessions:function() { + return when.resolve({"1234":{"user":"fred"}}); + }, + saveSessions:function(sess) { + savedSession = sess; + return when.resolve(); + } + }).then(function() { + Tokens.revoke("1234").then(function() { + try { + savedSession.should.not.have.a.property("1234"); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + +}); \ No newline at end of file diff --git a/test/red/api/index_spec.js b/test/red/api/index_spec.js index 1fc184383..ec40d67ee 100644 --- a/test/red/api/index_spec.js +++ b/test/red/api/index_spec.js @@ -17,6 +17,7 @@ var should = require("should"); var request = require("supertest"); var express = require("express"); +var when = require("when"); var fs = require("fs"); var path = require("path"); var settings = require("../../../red/settings"); @@ -62,7 +63,7 @@ describe("api index", function() { //settings.init({disableEditor:true}); settings.init({adminAuth:{type: "credentials",users:[],default:{permissions:"read"}}}); app = express(); - api.init(app); + api.init(app,{getSessions:function(){return when.resolve({})}}); }); after(function() { settings.reset(); diff --git a/test/red/nodes/credentials_spec.js b/test/red/nodes/credentials_spec.js index ab1a295bc..2fdc35c9b 100644 --- a/test/red/nodes/credentials_spec.js +++ b/test/red/nodes/credentials_spec.js @@ -332,134 +332,5 @@ describe('Credentials', function() { }); }); - - //describe('registerEndpoint', function() { - // var path = require('path'); - // var fs = require('fs-extra'); - // var http = require('http'); - // var express = require('express'); - // var request = require('supertest'); - // - // var server = require("../../../red/server"); - // var localfilesystem = require("../../../red/storage/localfilesystem"); - // var app = express(); - // var RED = require("../../../red/red.js"); - // - // var userDir = path.join(__dirname,".testUserHome"); - // before(function(done) { - // fs.remove(userDir,function(err) { - // fs.mkdir(userDir,function() { - // sinon.stub(index, 'load', function() { - // return when.promise(function(resolve,reject){ - // resolve([]); - // }); - // }); - // sinon.stub(localfilesystem, 'getCredentials', function() { - // return when.promise(function(resolve,reject) { - // resolve({"tab1":{"foo": 2, "pswd":'sticks'}}); - // }); - // }) ; - // RED.init(http.createServer(function(req,res){app(req,res)}), - // {userDir: userDir}); - // server.start().then(function () { - // done(); - // }); - // }); - // }); - // }); - // - // after(function(done) { - // fs.remove(userDir,done); - // server.stop(); - // index.load.restore(); - // localfilesystem.getCredentials.restore(); - // }); - // - // function TestNode(n) { - // index.createNode(this, n); - // var node = this; - // this.on("log", function() { - // // do nothing - // }); - // } - // - // it(': valid credential type', function(done) { - // index.registerType('test', TestNode, { - // credentials: { - // foo: {type:"test"} - // } - // }); - // index.loadFlows().then(function() { - // var testnode = new TestNode({id:'tab1',type:'foo',name:'barney'}); - // request(RED.httpAdmin).get('/credentials/test/tab1').expect(200).end(function(err,res) { - // if (err) { - // done(err); - // } - // res.body.should.have.property('foo', 2); - // done(); - // }); - // }).otherwise(function(err){ - // done(err); - // }); - // }); - // - // it(': password credential type', function(done) { - // index.registerType('password', TestNode, { - // credentials: { - // pswd: {type:"password"} - // } - // }); - // index.loadFlows().then(function() { - // var testnode = new TestNode({id:'tab1',type:'pswd',name:'barney'}); - // request(RED.httpAdmin).get('/credentials/password/tab1').expect(200).end(function(err,res) { - // if (err) { - // done(err); - // } - // res.body.should.have.property('has_pswd', true); - // res.body.should.not.have.property('pswd'); - // done(); - // }); - // }).otherwise(function(err){ - // done(err); - // }); - // }); - // - // it(': returns 404 for undefined credential type', function(done) { - // index.registerType('test', TestNode, { - // credentials: { - // foo: {type:"test"} - // } - // }); - // index.loadFlows().then(function() { - // var testnode = new TestNode({id:'tab1',type:'foo',name:'barney'}); - // request(RED.httpAdmin).get('/credentials/unknownType/tab1').expect(404).end(done); - // }).otherwise(function(err){ - // done(err); - // }); - // }); - // - // it(': undefined nodeID', function(done) { - // index.registerType('test', TestNode, { - // credentials: { - // foo: {type:"test"} - // } - // }); - // index.loadFlows().then(function() { - // var testnode = new TestNode({id:'tab1',type:'foo',name:'barney'}); - // request(RED.httpAdmin).get('/credentials/test/unknownNode').expect(200).end(function(err,res) { - // if (err) { - // done(err); - // } - // var b = res.body; - // res.body.should.not.have.property('foo'); - // done(); - // }); - // }).otherwise(function(err){ - // done(err); - // }); - // }); - // - //}) - }) diff --git a/test/red/server_spec.js b/test/red/server_spec.js index e09902d37..4e58f55a7 100644 --- a/test/red/server_spec.js +++ b/test/red/server_spec.js @@ -44,13 +44,11 @@ describe("red/server", function() { it("initialises components", function() { var commsInit = sinon.stub(comms,"init",function() {}); - var apiInit = sinon.stub(api,"init",function() {}); var dummyServer = {}; server.init(dummyServer,{httpAdminRoot:"/"}); commsInit.called.should.be.true; - apiInit.called.should.be.true; should.exist(server.app); should.exist(server.nodeApp); @@ -58,26 +56,6 @@ describe("red/server", function() { server.server.should.equal(dummyServer); commsInit.restore(); - apiInit.restore(); - }); - - it("does not initalise api when disabled", function() { - var commsInit = sinon.stub(comms,"init",function() {}); - var apiInit = sinon.stub(api,"init",function() {}); - - var dummyServer = {}; - server.init(dummyServer,{httpAdminRoot:false}); - - commsInit.called.should.be.true; - apiInit.called.should.be.false; - - should.exist(server.app); - should.exist(server.nodeApp); - - server.server.should.equal(dummyServer); - - commsInit.restore(); - apiInit.restore(); }); it("stops components", function() { diff --git a/test/red/storage/index_spec.js b/test/red/storage/index_spec.js index 4b60ba835..374a8c4fb 100644 --- a/test/red/storage/index_spec.js +++ b/test/red/storage/index_spec.js @@ -14,6 +14,7 @@ * limitations under the License. **/ var should = require("should"); +var storage = require("../../../red/storage/index"); describe("red/storage/index", function() { @@ -23,7 +24,6 @@ describe("red/storage/index", function() { storageModule : "thisaintloading" }; - var storage = require("../../../red/storage/index"); storage.init(wrongModule).then( function() { var one = 1; var zero = 0; @@ -50,17 +50,18 @@ describe("red/storage/index", function() { storageModule : moduleWithBooleanSettingInit }; - var storage = require("../../../red/storage/index"); storage.init(setsBooleanModule); initSetsMeToTrue.should.be.true; done(); }); - it('respects storage interface', function(done) { + it('respects storage interface', function() { var calledFlagGetFlows = false; var calledFlagGetCredentials = false; var calledFlagGetAllFlows = false; var calledInit = false; + var calledFlagGetSettings = false; + var calledFlagGetSessions = false; var interfaceCheckerModule = { init : function (settings) { @@ -79,6 +80,18 @@ describe("red/storage/index", function() { saveCredentials : function(credentials) { credentials.should.be.true; }, + getSettings : function() { + calledFlagGetSettings = true; + }, + saveSettings : function(settings) { + settings.should.be.true; + }, + getSessions : function() { + calledFlagGetSessions = true; + }, + saveSessions : function(sessions) { + sessions.should.be.true; + }, getAllFlows : function() { calledFlagGetAllFlows = true; }, @@ -102,15 +115,18 @@ describe("red/storage/index", function() { }; var moduleToLoad = { - storageModule : interfaceCheckerModule + storageModule : interfaceCheckerModule }; - var storage = require("../../../red/storage/index"); storage.init(moduleToLoad); storage.getFlows(); storage.saveFlows(true); storage.getCredentials(); storage.saveCredentials(true); + storage.getSettings(); + storage.saveSettings(true); + storage.getSessions(); + storage.saveSessions(true); storage.getAllFlows(); storage.getFlow("name"); storage.saveFlow("name", true); @@ -121,8 +137,38 @@ describe("red/storage/index", function() { calledFlagGetFlows.should.be.true; calledFlagGetCredentials.should.be.true; calledFlagGetAllFlows.should.be.true; + }); + + describe('handles missing settings/sessions interface', function() { + before(function() { + var interfaceCheckerModule = { + init : function () {} + }; + storage.init({storageModule: interfaceCheckerModule}); + }); - done(); + it('defaults missing getSettings',function(done) { + storage.getSettings().then(function(settings) { + should.not.exist(settings); + done(); + }); + }); + it('defaults missing saveSettings',function(done) { + storage.saveSettings({}).then(function() { + done(); + }); + }); + it('defaults missing getSessions',function(done) { + storage.getSessions().then(function(settings) { + should.not.exist(settings); + done(); + }); + }); + it('defaults missing saveSessions',function(done) { + storage.saveSessions({}).then(function() { + done(); + }); + }); }); });