divvy-rest
Version:
A RESTful API for submitting payments and monitoring accounts on the Divvy network.
632 lines (549 loc) • 22.6 kB
JavaScript
/* eslint-disable new-cap */
/* eslint-disable max-len */
;
var assert = require('assert');
var testutils = require('./testutils');
var fixtures = require('./fixtures').balances;
var errors = require('./fixtures').errors;
var addresses = require('./fixtures').addresses;
var requestPath = fixtures.requestPath;
var MARKER = '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73';
var NEXT_MARKER =
'0C812C919D343EAE789B29E8027C62C5792C22172D37EA2B2C0121D2381F80E1';
var LEDGER = 9592219;
var LEDGER_HASH =
'FD22E2A8D665A01711C0147173ECC0A32466BA976DE697E95197933311267BE8';
var LIMIT = 5;
var DEFAULT_LIMIT = 200;
suite('get balances', function() {
var self = this;
// self.wss: divvyd mock
// self.app: supertest-enabled REST handler
setup(testutils.setup.bind(self));
teardown(testutils.teardown.bind(self));
test('/accounts/:account/balances', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 'validated');
assert.strictEqual(message.limit, DEFAULT_LIMIT);
conn.send(fixtures.accountLinesResponse(message, {
ledger: LEDGER,
marker: NEXT_MARKER,
limit: DEFAULT_LIMIT
}));
});
self.app
.get(requestPath(addresses.VALID))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
ledger: LEDGER,
marker: NEXT_MARKER,
limit: DEFAULT_LIMIT
})))
.end(done);
});
test('/accounts/:account/balances -- with limit=all', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.on('request_account_lines', function(message, conn) {
if (message.ledger_index === 'validated') {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 'validated');
assert.strictEqual(message.marker, undefined);
assert.strictEqual(message.limit, DEFAULT_LIMIT);
conn.send(fixtures.accountLinesResponse(message, {
ledger: LEDGER,
marker: NEXT_MARKER
}));
} else {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, LEDGER);
assert.strictEqual(message.marker, NEXT_MARKER);
assert.notEqual(message.limit, 'all');
conn.send(fixtures.accountLinesResponse(message, {
ledger: LEDGER,
marker: undefined
}));
}
});
self.app
.get(requestPath(addresses.VALID, '?limit=all'))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.end(function(err, res) {
if (err) {
return done(err);
}
assert.strictEqual(res.body.balances.length, 49);
assert.strictEqual(res.body.marker, undefined);
assert.strictEqual(res.body.ledger, LEDGER);
assert.strictEqual(res.body.validated, true);
done();
});
});
test('/accounts/:account/balances -- with invalid ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?ledger=foo'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with ledger (sequence)', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, LEDGER);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?ledger=' + LEDGER))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances -- with ledger (hash)', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_hash, LEDGER_HASH);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?ledger=' + LEDGER_HASH))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances -- with non-validated ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, LEDGER);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER,
validated: false
}));
});
self.app
.get(requestPath(addresses.VALID, '?ledger=' + LEDGER))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
ledger: LEDGER,
validated: false
})))
.end(done);
});
test('/accounts/:account/balances -- with invalid limit', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?limit=foo'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('limit')))
.end(done);
});
test('/accounts/:account/balances -- with marker and missing ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with marker and valid ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 9592219);
assert.strictEqual(message.marker, MARKER);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&ledger=' + LEDGER))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, ledger and limit', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, LEDGER);
assert.strictEqual(message.limit, LIMIT);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?ledger=' + LEDGER + '&limit=' + LIMIT))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
limit: LIMIT,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, valid limit, and invalid ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&limit=' + LIMIT + '&ledger=foo'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, valid limit, and ledger=validated', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&limit=' + LIMIT + '&ledger=validated'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, valid limit, and ledger=closed', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&limit=' + LIMIT + '&ledger=closed'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, valid limit, and ledger=current', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function() {
assert(false);
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&limit=' + LIMIT + '&ledger=current'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.restInvalidParameter('ledger')))
.end(done);
});
test('/accounts/:account/balances -- with valid marker, valid limit, and valid ledger', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountInfoResponse(message));
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.limit, LIMIT);
assert.strictEqual(message.ledger_index, LEDGER);
assert.strictEqual(message.marker, MARKER);
conn.send(fixtures.accountLinesResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?marker=' + MARKER + '&limit=' + LIMIT + '&ledger=' + LEDGER))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesResponse({
marker: NEXT_MARKER,
limit: LIMIT,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances -- invalid account', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function() {
assert(false, 'Should not request account lines');
});
self.app
.get(requestPath(addresses.INVALID))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.RESTInvalidAccount))
.end(done);
});
test('/accounts/:account/balances -- non-existent account', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
conn.send(fixtures.accountNotFoundResponse(message));
});
/* TODO: uncommenting this breaks *other* test cases
self.wss.once('request_account_lines', function(message, conn) {
assert(false, 'Should not request account lines');
});
*/
self.app
.get(requestPath(addresses.VALID))
.expect(testutils.checkStatus(404))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.RESTAccountNotFound))
.end(done);
});
test('/accounts/:account/balances?currency', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 'validated');
conn.send(fixtures.accountLinesResponse(message, {
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?currency=USD'))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesUSDResponse({
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances?currency -- native currency', function(done) {
self.wss.once('request_account_info', function(message, conn) {
assert.strictEqual(message.command, 'account_info');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 'validated');
conn.send(fixtures.accountInfoResponse(message, {
ledger: LEDGER
}));
});
self.wss.once('request_account_lines', function() {
assert(false, 'Should not request account lines');
});
self.app
.get(requestPath(addresses.VALID, '?currency=XDV'))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesXDVResponse({
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances?currency -- invalid currency', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function() {
assert(false, 'Should not request account lines');
});
self.app
.get(requestPath(addresses.VALID, '?currency=AAAA'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.RESTInvalidCurrency))
.end(done);
});
test('/accounts/:account/balances?counterparty', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.peer, addresses.COUNTERPARTY);
assert.strictEqual(message.ledger_index, 'validated');
conn.send(fixtures.accountLinesCounterpartyResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?counterparty=' + addresses.COUNTERPARTY))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesCounterpartyResponse({
marker: NEXT_MARKER,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances?counterparty -- invalid counterparty', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function() {
assert(false, 'Should not request account lines');
});
self.app
.get(requestPath(addresses.VALID, '?counterparty=asdf'))
.expect(testutils.checkStatus(400))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(errors.RESTInvalidCounterparty))
.end(done);
});
test('/accounts/:account/balances?counterparty -- non-existent counterparty', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.peer, addresses.COUNTERPARTY);
conn.send(fixtures.accountLinesNoCounterpartyResponse(message));
});
self.app
.get(requestPath(addresses.VALID, '?counterparty=' + addresses.COUNTERPARTY))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesNoCounterpartyResponse))
.end(done);
});
test('/accounts/:account/balances?counterparty¤cy=EUR', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account info');
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.peer, addresses.COUNTERPARTY);
conn.send(fixtures.accountLinesCounterpartyResponse(message, {
marker: NEXT_MARKER,
ledger: LEDGER
}));
});
self.app
.get(requestPath(addresses.VALID, '?counterparty=' + addresses.COUNTERPARTY + '¤cy=EUR'))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.expect(testutils.checkBody(fixtures.RESTAccountBalancesCounterpartyCurrencyResponse({
marker: NEXT_MARKER,
ledger: LEDGER
})))
.end(done);
});
test('/accounts/:account/balances?frozen', function(done) {
self.wss.once('request_account_info', function() {
assert(false, 'Should not request account_info');
});
self.wss.once('request_account_lines', function(message, conn) {
assert.strictEqual(message.command, 'account_lines');
assert.strictEqual(message.account, addresses.VALID);
assert.strictEqual(message.ledger_index, 'validated');
conn.send(fixtures.accountLinesResponse(message));
});
self.app
.get(requestPath(addresses.VALID, '?frozen=true'))
.expect(testutils.checkBody(fixtures.RESTAccountBalancesFrozenResponse()))
.expect(testutils.checkStatus(200))
.expect(testutils.checkHeaders)
.end(done);
});
});