test for new Iden functions

This commit is contained in:
Matias Alejo Garcia 2014-09-28 18:38:06 -03:00
commit 0afc5f2c0c
3 changed files with 293 additions and 174 deletions

View file

@ -7,6 +7,7 @@ var PrivateKey = require('./PrivateKey');
var Wallet = require('./Wallet'); var Wallet = require('./Wallet');
var _ = require('underscore'); var _ = require('underscore');
var log = require('../log'); var log = require('../log');
var version = require('../../version').version;
var PluginManager = require('./PluginManager'); var PluginManager = require('./PluginManager');
var Profile = require('./Profile'); var Profile = require('./Profile');
var Insight = module.exports.Insight = require('./Insight'); var Insight = module.exports.Insight = require('./Insight');
@ -19,20 +20,17 @@ var Storage = module.exports.Storage = require('./Storage');
* *
* @param {Object} config - configuration for this wallet * @param {Object} config - configuration for this wallet
* @param {Object} config.wallet - default configuration for the wallet * @param {Object} config.wallet - default configuration for the wallet
* @TODO: put `version` inside of the config object
* @param {string} version - the version of copay for which this wallet was generated (for example, 0.4.7)
* @constructor * @constructor
*/ */
function Identity(config, version, pluginManager) { function Identity(email, password, opts) {
var self = this; preconditions.checkArgument(opts);
preconditions.checkArgument(config);
var storageOpts = {}; var storageOpts = {};
if (pluginManager) { if (opts.pluginManager) {
storageOpts = { storageOpts = _.clone({
db: pluginManager.get('DB') db: opts.pluginManager.get('DB')
}; });
/* /*
* TODO (plugins for other services) * TODO (plugins for other services)
* *
@ -41,28 +39,115 @@ function Identity(config, version, pluginManager) {
* } * }
*/ */
} }
storageOpts.password = password;
this.storage = this._getStorage(storageOpts); this.storage = Identity._newStorage(storageOpts);
this.networks = { this.networks = {
'livenet': new Insight(config.network.livenet), 'livenet': Identity._newInsight(opts.network.livenet),
'testnet': new Insight(config.network.testnet), 'testnet': Identity._newInsight(opts.network.testnet),
}; };
this.blockchains = { this.blockchains = {
'livenet': new Insight(config.network.livenet), 'livenet': Identity._newInsight(opts.network.livenet),
'testnet': new Insight(config.network.testnet), 'testnet': Identity._newInsight(opts.network.testnet),
}; };
this.walletDefaults = config.wallet || {}; this.walletDefaults = opts.wallet || {};
this.version = version; this.version = opts.version || version;
this.wallets = [];
this.profile = Identity._newProfile({
email: email,
}, password, this.storage);
}; };
/* for stubbing */ /* for stubbing */
Identity.prototype._getStorage = function(opts) { Identity._newProfile = function(info, password, storage) {
return new Profile(info, password, storage);
};
/* for stubbing */
Identity._newInsight = function(opts) {
return new Insight(opts);
};
/* for stubbing */
Identity._newStorage = function(opts) {
return new Storage(opts); return new Storage(opts);
}; };
/**
* creates and Identity
*
* @param email
* @param password
* @param opts
* @param cb
* @return {undefined}
*/
Identity.create = function(email, password, opts, cb) {
var iden = new Identity(email, password, opts);
iden.store({
overwrite: false,
}, function(err) {
return cb(err, iden);
});
};
/**
* validates Profile's email
*
* @param authcode
* @param cb
* @return {undefined}
*/
Identity.prototype.validate = function(authcode, cb) {
// TODO
console.log('[Identity.js.99] TODO: Should validate email thru authcode'); //TODO
return cb();
};
/**
* open's an Identity from storage
*
* @param email
* @param password
* @param opts
* @param cb
* @return {undefined}
*/
Identity.open = function(email, password, opts, cb) {
var iden = new Identity(email, password, opts);
iden.read(function(err){
return cb(err, iden);
});
};
/**
* isAvailable
*
* @param email
* @param opts
* @param cb
* @return {undefined}
*/
Identity.isAvailable = function(email, opts, cb) {
console.log('[Identity.js.127:isAvailable:] TODO'); //TODO
return cb();
};
Identity.prototype.store = function(opts, cb) {
console.log('[Identity.js.142] TODO .store'); //TODO
return cb();
};
/** /**
* @desc obtain network name from serialized wallet * @desc obtain network name from serialized wallet
* @param {Object} wallet object * @param {Object} wallet object
@ -81,7 +166,7 @@ Identity.prototype.obtainNetworkName = function(obj) {
* @param {string[]} skipFields - fields to skip when importing * @param {string[]} skipFields - fields to skip when importing
* @return {Wallet} * @return {Wallet}
*/ */
Identity.prototype.fromObj = function(inObj, skipFields) { Identity.prototype._fromObj = function(inObj, skipFields) {
var networkName = this.obtainNetworkName(inObj); var networkName = this.obtainNetworkName(inObj);
preconditions.checkState(networkName); preconditions.checkState(networkName);
preconditions.checkArgument(inObj); preconditions.checkArgument(inObj);
@ -113,7 +198,7 @@ Identity.prototype.fromObj = function(inObj, skipFields) {
* @param {string[]} skipFields - fields to ignore when importing * @param {string[]} skipFields - fields to ignore when importing
* @return {Wallet} * @return {Wallet}
*/ */
Identity.prototype.fromEncryptedObj = function(base64, passphrase, skipFields) { Identity.prototype.importWallet = function(base64, passphrase, skipFields) {
this.storage.setPassphrase(passphrase); this.storage.setPassphrase(passphrase);
var walletObj = this.storage.import(base64); var walletObj = this.storage.import(base64);
if (!walletObj) return false; if (!walletObj) return false;
@ -149,7 +234,7 @@ Identity.prototype.migrateWallet = function(walletId, passphrase, cb) {
* @param {string[]} skipFields - parameters to ignore when importing * @param {string[]} skipFields - parameters to ignore when importing
* @param {function} callback - {err, Wallet} * @param {function} callback - {err, Wallet}
*/ */
Identity.prototype.read = function(walletId, skipFields, cb) { Identity.prototype._readWallet = function(walletId, skipFields, cb) {
var self = this, var self = this,
err; err;
var obj = {}; var obj = {};
@ -330,13 +415,13 @@ Identity.prototype._checkVersion = function(inVersion) {
* @param {function} callback (err, {Wallet}) * @param {function} callback (err, {Wallet})
* @return * @return
*/ */
Identity.prototype.open = function(walletId, passphrase, cb) { Identity.prototype.openWallet = function(walletId, passphrase, cb) {
preconditions.checkArgument(cb); preconditions.checkArgument(cb);
var self = this; var self = this;
self.storage.setPassphrase(passphrase); self.storage.setPassphrase(passphrase);
self.migrateWallet(walletId, passphrase, function() { self.migrateWallet(walletId, passphrase, function() {
self.read(walletId, null, function(err, w) { self._readWallet(walletId, null, function(err, w) {
if (err) return cb(err); if (err) return cb(err);
w.store(function(err) { w.store(function(err) {
@ -348,7 +433,7 @@ Identity.prototype.open = function(walletId, passphrase, cb) {
}); });
}; };
Identity.prototype.getWallets = function(cb) { Identity.prototype.listWallets = function(cb) {
var self = this; var self = this;
this.storage.getWallets(function(wallets) { this.storage.getWallets(function(wallets) {
wallets.forEach(function(i) { wallets.forEach(function(i) {
@ -373,7 +458,7 @@ Identity.prototype.getWallets = function(cb) {
* @callback cb * @callback cb
* @return {?} the result of the callback * @return {?} the result of the callback
*/ */
Identity.prototype.delete = function(walletId, cb) { Identity.prototype.deleteWallet = function(walletId, cb) {
var self = this; var self = this;
self.storage.deleteWallet(walletId, function(err) { self.storage.deleteWallet(walletId, function(err) {
if (err) return cb(err); if (err) return cb(err);
@ -479,7 +564,7 @@ Identity.prototype.joinWallet = function(opts, cb) {
walletOpts.nickname = opts.nickname; walletOpts.nickname = opts.nickname;
walletOpts.passphrase = opts.passphrase; walletOpts.passphrase = opts.passphrase;
self.create(walletOpts, function(err, w) { self.createWallet(walletOpts, function(err, w) {
if (w) { if (w) {
w.sendWalletReady(decodedSecret.pubKey); w.sendWalletReady(decodedSecret.pubKey);

View file

@ -4,16 +4,16 @@ var _ = require('underscore');
var log = require('../log'); var log = require('../log');
var bitcore = require('bitcore'); var bitcore = require('bitcore');
function Profile(opts, password, storage) { function Profile(info, password, storage) {
preconditions.checkArgument(opts.email); preconditions.checkArgument(info.email);
preconditions.checkArgument(password); preconditions.checkArgument(password);
preconditions.checkArgument(storage); preconditions.checkArgument(storage);
preconditions.checkArgument(storage.getItem); preconditions.checkArgument(storage.getItem);
this.email = opts.email; this.email = info.email;
this.extra = info.extra;
this.hash = bitcore.util.sha256ripe160(this.email + this.password).toString('hex'); this.hash = bitcore.util.sha256ripe160(this.email + this.password).toString('hex');
this.storage = storage; this.storage = storage;
this.extra = opts.extra;
}; };
Profile.fromObj = function(obj, password, storage) { Profile.fromObj = function(obj, password, storage) {

View file

@ -28,39 +28,39 @@ function assertObjectEqual(a, b) {
describe('Identity model', function() { describe('Identity model', function() {
var iden, storage, wallet, profile;
var wf;
beforeEach(function() { beforeEach(function() {
var s = sinon.stub(); storage = sinon.stub();
storage.getItem = sinon.stub();
Identity.prototype._getStorage = sinon.stub().returns(s); storage.setPassphrase = sinon.spy();
storage.getSessionId = sinon.spy();
wf = new Identity(config,'0.0.1'); storage.setFromObj = sinon.spy();
storage.setLastOpened = sinon.stub().yields(null);
s.setPassphrase = sinon.spy(); Identity._newStorage = sinon.stub().returns(storage);
s.getSessionId = sinon.spy();
s.setFromObj = sinon.spy();
s.setLastOpened = sinon.stub().yields(null);
var w = sinon.stub(); wallet = sinon.stub();
w.store = sinon.stub().yields(null); wallet.store = sinon.stub().yields(null);
Identity._newWallet = sinon.stub().returns(wallet);
wf._getWallet = sinon.stub().returns(w); profile = sinon.stub();
profile.test = sinon.stub();
Identity._newProfile = sinon.stub().returns(profile);
iden = new Identity(email, password, config);
}); });
afterEach(function() { afterEach(function() {
wf = undefined; iden = undefined;
}); });
var email = 'hola@hola.com';
var password = 'password';
var config = { var config = {
Network: FakeNetwork,
Blockchain: FakeBlockchain,
Storage: FakeStorage,
wallet: { wallet: {
requiredCopayers: 3, requiredCopayers: 3,
totalCopayers: 5, totalCopayers: 5,
@ -88,30 +88,64 @@ describe('Identity model', function() {
url: 'https://insight.bitpay.com:443' url: 'https://insight.bitpay.com:443'
}, },
}, },
version: '0.0.1',
}; };
describe('#constructor', function() { describe.only('#constructors', function() {
it('should create the factory', function() { describe('#new', function() {
var wf = new Identity(config, '0.0.1'); it('should create an identity', function() {
should.exist(wf); var iden = new Identity(email, password, config);
wf.walletDefaults.should.deep.equal(config.wallet); should.exist(iden);
wf.version.should.equal('0.0.1'); iden.walletDefaults.should.deep.equal(config.wallet);
iden.version.should.equal('0.0.1');
should.exist(iden.profile.test);
Identity._newProfile.getCall(0).args[0].should.deep.equal({
email: email
});
Identity._newProfile.getCall(0).args[1].should.equal(password);
Identity._newProfile.getCall(0).args[2].should.equal(iden.storage);
});
});
describe('#create', function(done) {
it('should call .store', function(done) {
Identity.prototype.store = sinon.stub().yields(null);
Identity.create(email, password, config, function(err, iden) {
should.not.exist(err);
should.exist(iden.profile.test);
iden.store.getCall(0).args[0].should.deep.equal({overwrite:false});
done();
});
});
});
describe('#open', function(done) {
it('should call .read', function(done) {
Identity.prototype.read = sinon.stub().yields(null);
Identity.open(email, password, config, function(err, iden) {
should.not.exist(err);
should.exist(iden.profile.test);
iden.read.calledOnce.should.equal(true);
done();
});
});
}); });
}); });
// TODO this is a WALLET TEST! not Wallet Factory. Move it. // TODO this is a WALLET TEST! not Wallet Factory. Move it.
describe.skip('#fromObj / #toObj', function() { describe.skip('#fromObj / #toObj', function() {
it('round trip', function() { it('round trip', function() {
var wf = new Identity(config, '0.0.5'); var iden = new Identity(config, '0.0.5');
var original = JSON.parse(o); var original = JSON.parse(o);
var o2 = wf.fromObj(original).toObj(); var o2 = iden.fromObj(original).toObj();
assertObjectEqual(o2, original); assertObjectEqual(o2, original);
}); });
it('round trip, using old copayerIndex', function() { it('round trip, using old copayerIndex', function() {
var wf = new Identity(config, '0.0.5'); var iden = new Identity(config, '0.0.5');
var w = wf.fromObj(JSON.parse(o)); var w = iden.fromObj(JSON.parse(o));
should.exist(w); should.exist(w);
w.id.should.equal("dbfe10c3fae71cea"); w.id.should.equal("dbfe10c3fae71cea");
@ -122,8 +156,8 @@ describe('Identity model', function() {
}); });
it('#fromObj, skipping fields', function() { it('#fromObj, skipping fields', function() {
var wf = new Identity(config, '0.0.5'); var iden = new Identity(config, '0.0.5');
var w = wf.fromObj(JSON.parse(o), ['publicKeyRing']); var w = iden.fromObj(JSON.parse(o), ['publicKeyRing']);
should.exist(w); should.exist(w);
w.id.should.equal("dbfe10c3fae71cea"); w.id.should.equal("dbfe10c3fae71cea");
@ -139,8 +173,8 @@ describe('Identity model', function() {
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}';
var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}';
var wf = new Identity(config, '0.0.5'); var iden = new Identity(config, '0.0.5');
var w = wf.fromObj(JSON.parse(o)); var w = iden.fromObj(JSON.parse(o));
should.exist(w); should.exist(w);
w.id.should.equal("dbfe10c3fae71cea"); w.id.should.equal("dbfe10c3fae71cea");
@ -152,19 +186,19 @@ describe('Identity model', function() {
}); });
}); });
describe('#fromEncryptedObj', function() { describe('#import', function() {
it('should create wallet from encrypted object', function() { it('should create wallet from encrypted object', function() {
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
wf.storage.import = sinon.stub().withArgs('base64').returns('walletObj'); iden.storage.import = sinon.stub().withArgs('base64').returns('walletObj');
wf.fromObj = sinon.stub().withArgs('walletObj').returns('ok'); iden.fromObj = sinon.stub().withArgs('walletObj').returns('ok');
var w = wf.fromEncryptedObj("encrypted object", "123"); var w = iden.fromEncryptedObj("encrypted object", "123");
w.should.equal('ok'); w.should.equal('ok');
wf.storage.setPassphrase.calledOnce.should.be.true; iden.storage.setPassphrase.calledOnce.should.be.true;
wf.storage.setPassphrase.getCall(0).args[0].should.equal('123'); iden.storage.setPassphrase.getCall(0).args[0].should.equal('123');
wf.storage.import.calledOnce.should.be.true; iden.storage.import.calledOnce.should.be.true;
wf.fromObj.calledWith('walletObj').should.be.true; iden.fromObj.calledWith('walletObj').should.be.true;
}); });
it('should import and update indexes', function() { it('should import and update indexes', function() {
var wallet = { var wallet = {
@ -173,26 +207,26 @@ describe('Identity model', function() {
cb(); cb();
} }
}; };
wf.fromEncryptedObj = sinon.stub().returns(wallet); iden.fromEncryptedObj = sinon.stub().returns(wallet);
var w = wf.fromEncryptedObj("encrypted", "password"); var w = iden.fromEncryptedObj("encrypted", "password");
should.exist(w); should.exist(w);
wallet.should.equal(w); wallet.should.equal(w);
}); });
it('should import with a wrong password', function() { it('should import with a wrong password', function() {
wf.fromEncryptedObj = sinon.stub().returns(null); iden.fromEncryptedObj = sinon.stub().returns(null);
var w = wf.fromEncryptedObj("encrypted", "passwordasdfasdf"); var w = iden.fromEncryptedObj("encrypted", "passwordasdfasdf");
should.not.exist(w); should.not.exist(w);
}); });
}); });
describe('#getWallets', function() { describe('#getWallets', function() {
it('should return empty array if no wallets', function(done) { it('should return empty array if no wallets', function(done) {
wf.storage.getWallets = sinon.stub().yields([]); iden.storage.getWallets = sinon.stub().yields([]);
wf.storage.getLastOpened = sinon.stub().yields(null); iden.storage.getLastOpened = sinon.stub().yields(null);
wf.getWallets(function(err, ws) { iden.getWallets(function(err, ws) {
should.not.exist(err); should.not.exist(err);
ws.should.deep.equal([]); ws.should.deep.equal([]);
done(); done();
@ -200,16 +234,16 @@ describe('Identity model', function() {
}); });
it('should be able to get current wallets', function(done) { it('should be able to get current wallets', function(done) {
wf.storage.getWallets = sinon.stub().yields([{ iden.storage.getWallets = sinon.stub().yields([{
name: 'w1', name: 'w1',
id: 'id1', id: 'id1',
}, { }, {
name: 'w', name: 'w',
id: 'id2', id: 'id2',
}]); }]);
wf.storage.getLastOpened = sinon.stub().yields(null); iden.storage.getLastOpened = sinon.stub().yields(null);
wf.getWallets(function(err, ws) { iden.getWallets(function(err, ws) {
should.not.exist(err); should.not.exist(err);
ws.should.deep.equal([{ ws.should.deep.equal([{
name: 'w1', name: 'w1',
@ -224,16 +258,16 @@ describe('Identity model', function() {
}); });
}); });
it('should include last used info', function(done) { it('should include last used info', function(done) {
wf.storage.getWallets = sinon.stub().yields([{ iden.storage.getWallets = sinon.stub().yields([{
name: 'w1', name: 'w1',
id: 'id1', id: 'id1',
}, { }, {
name: 'w', name: 'w',
id: 'id2', id: 'id2',
}]); }]);
wf.storage.getLastOpened = sinon.stub().yields('id2'); iden.storage.getLastOpened = sinon.stub().yields('id2');
wf.getWallets(function(err, ws) { iden.getWallets(function(err, ws) {
should.not.exist(err); should.not.exist(err);
ws.should.deep.equal([{ ws.should.deep.equal([{
name: 'w1', name: 'w1',
@ -252,19 +286,19 @@ describe('Identity model', function() {
describe('#delete', function() { describe('#delete', function() {
it('should call deleteWallet', function(done) { it('should call deleteWallet', function(done) {
wf.storage.deleteWallet = sinon.stub().yields(null); iden.storage.deleteWallet = sinon.stub().yields(null);
wf.delete('xxx', function() { iden.delete('xxx', function() {
wf.storage.deleteWallet.getCall(0).args[0].should.equal('xxx'); iden.storage.deleteWallet.getCall(0).args[0].should.equal('xxx');
done(); done();
}); });
}); });
it('should call lastOpened', function(done) { it('should call lastOpened', function(done) {
wf.storage.deleteWallet = sinon.stub().yields(null); iden.storage.deleteWallet = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.delete('xxx', function() { iden.delete('xxx', function() {
wf.storage.setLastOpened.calledOnce.should.equal(true); iden.storage.setLastOpened.calledOnce.should.equal(true);
should.not.exist(wf.storage.setLastOpened.getCall(0).args[0]); should.not.exist(iden.storage.setLastOpened.getCall(0).args[0]);
done(); done();
}); });
}); });
@ -273,9 +307,9 @@ describe('Identity model', function() {
describe('#read', function() { describe('#read', function() {
it('should fail to read unexisting wallet', function(done) { it('should fail to read unexisting wallet', function(done) {
wf.storage.getFirst = sinon.stub().yields(null, {}); iden.storage.getFirst = sinon.stub().yields(null, {});
wf.read('id', [], function(err, w) { iden.read('id', [], function(err, w) {
should.not.exist(w); should.not.exist(w);
should.exist(err); should.exist(err);
should.exist(err.message); should.exist(err.message);
@ -285,10 +319,10 @@ describe('Identity model', function() {
}); });
}); });
it('should fail to read broken wallet', function(done) { it('should fail to read broken wallet', function(done) {
wf.storage.getFirst = sinon.stub().yields(null, { iden.storage.getFirst = sinon.stub().yields(null, {
'opts': 1 'opts': 1
}); });
wf.read('id', [], function(err, w) { iden.read('id', [], function(err, w) {
should.not.exist(w); should.not.exist(w);
should.exist(err); should.exist(err);
should.exist(err.message); should.exist(err.message);
@ -298,12 +332,12 @@ describe('Identity model', function() {
}); });
}); });
it('should read existing wallet', function(done) { it('should read existing wallet', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.getFirst = sinon.stub().yields(null, { iden.storage.getFirst = sinon.stub().yields(null, {
'opts': 1 'opts': 1
}); });
wf.fromObj = sinon.stub().returns('ok'); iden.fromObj = sinon.stub().returns('ok');
wf.read('id', [], function(err, w) { iden.read('id', [], function(err, w) {
should.not.exist(err); should.not.exist(err);
should.exist(w); should.exist(w);
done(); done();
@ -319,33 +353,33 @@ describe('Identity model', function() {
}; };
it('should call setPassphrase', function(done) { it('should call setPassphrase', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
var s1 = sinon.stub(); var s1 = sinon.stub();
s1.store = sinon.stub().yields(null); s1.store = sinon.stub().yields(null);
wf.read = sinon.stub().yields(null, s1); iden.read = sinon.stub().yields(null, s1);
wf.migrateWallet = sinon.stub().yields(null); iden.migrateWallet = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.open('dummy', 'xxx', function(err, w) { iden.open('dummy', 'xxx', function(err, w) {
wf.storage.setPassphrase.calledOnce.should.equal(true); iden.storage.setPassphrase.calledOnce.should.equal(true);
wf.storage.setPassphrase.getCall(0).args[0].should.equal('xxx'); iden.storage.setPassphrase.getCall(0).args[0].should.equal('xxx');
done(); done();
}); });
}); });
it('should call return wallet', function(done) { it('should call return wallet', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
var s1 = sinon.stub(); var s1 = sinon.stub();
s1.store = sinon.stub().yields(null); s1.store = sinon.stub().yields(null);
wf.read = sinon.stub().yields(null, s1); iden.read = sinon.stub().yields(null, s1);
wf.migrateWallet = sinon.stub().yields(null); iden.migrateWallet = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.open('dummy', 'xxx', function(err, w) { iden.open('dummy', 'xxx', function(err, w) {
w.should.equal(s1); w.should.equal(s1);
s1.store.calledOnce.should.equal(true); s1.store.calledOnce.should.equal(true);
done(); done();
@ -354,52 +388,52 @@ describe('Identity model', function() {
it('should call #store', function(done) { it('should call #store', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
var s1 = sinon.stub(); var s1 = sinon.stub();
s1.store = sinon.stub().yields(null); s1.store = sinon.stub().yields(null);
wf.read = sinon.stub().yields(null, s1); iden.read = sinon.stub().yields(null, s1);
wf.migrateWallet = sinon.stub().yields(null); iden.migrateWallet = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.open('dummy', 'xxx', function(err, w) { iden.open('dummy', 'xxx', function(err, w) {
s1.store.calledOnce.should.equal(true); s1.store.calledOnce.should.equal(true);
done(); done();
}); });
}); });
it('should call #setLastOpened', function(done) { it('should call #setLastOpened', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
var s1 = sinon.stub(); var s1 = sinon.stub();
s1.store = sinon.stub().yields(null); s1.store = sinon.stub().yields(null);
wf.read = sinon.stub().yields(null, s1); iden.read = sinon.stub().yields(null, s1);
wf.migrateWallet = sinon.stub().yields(null); iden.migrateWallet = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.open('dummy', 'xxx', function(err, w) { iden.open('dummy', 'xxx', function(err, w) {
wf.storage.setLastOpened.calledOnce.should.equal(true); iden.storage.setLastOpened.calledOnce.should.equal(true);
wf.storage.setLastOpened.getCall(0).args[0].should.equal('dummy'); iden.storage.setLastOpened.getCall(0).args[0].should.equal('dummy');
done(); done();
}); });
}); });
it('should call #migrateWallet', function(done) { it('should call #migrateWallet', function(done) {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
var s1 = sinon.stub(); var s1 = sinon.stub();
s1.store = sinon.stub().yields(null); s1.store = sinon.stub().yields(null);
wf.read = sinon.stub().yields(null, s1); iden.read = sinon.stub().yields(null, s1);
wf.migrateWallet = sinon.stub().yields(null); iden.migrateWallet = sinon.stub().yields(null);
wf.storage.deleteWallet_Old = sinon.stub().yields(null); iden.storage.deleteWallet_Old = sinon.stub().yields(null);
wf.storage.removeGlobal = sinon.stub().yields(null); iden.storage.removeGlobal = sinon.stub().yields(null);
wf.storage.setLastOpened = sinon.stub().yields(null); iden.storage.setLastOpened = sinon.stub().yields(null);
wf.open('dummy', 'xxx', function(err, w) { iden.open('dummy', 'xxx', function(err, w) {
wf.migrateWallet.calledOnce.should.equal(true); iden.migrateWallet.calledOnce.should.equal(true);
wf.migrateWallet.getCall(0).args[0].should.equal('dummy'); iden.migrateWallet.getCall(0).args[0].should.equal('dummy');
done(); done();
}); });
}); });
@ -407,7 +441,7 @@ describe('Identity model', function() {
describe('#createWallet', function() { describe('#createWallet', function() {
it('should create wallet', function(done) { it('should create wallet', function(done) {
wf.createWallet(null, function(err, w) { iden.createWallet(null, function(err, w) {
should.exist(w); should.exist(w);
should.not.exist(err); should.not.exist(err);
done(); done();
@ -416,20 +450,20 @@ describe('Identity model', function() {
it('should be able to create wallets with given pk', function(done) { it('should be able to create wallets with given pk', function(done) {
var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m';
wf.createWallet({ iden.createWallet({
privateKeyHex: priv, privateKeyHex: priv,
}, function(err, w) { }, function(err, w) {
wf._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.equal(priv); iden._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.equal(priv);
should.not.exist(err); should.not.exist(err);
done(); done();
}); });
}); });
it('should be able to create wallets with random pk', function(done) { it('should be able to create wallets with random pk', function(done) {
wf.createWallet(null, function(err, w1) { iden.createWallet(null, function(err, w1) {
wf.createWallet(null, function(err, w2) { iden.createWallet(null, function(err, w2) {
wf._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.not.equal( iden._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.not.equal(
wf._getWallet.getCall(1).args[0].privateKey.toObj().extendedPrivateKeyString iden._getWallet.getCall(1).args[0].privateKey.toObj().extendedPrivateKeyString
); );
done(); done();
}); });
@ -445,7 +479,7 @@ describe('Identity model', function() {
}; };
it('should yield bad network error', function(done) { it('should yield bad network error', function(done) {
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.greet = sinon.stub(); net.greet = sinon.stub();
net.cleanUp = sinon.stub(); net.cleanUp = sinon.stub();
net.start = sinon.stub().yields(null); net.start = sinon.stub().yields(null);
@ -456,7 +490,7 @@ describe('Identity model', function() {
opts: {}, opts: {},
}); });
opts.privHex = undefined; opts.privHex = undefined;
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
err.should.equal('badNetwork'); err.should.equal('badNetwork');
done(); done();
}); });
@ -465,18 +499,18 @@ describe('Identity model', function() {
it('should yield to join error', function(done) { it('should yield to join error', function(done) {
opts.privHex = undefined; opts.privHex = undefined;
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.greet = sinon.stub(); net.greet = sinon.stub();
net.cleanUp = sinon.stub(); net.cleanUp = sinon.stub();
net.start = sinon.stub().yields(null); net.start = sinon.stub().yields(null);
net.on = sinon.stub(); net.on = sinon.stub();
net.on.withArgs('serverError').yields(null); net.on.withArgs('serverError').yields(null);
net.on.withArgs('data').yields('senderId', { net.on.withArgs('data').yields('senderId', {
type: 'walletId', type: 'walletId',
networkName: wf.networkName, networkName: iden.networkName,
}); });
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
err.should.equal('joinError'); err.should.equal('joinError');
done(); done();
}); });
@ -485,7 +519,7 @@ describe('Identity model', function() {
it('should call network.start / create', function(done) { it('should call network.start / create', function(done) {
opts.privHex = undefined; opts.privHex = undefined;
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.cleanUp = sinon.spy(); net.cleanUp = sinon.spy();
net.greet = sinon.spy(); net.greet = sinon.spy();
net.start = sinon.stub().yields(null); net.start = sinon.stub().yields(null);
@ -500,11 +534,11 @@ describe('Identity model', function() {
var w = sinon.stub(); var w = sinon.stub();
w.sendWalletReady = sinon.spy(); w.sendWalletReady = sinon.spy();
wf.createWallet = sinon.stub().yields(null, w); iden.createWallet = sinon.stub().yields(null, w);
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
net.start.calledOnce.should.equal(true); net.start.calledOnce.should.equal(true);
wf.createWallet.calledOnce.should.equal(true); iden.createWallet.calledOnce.should.equal(true);
wf.createWallet.calledOnce.should.equal(true); iden.createWallet.calledOnce.should.equal(true);
w.sendWalletReady.calledOnce.should.equal(true); w.sendWalletReady.calledOnce.should.equal(true);
w.sendWalletReady.getCall(0).args[0].should.equal('03ddbc4711534bc62ccf576ab05f2a0afd11f9e2f4016781f3f5a88de9543a229a'); w.sendWalletReady.getCall(0).args[0].should.equal('03ddbc4711534bc62ccf576ab05f2a0afd11f9e2f4016781f3f5a88de9543a229a');
@ -514,7 +548,7 @@ describe('Identity model', function() {
it('should return walletFull', function(done) { it('should return walletFull', function(done) {
opts.privHex = undefined; opts.privHex = undefined;
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.cleanUp = sinon.spy(); net.cleanUp = sinon.spy();
net.greet = sinon.spy(); net.greet = sinon.spy();
net.start = sinon.stub().yields(null); net.start = sinon.stub().yields(null);
@ -526,30 +560,30 @@ describe('Identity model', function() {
networkName: 'testnet', networkName: 'testnet',
opts: {}, opts: {},
}); });
wf.createWallet = sinon.stub().yields(null, null); iden.createWallet = sinon.stub().yields(null, null);
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
err.should.equal('walletFull'); err.should.equal('walletFull');
done(); done();
}); });
}); });
it('should accept a priv key a input', function() { it('should accept a priv key a input', function() {
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
opts.privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; opts.privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd';
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.cleanUp = sinon.spy(); net.cleanUp = sinon.spy();
net.start = sinon.spy(); net.start = sinon.spy();
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
net.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); net.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d');
}); });
}); });
it('should call network.start with private key', function() { it('should call network.start with private key', function() {
opts.privHex = undefined; opts.privHex = undefined;
var wf = new Identity(config, '0.0.1'); var iden = new Identity(config, '0.0.1');
var net = wf.networks['testnet']; var net = iden.networks['testnet'];
net.cleanUp = sinon.spy(); net.cleanUp = sinon.spy();
net.start = sinon.spy(); net.start = sinon.spy();
wf.joinWallet(opts, function(err, w) { iden.joinWallet(opts, function(err, w) {
net.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer net.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer
}); });
}); });
@ -558,8 +592,8 @@ describe('Identity model', function() {
describe.skip('Backwards compatibility tests', function() { describe.skip('Backwards compatibility tests', function() {
it('should be able to import unencrypted legacy wallet TxProposal: v0', function() { it('should be able to import unencrypted legacy wallet TxProposal: v0', function() {
var wf = new Identity(config, '0.0.5'); var iden = new Identity(config, '0.0.5');
var w = wf.fromObj(JSON.parse(legacyO)); var w = iden.fromObj(JSON.parse(legacyO));
should.exist(w); should.exist(w);
w.id.should.equal('55d4bd062d32f90a'); w.id.should.equal('55d4bd062d32f90a');
@ -570,14 +604,14 @@ describe('Identity model', function() {
it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function() { it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function() {
wf.storage.import = sinon.stub(); iden.storage.import = sinon.stub();
wf.storage.setPassphrase = sinon.spy(); iden.storage.setPassphrase = sinon.spy();
wf.storage.import.withArgs('dummy').returns(JSON.parse(legacy1)); iden.storage.import.withArgs('dummy').returns(JSON.parse(legacy1));
var w = wf.fromEncryptedObj('dummy', 'xxx'); var w = iden.fromEncryptedObj('dummy', 'xxx');
should.exist(w); should.exist(w);
wf.storage.setPassphrase.calledOnce.should.equal(true); iden.storage.setPassphrase.calledOnce.should.equal(true);
wf.storage.setPassphrase.getCall(0).args[0].should.equal('xxx'); iden.storage.setPassphrase.getCall(0).args[0].should.equal('xxx');
w.isReady().should.equal(true); w.isReady().should.equal(true);
var wo = w.toObj(); var wo = w.toObj();