1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Move credential load/save storage functions under get/setFlows

This commit is contained in:
Nick O'Leary 2016-09-21 21:58:50 +01:00
parent e06cadd761
commit f9b972349d
8 changed files with 251 additions and 326 deletions

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2014, 2015 IBM Corp. * Copyright 2014, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,34 +19,40 @@ var when = require("when");
var log = require("../log"); var log = require("../log");
var credentialCache = {}; var credentialCache = {};
var storage = null;
var credentialsDef = {}; var credentialsDef = {};
var dirty = false;
module.exports = { var api = module.exports = {
init: function (_storage) { init: function() {
storage = _storage; dirty = false;
credentialCache = {};
credentialsDef = {};
}, },
/** /**
* Loads the credentials from storage. * Sets the credentials from storage.
*/ */
load: function () { load: function (credentials) {
return storage.getCredentials().then(function (creds) { credentialCache = credentials;
credentialCache = creds; dirty = false;
}).otherwise(function (err) { return when.resolve();
log.warn(log._("nodes.credentials.error",{message: err})); // return storage.getCredentials().then(function (creds) {
}); // credentialCache = creds;
// }).otherwise(function (err) {
// log.warn(log._("nodes.credentials.error",{message: err}));
// });
}, },
/** /**
* Adds a set of credentials for the given node id. * Adds a set of credentials for the given node id.
* @param id the node id for the credentials * @param id the node id for the credentials
* @param creds an object of credential key/value pairs * @param creds an object of credential key/value pairs
* @return a promise for the saving of credentials to storage * @return a promise for backwards compatibility TODO: can this be removed?
*/ */
add: function (id, creds) { add: function (id, creds) {
credentialCache[id] = creds; credentialCache[id] = creds;
return storage.saveCredentials(credentialCache); dirty = true;
return when.resolve();
}, },
/** /**
@ -65,7 +71,7 @@ module.exports = {
*/ */
delete: function (id) { delete: function (id) {
delete credentialCache[id]; delete credentialCache[id];
storage.saveCredentials(credentialCache); dirty = true;
}, },
/** /**
@ -77,6 +83,9 @@ module.exports = {
var existingIds = {}; var existingIds = {};
config.forEach(function(n) { config.forEach(function(n) {
existingIds[n.id] = true; existingIds[n.id] = true;
if (n.credentials) {
api.extract(n);
}
}); });
var deletedCredentials = false; var deletedCredentials = false;
for (var c in credentialCache) { for (var c in credentialCache) {
@ -88,10 +97,9 @@ module.exports = {
} }
} }
if (deletedCredentials) { if (deletedCredentials) {
return storage.saveCredentials(credentialCache); dirty = true;
} else {
return when.resolve();
} }
return when.resolve();
}, },
/** /**
@ -146,17 +154,10 @@ module.exports = {
} }
} }
credentialCache[nodeID] = savedCredentials; credentialCache[nodeID] = savedCredentials;
dirty = true;
} }
}, },
/**
* Saves the credentials to storage
* @return a promise for the saving of credentials to storage
*/
save: function () {
return storage.saveCredentials(credentialCache);
},
/** /**
* Gets the credential definition for the given node type * Gets the credential definition for the given node type
* @param type the node type * @param type the node type
@ -164,5 +165,14 @@ module.exports = {
*/ */
getDefinition: function (type) { getDefinition: function (type) {
return credentialsDef[type]; return credentialsDef[type];
},
dirty: function() {
return dirty;
},
export: function() {
dirty = false;
return when.resolve(credentialCache);
} }
} }

View File

