diff --git a/src/core/remote.js b/src/core/remote.js index 739ab738..7b9c2f7b 100644 --- a/src/core/remote.js +++ b/src/core/remote.js @@ -13,12 +13,12 @@ // has not yet been implemented. However, this class has been designed for it // to be a very simple drop option. -const EventEmitter = require('events').EventEmitter; const util = require('util'); const assert = require('assert'); +const _ = require('lodash'); const LRU = require('lru-cache'); const async = require('async'); -const lodash = require('lodash'); +const EventEmitter = require('events').EventEmitter; const Server = require('./server').Server; const Request = require('./request').Request; const Amount = require('./amount').Amount; @@ -47,7 +47,7 @@ function Remote(options = {}) { const self = this; - lodash.merge(this, lodash.defaults(options, Remote.DEFAULTS)); + _.merge(this, _.defaults(options, Remote.DEFAULTS)); this.state = 'offline'; // 'online', 'offline' this._server_fatal = false; // server exited @@ -152,7 +152,7 @@ function Remote(options = {}) { function listenersModified(action, event) { // Automatically subscribe and unsubscribe to orderbook // on the basis of existing event listeners - if (lodash.contains(Remote.TRANSACTION_EVENTS, event)) { + if (_.contains(Remote.TRANSACTION_EVENTS, event)) { switch (action) { case 'add': if (++self._transaction_listeners === 1) { @@ -448,7 +448,7 @@ Remote.prototype.disconnect = function(callback_) { throw new Error('No servers available, not disconnecting'); } - const callback = lodash.isFunction(callback_) + const callback = _.isFunction(callback_) ? callback_ : function() {}; @@ -737,7 +737,7 @@ Remote.prototype.request = function(request_) { } if (typeof this[request] === 'function') { - const args = Array.prototype.slice.call(arguments, 1); + const args = _.slice(arguments, 1); return this[request].apply(this, args); } @@ -766,6 +766,31 @@ Remote.prototype.request = function(request_) { } }; +/** + * Create options object from positional function arguments + * + * @param {Array} params function parameters + * @param {Array} args function arguments + * @return {Object} keyed options + */ + +function makeOptions(command, params, args) { + const result = {}; + + log.warn( + 'DEPRECATED: First argument to ' + command + + ' request constructor must be an object containing' + + ' request properties: ' + + params.join(', ') + ); + + if (_.isFunction(_.last(args))) { + result.callback = args.pop(); + } + + return _.merge(result, _.zipObject(params, args)); +} + /** * Request ping * @@ -981,7 +1006,7 @@ Remote.prototype.requestLedgerEntry = function(type, callback_) { const self = this; const request = new Request(this, 'ledger_entry'); - const callback = lodash.isFunction(type) ? type : callback_; + const callback = _.isFunction(type) ? type : callback_; // Transparent caching. When .request() is invoked, look in the Remote object // for the result. If not found, listen, cache result, and emit it. @@ -1006,7 +1031,6 @@ Remote.prototype.requestLedgerEntry = function(type, callback_) { if (node) { // Emulate fetch of ledger entry. - // console.log('request_ledger_entry: emulating'); // YYY Missing lots of fields. request.emit('success', {node: node}); bDefault = false; @@ -1016,7 +1040,6 @@ Remote.prototype.requestLedgerEntry = function(type, callback_) { case 'account_root': request.once('success', function(message) { // Cache node. - // console.log('request_ledger_entry: caching'); self.ledgers.current .account_root[message.node.Account] = message.node; }); @@ -1024,13 +1047,11 @@ Remote.prototype.requestLedgerEntry = function(type, callback_) { default: // This type not cached. - // console.log('request_ledger_entry: non-cached type'); } } } if (bDefault) { - // console.log('request_ledger_entry: invoking'); request.request_default(); } }; @@ -1093,26 +1114,17 @@ Remote.prototype.requestUnsubscribe = function(streams, callback) { Remote.prototype.requestTransactionEntry = function(options_, callback_) { // If not trusted, need to check proof, maybe talk packet protocol. // utils.assert(this.trusted); - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({ + if (_.isPlainObject(options_)) { + _.merge(options, { ledger: options_.ledger_index || options_.ledger_hash }, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - hash: args.shift(), - ledger: args.shift() - }; + _.merge(options, makeOptions( + 'transaction_entry', + ['hash', 'ledger'], + _.slice(arguments))); } const request = new Request(this, 'transaction_entry'); @@ -1130,7 +1142,7 @@ Remote.prototype.requestTransactionEntry = function(options_, callback_) { throw new Error('ledger must be a ledger index or hash'); } - request.callback(callback); + request.callback(options.callback); return request; }; @@ -1148,24 +1160,16 @@ Remote.prototype.requestTransactionEntry = function(options_, callback_) { Remote.prototype.requestTransaction = Remote.prototype.requestTx = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - hash: args.shift(), - binary: args.shift() - }; + _.merge(options, makeOptions( + 'tx', + ['hash', 'binary'], + _.slice(arguments) + )); } const request = new Request(this, 'tx'); @@ -1175,13 +1179,12 @@ Remote.prototype.requestTx = function(options_, callback_) { request.once('success', function(res) { if (options.binary === false) { request.emit('transaction', res); - return; + } else { + request.emit('transaction', Remote.parseBinaryTransaction(res)); } - - request.emit('transaction', Remote.parseBinaryTransaction(res)); }); - request.callback(callback, 'transaction'); + request.callback(options.callback, 'transaction'); return request; }; @@ -1196,7 +1199,7 @@ Remote.prototype.requestTx = function(options_, callback_) { * ledger closes. You have to supply a ledger_index or ledger_hash * when paging to ensure a complete response * - * @param {String} type - request name, e.g. 'account_lines' + * @param {String} command - request command, e.g. 'account_lines' * @param {Object} options - all optional * @param {String} account - ripple address * @param {String} peer - ripple address @@ -1209,35 +1212,21 @@ Remote.prototype.requestTx = function(options_, callback_) { */ Remote.accountRequest = function(command, options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - account: args.shift(), - peer: args.shift(), - ledger: args.shift(), - limit: args.shift(), - marker: args.shift() - }; + _.merge(options, makeOptions( + command, + ['account', 'ledger', 'peer', 'limit', 'marker'], + _.slice(arguments, 1))); } - const {account, ledger, peer, limit, marker} = options; - // if a marker is given, we need a ledger // check if a valid ledger_index or ledger_hash is provided - if (marker) { - if (!(Number(ledger) > 0) && !UInt256.is_valid(ledger)) { + if (options.marker) { + if (!(Number(options.ledger) > 0) && !UInt256.is_valid(options.ledger)) { throw new Error( 'A ledger_index or ledger_hash must be provided when using a marker'); } @@ -1245,18 +1234,15 @@ Remote.accountRequest = function(command, options_, callback_) { const request = new Request(this, command); - if (account) { - request.message.account = UInt160.json_rewrite(account); + request.message.account = UInt160.json_rewrite(options.account); + request.selectLedger(options.ledger); + + if (UInt160.is_valid(options.peer)) { + request.message.peer = UInt160.json_rewrite(options.peer); } - request.selectLedger(ledger); - - if (UInt160.is_valid(peer)) { - request.message.peer = UInt160.json_rewrite(peer); - } - - if (!isNaN(limit)) { - let _limit = Number(limit); + if (!isNaN(options.limit)) { + let _limit = Number(options.limit); // max for 32-bit unsigned int is 4294967295 // we'll clamp to 1e9 @@ -1272,11 +1258,11 @@ Remote.accountRequest = function(command, options_, callback_) { request.message.limit = _limit; } - if (marker) { - request.message.marker = marker; + if (options.marker) { + request.message.marker = options.marker; } - request.callback(callback); + request.callback(options.callback); return request; }; @@ -1336,7 +1322,20 @@ Remote.prototype.requestAccountCurrencies = function(...args) { Remote.prototype.requestAccountLines = function(...args) { // XXX Does this require the server to be trusted? // utils.assert(this.trusted); - const options = ['account_lines', ...args]; + let options = ['account_lines']; + + if (_.isPlainObject(args[0])) { + options = options.concat(args); + } else { + const [account, peer, ledger] = args; + options = options.concat([ + account, + ledger, + peer, + ...args.slice(3) + ]); + } + return Remote.accountRequest.apply(this, options); }; @@ -1549,18 +1548,17 @@ Remote.prototype.requestTxHistory = function(start_, callback_) { // utils.assert(this.trusted); const request = new Request(this, 'tx_history'); - let start = start_; - const callback = callback_; + const options = {start: start_, callback: callback_}; - if (lodash.isPlainObject(start)) { - start = start.start; + if (_.isPlainObject(start_)) { + _.merge(options, start_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); + _.merge(options, makeOptions( + 'tx_history', ['start'], _.slice(arguments))); } - request.message.start = start; - request.callback(callback); + request.message.start = options.start; + request.callback(options.callback); return request; }; @@ -1579,34 +1577,22 @@ Remote.prototype.requestTxHistory = function(start_, callback_) { */ Remote.prototype.requestBookOffers = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; if (options_.gets || options_.taker_gets) { - options = lodash.merge({ + _.merge(options, { pays: options_.taker_pays, gets: options_.taker_gets }, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - gets: args.shift(), - pays: args.shift(), - taker: args.shift(), - ledger: args.shift(), - limit: args.shift() - }; + _.merge(options, makeOptions( + 'book_offers', + ['gets', 'pays', 'taker', 'ledger', 'limit'], + _.slice(arguments) + )); } const {gets, pays, taker, ledger, limit} = options; - const request = new Request(this, 'book_offers'); request.message.taker_gets = { @@ -1645,7 +1631,7 @@ Remote.prototype.requestBookOffers = function(options_, callback_) { request.message.limit = _limit; } - request.callback(callback); + request.callback(options.callback); return request; }; @@ -1660,23 +1646,21 @@ Remote.prototype.requestBookOffers = function(options_, callback_) { Remote.prototype.requestWalletAccounts = function(options_, callback_) { utils.assert(this.trusted); // Don't send secrets. - let options; - const callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - options = { - seed: arguments[0] - }; + _.merge(options, makeOptions( + 'wallet_accounts', + ['seed'], + _.slice(arguments) + )); } const request = new Request(this, 'wallet_accounts'); request.message.seed = options.seed; - request.callback(callback); + request.callback(options.callback); return request; }; @@ -1693,26 +1677,22 @@ Remote.prototype.requestWalletAccounts = function(options_, callback_) { Remote.prototype.requestSign = function(options_, callback_) { utils.assert(this.trusted); // Don't send secrets. - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - options = { - secret: arguments[0], - tx_json: arguments[1] - }; - - callback = arguments[2]; + _.merge(options, makeOptions( + 'sign', + ['secret', 'tx_json'], + _.slice(arguments) + )); } const request = new Request(this, 'sign'); request.message.secret = options.secret; request.message.tx_json = options.tx_json; - request.callback(callback); + request.callback(options.callback); return request; }; @@ -1743,7 +1723,7 @@ Remote.prototype.requestSubmit = function(callback) { Remote.prototype._serverPrepareSubscribe = function(server, callback_) { const self = this; const feeds = ['ledger', 'server']; - const callback = lodash.isFunction(server) ? server : callback_; + const callback = _.isFunction(server) ? server : callback_; if (this._transaction_listeners) { feeds.push('transactions'); @@ -1812,24 +1792,15 @@ Remote.prototype.requestLedgerAccept = function(callback) { */ Remote.accountRootRequest = function(command, filter, options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - account: args.shift(), - ledger: args.shift() - }; + _.merge(options, makeOptions( + command, + ['account', 'ledger'], + _.slice(arguments, 2))); } const request = this.requestLedgerEntry('account_root'); @@ -1840,7 +1811,7 @@ Remote.accountRootRequest = function(command, filter, options_, callback_) { request.emit(command, filter(message)); }); - request.callback(callback, command); + request.callback(options.callback, command); return request; }; @@ -1950,20 +1921,16 @@ Remote.prototype.findAccount = function(accountID) { */ function createPathFind(options_) { - let options; + const options = {}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - options = { - src_account: arguments[0], - dst_account: arguments[1], - dst_amount: arguments[2], - src_currencies: arguments[3] - }; + _.merge(options, makeOptions( + 'pathfind', + ['src_account', 'dst_account', 'dst_amount', 'src_currencies'], + _.slice(arguments) + )); } const pathFind = new PathFind(this, @@ -1997,19 +1964,16 @@ Remote.prepareTrade = function(currency, issuer) { */ Remote.prototype.book = Remote.prototype.createOrderBook = function(options_) { - let options; + const options = {}; if (arguments.length === 1) { - options = lodash.merge({}, options_); + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - options = { - currency_gets: arguments[0], - issuer_gets: arguments[1], - currency_pays: arguments[2], - issuer_pays: arguments[3] - }; + _.merge(options, makeOptions( + 'orderbook', + ['currency_gets', 'issuer_gets', 'currency_pays', 'issuer_pays'], + _.slice(arguments) + )); } const gets = Remote.prepareTrade(options.currency_gets, options.issuer_gets); @@ -2085,24 +2049,15 @@ Remote.prototype.setAccountSeq = function(account_, sequence) { */ Remote.prototype.accountSeqCache = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - account: args.shift(), - ledger: args.shift() - }; + _.merge(options, makeOptions( + 'accountseqcache', + ['account', 'ledger'] + )); } if (!this.accounts.hasOwnProperty(options.account)) { @@ -2131,7 +2086,7 @@ Remote.prototype.accountSeqCache = function(options_, callback_) { request = this.requestLedgerEntry('account_root'); request.accountRoot(options.account); - if (!lodash.isUndefined(options.ledger)) { + if (!_.isUndefined(options.ledger)) { request.selectLedger(options.ledger); } @@ -2141,7 +2096,7 @@ Remote.prototype.accountSeqCache = function(options_, callback_) { account_info.caching_seq_request = request; } - request.callback(callback, 'success_cache', 'error_cache'); + request.callback(options.callback, 'success_cache', 'error_cache'); return request; }; @@ -2207,33 +2162,24 @@ Remote.prototype.requestOffer = function(options, callback) { */ Remote.prototype.requestRippleBalance = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({}, options_); + if (_.isPlainObject(options_)) { + _.merge(options, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); + _.merge(options, makeOptions( + 'ripplebalance', + ['account', 'issuer', 'currency', 'ledger'], + _.slice(arguments) + )); - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - account: args.shift(), - issuer: args.shift(), - currency: args.shift(), - ledger: args.shift() - }; } // YYY Could be cached per ledger. const request = this.requestLedgerEntry('ripple_state'); request.rippleState(options.account, options.issuer, options.currency); - if (!lodash.isUndefined(options.ledger)) { + if (!_.isUndefined(options.ledger)) { request.selectLedger(options.ledger); } @@ -2279,7 +2225,7 @@ Remote.prototype.requestRippleBalance = function(options_, callback_) { } request.once('success', rippleState); - request.callback(callback, 'ripple_state'); + request.callback(options.callback, 'ripple_state'); return request; }; @@ -2309,31 +2255,23 @@ Remote.prepareCurrencies = function(currency) { */ Remote.prototype.requestRipplePathFind = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({ + if (_.isPlainObject(options_)) { + _.merge(options, { source_account: options_.src_account, destination_account: options_.dst_account, destination_amount: options_.dst_amount, source_currencies: options_.src_currencies }, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - source_account: args.shift(), - destination_account: args.shift(), - destination_amount: args.shift(), - source_currencies: args.shift() - }; + _.merge(options, makeOptions( + 'ripple_path_find', + /* eslint-disable max-len */ + ['source_account', 'destination_account', 'destination_amount', 'source_currencies'], + /* eslint-enable max-len */ + _.slice(arguments) + )); } const request = new Request(this, 'ripple_path_find'); @@ -2351,7 +2289,7 @@ Remote.prototype.requestRipplePathFind = function(options_, callback_) { options.source_currencies.map(Remote.prepareCurrency); } - request.callback(callback); + request.callback(options.callback); return request; }; @@ -2365,31 +2303,23 @@ Remote.prototype.requestRipplePathFind = function(options_, callback_) { */ Remote.prototype.requestPathFindCreate = function(options_, callback_) { - let options, callback = callback_; + const options = {callback: callback_}; - if (lodash.isPlainObject(options_)) { - options = lodash.merge({ + if (_.isPlainObject(options_)) { + _.merge(options, { source_account: options_.src_account, destination_account: options_.dst_account, destination_amount: options_.dst_amount, source_currencies: options_.src_currencies }, options_); } else { - log.warn('DEPRECATED: First argument to request constructor should be' - + ' an object containing request properties'); - - const args = Array.prototype.slice.call(arguments); - - if (lodash.isFunction(lodash.last(args))) { - callback = args.pop(); - } - - options = { - source_account: args.shift(), - destination_account: args.shift(), - destination_amount: args.shift(), - source_currencies: args.shift() - }; + _.merge(options, makeOptions( + 'path_find', + /* eslint-disable max-len */ + ['source_account', 'destination_account', 'destination_amount', 'source_currencies'], + /* eslint-enable max-len */ + _.slice(arguments) + )); } const request = new Request(this, 'path_find'); @@ -2408,7 +2338,7 @@ Remote.prototype.requestPathFindCreate = function(options_, callback_) { options.source_currencies.map(Remote.prepareCurrency); } - request.callback(callback); + request.callback(options.callback); return request; }; diff --git a/test/remote-test.js b/test/remote-test.js index 6fdcb9bb..91750f4d 100644 --- a/test/remote-test.js +++ b/test/remote-test.js @@ -1,8 +1,10 @@ -/* eslint-disable no-new */ +/* eslint-disable no-new, max-len, no-comma-dangle, indent */ 'use strict'; const assert = require('assert-diff'); +const lodash = require('lodash'); +const ripple = require('ripple-lib'); const Remote = require('ripple-lib').Remote; const Server = require('ripple-lib').Server; const Transaction = require('ripple-lib').Transaction; @@ -22,9 +24,22 @@ const PAGING_MARKER = '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73'; const TRANSACTION_HASH = '14576FFD5D59FFA73CAA90547BE4DE09926AAB59E981306C32CCE04408CBF8EA'; +const HEX_USD = ripple.Currency.json_rewrite('USD', {force_hex: true}); +const SECRET = 'shvHH5yMTrVrF9s7YHSFPCWJgmfbE'; +const TX_JSON = { + Flags: 0, + TransactionType: 'Payment', + Account: ADDRESS, + Destination: ripple.UInt160.ACCOUNT_ONE, + Amount: { + value: '1', + currency: 'USD', + issuer: ADDRESS + } +}; describe('Remote', function() { - let initialLogEngine = Log.getEngine(); + const initialLogEngine = Log.getEngine(); beforeEach(function() { options = { @@ -1054,7 +1069,7 @@ describe('Remote', function() { }); }); it('Construct ledger request -- with transactions', function() { - let request = remote.requestLedger({ + const request = remote.requestLedger({ ledger: 'validated', transactions: true }); @@ -1067,21 +1082,21 @@ describe('Remote', function() { }); it('Construct ledger_closed request', function() { - let request = remote.requestLedgerClosed(); + const request = remote.requestLedgerClosed(); assert.deepEqual(request.message, { command: 'ledger_closed', id: undefined }); }); it('Construct ledger_header request', function() { - let request = remote.requestLedgerHeader(); + const request = remote.requestLedgerHeader(); assert.deepEqual(request.message, { command: 'ledger_header', id: undefined }); }); it('Construct ledger_current request', function() { - let request = remote.requestLedgerCurrent(); + const request = remote.requestLedgerCurrent(); assert.deepEqual(request.message, { command: 'ledger_current', id: undefined @@ -1089,7 +1104,7 @@ describe('Remote', function() { }); it('Construct ledger_data request -- with ledger hash', function() { - let request = remote.requestLedgerData({ + const request = remote.requestLedgerData({ ledger: LEDGER_HASH, limit: 5 }); @@ -1104,7 +1119,7 @@ describe('Remote', function() { }); it('Construct ledger_data request -- with ledger index', function() { - let request = remote.requestLedgerData({ + const request = remote.requestLedgerData({ ledger: LEDGER_INDEX, limit: 5 }); @@ -1119,7 +1134,7 @@ describe('Remote', function() { }); it('Construct ledger_data request -- no binary', function() { - let request = remote.requestLedgerData({ + const request = remote.requestLedgerData({ ledger: LEDGER_HASH, limit: 5, binary: false @@ -1135,7 +1150,7 @@ describe('Remote', function() { }); it('Construct server_info request', function() { - let request = remote.requestServerInfo(); + const request = remote.requestServerInfo(); assert.deepEqual(request.message, { command: 'server_info', id: undefined @@ -1143,7 +1158,7 @@ describe('Remote', function() { }); it('Construct peers request', function() { - let request = remote.requestPeers(); + const request = remote.requestPeers(); assert.deepEqual(request.message, { command: 'peers', id: undefined @@ -1151,7 +1166,7 @@ describe('Remote', function() { }); it('Construct connection request', function() { - let request = remote.requestConnect('0.0.0.0', '443'); + const request = remote.requestConnect('0.0.0.0', '443'); assert.deepEqual(request.message, { command: 'connect', id: undefined, @@ -1161,7 +1176,7 @@ describe('Remote', function() { }); it('Construct unl_add request', function() { - let request = remote.requestUnlAdd('0.0.0.0'); + const request = remote.requestUnlAdd('0.0.0.0'); assert.deepEqual(request.message, { command: 'unl_add', node: '0.0.0.0', @@ -1170,7 +1185,7 @@ describe('Remote', function() { }); it('Construct unl_list request', function() { - let request = remote.requestUnlList(); + const request = remote.requestUnlList(); assert.deepEqual(request.message, { command: 'unl_list', id: undefined @@ -1178,7 +1193,7 @@ describe('Remote', function() { }); it('Construct unl_delete request', function() { - let request = remote.requestUnlDelete('0.0.0.0'); + const request = remote.requestUnlDelete('0.0.0.0'); assert.deepEqual(request.message, { command: 'unl_delete', node: '0.0.0.0', @@ -1187,7 +1202,7 @@ describe('Remote', function() { }); it('Construct subscribe request', function() { - let request = remote.requestSubscribe(['server', 'ledger']); + const request = remote.requestSubscribe(['server', 'ledger']); assert.deepEqual(request.message, { command: 'subscribe', id: undefined, @@ -1195,7 +1210,7 @@ describe('Remote', function() { }); }); it('Construct unsubscribe request', function() { - let request = remote.requestUnsubscribe(['server', 'ledger']); + const request = remote.requestUnsubscribe(['server', 'ledger']); assert.deepEqual(request.message, { command: 'unsubscribe', id: undefined, @@ -1204,292 +1219,364 @@ describe('Remote', function() { }); it('Construct ping request', function() { - let request = remote.requestPing(); + const request = remote.requestPing(); assert.deepEqual(request.message, { command: 'ping', id: undefined }); }); it('Construct ping request -- with server', function() { - let request = remote.requestPing('wss://s1.ripple.com:443'); + const request = remote.requestPing('wss://s1.ripple.com:443'); assert.strictEqual(request.server, remote._servers[0]); assert.deepEqual(request.message, { command: 'ping', id: undefined }); }); - - it('Construct account_currencies request -- with ledger index', function() { + it('Construct account_currencies request', function() { let request = remote.requestAccountCurrencies({ account: ADDRESS - }); + }, lodash.noop); + assert.strictEqual(request.message.command, 'account_currencies'); assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.requested, true); + + Log.setEngine(Log.engines.none); + request = remote.requestAccountCurrencies(ADDRESS, lodash.noop); + assert.strictEqual(request.message.command, 'account_currencies'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.requested, true); + }); + + it('Construct account_info request', function() { + let request = remote.requestAccountInfo({ + account: ADDRESS + }, lodash.noop); + + assert.strictEqual(request.message.command, 'account_info'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.requested, true); + + Log.setEngine(Log.engines.none); + request = remote.requestAccountInfo(ADDRESS, lodash.noop); + assert.strictEqual(request.message.command, 'account_info'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.requested, true); }); it('Construct account_info request -- with ledger index', function() { let request = remote.requestAccountInfo({ account: ADDRESS, ledger: 9592219 - }); + }, lodash.noop); + assert.strictEqual(request.message.command, 'account_info'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.message.ledger_index, 9592219); + assert.strictEqual(request.requested, true); + + Log.setEngine(Log.engines.none); + request = remote.requestAccountInfo(ADDRESS, 9592219, lodash.noop); + assert.strictEqual(request.requested, true); + assert.strictEqual(request.message.command, 'account_info'); assert.strictEqual(request.message.account, ADDRESS); assert.strictEqual(request.message.ledger_index, 9592219); }); + it('Construct account_info request -- with ledger hash', function() { - let request = remote.requestAccountInfo({ - account: ADDRESS, - ledger: LEDGER_HASH - }); - assert.strictEqual(request.message.command, 'account_info'); - assert.strictEqual(request.message.account, ADDRESS); - assert.strictEqual(request.message.ledger_hash, LEDGER_HASH); - }); - it('Construct account_info request -- with ledger identifier', function() { - let request = remote.requestAccountInfo({ - account: ADDRESS, - ledger: 'validated' - }); - assert.strictEqual(request.message.command, 'account_info'); - assert.strictEqual(request.message.account, ADDRESS); - assert.strictEqual(request.message.ledger_index, 'validated'); - }); + const request = remote.requestAccountInfo({ + account: ADDRESS, + ledger: LEDGER_HASH + }, lodash.noop); + assert.strictEqual(request.message.command, 'account_info'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.message.ledger_hash, LEDGER_HASH); + assert.strictEqual(request.requested, true); + }); + it('Construct account_info request -- with ledger identifier', function() { + const request = remote.requestAccountInfo({ + account: ADDRESS, + ledger: 'validated' + }, lodash.noop); + assert.strictEqual(request.message.command, 'account_info'); + assert.strictEqual(request.message.account, ADDRESS); + assert.strictEqual(request.message.ledger_index, 'validated'); + assert.strictEqual(request.requested, true); + }); - it('Construct account balance request -- with ledger index', function() { - let request = remote.requestAccountBalance({ - account: ADDRESS, - ledger: 9592219 - }); - assert.strictEqual(request.message.command, 'ledger_entry'); - assert.strictEqual(request.message.account_root, ADDRESS); - assert.strictEqual(request.message.ledger_index, 9592219); - }); - it('Construct account balance request -- with ledger hash', function() { - let request = remote.requestAccountBalance({ - account: ADDRESS, - ledger: LEDGER_HASH - }); - assert.strictEqual(request.message.command, 'ledger_entry'); - assert.strictEqual(request.message.account_root, ADDRESS); - assert.strictEqual(request.message.ledger_hash, LEDGER_HASH); - }); - it('Construct account balance request -- with ledger identifier', function() { - let request = remote.requestAccountBalance({ - account: ADDRESS, - ledger: 'validated' - }); - assert.strictEqual(request.message.command, 'ledger_entry'); - assert.strictEqual(request.message.account_root, ADDRESS); - assert.strictEqual(request.message.ledger_index, 'validated'); - }); + it('Construct account balance request -- with ledger index', function() { + const request = remote.requestAccountBalance({ + account: ADDRESS, + ledger: 9592219 + }, lodash.noop); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.message.ledger_index, 9592219); + assert.strictEqual(request.requested, true); + }); + it('Construct account balance request -- with ledger hash', function() { + const request = remote.requestAccountBalance({ + account: ADDRESS, + ledger: LEDGER_HASH + }, lodash.noop); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.message.ledger_hash, LEDGER_HASH); + assert.strictEqual(request.requested, true); + }); + it('Construct account balance request -- with ledger identifier', function() { + const request = remote.requestAccountBalance({ + account: ADDRESS, + ledger: 'validated' + }, lodash.noop); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.message.ledger_index, 'validated'); + assert.strictEqual(request.requested, true); + }); - it('Construct account flags request', function() { - let request = remote.requestAccountFlags({account: ADDRESS}); - assert.strictEqual(request.message.command, 'ledger_entry'); - assert.strictEqual(request.message.account_root, ADDRESS); - }); - it('Construct account owner count request', function() { - let request = remote.requestOwnerCount({account: ADDRESS}); - assert.strictEqual(request.message.command, 'ledger_entry'); - assert.strictEqual(request.message.account_root, ADDRESS); - }); + it('Construct account flags request', function() { + const request = remote.requestAccountFlags({account: ADDRESS}, lodash.noop); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.requested, true); + }); + it('Construct account owner count request', function() { + let request = remote.requestOwnerCount({account: ADDRESS}, lodash.noop); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.requested, true); - it('Construct account_lines request', function() { - let request = remote.requestAccountLines({account: ADDRESS}); - assert.deepEqual(request.message, { - command: 'account_lines', - id: undefined, - account: ADDRESS - }); - }); - it('Construct account_lines request -- with peer', function() { - let request = remote.requestAccountLines({ - account: ADDRESS, - peer: ADDRESS - }); - assert.deepEqual(request.message, { - command: 'account_lines', - id: undefined, - account: ADDRESS, - peer: ADDRESS - }); - }); - it('Construct account_lines request -- with limit', function() { - let request = remote.requestAccountLines({ - account: ADDRESS, - limit: 100 - }); - assert.deepEqual(request.message, { - command: 'account_lines', - id: undefined, - account: ADDRESS, - limit: 100 - }); - }); - it('Construct account_lines request -- with limit and marker', function() { - let request = remote.requestAccountLines({ - account: ADDRESS, - limit: 100, - marker: PAGING_MARKER, - ledger: 9592219 - }); - assert.deepEqual(request.message, { - command: 'account_lines', - id: undefined, - account: ADDRESS, - limit: 100, - marker: PAGING_MARKER, - ledger_index: 9592219 - }); - }); - it('Construct account_lines request -- with min limit', function() { - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: 0 - }).message.limit, 0); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: -1 - }).message.limit, 0); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: -1e9 - }).message.limit, 0); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: -1e24 - }).message.limit, 0); - }); - it('Construct account_lines request -- with max limit', function() { - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: 1e9 - }).message.limit, 1e9); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: 1e9 + 1 - }).message.limit, 1e9); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: 1e10 - }).message.limit, 1e9); - assert.strictEqual(remote.requestAccountLines({ - account: ADDRESS, limit: 1e24 - }).message.limit, 1e9); - }); + Log.setEngine(Log.engines.none); + request = remote.requestOwnerCount(ADDRESS, lodash.noop); - it('Construct account_lines request -- with marker -- missing ledger', - function() { - assert.throws(function() { - remote.requestAccountLines({account: ADDRESS, marker: PAGING_MARKER}); - }, 'A ledger_index or ledger_hash must be provided when using a marker'); + assert.strictEqual(request.message.command, 'ledger_entry'); + assert.strictEqual(request.message.account_root, ADDRESS); + assert.strictEqual(request.requested, true); + }); - assert.throws(function() { - remote.requestAccountLines({ - account: ADDRESS, - marker: PAGING_MARKER, - ledger: 'validated' - }); - }, 'A ledger_index or ledger_hash must be provided when using a marker'); + it('Construct account_lines request', function() { + const request = remote.requestAccountLines({account: ADDRESS}, lodash.noop); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS + }); + assert.strictEqual(request.requested, true); + }); + it('Construct account_lines request -- with peer', function() { + const request = remote.requestAccountLines({ + account: ADDRESS, + peer: ADDRESS + }, lodash.noop); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS, + peer: ADDRESS + }); + assert.strictEqual(request.requested, true); + }); + it('Construct account_lines request -- with limit', function() { + const request = remote.requestAccountLines({ + account: ADDRESS, + limit: 100 + }, lodash.noop); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS, + limit: 100 + }); + assert.strictEqual(request.requested, true); + }); + it('Construct account_lines request -- with limit and marker', function() { + let request = remote.requestAccountLines({ + account: ADDRESS, + limit: 100, + marker: PAGING_MARKER, + ledger: 9592219 + }, lodash.noop); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS, + limit: 100, + marker: PAGING_MARKER, + ledger_index: 9592219 + }); + assert.strictEqual(request.requested, true); - assert.throws(function() { - remote.requestAccountLines({ - account: ADDRESS, - marker: PAGING_MARKER, - ledger: NaN - }); - }, 'A ledger_index or ledger_hash must be provided when using a marker'); + Log.setEngine(Log.engines.none); + request = remote.requestAccountLines( + ADDRESS, + null, + 9592219, + 100, + PAGING_MARKER, + lodash.noop + ); - assert.throws(function() { - remote.requestAccountLines({ - account: ADDRESS, - marker: PAGING_MARKER, - ledger: LEDGER_HASH.substr(0, 63) - }); - }, 'A ledger_index or ledger_hash must be provided when using a marker'); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS, + limit: 100, + marker: PAGING_MARKER, + ledger_index: 9592219 + }); + assert.strictEqual(request.requested, true); + }); + it('Construct account_lines request -- with min limit', function() { + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: 0 + }).message.limit, 0); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: -1 + }).message.limit, 0); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: -1e9 + }).message.limit, 0); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: -1e24 + }).message.limit, 0); + }); + it('Construct account_lines request -- with max limit', function() { + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: 1e9 + }).message.limit, 1e9); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: 1e9 + 1 + }).message.limit, 1e9); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: 1e10 + }).message.limit, 1e9); + assert.strictEqual(remote.requestAccountLines({ + account: ADDRESS, limit: 1e24 + }).message.limit, 1e9); + }); - assert.throws(function() { - remote.requestAccountLines({ - account: ADDRESS, marker: PAGING_MARKER, ledger: LEDGER_HASH + 'F' - }); - }, 'A ledger_index or ledger_hash must be provided when using a marker'); - }); - it('Construct account_lines request -- with callback', function() { - let request = remote.requestAccountLines({ - account: ADDRESS - }, callback); + it('Construct account_lines request -- with marker -- missing ledger', + function() { + assert.throws(function() { + remote.requestAccountLines({account: ADDRESS, marker: PAGING_MARKER}); + }, 'A ledger_index or ledger_hash must be provided when using a marker'); - assert.deepEqual(request.message, { - command: 'account_lines', - id: undefined, - account: ADDRESS - }); - }); + assert.throws(function() { + remote.requestAccountLines({ + account: ADDRESS, + marker: PAGING_MARKER, + ledger: 'validated' + }); + }, 'A ledger_index or ledger_hash must be provided when using a marker'); - it('Construct account_tx request', function() { - let request = remote.requestAccountTransactions({ - account: UInt160.ACCOUNT_ONE, - ledger_index_min: -1, - ledger_index_max: -1, - limit: 5, - forward: true, - marker: PAGING_MARKER - }); + assert.throws(function() { + remote.requestAccountLines({ + account: ADDRESS, + marker: PAGING_MARKER, + ledger: NaN + }); + }, 'A ledger_index or ledger_hash must be provided when using a marker'); - assert.deepEqual(request.message, { - command: 'account_tx', - id: undefined, - account: UInt160.ACCOUNT_ONE, - ledger_index_min: -1, - ledger_index_max: -1, - binary: true, - forward: true, - limit: 5, - marker: PAGING_MARKER - }); + assert.throws(function() { + remote.requestAccountLines({ + account: ADDRESS, + marker: PAGING_MARKER, + ledger: LEDGER_HASH.substr(0, 63) + }); + }, 'A ledger_index or ledger_hash must be provided when using a marker'); - request = remote.requestAccountTransactions({ - account: UInt160.ACCOUNT_ONE, - min_ledger: -1, - max_ledger: -1 - }); - assert.deepEqual(request.message, { - command: 'account_tx', - id: undefined, - account: UInt160.ACCOUNT_ONE, - binary: true, - ledger_index_min: -1, - ledger_index_max: -1 - }); - }); - it('Construct account_tx request -- no binary', function() { - let request = remote.requestAccountTransactions({ - account: UInt160.ACCOUNT_ONE, - ledger_index_min: -1, - ledger_index_max: -1, - limit: 5, - forward: true, - binary: false, - marker: PAGING_MARKER - }); + assert.throws(function() { + remote.requestAccountLines({ + account: ADDRESS, marker: PAGING_MARKER, ledger: LEDGER_HASH + 'F' + }); + }, 'A ledger_index or ledger_hash must be provided when using a marker'); + }); + it('Construct account_lines request -- with callback', function() { + const request = remote.requestAccountLines({ + account: ADDRESS + }, callback); - assert.deepEqual(request.message, { - command: 'account_tx', - id: undefined, - account: UInt160.ACCOUNT_ONE, - ledger_index_min: -1, - ledger_index_max: -1, - binary: false, - forward: true, - limit: 5, - marker: PAGING_MARKER - }); - }); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: ADDRESS + }); + }); + + it('Construct account_tx request', function() { + let request = remote.requestAccountTransactions({ + account: UInt160.ACCOUNT_ONE, + ledger_index_min: -1, + ledger_index_max: -1, + limit: 5, + forward: true, + marker: PAGING_MARKER + }); + + assert.deepEqual(request.message, { + command: 'account_tx', + id: undefined, + account: UInt160.ACCOUNT_ONE, + ledger_index_min: -1, + ledger_index_max: -1, + binary: true, + forward: true, + limit: 5, + marker: PAGING_MARKER + }); + + request = remote.requestAccountTransactions({ + account: UInt160.ACCOUNT_ONE, + min_ledger: -1, + max_ledger: -1 + }); + assert.deepEqual(request.message, { + command: 'account_tx', + id: undefined, + account: UInt160.ACCOUNT_ONE, + binary: true, + ledger_index_min: -1, + ledger_index_max: -1 + }); + }); + it('Construct account_tx request -- no binary', function() { + const request = remote.requestAccountTransactions({ + account: UInt160.ACCOUNT_ONE, + ledger_index_min: -1, + ledger_index_max: -1, + limit: 5, + forward: true, + binary: false, + marker: PAGING_MARKER + }); + + assert.deepEqual(request.message, { + command: 'account_tx', + id: undefined, + account: UInt160.ACCOUNT_ONE, + ledger_index_min: -1, + ledger_index_max: -1, + binary: false, + forward: true, + limit: 5, + marker: PAGING_MARKER + }); + }); + + it('Construct account_offers request -- no binary', function() { + const request = remote.requestAccountOffers({account: ADDRESS}); + assert.deepEqual(request.message, { + command: 'account_offers', + id: undefined, + account: ADDRESS + }); + }); - it('Construct account_offers request -- no binary', function() { - let request = remote.requestAccountOffers({account: ADDRESS}); - assert.deepEqual(request.message, { - command: 'account_offers', - id: undefined, - account: ADDRESS - }); - }); it('Construct offer request -- with ledger index', function() { - let request = remote.requestOffer({ + const request = remote.requestOffer({ index: TRANSACTION_HASH, ledger: LEDGER_INDEX }); assert.strictEqual(request.message.command, 'ledger_entry'); @@ -1497,7 +1584,7 @@ describe('Remote', function() { assert.strictEqual(request.message.ledger_index, LEDGER_INDEX); }); it('Construct offer request -- with ledger index and sequence', function() { - let request = remote.requestOffer({ + const request = remote.requestOffer({ account: ADDRESS, ledger: LEDGER_INDEX, sequence: 5 }); assert.strictEqual(request.message.command, 'ledger_entry'); @@ -1506,7 +1593,7 @@ describe('Remote', function() { assert.strictEqual(request.message.ledger_index, LEDGER_INDEX); }); it('Construct offer request -- with ledger hash', function() { - let request = remote.requestOffer({ + const request = remote.requestOffer({ account: ADDRESS, ledger: LEDGER_HASH, sequence: 5 }); assert.strictEqual(request.message.command, 'ledger_entry'); @@ -1516,7 +1603,7 @@ describe('Remote', function() { }); it('Construct offer request -- with ledger identifier and sequence', function() { - let request = remote.requestOffer({ + const request = remote.requestOffer({ account: ADDRESS, ledger: 'validated', sequence: 5 }); assert.strictEqual(request.message.command, 'ledger_entry'); @@ -1526,7 +1613,7 @@ describe('Remote', function() { }); it('Construct book_offers request', function() { - let request = remote.requestBookOffers({ + const request = remote.requestBookOffers({ taker_gets: { currency: 'USD', issuer: ADDRESS @@ -1551,7 +1638,7 @@ describe('Remote', function() { }); it('Construct book_offers request -- with ledger and limit', function() { - let request = remote.requestBookOffers({ + const request = remote.requestBookOffers({ taker_gets: { currency: 'USD', issuer: ADDRESS @@ -1580,7 +1667,7 @@ describe('Remote', function() { }); it('Construct tx request', function() { - let request = remote.requestTransaction({ + const request = remote.requestTransaction({ hash: TRANSACTION_HASH }); @@ -1592,7 +1679,7 @@ describe('Remote', function() { }); }); it('Construct tx request -- no binary', function() { - let request = remote.requestTransaction({ + const request = remote.requestTransaction({ hash: TRANSACTION_HASH, binary: false }); @@ -1606,7 +1693,7 @@ describe('Remote', function() { }); it('Construct transaction_entry request', function() { - let request = remote.requestTransactionEntry({ + const request = remote.requestTransactionEntry({ hash: TRANSACTION_HASH }); @@ -1618,7 +1705,7 @@ describe('Remote', function() { }); }); it('Construct transaction_entry request -- with ledger index', function() { - let request = remote.requestTransactionEntry({ + const request = remote.requestTransactionEntry({ hash: TRANSACTION_HASH, ledger: 1 }); @@ -1631,7 +1718,7 @@ describe('Remote', function() { }); }); it('Construct transaction_entry request -- with ledger hash', function() { - let request = remote.requestTransactionEntry({ + const request = remote.requestTransactionEntry({ hash: TRANSACTION_HASH, ledger: LEDGER_HASH }); @@ -1653,7 +1740,7 @@ describe('Remote', function() { }); it('Construct tx_history request', function() { - let request = remote.requestTransactionHistory({ + const request = remote.requestTransactionHistory({ start: 1 }); @@ -1665,7 +1752,7 @@ describe('Remote', function() { }); it('Construct wallet_accounts request', function() { - let request = remote.requestWalletAccounts({ + const request = remote.requestWalletAccounts({ seed: 'shmnpxY42DaoyNbNQDoGuymNT1T9U' }); @@ -1686,7 +1773,7 @@ describe('Remote', function() { }); it('Construct sign request', function() { - let request = remote.requestSign({ + const request = remote.requestSign({ secret: 'shmnpxY42DaoyNbNQDoGuymNT1T9U', tx_json: { Flags: 0, @@ -1722,7 +1809,7 @@ describe('Remote', function() { }); it('Construct submit request', function() { - let request = remote.requestSubmit(); + const request = remote.requestSubmit(); assert.deepEqual(request.message, { command: 'submit', id: undefined @@ -1758,7 +1845,7 @@ describe('Remote', function() { it('Construct ledger_accept request', function() { remote._stand_alone = true; - let request = remote.requestLedgerAccept(); + const request = remote.requestLedgerAccept(); assert.deepEqual(request.message, { command: 'ledger_accept', @@ -1787,7 +1874,7 @@ describe('Remote', function() { }); it('Construct ripple balance request', function() { - let request = remote.requestRippleBalance({ + const request = remote.requestRippleBalance({ account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54', issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6', ledger: 1, @@ -1809,7 +1896,7 @@ describe('Remote', function() { }); it('Construct ripple_path_find request', function() { - let request = remote.requestRipplePathFind({ + const request = remote.requestRipplePathFind({ src_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54', dst_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6', dst_amount: '1/USD/rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54', @@ -1836,7 +1923,7 @@ describe('Remote', function() { }); it('Construct path_find create request', function() { - let request = remote.requestPathFindCreate({ + const request = remote.requestPathFindCreate({ src_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54', dst_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6', dst_amount: '1/USD/rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54', @@ -1864,7 +1951,7 @@ describe('Remote', function() { }); it('Construct path_find close request', function() { - let request = remote.requestPathFindClose(); + const request = remote.requestPathFindClose(); assert.deepEqual(request.message, { command: 'path_find', @@ -1873,3 +1960,499 @@ describe('Remote', function() { }); }); }); + +describe.skip('Request API consistency tests', function() { + // XXX convert all this to use fixtures + + // Method parameters may be translated into multiple request parameters; + // 'ledger' may become the request param 'ledger_index' or 'ledger_hash' + // depending on the argument type. + // + // This function maps an args array to a new array that only includes one + // form of request parameter: the first specified + // + // ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]] + // + // should become + // + // ['ledger_index', LEDGER_INDEX] + function firstReqParam(arg) { + if (lodash.isEmpty(arg)) { + return undefined; + } + return Array.isArray(arg[1]) + ? arg[1][0] + : arg; + } + assert.deepEqual( + firstReqParam(['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]]), + ['ledger_index', LEDGER_INDEX] + ); + assert.deepEqual( + firstReqParam(['account', ADDRESS]), + ['account', ADDRESS] + ); + + // ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]] + // + // should become + // + // ['ledger', LEDGER_INDEX] + function firstMethodParam(arg) { + if (lodash.isEmpty(arg)) { + return undefined; + } + return Array.isArray(arg[1]) + ? [arg[0], arg[1][0][1]] + : arg; + } + assert.deepEqual( + firstMethodParam(['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]]), + ['ledger', LEDGER_INDEX] + ); + assert.deepEqual( + firstMethodParam(['account', ADDRESS]), + ['account', ADDRESS] + ); + + // Filters default params against optional params + function filterDefault(optionalArgs, defaultArg) { + return lodash.isEmpty(defaultArg) + || lodash.isEmpty(optionalArgs) + || !lodash.unzip(optionalArgs)[0].includes(defaultArg[0]); + } + assert.strictEqual(filterDefault([ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]], + ['ledger', 'validated'] + ), false); + + assert.strictEqual(filterDefault([ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]], + ['hash', TRANSACTION_HASH] + ), false); + assert.strictEqual(filterDefault([ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]], + ['binary', false] + ), false); + assert.strictEqual(filterDefault([ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]], + ['transaction', TRANSACTION_HASH] + ), true); + assert.strictEqual(filterDefault([ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]], + ['myprop', false] + ), true); + assert.deepEqual([['transaction', TRANSACTION_HASH], ['myprop', true], ['ledger', 'validated']].filter(lodash.partial(filterDefault, [ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]])), [['transaction', TRANSACTION_HASH], ['myprop', true]]); + assert.deepEqual([['binary', false], ['ledger', [['ledger_index', LEDGER_INDEX]]]].filter(lodash.partial(filterDefault, [ + ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ['hash', [['transaction', TRANSACTION_HASH]]], + ['binary', true]])), []); + + function filterDefaultArgs(defaultArgs, optionalArgs) { + return lodash.filter(defaultArgs, lodash.partial( + filterDefault, optionalArgs)); + } + + function normalizeOptionalArgs(args) { + if (lodash.isEmpty(args)) { + return []; + } + return Array.isArray(args[1]) + ? args[1].slice() + : [args]; + } + assert.deepEqual( + normalizeOptionalArgs(['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]]), + [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]] + ); + assert.deepEqual( + normalizeOptionalArgs(['binary', true]), + [['binary', true]] + ); + assert.deepEqual( + normalizeOptionalArgs([]), + [] + ); + + function makeRequest(command, methodName, options_) { + const opts = lodash.merge({}, options_); + + return lodash.extend({ + name: opts.alias || command, + command: command, + methodName: methodName, + requiredArgs: opts.required || [], + optionalArgs: opts.optional || [], + defaultArgs: opts.default || [], + }, opts); + } + + const REQOPTION = { + ACCOUNT: ['account', ADDRESS], + LEDGER: ['ledger', [['ledger_index', LEDGER_INDEX], ['ledger_hash', LEDGER_HASH]]], + ACCOUNT_ROOT: ['account', [['account_root', ADDRESS]]], + STREAMS: ['streams', [['streams', ['server', 'ledger']]]] + }; + + const testCases = [ + makeRequest('server_info', 'requestServerInfo'), + makeRequest('ping', 'requestPing'), + + makeRequest('subscribe', 'requestSubscribe', { + optional: [ + REQOPTION.STREAMS + ], + noKeyed: true + }), + makeRequest('unsubscribe', 'requestUnsubscribe', { + optional: [ + REQOPTION.STREAMS + ], + noKeyed: true + }), + + makeRequest('account_info', 'requestAccountInfo', { + required: [ + REQOPTION.ACCOUNT, + ], + optional: [ + undefined, + REQOPTION.LEDGER + ] + }), + makeRequest('account_currencies', 'requestAccountCurrencies', { + required: [ + REQOPTION.ACCOUNT, + ], + optional: [ + ['peer', ADDRESS], + REQOPTION.LEDGER, + ['limit', 10] + ] + }), + makeRequest('account_lines', 'requestAccountLines', { + required: [ + REQOPTION.ACCOUNT, + ], + optional: [ + ['peer', ADDRESS], + REQOPTION.LEDGER, + ['limit', 10] + ] + }), + makeRequest('account_offers', 'requestAccountOffers', { + required: [ + REQOPTION.ACCOUNT, + ], + optional: [ + undefined, + REQOPTION.LEDGER, + ['limit', 10] + ] + }), + makeRequest('account_tx', 'requestAccountTransactions', { + required: [ + REQOPTION.ACCOUNT, + ], + optional: [ + undefined, + ['binary', false], + ['ledger_index_min', -1], + ['ledger_index_max', -1], + ['forward', true], + ['limit', 10], + ], + default: [ + ['binary', true] + ], + noPositional: true + }), + + makeRequest('tx', 'requestTransaction', { + required: [ + ['hash', [['transaction', TRANSACTION_HASH]]] + ], + optional: [ + ['binary', false] + ], + default: [ + ['binary', true] + ] + }), + makeRequest('transaction_entry', 'requestTransactionEntry', { + required: [ + ['hash', [['tx_hash', TRANSACTION_HASH]]] + ], + optional: [ + REQOPTION.LEDGER, + ], + default: [ + ['ledger', [['ledger_index', 'validated']]] + ] + }), + + makeRequest('tx_history', 'requestTransactionHistory', { + optional: [ + ['start', 10] + ], + noPositional: true + }), + makeRequest('book_offers', 'requestBookOffers', { + required: [ + ['gets', [['taker_gets', {currency: HEX_USD, issuer: ADDRESS}]]], + ['pays', [['taker_pays', {currency: HEX_USD, issuer: ADDRESS}]]] + ], + optional: [ + ['taker', ADDRESS], + REQOPTION.LEDGER, + ['limit', 10], + ], + default: [ + ['taker', ripple.UInt160.ACCOUNT_ONE] + ], + noPositional: true + }), + + makeRequest('ledger', 'requestLedger', { + optional: [ + REQOPTION.LEDGER, + ['full', true], + ['expand', true], + ['transactions', true], + ['accounts', true] + ], + noPositional: true + }), + makeRequest('ledger_data', 'requestLedgerData', { + optional: [ + REQOPTION.LEDGER, + ['binary', false], + ['limit', 10] + ], + default: [ + ['binary', true] + ], + noPositional: true + }), + makeRequest('ledger_entry', 'requestLedgerEntry', { + required: [ + ['type', 'account_root'] + ], + noKeyed: true + }), + makeRequest('ledger_closed', 'requestLedgerClosed'), + makeRequest('ledger_current', 'requestLedgerCurrent'), + makeRequest('ledger_header', 'requestLedgerHeader'), + + makeRequest('ledger_entry', 'requestAccountBalance', { + alias: 'account_balance', + required: [ + REQOPTION.ACCOUNT_ROOT, + ], + optional: [ + REQOPTION.LEDGER, + ] + }), + makeRequest('ledger_entry', 'requestAccountFlags', { + alias: 'account_flags', + required: [ + REQOPTION.ACCOUNT_ROOT, + ], + optional: [ + REQOPTION.LEDGER, + ], + }), + makeRequest('ledger_entry', 'requestOwnerCount', { + alias: 'owner_count', + required: [ + REQOPTION.ACCOUNT_ROOT, + ], + optional: [ + REQOPTION.LEDGER, + ], + }), + + makeRequest('sign', 'requestSign', { + required: [ + ['secret', SECRET], + ['tx_json', TX_JSON] + ] + }), + makeRequest('submit', 'requestSubmit') + ]; + + function checkRequest(request, expectedReqParams) { + assert(request.requested, 'Request unattempted, most likely callback was ignored'); + [['id', undefined], ...expectedReqParams].forEach(arg => { + assert.deepEqual( + request.message[arg[0]], arg[1], + 'Expected request param: ' + arg.join('=') + ); + }); + } + + function makeRequestTest(testCase) { + it(`Construct ${testCase.name} request`, function() { + const reqMethod = remote[testCase.methodName]; + const requiredArgs = testCase.requiredArgs; + const optionalArgs = lodash.compact(testCase.optionalArgs); + const defaultArgs = filterDefaultArgs(testCase.defaultArgs, optionalArgs); + + assert.strictEqual(typeof reqMethod, 'function'); + assert(Array.isArray(requiredArgs)); + assert(Array.isArray(optionalArgs)); + assert(Array.isArray(defaultArgs)); + + // if (!lodash.isEmpty(requiredArgs)) { + // Most request constructors do not (but should) throw for missing + // required options + // + // assert.throws(function() { + // reqMethod.call(remote, {}, lodash.noop); + // }); + // } + + if (testCase.noKeyed) { + return; + } + + const baseReqParams = [ + ['command', testCase.command] + ] + .concat(requiredArgs.map(firstReqParam)) + .concat(defaultArgs.map(firstReqParam)); + + const baseReqOptions = lodash.zipObject(requiredArgs.map(firstMethodParam)); + + // All required options set + checkRequest(reqMethod.call(remote, baseReqOptions, lodash.noop), + baseReqParams); + + const expectedReqParams = [baseReqParams] + .concat(optionalArgs.map(firstReqParam)); + + const reqOptions = lodash.merge( + baseReqOptions, + lodash.zipObject(optionalArgs.map(firstMethodParam)) + ); + + // All options set + checkRequest(reqMethod.call(remote, reqOptions, lodash.noop), + expectedReqParams); + }); + } + + function makeRequestOptionTest(testCase, optionalArgs) { + if (lodash.isEmpty(optionalArgs)) { + return; + } + if (testCase.noKeyed) { + return; + } + + normalizeOptionalArgs(optionalArgs).forEach(function(optionalArg) { + const testParam = lodash.first(optionalArg); + + it(`Construct ${testCase.name} request -- with ${testParam}`, function() { + const reqMethod = remote[testCase.methodName]; + const requiredArgs = testCase.requiredArgs; + const defaultArgs = filterDefaultArgs(testCase.defaultArgs, [optionalArgs]); + + assert.strictEqual(typeof reqMethod, 'function'); + assert(Array.isArray(requiredArgs)); + assert(Array.isArray(optionalArg)); + assert(Array.isArray(defaultArgs)); + + const expectedReqParams = [ + ['command', testCase.command], + optionalArg + ] + .concat(requiredArgs.map(firstReqParam)) + .concat(defaultArgs.map(firstReqParam)); + + const reqOptions = lodash.merge( + // Required args + lodash.zipObject(requiredArgs.map(firstMethodParam)), + // Optional arg + lodash.zipObject([optionalArgs[0]], [optionalArg[1]]) + ); + + checkRequest(reqMethod.call(remote, reqOptions, lodash.noop), + expectedReqParams); + }); + }); + } + + function makePositionalRequestOptionTest(testCase, optionalArgs, index) { + if (lodash.isEmpty(optionalArgs)) { + return; + } + if (testCase.noPositional) { + return; + } + + normalizeOptionalArgs(optionalArgs).forEach(function(optionalArg) { + const testParam = lodash.first(optionalArg); + + it(`Construct ${testCase.name} request -- with ${testParam} as postiional arg`, function() { + const reqMethod = remote[testCase.methodName]; + const requiredArgs = testCase.requiredArgs; + const defaultArgs = filterDefaultArgs(testCase.defaultArgs, [optionalArgs]); + + assert.strictEqual(typeof reqMethod, 'function'); + assert(Array.isArray(requiredArgs)); + assert(Array.isArray(optionalArg)); + assert(Array.isArray(defaultArgs)); + + const expectedReqParams = [ + ['command', testCase.command], + optionalArg + ] + .concat(requiredArgs.map(firstReqParam)) + .concat(defaultArgs.map(firstReqParam)); + + const reqArgs = [] + // Required args + .concat(lodash.last(lodash.unzip(expectedReqParams.slice(2))) || []) + // Placeholder undefined args + .concat(lodash.fill(Array(index), undefined)) + // Optional arg + .concat(lodash.last(optionalArg)) + // Callback + .concat(lodash.noop); + + // Silence positional arguments deprecation warning + Log.setEngine(Log.engines.none); + + checkRequest(reqMethod.apply(remote, reqArgs), + expectedReqParams); + }); + }); + } + + testCases.forEach(function(testCase) { + makeRequestTest(lodash.merge({}, testCase)); + + [ + makeRequestOptionTest, + /* DEPRECATED */ makePositionalRequestOptionTest + ].forEach(function(optionTest) { + lodash.each(testCase.optionalArgs.slice(), lodash.partial( + optionTest, lodash.merge({}, testCase))); + }); + }); +}); +