Files
xahau.js/test/remote-test.js
2015-07-24 15:22:21 -07:00

2480 lines
72 KiB
JavaScript

/* 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;
const UInt160 = require('ripple-lib').UInt160;
const Currency = require('ripple-lib').Currency;
const Amount = require('ripple-lib').Amount;
const PathFind = require('ripple-lib')._test.PathFind;
const Log = require('ripple-lib')._test.Log;
let options, remote, callback;
const ADDRESS = 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS';
const LEDGER_INDEX = 9592219;
const LEDGER_HASH =
'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE';
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() {
const initialLogEngine = Log.getEngine();
beforeEach(function() {
options = {
trusted: true,
servers: ['wss://s1.ripple.com:443']
};
remote = new Remote(options);
});
afterEach(function() {
Log.setEngine(initialLogEngine);
});
it('Server initialization -- url object', function() {
remote = new Remote({
servers: [{host: 's-west.ripple.com', port: 443, secure: true}]
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'wss://s-west.ripple.com:443');
});
it('Server initialization -- url object -- no secure property', function() {
remote = new Remote({
servers: [{host: 's-west.ripple.com', port: 443}]
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'wss://s-west.ripple.com:443');
});
it('Server initialization -- url object -- secure: false', function() {
remote = new Remote({
servers: [{host: 's-west.ripple.com', port: 443, secure: false}]
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'ws://s-west.ripple.com:443');
});
it('Server initialization -- url object -- string port', function() {
remote = new Remote({
servers: [{host: 's-west.ripple.com', port: '443', secure: true}]
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'wss://s-west.ripple.com:443');
});
it('Server initialization -- url object -- invalid host', function() {
assert.throws(
function() {
new Remote({
servers: [{host: '+', port: 443, secure: true}]
});
}, Error);
});
it('Server initialization -- url object -- invalid port', function() {
assert.throws(
function() {
new Remote({
servers: [{host: 's-west.ripple.com', port: null, secure: true}]
});
}, TypeError);
});
it('Server initialization -- url object -- port out of range', function() {
assert.throws(
function() {
new Remote({
servers: [{host: 's-west.ripple.com', port: 65537, secure: true}]
});
}, Error);
});
it('Server initialization -- url string', function() {
remote = new Remote({
servers: ['wss://s-west.ripple.com:443']
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'wss://s-west.ripple.com:443');
});
it('Server initialization -- url string -- ws://', function() {
remote = new Remote({
servers: ['ws://s-west.ripple.com:443']
});
assert(Array.isArray(remote._servers));
assert(remote._servers[0] instanceof Server);
assert.strictEqual(remote._servers[0]._url, 'ws://s-west.ripple.com:443');
});
it('Server initialization -- url string -- invalid host', function() {
assert.throws(
function() {
new Remote({
servers: ['ws://+:443']
});
}, Error
);
});
it('Server initialization -- url string -- invalid port', function() {
assert.throws(
function() {
new Remote({
servers: ['ws://s-west.ripple.com:null']
});
}, Error
);
});
it('Server initialization -- url string -- port out of range', function() {
assert.throws(
function() {
new Remote({
servers: ['ws://s-west.ripple.com:65537:']
});
}, Error
);
});
it('Server initialization -- set max_fee', function() {
remote = new Remote({max_fee: 10});
assert.strictEqual(remote.max_fee, 10);
remote = new Remote({max_fee: 1234567890});
assert.strictEqual(remote.max_fee, 1234567890);
});
it('Server initialization -- set max_fee -- invalid', function() {
assert.throws(function() {
new Remote({max_fee: '1234567890'});
});
});
it('Server initialization -- set trusted', function() {
remote = new Remote({trusted: true});
assert.strictEqual(remote.trusted, true);
});
it('Server initialization -- set trusted -- invalid', function() {
assert.throws(function() {
new Remote({trusted: '1234567890'});
});
});
it('Server initialization -- set trace', function() {
remote = new Remote({trace: true});
assert.strictEqual(remote.trace, true);
});
it('Server initialization -- set trace -- invalid', function() {
assert.throws(function() {
new Remote({trace: '1234567890'});
});
});
it('Server initialization -- set allow_partial_history', function() {
remote = new Remote({allow_partial_history: true});
assert.strictEqual(remote.allow_partial_history, true);
});
it('Server initialization -- set allow_partial_history -- invalid',
function() {
assert.throws(function() {
new Remote({allow_partial_history: '1234567890'});
});
});
it('Server initialization -- set max_attempts', function() {
remote = new Remote({max_attempts: 10});
assert.strictEqual(remote.max_attempts, 10);
});
it('Server initialization -- set max_attempts -- invalid', function() {
assert.throws(function() {
new Remote({max_attempts: '1234567890'});
});
});
it('Server initialization -- set fee_cushion', function() {
remote = new Remote({fee_cushion: 1.3});
assert.strictEqual(remote.fee_cushion, 1.3);
});
it('Server initialization -- set fee_cushion -- invalid', function() {
assert.throws(function() {
new Remote({fee_cushion: '1234567890'});
});
});
it('Server initialization -- set local_signing', function() {
remote = new Remote({local_signing: false});
assert.strictEqual(remote.local_signing, false);
});
it('Server initialization -- set local_signing -- invalid', function() {
assert.throws(function() {
remote = new Remote({local_signing: '1234567890'});
});
});
it('Server initialization -- set local_fee', function() {
remote = new Remote({local_fee: false});
assert.strictEqual(remote.local_fee, true);
remote = new Remote({local_signing: false, local_fee: false});
assert.strictEqual(remote.local_fee, false);
});
it('Server initialization -- set local_fee -- invalid', function() {
assert.throws(function() {
new Remote({
local_signing: false,
local_fee: '1234567890'
});
});
});
it('Server initialization -- set local_sequence', function() {
remote = new Remote({local_sequence: false});
assert.strictEqual(remote.local_sequence, true);
remote = new Remote({local_signing: false, local_sequence: false});
assert.strictEqual(remote.local_sequence, false);
});
it('Server initialization -- set local_sequence -- invalid', function() {
assert.throws(function() {
new Remote({
local_signing: false,
local_sequence: '1234567890'
});
});
});
it('Server initialization -- set canonical_signing', function() {
assert.strictEqual(new Remote({canonical_signing: false})
.canonical_signing, false);
});
it('Server initialization -- set canonical_signing -- invalid', function() {
assert.throws(function() {
new Remote({canonical_signing: '1234567890'});
});
});
it('Server initialization -- set submission_timeout', function() {
assert.strictEqual(new Remote({submission_timeout: 10})
.submission_timeout, 10);
});
it('Server initialization -- set submission_timeout -- invalid', function() {
assert.throws(function() {
new Remote({submission_timeout: '1234567890'});
});
});
it('Server initialization -- set last_ledger_offset', function() {
assert.strictEqual(new Remote({last_ledger_offset: 10})
.last_ledger_offset, 10);
});
it('Server initialization -- set last_ledger_offset -- invalid', function() {
assert.throws(function() {
new Remote({last_ledger_offset: '1234567890'});
});
});
it('Server initialization -- set servers', function() {
assert.deepEqual(new Remote({servers: []}).servers, [ ]);
});
it('Server initialization -- set servers -- invalid', function() {
assert.throws(function() {
new Remote({servers: '1234567890'});
});
});
it('Automatic transactions subscription', function(done) {
let i = 0;
remote.request = function(request) {
switch (++i) {
case 1:
assert.strictEqual(request.message.command, 'subscribe');
break;
case 2:
assert.strictEqual(request.message.command, 'unsubscribe');
done();
break;
}
assert.deepEqual(request.message.streams, ['transactions']);
};
remote.on('transaction', function() {});
remote.removeAllListeners('transaction');
});
it('Check is valid message', function() {
assert(Remote.isValidMessage({type: 'response'}));
assert(!Remote.isValidMessage({}));
assert(!Remote.isValidMessage(''));
});
it('Check is valid ledger data', function() {
assert(Remote.isValidLedgerData({
fee_base: 10,
fee_ref: 10,
ledger_hash: LEDGER_HASH,
ledger_index: 1,
ledger_time: 1,
reserve_base: 10,
reserve_inc: 10
}));
assert(!Remote.isValidLedgerData({
fee_base: 10,
fee_ref: 10,
ledger_hash: LEDGER_HASH,
ledger_index: 1,
ledger_time: 1,
reserve_base: 10,
reserve_inc: '10'
}));
assert(!Remote.isValidLedgerData({
fee_base: 10,
fee_ref: 10,
ledger_hash: LEDGER_HASH,
ledger_index: 1,
reserve_base: 10,
reserve_inc: 10
}));
});
it('Check is valid load status', function() {
assert(Remote.isValidLoadStatus({
load_base: 10,
load_factor: 10
}));
assert(!Remote.isValidLoadStatus({
load_base: 10,
load_factor: '10'
}));
assert(!Remote.isValidLoadStatus({
load_base: 10
}));
});
it('Check is validated', function() {
assert(Remote.isValidated({validated: true}));
assert(!Remote.isValidated({validated: false}));
assert(!Remote.isValidated({validated: 'true'}));
assert(!Remote.isValidated({}));
assert(!Remote.isValidated(null));
});
it('Set state', function() {
let i = 0;
remote.on('state', function(state) {
switch (++i) {
case 1:
assert.strictEqual(state, 'online');
break;
case 2:
assert.strictEqual(state, 'offline');
break;
}
assert.strictEqual(state, remote.state);
});
remote._setState('online');
remote._setState('online');
remote._setState('offline');
remote._setState('offline');
assert.strictEqual(i, 2);
});
it('Set trace', function() {
remote.setTrace(true);
assert.strictEqual(remote.trace, true);
remote.setTrace();
assert.strictEqual(remote.trace, true);
remote.setTrace(false);
assert.strictEqual(remote.trace, false);
});
it('Set server fatal', function() {
remote.setServerFatal();
assert.strictEqual(remote._server_fatal, true);
});
it('Add server', function() {
const server = remote.addServer('wss://s1.ripple.com:443');
assert(server instanceof Server);
let i = 0;
remote.once('connect', function() {
assert.strictEqual(remote._connection_count, 1);
++i;
});
remote.once('disconnect', function() {
assert.strictEqual(remote._connection_count, 0);
++i;
});
server.emit('connect');
server.emit('disconnect');
assert.strictEqual(i, 2, 'Remote did not receive all server events');
});
it('Add server -- primary server', function() {
const server = remote.addServer({
host: 's1.ripple.com',
port: 443,
secure: true,
primary: true
});
assert(server instanceof Server);
assert.strictEqual(remote._servers.length, 2);
assert.strictEqual(remote._servers[1], server);
let i = 0;
remote.once('connect', function() {
assert.strictEqual(remote._connection_count, 1);
assert.strictEqual(remote._primary_server, server);
remote.setPrimaryServer(remote._servers[0]);
assert.strictEqual(server._primary, false);
assert.strictEqual(remote._primary_server, remote._servers[0]);
++i;
});
server.emit('connect');
assert.strictEqual(i, 1, 'Remote did not receive all server events');
});
it('Connect', function() {
remote.addServer('wss://s1.ripple.com:443');
let i = 0;
remote._servers.forEach(function(s) {
s.connect = function() {
++i;
};
});
remote.connect();
assert.strictEqual(remote._should_connect, true);
assert.strictEqual(i, 2, 'Did not attempt connect to all servers');
});
it('Connect -- with callback', function(done) {
remote.addServer('wss://s1.ripple.com:443');
let i = 0;
remote._servers.forEach(function(s) {
s.connect = function() {
++i;
};
});
remote.connect(done);
assert.strictEqual(remote._should_connect, true);
assert.strictEqual(i, 2, 'Did not attempt connect to all servers');
remote._servers[0].emit('connect');
});
it('Connect -- no servers', function() {
remote._servers = [];
assert.throws(function() {
remote.connect();
});
});
it('Disconnect', function() {
remote.addServer('wss://s1.ripple.com:443');
let i = 0;
remote._servers.forEach(function(s) {
s.disconnect = function() {
++i;
};
s.emit('connect');
});
remote.disconnect();
assert.strictEqual(remote._should_connect, false);
assert.strictEqual(i, 2, 'Did not attempt disconnect to all servers');
});
it('Disconnect -- with callback', function(done) {
remote.addServer('wss://s1.ripple.com:443');
let i = 0;
remote._servers.forEach(function(s) {
s.disconnect = function() {
++i;
};
s.emit('connect');
});
remote.disconnect(done);
assert.strictEqual(remote._should_connect, false);
assert.strictEqual(i, 2, 'Did not attempt disconnect to all servers');
remote._servers.forEach(function(s) {
s.emit('disconnect');
});
});
it('Disconnect -- unconnected', function(done) {
remote.addServer('wss://s1.ripple.com:443');
let i = 0;
remote._servers.forEach(function(s) {
s.disconnect = function() {
++i;
};
});
remote.disconnect(done);
assert.strictEqual(i, 0, 'Should not attempt disconnect');
});
it('Disconnect -- no servers', function() {
remote._servers = [];
assert.throws(function() {
remote.disconnect();
});
});
it('Handle server message -- ledger', function() {
const message = {
type: 'ledgerClosed',
fee_base: 10,
fee_ref: 10,
ledger_hash:
'F824560DD788E5E4B65F5843A6616872873EAB74AA759C73A992355FFDFC4237',
ledger_index: 11368614,
ledger_time: 475696280,
reserve_base: 20000000,
reserve_inc: 5000000,
txn_count: 9,
validated_ledgers: '32570-11368614'
};
remote.once('ledger_closed', function(l) {
assert.deepEqual(l, message);
assert.strictEqual(remote.getLedgerHash(), message.ledger_hash);
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
});
it('Handle server message -- ledger', function(done) {
const message = {
type: 'ledgerClosed',
fee_base: 10,
fee_ref: 10,
ledger_hash:
'F824560DD788E5E4B65F5843A6616872873EAB74AA759C73A992355FFDFC4237',
ledger_index: 11368614,
ledger_time: 475696280,
reserve_base: 20000000,
reserve_inc: 5000000,
txn_count: 9,
validated_ledgers: '32570-11368614'
};
remote.once('ledger_closed', function(l) {
assert.deepEqual(l, message);
done();
});
remote._servers[0].emit('message', message);
setImmediate(function() {
remote._servers[0].emit('connect');
});
});
it('Handle server message -- server status', function() {
const message = {
type: 'serverStatus',
load_base: 256,
load_factor: 256,
server_status: 'full'
};
remote.once('server_status', function(l) {
assert.deepEqual(l, message);
});
remote._servers[0].emit('message', message);
remote._servers[0].emit('connect');
});
it('Handle server message -- validation received', function() {
const message = {
type: 'validationReceived',
ledger_hash:
'96D9E225F10C22D5047B87597939F94024F4180609227D1EB7E9D1CE9A428620',
validation_public_key:
'n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C',
signature:
'304402207E221CF0679B1A52BC07C4B97C56B93392F8BB53DFB52B821828118A740' +
'9F3E302202669AD632D9CD288B20A0A98DBC50DD3961EC50B95B138A9DCBDC11506' +
'F63646'
};
remote.once('validation_received', function(l) {
assert.deepEqual(l, message);
});
remote._servers[0].emit('message', message);
remote._servers[0].emit('connect');
});
it('Handle server message -- transaction', function() {
const message = require('./fixtures/transaction');
remote.once('transaction', function(l) {
assert.deepEqual(l, message);
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
});
it('Handle server message -- transaction -- duplicate hashes', function() {
const message = require('./fixtures/transaction');
let i = 0;
remote.once('transaction', function(l) {
assert.deepEqual(l, message);
++i;
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
remote._servers[0].emit('message', message);
remote._servers[0].emit('message', message);
assert.strictEqual(i, 1);
});
it('Handle server message -- '
+ 'transaction -- with account notification', function() {
const message = require('./fixtures/transaction');
let i = 0;
const account = remote.addAccount(message.transaction.Account);
account.once('transaction', function(t) {
assert.deepEqual(t, message);
++i;
});
remote.once('transaction', function(l) {
assert.deepEqual(l, message);
++i;
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
assert.strictEqual(i, 2);
});
it('Handle server message -- '
+ 'transaction proposed -- with account notification', function() {
const message = require('./fixtures/transaction-proposed');
let i = 0;
const account = remote.addAccount(message.transaction.Account);
account.once('transaction', function(t) {
assert.deepEqual(t, message);
++i;
});
remote.once('transaction', function(l) {
assert.deepEqual(l, message);
++i;
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
assert.strictEqual(i, 2);
});
it('Handle server message -- transaction -- with orderbook notification',
function() {
const message = require('./fixtures/transaction-offercreate');
let i = 0;
const orderbook = remote.createOrderBook({
currency_gets: 'USD',
issuer_gets: 'rJy64aCJLP3vf8o3WPKn4iQKtfpjh6voAR',
currency_pays: 'XRP'
});
orderbook._subscribed = true;
orderbook._synced = true;
orderbook.once('transaction', function(t) {
assert.deepEqual(t.transaction, message.transaction);
assert.deepEqual(t.meta, message.meta);
++i;
});
remote.once('transaction', function(l) {
assert.deepEqual(l, message);
++i;
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
assert.strictEqual(i, 2);
});
it('Handle server message -- path find', function() {
const message = require('./fixtures/pathfind');
let i = 0;
const amount = Amount.from_json({
currency: 'USD',
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
value: '0.001'
});
const path = new PathFind(remote,
'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59',
'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59',
amount
);
path.once('update', function(p) {
assert.deepEqual(p, message);
++i;
});
remote.once('path_find_all', function(p) {
assert.deepEqual(p, message);
++i;
});
remote._cur_path_find = path;
remote._servers[0].emit('connect');
remote._servers[0].emit('message', message);
assert.strictEqual(i, 2);
});
it('Handle server message -- invalid message', function() {
// Silence error log
Log.setEngine(Log.engines.none);
require('./fixtures/pathfind');
let i = 0;
remote.on('error', function(e) {
assert(/^Unexpected response from remote/.test(e.message));
++i;
});
remote._servers[0].emit('message', '1');
remote._servers[0].emit('message', {});
remote._servers[0].emit('message', {type: 'response'});
remote._servers[0].emit('message', JSON.stringify({type: 'response'}));
assert.strictEqual(i, 3, 'Failed to receive all invalid message errors');
});
it('Get server', function() {
remote.addServer('wss://sasdf.ripple.com:443');
remote.connect();
remote._connected = true;
remote._servers.forEach(function(s) {
s._connected = true;
});
const message = {
type: 'ledgerClosed',
fee_base: 10,
fee_ref: 10,
ledger_hash:
'F824560DD788E5E4B65F5843A6616872873EAB74AA759C73A992355FFDFC4237',
ledger_index: 1,
ledger_time: 475696280,
reserve_base: 20000000,
reserve_inc: 5000000,
txn_count: 9,
validated_ledgers: '32570-11368614'
};
remote._servers[0].emit('message', message);
assert.strictEqual(remote.getServer(), remote._servers[0]);
message.ledger_index += 1;
remote._servers[1].emit('message', message);
assert.strictEqual(remote.getServer(), remote._servers[1]);
});
it('Get server -- no servers', function() {
assert.strictEqual(new Remote().getServer(), null);
});
it('Get server -- no connected servers', function() {
remote.addServer('wss://sasdf.ripple.com:443');
assert.strictEqual(remote._servers.length, 2);
assert.strictEqual(remote.getServer(), null);
});
it('Get server -- primary server', function() {
const server = remote.addServer({
host: 'sasdf.ripple.com',
port: 443,
secure: true,
primary: true
});
remote.connect();
server._connected = true;
assert.strictEqual(remote.getServer().getServerID(), server.getServerID());
});
it('Parse binary transaction', function() {
const binaryTransaction = require('./fixtures/binary-transaction.json');
const parsedSourceTag = Remote.parseBinaryTransaction(
binaryTransaction.PaymentWithSourceTag.binary);
assert.deepEqual(parsedSourceTag,
binaryTransaction.PaymentWithSourceTag.parsed);
const parsedMemosAndPaths = Remote.parseBinaryTransaction(
binaryTransaction.PaymentWithMemosAndPaths.binary);
assert.deepEqual(parsedMemosAndPaths,
binaryTransaction.PaymentWithMemosAndPaths.parsed);
const parsedPartialPayment = Remote.parseBinaryTransaction(
binaryTransaction.PartialPayment.binary);
assert.deepEqual(parsedPartialPayment,
binaryTransaction.PartialPayment.parsed);
const parsedOfferCreate = Remote.parseBinaryTransaction(
binaryTransaction.OfferCreate.binary);
assert.deepEqual(parsedOfferCreate, binaryTransaction.OfferCreate.parsed);
const parsedPartialPaymentWithXRPDelieveredAmount =
Remote.parseBinaryTransaction(
binaryTransaction.PartialPaymentWithXRPDeliveredAmount.binary);
assert.deepEqual(parsedPartialPaymentWithXRPDelieveredAmount,
binaryTransaction
.PartialPaymentWithXRPDeliveredAmount
.parsed);
});
it('Parse binary account transaction', function() {
const binaryAccountTransaction =
require('./fixtures/binary-account-transaction.json');
const parsed = Remote.parseBinaryAccountTransaction(
binaryAccountTransaction.OfferCreate.binary);
assert.deepEqual(parsed, binaryAccountTransaction.OfferCreate.parsed);
const parsedPartialPayment = Remote.parseBinaryAccountTransaction(
binaryAccountTransaction.PartialPayment.binary);
assert.deepEqual(parsedPartialPayment,
binaryAccountTransaction.PartialPayment.parsed);
const parsedPayment = Remote.parseBinaryAccountTransaction(
binaryAccountTransaction.Payment.binary);
assert.deepEqual(parsedPayment, binaryAccountTransaction.Payment.parsed);
});
it('Parse binary ledger', function() {
const binaryLedgerData = require('./fixtures/binary-ledger-data.json');
const parsedAccountRoot =
Remote.parseBinaryLedgerData(binaryLedgerData.AccountRoot.binary);
assert.deepEqual(parsedAccountRoot, binaryLedgerData.AccountRoot.parsed);
const parsedOffer =
Remote.parseBinaryLedgerData(binaryLedgerData.Offer.binary);
assert.deepEqual(parsedOffer, binaryLedgerData.Offer.parsed);
const parsedDirectoryNode =
Remote.parseBinaryLedgerData(binaryLedgerData.DirectoryNode.binary);
assert.deepEqual(parsedDirectoryNode,
binaryLedgerData.DirectoryNode.parsed);
const parsedRippleState =
Remote.parseBinaryLedgerData(binaryLedgerData.RippleState.binary);
assert.deepEqual(parsedRippleState, binaryLedgerData.RippleState.parsed);
});
it('Prepare currency', function() {
assert.deepEqual(Remote.prepareCurrencies({
issuer: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
currency: 'USD',
value: 1
}), {
issuer: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
currency: '0000000000000000000000005553440000000000'
});
});
it('Get transaction fee', function() {
remote._connected = true;
remote._servers[0]._connected = true;
assert.strictEqual(remote.feeTx(10).to_json(), '12');
remote._servers = [];
assert.throws(function() {
remote.feeTx(10).to_json();
});
});
it('Get transaction fee units', function() {
remote._connected = true;
remote._servers[0]._connected = true;
assert.strictEqual(remote.feeTxUnit(), 1.2);
remote._servers = [];
assert.throws(function() {
remote.feeTxUnit(10).to_json();
});
});
it('Get reserve', function() {
remote._connected = true;
remote._servers[0]._connected = true;
assert.strictEqual(remote.reserve(1).to_json(), 'NaN');
remote._servers = [];
assert.throws(function() {
remote.reserve(10).to_json();
});
});
it('Initiate request', function() {
const request = remote.requestServerInfo();
assert.deepEqual(request.message, {
command: 'server_info',
id: undefined
});
let i = 0;
remote._connected = true;
remote._servers[0]._connected = true;
remote._servers[0]._request = function() {
++i;
};
remote.request(request);
assert.strictEqual(i, 1, 'Did not initiate request');
});
it('Initiate request -- with request name', function() {
const request = remote.request('server_info');
assert.deepEqual(request.message, {
command: 'server_info',
id: undefined
});
let i = 0;
remote._connected = true;
remote._servers[0]._connected = true;
remote._servers[0]._request = function() {
++i;
};
remote.request(request);
assert.strictEqual(i, 1, 'Did not initiate request');
});
it('Initiate request -- with invalid request name', function() {
assert.throws(function() {
remote.request('server_infoz');
});
});
it('Initiate request -- with invalid request', function() {
assert.throws(function() {
remote.request({});
});
assert.throws(function() {
remote.request({command: 'server_info', id: 1});
});
});
it('Initiate request -- set non-existent servers', function() {
const request = remote.requestServerInfo();
request.setServer('wss://s-east.ripple.com:443');
assert.strictEqual(request.server, null);
assert.throws(function() {
remote._connected = true;
remote.request(request);
});
});
it('Construct ledger request', function() {
const request = remote.requestLedger();
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined
});
});
it('Construct ledger request -- with ledger index', function() {
let request = remote.requestLedger({ledger: 1});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 1
});
request = remote.requestLedger({ledger_index: 1});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 1
});
request = remote.requestLedger(1);
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 1
});
request = remote.requestLedger(null);
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined
});
});
it('Construct ledger request -- with ledger hash', function() {
let request = remote.requestLedger({ledger: LEDGER_HASH});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_hash: LEDGER_HASH
});
request = remote.requestLedger({ledger_hash: LEDGER_HASH});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_hash: LEDGER_HASH
});
request = remote.requestLedger(LEDGER_HASH);
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_hash: LEDGER_HASH
});
});
it('Construct ledger request -- with ledger identifier', function() {
let request = remote.requestLedger({ledger: 'validated'});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 'validated'
});
request = remote.requestLedger({ledger: 'current'});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 'current'
});
request = remote.requestLedger('validated');
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 'validated'
});
request = remote.requestLedger({validated: true});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 'validated'
});
});
it('Construct ledger request -- with transactions', function() {
const request = remote.requestLedger({
ledger: 'validated',
transactions: true
});
assert.deepEqual(request.message, {
command: 'ledger',
id: undefined,
ledger_index: 'validated',
transactions: true
});
});
it('Construct ledger_closed request', function() {
const request = remote.requestLedgerClosed();
assert.deepEqual(request.message, {
command: 'ledger_closed',
id: undefined
});
});
it('Construct ledger_header request', function() {
const request = remote.requestLedgerHeader();
assert.deepEqual(request.message, {
command: 'ledger_header',
id: undefined
});
});
it('Construct ledger_current request', function() {
const request = remote.requestLedgerCurrent();
assert.deepEqual(request.message, {
command: 'ledger_current',
id: undefined
});
});
it('Construct ledger_data request -- with ledger hash', function() {
const request = remote.requestLedgerData({
ledger: LEDGER_HASH,
limit: 5
});
assert.deepEqual(request.message, {
command: 'ledger_data',
id: undefined,
binary: true,
ledger_hash: LEDGER_HASH,
limit: 5
});
});
it('Construct ledger_data request -- with ledger index', function() {
const request = remote.requestLedgerData({
ledger: LEDGER_INDEX,
limit: 5
});
assert.deepEqual(request.message, {
command: 'ledger_data',
id: undefined,
binary: true,
ledger_index: LEDGER_INDEX,
limit: 5
});
});
it('Construct ledger_data request -- no binary', function() {
const request = remote.requestLedgerData({
ledger: LEDGER_HASH,
limit: 5,
binary: false
});
assert.deepEqual(request.message, {
command: 'ledger_data',
id: undefined,
binary: false,
ledger_hash: LEDGER_HASH,
limit: 5
});
});
it('Construct server_info request', function() {
const request = remote.requestServerInfo();
assert.deepEqual(request.message, {
command: 'server_info',
id: undefined
});
});
it('Construct peers request', function() {
const request = remote.requestPeers();
assert.deepEqual(request.message, {
command: 'peers',
id: undefined
});
});
it('Construct connection request', function() {
const request = remote.requestConnect('0.0.0.0', '443');
assert.deepEqual(request.message, {
command: 'connect',
id: undefined,
ip: '0.0.0.0',
port: '443'
});
});
it('Construct unl_add request', function() {
const request = remote.requestUnlAdd('0.0.0.0');
assert.deepEqual(request.message, {
command: 'unl_add',
node: '0.0.0.0',
id: undefined
});
});
it('Construct unl_list request', function() {
const request = remote.requestUnlList();
assert.deepEqual(request.message, {
command: 'unl_list',
id: undefined
});
});
it('Construct unl_delete request', function() {
const request = remote.requestUnlDelete('0.0.0.0');
assert.deepEqual(request.message, {
command: 'unl_delete',
node: '0.0.0.0',
id: undefined
});
});
it('Construct subscribe request', function() {
const request = remote.requestSubscribe(['server', 'ledger']);
assert.deepEqual(request.message, {
command: 'subscribe',
id: undefined,
streams: ['server', 'ledger']
});
});
it('Construct unsubscribe request', function() {
const request = remote.requestUnsubscribe(['server', 'ledger']);
assert.deepEqual(request.message, {
command: 'unsubscribe',
id: undefined,
streams: ['server', 'ledger']
});
});
it('Construct ping request', function() {
const request = remote.requestPing();
assert.deepEqual(request.message, {
command: 'ping',
id: undefined
});
});
it('Construct ping request -- with server', function() {
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', 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() {
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() {
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() {
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);
Log.setEngine(Log.engines.none);
request = remote.requestOwnerCount(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() {
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);
Log.setEngine(Log.engines.none);
request = remote.requestAccountLines(
ADDRESS,
null,
9592219,
100,
PAGING_MARKER,
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);
});
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);
});
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.throws(function() {
remote.requestAccountLines({
account: ADDRESS,
marker: PAGING_MARKER,
ledger: 'validated'
});
}, 'A ledger_index or ledger_hash must be provided when using a 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.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.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_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 offer request -- with ledger index', function() {
const request = remote.requestOffer({
index: TRANSACTION_HASH, ledger: LEDGER_INDEX
});
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.offer, TRANSACTION_HASH);
assert.strictEqual(request.message.ledger_index, LEDGER_INDEX);
});
it('Construct offer request -- with ledger index and sequence', function() {
const request = remote.requestOffer({
account: ADDRESS, ledger: LEDGER_INDEX, sequence: 5
});
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.offer.account, ADDRESS);
assert.strictEqual(request.message.offer.seq, 5);
assert.strictEqual(request.message.ledger_index, LEDGER_INDEX);
});
it('Construct offer request -- with ledger hash', function() {
const request = remote.requestOffer({
account: ADDRESS, ledger: LEDGER_HASH, sequence: 5
});
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.offer.account, ADDRESS);
assert.strictEqual(request.message.offer.seq, 5);
assert.strictEqual(request.message.ledger_hash, LEDGER_HASH);
});
it('Construct offer request -- with ledger identifier and sequence',
function() {
const request = remote.requestOffer({
account: ADDRESS, ledger: 'validated', sequence: 5
});
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.offer.account, ADDRESS);
assert.strictEqual(request.message.offer.seq, 5);
assert.strictEqual(request.message.ledger_index, 'validated');
});
it('Construct book_offers request', function() {
const request = remote.requestBookOffers({
taker_gets: {
currency: 'USD',
issuer: ADDRESS
},
taker_pays: {
currency: 'XRP'
}
});
assert.deepEqual(request.message, {
command: 'book_offers',
id: undefined,
taker_gets: {
currency: Currency.from_human('USD').to_hex(),
issuer: ADDRESS
},
taker_pays: {
currency: Currency.from_human('XRP').to_hex()
},
taker: UInt160.ACCOUNT_ONE
});
});
it('Construct book_offers request -- with ledger and limit', function() {
const request = remote.requestBookOffers({
taker_gets: {
currency: 'USD',
issuer: ADDRESS
},
taker_pays: {
currency: 'XRP'
},
ledger: LEDGER_HASH,
limit: 10
});
assert.deepEqual(request.message, {
command: 'book_offers',
id: undefined,
taker_gets: {
currency: Currency.from_human('USD').to_hex(),
issuer: ADDRESS
},
taker_pays: {
currency: Currency.from_human('XRP').to_hex()
},
taker: UInt160.ACCOUNT_ONE,
ledger_hash: LEDGER_HASH,
limit: 10
});
});
it('Construct tx request', function() {
const request = remote.requestTransaction({
hash: TRANSACTION_HASH
});
assert.deepEqual(request.message, {
command: 'tx',
id: undefined,
binary: true,
transaction: TRANSACTION_HASH
});
});
it('Construct tx request -- no binary', function() {
const request = remote.requestTransaction({
hash: TRANSACTION_HASH,
binary: false
});
assert.deepEqual(request.message, {
command: 'tx',
id: undefined,
binary: false,
transaction: TRANSACTION_HASH
});
});
it('Construct transaction_entry request', function() {
const request = remote.requestTransactionEntry({
hash: TRANSACTION_HASH
});
assert.deepEqual(request.message, {
command: 'transaction_entry',
id: undefined,
tx_hash: TRANSACTION_HASH,
ledger_index: 'validated'
});
});
it('Construct transaction_entry request -- with ledger index', function() {
const request = remote.requestTransactionEntry({
hash: TRANSACTION_HASH,
ledger: 1
});
assert.deepEqual(request.message, {
command: 'transaction_entry',
id: undefined,
tx_hash: TRANSACTION_HASH,
ledger_index: 1
});
});
it('Construct transaction_entry request -- with ledger hash', function() {
const request = remote.requestTransactionEntry({
hash: TRANSACTION_HASH,
ledger: LEDGER_HASH
});
assert.deepEqual(request.message, {
command: 'transaction_entry',
id: undefined,
tx_hash: TRANSACTION_HASH,
ledger_hash: LEDGER_HASH
});
});
it('Construct transaction_entry request -- with invalid ledger', function() {
assert.throws(function() {
remote.requestTransactionEntry({
hash: TRANSACTION_HASH,
ledger: {}
});
});
});
it('Construct tx_history request', function() {
const request = remote.requestTransactionHistory({
start: 1
});
assert.deepEqual(request.message, {
command: 'tx_history',
id: undefined,
start: 1
});
});
it('Construct wallet_accounts request', function() {
const request = remote.requestWalletAccounts({
seed: 'shmnpxY42DaoyNbNQDoGuymNT1T9U'
});
assert.deepEqual(request.message, {
command: 'wallet_accounts',
id: undefined,
seed: 'shmnpxY42DaoyNbNQDoGuymNT1T9U'
});
});
it('Construct wallet_accounts request -- untrusted', function() {
remote.trusted = false;
assert.throws(function() {
remote.requestWalletAccounts({
seed: 'shmnpxY42DaoyNbNQDoGuymNT1T9U'
});
});
});
it('Construct sign request', function() {
const request = remote.requestSign({
secret: 'shmnpxY42DaoyNbNQDoGuymNT1T9U',
tx_json: {
Flags: 0,
TransactionType: 'AccountSet',
Account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8'
}
});
assert.deepEqual(request.message, {
command: 'sign',
id: undefined,
secret: 'shmnpxY42DaoyNbNQDoGuymNT1T9U',
tx_json: {
Flags: 0,
TransactionType: 'AccountSet',
Account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8'
}
});
});
it('Construct sign request -- untrusted', function() {
remote.trusted = false;
assert.throws(function() {
remote.requestSign({
secret: 'shmnpxY42DaoyNbNQDoGuymNT1T9U',
tx_json: {
Flags: 0,
TransactionType: 'AccountSet',
Account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8'
}
});
});
});
it('Construct submit request', function() {
const request = remote.requestSubmit();
assert.deepEqual(request.message, {
command: 'submit',
id: undefined
});
});
it('Construct transaction', function() {
let tx = remote.createTransaction('AccountSet', {
account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8',
flags: 0
});
assert(tx instanceof Transaction);
assert.deepEqual(tx.tx_json, {
Flags: 0,
TransactionType: 'AccountSet',
Account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8'
});
tx = remote.createTransaction();
assert(tx instanceof Transaction);
assert.deepEqual(tx.tx_json, {
Flags: 0
});
});
it('Construct transaction -- invalid type', function() {
assert.throws(function() {
remote.createTransaction('AccountSetz', {
account: 'rwLZs9MUVv28XZdYXDk9uNRUpAh1c6jij8',
flags: 0
});
});
});
it('Construct ledger_accept request', function() {
remote._stand_alone = true;
const request = remote.requestLedgerAccept();
assert.deepEqual(request.message, {
command: 'ledger_accept',
id: undefined
});
remote._servers[0].emit('connect');
remote._servers[0].emit('message', {
type: 'ledgerClosed',
fee_base: 10,
fee_ref: 10,
ledger_hash:
'F824560DD788E5E4B65F5843A6616872873EAB74AA759C73A992355FFDFC4237',
ledger_index: 11368614,
ledger_time: 475696280,
reserve_base: 20000000,
reserve_inc: 5000000,
txn_count: 9,
validated_ledgers: '32570-11368614'
});
});
it('Construct ledger_accept request -- not standalone', function() {
assert.throws(function() {
remote.requestLedgerAccept();
});
});
it('Construct ripple balance request', function() {
const request = remote.requestRippleBalance({
account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
ledger: 1,
currency: 'USD'
});
assert.deepEqual(request.message, {
command: 'ledger_entry',
id: undefined,
ripple_state: {
currency: 'USD',
accounts: [
'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6'
]
},
ledger_index: 1
});
});
it('Construct ripple_path_find request', function() {
const request = remote.requestRipplePathFind({
src_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
dst_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
dst_amount: '1/USD/rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
src_currencies: [{
currency: 'BTC', issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6'
}]
});
assert.deepEqual(request.message, {
command: 'ripple_path_find',
id: undefined,
source_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
destination_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
destination_amount: {
value: '1',
currency: 'USD',
issuer: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54'
},
source_currencies: [{
issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
currency: '0000000000000000000000004254430000000000'
}]
});
});
it('Construct path_find create request', function() {
const request = remote.requestPathFindCreate({
src_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
dst_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
dst_amount: '1/USD/rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
src_currencies: [{
currency: 'BTC', issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6'
}]
});
assert.deepEqual(request.message, {
command: 'path_find',
id: undefined,
subcommand: 'create',
source_account: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54',
destination_account: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
destination_amount: {
value: '1',
currency: 'USD',
issuer: 'rGr9PjmVe7MqEXTSbd3njhgJc2s5vpHV54'
},
source_currencies: [{
issuer: 'rwxBjBC9fPzyQ9GgPZw6YYLNeRTSx5c2W6',
currency: '0000000000000000000000004254430000000000'
}]
});
});
it('Construct path_find close request', function() {
const request = remote.requestPathFindClose();
assert.deepEqual(request.message, {
command: 'path_find',
id: undefined,
subcommand: 'close'
});
});
});
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)));
});
});
});