@ -67,9 +67,9 @@ function init(runtime) {
} }
} }
function load() { function load() {
return storage.getFlows().then(function(flows) { return storage.getFlows().then(function(config) {
return credentials.load().then(function() { return credentials.load(config.credentials).then(function() {
return setConfig(flows,"load"); return setConfig(config.flows,"load");
}); });
}).otherwise(function(err) { }).otherwise(function(err) {
log.warn(log._("nodes.flows.error",{message:err.toString()})); log.warn(log._("nodes.flows.error",{message:err.toString()}));
@ -81,8 +81,6 @@ function setConfig(_config,type,muteLog) {
var config = clone(_config); var config = clone(_config);
type = type||"full"; type = type||"full";
var credentialsChanged = false;
var credentialSavePromise = null;
var configSavePromise = null; var configSavePromise = null;
var diff; var diff;
@ -90,23 +88,20 @@ function setConfig(_config,type,muteLog) {
if (type !== 'full' && type !== 'load') { if (type !== 'full' && type !== 'load') {
diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig); diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig);
} }
config.forEach(function(node) {
if (node.credentials) {
credentials.extract(node);
credentialsChanged = true;
}
});
if (credentialsChanged) {
credentialSavePromise = credentials.save();
} else {
credentialSavePromise = when.resolve();
}
if (type === 'load') { if (type === 'load') {
configSavePromise = credentialSavePromise;
type = 'full'; type = 'full';
configSavePromise = when.resolve();
} else { } else {
configSavePromise = credentialSavePromise.then(function() { credentials.clean(config);
return storage.saveFlows(config); var credsDirty = credentials.dirty();
configSavePromise = credentials.export().then(function(creds) {
var saveConfig = {
flows: config,
credentialsDirty:credsDirty,
credentials: creds
}
storage.saveFlows(saveConfig);
}); });
} }
@ -114,15 +109,13 @@ function setConfig(_config,type,muteLog) {
.then(function() { .then(function() {
activeConfig = config; activeConfig = config;
activeFlowConfig = newFlowConfig; activeFlowConfig = newFlowConfig;
return credentials.clean(activeConfig).then(function() { if (started) {
if (started) { return stop(type,diff,muteLog).then(function() {
return stop(type,diff,muteLog).then(function() { context.clean(activeFlowConfig);
context.clean(activeFlowConfig); start(type,diff,muteLog);
start(type,diff,muteLog); }).otherwise(function(err) {
}).otherwise(function(err) { })
}) }
}
});
}); });
} }

View File

@ -77,7 +77,7 @@ function createNode(node,def) {
function init(runtime) { function init(runtime) {
settings = runtime.settings; settings = runtime.settings;
credentials.init(runtime.storage); credentials.init();
flows.init(runtime); flows.init(runtime);
registry.init(runtime); registry.init(runtime);
context.init(runtime.settings); context.init(runtime.settings);

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2013, 2015 IBM Corp. * Copyright 2013, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,17 +55,35 @@ var storageModuleInterface = {
return storageModule.init(runtime.settings); return storageModule.init(runtime.settings);
}, },
getFlows: function() { getFlows: function() {
return storageModule.getFlows(); return storageModule.getFlows().then(function(flows) {
return storageModule.getCredentials().then(function(creds) {
return {
flows: flows,
credentials: creds
}
})
});
}, },
saveFlows: function(flows) { saveFlows: function(config) {
return storageModule.saveFlows(flows); var flows = config.flows;
}, var credentials = config.credentials;
getCredentials: function() { var credentialSavePromise;
return storageModule.getCredentials(); if (config.credentialsDirty) {
}, credentialSavePromise = storageModule.saveCredentials(credentials);
saveCredentials: function(credentials) { } else {
return storageModule.saveCredentials(credentials); credentialSavePromise = when.resolve();
}
return credentialSavePromise.then(function() {
return storageModule.saveFlows(flows);
});
}, },
// getCredentials: function() {
// return storageModule.getCredentials();
// },
// saveCredentials: function(credentials) {
// return storageModule.saveCredentials(credentials);
// },
getSettings: function() { getSettings: function() {
if (settingsAvailable) { if (settingsAvailable) {
return storageModule.getSettings(); return storageModule.getSettings();

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2014, 2015 IBM Corp. * Copyright 2014, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,34 +19,21 @@ var sinon = require("sinon");
var when = require("when"); var when = require("when");
var util = require("util"); var util = require("util");
var express = require("express");
var request = require("supertest");
var index = require("../../../../red/runtime/nodes/index"); var index = require("../../../../red/runtime/nodes/index");
var credentials = require("../../../../red/runtime/nodes/credentials"); var credentials = require("../../../../red/runtime/nodes/credentials");
var log = require("../../../../red/runtime/log"); var log = require("../../../../red/runtime/log");
var auth = require("../../../../red/api/auth");
describe('Credentials', function() { describe('red/runtime/nodes/credentials', function() {
afterEach(function() { afterEach(function() {
index.clearRegistry(); index.clearRegistry();
}); });
it('loads from storage',function(done) { it('loads provided credentials',function(done) {
credentials.init();
var storage = { credentials.load({"a":{"b":1,"c":2}}).then(function() {
getCredentials: function() {
return when.promise(function(resolve,reject) {
resolve({"a":{"b":1,"c":2}});
});
}
};
credentials.init(storage);
credentials.load().then(function() {
credentials.get("a").should.have.property('b',1); credentials.get("a").should.have.property('b',1);
credentials.get("a").should.have.property('c',2); credentials.get("a").should.have.property('c',2);
@ -54,182 +41,99 @@ describe('Credentials', function() {
done(); done();
}); });
}); });
it('adds a new credential',function(done) {
it('saves to storage', function(done) { credentials.init();
var storage = { credentials.load({"a":{"b":1,"c":2}}).then(function() {
saveCredentials: function(creds) { credentials.dirty().should.be.false;
return when.resolve("saveCalled"); should.not.exist(credentials.get("b"));
} credentials.add("b",{"foo":"bar"}).then(function() {
}; credentials.get("b").should.have.property("foo","bar");
credentials.init(storage); credentials.dirty().should.be.true;
credentials.save().then(function(res) { done();
res.should.equal("saveCalled");
done();
});
});
it('saves to storage when new cred added', function(done) {
var storage = {
getCredentials: function() {
return when.promise(function(resolve,reject) {
resolve({"a":{"b":1,"c":2}});
});
},
saveCredentials: function(creds) {
return when(true);
}
};
sinon.spy(storage,"saveCredentials");
credentials.init(storage);
credentials.load().then(function() {
should.not.exist(credentials.get("b"))
credentials.add('b',{"d":3});
storage.saveCredentials.callCount.should.be.exactly(1);
credentials.get("b").should.have.property('d',3);
storage.saveCredentials.restore();
done();
});
});
it('deletes from storage', function(done) {
var storage = {
getCredentials: function() {
return when.promise(function(resolve,reject) {
resolve({"a":{"b":1,"c":2}});
});
},
saveCredentials: function(creds) {
return when(true);
}
};
sinon.spy(storage,"saveCredentials");
credentials.init(storage);
credentials.load().then(function() {
should.exist(credentials.get("a"))
credentials.delete('a');
storage.saveCredentials.callCount.should.be.exactly(1);
should.not.exist(credentials.get("a"));
storage.saveCredentials.restore();
done();
});
});
it('clean up from storage', function(done) {
var storage = {
getCredentials: function() {
return when.promise(function(resolve,reject) {
resolve({"a":{"b":1,"c":2}});
});
},
saveCredentials: function(creds) {
return when(true);
}
};
sinon.spy(storage,"saveCredentials");
credentials.init(storage);
credentials.load().then(function() {
should.exist(credentials.get("a"));
credentials.clean([]);
storage.saveCredentials.callCount.should.be.exactly(1);
should.not.exist(credentials.get("a"));
storage.saveCredentials.restore();
done();
});
});
it('handle error loading from storage', function(done) {
var storage = {
getCredentials: function() {
return when.promise(function(resolve,reject) {
reject("test forcing failure");
});
},
saveCredentials: function(creds) {
return when(true);
}
};
var logmsg = 'nothing logged yet';
sinon.stub(log, 'warn', function(msg) {
logmsg = msg;
});
credentials.init(storage);
credentials.load().then(function() {
log.warn.calledOnce.should.be.true;
log.warn.restore();
done();
}).otherwise(function(err){
log.warn.restore();
done(err);
});
});
it('credential type is not registered when extract', function(done) {
var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}];
var storage = {
getFlows: function() {
var defer = when.defer();
defer.resolve(testFlows);
return defer.promise;
},
getCredentials: function() {
return when.promise(function(resolve,reject) {
resolve({"tab1":{"b":1,"c":2}});
});
},
saveFlows: function(conf) {
var defer = when.defer();
defer.resolve();
should.deepEqual(testFlows, conf);
return defer.promise;
},
saveCredentials: function(creds) {
return when(true);
},
getSettings: function() {
return when({});
},
saveSettings: function(s) {
return when();
}
};
function TestNode(n) {
index.createNode(this, n);
this.id = 'tab1';
this.type = 'test';
this.name = 'barney';
var node = this;
this.on("log", function() {
// do nothing
}); });
}
var logmsg = 'nothing logged yet';
sinon.stub(log, 'warn', function(msg) {
logmsg = msg;
}); });
var settings = { });
available: function() { return false;} it('deletes an existing credential',function(done) {
} credentials.init();
index.init({settings:settings, storage:storage}); credentials.load({"a":{"b":1,"c":2}}).then(function() {
index.registerType('test', TestNode); credentials.dirty().should.be.false;
index.loadFlows().then(function() { credentials.delete("a");
var testnode = new TestNode({id:'tab1',type:'test',name:'barney'}); should.not.exist(credentials.get("a"));
credentials.extract(testnode); credentials.dirty().should.be.true;
log.warn.calledOnce.should.be.true;
log.warn.restore();
done(); done();
}).otherwise(function(err){
log.warn.restore();
done(err);
}); });
}); });
it('extract and store credential updates in the provided node', function(done) { it('exports the credentials, clearing dirty flag', function(done) {
credentials.init({saveCredentials:function(){}},express()); credentials.init();
credentials.register("test",{ var creds = {"a":{"b":1,"c":2}};
credentials.load(creds).then(function() {
credentials.add("b",{"foo":"bar"}).then(function() {
credentials.dirty().should.be.true;
credentials.export().then(function(exported) {
exported.should.eql(creds);
credentials.dirty().should.be.false;
done();
})
});
});
})
describe("#clean",function() {
it("removes credentials of unknown nodes",function(done) {
credentials.init();
var creds = {"a":{"b":1,"c":2},"b":{"d":3}};
credentials.load(creds).then(function() {
credentials.dirty().should.be.false;
should.exist(credentials.get("a"));
should.exist(credentials.get("b"));
credentials.clean([{id:"b"}]).then(function() {
credentials.dirty().should.be.true;
should.not.exist(credentials.get("a"));
should.exist(credentials.get("b"));
done();
});
});
});
it("extracts credentials of known nodes",function(done) {
credentials.init();
credentials.register("testNode",{"b":"text","c":"password"})
var creds = {"a":{"b":1,"c":2}};
var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}];
credentials.load(creds).then(function() {
credentials.dirty().should.be.false;
credentials.clean(newConfig).then(function() {
credentials.dirty().should.be.true;
credentials.get("a").should.have.property('b',"newBValue");
credentials.get("a").should.have.property('c',"newCValue");
should.not.exist(newConfig[0].credentials);
done();
});
});
});
});
it('warns if a node has no credential definition', function(done) {
credentials.init();
credentials.load({}).then(function() {
var node = {id:"node",type:"test",credentials:{
user1:"newUser",
password1:"newPassword"
}};
sinon.spy(log,"warn");
credentials.extract(node);
log.warn.called.should.be.true;
should.not.exist(node.credentials);
log.warn.restore();
done();
});
})
it('extract credential updates in the provided node', function(done) {
credentials.init();
var defintion = {
user1:{type:"text"}, user1:{type:"text"},
password1:{type:"password"}, password1:{type:"password"},
user2:{type:"text"}, user2:{type:"text"},
@ -237,28 +141,46 @@ describe('Credentials', function() {
user3:{type:"text"}, user3:{type:"text"},
password3:{type:"password"} password3:{type:"password"}
};
credentials.register("test",defintion);
var def = credentials.getDefinition("test");
defintion.should.eql(def);
credentials.load({"node":{user1:"abc",password1:"123",user2:"def",password2:"456",user3:"ghi",password3:"789"}}).then(function() {
var node = {id:"node",type:"test",credentials:{
// user1 unchanged
password1:"__PWRD__",
user2: "",
password2:" ",
user3:"newUser",
password3:"newPassword"
}};
credentials.dirty().should.be.false;
credentials.extract(node);
node.should.not.have.a.property("credentials");
credentials.dirty().should.be.true;
var newCreds = credentials.get("node");
newCreds.should.have.a.property("user1","abc");
newCreds.should.have.a.property("password1","123");
newCreds.should.not.have.a.property("user2");
newCreds.should.not.have.a.property("password2");
newCreds.should.have.a.property("user3","newUser");
newCreds.should.have.a.property("password3","newPassword");
done();
}); });
credentials.add("node",{user1:"abc",password1:"123",user2:"def",password2:"456",user3:"ghi",password3:"789"}); });
var node = {id:"node",type:"test",credentials:{ it('extract ignores node without credentials', function(done) {
// user1 unchanged credentials.init();
password1:"__PWRD__", credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() {
user2: "", var node = {id:"node",type:"test"};
password2:" ",
user3:"newUser",
password3:"newPassword"
}};
credentials.extract(node);
node.should.not.have.a.property("credentials"); credentials.dirty().should.be.false;
credentials.extract(node);
var newCreds = credentials.get("node"); credentials.dirty().should.be.false;
newCreds.should.have.a.property("user1","abc"); done();
newCreds.should.have.a.property("password1","123"); });
newCreds.should.not.have.a.property("user2");
newCreds.should.not.have.a.property("password2");
newCreds.should.have.a.property("user3","newUser");
newCreds.should.have.a.property("password3","newPassword");
done();
}); });
}) })

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2014, 2015 IBM Corp. * Copyright 2014, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,8 +30,6 @@ describe('flows/index', function() {
var storage; var storage;
var eventsOn; var eventsOn;
var credentialsExtract;
var credentialsSave;
var credentialsClean; var credentialsClean;
var credentialsLoad; var credentialsLoad;
@ -50,13 +48,10 @@ describe('flows/index', function() {
beforeEach(function() { beforeEach(function() {
eventsOn = sinon.spy(events,"on"); eventsOn = sinon.spy(events,"on");
credentialsExtract = sinon.stub(credentials,"extract",function(conf) {
delete conf.credentials;
});
credentialsSave = sinon.stub(credentials,"save",function() {
return when.resolve();
});
credentialsClean = sinon.stub(credentials,"clean",function(conf) { credentialsClean = sinon.stub(credentials,"clean",function(conf) {
conf.forEach(function(n) {
delete n.credentials;
});
return when.resolve(); return when.resolve();
}); });
credentialsLoad = sinon.stub(credentials,"load",function() { credentialsLoad = sinon.stub(credentials,"load",function() {
@ -97,8 +92,6 @@ describe('flows/index', function() {
afterEach(function(done) { afterEach(function(done) {
eventsOn.restore(); eventsOn.restore();
credentialsExtract.restore();
credentialsSave.restore();
credentialsClean.restore(); credentialsClean.restore();
credentialsLoad.restore(); credentialsLoad.restore();
flowCreate.restore(); flowCreate.restore();
@ -121,7 +114,6 @@ describe('flows/index', function() {
]; ];
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() { flows.setFlows(originalConfig).then(function() {
credentialsExtract.called.should.be.false;
credentialsClean.called.should.be.true; credentialsClean.called.should.be.true;
storage.hasOwnProperty('conf').should.be.true; storage.hasOwnProperty('conf').should.be.true;
flows.getFlows().should.eql(originalConfig); flows.getFlows().should.eql(originalConfig);
@ -136,8 +128,7 @@ describe('flows/index', function() {
]; ];
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.setFlows(originalConfig,"load").then(function() { flows.setFlows(originalConfig,"load").then(function() {
credentialsExtract.called.should.be.false; credentialsClean.called.should.be.false;
credentialsClean.called.should.be.true;
// 'load' type does not trigger a save // 'load' type does not trigger a save
storage.hasOwnProperty('conf').should.be.false; storage.hasOwnProperty('conf').should.be.false;
flows.getFlows().should.eql(originalConfig); flows.getFlows().should.eql(originalConfig);
@ -148,18 +139,17 @@ describe('flows/index', function() {
it('extracts credentials from the full flow', function(done) { it('extracts credentials from the full flow', function(done) {
var originalConfig = [ var originalConfig = [
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{}}, {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{"a":1}},
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.setFlows(originalConfig).then(function() { flows.setFlows(originalConfig).then(function() {
credentialsExtract.called.should.be.true;
credentialsClean.called.should.be.true; credentialsClean.called.should.be.true;
storage.hasOwnProperty('conf').should.be.true; storage.hasOwnProperty('conf').should.be.true;
var cleanedFlows = flows.getFlows(); var cleanedFlows = flows.getFlows();
storage.conf.should.eql(cleanedFlows); storage.conf.flows.should.eql(cleanedFlows);
cleanedFlows.should.not.eql(originalConfig); cleanedFlows.should.not.eql(originalConfig);
cleanedFlows[0].credentials = {}; cleanedFlows[0].credentials = {"a":1};
cleanedFlows.should.eql(originalConfig); cleanedFlows.should.eql(originalConfig);
done(); done();
}); });
@ -175,7 +165,7 @@ describe('flows/index', function() {
newConfig.push({id:"t2",type:"tab"}); newConfig.push({id:"t2",type:"tab"});
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}); newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -204,7 +194,7 @@ describe('flows/index', function() {
newConfig.push({id:"t2",type:"tab"}); newConfig.push({id:"t2",type:"tab"});
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}); newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -232,13 +222,11 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.load().then(function() { flows.load().then(function() {
credentialsExtract.called.should.be.false;
credentialsLoad.called.should.be.true; credentialsLoad.called.should.be.true;
credentialsClean.called.should.be.true;
// 'load' type does not trigger a save // 'load' type does not trigger a save
storage.hasOwnProperty('conf').should.be.false; storage.hasOwnProperty('conf').should.be.false;
flows.getFlows().should.eql(originalConfig); flows.getFlows().should.eql(originalConfig);
@ -254,7 +242,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -274,7 +262,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
@ -293,7 +281,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.load().then(function() { flows.load().then(function() {
@ -316,7 +304,7 @@ describe('flows/index', function() {
}); });
describe('#get',function() { describe.skip('#get',function() {
}); });
@ -327,7 +315,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.load().then(function() { flows.load().then(function() {
@ -351,7 +339,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -376,7 +364,7 @@ describe('flows/index', function() {
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]} {id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -404,7 +392,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -430,7 +418,7 @@ describe('flows/index', function() {
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]} {id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
events.once('nodes-started',function() { events.once('nodes-started',function() {
@ -505,7 +493,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
flows.init({settings:{},storage:storage}); flows.init({settings:{},storage:storage});
flows.load().then(function() { flows.load().then(function() {
@ -529,7 +517,7 @@ describe('flows/index', function() {
{id:"t1",type:"tab"} {id:"t1",type:"tab"}
]; ];
storage.getFlows = function() { storage.getFlows = function() {
return when.resolve(originalConfig); return when.resolve({flows:originalConfig});
} }
storage.setFlows = function() { storage.setFlows = function() {
return when.resolve(); return when.resolve();

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2014 IBM Corp. * Copyright 2014, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,19 +40,13 @@ describe("red/nodes/index", function() {
var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}]; var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}];
var storage = { var storage = {
getFlows: function() { getFlows: function() {
return when(testFlows); return when({flows:testFlows,credentials:{"tab1":{"b":1,"c":2}}});
}, },
getCredentials: function() { saveFlows: function(conf) {
return when({"tab1":{"b":1,"c":2}}); should.deepEqual(testFlows, conf.flows);
}, return when();
saveFlows: function(conf) { }
should.deepEqual(testFlows, conf);
return when();
},
saveCredentials: function(creds) {
return when(true);
}
}; };
var settings = { var settings = {

View File

@ -1,5 +1,5 @@
/** /**
* Copyright 2014, 2015 IBM Corp. * Copyright 2014, 2016 IBM Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -75,12 +75,14 @@ describe("red/storage/index", function() {
}, },
getFlows : function() { getFlows : function() {
calledFlagGetFlows = true; calledFlagGetFlows = true;
return when.resolve([]);
}, },
saveFlows : function (flows) { saveFlows : function (flows) {
flows.should.be.true; flows.should.be.true;
}, },
getCredentials : function() { getCredentials : function() {
calledFlagGetCredentials = true; calledFlagGetCredentials = true;
return when.resolve({});
}, },
saveCredentials : function(credentials) { saveCredentials : function(credentials) {
credentials.should.be.true; credentials.should.be.true;
@ -127,9 +129,7 @@ describe("red/storage/index", function() {
storage.init(moduleToLoad); storage.init(moduleToLoad);
storage.getFlows(); storage.getFlows();
storage.saveFlows(true); storage.saveFlows({flows:[],credentials:{}});
storage.getCredentials();
storage.saveCredentials(true);
storage.getSettings(); storage.getSettings();
storage.saveSettings(true); storage.saveSettings(true);
storage.getSessions(); storage.getSessions();