From c4920f474d0eb7bf88f30db6922641a8bb1deced Mon Sep 17 00:00:00 2001 From: Matthew Fettig Date: Tue, 6 Oct 2015 15:56:10 -0700 Subject: [PATCH] fix orderbook subscription bug --- src/orderbook.js | 10 ++- test/orderbook-test.js | 167 ++++++++++++++++++++++++++++++++++------- 2 files changed, 147 insertions(+), 30 deletions(-) diff --git a/src/orderbook.js b/src/orderbook.js index cfa966ee..e7a45824 100644 --- a/src/orderbook.js +++ b/src/orderbook.js @@ -22,6 +22,7 @@ const Currency = require('./currency').Currency; const AutobridgeCalculator = require('./autobridgecalculator'); const OrderBookUtils = require('./orderbookutils'); const log = require('./log').internal.sub('orderbook'); +const RippleError = require('./rippleerror').RippleError; /** * @constructor OrderBook @@ -326,15 +327,16 @@ OrderBook.prototype.requestOffers = function(callback = function() {}, internal = false) { const self = this; - if (!this._remote.isConnected()) { + if (!this._remote.isConnected() && !internal) { // do not make request if not online. // that requests will be queued and // eventually all of them will fire back + callback(new RippleError('remote is offline')); return undefined; } if (!this._shouldSubscribe) { - callback(new Error('Should not request offers')); + callback(new RippleError('Should not request offers')); return undefined; } @@ -362,7 +364,7 @@ OrderBook.prototype.requestOffers = function(callback = function() {}, if (!Array.isArray(res.offers)) { // XXX What now? - callback(new Error('Invalid response')); + callback(new RippleError('Invalid response')); self.emit('model', []); return; } @@ -1351,7 +1353,7 @@ OrderBook.prototype.computeAutobridgedOffers = function(callback = function() {} assert(!this._currencyGets.is_native() && !this._currencyPays.is_native(), 'Autobridging is only for IOU:IOU orderbooks'); - + if (this._destroyed) { return; } diff --git a/test/orderbook-test.js b/test/orderbook-test.js index 5a375fa8..5e9500e1 100644 --- a/test/orderbook-test.js +++ b/test/orderbook-test.js @@ -67,40 +67,155 @@ describe('OrderBook', function() { assert(book.isValid()); }); - it('Automatic subscription (based on listeners)', function(done) { - const book = createRemote().createOrderBook({ - currency_gets: 'XRP', - issuer_pays: addresses.ISSUER, - currency_pays: 'BTC' - }); - - book.subscribe = function() { - done(); - }; - - book.on('model', function() {}); - }); - it('Subscribe', function(done) { - const book = createRemote().createOrderBook({ - currency_gets: 'XRP', - issuer_pays: addresses.ISSUER, - currency_pays: 'BTC' + const remote = createRemote(); + const book = remote.createOrderBook({ + currency_pays: 'XRP', + issuer_gets: addresses.ISSUER, + currency_gets: 'BTC' }); - let requestedOffers = false; + remote.request = function(request) { + const response = {}; - book.subscribeTransactions = function() { - assert(requestedOffers); - done(); - }; + if (request.message.command === 'account_info') { + response.account_data = { + TransferRate: 1002000000 + }; - book.requestOffers = function(callback) { - requestedOffers = true; - callback(); + } else if (request.message.command === 'book_offers') { + response.offers = []; + } + + request.emit('success', response); }; book.subscribe(); + assert.strictEqual(book._subscribed, true); + done(); + }); + + it('Subscribe - gets XRP', function(done) { + const remote = createRemote(); + const book = remote.createOrderBook({ + currency_gets: 'XRP', + issuer_pays: addresses.ISSUER, + currency_pays: 'BTC' + }); + + remote.isConnected = function() { + return false; + }; + + remote.request = function(request) { + const response = {}; + if (request.message.command === 'book_offers') { + response.offers = []; + } + + request.emit('success', response); + }; + + book.subscribe(); + assert.strictEqual(book._subscribed, true, '_subscribed'); + done(); + }); + + it('Subscribe - autobridged', function(done) { + + const remote = createRemote(); + const book = remote.createOrderBook({ + currency_pays: 'USD', + issuer_pays: addresses.ISSUER, + currency_gets: 'BTC', + issuer_gets: addresses.ISSUER + }); + + remote.request = function(request) { + const response = {}; + + if (request.message.command === 'account_info') { + response.account_data = { + TransferRate: 1002000000 + }; + + } else if (request.message.command === 'book_offers') { + response.offers = []; + } + + request.emit('success', response); + }; + + book.subscribe(); + assert.strictEqual(book._subscribed, true, '_subscribed'); + done(); + }); + + it('Automatic subscription (based on listeners)', function(done) { + this.timeout(100); + + const remote = createRemote(); + const book = remote.createOrderBook({ + currency_gets: 'XRP', + issuer_pays: addresses.ISSUER, + currency_pays: 'BTC' + }); + + remote.request = function(request) { + const response = {}; + + if (request.message.command === 'account_info') { + response.account_data = { + TransferRate: 1002000000 + }; + + } else if (request.message.command === 'book_offers') { + response.offers = []; + } + + setImmediate(function() { + request.emit('success', response); + }); + }; + + book.on('model', function(offers) { + assert.strictEqual(offers.length, 0); + done(); + }); + }); + + it('Automatic subscription (based on listeners) - autobridged', function(done) { + this.timeout(100); + + const remote = createRemote(); + const book = remote.createOrderBook({ + currency_pays: 'USD', + issuer_pays: addresses.ISSUER, + currency_gets: 'BTC', + issuer_gets: addresses.ISSUER + }); + + remote.request = function(request) { + const response = {}; + + if (request.message.command === 'account_info') { + response.account_data = { + TransferRate: 1002000000 + }; + + } else if (request.message.command === 'book_offers') { + response.offers = []; + } + + setImmediate(function() { + request.emit('success', response); + }); + }; + + book.on('model', function(offers) { + assert.strictEqual(offers.length, 0); + done(); + }); }); it('Unsubscribe', function(done) {