From f70b9dca8a6a6ae6fa88ab28ba0fe592871ec504 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Tue, 25 Nov 2014 09:51:57 -0300 Subject: [PATCH 1/8] Checking for null values --- js/controllers/history.js | 17 +++++++++++++++-- js/models/Wallet.js | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/js/controllers/history.js b/js/controllers/history.js index af6bacbe1..34fba24a4 100644 --- a/js/controllers/history.js +++ b/js/controllers/history.js @@ -28,9 +28,15 @@ angular.module('copayApp.controllers').controller('HistoryController', $scope.generating = true; w.getTransactionHistory(function(err, res) { - if (err) throw err; + if (err) { + $scope.generating = false; + throw err; + } - if (!res) return; + if (!res) { + $scope.generating = false; + return; + } var unit = w.settings.unitName; var data = res.items; @@ -45,6 +51,13 @@ angular.module('copayApp.controllers').controller('HistoryController', } data.forEach(function(it, index) { + if (!it) { + console.log('Error on tx with index ', index); + return; + } else { + console.log('Txid with index ', it.txid, index); + + } var dataString = formatDate(it.minedTs || it.sentTs) + ',' + it.amount + ',' + it.action + ',' + formatString(it.addressTo) + ',' + formatString(it.comment); if (it.actionList) { dataString += ',' + formatSigners(it.actionList); diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 1414ddf8f..a4d604ff4 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -1368,7 +1368,31 @@ Wallet.prototype.generateAddress = function(isChange) { }; /** - * TODO: get this out of here + * @desc Retrieve all the Transaction proposals (see {@link TxProposals}) + * @return {Object[]} each object returned represents a transaction proposal, with two additional + * booleans: signedByUs and rejectedByUs. An optional third boolean signals + * whether the transaction was finally rejected (finallyRejected set to true). + */ +Wallet.prototype.getTxProposals = function() { + var ret = []; + var self = this; + var copayers = self.getRegisteredCopayerIds(); + var myId = self.getMyCopayerId(); + + _.each(self.txProposals.txps, function(txp, ntxid) { + txp.signedByUs = txp.signedBy[myId] ? true : false; + txp.rejectedByUs = txp.rejectedBy[self.getMyCopayerId()] ? true : false; + txp.finallyRejected = self.totalCopayers - txp.rejectCount < self.requiredCopayers; + txp.isPending = !txp.finallyRejected && !txp.sentTxid; + + if (!txp.readonly || txp.finallyRejected || txp.sentTs) { + ret.push(txp); + } + }); + return ret; +}; + +/** * @desc get list of actions (see {@link getPendingTxProposals}) */ Wallet.prototype._getActionList = function(txp) { @@ -2568,6 +2592,7 @@ Wallet.prototype.getTransactionHistory = function(opts, cb) { function extractInsOuts(tx) { // Inputs + console.log('extractInsOuts'); var inputs = _.map(tx.vin, function(item) { return { type: 'in', @@ -2690,8 +2715,11 @@ Wallet.prototype.getTransactionHistory = function(opts, cb) { self.blockchain.getTransactions(addresses, from, to, function(err, res) { if (err) return cb(err); + console.log(res.items); _.each(res.items, function(tx) { - decorateTx(tx); + if (tx) { + decorateTx(tx); + } }); return cb(null, paginate(res, opts.currentPage, opts.itemsPerPage)); From ae9b79b843c91730a60aaea157ba0594b1f7bd57 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Wed, 26 Nov 2014 18:33:22 -0300 Subject: [PATCH 2/8] Move function getTransactionHistoryCsv to wallet --- js/controllers/history.js | 86 ++-------------- js/models/Wallet.js | 203 +++++++++++++++++++++++++++++++++++++- 2 files changed, 209 insertions(+), 80 deletions(-) diff --git a/js/controllers/history.js b/js/controllers/history.js index 34fba24a4..d2ce29f93 100644 --- a/js/controllers/history.js +++ b/js/controllers/history.js @@ -27,89 +27,13 @@ angular.module('copayApp.controllers').controller('HistoryController', if (!w) return; $scope.generating = true; - w.getTransactionHistory(function(err, res) { - if (err) { - $scope.generating = false; - throw err; - } - if (!res) { - $scope.generating = false; - return; - } + //getTransactionHistoryCSV - var unit = w.settings.unitName; - var data = res.items; - var filename = "copay_history.csv"; - var csvContent = "data:text/csv;charset=utf-8,"; - csvContent += "Date,Amount(" + unit + "),Action,AddressTo,Comment"; - - if (w.isShared()) { - csvContent += ",Signers\n"; - } else { - csvContent += "\n"; - } - - data.forEach(function(it, index) { - if (!it) { - console.log('Error on tx with index ', index); - return; - } else { - console.log('Txid with index ', it.txid, index); - - } - var dataString = formatDate(it.minedTs || it.sentTs) + ',' + it.amount + ',' + it.action + ',' + formatString(it.addressTo) + ',' + formatString(it.comment); - if (it.actionList) { - dataString += ',' + formatSigners(it.actionList); - } - csvContent += index < data.length ? dataString + "\n" : dataString; - }); - - var encodedUri = encodeURI(csvContent); - var link = document.createElement("a"); - link.setAttribute("href", encodedUri); - link.setAttribute("download", filename); - - link.click(); + w.getTransactionHistoryCsv(function() { $scope.generating = false; $scope.$digest(); - function formatDate(date) { - var dateObj = new Date(date); - if (!dateObj) { - log.error('Error formating a date'); - return 'DateError' - } - if (!dateObj.toJSON()) { - return ''; - } - - return dateObj.toJSON().substring(0, 10); - } - - function formatString(str) { - if (!str) return ''; - - if (str.indexOf('"') !== -1) { - //replace all - str = str.replace(new RegExp('"', 'g'), '\''); - } - - //escaping commas - str = '\"' + str + '\"'; - - return str; - } - - function formatSigners(item) { - if (!item) return ''; - var str = ''; - item.forEach(function(it, index) { - str += index == 0 ? w.publicKeyRing.nicknameForCopayer(it.cId) : '|' + w.publicKeyRing.nicknameForCopayer(it.cId); - }); - return str; - } - }) }; @@ -147,11 +71,17 @@ angular.module('copayApp.controllers').controller('HistoryController', } var items = res.items; +<<<<<<< HEAD var now = new Date(); _.each(items, function(tx) { tx.ts = tx.minedTs || tx.sentTs; tx.rateTs = Math.floor((tx.ts || now) / 1000); tx.amount = $filter('noFractionNumber')(tx.amount); +======= + + _.each(items, function(r, index) { + r.ts = r.minedTs || r.sentTs; +>>>>>>> Move function getTransactionHistoryCsv to wallet }); var index = _.indexBy(items, 'rateTs'); diff --git a/js/models/Wallet.js b/js/models/Wallet.js index a4d604ff4..3d25c3101 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -2567,6 +2567,207 @@ Wallet.prototype.isComplete = function() { return this.publicKeyRing.isComplete(); }; +/** + * @desc Sign a JSON + * + * @TODO: THIS WON'T WORK ALLWAYS! JSON.stringify doesn't warants an order + * @param {Object} payload - the payload to verify + * @return {string} base64 encoded string + */ +Wallet.prototype.signJson = function(payload) { + var key = new bitcore.Key(); + key.private = new Buffer(this.getMyCopayerIdPriv(), 'hex'); + key.regenerateSync(); + var sign = bitcore.Message.sign(JSON.stringify(payload), key); + return sign.toString('hex'); +} + +/** + * @desc Verify that a JSON object is correctly signed + * + * @TODO: THIS WON'T WORK ALLWAYS! JSON.stringify doesn't warants an order + * + * @param {string} senderId - a sender's public key, hex encoded + * @param {Object} payload - the object to verify + * @param {string} signature - a sender's public key, hex encoded + * @return {boolean} + */ +Wallet.prototype.verifySignedJson = function(senderId, payload, signature) { + var pubkey = new Buffer(senderId, 'hex'); + var sign = new Buffer(signature, 'hex'); + var v = bitcore.Message.verifyWithPubKey(pubkey, JSON.stringify(payload), sign); + return v; +} + +/** + * @desc Create a HTTP request + * @TODO: This shouldn't be a wallet responsibility + */ +Wallet.request = function(options, callback) { + if (_.isString(options)) { + options = { + uri: options + }; + } + + options.method = options.method || 'GET'; + options.headers = options.headers || {}; + + var ret = { + success: function(cb) { + this._success = cb; + return this; + }, + error: function(cb) { + this._error = cb; + return this; + }, + _success: function() {; + }, + _error: function(_, err) { + throw err; + } + }; + + var method = (options.method || 'GET').toUpperCase(); + var uri = options.uri || options.url; + var req = options; + + req.headers = req.headers || {}; + req.body = req.body || req.data || {}; + + var xhr = new XMLHttpRequest(); + xhr.open(method, uri, true); + + Object.keys(req.headers).forEach(function(key) { + var val = req.headers[key]; + if (key === 'Content-Length') return; + if (key === 'Content-Transfer-Encoding') return; + xhr.setRequestHeader(key, val); + }); + + if (req.responseType) { + xhr.responseType = req.responseType; + } + + xhr.onload = function(event) { + var response = xhr.response; + var buf = new Uint8Array(response); + var headers = {}; + (xhr.getAllResponseHeaders() || '').replace( + /(?:\r?\n|^)([^:\r\n]+): *([^\r\n]+)/g, + function($0, $1, $2) { + headers[$1.toLowerCase()] = $2; + } + ); + return ret._success(buf, xhr.status, headers, options); + }; + + xhr.onerror = function(event) { + var status; + if (xhr.status === 0 || !xhr.statusText) { + status = 'HTTP Request Error: This endpoint likely does not support cross-origin requests.'; + } else { + status = xhr.statusText; + } + return ret._error(null, status, null, options); + }; + + if (req.body) { + xhr.send(req.body); + } else { + xhr.send(null); + } + + return ret; +}; + + + +Wallet.prototype.getTransactionHistoryCsv = function(cb) { + var self = this; + self.getTransactionHistory(function(err, res) { + if (err) { + return cb(err); + } + + if (!res) { + return cb('Error'); + } + + var unit = self.settings.unitName; + var data = res.items; + var filename = "copay_history.csv"; + var csvContent = "data:text/csv;charset=utf-8,"; + csvContent += "Date,Amount(" + unit + "),Action,AddressTo,Comment"; + + if (self.isShared()) { + csvContent += ",Signers\n"; + } else { + csvContent += "\n"; + } + + data.forEach(function(it, index) { + if (!it) { + return cb('Error'); + } + var dataString = formatDate(it.minedTs || it.sentTs) + ',' + it.amount + ',' + it.action + ',' + formatString(it.addressTo) + ',' + formatString(it.comment); + if (self.isShared() && it.actionList) { + dataString += ',' + formatSigners(it.actionList); + } + csvContent += index < data.length ? dataString + "\n" : dataString; + }); + + var encodedUri = encodeURI(csvContent); + var link = document.createElement("a"); + link.setAttribute("href", encodedUri); + link.setAttribute("download", filename); + + link.click(); + + return cb(null); + + function formatDate(date) { + var dateObj = new Date(date); + if (!dateObj) { + log.error('Error formating a date'); + return 'DateError' + } + if (!dateObj.toJSON()) { + return ''; + } + + return dateObj.toJSON().substring(0, 10); + } + + function formatString(str) { + if (!str) return ''; + + if (str.indexOf('"') !== -1) { + //replace all + str = str.replace(new RegExp('"', 'g'), '\''); + } + + //escaping commas + str = '\"' + str + '\"'; + + return str; + } + + function formatSigners(item) { + if (!item) return ''; + var str = ''; + item.forEach(function(it, index) { + str += index == 0 ? self.publicKeyRing.nicknameForCopayer(it.cId) : '|' + self.publicKeyRing.nicknameForCopayer(it.cId); + }); + return str; + } + + }); + +} + + /** * @desc Return a list of past transactions * @@ -2592,7 +2793,6 @@ Wallet.prototype.getTransactionHistory = function(opts, cb) { function extractInsOuts(tx) { // Inputs - console.log('extractInsOuts'); var inputs = _.map(tx.vin, function(item) { return { type: 'in', @@ -2715,7 +2915,6 @@ Wallet.prototype.getTransactionHistory = function(opts, cb) { self.blockchain.getTransactions(addresses, from, to, function(err, res) { if (err) return cb(err); - console.log(res.items); _.each(res.items, function(tx) { if (tx) { decorateTx(tx); From 3c238ca0649b70b9e06138700c49c6f23439d725 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 27 Nov 2014 10:56:41 -0300 Subject: [PATCH 3/8] Added test to transactionHistoryCvs --- js/controllers/history.js | 13 ++++++-- js/models/Wallet.js | 16 ++++------ test/Wallet.js | 64 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/js/controllers/history.js b/js/controllers/history.js index d2ce29f93..20c149026 100644 --- a/js/controllers/history.js +++ b/js/controllers/history.js @@ -28,12 +28,19 @@ angular.module('copayApp.controllers').controller('HistoryController', $scope.generating = true; - //getTransactionHistoryCSV + w.getTransactionHistoryCsv(function(csvContent) { + if (csvContent && csvContent !== 'ERROR') { + var filename = "copay_history.csv"; - w.getTransactionHistoryCsv(function() { + var encodedUri = encodeURI(csvContent); + var link = document.createElement("a"); + link.setAttribute("href", encodedUri); + link.setAttribute("download", filename); + + link.click(); + } $scope.generating = false; $scope.$digest(); - }) }; diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 3d25c3101..e33e4c867 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -2688,16 +2688,17 @@ Wallet.prototype.getTransactionHistoryCsv = function(cb) { var self = this; self.getTransactionHistory(function(err, res) { if (err) { - return cb(err); + log.debug(err); + return cb('ERROR'); } if (!res) { - return cb('Error'); + return cb('ERROR'); } var unit = self.settings.unitName; var data = res.items; - var filename = "copay_history.csv"; + var csvContent = "data:text/csv;charset=utf-8,"; csvContent += "Date,Amount(" + unit + "),Action,AddressTo,Comment"; @@ -2709,7 +2710,7 @@ Wallet.prototype.getTransactionHistoryCsv = function(cb) { data.forEach(function(it, index) { if (!it) { - return cb('Error'); + return cb('ERROR'); } var dataString = formatDate(it.minedTs || it.sentTs) + ',' + it.amount + ',' + it.action + ',' + formatString(it.addressTo) + ',' + formatString(it.comment); if (self.isShared() && it.actionList) { @@ -2718,14 +2719,9 @@ Wallet.prototype.getTransactionHistoryCsv = function(cb) { csvContent += index < data.length ? dataString + "\n" : dataString; }); - var encodedUri = encodeURI(csvContent); - var link = document.createElement("a"); - link.setAttribute("href", encodedUri); - link.setAttribute("download", filename); - link.click(); - return cb(null); + return cb(csvContent); function formatDate(date) { var dateObj = new Date(date); diff --git a/test/Wallet.js b/test/Wallet.js index 91e14e739..ad7891526 100644 --- a/test/Wallet.js +++ b/test/Wallet.js @@ -2472,6 +2472,7 @@ describe('Wallet model', function() { }); }); + // TODO describe.skip('#onPayProPaymentAck', function() { it('should emit', function() { @@ -2484,6 +2485,69 @@ describe('Wallet model', function() { }); }); + describe('#getTransactionHistoryCsv', function() { + it.only('should return list of txs', function(done) { + var w = cachedCreateW2(); + var txs = [{ + vin: [{ + addr: 'addr_in_1', + valueSat: 1000 + }], + vout: [{ + scriptPubKey: { + addresses: ['addr_out_1'], + }, + value: '0.00000900', + }], + fees: 0.00000100 + }, { + vin: [{ + addr: 'addr_in_2', + valueSat: 2000 + }], + vout: [{ + scriptPubKey: { + addresses: ['addr_out_2'], + }, + value: '0.00001900', + }], + fees: 0.00000100 + }, { + vin: [{ + addr: 'addr_in_1', + valueSat: 3000 + + }], + vout: [{ + scriptPubKey: { + addresses: ['addr_out_2'], + }, + value: '0.00002900', + + }], + fees: 0.00000100 + }]; + + w.blockchain.getTransactions = sinon.stub().yields(null, { + items: txs, + totalItems: txs.length, + }); + w.getAddressesInfo = sinon.stub().returns([{ + addressStr: 'addr_in_1' + }, { + addressStr: 'addr_out_2' + }]); + + w.getTransactionHistoryCsv(function(data) { + data.should.exist; + data.should.equal('data:text/csv;charset=utf-8,Date,Amount(bits),Action,AddressTo,Comment,Signers\n,9,sent,"addr_out_1",\n,19,received,,\n,29,moved,"addr_out_2",\n'); + done(); + }); + }); + + }); + + describe.skip('#read', function() { var network, blockchain; From 8c36b040c05be04b0452eb98c64454840b23a6b6 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 27 Nov 2014 11:07:14 -0300 Subject: [PATCH 4/8] Test fixed --- test/Wallet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Wallet.js b/test/Wallet.js index ad7891526..e9c2c2acd 100644 --- a/test/Wallet.js +++ b/test/Wallet.js @@ -2486,7 +2486,7 @@ describe('Wallet model', function() { }); describe('#getTransactionHistoryCsv', function() { - it.only('should return list of txs', function(done) { + it('should return list of txs', function(done) { var w = cachedCreateW2(); var txs = [{ vin: [{ From 78c1d409867453b974963b1ce9814414fab2a6a6 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 27 Nov 2014 18:11:30 -0300 Subject: [PATCH 5/8] Code cleaned --- js/models/Wallet.js | 117 -------------------------------------------- 1 file changed, 117 deletions(-) diff --git a/js/models/Wallet.js b/js/models/Wallet.js index e33e4c867..04e58e01c 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -2567,123 +2567,6 @@ Wallet.prototype.isComplete = function() { return this.publicKeyRing.isComplete(); }; -/** - * @desc Sign a JSON - * - * @TODO: THIS WON'T WORK ALLWAYS! JSON.stringify doesn't warants an order - * @param {Object} payload - the payload to verify - * @return {string} base64 encoded string - */ -Wallet.prototype.signJson = function(payload) { - var key = new bitcore.Key(); - key.private = new Buffer(this.getMyCopayerIdPriv(), 'hex'); - key.regenerateSync(); - var sign = bitcore.Message.sign(JSON.stringify(payload), key); - return sign.toString('hex'); -} - -/** - * @desc Verify that a JSON object is correctly signed - * - * @TODO: THIS WON'T WORK ALLWAYS! JSON.stringify doesn't warants an order - * - * @param {string} senderId - a sender's public key, hex encoded - * @param {Object} payload - the object to verify - * @param {string} signature - a sender's public key, hex encoded - * @return {boolean} - */ -Wallet.prototype.verifySignedJson = function(senderId, payload, signature) { - var pubkey = new Buffer(senderId, 'hex'); - var sign = new Buffer(signature, 'hex'); - var v = bitcore.Message.verifyWithPubKey(pubkey, JSON.stringify(payload), sign); - return v; -} - -/** - * @desc Create a HTTP request - * @TODO: This shouldn't be a wallet responsibility - */ -Wallet.request = function(options, callback) { - if (_.isString(options)) { - options = { - uri: options - }; - } - - options.method = options.method || 'GET'; - options.headers = options.headers || {}; - - var ret = { - success: function(cb) { - this._success = cb; - return this; - }, - error: function(cb) { - this._error = cb; - return this; - }, - _success: function() {; - }, - _error: function(_, err) { - throw err; - } - }; - - var method = (options.method || 'GET').toUpperCase(); - var uri = options.uri || options.url; - var req = options; - - req.headers = req.headers || {}; - req.body = req.body || req.data || {}; - - var xhr = new XMLHttpRequest(); - xhr.open(method, uri, true); - - Object.keys(req.headers).forEach(function(key) { - var val = req.headers[key]; - if (key === 'Content-Length') return; - if (key === 'Content-Transfer-Encoding') return; - xhr.setRequestHeader(key, val); - }); - - if (req.responseType) { - xhr.responseType = req.responseType; - } - - xhr.onload = function(event) { - var response = xhr.response; - var buf = new Uint8Array(response); - var headers = {}; - (xhr.getAllResponseHeaders() || '').replace( - /(?:\r?\n|^)([^:\r\n]+): *([^\r\n]+)/g, - function($0, $1, $2) { - headers[$1.toLowerCase()] = $2; - } - ); - return ret._success(buf, xhr.status, headers, options); - }; - - xhr.onerror = function(event) { - var status; - if (xhr.status === 0 || !xhr.statusText) { - status = 'HTTP Request Error: This endpoint likely does not support cross-origin requests.'; - } else { - status = xhr.statusText; - } - return ret._error(null, status, null, options); - }; - - if (req.body) { - xhr.send(req.body); - } else { - xhr.send(null); - } - - return ret; -}; - - - Wallet.prototype.getTransactionHistoryCsv = function(cb) { var self = this; self.getTransactionHistory(function(err, res) { From 2c81f2ab8c2067966c874ba87237667c975b00cb Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Fri, 28 Nov 2014 10:43:01 -0300 Subject: [PATCH 6/8] Added jsdoc --- js/models/Wallet.js | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 04e58e01c..3e7d07a96 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -1367,30 +1367,6 @@ Wallet.prototype.generateAddress = function(isChange) { return addr; }; -/** - * @desc Retrieve all the Transaction proposals (see {@link TxProposals}) - * @return {Object[]} each object returned represents a transaction proposal, with two additional - * booleans: signedByUs and rejectedByUs. An optional third boolean signals - * whether the transaction was finally rejected (finallyRejected set to true). - */ -Wallet.prototype.getTxProposals = function() { - var ret = []; - var self = this; - var copayers = self.getRegisteredCopayerIds(); - var myId = self.getMyCopayerId(); - - _.each(self.txProposals.txps, function(txp, ntxid) { - txp.signedByUs = txp.signedBy[myId] ? true : false; - txp.rejectedByUs = txp.rejectedBy[self.getMyCopayerId()] ? true : false; - txp.finallyRejected = self.totalCopayers - txp.rejectCount < self.requiredCopayers; - txp.isPending = !txp.finallyRejected && !txp.sentTxid; - - if (!txp.readonly || txp.finallyRejected || txp.sentTs) { - ret.push(txp); - } - }); - return ret; -}; /** * @desc get list of actions (see {@link getPendingTxProposals}) @@ -2567,6 +2543,10 @@ Wallet.prototype.isComplete = function() { return this.publicKeyRing.isComplete(); }; +/** + * @desc Return a list of transactions on CSV format + * @return {Object} the list of transactions on CSV format + */ Wallet.prototype.getTransactionHistoryCsv = function(cb) { var self = this; self.getTransactionHistory(function(err, res) { From 0712300580c6e7901f1047c69afd997670f37749 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Tue, 2 Dec 2014 15:13:30 -0300 Subject: [PATCH 7/8] Fixing style --- js/controllers/history.js | 6 ------ views/history.html | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/js/controllers/history.js b/js/controllers/history.js index 20c149026..82c387d12 100644 --- a/js/controllers/history.js +++ b/js/controllers/history.js @@ -78,17 +78,11 @@ angular.module('copayApp.controllers').controller('HistoryController', } var items = res.items; -<<<<<<< HEAD var now = new Date(); _.each(items, function(tx) { tx.ts = tx.minedTs || tx.sentTs; tx.rateTs = Math.floor((tx.ts || now) / 1000); tx.amount = $filter('noFractionNumber')(tx.amount); -======= - - _.each(items, function(r, index) { - r.ts = r.minedTs || r.sentTs; ->>>>>>> Move function getTransactionHistoryCsv to wallet }); var index = _.indexBy(items, 'rateTs'); diff --git a/views/history.html b/views/history.html index d438af1b9..eaa23f302 100644 --- a/views/history.html +++ b/views/history.html @@ -130,7 +130,7 @@
-
+
Generating file... From c7590c2d33a246abaa07f70ac2c48157eacf9317 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Tue, 2 Dec 2014 17:46:31 -0300 Subject: [PATCH 8/8] Test fixed and added error checks --- js/models/Wallet.js | 13 +++++-------- test/Wallet.js | 47 ++++++++++++++++++--------------------------- 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 3e7d07a96..010294bfc 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -2550,13 +2550,10 @@ Wallet.prototype.isComplete = function() { Wallet.prototype.getTransactionHistoryCsv = function(cb) { var self = this; self.getTransactionHistory(function(err, res) { + preconditions.checkState(res); if (err) { - log.debug(err); - return cb('ERROR'); - } - - if (!res) { - return cb('ERROR'); + log.warn(err); + return cb(new Error('TXHISTORY: ' + err.toString())); } var unit = self.settings.unitName; @@ -2573,7 +2570,7 @@ Wallet.prototype.getTransactionHistoryCsv = function(cb) { data.forEach(function(it, index) { if (!it) { - return cb('ERROR'); + return cb(new Error('TXHISTORY: The item is null')); } var dataString = formatDate(it.minedTs || it.sentTs) + ',' + it.amount + ',' + it.action + ',' + formatString(it.addressTo) + ',' + formatString(it.comment); if (self.isShared() && it.actionList) { @@ -2589,7 +2586,7 @@ Wallet.prototype.getTransactionHistoryCsv = function(cb) { function formatDate(date) { var dateObj = new Date(date); if (!dateObj) { - log.error('Error formating a date'); + log.warn('Error formating a date'); return 'DateError' } if (!dateObj.toJSON()) { diff --git a/test/Wallet.js b/test/Wallet.js index e9c2c2acd..74d5be787 100644 --- a/test/Wallet.js +++ b/test/Wallet.js @@ -2391,14 +2391,6 @@ describe('Wallet model', function() { items: txs, totalItems: txs.length, }); - w.getAddressesInfo = sinon.stub().returns([{ - addressStr: 'addr_in_1' - }, { - addressStr: 'addr_in_2' - }, { - addressStr: 'change', - isChange: true, - }]); w.addressBook = { 'addr_out_1': { @@ -2441,14 +2433,6 @@ describe('Wallet model', function() { items: txs, totalItems: txs.length, }); - w.getAddressesInfo = sinon.stub().returns([{ - addressStr: 'addr_in_1' - }, { - addressStr: 'addr_in_2' - }, { - addressStr: 'change', - isChange: true, - }]); w.txProposals.txps = [{ sentTxid: 'id0', @@ -2490,37 +2474,37 @@ describe('Wallet model', function() { var w = cachedCreateW2(); var txs = [{ vin: [{ - addr: 'addr_in_1', + addr: 'in_1', valueSat: 1000 }], vout: [{ scriptPubKey: { - addresses: ['addr_out_1'], + addresses: ['out_1'], }, value: '0.00000900', }], fees: 0.00000100 }, { vin: [{ - addr: 'addr_in_2', + addr: 'in_2', valueSat: 2000 }], vout: [{ scriptPubKey: { - addresses: ['addr_out_2'], + addresses: ['out_2'], }, value: '0.00001900', }], fees: 0.00000100 }, { vin: [{ - addr: 'addr_in_1', + addr: 'in_3', valueSat: 3000 }], vout: [{ scriptPubKey: { - addresses: ['addr_out_2'], + addresses: ['out_3'], }, value: '0.00002900', @@ -2532,15 +2516,22 @@ describe('Wallet model', function() { items: txs, totalItems: txs.length, }); - w.getAddressesInfo = sinon.stub().returns([{ - addressStr: 'addr_in_1' - }, { - addressStr: 'addr_out_2' - }]); + + sinon.stub(w, 'getAddresses').returns(['in_1', 'in_2', 'in_3', 'out_1', 'out_2', 'out_3']); + var s = sinon.stub(w.publicKeyRing, 'addressIsOwn'); + s.withArgs('in_1').returns(true); + s.withArgs('out_1').returns(false); + + s.withArgs('in_2').returns(false); + s.withArgs('out_2').returns(true); + + s.withArgs('in_3').returns(true); + s.withArgs('out_3').returns(true); + w.getTransactionHistoryCsv(function(data) { data.should.exist; - data.should.equal('data:text/csv;charset=utf-8,Date,Amount(bits),Action,AddressTo,Comment,Signers\n,9,sent,"addr_out_1",\n,19,received,,\n,29,moved,"addr_out_2",\n'); + data.should.equal('data:text/csv;charset=utf-8,Date,Amount(bits),Action,AddressTo,Comment,Signers\n,9,sent,"out_1",\n,0,moved,"out_2",\n,29,sent,"out_3",\n'); done(); }); });