copay/test/test.Wallet.js

1281 lines
38 KiB
JavaScript
Raw Normal View History

2014-04-10 13:57:41 -07:00
'use strict';
2014-04-14 14:30:08 -07:00
var chai = chai || require('chai');
var should = chai.should();
var sinon = require('sinon');
var is_browser = (typeof process == 'undefined' || typeof process.versions === 'undefined');
if (is_browser) {
var copay = require('copay'); //browser
} else {
var copay = require('../copay'); //node
}
2014-07-08 08:34:49 -07:00
var copayConfig = require('../config');
2014-08-14 08:51:56 -07:00
var Wallet = copay.Wallet;
var PrivateKey = copay.PrivateKey;
var Storage = require('./mocks/FakeStorage');
var Network = require('./mocks/FakeNetwork');
2014-06-09 07:19:38 -07:00
var Blockchain = require('./mocks/FakeBlockchain');
2014-06-09 13:28:56 -07:00
var bitcore = bitcore || require('bitcore');
var TransactionBuilder = bitcore.TransactionBuilder;
var Transaction = bitcore.Transaction;
var Address = bitcore.Address;
2014-04-15 11:50:22 -07:00
var config = {
requiredCopayers: 3,
totalCopayers: 5,
spendUnconfirmed: true,
reconnectDelay: 100,
networkName: 'testnet',
};
var getNewEpk = function() {
return new PrivateKey({
networkName: config.networkName,
})
.deriveBIP45Branch()
.extendedPublicKeyString();
}
var addCopayers = function(w) {
for (var i = 0; i < 4; i++) {
w.publicKeyRing.addCopayer(getNewEpk());
2014-04-15 11:50:22 -07:00
}
};
2014-04-10 13:57:41 -07:00
describe('Wallet model', function() {
2014-04-16 17:10:04 -07:00
it('should fail to create an instance', function() {
(function() {
new Wallet(config)
}).should.
throw();
2014-04-10 13:57:41 -07:00
});
2014-06-18 06:09:40 -07:00
it('should getNetworkName', function() {
var w = cachedCreateW();
2014-06-18 06:09:40 -07:00
w.getNetworkName().should.equal('testnet');
});
2014-04-14 14:30:08 -07:00
2014-06-24 09:17:22 -07:00
var createW = function(N, conf) {
2014-06-09 13:52:08 -07:00
var c = JSON.parse(JSON.stringify(conf || config));
2014-06-09 13:52:08 -07:00
if (!N) N = c.totalCopayers;
2014-06-24 09:17:22 -07:00
var mainPrivateKey = new copay.PrivateKey({
networkName: config.networkName
});
2014-06-24 09:17:22 -07:00
var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
c.privateKey = mainPrivateKey;
2014-04-15 11:50:22 -07:00
2014-04-16 17:10:04 -07:00
c.publicKeyRing = new copay.PublicKeyRing({
networkName: c.networkName,
2014-06-09 13:52:08 -07:00
requiredCopayers: Math.min(N, c.requiredCopayers),
totalCopayers: N,
2014-04-16 17:10:04 -07:00
});
2014-06-24 09:17:22 -07:00
c.publicKeyRing.addCopayer(mainCopayerEPK);
2014-04-15 11:50:22 -07:00
2014-04-16 17:10:04 -07:00
c.txProposals = new copay.TxProposals({
networkName: c.networkName,
});
2014-06-24 09:17:22 -07:00
var storage = new Storage(config.storage);
var network = new Network(config.network);
var blockchain = new Blockchain(config.blockchain);
c.storage = storage;
c.network = network;
c.blockchain = blockchain;
2014-04-16 17:10:04 -07:00
2014-06-23 06:59:33 -07:00
c.addressBook = {
'2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
2014-06-18 16:18:13 -07:00
label: 'John',
copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03',
createdTs: 1403102115,
hidden: false
2014-06-23 06:59:33 -07:00
},
'2MtP8WyiwG7ZdVWM96CVsk2M1N8zyfiVQsY': {
2014-06-18 16:18:13 -07:00
label: 'Jennifer',
copayerId: '032991f836543a492bd6d0bb112552bfc7c5f3b7d5388fcbcbf2fbb893b44770d7',
createdTs: 1403103115,
hidden: false
2014-06-18 16:18:13 -07:00
}
};
2014-04-16 17:10:04 -07:00
c.networkName = config.networkName;
c.verbose = config.verbose;
c.version = '0.0.1';
2014-04-16 17:10:04 -07:00
return new Wallet(c);
}
var cachedW = null;
var cachedWobj = null;
var cachedCreateW = function() {
if (!cachedW) {
cachedW = createW();
cachedWobj = cachedW.toObj();
cachedWobj.opts.reconnectDelay = 100;
}
var w = Wallet.fromObj(cachedWobj, cachedW.storage, cachedW.network, cachedW.blockchain);
return w;
};
it('should create an instance', function() {
var w = cachedCreateW();
2014-04-16 17:10:04 -07:00
should.exist(w);
w.publicKeyRing.walletId.should.equal(w.id);
w.txProposals.walletId.should.equal(w.id);
w.requiredCopayers.should.equal(3);
2014-04-15 11:50:22 -07:00
should.exist(w.id);
should.exist(w.publicKeyRing);
should.exist(w.privateKey);
should.exist(w.txProposals);
2014-06-17 21:00:32 -07:00
should.exist(w.addressBook);
2014-04-15 11:50:22 -07:00
});
2014-06-09 07:19:38 -07:00
it('should provide some basic features', function(done) {
2014-04-15 11:50:22 -07:00
var opts = {};
var w = cachedCreateW();
2014-04-15 11:50:22 -07:00
addCopayers(w);
w.publicKeyRing.generateAddress(false, w.publicKey);
2014-04-15 11:50:22 -07:00
w.publicKeyRing.isComplete().should.equal(true);
2014-06-09 07:19:38 -07:00
w.generateAddress(true).isValid().should.equal(true);
w.generateAddress(true, function(addr) {
addr.isValid().should.equal(true);
done();
});
2014-04-14 14:30:08 -07:00
});
var unspentTest = [{
2014-04-15 14:23:35 -07:00
"address": "dummy",
"scriptPubKey": "dummy",
"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
"vout": 1,
"amount": 10,
"confirmations": 7
}];
2014-04-15 14:23:35 -07:00
var createW2 = function(privateKeys, N, conf) {
2014-06-09 13:52:08 -07:00
if (!N) N = 3;
var w = createW(N, conf);
2014-04-15 14:23:35 -07:00
should.exist(w);
var pkr = w.publicKeyRing;
2014-04-15 14:23:35 -07:00
2014-06-13 07:30:48 -07:00
for (var i = 0; i < N - 1; i++) {
2014-04-17 13:01:31 -07:00
if (privateKeys) {
var k = privateKeys[i];
pkr.addCopayer(k ? k.deriveBIP45Branch().extendedPublicKeyString() : getNewEpk());
2014-05-29 13:18:55 -07:00
} else {
pkr.addCopayer(getNewEpk());
2014-05-29 13:18:55 -07:00
}
2014-04-15 14:23:35 -07:00
}
return w;
};
var cachedW2 = null;
var cachedW2obj = null;
var cachedCreateW2 = function() {
if (!cachedW2) {
cachedW2 = createW2();
cachedW2obj = cachedW2.toObj();
cachedW2obj.opts.reconnectDelay = 100;
}
var w = Wallet.fromObj(cachedW2obj, cachedW2.storage, cachedW2.network, cachedW2.blockchain);
return w;
};
2014-07-04 08:51:27 -07:00
it('#create, fail for network', function() {
2014-04-15 14:23:35 -07:00
var w = cachedCreateW2();
2014-04-15 14:23:35 -07:00
unspentTest[0].address = w.publicKeyRing.getAddress(1, true).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true);
2014-04-15 14:23:35 -07:00
2014-07-04 08:51:27 -07:00
var f = function() {
var ntxid = w.createTxSync(
'15q6HKjWHAksHcH91JW23BJEuzZgFwydBt',
'123456789',
null,
unspentTest
);
};
f.should.throw(Error);
});
it('#create, 1 sign', function() {
2014-04-15 14:23:35 -07:00
var w = cachedCreateW2();
2014-04-15 14:23:35 -07:00
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
2014-04-15 14:23:35 -07:00
2014-05-29 13:18:55 -07:00
var ntxid = w.createTxSync(
2014-07-04 08:51:27 -07:00
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
'123456789',
null,
2014-04-15 14:23:35 -07:00
unspentTest
);
var t = w.txProposals;
2014-05-29 13:18:55 -07:00
var txp = t.txps[ntxid];
Object.keys(txp._inputSignatures).length.should.equal(1);
2014-05-29 13:18:55 -07:00
var tx = txp.builder.build();
2014-04-15 14:23:35 -07:00
should.exist(tx);
chai.expect(txp.comment).to.be.null;
2014-04-15 14:23:35 -07:00
tx.isComplete().should.equal(false);
2014-05-29 13:18:55 -07:00
Object.keys(txp.seenBy).length.should.equal(1);
2014-04-15 14:23:35 -07:00
});
it('#create with comment', function() {
var w = cachedCreateW2();
var comment = 'This is a comment';
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
var ntxid = w.createTxSync(
2014-07-04 08:51:27 -07:00
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
'123456789',
comment,
unspentTest
);
var t = w.txProposals;
var txp = t.txps[ntxid];
var tx = txp.builder.build();
should.exist(tx);
txp.comment.should.equal(comment);
});
it('#create throw exception on long comment', function() {
var w = cachedCreateW2();
var comment = 'Lorem ipsum dolor sit amet, suas euismod vis te, velit deleniti vix an. Pri ex suscipit similique, inermis per';
unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
var badCreate = function() {
w.createTxSync(
2014-07-04 08:51:27 -07:00
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
'123456789',
comment,
unspentTest
);
}
chai.expect(badCreate).to.throw(Error);
});
it('#addressIsOwn', function() {
var w = cachedCreateW2();
2014-04-18 07:19:39 -07:00
var l = w.getAddressesStr();
for (var i = 0; i < l.length; i++)
w.addressIsOwn(l[i]).should.equal(true);
2014-05-01 07:04:21 -07:00
w.addressIsOwn(l[0], {
excludeMain: true
}).should.equal(false);
2014-05-01 07:04:21 -07:00
2014-04-18 07:19:39 -07:00
w.addressIsOwn('mmHqhvTVbxgJTnePa7cfweSRjBCy9bQQXJ').should.equal(false);
w.addressIsOwn('mgtUfP9sTJ6vPLoBxZLPEccGpcjNVryaCX').should.equal(false);
});
2014-04-15 14:23:35 -07:00
it('#create. Signing with derivate keys', function() {
2014-04-15 14:23:35 -07:00
var w = cachedCreateW2();
2014-04-15 14:23:35 -07:00
var ts = Date.now();
2014-06-24 09:17:22 -07:00
for (var isChange = false; !isChange; isChange = true) {
for (var index = 0; index < 3; index++) {
unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange, w.publicKey).toString();
unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange, w.publicKey);
2014-04-16 17:10:04 -07:00
w.createTxSync(
2014-07-04 08:51:27 -07:00
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
'123456789',
null,
2014-04-15 14:23:35 -07:00
unspentTest
);
var t = w.txProposals;
2014-04-18 15:28:28 -07:00
var k = Object.keys(t.txps)[0];
var tx = t.txps[k].builder.build();
2014-04-15 14:23:35 -07:00
should.exist(tx);
tx.isComplete().should.equal(false);
tx.countInputMissingSignatures(0).should.equal(2);
(t.txps[k].signedBy[w.privateKey.getId()] - ts > 0).should.equal(true);
(t.txps[k].seenBy[w.privateKey.getId()] - ts > 0).should.equal(true);
2014-04-15 14:23:35 -07:00
}
}
});
it('#fromObj #toObj round trip', function() {
var w = cachedCreateW2();
var o = w.toObj();
o = JSON.parse(JSON.stringify(o));
2014-06-09 16:08:12 -07:00
// non stored options
2014-06-13 07:30:48 -07:00
o.opts.reconnectDelay = 100;
2014-06-09 16:08:12 -07:00
var w2 = Wallet.fromObj(o,
new Storage(config.storage),
new Network(config.network),
new Blockchain(config.blockchain));
should.exist(w2);
w2.publicKeyRing.requiredCopayers.should.equal(w.publicKeyRing.requiredCopayers);
should.exist(w2.publicKeyRing.getCopayerId);
should.exist(w2.txProposals.toObj);
should.exist(w2.privateKey.toObj);
});
it('#getSecret decodeSecret', function() {
var w = cachedCreateW2();
2014-04-30 08:58:40 -07:00
var id = w.getMyCopayerId();
var sb = w.getSecret();
2014-04-30 08:58:40 -07:00
should.exist(sb);
var s = Wallet.decodeSecret(sb);
s.pubKey.should.equal(id);
});
it('decodeSecret check', function() {
(function() {
Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoKM');
}).should.not.
throw();
(function() {
Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoK');
}).should.
throw();
(function() {
Wallet.decodeSecret('12345');
}).should.
throw();
});
2014-06-09 06:30:37 -07:00
2014-07-08 15:52:47 -07:00
//this test fails randomly
it.skip('call reconnect after interval', function(done) {
this.timeout(10000);
var w = cachedCreateW2();
var spy = sinon.spy(w, 'scheduleConnect');
2014-06-18 07:08:50 -07:00
var callCount = 3;
w.netStart();
setTimeout(function() {
2014-06-09 16:08:12 -07:00
sinon.assert.callCount(spy, callCount);
done();
2014-06-23 06:59:33 -07:00
}, w.reconnectDelay * callCount * (callCount + 1) / 2);
2014-04-30 08:58:40 -07:00
});
2014-06-09 06:30:37 -07:00
it('#isSingleUser', function() {
var w = createW();
w.isShared().should.equal(true);
w.totalCopayers = 1;
w.isShared().should.equal(false);
});
2014-07-08 07:52:24 -07:00
it('#isReady', function() {
var w = createW();
w.publicKeyRing.isComplete().should.equal(false);
w.isReady().should.equal(false);
var w2 = createW2();
w2.publicKeyRing.isComplete().should.equal(true);
w2.isReady().should.equal(false);
w2.publicKeyRing.copayersBackup = ["a", "b", "c"];
w2.publicKeyRing.isFullyBackup().should.equal(true);
w2.isReady().should.equal(true);
});
2014-06-09 06:30:37 -07:00
it('handle network indexes correctly', function() {
var w = createW();
var aiObj = {
indexes: [{
copayerIndex: 0,
changeIndex: 3,
receiveIndex: 2
}]
2014-06-09 06:30:37 -07:00
};
w._handleIndexes('senderID', aiObj, true);
w.publicKeyRing.getHDParams(0).getReceiveIndex(2);
w.publicKeyRing.getHDParams(0).getChangeIndex(3);
2014-06-09 06:30:37 -07:00
});
2014-06-09 07:19:38 -07:00
it('handle network pubKeyRings correctly', function() {
2014-06-09 06:30:37 -07:00
var w = createW();
2014-06-09 16:08:12 -07:00
w.getNetworkName().should.equal('testnet');
2014-06-09 06:30:37 -07:00
var cepk = [
w.publicKeyRing.toObj().copayersExtPubKeys[0],
2014-06-09 13:28:56 -07:00
'tpubDEqHs8LoCB1MDfXs1y2WaLJqPkKsgt8mDoQUFsQ4aKHvho5oFJkF7UrZnfFXKMhA1MuVPwq8a5VhFHvCquYcCVHeCrW4ZCWoDDE9K95e8rP',
'tpubDEqHs8LoCB1MGGKRyouphPdFNNuay5PBzCuJkgDSiWeAST8m7y4nwPZ7M27mUNWLLPDp6n8kp4P57sd8xHXNnZvap8PxWrUMvXzkxFNgCh7',
2014-06-09 06:30:37 -07:00
];
var pkrObj = {
walletId: w.id,
networkName: w.networkName,
requiredCopayers: w.requiredCopayers,
totalCopayers: w.totalCopayers,
indexes: [{
copayerIndex: 0,
2014-06-09 06:30:37 -07:00
changeIndex: 2,
receiveIndex: 3
}],
2014-06-09 06:30:37 -07:00
copayersExtPubKeys: cepk,
nicknameFor: {},
};
w._handlePublicKeyRing('senderID', {
publicKeyRing: pkrObj
}, true);
w.publicKeyRing.getHDParams(0).getReceiveIndex(2);
w.publicKeyRing.getHDParams(0).getChangeIndex(3);
2014-06-09 06:30:37 -07:00
for (var i = 0; i < w.requiredCopayers; i++) {
w.publicKeyRing.toObj().copayersExtPubKeys[i].should.equal(cepk[i]);
}
});
2014-06-09 07:19:38 -07:00
2014-06-09 13:28:56 -07:00
it('handle network txProposals correctly', function() {
var w = createW();
2014-06-18 06:21:26 -07:00
var txp = {
2014-06-18 06:09:40 -07:00
'txProposal': {
2014-08-04 13:12:53 -07:00
inputChainPaths: ['m/1'],
builderObj: {
version: 1,
outs: [{
address: '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt',
amountSatStr: '123456789'
}],
utxos: [{
address: '2N6fdPg2QL7V36XKe7a8wkkA5HCy7fNYmZF',
scriptPubKey: 'a91493372782bab70f4eefdefefea8ece0df44f9596887',
txid: '2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1',
vout: 1,
amount: 10,
confirmations: 7
2014-06-18 06:09:40 -07:00
}],
opts: {
remainderOut: {
address: '2N7BLvdrxJ4YzDtb3hfgt6CMY5rrw5kNT1H'
}
},
scriptSig: ['00493046022100b8249a4fc326c4c33882e9d5468a1c6faa01e8c6cef0a24970122e804abdd860022100dbf6ee3b07d3aad8f73997e62ad20654a08aa63a7609792d02f3d5d088e69ad9014cad5321027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d5092102ab32ba51402a139873aeb919c738f5a945f3956f8f8c6ba296677bd29e85d7e821036f119b72e09f76c11ebe2cf754d64eac2cb42c9e623455d54aaa89d70c11f9c82103bcbd3f8ab2c849ea9eae434733cee8b75120d26233def56011b3682ca12081d72103f37f81dc534163b9f73ecf36b91e6c3fb8ae370c24618f91bb1d972e86ceeee255ae'],
hashToScriptMap: {
'2N6fdPg2QL7V36XKe7a8wkkA5HCy7fNYmZF': '5321027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d5092102ab32ba51402a139873aeb919c738f5a945f3956f8f8c6ba296677bd29e85d7e821036f119b72e09f76c11ebe2cf754d64eac2cb42c9e623455d54aaa89d70c11f9c82103bcbd3f8ab2c849ea9eae434733cee8b75120d26233def56011b3682ca12081d72103f37f81dc534163b9f73ecf36b91e6c3fb8ae370c24618f91bb1d972e86ceeee255ae'
}
2014-06-18 06:09:40 -07:00
}
2014-06-09 13:28:56 -07:00
}
};
2014-08-04 13:12:53 -07:00
var stub = sinon.stub(w.publicKeyRing,'copayersForPubkeys').returns(
{'027445ab3a935dce7aee1dadb0d103ed6147a0f83deb80474a04538b2c5bc4d509':'pepe'}
);
2014-06-18 06:21:26 -07:00
w._handleTxProposal('senderID', txp, true);
2014-06-09 13:28:56 -07:00
Object.keys(w.txProposals.txps).length.should.equal(1);
w.getTxProposals().length.should.equal(1);
2014-08-04 13:12:53 -07:00
//stub.restore();
2014-06-09 13:28:56 -07:00
});
2014-06-09 07:19:38 -07:00
var newId = '00bacacafe';
it('handle new connections', function(done) {
var w = createW();
w.on('connect', function(id) {
id.should.equal(newId);
done();
});
w._handleConnect(newId);
});
it('handle disconnections', function(done) {
var w = createW();
w.on('disconnect', function(id) {
id.should.equal(newId);
done();
});
w._handleDisconnect(newId);
});
it('should register new copayers correctly', function() {
var w = createW();
var r = w.getRegisteredCopayerIds();
r.length.should.equal(1);
w.publicKeyRing.addCopayer(getNewEpk());
2014-06-09 07:19:38 -07:00
r = w.getRegisteredCopayerIds();
r.length.should.equal(2);
r[0].should.not.equal(r[1]);
});
it('should register new peers correctly', function() {
var w = createW();
var r = w.getRegisteredPeerIds();
r.length.should.equal(1);
w.publicKeyRing.addCopayer(getNewEpk());
2014-06-09 07:19:38 -07:00
r = w.getRegisteredPeerIds();
r.length.should.equal(2);
r[0].should.not.equal(r[1]);
});
2014-06-12 13:42:26 -07:00
it('#getBalance should call #getUnspent', function(done) {
var w = cachedCreateW2();
2014-06-12 13:42:26 -07:00
var spy = sinon.spy(w.blockchain, 'getUnspent');
w.generateAddress();
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
sinon.assert.callCount(spy, 1);
done();
});
});
it('#getBalance should return values in satoshis', function(done) {
var w = cachedCreateW2();
2014-06-12 13:42:26 -07:00
w.generateAddress();
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
balance.should.equal(2500010000);
safeBalance.should.equal(2500010000);
balanceByAddr.mji7zocy8QzYywQakwWf99w9bCT6orY1C1.should.equal(2500010000);
2014-06-12 13:42:26 -07:00
Object.keys(balanceByAddr).length.should.equal(1);
done();
});
});
it('#getUnspent should honor spendUnconfirmed = false', function(done) {
var conf = JSON.parse(JSON.stringify(config));
conf.spendUnconfirmed = false;
var w = createW2(null, null, conf);
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
balance.should.equal(2500010000);
safeBalance.should.equal(0);
balanceByAddr.mji7zocy8QzYywQakwWf99w9bCT6orY1C1.should.equal(2500010000);
done();
});
});
it('#getUnspent and spendUnconfirmed should count transactions with 1 confirmations', function(done) {
var conf = JSON.parse(JSON.stringify(config));
conf.spendUnconfirmed = false;
var w = cachedCreateW2(null, null, conf);
w.blockchain.getUnspent = w.blockchain.getUnspent2;
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
balance.should.equal(2500010000);
safeBalance.should.equal(2500010000);
balanceByAddr.mji7zocy8QzYywQakwWf99w9bCT6orY1C1.should.equal(2500010000);
done();
});
});
2014-06-13 07:30:48 -07:00
var roundErrorChecks = [{
unspent: [1.0001],
balance: 100010000
}, {
unspent: [1.0002, 1.0003, 1.0004],
balance: 300090000
}, {
unspent: [0.000002, 1.000003, 2.000004],
balance: 300000900
}, {
unspent: [0.0001, 0.0003],
balance: 40000
}, {
unspent: [0.0001, 0.0003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0002],
balance: 110000
},
2014-06-13 07:30:48 -07:00
2014-06-12 13:42:26 -07:00
];
2014-06-26 06:47:39 -07:00
var roundWallet = cachedCreateW2();
2014-06-12 13:42:26 -07:00
2014-06-13 07:30:48 -07:00
roundErrorChecks.forEach(function(c) {
2014-06-26 06:47:39 -07:00
it('#getBalance should handle rounding errors: ' + c.unspent[0], function(done) {
var w = roundWallet;
//w.generateAddress();
2014-06-13 07:30:48 -07:00
w.blockchain.fixUnspent(c.unspent.map(function(u) {
return {
amount: u
}
}));
2014-06-12 13:42:26 -07:00
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
balance.should.equal(c.balance);
done();
});
});
});
2014-06-09 07:19:38 -07:00
it('should get balance', function(done) {
var w = createW2();
2014-06-12 13:42:26 -07:00
var spy = sinon.spy(w.blockchain, 'getUnspent');
2014-06-24 09:17:22 -07:00
w.blockchain.fixUnspent([]);
2014-06-09 07:19:38 -07:00
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
2014-06-12 13:42:26 -07:00
sinon.assert.callCount(spy, 1);
2014-06-09 07:19:38 -07:00
balance.should.equal(0);
done();
});
});
2014-06-09 13:28:56 -07:00
// tx handling
var createUTXO = function(w) {
var utxo = [{
2014-06-09 07:19:38 -07:00
'txid': '0be0fb4579911be829e3077202e1ab47fcc12cf3ab8f8487ccceae768e1f95fa',
'vout': 0,
'ts': 1402323949,
'amount': 25.0001,
'confirmations': 10,
'confirmationsFromCache': false
2014-06-09 13:28:56 -07:00
}];
var addr = w.generateAddress().toString();
utxo[0].address = addr;
utxo[0].scriptPubKey = (new bitcore.Address(addr)).getScriptPubKey().serialize().toString('hex');
2014-06-09 13:28:56 -07:00
return utxo;
};
var toAddress = 'mjfAe7YrzFujFf8ub5aUrCaN5GfSABdqjh';
var amountSatStr = '1000';
it('should create transaction', function(done) {
var w = cachedCreateW2();
2014-06-09 13:28:56 -07:00
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-06-09 07:19:38 -07:00
ntxid.length.should.equal(64);
done();
});
2014-06-09 13:28:56 -07:00
});
it('should create & sign transaction from received funds', function(done) {
var k2 = new PrivateKey({
networkName: config.networkName
});
var w = createW2([k2]);
2014-06-09 13:28:56 -07:00
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-06-09 13:28:56 -07:00
w.on('txProposalsUpdated', function() {
w.getTxProposals()[0].signedByUs.should.equal(true);
w.getTxProposals()[0].rejectedByUs.should.equal(false);
done();
});
w.privateKey = k2;
2014-06-09 13:28:56 -07:00
w.sign(ntxid, function(success) {
success.should.equal(true);
});
});
});
2014-08-03 19:57:23 -07:00
it('should fail to reject a signed transaction', function() {
var w = cachedCreateW2();
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-08-04 08:43:21 -07:00
(function() {
w.reject(ntxid);
}).should.throw('reject a signed');
2014-08-03 19:57:23 -07:00
});
});
2014-06-09 13:28:56 -07:00
it('should create & reject transaction', function(done) {
var w = cachedCreateW2();
2014-08-03 19:57:23 -07:00
var oldK = w.privateKey;
2014-06-09 13:28:56 -07:00
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-08-03 19:57:23 -07:00
var s = sinon.stub(w, 'getMyCopayerId').returns('213');
2014-08-05 12:25:02 -07:00
Object.keys(w.txProposals.get(ntxid).rejectedBy).length.should.equal(0);
2014-06-09 13:28:56 -07:00
w.reject(ntxid);
2014-08-05 12:25:02 -07:00
Object.keys(w.txProposals.get(ntxid).rejectedBy).length.should.equal(1);
w.txProposals.get(ntxid).rejectedBy['213'].should.gt(1);
2014-08-03 19:57:23 -07:00
s.restore();
done();
2014-06-09 13:28:56 -07:00
});
2014-06-09 07:19:38 -07:00
});
2014-06-09 13:52:08 -07:00
it('should create & sign & send a transaction', function(done) {
var w = createW2(null, 1);
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-06-09 13:52:08 -07:00
w.sendTx(ntxid, function(txid) {
txid.length.should.equal(64);
done();
});
});
});
2014-06-18 06:09:40 -07:00
it('should send TxProposal', function(done) {
var w = cachedCreateW2();
2014-06-18 06:09:40 -07:00
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
2014-06-18 06:21:26 -07:00
w.sendTxProposal.bind(w).should.throw('Illegal Argument.');
2014-06-18 06:09:40 -07:00
(function() {
2014-06-18 06:21:26 -07:00
w.sendTxProposal(ntxid);
}).should.not.throw();
done();
});
});
2014-06-18 06:21:26 -07:00
it('should send all TxProposal', function(done) {
var w = cachedCreateW2();
2014-06-18 06:21:26 -07:00
var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(ntxid) {
w.sendAllTxProposals.bind(w).should.not.throw();
(function() {
w.sendAllTxProposals();
2014-06-18 06:09:40 -07:00
}).should.not.throw();
done();
});
2014-06-09 14:01:15 -07:00
});
2014-06-13 07:30:48 -07:00
describe('#send', function() {
it('should call this.network.send', function() {
var w = cachedCreateW2();
var save = w.network.send;
w.network.send = sinon.spy();
w.send();
w.network.send.calledOnce.should.equal(true);
w.network.send = save;
});
});
2014-06-25 09:06:25 -07:00
describe('#indexDiscovery', function() {
var ADDRESSES_CHANGE, ADDRESSES_RECEIVE, w;
before(function() {
w = cachedCreateW2();
ADDRESSES_CHANGE = w.deriveAddresses(0, 20, true, 0);
ADDRESSES_RECEIVE = w.deriveAddresses(0, 20, false, 0);
2014-06-25 09:06:25 -07:00
});
var mockFakeActivity = function(f) {
w.blockchain.checkActivity = function(addresses, cb) {
var activity = new Array(addresses.length);
for (var i = 0; i < addresses.length; i++) {
var a1 = ADDRESSES_CHANGE.indexOf(addresses[i]);
var a2 = ADDRESSES_RECEIVE.indexOf(addresses[i]);
activity[i] = f(Math.max(a1, a2));
}
cb(null, activity);
2014-06-18 10:24:48 -07:00
}
}
2014-06-25 09:06:25 -07:00
it('#indexDiscovery should work without found activities', function(done) {
mockFakeActivity(function(index) {
return false;
});
w.indexDiscovery(0, false, 0, 5, function(e, lastActive) {
2014-06-25 09:06:25 -07:00
lastActive.should.equal(-1);
done();
});
});
2014-06-25 09:06:25 -07:00
it('#indexDiscovery should continue scanning', function(done) {
mockFakeActivity(function(index) {
return index <= 7;
});
w.indexDiscovery(0, false, 0, 5, function(e, lastActive) {
2014-06-25 09:06:25 -07:00
lastActive.should.equal(7);
done();
});
});
2014-06-25 09:06:25 -07:00
it('#indexDiscovery should not found beyond the scannWindow', function(done) {
mockFakeActivity(function(index) {
return index <= 10 || index == 17;
});
w.indexDiscovery(0, false, 0, 5, function(e, lastActive) {
2014-06-25 09:06:25 -07:00
lastActive.should.equal(10);
done();
});
});
2014-06-25 09:06:25 -07:00
it('#indexDiscovery should look for activity along the scannWindow', function(done) {
mockFakeActivity(function(index) {
return index <= 14 && index % 2 == 0;
});
w.indexDiscovery(0, false, 0, 5, function(e, lastActive) {
2014-06-25 09:06:25 -07:00
lastActive.should.equal(14);
done();
});
});
2014-06-18 10:24:48 -07:00
2014-06-25 09:06:25 -07:00
it('#updateIndexes should update correctly', function(done) {
mockFakeActivity(function(index) {
return index <= 14 && index % 2 == 0;
});
2014-06-18 10:24:48 -07:00
var updateIndex = sinon.stub(w, 'updateIndex', function(i, cb) {
cb();
});
2014-06-25 09:06:25 -07:00
w.updateIndexes(function(err) {
// check updated all indexes
var cosignersChecked = []
updateIndex.args.forEach(function(i) {
cosignersChecked.indexOf(i[0].copayerIndex).should.equal(-1);
cosignersChecked.push(i[0].copayerIndex);
});
sinon.assert.callCount(updateIndex, 4);
2014-08-18 15:11:30 -07:00
sinon.assert.calledWith(updateIndex, w.publicKeyRing.indexes[0] );
sinon.assert.calledWith(updateIndex, w.publicKeyRing.indexes[1] );
sinon.assert.calledWith(updateIndex, w.publicKeyRing.indexes[2] );
w.updateIndex.restore();
done();
});
});
it('#updateIndex should update correctly', function(done) {
mockFakeActivity(function(index) {
return index <= 14 && index % 2 == 0;
});
var indexDiscovery = sinon.stub(w, 'indexDiscovery', function(a, b, c, d, cb) {
cb(null, 8);
});
var index = {
changeIndex: 1,
receiveIndex: 2,
copayerIndex: 2,
}
w.updateIndex(index, function(err) {
index.receiveIndex.should.equal(9);
index.changeIndex.should.equal(9);
indexDiscovery.callCount.should.equal(2);
2014-08-18 15:11:30 -07:00
sinon.assert.calledWith(indexDiscovery, 1, true, 2, 20 );
sinon.assert.calledWith(indexDiscovery, 2, false, 2, 20 );
w.indexDiscovery.restore();
2014-06-25 09:06:25 -07:00
done();
});
2014-06-23 06:59:33 -07:00
});
2014-06-25 09:06:25 -07:00
it('#updateIndexes should store wallet', function(done) {
2014-06-25 09:06:25 -07:00
mockFakeActivity(function(index) {
return index <= 14 && index % 2 == 0;
});
var indexDiscovery = sinon.stub(w, 'indexDiscovery', function(a, b, c, d, cb) {
cb(null, 8);
});
2014-06-25 09:06:25 -07:00
var spyStore = sinon.spy(w, 'store');
w.updateIndexes(function(err) {
sinon.assert.callCount(spyStore, 1);
done();
});
2014-06-18 10:24:48 -07:00
});
2014-06-25 09:06:25 -07:00
2014-06-18 10:24:48 -07:00
});
it('#deriveAddresses', function(done) {
var w = cachedCreateW2();
var addresses1 = w.deriveAddresses(0, 5, false, 0);
var addresses2 = w.deriveAddresses(4, 5, false, 0);
2014-06-18 10:24:48 -07:00
addresses1.length.should.equal(5);
addresses2.length.should.equal(5);
addresses1[4].should.equal(addresses2[0]);
done();
2014-06-09 14:01:15 -07:00
});
2014-06-13 07:30:48 -07:00
describe('#AddressBook', function() {
var contacts = [{
label: 'Charles',
address: '2N8pJWpXCAxmNLHKVEhz3TtTcYCtHd43xWU ',
}, {
label: 'Linda',
address: '2N4Zq92goYGrf5J4F4SZZq7jnPYbCiyRYT2 ',
}];
2014-06-17 21:00:32 -07:00
it('should create new entry for address book', function() {
var w = createW();
contacts.forEach(function(c) {
w.setAddressBook(c.address, c.label);
});
Object.keys(w.addressBook).length.should.equal(4);
2014-06-17 21:00:32 -07:00
});
it('should fail if create a duplicate address', function() {
var w = createW();
2014-06-18 16:18:13 -07:00
w.setAddressBook(contacts[0].address, contacts[0].label);
(function() {
w.setAddressBook(contacts[0].address, contacts[0].label);
}).should.
throw();
});
2014-06-23 06:59:33 -07:00
it('should show/hide everywhere', function() {
var w = createW();
var key = '2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ';
w.toggleAddressBookEntry(key);
w.addressBook[key].hidden.should.equal(true);
w.toggleAddressBookEntry(key);
w.addressBook[key].hidden.should.equal(false);
(function() {
w.toggleAddressBookEntry();
}).should.throw();
});
it('handle network addressBook correctly', function() {
var w = createW();
2014-07-07 15:12:34 -07:00
var data = {
type: "addressbook",
addressBook: {
"3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z": {
2014-07-07 15:12:34 -07:00
copayerId: "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb",
createdTs: 1404769393509,
hidden: false,
label: "adsf",
signature: "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586"
}
},
walletId: "11d23e638ed84c06",
2014-07-07 15:12:34 -07:00
isBroadcast: 1
2014-07-07 13:38:17 -07:00
};
2014-07-07 15:12:34 -07:00
var senderId = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb";
Object.keys(w.addressBook).length.should.equal(2);
2014-07-07 15:12:34 -07:00
w._handleAddressBook(senderId, data, true);
Object.keys(w.addressBook).length.should.equal(3);
});
it('should return signed object', function() {
var w = createW();
var payload = {
address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx',
label: 'Faucet',
copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03',
createdTs: 1403102115
};
should.exist(w.signJson(payload));
});
it('should verify signed object', function() {
var w = createW();
2014-07-07 15:12:34 -07:00
var payload = {
address: "3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z",
label: "adsf",
copayerId: "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb",
createdTs: 1404769393509
}
var signature = "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586";
var pubKey = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb";
w.verifySignedJson(pubKey, payload, signature).should.equal(true);
payload.label = 'Another';
w.verifySignedJson(pubKey, payload, signature).should.equal(false);
});
it('should verify signed addressbook entry', function() {
var w = createW();
2014-07-07 15:12:34 -07:00
var key = "3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z";
var pubKey = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb";
w.addressBook[key] = {
copayerId: pubKey,
createdTs: 1404769393509,
hidden: false,
2014-07-07 15:12:34 -07:00
label: "adsf",
signature: "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586"
};
2014-07-07 16:01:50 -07:00
w.verifyAddressbookEntry(w.addressBook[key], pubKey, key).should.equal(true);
w.addressBook[key].label = 'Another';
2014-07-07 16:01:50 -07:00
w.verifyAddressbookEntry(w.addressBook[key], pubKey, key).should.equal(false);
(function() {
2014-07-07 16:01:50 -07:00
w.verifyAddressbookEntry();
}).should.throw();
2014-06-17 21:00:32 -07:00
});
});
2014-06-19 11:03:31 -07:00
it('#getNetworkName', function() {
var w = createW();
w.getNetworkName().should.equal('testnet');
});
describe('#getMyCopayerId', function() {
it('should call getCopayerId', function() {
var w = cachedCreateW2();
2014-06-19 11:03:31 -07:00
w.getCopayerId = sinon.spy();
w.getMyCopayerId();
w.getCopayerId.calledOnce.should.equal(true);
});
});
describe('#getMyCopayerIdPriv', function() {
it('should call privateKey.getIdPriv', function() {
var w = cachedCreateW2();
2014-06-19 11:03:31 -07:00
w.privateKey.getIdPriv = sinon.spy();
w.getMyCopayerIdPriv();
w.privateKey.getIdPriv.calledOnce.should.equal(true);
});
});
describe('#netStart', function() {
it('should call Network.start', function() {
var w = cachedCreateW2();
2014-06-19 11:03:31 -07:00
w.network.start = sinon.spy();
w.netStart();
w.network.start.calledOnce.should.equal(true);
});
it('should call Network.start with a private key', function() {
var w = cachedCreateW2();
2014-06-19 11:03:31 -07:00
w.network.start = sinon.spy();
w.netStart();
w.network.start.getCall(0).args[0].privkey.length.should.equal(64);
});
2014-06-25 13:36:34 -07:00
});
2014-06-19 11:03:31 -07:00
2014-07-08 08:34:49 -07:00
describe('#forceNetwork in config', function() {
it('should throw if network is different', function() {
var backup = copayConfig.forceNetwork;
copayConfig.forceNetwork = true;
config.networkName = 'livenet';
cachedCreateW2.should.throw(Error);
copayConfig.forceNetwork = backup;
});
});
2014-08-04 08:43:21 -07:00
describe('_getKeymap', function() {
var w = cachedCreateW();
it('should set keymap', function() {
var stub = sinon.stub(w.publicKeyRing, 'copayersForPubkeys', function() {
return {
'123': 'juan'
};
});
var txp = {
_inputSignatures: [
['123']
],
2014-08-04 13:12:53 -07:00
inputChainPaths: ['/m/1'],
2014-08-04 08:43:21 -07:00
};
var map = w._getKeyMap(txp);
Object.keys(map).length.should.equal(1);
map['123'].should.equal('juan');
stub.restore();
});
it('should throw if unmatched sigs', function() {
var stub = sinon.stub(w.publicKeyRing, 'copayersForPubkeys', function() {
return {
'123': 'juan'
};
});
var txp = {
_inputSignatures: [
['234']
],
2014-08-04 13:12:53 -07:00
inputChainPaths: ['/m/1'],
2014-08-04 08:43:21 -07:00
};
(function() {
w._getKeyMap(txp);
}).should.throw('dont match know copayers');
stub.restore();
});
it('should set keymap with multiple signatures', function() {
var stub = sinon.stub(w.publicKeyRing, 'copayersForPubkeys', function() {
return {
'123': 'juan',
'234': 'pepe',
};
});
var txp = {
_inputSignatures: [
['234', '123']
],
2014-08-04 13:12:53 -07:00
inputChainPaths: ['/m/1'],
2014-08-04 08:43:21 -07:00
};
var map = w._getKeyMap(txp);
Object.keys(map).length.should.equal(2);
map['123'].should.equal('juan');
map['234'].should.equal('pepe');
stub.restore();
});
it('should throw is one inputs has missing sigs', function() {
var stub = sinon.stub(w.publicKeyRing, 'copayersForPubkeys', function() {
return {
'123': 'juan',
'234': 'pepe',
};
});
var txp = {
_inputSignatures: [
['234', '123'],
['234']
],
2014-08-04 13:12:53 -07:00
inputChainPaths: ['/m/1'],
2014-08-04 08:43:21 -07:00
};
(function() {
w._getKeyMap(txp);
}).should.throw('different sig');
stub.restore();
});
});
2014-08-03 19:57:23 -07:00
describe('_handleTxProposal', function() {
var testValidate = function(response, result, done) {
var w = cachedCreateW();
var spy = sinon.spy();
w.on('txProposalEvent', spy);
w.on('txProposalEvent', function(e) {
e.type.should.equal(result);
done();
});
// txp.prototype.getId = function() {return 'aa'};
2014-08-04 08:43:21 -07:00
var txp = {
dummy: 1
};
var txp = {
'txProposal': txp
};
2014-08-03 19:57:23 -07:00
var merge = sinon.stub(w.txProposals, 'merge', function() {
2014-08-04 08:43:21 -07:00
if (response == 0) throw new Error();
return {
newCopayer: ['juan'],
ntxid: 1,
new: response == 1
};
2014-08-01 06:51:46 -07:00
});
2014-08-03 19:57:23 -07:00
w._handleTxProposal('senderID', txp);
spy.callCount.should.equal(1);
2014-08-01 06:51:46 -07:00
merge.restore();
};
2014-08-03 19:57:23 -07:00
it('should handle corrupt', function(done) {
2014-07-31 21:09:46 -07:00
var result = 'corrupt';
2014-08-03 19:57:23 -07:00
testValidate(0, result, done);
2014-07-25 09:37:12 -07:00
});
2014-08-03 19:57:23 -07:00
it('should handle new', function(done) {
var result = 'new';
2014-08-03 19:57:23 -07:00
testValidate(1, result, done);
});
2014-08-03 19:57:23 -07:00
it('should handle signed', function(done) {
var result = 'signed';
testValidate(2, result, done);
});
});
2014-08-04 08:43:21 -07:00
describe('_handleReject', function() {
it('should fails if unknown tx', function() {
var w = cachedCreateW();
(function() {
w._handleReject(1, {
ntxid: 1
}, 1);
2014-08-05 12:25:02 -07:00
}).should.throw('Unknown TXP');
2014-08-04 08:43:21 -07:00
});
it('should fail to reject a signed tx', function() {
var w = cachedCreateW();
w.txProposals.txps['qwerty'] = {
signedBy: {
john: 1
}
};
(function() {
w._handleReject('john', {
ntxid: 'qwerty'
}, 1);
}).should.throw('already signed');
});
it('should reject a tx', function() {
var w = cachedCreateW();
2014-08-04 13:12:53 -07:00
2014-08-04 08:43:21 -07:00
function txp() {
2014-08-04 13:12:53 -07:00
this.ok = 0;
2014-08-04 08:43:21 -07:00
this.signedBy = {};
};
2014-08-04 13:12:53 -07:00
txp.prototype.setRejected = function() {
this.ok = 1;
2014-08-04 08:43:21 -07:00
};
2014-08-04 13:12:53 -07:00
txp.prototype.toObj = function() {};
2014-08-04 08:43:21 -07:00
2014-08-04 13:12:53 -07:00
var spy1 = sinon.spy(w, 'store');
var spy2 = sinon.spy(w, 'emit');
2014-08-04 08:43:21 -07:00
w.txProposals.txps['qwerty'] = new txp();
2014-08-04 13:12:53 -07:00
w.txProposals.txps['qwerty'].ok.should.equal(0);
2014-08-04 08:43:21 -07:00
w._handleReject('john', {
ntxid: 'qwerty'
}, 1);
2014-08-04 13:12:53 -07:00
w.txProposals.txps['qwerty'].ok.should.equal(1);
2014-08-04 08:43:21 -07:00
spy1.calledOnce.should.equal(true);
spy2.callCount.should.equal(2);
spy2.firstCall.args.should.deep.equal(['txProposalsUpdated']);
2014-08-04 13:12:53 -07:00
spy2.secondCall.args.should.deep.equal(['txProposalEvent', {
type: 'rejected',
2014-08-04 08:43:21 -07:00
cId: 'john',
txId: 'qwerty',
}]);
});
});
describe('_handleSeen', function() {
it('should fails if unknown tx', function() {
var w = cachedCreateW();
(function() {
w._handleReject(1, {
ntxid: 1
}, 1);
2014-08-05 12:25:02 -07:00
}).should.throw('Unknown TXP');
2014-08-04 08:43:21 -07:00
});
it('should set seen a tx', function() {
var w = cachedCreateW();
2014-08-04 13:12:53 -07:00
2014-08-04 08:43:21 -07:00
function txp() {
2014-08-04 13:12:53 -07:00
this.ok = 0;
2014-08-04 08:43:21 -07:00
this.signedBy = {};
};
2014-08-04 13:12:53 -07:00
txp.prototype.setSeen = function() {
this.ok = 1;
2014-08-04 08:43:21 -07:00
};
2014-08-04 13:12:53 -07:00
txp.prototype.toObj = function() {};
2014-08-04 08:43:21 -07:00
2014-08-04 13:12:53 -07:00
var spy1 = sinon.spy(w, 'store');
var spy2 = sinon.spy(w, 'emit');
2014-08-04 08:43:21 -07:00
w.txProposals.txps['qwerty'] = new txp();
2014-08-04 13:12:53 -07:00
w.txProposals.txps['qwerty'].ok.should.equal(0);
2014-08-04 08:43:21 -07:00
w._handleSeen('john', {
ntxid: 'qwerty'
}, 1);
2014-08-04 13:12:53 -07:00
w.txProposals.txps['qwerty'].ok.should.equal(1);
2014-08-04 08:43:21 -07:00
spy1.calledOnce.should.equal(true);
spy2.callCount.should.equal(2);
spy2.firstCall.args.should.deep.equal(['txProposalsUpdated']);
2014-08-04 13:12:53 -07:00
spy2.secondCall.args.should.deep.equal(['txProposalEvent', {
type: 'seen',
2014-08-04 08:43:21 -07:00
cId: 'john',
txId: 'qwerty',
}]);
});
});
it('getNetwork', function() {
var w = cachedCreateW();
var n = w.getNetwork();
n.maxPeers.should.equal(5);
should.exist(n.networkNonce);
});
it('#disconnect', function() {
var w = cachedCreateW();
2014-08-04 13:12:53 -07:00
var spy1 = sinon.spy(w.network, 'disconnect');
2014-08-04 08:43:21 -07:00
w.disconnect();
spy1.callCount.should.equal(1);
});
2014-04-10 13:57:41 -07:00
});