This commit is contained in:
Ivan Socolsky 2015-02-24 10:36:14 -03:00
parent 4d1cb07a79
commit 66e173be43
2 changed files with 244 additions and 31 deletions

View File

@ -119,8 +119,8 @@ WalletService.prototype.createWallet = function(opts, cb) {
try {
pubKey = new PublicKey.fromString(opts.pubKey);
} catch (e) {
return cb(e.toString());
} catch (ex) {
return cb(new ClientError('Invalid public key'));
};
var wallet = Wallet.create({
@ -512,6 +512,9 @@ WalletService.prototype.createTx = function(opts, cb) {
if (toAddress.network != wallet.getNetworkName())
return cb(new ClientError('INVALIDADDRESS', 'Incorrect address network'));
if (opts.amount <= 0)
return cb(new ClientError('Invalid amount'));
if (opts.amount < Bitcore.Transaction.DUST_AMOUNT)
return cb(new ClientError('DUSTAMOUNT', 'Amount below dust threshold'));
@ -538,8 +541,7 @@ WalletService.prototype.createTx = function(opts, cb) {
try {
self._selectUtxos(txp, utxos);
} catch (ex) {
console.log('[server.js.523:ex:]', ex); //TODO
return cb(new ClientError(ex));
return cb(new ClientError(ex.toString()));
}
if (!txp.inputs)

View File

@ -302,7 +302,7 @@ describe('Copay server', function() {
};
server.createWallet(opts, function(err, walletId) {
should.not.exist(walletId);
err.should.exist;
should.exist(err);
err.message.should.contain('name');
done();
});
@ -346,7 +346,20 @@ describe('Copay server', function() {
});
});
it.skip('should fail to create wallet with invalid pubKey argument', function(done) {});
it('should fail to create wallet with invalid pubKey argument', function(done) {
var opts = {
name: 'my wallet',
m: 2,
n: 3,
pubKey: 'dummy',
};
server.createWallet(opts, function(err, walletId) {
should.not.exist(walletId);
should.exist(err);
err.message.should.contain('Invalid public key');
done();
});
});
});
describe('#joinWallet', function() {
@ -399,7 +412,7 @@ describe('Copay server', function() {
};
server.joinWallet(copayerOpts, function(err, result) {
should.not.exist(result);
err.should.exist;
should.exist(err);
err.message.should.contain('name');
done();
});
@ -453,7 +466,39 @@ describe('Copay server', function() {
});
});
it.skip('should fail two wallets with same xPubKey', function(done) {});
it('should fail two wallets with same xPubKey', function(done) {
var copayerOpts = {
walletId: walletId,
name: 'me',
xPubKey: TestData.copayers[0].xPubKey,
xPubKeySignature: TestData.copayers[0].xPubKeySignature,
};
server.joinWallet(copayerOpts, function(err) {
should.not.exist(err);
var walletOpts = {
name: 'my other wallet',
m: 1,
n: 1,
pubKey: TestData.keyPair.pub,
};
server.createWallet(walletOpts, function(err, walletId) {
should.not.exist(err);
copayerOpts = {
walletId: walletId,
name: 'me',
xPubKey: TestData.copayers[0].xPubKey,
xPubKeySignature: TestData.copayers[0].xPubKeySignature,
};
server.joinWallet(copayerOpts, function(err) {
should.exist(err);
err.code.should.equal('CREGISTERED');
err.message.should.equal('Copayer ID already registered on server');
done();
});
});
});
});
it('should fail to join with bad formated signature', function(done) {
var copayerOpts = {
@ -475,7 +520,7 @@ describe('Copay server', function() {
xPubKey: TestData.copayers[0].xPubKey[0],
};
server.joinWallet(copayerOpts, function(err) {
err.should.exist;
should.exist(err);
err.message.should.contain('argument missing');
done();
});
@ -583,7 +628,7 @@ describe('Copay server', function() {
it('should not create address if unable to store it', function(done) {
sinon.stub(server.storage, 'storeAddressAndWallet').yields('dummy error');
server.createAddress({}, function(err, address) {
err.should.exist;
should.exist(err);
should.not.exist(address);
server.getMainAddresses({}, function(err, addresses) {
@ -625,7 +670,7 @@ describe('Copay server', function() {
helpers.getAuthServer(result.copayerId, function(server) {
server.createAddress({}, function(err, address) {
should.not.exist(address);
err.should.exist;
should.exist(err);
err.message.should.contain('not complete');
done();
});
@ -656,7 +701,7 @@ describe('Copay server', function() {
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[0].privKey);
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
err.should.exist;
should.exist(err);
err.message.should.contain('not complete');
done();
});
@ -714,7 +759,7 @@ describe('Copay server', function() {
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
err.should.exist;
should.exist(err);
err.message.should.equal('Invalid proposal signature');
done();
});
@ -727,7 +772,7 @@ describe('Copay server', function() {
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
err.should.exist;
should.exist(err);
err.message.should.equal('Invalid proposal signature');
done();
});
@ -740,7 +785,7 @@ describe('Copay server', function() {
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
err.should.exist;
should.exist(err);
err.code.should.equal('INVALIDADDRESS');
err.message.should.equal('Invalid address');
done();
@ -762,7 +807,15 @@ describe('Copay server', function() {
});
});
it.skip('should fail to create tx for invalid amount', function(done) {});
it('should fail to create tx for invalid amount', function(done) {
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0, null, TestData.copayers[0].privKey);
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
should.exist(err);
err.message.should.equal('Invalid amount');
done();
});
});
it('should fail to create tx when insufficient funds', function(done) {
helpers.stubUtxos(server, wallet, [100], function() {
@ -809,7 +862,22 @@ describe('Copay server', function() {
});
});
it.skip('should fail gracefully when bitcore throws exception on raw tx creation', function(done) {});
it('should fail gracefully when bitcore throws exception on raw tx creation', function(done) {
helpers.stubUtxos(server, wallet, [10], function() {
var bitcoreStub = sinon.stub(Bitcore, 'Transaction');
bitcoreStub.throws({
name: 'dummy',
message: 'dummy exception'
});
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 2, null, TestData.copayers[0].privKey);
server.createTx(txOpts, function(err, tx) {
should.exist(err);
err.message.should.equal('dummy exception');
bitcoreStub.restore();
done();
});
});
});
it('should create tx when there is a pending tx and enough UTXOs', function(done) {
helpers.stubUtxos(server, wallet, [10.1, 10.2, 10.3], function() {
@ -897,7 +965,7 @@ describe('Copay server', function() {
var server, wallet, txid;
beforeEach(function(done) {
helpers.createAndJoinWallet(2, 3, function(s, w) {
helpers.createAndJoinWallet(2, 2, function(s, w) {
server = s;
wallet = w;
helpers.stubUtxos(server, wallet, _.range(1, 9), function() {
@ -924,22 +992,63 @@ describe('Copay server', function() {
should.not.exist(err);
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
var tx = txs[0];
tx.id.should.equal(txid);
var actors = tx.getActors();
actors.length.should.equal(1);
actors[0].should.equal(wallet.copayers[0].id);
var action = tx.getActionBy(wallet.copayers[0].id);
action.type.should.equal('reject');
action.comment.should.equal('some reason');
done();
txs.should.be.empty;
server.getTx({
id: txid
}, function(err, tx) {
var actors = tx.getActors();
actors.length.should.equal(1);
actors[0].should.equal(wallet.copayers[0].id);
var action = tx.getActionBy(wallet.copayers[0].id);
action.type.should.equal('reject');
action.comment.should.equal('some reason');
done();
});
});
});
});
});
it.skip('should fail to reject non-pending TX', function(done) {});
it('should fail to reject non-pending TX', function(done) {
async.waterfall([
function(next) {
server.getPendingTxs({}, function(err, txs) {
var tx = txs[0];
tx.id.should.equal(txid);
next();
});
},
function(next) {
server.rejectTx({
txProposalId: txid,
reason: 'some reason',
}, function(err) {
should.not.exist(err);
next();
});
},
function(next) {
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
txs.should.be.empty;
next();
});
},
function(next) {
helpers.getAuthServer(wallet.copayers[1].id, function(server) {
server.rejectTx({
txProposalId: txid,
reason: 'some other reason',
}, function(err) {
should.exist(err);
err.code.should.equal('TXNOTPENDING');
done();
});
});
},
]);
});
});
describe('#signTx', function() {
@ -1095,6 +1204,57 @@ describe('Copay server', function() {
});
});
});
it('should fail to sign a non-pending TX', function(done) {
async.waterfall([
function(next) {
server.rejectTx({
txProposalId: txid,
reason: 'some reason',
}, function(err) {
should.not.exist(err);
next();
});
},
function(next) {
helpers.getAuthServer(wallet.copayers[1].id, function(server) {
server.rejectTx({
txProposalId: txid,
reason: 'some reason',
}, function(err) {
should.not.exist(err);
next();
});
});
},
function(next) {
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
txs.should.be.empty;
next();
});
},
function(next) {
helpers.getAuthServer(wallet.copayers[2].id, function(server) {
server.getTx({
id: txid
}, function(err, tx) {
should.not.exist(err);
var signatures = helpers.clientSign(tx, TestData.copayers[2].xPrivKey);
server.signTx({
txProposalId: txid,
signatures: signatures,
}, function(err) {
should.exist(err);
err.code.should.equal('TXNOTPENDING');
done();
});
});
});
},
]);
});
});
describe.skip('#broadcastTx', function() {
@ -1644,9 +1804,10 @@ describe('Copay server', function() {
it('should allow creator to remove an signed TX by himself', function(done) {
var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey);
server.signTx({
txProposalId: txp[0],
txProposalId: txp.id,
signatures: signatures,
}, function(err) {
should.not.exist(err);
server.removePendingTx({
txProposalId: txp.id
}, function(err) {
@ -1659,7 +1820,57 @@ describe('Copay server', function() {
});
});
it.skip('should fail to remove non-pending TX', function(done) {});
it('should fail to remove non-pending TX', function(done) {
async.waterfall([
function(next) {
var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey);
server.signTx({
txProposalId: txp.id,
signatures: signatures,
}, function(err) {
should.not.exist(err);
next();
});
},
function(next) {
helpers.getAuthServer(wallet.copayers[1].id, function(server) {
server.rejectTx({
txProposalId: txp.id,
}, function(err) {
should.not.exist(err);
next();
});
});
},
function(next) {
helpers.getAuthServer(wallet.copayers[2].id, function(server) {
server.rejectTx({
txProposalId: txp.id,
}, function(err) {
should.not.exist(err);
next();
});
});
},
function(next) {
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
txs.should.be.empty;
next();
});
},
function(next) {
server.removePendingTx({
txProposalId: txp.id
}, function(err) {
should.exist(err);
err.code.should.equal('TXNOTPENDING');
done();
});
},
]);
});
it('should not allow non-creator copayer to remove an unsigned TX ', function(done) {
helpers.getAuthServer(wallet.copayers[1].id, function(server2) {