Merge pull request #1550 from cmgustavo/bug/10-amount

Bug/Invalid-amount
This commit is contained in:
Matias Pando 2014-10-09 13:15:32 -03:00
commit 02b85870df
4 changed files with 48 additions and 38 deletions

View file

@ -48,32 +48,37 @@ angular.module('copayApp.directives')
}; };
} }
]) ])
.directive('enoughAmount', ['$rootScope', .directive('validAmount', ['$rootScope', '$locale',
function($rootScope) { function($rootScope, locale) {
var w = $rootScope.wallet; var w = $rootScope.wallet;
preconditions.checkState(w); preconditions.checkState(w);
preconditions.checkState(w.settings.unitToSatoshi); preconditions.checkState(w.settings.unitToSatoshi);
var formats = locale.NUMBER_FORMATS;
var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT);
return { return {
require: 'ngModel', require: 'ngModel',
link: function(scope, element, attrs, ctrl) { link: function(scope, element, attrs, ctrl) {
var val = function(value) { var val = function(value) {
var availableBalanceNum = Number(($rootScope.availableBalance * w.settings.unitToSatoshi).toFixed(0));
var vNum = Number((value * w.settings.unitToSatoshi).toFixed(0)); var vNum = Number((value * w.settings.unitToSatoshi).toFixed(0));
if (typeof value == 'undefined') {
ctrl.$pristine = true;
}
if (typeof vNum == "number" && vNum > 0) { if (typeof vNum == "number" && vNum > 0) {
vNum = vNum + feeSat; var decimals = Number(w.settings.unitDecimals);
if (availableBalanceNum < vNum || isNaN(availableBalanceNum)) { var sep_index = ('' + value).indexOf(formats.DECIMAL_SEP);
ctrl.$setValidity('enoughAmount', false); var str_value = ('' + value).substring(sep_index+1);
scope.notEnoughAmount = true; if (sep_index > 0 && str_value.length > decimals) {
ctrl.$setValidity('validAmount', false);
scope.notValidAmount = true;
} else { } else {
ctrl.$setValidity('enoughAmount', true); ctrl.$setValidity('validAmount', true);
scope.notEnoughAmount = null; scope.notValidAmount = null;
} }
} else { } else {
ctrl.$setValidity('enoughAmount', false); ctrl.$setValidity('validAmount', false);
scope.notEnoughAmount = null; scope.notValidAmount = null;
} }
return value; return value;
} }

View file

@ -2206,7 +2206,7 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb)
var ntxid = self.createTxSync(toAddress, amountSatStr, comment, safeUnspent, opts); var ntxid = self.createTxSync(toAddress, amountSatStr, comment, safeUnspent, opts);
if (!ntxid) { if (!ntxid) {
return cb(new Error('Error creating TX')); return cb(new Error('Error creating the Transaction'));
} }
self.sendIndexes(); self.sendIndexes();
@ -2241,12 +2241,19 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
opts[k] = Wallet.builderOpts[k]; opts[k] = Wallet.builderOpts[k];
} }
var b = new Builder(opts) var b;
try {
b = new Builder(opts)
.setUnspent(utxos) .setUnspent(utxos)
.setOutputs([{ .setOutputs([{
address: toAddress, address: toAddress,
amountSatStr: amountSatStr, amountSatStr: amountSatStr,
}]); }]);
} catch (e) {
log.debug(e.message);
return;
};
var selectedUtxos = b.getSelectedUnspent(); var selectedUtxos = b.getSelectedUnspent();
var inputChainPaths = selectedUtxos.map(function(utxo) { var inputChainPaths = selectedUtxos.map(function(utxo) {

View file

@ -62,10 +62,9 @@ describe("Unit: Testing Directives", function() {
describe('Unit: bits', function() { describe('Unit: bits', function() {
beforeEach(inject(function($compile, $rootScope) { beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope; $scope = $rootScope;
$rootScope.availableBalance = 1000;
var element = angular.element( var element = angular.element(
'<form name="form">' + '<form name="form">' +
'<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.0001" max="10000000" enough-amount required>' + '<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.00000001" max="10000000000" valid-amount required>' +
'</form>' '</form>'
); );
$scope.model = { $scope.model = {
@ -81,20 +80,19 @@ describe("Unit: Testing Directives", function() {
form.amount.$setViewValue(800); form.amount.$setViewValue(800);
expect(form.amount.$invalid).to.equal(false); expect(form.amount.$invalid).to.equal(false);
form.amount.$setViewValue(900); form.amount.$setViewValue(900);
expect($scope.notEnoughAmount).to.equal(null); expect($scope.notValidAmount).to.equal(null);
form.amount.$setViewValue(0.44);
expect($scope.notValidAmount).to.equal(null);
}); });
it('should not validate', function() { it('should not validate', function() {
form.amount.$setViewValue(0); form.amount.$setViewValue(0);
expect(form.amount.$invalid).to.equal(true); expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(9999999999); form.amount.$setViewValue(999999999999);
expect(form.amount.$invalid).to.equal(true); expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(901); form.amount.$setViewValue(0.333);
expect(form.amount.$invalid).to.equal(true); expect($scope.notValidAmount).to.equal(true);
form.amount.$setViewValue(1000);
expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(901);
expect($scope.notEnoughAmount).to.equal(true);
}); });
}); });
@ -104,12 +102,13 @@ describe("Unit: Testing Directives", function() {
var w = new FakeWallet(walletConfig); var w = new FakeWallet(walletConfig);
w.settings.unitToSatoshi = 100000000; w.settings.unitToSatoshi = 100000000;
w.settings.unitName = 'BTC'; w.settings.unitName = 'BTC';
w.settings.unitDecimals = 8;
$rootScope.wallet = w; $rootScope.wallet = w;
$rootScope.availableBalance = 0.04; $rootScope.availableBalance = 0.04;
var element = angular.element( var element = angular.element(
'<form name="form">' + '<form name="form">' +
'<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.0001" max="10000000" enough-amount required>' + '<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.00000001" max="10000000000" valid-amount required>' +
'</form>' '</form>'
); );
$scope.model = { $scope.model = {
@ -122,25 +121,24 @@ describe("Unit: Testing Directives", function() {
it('should validate', function() { it('should validate', function() {
form.amount.$setViewValue(0.01); form.amount.$setViewValue(0.01);
expect($scope.notEnoughAmount).to.equal(null); expect($scope.notValidAmount).to.equal(null);
expect(form.amount.$invalid).to.equal(false); expect(form.amount.$invalid).to.equal(false);
form.amount.$setViewValue(0.039); form.amount.$setViewValue(0.039);
expect($scope.notEnoughAmount).to.equal(null); expect($scope.notValidAmount).to.equal(null);
expect(form.amount.$invalid).to.equal(false);
form.amount.$setViewValue(100292.039);
expect($scope.notValidAmount).to.equal(null);
expect(form.amount.$invalid).to.equal(false); expect(form.amount.$invalid).to.equal(false);
}); });
it('should not validate', function() { it('should not validate', function() {
form.amount.$setViewValue(0.03999); form.amount.$setViewValue(0.039998888888888);
expect($scope.notEnoughAmount).to.equal(true); expect($scope.notValidAmount).to.equal(true);
expect(form.amount.$invalid).to.equal(true); expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(0); form.amount.$setViewValue(0);
expect(form.amount.$invalid).to.equal(true); expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(0.0); form.amount.$setViewValue(0.0);
expect(form.amount.$invalid).to.equal(true); expect(form.amount.$invalid).to.equal(true);
form.amount.$setViewValue(0.05);
expect($scope.notEnoughAmount).to.equal(true);
expect(form.amount.$invalid).to.equal(true);
}); });
}); });

View file

@ -61,19 +61,19 @@
ng-show="!sendForm.amount.$invalid && ng-show="!sendForm.amount.$invalid &&
!sendForm.amount.$pristine">valid!</small> !sendForm.amount.$pristine">valid!</small>
<small translate class="has-error" <small translate class="has-error"
ng-show="sendForm.amount.$invalid && ng-show="(sendForm.amount.$invalid || notValidAmount) &&
!sendForm.amount.$pristine && !notEnoughAmount">not valid !sendForm.amount.$pristine">not valid
</small> </small>
<small translate ng-show="notEnoughAmount" class="has-error">Insufficient funds</small>
</label> </label>
<div class="small-9 columns"> <div class="small-9 columns">
<input type="number" id="amount" <input type="number" id="amount"
ng-disabled="loading || ($root.merchant && +$root.merchant.total > 0) || $root.merchantError" ng-disabled="loading || ($root.merchant && +$root.merchant.total > 0) || $root.merchantError"
name="amount" placeholder="{{'Amount'|translate}}" ng-model="amount" name="amount" placeholder="{{'Amount'|translate}}" ng-model="amount"
min="0.00000001" max="10000000000" enough-amount required min="0.00000001" max="10000000000" valid-amount required
autocomplete="off"> autocomplete="off">
<small class="icon-input" ng-show="!sendForm.amount.$invalid && amount"><i class="fi-check"></i></small> <small class="icon-input" ng-show="!sendForm.amount.$invalid && amount"><i class="fi-check"></i></small>
<small class="icon-input" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount"><i class="fi-x"></i></small> <small class="icon-input" ng-show="sendForm.amount.$invalid &&
!sendForm.amount.$pristine && !notValidAmount"><i class="fi-x"></i></small>
<a class="small input-note" title="{{'Send all funds'|translate}}" <a class="small input-note" title="{{'Send all funds'|translate}}"
ng-show="$root.availableBalance > 0 && (!$root.merchant || +$root.merchant.total === 0)" ng-show="$root.availableBalance > 0 && (!$root.merchant || +$root.merchant.total === 0)"
ng-click="topAmount(sendForm)"> ng-click="topAmount(sendForm)">