diff --git a/src/Wallet.ts b/src/Wallet.ts index 49481fe2..4043d68d 100644 --- a/src/Wallet.ts +++ b/src/Wallet.ts @@ -1,14 +1,19 @@ -import { fromSeed } from 'bip32'; -import { mnemonicToSeedSync } from 'bip39'; -import { classicAddressToXAddress } from 'ripple-address-codec' -import { decode, encodeForSigning } from 'ripple-binary-codec'; -import { deriveAddress, deriveKeypair, generateSeed, verify } from 'ripple-keypairs'; +import { fromSeed } from "bip32"; +import { mnemonicToSeedSync } from "bip39"; +import { classicAddressToXAddress } from "ripple-address-codec"; +import { decode, encodeForSigning } from "ripple-binary-codec"; +import { + deriveAddress, + deriveKeypair, + generateSeed, + verify, +} from "ripple-keypairs"; -import ECDSA from './common/ecdsa'; -import { ValidationError } from './common/errors'; -import { SignedTransaction } from './common/types/objects'; -import { signOffline } from './transaction/sign'; -import { SignOptions } from './transaction/types'; +import ECDSA from "./common/ecdsa"; +import { ValidationError } from "./common/errors"; +import { SignedTransaction } from "./common/types/objects"; +import { signOffline } from "./transaction/sign"; +import { SignOptions } from "./transaction/types"; /** * A utility for deriving a wallet composed of a keypair (publicKey/privateKey). @@ -125,16 +130,13 @@ class Wallet { /** * Gets an X-address in Testnet/Mainnet format. - * @param {number} tag A tag to be included within the X-address. - * @param {boolean} test A boolean to indicate if X-address should be in Testnet (true) or Mainnet (false) format. - * @returns {string} An X-address. + * + * @param tag - A tag to be included within the X-address. + * @param test - A boolean to indicate if X-address should be in Testnet (true) or Mainnet (false) format. + * @returns An X-address. */ - getXAddress(tag: number, test: boolean = false): string { - return classicAddressToXAddress( - deriveAddress(this.publicKey), - tag, - test, - ) + getXAddress(tag: number, test = false): string { + return classicAddressToXAddress(deriveAddress(this.publicKey), tag, test); } } diff --git a/test/rippleClientPrivate.ts b/test/client.ts similarity index 100% rename from test/rippleClientPrivate.ts rename to test/client.ts diff --git a/test/client/combine.ts b/test/client/combine.ts index 49aa0d76..0ba3bcb1 100644 --- a/test/client/combine.ts +++ b/test/client/combine.ts @@ -3,29 +3,28 @@ import binary from "ripple-binary-codec"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch } from "../testUtils"; const { combine: REQUEST_FIXTURES } = requests; const { combine: RESPONSE_FIXTURES } = responses; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async combine(client, address) { - const combined = client.combine(REQUEST_FIXTURES.setDomain); - assertResultMatch(combined, RESPONSE_FIXTURES.single, "sign"); - }, +describe("client.combine", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "combine - different transactions": async (client, address) => { + it("combine", async function () { + const combined = this.client.combine(REQUEST_FIXTURES.setDomain); + assertResultMatch(combined, RESPONSE_FIXTURES.single, "sign"); + }); + + it("combine - different transactions", async function () { const request = [REQUEST_FIXTURES.setDomain[0]]; const tx = binary.decode(REQUEST_FIXTURES.setDomain[0]); tx.Flags = 0; request.push(binary.encode(tx)); assert.throws(() => { - client.combine(request); + this.client.combine(request); }, /txJSON is not the same for all signedTransactions/); - }, -}; + }); +}); diff --git a/test/client/constructor.ts b/test/client/constructor.ts index ba03d114..a5c171d4 100644 --- a/test/client/constructor.ts +++ b/test/client/constructor.ts @@ -2,30 +2,23 @@ import { assert } from "chai"; import { Client } from "xrpl-local"; -import { TestSuite } from "../testUtils"; - -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "Client - implicit server port": () => { +describe("client constructor", function () { + it("Client - implicit server port", function () { new Client("wss://s1.ripple.com"); - }, + }); - "Client invalid options": () => { + it("Client invalid options", function () { // @ts-expect-error - This is intentionally invalid assert.throws(() => new Client({ invalid: true })); - }, + }); - "Client valid options": () => { + it("Client valid options", function () { const client = new Client("wss://s:1"); const privateConnectionUrl = (client.connection as any)._url; assert.deepEqual(privateConnectionUrl, "wss://s:1"); - }, + }); - "Client invalid server uri": () => { + it("Client invalid server uri", function () { assert.throws(() => new Client("wss//s:1")); - }, -}; + }); +}); diff --git a/test/client/deriveXAddress.ts b/test/client/deriveXAddress.ts index a5aae3ac..e361930b 100644 --- a/test/client/deriveXAddress.ts +++ b/test/client/deriveXAddress.ts @@ -1,15 +1,9 @@ import { assert } from "chai"; import { Client } from "../../src"; -import { TestSuite } from "../testUtils"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "returns address for public key": async (client, address) => { +describe("client.deriveXAddress", function () { + it("returns address for public key", function () { assert.equal( Client.deriveXAddress({ publicKey: @@ -28,5 +22,5 @@ export default { }), "TVVrSWtmQQssgVcmoMBcFQZKKf56QscyWLKnUyiuZW8ALU4" ); - }, -}; + }); +}); diff --git a/test/client/errors.ts b/test/client/errors.ts index 3357e89f..f928f94e 100644 --- a/test/client/errors.ts +++ b/test/client/errors.ts @@ -1,20 +1,18 @@ import { assert } from "chai"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "RippleError with data": async (client, address) => { - const error = new client.errors.RippleError("_message_", "_data_"); +describe("client errors", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + it("RippleError with data", async function () { + const error = new this.client.errors.RippleError("_message_", "_data_"); assert.strictEqual(error.toString(), "[RippleError(_message_, '_data_')]"); - }, + }); - "NotFoundError default message": async (client, address) => { - const error = new client.errors.NotFoundError(); + it("NotFoundError default message", async function () { + const error = new this.client.errors.NotFoundError(); assert.strictEqual(error.toString(), "[NotFoundError(Not found)]"); - }, -}; + }); +}); diff --git a/test/client/formatBidsAndAsks.ts b/test/client/formatBidsAndAsks.ts index 94bb1f47..20da7e69 100644 --- a/test/client/formatBidsAndAsks.ts +++ b/test/client/formatBidsAndAsks.ts @@ -3,7 +3,6 @@ // import {Client} from 'xrpl-local' // import requests from '../fixtures/requests' // import responses from '../fixtures/responses' -import { TestSuite } from "../testUtils"; // function checkSortingOfOrders(orders) { // let previousRate = '0' @@ -39,12 +38,7 @@ import { TestSuite } from "../testUtils"; // return true // } -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { +describe("client.formatBidsAndAsks", function () { // 'normal': async (client, address) => { // const orderbookInfo = { // base: { @@ -365,4 +359,4 @@ export default { // ) // }) // } -}; +}); diff --git a/test/client/getBalances.ts b/test/client/getBalances.ts index 8535cad9..7909e330 100644 --- a/test/client/getBalances.ts +++ b/test/client/getBalances.ts @@ -1,66 +1,94 @@ import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; import rippledAccountLines from "../fixtures/rippled/accountLines"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; /** * Every test suite exports their tests in the default object. * - Check out the "TestSuite" type for documentation on the interface. * - Check out "test/client/index.ts" for more information about the test runner. */ -export default { - async getBalances(client, address, mockRippled) { - mockRippled.addResponse("account_info", rippled.account_info.normal); - mockRippled.addResponse("account_lines", rippledAccountLines.normal); - mockRippled.addResponse("ledger", rippled.ledger.normal); - const result = await client.getBalances(address); - assertResultMatch(result, responses.getBalances, "getBalances"); - }, +describe("getBalances", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "getBalances - limit": async (client, address, mockRippled) => { - const options = { limit: 3, ledgerVersion: 123456 }; - mockRippled.addResponse("account_info", rippled.account_info.normal); - mockRippled.addResponse("account_lines", rippledAccountLines.normal); - mockRippled.addResponse("ledger", rippled.ledger.normal); - const expectedResponse = responses.getBalances.slice(0, 3); - const result = await client.getBalances(address, options); - assertResultMatch(result, expectedResponse, "getBalances"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("getBalances", async function () { + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.mockRippled.addResponse( + "account_lines", + rippledAccountLines.normal + ); + this.mockRippled.addResponse("ledger", rippled.ledger.normal); + const result = await this.client.getBalances(test.address); + assertResultMatch(result, responses.getBalances, "getBalances"); + }); - "getBalances - limit & currency": async (client, address, mockRippled) => { - const options = { currency: "USD", limit: 3 }; - mockRippled.addResponse("account_info", rippled.account_info.normal); - mockRippled.addResponse("account_lines", rippledAccountLines.normal); - mockRippled.addResponse("ledger", rippled.ledger.normal); - const expectedResponse = responses.getBalances - .filter((item) => item.currency === "USD") - .slice(0, 3); - const result = await client.getBalances(address, options); - assertResultMatch(result, expectedResponse, "getBalances"); - }, + it("getBalances - limit", async function () { + const options = { limit: 3, ledgerVersion: 123456 }; + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.mockRippled.addResponse( + "account_lines", + rippledAccountLines.normal + ); + this.mockRippled.addResponse("ledger", rippled.ledger.normal); + const expectedResponse = responses.getBalances.slice(0, 3); + const result = await this.client.getBalances(test.address, options); + assertResultMatch(result, expectedResponse, "getBalances"); + }); - "getBalances - limit & currency & issuer": async ( - client, - address, - mockRippled - ) => { - const options = { - currency: "USD", - counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - limit: 3, - }; - mockRippled.addResponse("account_info", rippled.account_info.normal); - mockRippled.addResponse("account_lines", rippledAccountLines.normal); - mockRippled.addResponse("ledger", rippled.ledger.normal); + it("getBalances - limit & currency", async function () { + const options = { currency: "USD", limit: 3 }; + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.mockRippled.addResponse( + "account_lines", + rippledAccountLines.normal + ); + this.mockRippled.addResponse("ledger", rippled.ledger.normal); + const expectedResponse = responses.getBalances + .filter((item) => item.currency === "USD") + .slice(0, 3); + const result = await this.client.getBalances(test.address, options); + assertResultMatch(result, expectedResponse, "getBalances"); + }); - const expectedResponse = responses.getBalances - .filter( - (item) => - item.currency === "USD" && - item.counterparty === "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" - ) - .slice(0, 3); - const result = await client.getBalances(address, options); - assertResultMatch(result, expectedResponse, "getBalances"); - }, -}; + it("getBalances - limit & currency & issuer", async function () { + const options = { + currency: "USD", + counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + limit: 3, + }; + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.mockRippled.addResponse( + "account_lines", + rippledAccountLines.normal + ); + this.mockRippled.addResponse("ledger", rippled.ledger.normal); + + const expectedResponse = responses.getBalances + .filter( + (item) => + item.currency === "USD" && + item.counterparty === "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" + ) + .slice(0, 3); + const result = await this.client.getBalances(test.address, options); + assertResultMatch(result, expectedResponse, "getBalances"); + }); + }); + }); +}); diff --git a/test/client/getFee.ts b/test/client/getFee.ts index a8c7d059..1c2c8ee9 100644 --- a/test/client/getFee.ts +++ b/test/client/getFee.ts @@ -1,65 +1,70 @@ import { assert } from "chai"; import rippled from "../fixtures/rippled"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { addressTests } from "../testUtils"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async getFee(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - const fee = await client.getFee(); - assert.strictEqual(fee, "0.000012"); - }, +describe("client.getFee", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "getFee default": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - client._feeCushion = undefined as unknown as number; - const fee = await client.getFee(); - assert.strictEqual(fee, "0.000012"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("getFee", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + const fee = await this.client.getFee(); + assert.strictEqual(fee, "0.000012"); + }); - "getFee - high load_factor": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.highLoadFactor); - const fee = await client.getFee(); - assert.strictEqual(fee, "2"); - }, + it("getFee default", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.client._feeCushion = undefined as unknown as number; + const fee = await this.client.getFee(); + assert.strictEqual(fee, "0.000012"); + }); - "getFee - high load_factor with custom maxFeeXRP": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.highLoadFactor); - // Ensure that overriding with high maxFeeXRP of '51540' causes no errors. - // (fee will actually be 51539.607552) - client._maxFeeXRP = "51540"; - const fee = await client.getFee(); - assert.strictEqual(fee, "51539.607552"); - }, + it("getFee - high load_factor", async function () { + this.mockRippled.addResponse( + "server_info", + rippled.server_info.highLoadFactor + ); + const fee = await this.client.getFee(); + assert.strictEqual(fee, "2"); + }); - "getFee custom cushion": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - client._feeCushion = 1.4; - const fee = await client.getFee(); - assert.strictEqual(fee, "0.000014"); - }, + it("getFee - high load_factor with custom maxFeeXRP", async function () { + this.mockRippled.addResponse( + "server_info", + rippled.server_info.highLoadFactor + ); + // Ensure that overriding with high maxFeeXRP of '51540' causes no errors. + // (fee will actually be 51539.607552) + this.client._maxFeeXRP = "51540"; + const fee = await this.client.getFee(); + assert.strictEqual(fee, "51539.607552"); + }); - // This is not recommended since it may result in attempting to pay - // less than the base fee. However, this test verifies the existing behavior. - "getFee cushion less than 1.0": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - client._feeCushion = 0.9; - const fee = await client.getFee(); - assert.strictEqual(fee, "0.000009"); - }, + it("getFee custom cushion", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.client._feeCushion = 1.4; + const fee = await this.client.getFee(); + assert.strictEqual(fee, "0.000014"); + }); - "getFee reporting": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - const fee = await client.getFee(); - assert.strictEqual(fee, "0.000012"); - }, -}; + // This is not recommended since it may result in attempting to pay + // less than the base fee. However, this test verifies the existing behavior. + it("getFee cushion less than 1.0", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.client._feeCushion = 0.9; + const fee = await this.client.getFee(); + assert.strictEqual(fee, "0.000009"); + }); + + it("getFee reporting", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + const fee = await this.client.getFee(); + assert.strictEqual(fee, "0.000012"); + }); + }); + }); +}); diff --git a/test/client/getOrderbook.ts b/test/client/getOrderbook.ts index 6efe88b5..cda1bc49 100644 --- a/test/client/getOrderbook.ts +++ b/test/client/getOrderbook.ts @@ -4,7 +4,8 @@ import { BookOffersRequest } from "../../src"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { TestSuite, assertResultMatch, assertRejects } from "../testUtils"; +import setupClient from "../setupClient"; +import { addressTests, assertResultMatch, assertRejects } from "../testUtils"; // import BigNumber from 'bignumber.js' // function checkSortingOfOrders(orders) { @@ -81,137 +82,136 @@ function xrpRippledResponse(request: BookOffersRequest): object { throw new Error("unexpected end"); } -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async normal(client, address, mockRippled) { - mockRippled.addResponse("book_offers", normalRippledResponse); - const response = await client.getOrderbook( - address, - requests.getOrderbook.normal, - { limit: 20 } - ); - assertResultMatch(response, responses.getOrderbook.normal, "getOrderbook"); - }, +describe("client.getOrderbook", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "invalid options": async (client, address, mockRippled) => { - mockRippled.addResponse("book_offers", normalRippledResponse); - assertRejects( - client.getOrderbook(address, requests.getOrderbook.normal, { - // @ts-expect-error - invalid: "options", - }), - client.errors.ValidationError - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("normal", async function () { + this.mockRippled.addResponse("book_offers", normalRippledResponse); + const response = await this.client.getOrderbook( + test.address, + requests.getOrderbook.normal, + { limit: 20 } + ); + assertResultMatch( + response, + responses.getOrderbook.normal, + "getOrderbook" + ); + }); - "with XRP": async (client, address, mockRippled) => { - mockRippled.addResponse("book_offers", xrpRippledResponse); - const response = await client.getOrderbook( - address, - requests.getOrderbook.withXRP - ); - assertResultMatch(response, responses.getOrderbook.withXRP, "getOrderbook"); - }, + it("invalid options", async function () { + this.mockRippled.addResponse("book_offers", normalRippledResponse); + assertRejects( + this.client.getOrderbook(test.address, requests.getOrderbook.normal, { + invalid: "options", + }), + this.client.errors.ValidationError + ); + }); - // 'sample XRP/JPY book has orders sorted correctly': async (client, address, mockRippled) => { - // const orderbookInfo = { - // base: { - // // the first currency in pair - // currency: 'XRP' - // }, - // counter: { - // currency: 'JPY', - // counterparty: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS' - // } - // } - // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' - // const response = await client.getOrderbook(myAddress, orderbookInfo) - // assert.deepStrictEqual([], response.bids) - // checkSortingOfOrders(response.asks) - // }, + it("with XRP", async function () { + this.mockRippled.addResponse("book_offers", xrpRippledResponse); + const response = await this.client.getOrderbook( + test.address, + requests.getOrderbook.withXRP + ); + assertResultMatch( + response, + responses.getOrderbook.withXRP, + "getOrderbook" + ); + }); - // 'sample USD/XRP book has orders sorted correctly': async (client, address, mockRippled) => { - // const orderbookInfo = { - // counter: {currency: 'XRP'}, - // base: { - // currency: 'USD', - // counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' - // } - // } - // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' - // const response = await client.getOrderbook(myAddress, orderbookInfo) - // checkSortingOfOrders(response.bids) - // checkSortingOfOrders(response.asks) - // }, + // 'sample XRP/JPY book has orders sorted correctly', async function () { + // const orderbookInfo = { + // base: { + // // the first currency in pair + // currency: 'XRP' + // }, + // counter: { + // currency: 'JPY', + // counterparty: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS' + // } + // } + // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' + // const response = await this.client.getOrderbook(myAddress, orderbookInfo) + // assert.deepStrictEqual([], response.bids) + // checkSortingOfOrders(response.asks) + // }, - // WARNING: This test fails to catch the sorting bug, issue #766 - "sorted so that best deals come first [bad test]": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("book_offers", normalRippledResponse); - const response = await client.getOrderbook( - address, - requests.getOrderbook.normal - ); - const bidRates = response.bids.map( - (bid) => bid.properties.makerExchangeRate - ); - const askRates = response.asks.map( - (ask) => ask.properties.makerExchangeRate - ); - // makerExchangeRate = quality = takerPays.value/takerGets.value - // so the best deal for the taker is the lowest makerExchangeRate - // bids and asks should be sorted so that the best deals come first - assert.deepEqual( - bidRates.sort((x) => Number(x)), - bidRates - ); - assert.deepEqual( - askRates.sort((x) => Number(x)), - askRates - ); - }, + // 'sample USD/XRP book has orders sorted correctly', async function () { + // const orderbookInfo = { + // counter: {currency: 'XRP'}, + // base: { + // currency: 'USD', + // counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' + // } + // } + // const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR' + // const response = await this.client.getOrderbook(myAddress, orderbookInfo) + // checkSortingOfOrders(response.bids) + // checkSortingOfOrders(response.asks) + // }, - "currency & counterparty are correct": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("book_offers", normalRippledResponse); - const response = await client.getOrderbook( - address, - requests.getOrderbook.normal - ); - [...response.bids, ...response.asks].forEach((order) => { - const quantity = order.specification.quantity; - const totalPrice = order.specification.totalPrice; - const { base, counter } = requests.getOrderbook.normal; - assert.strictEqual(quantity.currency, base.currency); - assert.strictEqual(quantity.counterparty, base.counterparty); - assert.strictEqual(totalPrice.currency, counter.currency); - assert.strictEqual(totalPrice.counterparty, counter.counterparty); + // WARNING: This test fails to catch the sorting bug, issue #766 + it("sorted so that best deals come first [bad test]", async function () { + this.mockRippled.addResponse("book_offers", normalRippledResponse); + const response = await this.client.getOrderbook( + test.address, + requests.getOrderbook.normal + ); + const bidRates = response.bids.map( + (bid) => bid.properties.makerExchangeRate + ); + const askRates = response.asks.map( + (ask) => ask.properties.makerExchangeRate + ); + // makerExchangeRate = quality = takerPays.value/takerGets.value + // so the best deal for the taker is the lowest makerExchangeRate + // bids and asks should be sorted so that the best deals come first + assert.deepEqual( + bidRates.sort((x) => Number(x)), + bidRates + ); + assert.deepEqual( + askRates.sort((x) => Number(x)), + askRates + ); + }); + + it("currency & counterparty are correct", async function () { + this.mockRippled.addResponse("book_offers", normalRippledResponse); + const response = await this.client.getOrderbook( + test.address, + requests.getOrderbook.normal + ); + [...response.bids, ...response.asks].forEach((order) => { + const quantity = order.specification.quantity; + const totalPrice = order.specification.totalPrice; + const { base, counter } = requests.getOrderbook.normal; + assert.strictEqual(quantity.currency, base.currency); + assert.strictEqual(quantity.counterparty, base.counterparty); + assert.strictEqual(totalPrice.currency, counter.currency); + assert.strictEqual(totalPrice.counterparty, counter.counterparty); + }); + }); + + it("direction is correct for bids and asks", async function () { + this.mockRippled.addResponse("book_offers", normalRippledResponse); + const response = await this.client.getOrderbook( + test.address, + requests.getOrderbook.normal + ); + assert( + response.bids.every((bid) => bid.specification.direction === "buy") + ); + assert( + response.asks.every((ask) => ask.specification.direction === "sell") + ); + }); }); - }, - - "direction is correct for bids and asks": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("book_offers", normalRippledResponse); - const response = await client.getOrderbook( - address, - requests.getOrderbook.normal - ); - assert(response.bids.every((bid) => bid.specification.direction === "buy")); - assert( - response.asks.every((ask) => ask.specification.direction === "sell") - ); - }, -}; + }); +}); diff --git a/test/client/getPaths.ts b/test/client/getPaths.ts index 1e56fe2f..c4242e28 100644 --- a/test/client/getPaths.ts +++ b/test/client/getPaths.ts @@ -3,7 +3,8 @@ import { assert } from "chai"; import addresses from "../fixtures/addresses.json"; import requests from "../fixtures/requests"; import rippled from "../fixtures/rippled"; -import { assertRejects, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects } from "../testUtils"; // import responses from '../fixtures/responses' const { getPaths: REQUEST_FIXTURES } = requests; // const {getPaths: RESPONSE_FIXTURES} = responses @@ -15,97 +16,94 @@ const rippledResponse = rippled.path_find.generate.generateIOUPaymentPaths( REQUEST_FIXTURES.normal.destination.amount ); -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - // 'simple test': async (client) => { - // const response = await client.getPaths(REQUEST_FIXTURES.normal) +describe("client.getPaths", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + // 'simple test', function () { + // const response = await this.client.getPaths(REQUEST_FIXTURES.normal) // assertResultMatch(response, RESPONSE_FIXTURES.XrpToUsd, 'getPaths') - // }, - // 'queuing': async (client) => { + // }) + // 'queuing', function () { // const [normalResult, usdOnlyResult, xrpOnlyResult] = await Promise.all([ - // client.getPaths(REQUEST_FIXTURES.normal), - // client.getPaths(REQUEST_FIXTURES.UsdToUsd), - // client.getPaths(REQUEST_FIXTURES.XrpToXrp) + // this.client.getPaths(REQUEST_FIXTURES.normal), + // this.client.getPaths(REQUEST_FIXTURES.UsdToUsd), + // this.client.getPaths(REQUEST_FIXTURES.XrpToXrp) // ]) // assertResultMatch(normalResult, RESPONSE_FIXTURES.XrpToUsd, 'getPaths') // assertResultMatch(usdOnlyResult, RESPONSE_FIXTURES.UsdToUsd, 'getPaths') // assertResultMatch(xrpOnlyResult, RESPONSE_FIXTURES.XrpToXrp, 'getPaths') - // }, + // }) // // @TODO // // need decide what to do with currencies/XRP: // // if add 'XRP' in currencies, then there will be exception in // // xrpToDrops function (called from toRippledAmount) - // 'getPaths USD 2 USD': async (client) => { - // const response = await client.getPaths(REQUEST_FIXTURES.UsdToUsd) + // 'getPaths USD 2 USD', function () { + // const response = await this.client.getPaths(REQUEST_FIXTURES.UsdToUsd) // assertResultMatch(response, RESPONSE_FIXTURES.UsdToUsd, 'getPaths') - // }, - // 'getPaths XRP 2 XRP': async (client) => { - // const response = await client.getPaths(REQUEST_FIXTURES.XrpToXrp) + // }) + // 'getPaths XRP 2 XRP', function () { + // const response = await this.client.getPaths(REQUEST_FIXTURES.XrpToXrp) // assertResultMatch(response, RESPONSE_FIXTURES.XrpToXrp, 'getPaths') - // }, - "source with issuer": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + // }) + it("source with issuer", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths(REQUEST_FIXTURES.issuer), - client.errors.NotFoundError + this.client.getPaths(REQUEST_FIXTURES.issuer), + this.client.errors.NotFoundError ); - }, - // 'XRP 2 XRP - not enough': async (client) => { + }); + // 'XRP 2 XRP - not enough', function () { // return assertRejects( - // client.getPaths(REQUEST_FIXTURES.XrpToXrpNotEnough), - // client.errors.NotFoundError + // this.client.getPaths(REQUEST_FIXTURES.XrpToXrpNotEnough), + // this.client.errors.NotFoundError // ) - // }, - "invalid PathFind": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + // }) + it("invalid PathFind", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); assert.throws(() => { - client.getPaths(REQUEST_FIXTURES.invalid); + this.client.getPaths(REQUEST_FIXTURES.invalid); }, /Cannot specify both source.amount/); - }, - "does not accept currency": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + }); + it("does not accept currency", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths(REQUEST_FIXTURES.NotAcceptCurrency), - client.errors.NotFoundError + this.client.getPaths(REQUEST_FIXTURES.NotAcceptCurrency), + this.client.errors.NotFoundError ); - }, - "no paths": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + }); + it("no paths", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths(REQUEST_FIXTURES.NoPaths), - client.errors.NotFoundError + this.client.getPaths(REQUEST_FIXTURES.NoPaths), + this.client.errors.NotFoundError ); - }, - "no paths source amount": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + }); + it("no paths source amount", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths(REQUEST_FIXTURES.NoPathsSource), - client.errors.NotFoundError + this.client.getPaths(REQUEST_FIXTURES.NoPathsSource), + this.client.errors.NotFoundError ); - }, - "no paths with source currencies": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + }); + it("no paths with source currencies", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths(REQUEST_FIXTURES.NoPathsWithCurrencies), - client.errors.NotFoundError + this.client.getPaths(REQUEST_FIXTURES.NoPathsWithCurrencies), + this.client.errors.NotFoundError ); - }, - "error: srcActNotFound": async (client, _, mockRippled) => { - mockRippled.addResponse("ripple_path_find", rippledResponse); + }); + it("error: srcActNotFound", function () { + this.mockRippled.addResponse("ripple_path_find", rippledResponse); return assertRejects( - client.getPaths({ + this.client.getPaths({ ...REQUEST_FIXTURES.normal, source: { address: addresses.NOTFOUND }, }), - client.errors.RippleError + this.client.errors.RippleError ); - }, - // 'send all': async (client) => { - // const response = await client.getPaths(REQUEST_FIXTURES.sendAll) + }); + // 'send all', function () { + // const response = await this.client.getPaths(REQUEST_FIXTURES.sendAll) // assertResultMatch(response, RESPONSE_FIXTURES.sendAll, 'getPaths') - // } -}; + // }) +}); diff --git a/test/client/getTrustlines.ts b/test/client/getTrustlines.ts index 7cb05163..5dccc69f 100644 --- a/test/client/getTrustlines.ts +++ b/test/client/getTrustlines.ts @@ -1,70 +1,60 @@ -import addresses from "../fixtures/addresses.json"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled/accountLines"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const { getTrustlines: RESPONSE_FIXTURES } = responses; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "getTrustlines - filtered": async (client, address, mockRippled) => { - mockRippled.addResponse("account_lines", rippled.normal); - const options = { currency: "USD" }; - const result = await client.getTrustlines(address, options); - assertResultMatch(result, RESPONSE_FIXTURES.filtered, "getTrustlines"); - }, +describe("client.getTrustlines", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "getTrustlines - more than 400 items": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("account_lines", rippled.manyItems); - const options = { limit: 401 }; - const result = await client.getTrustlines(address, options); - assertResultMatch( - result, - RESPONSE_FIXTURES.moreThan400Items, - "getTrustlines" - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("getTrustlines - filtered", async function () { + this.mockRippled.addResponse("account_lines", rippled.normal); + const options = { currency: "USD" }; + const result = await this.client.getTrustlines(test.address, options); + assertResultMatch(result, RESPONSE_FIXTURES.filtered, "getTrustlines"); + }); - "getTrustlines - no options": async (client, address, mockRippled) => { - mockRippled.addResponse("account_lines", rippled.normal); - await client.getTrustlines(address); - }, + it("getTrustlines - more than 400 items", async function () { + this.mockRippled.addResponse("account_lines", rippled.manyItems); + const options = { limit: 401 }; + const result = await this.client.getTrustlines(test.address, options); + assertResultMatch( + result, + RESPONSE_FIXTURES.moreThan400Items, + "getTrustlines" + ); + }); - "getTrustlines - ripplingDisabled works properly": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("account_lines", rippled.ripplingDisabled); - const result = await client.getTrustlines(address); - assertResultMatch( - result, - RESPONSE_FIXTURES.ripplingDisabled, - "getTrustlines" - ); - }, + it("getTrustlines - no options", async function () { + this.mockRippled.addResponse("account_lines", rippled.normal); + await this.client.getTrustlines(test.address); + }); - "getTrustlines - ledger version option": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("account_lines", rippled.manyItems); - const result = await client.getTrustlines(addresses.FOURTH_ACCOUNT, { - ledgerVersion: 5, + it("getTrustlines - ripplingDisabled works properly", async function () { + this.mockRippled.addResponse("account_lines", rippled.ripplingDisabled); + const result = await this.client.getTrustlines(test.address); + assertResultMatch( + result, + RESPONSE_FIXTURES.ripplingDisabled, + "getTrustlines" + ); + }); + + it("getTrustlines - ledger version option", async function () { + this.mockRippled.addResponse("account_lines", rippled.manyItems); + const result = await this.client.getTrustlines(test.address, { + ledgerVersion: 5, + }); + assertResultMatch( + result, + RESPONSE_FIXTURES.moreThan400Items, + "getTrustlines" + ); + }); }); - assertResultMatch( - result, - RESPONSE_FIXTURES.moreThan400Items, - "getTrustlines" - ); - }, -}; + }); +}); diff --git a/test/client/hasNextPage.ts b/test/client/hasNextPage.ts index 609b2e9a..d3d597bd 100644 --- a/test/client/hasNextPage.ts +++ b/test/client/hasNextPage.ts @@ -1,41 +1,31 @@ import { assert } from "chai"; import rippled from "../fixtures/rippled"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "returns true when there is another page": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("ledger_data", rippled.ledger_data.first_page); - const response = await client.request({ command: "ledger_data" }); - assert(client.hasNextPage(response)); - }, +describe("client.hasNextPage", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "returns false when there are no more pages": async ( - client, - address, - mockRippled - ) => { + it("returns true when there is another page", async function () { + this.mockRippled.addResponse("ledger_data", rippled.ledger_data.first_page); + const response = await this.client.request({ command: "ledger_data" }); + assert(this.client.hasNextPage(response)); + }); + + it("returns false when there are no more pages", async function () { const rippledResponse = function (request: Request): object { if ("marker" in request) { return rippled.ledger_data.last_page; } return rippled.ledger_data.first_page; }; - mockRippled.addResponse("ledger_data", rippledResponse); - const response = await client.request({ command: "ledger_data" }); - const responseNextPage = await client.requestNextPage( + this.mockRippled.addResponse("ledger_data", rippledResponse); + const response = await this.client.request({ command: "ledger_data" }); + const responseNextPage = await this.client.requestNextPage( { command: "ledger_data" }, response ); - assert(!client.hasNextPage(responseNextPage)); - }, -}; + assert(!this.client.hasNextPage(responseNextPage)); + }); +}); diff --git a/test/client/isConnected.ts b/test/client/isConnected.ts index 22b41fe8..e9925e33 100644 --- a/test/client/isConnected.ts +++ b/test/client/isConnected.ts @@ -1,16 +1,14 @@ import { assert } from "chai"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "disconnect & isConnected": async (client, address) => { - assert.strictEqual(client.isConnected(), true); - await client.disconnect(); - assert.strictEqual(client.isConnected(), false); - }, -}; +describe("client.isConnected", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + it("disconnect & isConnected", async function () { + assert.strictEqual(this.client.isConnected(), true); + await this.client.disconnect(); + assert.strictEqual(this.client.isConnected(), false); + }); +}); diff --git a/test/client/isValidAddress.ts b/test/client/isValidAddress.ts index 8a92678c..0134dbe8 100644 --- a/test/client/isValidAddress.ts +++ b/test/client/isValidAddress.ts @@ -1,18 +1,21 @@ import { assert } from "chai"; import addresses from "../fixtures/addresses.json"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; -export default { - "returns true for valid address": async (client, address) => { - assert(client.isValidAddress("rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K")); - assert(client.isValidAddress(addresses.ACCOUNT_X)); - assert(client.isValidAddress(addresses.ACCOUNT_T)); - }, +describe("isValidAddress", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "returns false for invalid address": async (client, address) => { - assert(!client.isValidAddress("foobar")); - assert(!client.isValidAddress(addresses.ACCOUNT_X.slice(0, -1))); - assert(!client.isValidAddress(addresses.ACCOUNT_T.slice(1))); - }, -}; + it("returns true for valid address", async function () { + assert(this.client.isValidAddress("rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K")); + assert(this.client.isValidAddress(addresses.ACCOUNT_X)); + assert(this.client.isValidAddress(addresses.ACCOUNT_T)); + }); + + it("returns false for invalid address", async function () { + assert(!this.client.isValidAddress("foobar")); + assert(!this.client.isValidAddress(addresses.ACCOUNT_X.slice(0, -1))); + assert(!this.client.isValidAddress(addresses.ACCOUNT_T.slice(1))); + }); +}); diff --git a/test/client/isValidSecret.ts b/test/client/isValidSecret.ts index f029cb5d..2d727be1 100644 --- a/test/client/isValidSecret.ts +++ b/test/client/isValidSecret.ts @@ -1,13 +1,16 @@ import { assert } from "chai"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; -export default { - "returns true for valid secret": async (client, address) => { - assert(client.isValidSecret("snsakdSrZSLkYpCXxfRkS4Sh96PMK")); - }, +describe("isValidSecret", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "returns false for invalid secret": async (client, address) => { - assert(!client.isValidSecret("foobar")); - }, -}; + it("returns true for valid secret", async function () { + assert(this.client.isValidSecret("snsakdSrZSLkYpCXxfRkS4Sh96PMK")); + }); + + it("returns false for invalid secret", async function () { + assert(!this.client.isValidSecret("foobar")); + }); +}); diff --git a/test/client/prepareCheckCancel.ts b/test/client/prepareCheckCancel.ts index 99743b7b..b55e674c 100644 --- a/test/client/prepareCheckCancel.ts +++ b/test/client/prepareCheckCancel.ts @@ -1,43 +1,60 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareCheckCancel(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareCheckCancel( - address, - requests.prepareCheckCancel.normal - ); - assertResultMatch(result, responses.prepareCheckCancel.normal, "prepare"); - }, +describe("client.prepareCheckCancel", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareCheckCancel( - address, - requests.prepareCheckCancel.normal, - localInstructions - ); - assertResultMatch(result, responses.prepareCheckCancel.ticket, "prepare"); - }, -}; + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareCheckCancel", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareCheckCancel( + test.address, + requests.prepareCheckCancel.normal + ); + assertResultMatch( + result, + responses.prepareCheckCancel.normal, + "prepare" + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareCheckCancel( + test.address, + requests.prepareCheckCancel.normal, + localInstructions + ); + assertResultMatch( + result, + responses.prepareCheckCancel.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareCheckCash.ts b/test/client/prepareCheckCash.ts index 88a50c53..bfa1bec2 100644 --- a/test/client/prepareCheckCash.ts +++ b/test/client/prepareCheckCash.ts @@ -1,55 +1,71 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "prepareCheckCash amount": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareCheckCash( - address, - requests.prepareCheckCash.amount - ); - assertResultMatch(result, responses.prepareCheckCash.amount, "prepare"); - }, +describe("client.prepareCheckCash", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "prepareCheckCash deliverMin": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareCheckCash( - address, - requests.prepareCheckCash.deliverMin - ); - assertResultMatch(result, responses.prepareCheckCash.deliverMin, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareCheckCash amount", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareCheckCash( + test.address, + requests.prepareCheckCash.amount + ); + assertResultMatch(result, responses.prepareCheckCash.amount, "prepare"); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareCheckCash( - address, - requests.prepareCheckCash.amount, - localInstructions - ); - assertResultMatch(result, responses.prepareCheckCash.ticket, "prepare"); - }, -}; + it("prepareCheckCash deliverMin", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareCheckCash( + test.address, + requests.prepareCheckCash.deliverMin + ); + assertResultMatch( + result, + responses.prepareCheckCash.deliverMin, + "prepare" + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareCheckCash( + test.address, + requests.prepareCheckCash.amount, + localInstructions + ); + assertResultMatch(result, responses.prepareCheckCash.ticket, "prepare"); + }); + }); + }); +}); diff --git a/test/client/prepareCheckCreate.ts b/test/client/prepareCheckCreate.ts index e498c630..e74b60aa 100644 --- a/test/client/prepareCheckCreate.ts +++ b/test/client/prepareCheckCreate.ts @@ -1,60 +1,80 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareCheckCreate(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const result = await client.prepareCheckCreate( - address, - requests.prepareCheckCreate.normal, - localInstructions - ); - assertResultMatch(result, responses.prepareCheckCreate.normal, "prepare"); - }, +describe("client.prepareCheckCreate", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "prepareCheckCreate full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareCheckCreate( - address, - requests.prepareCheckCreate.full - ); - assertResultMatch(result, responses.prepareCheckCreate.full, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareCheckCreate", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const result = await this.client.prepareCheckCreate( + test.address, + requests.prepareCheckCreate.normal, + localInstructions + ); + assertResultMatch( + result, + responses.prepareCheckCreate.normal, + "prepare" + ); + }); - "prepareCheckCreate with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareCheckCreate( - address, - requests.prepareCheckCreate.normal, - localInstructions - ); - assertResultMatch(result, responses.prepareCheckCreate.ticket, "prepare"); - }, -}; + it("prepareCheckCreate full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareCheckCreate( + test.address, + requests.prepareCheckCreate.full + ); + assertResultMatch(result, responses.prepareCheckCreate.full, "prepare"); + }); + + it("prepareCheckCreate with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareCheckCreate( + test.address, + requests.prepareCheckCreate.normal, + localInstructions + ); + assertResultMatch( + result, + responses.prepareCheckCreate.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareEscrowCancellation.ts b/test/client/prepareEscrowCancellation.ts index adec389c..da51b998 100644 --- a/test/client/prepareEscrowCancellation.ts +++ b/test/client/prepareEscrowCancellation.ts @@ -1,72 +1,80 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareEscrowCancellation(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareEscrowCancellation( - address, - requests.prepareEscrowCancellation.normal, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - result, - responses.prepareEscrowCancellation.normal, - "prepare" - ); - }, +describe("client.prepareEscrowCancellation", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "prepareEscrowCancellation with memos": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareEscrowCancellation( - address, - requests.prepareEscrowCancellation.memos - ); - assertResultMatch( - result, - responses.prepareEscrowCancellation.memos, - "prepare" - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareEscrowCancellation", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareEscrowCancellation( + test.address, + requests.prepareEscrowCancellation.normal, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + result, + responses.prepareEscrowCancellation.normal, + "prepare" + ); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareEscrowCancellation( - address, - requests.prepareEscrowCancellation.normal, - localInstructions - ); - assertResultMatch( - result, - responses.prepareEscrowCancellation.ticket, - "prepare" - ); - }, -}; + it("prepareEscrowCancellation with memos", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareEscrowCancellation( + test.address, + requests.prepareEscrowCancellation.memos + ); + assertResultMatch( + result, + responses.prepareEscrowCancellation.memos, + "prepare" + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareEscrowCancellation( + test.address, + requests.prepareEscrowCancellation.normal, + localInstructions + ); + assertResultMatch( + result, + responses.prepareEscrowCancellation.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareEscrowCreation.ts b/test/client/prepareEscrowCreation.ts index 62f6a0cd..846c33d1 100644 --- a/test/client/prepareEscrowCreation.ts +++ b/test/client/prepareEscrowCreation.ts @@ -1,7 +1,9 @@ +import addresses from "../fixtures/addresses.json"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects, assertResultMatch } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; @@ -12,23 +14,21 @@ export const config = { skipXAddress: true, }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareEscrowCreation(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); +describe("client.prepareEscrowCreation", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + it("prepareEscrowCreation", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; - const result = await client.prepareEscrowCreation( - address, + const result = await this.client.prepareEscrowCreation( + addresses.ACCOUNT, requests.prepareEscrowCreation.normal, localInstructions ); @@ -37,46 +37,46 @@ export default { responses.prepareEscrowCreation.normal, "prepare" ); - }, + }); - "prepareEscrowCreation full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareEscrowCreation( - address, + it("prepareEscrowCreation full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const result = await this.client.prepareEscrowCreation( + addresses.ACCOUNT, requests.prepareEscrowCreation.full ); assertResultMatch(result, responses.prepareEscrowCreation.full, "prepare"); - }, + }); - "prepareEscrowCreation - invalid": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("prepareEscrowCreation - invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const escrow = { ...requests.prepareEscrowCreation.full }; delete escrow.amount; // Make invalid await assertRejects( - client.prepareEscrowCreation(address, escrow), - client.errors.ValidationError, + this.client.prepareEscrowCreation(addresses.ACCOUNT, escrow), + this.client.errors.ValidationError, 'instance.escrowCreation requires property "amount"' ); - }, + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000396", ticketSequence: 23, }; - const result = await client.prepareEscrowCreation( - address, + const result = await this.client.prepareEscrowCreation( + addresses.ACCOUNT, requests.prepareEscrowCreation.normal, localInstructions ); @@ -85,5 +85,5 @@ export default { responses.prepareEscrowCreation.ticket, "prepare" ); - }, -}; + }); +}); diff --git a/test/client/prepareEscrowExecution.ts b/test/client/prepareEscrowExecution.ts index 15406c6d..ea5570f9 100644 --- a/test/client/prepareEscrowExecution.ts +++ b/test/client/prepareEscrowExecution.ts @@ -1,108 +1,118 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { TestSuite, assertRejects, assertResultMatch } from "../testUtils"; +import setupClient from "../setupClient"; +import { addressTests, assertRejects, assertResultMatch } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareEscrowExecution(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareEscrowExecution( - address, - requests.prepareEscrowExecution.normal, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - result, - responses.prepareEscrowExecution.normal, - "prepare" - ); - }, +describe("client.prepareEscrowExecution", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "prepareEscrowExecution - simple": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareEscrowExecution( - address, - requests.prepareEscrowExecution.simple - ); - assertResultMatch( - result, - responses.prepareEscrowExecution.simple, - "prepare" - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareEscrowExecution", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareEscrowExecution( + test.address, + requests.prepareEscrowExecution.normal, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + result, + responses.prepareEscrowExecution.normal, + "prepare" + ); + }); - "prepareEscrowExecution - no condition": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - await assertRejects( - client.prepareEscrowExecution( - address, - requests.prepareEscrowExecution.noCondition, - instructionsWithMaxLedgerVersionOffset - ), - client.errors.ValidationError, - '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' - ); - }, + it("prepareEscrowExecution - simple", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareEscrowExecution( + test.address, + requests.prepareEscrowExecution.simple + ); + assertResultMatch( + result, + responses.prepareEscrowExecution.simple, + "prepare" + ); + }); - "prepareEscrowExecution - no fulfillment": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - await assertRejects( - client.prepareEscrowExecution( - address, - requests.prepareEscrowExecution.noFulfillment, - instructionsWithMaxLedgerVersionOffset - ), - client.errors.ValidationError, - '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' - ); - }, + it("prepareEscrowExecution - no condition", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + await assertRejects( + this.client.prepareEscrowExecution( + test.address, + requests.prepareEscrowExecution.noCondition, + instructionsWithMaxLedgerVersionOffset + ), + this.client.errors.ValidationError, + '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' + ); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000396", - ticketSequence: 23, - }; - const result = await client.prepareEscrowExecution( - address, - requests.prepareEscrowExecution.normal, - localInstructions - ); - assertResultMatch( - result, - responses.prepareEscrowExecution.ticket, - "prepare" - ); - }, -}; + it("prepareEscrowExecution - no fulfillment", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + await assertRejects( + this.client.prepareEscrowExecution( + test.address, + requests.prepareEscrowExecution.noFulfillment, + instructionsWithMaxLedgerVersionOffset + ), + this.client.errors.ValidationError, + '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.' + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000396", + ticketSequence: 23, + }; + const result = await this.client.prepareEscrowExecution( + test.address, + requests.prepareEscrowExecution.normal, + localInstructions + ); + assertResultMatch( + result, + responses.prepareEscrowExecution.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareOrder.ts b/test/client/prepareOrder.ts index 1f899172..40d76167 100644 --- a/test/client/prepareOrder.ts +++ b/test/client/prepareOrder.ts @@ -1,89 +1,107 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects, assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "buy order": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrder.buy; - const result = await client.prepareOrder(address, request); - assertResultMatch(result, responses.prepareOrder.buy, "prepare"); - }, +describe("client.prepareOrder", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "buy order with expiration": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrder.expiration; - const response = responses.prepareOrder.expiration; - const result = await client.prepareOrder( - address, - request, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(result, response, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("buy order", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrder.buy; + const result = await this.client.prepareOrder(test.address, request); + assertResultMatch(result, responses.prepareOrder.buy, "prepare"); + }); - "sell order": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrder.sell; - const result = await client.prepareOrder( - address, - request, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(result, responses.prepareOrder.sell, "prepare"); - }, + it("buy order with expiration", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrder.expiration; + const response = responses.prepareOrder.expiration; + const result = await this.client.prepareOrder( + test.address, + request, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(result, response, "prepare"); + }); - async invalid(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = { ...requests.prepareOrder.sell }; - delete request.direction; // Make invalid - await assertRejects( - client.prepareOrder( - address, - request, - instructionsWithMaxLedgerVersionOffset - ), - client.errors.ValidationError, - 'instance.order requires property "direction"' - ); - }, + it("sell order", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrder.sell; + const result = await this.client.prepareOrder( + test.address, + request, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(result, responses.prepareOrder.sell, "prepare"); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrder.sell; - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareOrder( - address, - request, - localInstructions - ); - assertResultMatch(result, responses.prepareOrder.ticket, "prepare"); - }, -}; + it("invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = { ...requests.prepareOrder.sell }; + delete request.direction; // Make invalid + await assertRejects( + this.client.prepareOrder( + test.address, + request, + instructionsWithMaxLedgerVersionOffset + ), + this.client.errors.ValidationError, + 'instance.order requires property "direction"' + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrder.sell; + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareOrder( + test.address, + request, + localInstructions + ); + assertResultMatch(result, responses.prepareOrder.ticket, "prepare"); + }); + }); + }); +}); diff --git a/test/client/prepareOrderCancellation.ts b/test/client/prepareOrderCancellation.ts index 7827e290..71bf075d 100644 --- a/test/client/prepareOrderCancellation.ts +++ b/test/client/prepareOrderCancellation.ts @@ -1,99 +1,123 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects, assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async prepareOrderCancellation(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrderCancellation.simple; - const result = await client.prepareOrderCancellation( - address, - request, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - result, - responses.prepareOrderCancellation.normal, - "prepare" - ); - }, +describe("client.prepareOrderCancellation", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "no instructions": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrderCancellation.simple; - const result = await client.prepareOrderCancellation(address, request); - assertResultMatch( - result, - responses.prepareOrderCancellation.noInstructions, - "prepare" - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("prepareOrderCancellation", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrderCancellation.simple; + const result = await this.client.prepareOrderCancellation( + test.address, + request, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + result, + responses.prepareOrderCancellation.normal, + "prepare" + ); + }); - "with memos": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrderCancellation.withMemos; - const result = await client.prepareOrderCancellation(address, request); - assertResultMatch( - result, - responses.prepareOrderCancellation.withMemos, - "prepare" - ); - }, + it("no instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrderCancellation.simple; + const result = await this.client.prepareOrderCancellation( + test.address, + request + ); + assertResultMatch( + result, + responses.prepareOrderCancellation.noInstructions, + "prepare" + ); + }); - async invalid(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = { - ...requests.prepareOrderCancellation.withMemos, - }; - delete request.orderSequence; // Make invalid + it("with memos", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrderCancellation.withMemos; + const result = await this.client.prepareOrderCancellation( + test.address, + request + ); + assertResultMatch( + result, + responses.prepareOrderCancellation.withMemos, + "prepare" + ); + }); - await assertRejects( - client.prepareOrderCancellation(address, request), - client.errors.ValidationError, - 'instance.orderCancellation requires property "orderSequence"' - ); - }, + it("invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = { + ...requests.prepareOrderCancellation.withMemos, + }; + delete request.orderSequence; // Make invalid - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const request = requests.prepareOrderCancellation.simple; - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareOrderCancellation( - address, - request, - localInstructions - ); - assertResultMatch( - result, - responses.prepareOrderCancellation.ticket, - "prepare" - ); - }, -}; + await assertRejects( + this.client.prepareOrderCancellation(test.address, request), + this.client.errors.ValidationError, + 'instance.orderCancellation requires property "orderSequence"' + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const request = requests.prepareOrderCancellation.simple; + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareOrderCancellation( + test.address, + request, + localInstructions + ); + assertResultMatch( + result, + responses.prepareOrderCancellation.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/preparePayment.ts b/test/client/preparePayment.ts index d0883286..95c9e59a 100644 --- a/test/client/preparePayment.ts +++ b/test/client/preparePayment.ts @@ -3,608 +3,669 @@ import { ValidationError } from "xrpl-local/common/errors"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite, assertRejects } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests, assertRejects } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const { preparePayment: REQUEST_FIXTURES } = requests; const { preparePayment: RESPONSE_FIXTURES } = responses; const RECIPIENT_ADDRESS = "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async normal(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.normal, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare"); - }, +describe("client.preparePayment", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "min amount xrp": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.minAmountXRP, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.minAmountXRP, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("normal", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.normal, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare"); + }); - "min amount xrp2xrp": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.minAmount, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, RESPONSE_FIXTURES.minAmountXRPXRP, "prepare"); - }, + it("min amount xrp", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.minAmountXRP, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.minAmountXRP, "prepare"); + }); - "XRP to XRP": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - maxAmount: { value: "1", currency: "XRP" }, - }, - destination: { - address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - amount: { value: "1", currency: "XRP" }, - }, - }; - const expected = { - txJSON: - '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', - instructions: { - fee: "0.000012", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - payment, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expected, "prepare"); - }, + it("min amount xrp2xrp", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.minAmount, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + RESPONSE_FIXTURES.minAmountXRPXRP, + "prepare" + ); + }); - "XRP drops to XRP drops": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - maxAmount: { value: "1000000", currency: "drops" }, - }, - destination: { - address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - amount: { value: "1000000", currency: "drops" }, - }, - }; - const expected = { - txJSON: - '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', - instructions: { - fee: "0.000012", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - payment, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expected, "prepare"); - }, + it("XRP to XRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + maxAmount: { value: "1", currency: "XRP" }, + }, + destination: { + address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + amount: { value: "1", currency: "XRP" }, + }, + }; + const expected = { + txJSON: + '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', + instructions: { + fee: "0.000012", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + payment, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expected, "prepare"); + }); - "XRP drops to XRP": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - maxAmount: { value: "1000000", currency: "drops" }, - }, - destination: { - address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - amount: { value: "1", currency: "XRP" }, - }, - }; - const expected = { - txJSON: - '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', - instructions: { - fee: "0.000012", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - payment, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expected, "prepare"); - }, + it("XRP drops to XRP drops", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + maxAmount: { value: "1000000", currency: "drops" }, + }, + destination: { + address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + amount: { value: "1000000", currency: "drops" }, + }, + }; + const expected = { + txJSON: + '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', + instructions: { + fee: "0.000012", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + payment, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expected, "prepare"); + }); - "XRP to XRP drops": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - maxAmount: { value: "1", currency: "XRP" }, - }, - destination: { - address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - amount: { value: "1000000", currency: "drops" }, - }, - }; - const expected = { - txJSON: - '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', - instructions: { - fee: "0.000012", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - payment, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expected, "prepare"); - }, + it("XRP drops to XRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + maxAmount: { value: "1000000", currency: "drops" }, + }, + destination: { + address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + amount: { value: "1", currency: "XRP" }, + }, + }; + const expected = { + txJSON: + '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', + instructions: { + fee: "0.000012", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + payment, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expected, "prepare"); + }); - // Errors - "rejects promise and does not throw when payment object is invalid": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address, - // instead of `maxAmount` - amount: { value: "1000", currency: "drops" }, - }, - destination: { - address: RECIPIENT_ADDRESS, - amount: { value: "1000", currency: "drops" }, - }, - }; + it("XRP to XRP drops", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + maxAmount: { value: "1", currency: "XRP" }, + }, + destination: { + address: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + amount: { value: "1000000", currency: "drops" }, + }, + }; + const expected = { + txJSON: + '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":"1000000","Flags":2147483648,"LastLedgerSequence":8820051,"Sequence":23,"Fee":"12"}', + instructions: { + fee: "0.000012", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + payment, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expected, "prepare"); + }); - return assertRejects( - client.preparePayment(address, payment), - ValidationError, - "payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)" - ); - }, + // Errors + it("rejects promise and does not throw when payment object is invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: test.address, + // instead of `maxAmount` + amount: { value: "1000", currency: "drops" }, + }, + destination: { + address: RECIPIENT_ADDRESS, + amount: { value: "1000", currency: "drops" }, + }, + }; - "rejects promise and does not throw when field is missing": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - // Marking as "any" to get around the fact that TS won't allow this. - const payment: any = { - source: { address }, - destination: { - address: RECIPIENT_ADDRESS, - amount: { value: "1000", currency: "drops" }, - }, - }; + return assertRejects( + this.client.preparePayment(test.address, payment), + ValidationError, + "payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)" + ); + }); - return assertRejects( - client.preparePayment(address, payment), - ValidationError, - "instance.payment.source is not exactly one from ," - ); - }, + it("rejects promise and does not throw when field is missing", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + // Marking as "any" to get around the fact that TS won't allow this. + const payment: any = { + source: { address: test.address }, + destination: { + address: RECIPIENT_ADDRESS, + amount: { value: "1000", currency: "drops" }, + }, + }; - "rejects promise and does not throw when fee exceeds maxFeeXRP": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = { - source: { - address, - maxAmount: { value: "1000", currency: "drops" }, - }, - destination: { - address: RECIPIENT_ADDRESS, - amount: { value: "1000", currency: "drops" }, - }, - }; - return assertRejects( - client.preparePayment(address, payment, { fee: "3" }), - ValidationError, - "Fee of 3 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the Client constructor." - ); - }, + return assertRejects( + this.client.preparePayment(test.address, payment), + ValidationError, + "instance.payment.source is not exactly one from ," + ); + }); - "XRP to XRP no partial": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - return assertRejects( - client.preparePayment(address, REQUEST_FIXTURES.wrongPartial), - ValidationError, - "XRP to XRP payments cannot be partial payments" - ); - }, + it("rejects promise and does not throw when fee exceeds maxFeeXRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = { + source: { + address: test.address, + maxAmount: { value: "1000", currency: "drops" }, + }, + destination: { + address: RECIPIENT_ADDRESS, + amount: { value: "1000", currency: "drops" }, + }, + }; + return assertRejects( + this.client.preparePayment(test.address, payment, { fee: "3" }), + ValidationError, + "Fee of 3 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the Client constructor." + ); + }); - "address must match payment.source.address": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - return assertRejects( - client.preparePayment(address, REQUEST_FIXTURES.wrongAddress), - ValidationError, - "address must match payment.source.address" - ); - }, + it("XRP to XRP no partial", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + return assertRejects( + this.client.preparePayment( + test.address, + REQUEST_FIXTURES.wrongPartial + ), + ValidationError, + "XRP to XRP payments cannot be partial payments" + ); + }); - "wrong amount": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - return assertRejects( - client.preparePayment(address, REQUEST_FIXTURES.wrongAmount), - ValidationError, - "payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)" - ); - }, + it("address must match payment.source.address", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + return assertRejects( + this.client.preparePayment( + test.address, + REQUEST_FIXTURES.wrongAddress + ), + ValidationError, + "address must match payment.source.address" + ); + }); - "throws when fee exceeds 2 XRP": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - fee: "2.1", - }; - return assertRejects( - client.preparePayment( - address, - REQUEST_FIXTURES.normal, - localInstructions - ), - ValidationError, - "Fee of 2.1 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the Client constructor." - ); - }, + it("wrong amount", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + return assertRejects( + this.client.preparePayment( + test.address, + REQUEST_FIXTURES.wrongAmount + ), + ValidationError, + "payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)" + ); + }); - // 'preparePayment with all options specified': async (client, address) => { - // const ledgerResponse = await client.request({command: 'ledger', ledger_index: 'validated'}) - // const version = ledgerResponse.result.ledger_index - // const localInstructions = { - // maxLedgerVersion: version + 100, - // fee: '0.000012' - // } - // const response = await client.preparePayment( - // address, - // REQUEST_FIXTURES.allOptions, - // localInstructions - // ) - // assertResultMatch(response, RESPONSE_FIXTURES.allOptions, 'prepare') - // }, + it("throws when fee exceeds 2 XRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + fee: "2.1", + }; + return assertRejects( + this.client.preparePayment( + test.address, + REQUEST_FIXTURES.normal, + localInstructions + ), + ValidationError, + "Fee of 2.1 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the Client constructor." + ); + }); - "preparePayment without counterparty set": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - sequence: 23, - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.noCounterparty, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.noCounterparty, "prepare"); - }, + // 'preparePayment with all options specified': async (client, test.address) => { + // const ledgerResponse = await this.client.request({command: 'ledger', ledger_index: 'validated'}) + // const version = ledgerResponse.result.ledger_index + // const localInstructions = { + // maxLedgerVersion: version + 100, + // fee: '0.000012' + // } + // const response = await this.client.preparePayment( + // test.address, + // REQUEST_FIXTURES.allOptions, + // localInstructions + // ) + // assertResultMatch(response, RESPONSE_FIXTURES.allOptions, 'prepare') + // }, - "preparePayment with source.amount/destination.minAmount can be signed": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - // See also: 'sign succeeds with source.amount/destination.minAmount' + it("preparePayment without counterparty set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + sequence: 23, + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.noCounterparty, + localInstructions + ); + assertResultMatch( + response, + RESPONSE_FIXTURES.noCounterparty, + "prepare" + ); + }); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - sequence: 23, - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.noCounterparty, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.noCounterparty, "prepare"); - }, + it("preparePayment with source.amount/destination.minAmount can be signed", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + // See also: 'sign succeeds with source.amount/destination.minAmount' - "destination.minAmount": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const response = await client.preparePayment( - address, - responses.getPaths.sendAll[0], - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, RESPONSE_FIXTURES.minAmount, "prepare"); - }, + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + sequence: 23, + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.noCounterparty, + localInstructions + ); + assertResultMatch( + response, + RESPONSE_FIXTURES.noCounterparty, + "prepare" + ); + }); - "caps fee at 2 XRP by default": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', - instructions: { - fee: "2", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.normal, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + it("destination.minAmount", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const response = await this.client.preparePayment( + test.address, + responses.getPaths.sendAll[0], + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, RESPONSE_FIXTURES.minAmount, "prepare"); + }); - "allows fee exceeding 2 XRP when maxFeeXRP is higher": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._maxFeeXRP = "2.2"; - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - fee: "2.1", - }; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2100000","Sequence":23}', - instructions: { - fee: "2.1", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - REQUEST_FIXTURES.normal, - localInstructions - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + it("caps fee at 2 XRP by default", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.client._feeCushion = 1000000; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', + instructions: { + fee: "2", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.normal, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - "fee - default maxFee of 2 XRP": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', - instructions: { - fee: "2", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - requests.preparePayment.normal, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + it("allows fee exceeding 2 XRP when maxFeeXRP is higher", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.client._maxFeeXRP = "2.2"; + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + fee: "2.1", + }; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2100000","Sequence":23}', + instructions: { + fee: "2.1", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + REQUEST_FIXTURES.normal, + localInstructions + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - "fee - capped to maxFeeXRP when maxFee exceeds maxFeeXRP": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - client._maxFeeXRP = "3"; - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "4", - }; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"3000000","Sequence":23}', - instructions: { - fee: "3", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - requests.preparePayment.normal, - localInstructions - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + it("fee - default maxFee of 2 XRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.client._feeCushion = 1000000; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', + instructions: { + fee: "2", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + requests.preparePayment.normal, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - "fee - capped to maxFee": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - client._maxFeeXRP = "5"; - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "4", - }; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"4000000","Sequence":23}', - instructions: { - fee: "4", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.preparePayment( - address, - requests.preparePayment.normal, - localInstructions - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + it("fee - capped to maxFeeXRP when maxFee exceeds maxFeeXRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.client._feeCushion = 1000000; + this.client._maxFeeXRP = "3"; + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "4", + }; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"3000000","Sequence":23}', + instructions: { + fee: "3", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + requests.preparePayment.normal, + localInstructions + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - // 'fee - calculated fee does not use more than 6 decimal places': async ( - // client, - // address - // ) => { - // client.connection.request({ - // command: 'config', - // data: {loadFactor: 5407.96875} - // }) - // const expectedResponse = { - // txJSON: - // '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"64896","Sequence":23}', - // instructions: { - // fee: '0.064896', - // sequence: 23, - // maxLedgerVersion: 8820051 - // } - // } - // const response = await client.preparePayment( - // address, - // requests.preparePayment.normal, - // instructionsWithMaxLedgerVersionOffset - // ) - // assertResultMatch(response, expectedResponse, 'prepare') - // }, + it("fee - capped to maxFee", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + this.client._feeCushion = 1000000; + this.client._maxFeeXRP = "5"; + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "4", + }; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"4000000","Sequence":23}', + instructions: { + fee: "4", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + const response = await this.client.preparePayment( + test.address, + requests.preparePayment.normal, + localInstructions + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - // Tickets - // 'preparePayment with ticketSequence': async (client, address) => { - // const ledgerResponse = await client.request({ - // command: 'ledger', - // ledger_index: 'validated' - // }) - // const version = ledgerResponse.result.ledger_index - // const localInstructions = { - // maxLedgerVersion: version + 100, - // fee: '0.000012', - // ticketSequence: 23 - // } - // const response = await client.preparePayment( - // address, - // REQUEST_FIXTURES.allOptions, - // localInstructions - // ) - // assertResultMatch(response, RESPONSE_FIXTURES.ticketSequence, 'prepare') - // }, + // 'fee - calculated fee does not use more than 6 decimal places': async ( + // client, + // test.address + // ) => { + // this.client.connection.request({ + // command: 'config', + // data: {loadFactor: 5407.96875} + // }) + // const expectedResponse = { + // txJSON: + // '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"64896","Sequence":23}', + // instructions: { + // fee: '0.064896', + // sequence: 23, + // maxLedgerVersion: 8820051 + // } + // } + // const response = await this.client.preparePayment( + // test.address, + // requests.preparePayment.normal, + // instructionsWithMaxLedgerVersionOffset + // ) + // assertResultMatch(response, expectedResponse, 'prepare') + // }, - // 'throws when both sequence and ticketSequence are set': async ( - // client, - // address - // ) => { - // const ledgerResponse = await client.request({ - // command: 'ledger', - // ledger_index: 'validated' - // }) - // const version = ledgerResponse.result.ledger_index - // const localInstructions = { - // maxLedgerVersion: version + 100, - // fee: '0.000012', - // ticketSequence: 23, - // sequence: 12 - // } - // return assertRejects( - // client.preparePayment( - // address, - // REQUEST_FIXTURES.allOptions, - // localInstructions - // ), - // ValidationError, - // 'instance.instructions is of prohibited type [object Object]' - // ) - // } -}; + // Tickets + // 'preparePayment with ticketSequence': async (client, test.address) => { + // const ledgerResponse = await this.client.request({ + // command: 'ledger', + // ledger_index: 'validated' + // }) + // const version = ledgerResponse.result.ledger_index + // const localInstructions = { + // maxLedgerVersion: version + 100, + // fee: '0.000012', + // ticketSequence: 23 + // } + // const response = await this.client.preparePayment( + // test.address, + // REQUEST_FIXTURES.allOptions, + // localInstructions + // ) + // assertResultMatch(response, RESPONSE_FIXTURES.ticketSequence, 'prepare') + // }, + + // 'throws when both sequence and ticketSequence are set': async ( + // client, + // test.address + // ) => { + // const ledgerResponse = await this.client.request({ + // command: 'ledger', + // ledger_index: 'validated' + // }) + // const version = ledgerResponse.result.ledger_index + // const localInstructions = { + // maxLedgerVersion: version + 100, + // fee: '0.000012', + // ticketSequence: 23, + // sequence: 12 + // } + // return assertRejects( + // this.client.preparePayment( + // test.address, + // REQUEST_FIXTURES.allOptions, + // localInstructions + // ), + // ValidationError, + // 'instance.instructions is of prohibited type [object Object]' + // ) + // } + }); + }); +}); diff --git a/test/client/preparePaymentChannelClaim.ts b/test/client/preparePaymentChannelClaim.ts index 7999236c..8f78ee99 100644 --- a/test/client/preparePaymentChannelClaim.ts +++ b/test/client/preparePaymentChannelClaim.ts @@ -3,140 +3,153 @@ import { assert } from "chai"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; const { preparePaymentChannelClaim: REQUEST_FIXTURES } = requests; const { preparePaymentChannelClaim: RESPONSE_FIXTURES } = responses; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async default(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const response = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.normal, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare"); - }, +describe("client.preparePaymentChannelClaim", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "with renew": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const response = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.renew, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.renew, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("default", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const response = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.normal, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare"); + }); - "with close": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const response = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.close, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.close, "prepare"); - }, + it("with renew", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const response = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.renew, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.renew, "prepare"); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const response = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.normal, - localInstructions - ); - assertResultMatch(response, RESPONSE_FIXTURES.ticket, "prepare"); - }, + it("with close", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const response = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.close, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.close, "prepare"); + }); - "rejects Promise on preparePaymentChannelClaim with renew and close": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - try { - const prepared = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.full - ); - throw new Error( - `Expected method to reject. Prepared transaction: ${JSON.stringify( - prepared - )}` - ); - } catch (err) { - assert.strictEqual(err.name, "ValidationError"); - assert.strictEqual( - err.message, - '"renew" and "close" flags on PaymentChannelClaim are mutually exclusive' - ); - } - }, + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const response = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.normal, + localInstructions + ); + assertResultMatch(response, RESPONSE_FIXTURES.ticket, "prepare"); + }); - "rejects Promise on preparePaymentChannelClaim with no signature": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - try { - const prepared = await client.preparePaymentChannelClaim( - address, - REQUEST_FIXTURES.noSignature - ); - throw new Error( - `Expected method to reject. Prepared transaction: ${JSON.stringify( - prepared - )}` - ); - } catch (err) { - assert.strictEqual(err.name, "ValidationError"); - assert.strictEqual( - err.message, - '"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.' - ); - } - }, -}; + it("rejects Promise on preparePaymentChannelClaim with renew and close", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + try { + const prepared = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.full + ); + throw new Error( + `Expected method to reject. Prepared transaction: ${JSON.stringify( + prepared + )}` + ); + } catch (err) { + assert.strictEqual(err.name, "ValidationError"); + assert.strictEqual( + err.message, + '"renew" and "close" flags on PaymentChannelClaim are mutually exclusive' + ); + } + }); + + it("rejects Promise on preparePaymentChannelClaim with no signature", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + try { + const prepared = await this.client.preparePaymentChannelClaim( + test.address, + REQUEST_FIXTURES.noSignature + ); + throw new Error( + `Expected method to reject. Prepared transaction: ${JSON.stringify( + prepared + )}` + ); + } catch (err) { + assert.strictEqual(err.name, "ValidationError"); + assert.strictEqual( + err.message, + '"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.' + ); + } + }); + }); + }); +}); diff --git a/test/client/preparePaymentChannelCreate.ts b/test/client/preparePaymentChannelCreate.ts index ac3163a3..72aef5d1 100644 --- a/test/client/preparePaymentChannelCreate.ts +++ b/test/client/preparePaymentChannelCreate.ts @@ -1,7 +1,9 @@ +import addresses from "../fixtures/addresses.json"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; @@ -12,23 +14,21 @@ export const config = { skipXAddress: true, }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async preparePaymentChannelCreate(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); +describe("client.preparePaymentChannelCreate", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + it("preparePaymentChannelCreate", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; - const result = await client.preparePaymentChannelCreate( - address, + const result = await this.client.preparePaymentChannelCreate( + addresses.ACCOUNT, requests.preparePaymentChannelCreate.normal, localInstructions ); @@ -37,15 +37,15 @@ export default { responses.preparePaymentChannelCreate.normal, "prepare" ); - }, + }); - "preparePaymentChannelCreate full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.preparePaymentChannelCreate( - address, + it("preparePaymentChannelCreate full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const result = await this.client.preparePaymentChannelCreate( + addresses.ACCOUNT, requests.preparePaymentChannelCreate.full ); assertResultMatch( @@ -53,24 +53,20 @@ export default { responses.preparePaymentChannelCreate.full, "prepare" ); - }, + }); - "preparePaymentChannelCreate with ticket": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("preparePaymentChannelCreate with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", ticketSequence: 23, }; - const result = await client.preparePaymentChannelCreate( - address, + const result = await this.client.preparePaymentChannelCreate( + addresses.ACCOUNT, requests.preparePaymentChannelCreate.normal, localInstructions ); @@ -79,5 +75,5 @@ export default { responses.preparePaymentChannelCreate.ticket, "prepare" ); - }, -}; + }); +}); diff --git a/test/client/preparePaymentChannelFund.ts b/test/client/preparePaymentChannelFund.ts index 8911341a..05fab95a 100644 --- a/test/client/preparePaymentChannelFund.ts +++ b/test/client/preparePaymentChannelFund.ts @@ -1,72 +1,84 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async preparePaymentChannelFund(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - }; - const result = await client.preparePaymentChannelFund( - address, - requests.preparePaymentChannelFund.normal, - localInstructions - ); - assertResultMatch( - result, - responses.preparePaymentChannelFund.normal, - "prepare" - ); - }, +describe("client.preparePaymentChannelFund", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "preparePaymentChannelFund full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.preparePaymentChannelFund( - address, - requests.preparePaymentChannelFund.full - ); - assertResultMatch( - result, - responses.preparePaymentChannelFund.full, - "prepare" - ); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("preparePaymentChannelFund", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + }; + const result = await this.client.preparePaymentChannelFund( + test.address, + requests.preparePaymentChannelFund.normal, + localInstructions + ); + assertResultMatch( + result, + responses.preparePaymentChannelFund.normal, + "prepare" + ); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.preparePaymentChannelFund( - address, - requests.preparePaymentChannelFund.normal, - localInstructions - ); - assertResultMatch( - result, - responses.preparePaymentChannelFund.ticket, - "prepare" - ); - }, -}; + it("preparePaymentChannelFund full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.preparePaymentChannelFund( + test.address, + requests.preparePaymentChannelFund.full + ); + assertResultMatch( + result, + responses.preparePaymentChannelFund.full, + "prepare" + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.preparePaymentChannelFund( + test.address, + requests.preparePaymentChannelFund.normal, + localInstructions + ); + assertResultMatch( + result, + responses.preparePaymentChannelFund.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareSettings.ts b/test/client/prepareSettings.ts index 08996ae4..2e730832 100644 --- a/test/client/prepareSettings.ts +++ b/test/client/prepareSettings.ts @@ -4,352 +4,432 @@ import { FormattedSettings } from "../../src/common/types/objects"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "simple test": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const response = await client.prepareSettings( - address, - requests.prepareSettings.domain, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, responses.prepareSettings.flags, "prepare"); - }, - "no maxLedgerVersion": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const response = await client.prepareSettings( - address, - requests.prepareSettings.domain, - { - maxLedgerVersion: null as unknown as undefined, - } - ); - assertResultMatch( - response, - responses.prepareSettings.noMaxLedgerVersion, - "prepare" - ); - }, - "no instructions": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const response = await client.prepareSettings( - address, - requests.prepareSettings.domain - ); - assertResultMatch( - response, - responses.prepareSettings.noInstructions, - "prepare" - ); - }, - async regularKey(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const regularKey = { regularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD" }; - const response = await client.prepareSettings( - address, - regularKey, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - response, - responses.prepareSettings.regularKey, - "prepare" - ); - }, - "remove regularKey": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const regularKey = { regularKey: null }; - const response = await client.prepareSettings( - address, - regularKey as unknown as FormattedSettings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - response, - responses.prepareSettings.removeRegularKey, - "prepare" - ); - }, - "flag set": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { requireDestinationTag: true }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, responses.prepareSettings.flagSet, "prepare"); - }, - "flag clear": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { requireDestinationTag: false }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, responses.prepareSettings.flagClear, "prepare"); - }, - "set depositAuth flag": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { depositAuth: true }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - response, - responses.prepareSettings.flagSetDepositAuth, - "prepare" - ); - }, - "clear depositAuth flag": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { depositAuth: false }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - response, - responses.prepareSettings.flagClearDepositAuth, - "prepare" - ); - }, - "integer field clear": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { transferRate: null }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assert(response); - assert.strictEqual(JSON.parse(response.txJSON).TransferRate, 0); - }, - "set transferRate": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = { transferRate: 1 }; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - response, - responses.prepareSettings.setTransferRate, - "prepare" - ); - }, - "set signers": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = requests.prepareSettings.signers.normal; - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(response, responses.prepareSettings.signers, "prepare"); - }, - "signers no threshold": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = requests.prepareSettings.signers.noThreshold; - try { - const response = await client.prepareSettings( - address, - settings, - instructionsWithMaxLedgerVersionOffset - ); - throw new Error( - `Expected method to reject. Prepared transaction: ${JSON.stringify( - response - )}` - ); - } catch (err) { - assert.strictEqual( - err.message, - 'instance.settings.signers requires property "threshold"' - ); - assert.strictEqual(err.name, "ValidationError"); - } - }, - "signers no weights": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = requests.prepareSettings.signers.noWeights; - const localInstructions = { - signersCount: 1, - ...instructionsWithMaxLedgerVersionOffset, - }; - const response = await client.prepareSettings( - address, - settings, - localInstructions - ); - assertResultMatch(response, responses.prepareSettings.noWeights, "prepare"); - }, - "fee for multisign": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - signersCount: 4, - ...instructionsWithMaxLedgerVersionOffset, - }; - const response = await client.prepareSettings( - address, - requests.prepareSettings.domain, - localInstructions - ); - assertResultMatch( - response, - responses.prepareSettings.flagsMultisign, - "prepare" - ); - }, - "no signer list": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const settings = requests.prepareSettings.noSignerEntries; - const localInstructions = { - signersCount: 1, - ...instructionsWithMaxLedgerVersionOffset, - }; - const response = await client.prepareSettings( - address, - settings, - localInstructions - ); - assertResultMatch( - response, - responses.prepareSettings.noSignerList, - "prepare" - ); - }, - async invalid(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - // domain must be a string - const settings = { ...requests.prepareSettings.domain, domain: 123 }; - const localInstructions = { - signersCount: 4, - ...instructionsWithMaxLedgerVersionOffset, - }; +describe("client.prepareSettings", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - try { - const response = await client.prepareSettings( - address, - settings, - localInstructions - ); - throw new Error( - `Expected method to reject. Prepared transaction: ${JSON.stringify( - response - )}` - ); - } catch (err) { - assert.strictEqual( - err.message, - "instance.settings.domain is not of a type(s) string" - ); - assert.strictEqual(err.name, "ValidationError"); - } - }, - async offline(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + addressTests.forEach(function (test) { + describe(test.type, function () { + it("simple test", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const response = await this.client.prepareSettings( + test.address, + requests.prepareSettings.domain, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(response, responses.prepareSettings.flags, "prepare"); + }); + it("no maxLedgerVersion", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const response = await this.client.prepareSettings( + test.address, + requests.prepareSettings.domain, + { + maxLedgerVersion: null as unknown as undefined, + } + ); + assertResultMatch( + response, + responses.prepareSettings.noMaxLedgerVersion, + "prepare" + ); + }); + it("no instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const response = await this.client.prepareSettings( + test.address, + requests.prepareSettings.domain + ); + assertResultMatch( + response, + responses.prepareSettings.noInstructions, + "prepare" + ); + }); + it("regularKey", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const regularKey = { regularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD" }; + const response = await this.client.prepareSettings( + test.address, + regularKey, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.regularKey, + "prepare" + ); + }); + it("remove regularKey", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const regularKey = { regularKey: null }; + const response = await this.client.prepareSettings( + test.address, + regularKey as unknown as FormattedSettings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.removeRegularKey, + "prepare" + ); + }); + it("flag set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { requireDestinationTag: true }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.flagSet, + "prepare" + ); + }); + it("flag clear", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { requireDestinationTag: false }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.flagClear, + "prepare" + ); + }); + it("set depositAuth flag", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { depositAuth: true }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.flagSetDepositAuth, + "prepare" + ); + }); + it("clear depositAuth flag", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { depositAuth: false }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.flagClearDepositAuth, + "prepare" + ); + }); + it("integer field clear", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { transferRate: null }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assert(response); + assert.strictEqual(JSON.parse(response.txJSON).TransferRate, 0); + }); + it("set transferRate", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = { transferRate: 1 }; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.setTransferRate, + "prepare" + ); + }); + it("set signers", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = requests.prepareSettings.signers.normal; + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + response, + responses.prepareSettings.signers, + "prepare" + ); + }); + it("signers no threshold", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = requests.prepareSettings.signers.noThreshold; + try { + const response = await this.client.prepareSettings( + test.address, + settings, + instructionsWithMaxLedgerVersionOffset + ); + throw new Error( + `Expected method to reject. Prepared transaction: ${JSON.stringify( + response + )}` + ); + } catch (err) { + assert.strictEqual( + err.message, + 'instance.settings.signers requires property "threshold"' + ); + assert.strictEqual(err.name, "ValidationError"); + } + }); + it("signers no weights", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = requests.prepareSettings.signers.noWeights; + const localInstructions = { + signersCount: 1, + ...instructionsWithMaxLedgerVersionOffset, + }; + const response = await this.client.prepareSettings( + test.address, + settings, + localInstructions + ); + assertResultMatch( + response, + responses.prepareSettings.noWeights, + "prepare" + ); + }); + it("fee for multisign", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + signersCount: 4, + ...instructionsWithMaxLedgerVersionOffset, + }; + const response = await this.client.prepareSettings( + test.address, + requests.prepareSettings.domain, + localInstructions + ); + assertResultMatch( + response, + responses.prepareSettings.flagsMultisign, + "prepare" + ); + }); + it("no signer list", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const settings = requests.prepareSettings.noSignerEntries; + const localInstructions = { + signersCount: 1, + ...instructionsWithMaxLedgerVersionOffset, + }; + const response = await this.client.prepareSettings( + test.address, + settings, + localInstructions + ); + assertResultMatch( + response, + responses.prepareSettings.noSignerList, + "prepare" + ); + }); + it("invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + // domain must be a string + const settings = { ...requests.prepareSettings.domain, domain: 123 }; + const localInstructions = { + signersCount: 4, + ...instructionsWithMaxLedgerVersionOffset, + }; - const settings = requests.prepareSettings.domain; - const instructions = { - sequence: 23, - maxLedgerVersion: 8820051, - fee: "0.000012", - }; - const result = await client.prepareSettings( - address, - settings, - instructions - ); - assertResultMatch(result, responses.prepareSettings.flags, "prepare"); - assert.deepEqual( - client.sign(result.txJSON, secret), - responses.prepareSettings.signed - ); - }, - "prepare settings with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const instructions = { - ticketSequence: 23, - maxLedgerVersion: 8820051, - fee: "0.000012", - }; - const response = await client.prepareSettings( - address, - requests.prepareSettings.domain, - instructions - ); - assertResultMatch(response, responses.prepareSettings.ticket, "prepare"); - }, -}; + try { + const response = await this.client.prepareSettings( + test.address, + settings, + localInstructions + ); + throw new Error( + `Expected method to reject. Prepared transaction: ${JSON.stringify( + response + )}` + ); + } catch (err) { + assert.strictEqual( + err.message, + "instance.settings.domain is not of a type(s) string" + ); + assert.strictEqual(err.name, "ValidationError"); + } + }); + it("offline", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + + const settings = requests.prepareSettings.domain; + const instructions = { + sequence: 23, + maxLedgerVersion: 8820051, + fee: "0.000012", + }; + const result = await this.client.prepareSettings( + test.address, + settings, + instructions + ); + assertResultMatch(result, responses.prepareSettings.flags, "prepare"); + assert.deepEqual( + this.client.sign(result.txJSON, secret), + responses.prepareSettings.signed + ); + }); + it("prepare settings with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const instructions = { + ticketSequence: 23, + maxLedgerVersion: 8820051, + fee: "0.000012", + }; + const response = await this.client.prepareSettings( + test.address, + requests.prepareSettings.domain, + instructions + ); + assertResultMatch( + response, + responses.prepareSettings.ticket, + "prepare" + ); + }); + }); + }); +}); diff --git a/test/client/prepareTicket.ts b/test/client/prepareTicket.ts index f2c42648..29e6ab87 100644 --- a/test/client/prepareTicket.ts +++ b/test/client/prepareTicket.ts @@ -1,5 +1,6 @@ import rippled from "../fixtures/rippled"; -import { assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertResultMatch, addressTests } from "../testUtils"; // import responses from '../fixtures/responses' // import requests from '../fixtures/requests' // import {ValidationError} from 'xrpl-local/common/errors' @@ -13,58 +14,62 @@ import { assertResultMatch, TestSuite } from "../testUtils"; // const {preparePayment: RESPONSE_FIXTURES} = responses // const ADDRESS = 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo' -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "creates a ticket successfully with a sequence number": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const expected = { - txJSON: - '{"TransactionType":"TicketCreate", "TicketCount": 2, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence":23,"Fee":"12"}', - instructions: { - maxLedgerVersion: 8819954, - sequence: 23, - fee: "0.000012", - }, - }; - const response = await client.prepareTicketCreate(address, 2); - assertResultMatch(response, expected, "prepare"); - }, +describe("client.prepareTicket", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - "creates a ticket successfully with another ticket": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const expected = { - txJSON: - '{"TransactionType":"TicketCreate", "TicketCount": 1, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence": 0,"TicketSequence":23,"Fee":"12"}', - instructions: { - maxLedgerVersion: 8819954, - ticketSequence: 23, - fee: "0.000012", - }, - }; - const instructions = { - maxLedgerVersion: 8819954, - ticketSequence: 23, - fee: "0.000012", - }; - const response = await client.prepareTicketCreate(address, 1, instructions); - assertResultMatch(response, expected, "prepare"); - }, -}; + addressTests.forEach(function (test) { + describe(test.type, function () { + it("creates a ticket successfully with a sequence number", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const expected = { + txJSON: + '{"TransactionType":"TicketCreate", "TicketCount": 2, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence":23,"Fee":"12"}', + instructions: { + maxLedgerVersion: 8819954, + sequence: 23, + fee: "0.000012", + }, + }; + const response = await this.client.prepareTicketCreate(test.address, 2); + assertResultMatch(response, expected, "prepare"); + }); + + it("creates a ticket successfully with another ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const expected = { + txJSON: + '{"TransactionType":"TicketCreate", "TicketCount": 1, "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Flags":2147483648,"LastLedgerSequence":8819954,"Sequence": 0,"TicketSequence":23,"Fee":"12"}', + instructions: { + maxLedgerVersion: 8819954, + ticketSequence: 23, + fee: "0.000012", + }, + }; + const instructions = { + maxLedgerVersion: 8819954, + ticketSequence: 23, + fee: "0.000012", + }; + const response = await this.client.prepareTicketCreate( + test.address, + 1, + instructions + ); + assertResultMatch(response, expected, "prepare"); + }); + }); + }); +}); diff --git a/test/client/prepareTransaction.ts b/test/client/prepareTransaction.ts index 564a84b2..4b827cb9 100644 --- a/test/client/prepareTransaction.ts +++ b/test/client/prepareTransaction.ts @@ -2,9 +2,11 @@ import { ValidationError } from "xrpl-local/common/errors"; // import requests from '../fixtures/requests' import { xrpToDrops, ISOTimeToRippleTime } from "../../src/utils"; +import addresses from "../fixtures/addresses.json"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects, assertResultMatch } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; @@ -15,31 +17,28 @@ export const config = { skipXAddress: true, }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "auto-fillable fields - does not overwrite Fee in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); +describe("client.prepareTransaction", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + it("auto-fillable fields - does not overwrite Fee in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = instructionsWithMaxLedgerVersionOffset; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Fee: "10", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"10","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"10","Sequence":23}`, instructions: { fee: "0.00001", // Notice there are not always 6 digits after the decimal point as trailing zeros are omitted sequence: 23, @@ -47,29 +46,28 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "does not overwrite Fee in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite Fee in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, fee: "0.000014", // CAUTION: This `fee` is specified in XRP, not drops. }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"14","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"14","Sequence":23}`, instructions: { fee: "0.000014", sequence: 23, @@ -77,134 +75,115 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "rejects Promise if both are set, even when txJSON.Fee matches instructions.fee": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - fee: "0.000016", - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Fee: "16", - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "`Fee` in txJSON and `fee` in `instructions` cannot both be set" - ); - }, - - "rejects Promise if both are set, when txJSON.Fee does not match instructions.fee": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise if both are set, even when txJSON.Fee matches instructions.fee", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + fee: "0.000016", + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Fee: "16", + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "`Fee` in txJSON and `fee` in `instructions` cannot both be set" + ); + }), + it("rejects Promise if both are set, when txJSON.Fee does not match instructions.fee", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, fee: "0.000018", }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Fee: "20", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "`Fee` in txJSON and `fee` in `instructions` cannot both be set" ); - }, + }); - "rejects Promise when the Fee is capitalized in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when the Fee is capitalized in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, Fee: "0.000022", // Intentionally capitalized in this test, but the correct field would be `fee` }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance additionalProperty "Fee" exists in instance when not allowed' ); - }, + }); - "rejects Promise when the fee is specified in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when the fee is specified in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = instructionsWithMaxLedgerVersionOffset; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", fee: "10", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'txJSON additionalProperty "fee" exists in instance when not allowed' ); - }, + }); - "does not overwrite Sequence in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite Sequence in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = instructionsWithMaxLedgerVersionOffset; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", fee: "10", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'txJSON additionalProperty "fee" exists in instance when not allowed' ); - }, + }); - "does not overwrite Sequence in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite Sequence in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -212,12 +191,15 @@ export default { }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":100}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":100}`, instructions: { fee: "0.000012", sequence: 100, @@ -225,72 +207,66 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "does not overwrite Sequence when same sequence is provided in both txJSON and Instructions": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", + it("does not overwrite Sequence when same sequence is provided in both txJSON and Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + sequence: 100, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + }; + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); + const expected = { + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":100}`, + instructions: { + fee: "0.000012", sequence: 100, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - }; - const response = await client.prepareTransaction( - txJSON, - localInstructions - ); - const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":100}`, - instructions: { - fee: "0.000012", - sequence: 100, - maxLedgerVersion: 8820051, - }, - }; - return assertResultMatch(response, expected, "prepare"); - }, + maxLedgerVersion: 8820051, + }, + }; + return assertResultMatch(response, expected, "prepare"); + }); - "rejects Promise when Sequence in txJSON does not match sequence in Instructions": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - sequence: 100, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Sequence: 101, - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "`Sequence` in txJSON must match `sequence` in `instructions`" - ); - }, + it("rejects Promise when Sequence in txJSON does not match sequence in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + sequence: 100, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Sequence: 101, + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "`Sequence` in txJSON must match `sequence` in `instructions`" + ); + }); - "rejects Promise when the Sequence is capitalized in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when the Sequence is capitalized in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -298,27 +274,23 @@ export default { }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance additionalProperty "Sequence" exists in instance when not allowed' ); - }, + }); // LastLedgerSequence aka maxLedgerVersion/maxLedgerVersionOffset: - "does not overwrite LastLedgerSequence in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite LastLedgerSequence in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -326,36 +298,35 @@ export default { }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance additionalProperty "Sequence" exists in instance when not allowed' ); - }, + }); - "does not overwrite maxLedgerVersion in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite maxLedgerVersion in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { maxLedgerVersion: 8890000, }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8890000,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8890000,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -363,29 +334,28 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "does not overwrite maxLedgerVersionOffset in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("does not overwrite maxLedgerVersionOffset in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxLedgerVersionOffset: 124, }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820075,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820075,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -393,135 +363,58 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersion both are set": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - maxLedgerVersion: 8900000, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Fee: "16", - LastLedgerSequence: 8900000, - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "`LastLedgerSequence` in txJSON and `maxLedgerVersion` in `instructions` cannot both be set" - ); - }, + it("rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersion both are set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + maxLedgerVersion: 8900000, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Fee: "16", + LastLedgerSequence: 8900000, + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "`LastLedgerSequence` in txJSON and `maxLedgerVersion` in `instructions` cannot both be set" + ); + }); - "rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersionOffset both are set": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxLedgerVersionOffset: 123, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Fee: "16", - LastLedgerSequence: 8900000, - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "`LastLedgerSequence` in txJSON and `maxLedgerVersionOffset` in `instructions` cannot both be set" - ); - }, + it("rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersionOffset both are set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxLedgerVersionOffset: 123, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Fee: "16", + LastLedgerSequence: 8900000, + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "`LastLedgerSequence` in txJSON and `maxLedgerVersionOffset` in `instructions` cannot both be set" + ); + }); - "rejects Promise if instructions.maxLedgerVersion and instructions.maxLedgerVersionOffset both are set": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxLedgerVersion: 8900000, - maxLedgerVersionOffset: 123, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Fee: "16", - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "instance is of prohibited type [object Object]" - ); - }, - - "rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersion and instructions.maxLedgerVersionOffset all are set": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxLedgerVersion: 8900000, - maxLedgerVersionOffset: 123, - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Fee: "16", - LastLedgerSequence: 8900000, - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - "instance is of prohibited type [object Object]" - ); - }, - - "rejects Promise when the maxLedgerVersion is capitalized in Instructions": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - MaxLedgerVersion: 8900000, // Intentionally capitalized in this test, but the correct field would be `maxLedgerVersion` - }; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - 'instance additionalProperty "MaxLedgerVersion" exists in instance when not allowed' - ); - }, - - "rejects Promise when the maxLedgerVersion is specified in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise if instructions.maxLedgerVersion and instructions.maxLedgerVersionOffset both are set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxLedgerVersion: 8900000, @@ -529,73 +422,132 @@ export default { }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Fee: "16", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "instance is of prohibited type [object Object]" ); - }, + }); - "rejects Promise when the maxLedgerVersionOffset is specified in txJSON": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = instructionsWithMaxLedgerVersionOffset; - const txJSON = { - TransactionType: "DepositPreauth", - Account: address, - Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - maxLedgerVersionOffset: 8900000, - }; - await assertRejects( - client.prepareTransaction(txJSON, localInstructions), - ValidationError, - 'txJSON additionalProperty "maxLedgerVersionOffset" exists in instance when not allowed' - ); - }, + it("rejects Promise if txJSON.LastLedgerSequence and instructions.maxLedgerVersion and instructions.maxLedgerVersionOffset all are set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxLedgerVersion: 8900000, + maxLedgerVersionOffset: 123, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Fee: "16", + LastLedgerSequence: 8900000, + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "instance is of prohibited type [object Object]" + ); + }); - "rejects Promise when the sequence is specified in txJSON": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when the maxLedgerVersion is capitalized in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + MaxLedgerVersion: 8900000, // Intentionally capitalized in this test, but the correct field would be `maxLedgerVersion` + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + 'instance additionalProperty "MaxLedgerVersion" exists in instance when not allowed' + ); + }); + + it("rejects Promise when the maxLedgerVersion is specified in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxLedgerVersion: 8900000, + maxLedgerVersionOffset: 123, + }; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Fee: "16", + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + "instance is of prohibited type [object Object]" + ); + }); + + it("rejects Promise when the maxLedgerVersionOffset is specified in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = instructionsWithMaxLedgerVersionOffset; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, + Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + maxLedgerVersionOffset: 8900000, + }; + await assertRejects( + this.client.prepareTransaction(txJSON, localInstructions), + ValidationError, + 'txJSON additionalProperty "maxLedgerVersionOffset" exists in instance when not allowed' + ); + }); + + it("rejects Promise when the sequence is specified in txJSON", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + const localInstructions = instructionsWithMaxLedgerVersionOffset; + const txJSON = { + TransactionType: "DepositPreauth", + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", sequence: 8900000, }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'txJSON additionalProperty "sequence" exists in instance when not allowed' ); - }, + }); // Paths: is not auto-filled by ripple-lib. // Other errors: - "rejects Promise when an unrecognized field is in Instructions": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when an unrecognized field is in Instructions", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -603,25 +555,21 @@ export default { }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance additionalProperty "foo" exists in instance when not allowed' ); - }, + }); - "rejects Promise when Account is missing": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when Account is missing", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -632,21 +580,17 @@ export default { Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance requires property "Account"' ); - }, + }); - "rejects Promise when Account is not a string": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when Account is not a string", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -658,21 +602,17 @@ export default { Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "instance.Account is not of a type(s) string,instance.Account is not exactly one from ," ); - }, + }); - "rejects Promise when Account is invalid": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when Account is invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -683,11 +623,11 @@ export default { Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "instance.Account is not exactly one from ," ); - }, + }); // 'rejects Promise when Account is valid but non-existent on the ledger': async ( // client @@ -702,63 +642,58 @@ export default { // Authorize: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo' // } // await assertRejects( - // client.prepareTransaction(txJSON, localInstructions), + // this.client.prepareTransaction(txJSON, localInstructions), // RippledError, // 'Account not found.' // ) // }, - "rejects Promise when TransactionType is missing": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when TransactionType is missing", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; // Marking as "any" to get around the fact that TS won't allow this. const txJSON: any = { - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, 'instance requires property "TransactionType"' ); - }, + }); // Note: This transaction will fail at the `sign` step: // // Error: DepositPreXXXX is not a valid name or ordinal for TransactionType // // at Function.from (ripple-binary-codec/distrib/npm/enums/index.js:43:15) - "prepares tx when TransactionType is invalid": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("prepares tx when TransactionType is invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "DepositPreXXXX", Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreXXXX","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreXXXX","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -766,33 +701,29 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "rejects Promise when TransactionType is not a string": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise when TransactionType is not a string", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; // Marking as "any" to get around the fact that TS won't allow this. const txJSON: any = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: 1234, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "instance.TransactionType is not of a type(s) string" ); - }, + }); // Note: This transaction will fail at the `submit` step: // @@ -814,27 +745,26 @@ export default { // '304402201F0EF6A2DE7F96966F7082294D14F3EC1EF59C21E29443E5858A0120079357A302203CDB7FEBDEAAD93FF39CB589B55778CB80DC3979F96F27E828D5E659BEB26B7A', // hash: // 'C181D470684311658852713DA81F8201062535C8DE2FF853F7DD9981BB85312F' } })] - "prepares tx when a required field is missing": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("prepares tx when a required field is missing", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "DepositPreauth", // Authorize: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo' // Normally required, intentionally removed }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -842,39 +772,42 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - "DepositPreauth - Authorize": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("DepositPreauth - Authorize", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Authorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, maxLedgerVersion: 8820051, }, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); return assertResultMatch(response, expected, "prepare"); - }, + }); - "DepositPreauth - Unauthorize": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("DepositPreauth - Unauthorize", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -882,13 +815,16 @@ export default { const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Unauthorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"DepositPreauth","Account":"${address}","Unauthorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"DepositPreauth","Account":"${addresses.ACCOUNT}","Unauthorize":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -896,13 +832,13 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); - async AccountDelete(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("AccountDelete", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "5.0", // 5 XRP fee for AccountDelete @@ -910,13 +846,16 @@ export default { const txJSON = { TransactionType: "AccountDelete", - Account: address, + Account: addresses.ACCOUNT, Destination: "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe", }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); const expected = { - txJSON: `{"TransactionType":"AccountDelete","Account":"${address}","Destination":"rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, + txJSON: `{"TransactionType":"AccountDelete","Account":"${addresses.ACCOUNT}","Destination":"rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe","Flags":2147483648,"LastLedgerSequence":8820051,"Fee":"12","Sequence":23}`, instructions: { fee: "0.000012", sequence: 23, @@ -924,14 +863,14 @@ export default { }, }; return assertResultMatch(response, expected, "prepare"); - }, + }); // prepareTransaction - Payment - "Payment - normal": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("Payment - normal", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -939,7 +878,7 @@ export default { const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Amount: { currency: "USD", @@ -954,15 +893,18 @@ export default { Flags: 0, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch(response, responses.preparePayment.normal, "prepare"); - }, + }); - "min amount xrp": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("min amount xrp", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -970,7 +912,7 @@ export default { const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", // Max amount to send. Use 100 billion XRP to @@ -983,30 +925,33 @@ export default { value: "0.01", }, DeliverMin: "10000", - Flags: client.txFlags.Payment.PartialPayment, + Flags: this.client.txFlags.Payment.PartialPayment, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch( response, responses.preparePayment.minAmountXRP, "prepare" ); - }, + }); - "min amount xrp2xrp": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("min amount xrp2xrp", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Amount: "10000", Flags: 0, }; - const response = await client.prepareTransaction( + const response = await this.client.prepareTransaction( txJSON, instructionsWithMaxLedgerVersionOffset ); @@ -1016,10 +961,10 @@ export default { responses.preparePayment.minAmountXRPXRP, "prepare" ); - }, + }); - // 'with all options specified': async (client, address) => { - // const ledgerResponse = await client.request({ + // 'with all options specified': async (client, addresses.ACCOUNT) => { + // const ledgerResponse = await this.client.request({ // command: 'ledger', // ledger_index: 'validated' // }) @@ -1030,7 +975,7 @@ export default { // } // const txJSON = { // TransactionType: 'Payment', - // Account: address, + // Account: addresses.ACCOUNT, // Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo', // Amount: '10000', // InvoiceID: @@ -1040,121 +985,115 @@ export default { // Memos: [ // { // Memo: { - // MemoType: client.convertStringToHex('test'), - // MemoFormat: client.convertStringToHex('text/plain'), - // MemoData: client.convertStringToHex('texted data') + // MemoType: this.client.convertStringToHex('test'), + // MemoFormat: this.client.convertStringToHex('text/plain'), + // MemoData: this.client.convertStringToHex('texted data') // } // } // ], // Flags: // 0 | - // client.txFlags.Payment.NoRippleDirect | - // client.txFlags.Payment.LimitQuality + // this.client.txFlags.Payment.NoRippleDirect | + // this.client.txFlags.Payment.LimitQuality // } - // const response = await client.prepareTransaction(txJSON, localInstructions) + // const response = await this.client.prepareTransaction(txJSON, localInstructions) // assertResultMatch(response, responses.preparePayment.allOptions, 'prepare') // }, - "fee is capped at default maxFee of 2 XRP (using txJSON.LastLedgerSequence)": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; + it("fee is capped at default maxFee of 2 XRP (using txJSON.LastLedgerSequence)", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + this.client._feeCushion = 1000000; - const txJSON = { - Flags: 2147483648, - TransactionType: "Payment", - Account: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Amount: { - value: "0.01", - currency: "USD", - issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", - }, - SendMax: { - value: "0.01", - currency: "USD", - issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", - }, - LastLedgerSequence: 8820051, - }; - const localInstructions = {}; - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', - instructions: { - fee: "2", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - const response = await client.prepareTransaction( - txJSON, - localInstructions - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, - - "fee is capped at default maxFee of 2 XRP (using instructions.maxLedgerVersion)": - async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - - const txJSON = { - Flags: 2147483648, - TransactionType: "Payment", - Account: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", - Amount: { - value: "0.01", - currency: "USD", - issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", - }, - SendMax: { - value: "0.01", - currency: "USD", - issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", - }, - }; - - const localInstructions = { + const txJSON = { + Flags: 2147483648, + TransactionType: "Payment", + Account: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Amount: { + value: "0.01", + currency: "USD", + issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + }, + SendMax: { + value: "0.01", + currency: "USD", + issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + }, + LastLedgerSequence: 8820051, + }; + const localInstructions = {}; + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', + instructions: { + fee: "2", + sequence: 23, maxLedgerVersion: 8820051, - }; + }, + }; + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); - const expectedResponse = { - txJSON: - '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', - instructions: { - fee: "2", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; + it("fee is capped at default maxFee of 2 XRP (using instructions.maxLedgerVersion)", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + this.client._feeCushion = 1000000; - const response = await client.prepareTransaction( - txJSON, - localInstructions - ); - assertResultMatch(response, expectedResponse, "prepare"); - }, + const txJSON = { + Flags: 2147483648, + TransactionType: "Payment", + Account: "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", + Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", + Amount: { + value: "0.01", + currency: "USD", + issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + }, + SendMax: { + value: "0.01", + currency: "USD", + issuer: "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM", + }, + }; + + const localInstructions = { + maxLedgerVersion: 8820051, + }; + + const expectedResponse = { + txJSON: + '{"Flags":2147483648,"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo","Amount":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"SendMax":{"value":"0.01","currency":"USD","issuer":"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"},"LastLedgerSequence":8820051,"Fee":"2000000","Sequence":23}', + instructions: { + fee: "2", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); + assertResultMatch(response, expectedResponse, "prepare"); + }); // prepareTransaction - Payment - "fee is capped to custom maxFeeXRP when maxFee exceeds maxFeeXRP": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - client._maxFeeXRP = "3"; + it("fee is capped to custom maxFeeXRP when maxFee exceeds maxFeeXRP", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + this.client._feeCushion = 1000000; + this.client._maxFeeXRP = "3"; const localInstructions = { maxFee: "4", // We are testing that this does not matter; fee is still capped to maxFeeXRP }; @@ -1187,18 +1126,21 @@ export default { }, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch(response, expectedResponse, "prepare"); - }, + }); // prepareTransaction - Payment - "fee is capped to maxFee": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - client._feeCushion = 1000000; - client._maxFeeXRP = "5"; + it("fee is capped to maxFee", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); + this.client._feeCushion = 1000000; + this.client._maxFeeXRP = "5"; const localInstructions = { maxFee: "4", // maxFeeXRP does not matter if maxFee is lower than maxFeeXRP }; @@ -1231,15 +1173,18 @@ export default { }, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch(response, expectedResponse, "prepare"); - }, + }); // 'fee - calculated fee does not use more than 6 decimal places': async ( // client, - // address + // addresses.ACCOUNT // ) => { - // client.connection.request({ + // this.client.connection.request({ // command: 'config', // data: {loadFactor: 5407.96875} // }) @@ -1254,19 +1199,19 @@ export default { // } // } - // const response = await client.preparePayment( - // address, + // const response = await this.client.preparePayment( + // addresses.ACCOUNT, // requests.preparePayment.normal, // instructionsWithMaxLedgerVersionOffset // ) // assertResultMatch(response, expectedResponse, 'prepare') // }, - "xaddress-issuer": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("xaddresses.ACCOUNT-issuer", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -1274,7 +1219,7 @@ export default { const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Amount: { currency: "USD", @@ -1289,22 +1234,25 @@ export default { Flags: 0, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch(response, responses.preparePayment.normal, "prepare"); - }, + }); - async PaymentChannelCreate(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelCreate", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; - const response = await client.prepareTransaction( + const response = await this.client.prepareTransaction( { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelCreate", Amount: "1000000", // 1 XRP in drops. Use a string-encoded integer. Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", @@ -1324,15 +1272,15 @@ export default { responses.preparePaymentChannelCreate.normal, "prepare" ); - }, + }); - "PaymentChannelCreate full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelCreate full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelCreate", Amount: xrpToDrops("1"), // or '1000000' Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", @@ -1345,45 +1293,48 @@ export default { DestinationTag: 23480, }; - const response = await client.prepareTransaction(txJSON); + const response = await this.client.prepareTransaction(txJSON); assertResultMatch( response, responses.preparePaymentChannelCreate.full, "prepare" ); - }, + }); - async PaymentChannelFund(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelFund", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelFund", Channel: "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198", Amount: xrpToDrops("1"), // or '1000000' }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch( response, responses.preparePaymentChannelFund.normal, "prepare" ); - }, + }); - "PaymentChannelFund full": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelFund full", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelFund", Channel: "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198", @@ -1391,52 +1342,55 @@ export default { Expiration: ISOTimeToRippleTime("2017-02-17T15:04:57Z"), }; - const response = await client.prepareTransaction(txJSON); + const response = await this.client.prepareTransaction(txJSON); assertResultMatch( response, responses.preparePaymentChannelFund.full, "prepare" ); - }, + }); - async PaymentChannelClaim(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelClaim", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelClaim", Channel: "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198", Flags: 0, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch( response, responses.preparePaymentChannelClaim.normal, "prepare" ); - }, + }); - "PaymentChannelClaim with renew": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelClaim with renew", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelClaim", Channel: "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198", @@ -1448,28 +1402,31 @@ export default { "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A", Flags: 0, }; - txJSON.Flags |= client.txFlags.PaymentChannelClaim.Renew; + txJSON.Flags |= this.client.txFlags.PaymentChannelClaim.Renew; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch( response, responses.preparePaymentChannelClaim.renew, "prepare" ); - }, + }); - "PaymentChannelClaim with close": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("PaymentChannelClaim with close", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", }; const txJSON = { - Account: address, + Account: addresses.ACCOUNT, TransactionType: "PaymentChannelClaim", Channel: "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198", @@ -1481,51 +1438,46 @@ export default { "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A", Flags: 0, }; - txJSON.Flags |= client.txFlags.PaymentChannelClaim.Close; + txJSON.Flags |= this.client.txFlags.PaymentChannelClaim.Close; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch( response, responses.preparePaymentChannelClaim.close, "prepare" ); - }, + }); - "rejects Promise if both sequence and ticketSecuence are set": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise if both sequence and ticketSecuence are set", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ticketSequence: 23, sequence: 23, }; const txJSON = { TransactionType: "DepositPreauth", - Account: address, + Account: addresses.ACCOUNT, Authorize: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Fee: "16", }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "instance is of prohibited type [object Object]" ); - }, + }); - "sets sequence to 0 if a ticketSequence is passed": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("sets sequence to 0 if a ticketSequence is passed", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -1534,7 +1486,7 @@ export default { const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Amount: { currency: "USD", @@ -1549,19 +1501,18 @@ export default { Flags: 0, }; - const response = await client.prepareTransaction(txJSON, localInstructions); + const response = await this.client.prepareTransaction( + txJSON, + localInstructions + ); assertResultMatch(response, responses.preparePayment.ticket, "prepare"); - }, + }); - "rejects Promise if a sequence with value 0 is passed": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); + it("rejects Promise if a sequence with value 0 is passed", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse("account_info", rippled.account_info.normal); const localInstructions = { ...instructionsWithMaxLedgerVersionOffset, maxFee: "0.000012", @@ -1570,7 +1521,7 @@ export default { const txJSON = { TransactionType: "Payment", - Account: address, + Account: addresses.ACCOUNT, Destination: "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo", Amount: { currency: "USD", @@ -1586,9 +1537,9 @@ export default { }; await assertRejects( - client.prepareTransaction(txJSON, localInstructions), + this.client.prepareTransaction(txJSON, localInstructions), ValidationError, "`sequence` cannot be 0" ); - }, -}; + }); +}); diff --git a/test/client/prepareTrustline.ts b/test/client/prepareTrustline.ts index 3f992941..520f6819 100644 --- a/test/client/prepareTrustline.ts +++ b/test/client/prepareTrustline.ts @@ -1,105 +1,130 @@ import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { assertRejects, assertResultMatch, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects, assertResultMatch, addressTests } from "../testUtils"; const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async simple(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareTrustline( - address, - requests.prepareTrustline.simple, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(result, responses.prepareTrustline.simple, "prepare"); - }, +describe("client.prepareTrustline", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); - async frozen(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareTrustline( - address, - requests.prepareTrustline.frozen - ); - assertResultMatch(result, responses.prepareTrustline.frozen, "prepare"); - }, + addressTests.forEach(function (test) { + describe(test.type, function () { + it("simple", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareTrustline( + test.address, + requests.prepareTrustline.simple, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch(result, responses.prepareTrustline.simple, "prepare"); + }); - async complex(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareTrustline( - address, - requests.prepareTrustline.complex, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch(result, responses.prepareTrustline.complex, "prepare"); - }, + it("frozen", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareTrustline( + test.address, + requests.prepareTrustline.frozen + ); + assertResultMatch(result, responses.prepareTrustline.frozen, "prepare"); + }); - async invalid(client, address, mockRippled) { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const trustline = { ...requests.prepareTrustline.complex }; - delete trustline.limit; // Make invalid + it("complex", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareTrustline( + test.address, + requests.prepareTrustline.complex, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + result, + responses.prepareTrustline.complex, + "prepare" + ); + }); - await assertRejects( - client.prepareTrustline( - address, - trustline, - instructionsWithMaxLedgerVersionOffset - ), - client.errors.ValidationError, - 'instance.trustline requires property "limit"' - ); - }, + it("invalid", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const trustline = { ...requests.prepareTrustline.complex }; + delete trustline.limit; // Make invalid - "xaddress-issuer": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const result = await client.prepareTrustline( - address, - requests.prepareTrustline.issuedXAddress, - instructionsWithMaxLedgerVersionOffset - ); - assertResultMatch( - result, - responses.prepareTrustline.issuedXAddress, - "prepare" - ); - }, + await assertRejects( + this.client.prepareTrustline( + test.address, + trustline, + instructionsWithMaxLedgerVersionOffset + ), + this.client.errors.ValidationError, + 'instance.trustline requires property "limit"' + ); + }); - "with ticket": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const localInstructions = { - ...instructionsWithMaxLedgerVersionOffset, - maxFee: "0.000012", - ticketSequence: 23, - }; - const result = await client.prepareTrustline( - address, - requests.prepareTrustline.simple, - localInstructions - ); - assertResultMatch(result, responses.prepareTrustline.ticket, "prepare"); - }, -}; + it("xtest.address-issuer", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const result = await this.client.prepareTrustline( + test.address, + requests.prepareTrustline.issuedXAddress, + instructionsWithMaxLedgerVersionOffset + ); + assertResultMatch( + result, + responses.prepareTrustline.issuedXAddress, + "prepare" + ); + }); + + it("with ticket", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const localInstructions = { + ...instructionsWithMaxLedgerVersionOffset, + maxFee: "0.000012", + ticketSequence: 23, + }; + const result = await this.client.prepareTrustline( + test.address, + requests.prepareTrustline.simple, + localInstructions + ); + assertResultMatch(result, responses.prepareTrustline.ticket, "prepare"); + }); + }); + }); +}); diff --git a/test/client/request.ts b/test/client/request.ts index 2a5c3ea1..ad77310a 100644 --- a/test/client/request.ts +++ b/test/client/request.ts @@ -1,42 +1,47 @@ import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { TestSuite, assertResultMatch } from "../testUtils"; +import setupClient from "../setupClient"; +import { addressTests, assertResultMatch } from "../testUtils"; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "request account_objects": async (client, address, mockRippled) => { - mockRippled.addResponse("account_objects", rippled.account_objects.normal); - const result = await client.request({ - command: "account_objects", - account: address, +describe("client.request", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + + addressTests.forEach(function (test) { + describe(test.type, function () { + it("request account_objects", async function () { + this.mockRippled.addResponse( + "account_objects", + rippled.account_objects.normal + ); + const result = await this.client.request({ + command: "account_objects", + account: test.address, + }); + + assertResultMatch( + result.result, + responses.getAccountObjects, + "AccountObjectsResponse" + ); + }); + + it("request account_objects - invalid options", async function () { + this.mockRippled.addResponse( + "account_objects", + rippled.account_objects.normal + ); + const result = await this.client.request({ + command: "account_objects", + account: test.address, + }); + + assertResultMatch( + result.result, + responses.getAccountObjects, + "AccountObjectsResponse" + ); + }); }); - - assertResultMatch( - result.result, - responses.getAccountObjects, - "AccountObjectsResponse" - ); - }, - - "request account_objects - invalid options": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("account_objects", rippled.account_objects.normal); - const result = await client.request({ - command: "account_objects", - account: address, - }); - - assertResultMatch( - result.result, - responses.getAccountObjects, - "AccountObjectsResponse" - ); - }, -}; + }); +}); diff --git a/test/client/requestNextPage.ts b/test/client/requestNextPage.ts index 38eeed3e..e995a7df 100644 --- a/test/client/requestNextPage.ts +++ b/test/client/requestNextPage.ts @@ -1,7 +1,8 @@ import { assert } from "chai"; import rippled from "../fixtures/rippled"; -import { assertRejects, TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { assertRejects } from "../testUtils"; const rippledResponse = function (request: Request): object { if ("marker" in request) { @@ -10,16 +11,13 @@ const rippledResponse = function (request: Request): object { return rippled.ledger_data.first_page; }; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - "requests the next page": async (client, address, mockRippled) => { - mockRippled.addResponse("ledger_data", rippledResponse); - const response = await client.request({ command: "ledger_data" }); - const responseNextPage = await client.requestNextPage( +describe("client.requestNextPage", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + it("requests the next page", async function () { + this.mockRippled.addResponse("ledger_data", rippledResponse); + const response = await this.client.request({ command: "ledger_data" }); + const responseNextPage = await this.client.requestNextPage( { command: "ledger_data" }, response ); @@ -27,24 +25,20 @@ export default { responseNextPage.result.state[0].index, "000B714B790C3C79FEE00D17C4DEB436B375466F29679447BA64F265FD63D731" ); - }, + }); - "rejects when there are no more pages": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("ledger_data", rippledResponse); - const response = await client.request({ command: "ledger_data" }); - const responseNextPage = await client.requestNextPage( + it("rejects when there are no more pages", async function () { + this.mockRippled.addResponse("ledger_data", rippledResponse); + const response = await this.client.request({ command: "ledger_data" }); + const responseNextPage = await this.client.requestNextPage( { command: "ledger_data" }, response ); - assert(!client.hasNextPage(responseNextPage)); + assert(!this.client.hasNextPage(responseNextPage)); await assertRejects( - client.requestNextPage({ command: "ledger_data" }, responseNextPage), + this.client.requestNextPage({ command: "ledger_data" }, responseNextPage), Error, "response does not have a next page" ); - }, -}; + }); +}); diff --git a/test/client/sign.ts b/test/client/sign.ts index df41ecd5..b9229966 100644 --- a/test/client/sign.ts +++ b/test/client/sign.ts @@ -6,161 +6,110 @@ import * as schemaValidator from "xrpl-local/common/schema-validator"; import requests from "../fixtures/requests"; import responses from "../fixtures/responses"; import rippled from "../fixtures/rippled"; -import { TestSuite } from "../testUtils"; +import setupClient from "../setupClient"; +import { addressTests } from "../testUtils"; const { sign: REQUEST_FIXTURES } = requests; const { sign: RESPONSE_FIXTURES } = responses; -/** - * Every test suite exports their tests in the default object. - * - Check out the "TestSuite" type for documentation on the interface. - * - Check out "test/client/index.ts" for more information about the test runner. - */ -export default { - async sign(client, address) { +describe("client.sign", function () { + beforeEach(setupClient.setup); + afterEach(setupClient.teardown); + it("sign", async function () { const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret); + const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, secret); assert.deepEqual(result, RESPONSE_FIXTURES.normal); schemaValidator.schemaValidate("sign", result); - }, + }); - "sign with lowercase hex data in memo (hex should be case insensitive)": - async (client, address) => { - const secret = "shd2nxpFD6iBRKWsRss2P4tKMWyy9"; - const lowercaseMemoTxJson = { - TransactionType: "Payment", - Flags: 2147483648, - Account: "rwiZ3q3D3QuG4Ga2HyGdq3kPKJRGctVG8a", - Amount: "10000000", - LastLedgerSequence: 14000999, - Destination: "rUeEBYXHo8vF86Rqir3zWGRQ84W9efdAQd", - Fee: "12", - Sequence: 12, - SourceTag: 8888, - DestinationTag: 9999, - Memos: [ - { - Memo: { - MemoType: - "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963", - MemoData: "72656e74", - }, + it("sign with lowercase hex data in memo (hex should be case insensitive)", async function () { + const secret = "shd2nxpFD6iBRKWsRss2P4tKMWyy9"; + const lowercaseMemoTxJson = { + TransactionType: "Payment", + Flags: 2147483648, + Account: "rwiZ3q3D3QuG4Ga2HyGdq3kPKJRGctVG8a", + Amount: "10000000", + LastLedgerSequence: 14000999, + Destination: "rUeEBYXHo8vF86Rqir3zWGRQ84W9efdAQd", + Fee: "12", + Sequence: 12, + SourceTag: 8888, + DestinationTag: 9999, + Memos: [ + { + Memo: { + MemoType: + "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963", + MemoData: "72656e74", }, - ], - }; - - const txParams = JSON.stringify(lowercaseMemoTxJson); - const result = client.sign(txParams, secret); - assert.deepEqual(result, { - signedTransaction: - "120000228000000023000022B8240000000C2E0000270F201B00D5A36761400000000098968068400000000000000C73210305E09ED602D40AB1AF65646A4007C2DAC17CB6CDACDE301E74FB2D728EA057CF744730450221009C00E8439E017CA622A5A1EE7643E26B4DE9C808DE2ABE45D33479D49A4CEC66022062175BE8733442FA2A4D9A35F85A57D58252AE7B19A66401FE238B36FA28E5A081146C1856D0E36019EA75C56D7E8CBA6E35F9B3F71583147FB49CD110A1C46838788CD12764E3B0F837E0DDF9EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1F1", - id: "41B9CB78D8E18A796CDD4B0BC6FB0EA19F64C4F25FDE23049197852CAB71D10D", - }); - }, - - "sign with paths": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const payment = { - source: { - address, - amount: { - currency: "drops", - value: "100", }, - }, - destination: { - address: "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj", - minAmount: { - currency: "USD", - value: "0.00004579644712312366", - counterparty: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc", - }, - }, - // eslint-disable-next-line no-useless-escape - paths: - '[[{"currency":"USD","issuer":"rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc"}]]', + ], }; - const ret = await client.preparePayment(address, payment, { - sequence: 1, - maxLedgerVersion: 15696358, - }); - const result = client.sign(ret.txJSON, secret); + + const txParams = JSON.stringify(lowercaseMemoTxJson); + const result = this.client.sign(txParams, secret); assert.deepEqual(result, { signedTransaction: - "12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900", - id: "78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796", + "120000228000000023000022B8240000000C2E0000270F201B00D5A36761400000000098968068400000000000000C73210305E09ED602D40AB1AF65646A4007C2DAC17CB6CDACDE301E74FB2D728EA057CF744730450221009C00E8439E017CA622A5A1EE7643E26B4DE9C808DE2ABE45D33479D49A4CEC66022062175BE8733442FA2A4D9A35F85A57D58252AE7B19A66401FE238B36FA28E5A081146C1856D0E36019EA75C56D7E8CBA6E35F9B3F71583147FB49CD110A1C46838788CD12764E3B0F837E0DDF9EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1F1", + id: "41B9CB78D8E18A796CDD4B0BC6FB0EA19F64C4F25FDE23049197852CAB71D10D", }); - schemaValidator.schemaValidate("sign", result); - }, + }); - "already signed": async (client, address) => { - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret); - assert.throws(() => { - const tx = JSON.stringify(binary.decode(result.signedTransaction)); - client.sign(tx, secret); - }, /txJSON must not contain "TxnSignature" or "Signers" properties/); - }, - - async EscrowExecution(client, address) { + it("EscrowExecution", async function () { const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb"; - const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, secret); + const result = this.client.sign(REQUEST_FIXTURES.escrow.txJSON, secret); assert.deepEqual(result, RESPONSE_FIXTURES.escrow); schemaValidator.schemaValidate("sign", result); - }, + }); - async signAs(client, address) { + it("signAs", async function () { const txJSON = REQUEST_FIXTURES.signAs; const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb"; - const signature = client.sign(JSON.stringify(txJSON), secret, { + const signature = this.client.sign(JSON.stringify(txJSON), secret, { signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", }); assert.deepEqual(signature, RESPONSE_FIXTURES.signAs); - }, + }); - async withKeypair(client, address) { + it("withKeypair", async function () { const keypair = { privateKey: "00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A", publicKey: "02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8", }; - const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); + const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); assert.deepEqual(result, RESPONSE_FIXTURES.normal); schemaValidator.schemaValidate("sign", result); - }, + }); - "withKeypair already signed": async (client, address) => { + it("withKeypair already signed", async function () { const keypair = { privateKey: "00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A", publicKey: "02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8", }; - const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); + const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, keypair); assert.throws(() => { const tx = JSON.stringify(binary.decode(result.signedTransaction)); - client.sign(tx, keypair); + this.client.sign(tx, keypair); }, /txJSON must not contain "TxnSignature" or "Signers" properties/); - }, + }); - "withKeypair EscrowExecution": async (client, address) => { + it("withKeypair EscrowExecution", async function () { const keypair = { privateKey: "001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7", publicKey: "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", }; - const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair); + const result = this.client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair); assert.deepEqual(result, RESPONSE_FIXTURES.escrow); schemaValidator.schemaValidate("sign", result); - }, + }); - "withKeypair signAs": async (client, address) => { + it("withKeypair signAs", async function () { const txJSON = REQUEST_FIXTURES.signAs; const keypair = { privateKey: @@ -168,49 +117,26 @@ export default { publicKey: "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020", }; - const signature = client.sign(JSON.stringify(txJSON), keypair, { + const signature = this.client.sign(JSON.stringify(txJSON), keypair, { signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", }); assert.deepEqual(signature, RESPONSE_FIXTURES.signAs); - }, + }); - "succeeds - prepared payment": async (client, address, mockRippled) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = await client.preparePayment(address, { - source: { - address, - maxAmount: { - value: "1", - currency: "drops", - }, - }, - destination: { - address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r", - amount: { - value: "1", - currency: "drops", - }, - }, - }); + it("already signed", async function () { const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const result = client.sign(payment.txJSON, secret); - const expectedResult = { - signedTransaction: - "12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648", - id: "88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700", - }; - assert.deepEqual(result, expectedResult); - schemaValidator.schemaValidate("sign", result); - }, + const result = this.client.sign(REQUEST_FIXTURES.normal.txJSON, secret); + assert.throws(() => { + const tx = JSON.stringify(binary.decode(result.signedTransaction)); + this.client.sign(tx, secret); + }, /txJSON must not contain "TxnSignature" or "Signers" properties/); + }); - "succeeds - no flags": async (client, address) => { + it("succeeds - no flags", async function () { const txJSON = '{"TransactionType":"Payment","Account":"r45Rev1EXGxy2hAUmJPCne97KUE7qyrD3j","Destination":"rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r","Amount":"20000000","Sequence":1,"Fee":"12"}'; const secret = "shotKgaEotpcYsshSE39vmSnBDRim"; - const result = client.sign(txJSON, secret); + const result = this.client.sign(txJSON, secret); const expectedResult = { signedTransaction: "1200002400000001614000000001312D0068400000000000000C7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100C104B7B97C31FACA4597E7D6FCF13BD85BD11375963A62A0AC45B0061236E39802207784F157F6A98DFC85B051CDDF61CC3084C4F5750B82674801C8E9950280D1998114EE3046A5DDF8422C40DDB93F1D522BB4FE6419158314FDB08D07AAA0EB711793A3027304D688E10C3648", @@ -223,18 +149,15 @@ export default { ); assert.deepEqual(result, expectedResult); schemaValidator.schemaValidate("sign", result); - }, + }); - "sign succeeds with source.amount/destination.minAmount": async ( - client, - address - ) => { + it("sign succeeds with source.amount/destination.minAmount", async function () { // See also: 'preparePayment with source.amount/destination.minAmount' const txJSON = '{"TransactionType":"Payment","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Destination":"rEX4LtGJubaUcMWCJULcy4NVxGT9ZEMVRq","Amount":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000"},"Flags":2147614720,"SendMax":{"currency":"GBP","issuer":"rpat5TmYjDsnFSStmgTumFgXCM9eqsWPro","value":"0.1"},"DeliverMin":{"currency":"USD","issuer":"rMaa8VLBTjwTJWA2kSme4Sqgphhr6Lr6FH","value":"0.1248548562296331"},"Sequence":23,"LastLedgerSequence":8820051,"Fee":"12"}'; const secret = "shotKgaEotpcYsshSE39vmSnBDRim"; - const result = client.sign(txJSON, secret); + const result = this.client.sign(txJSON, secret); const expectedResult = { signedTransaction: "12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376", @@ -247,85 +170,9 @@ export default { ); assert.deepEqual(result, expectedResult); schemaValidator.schemaValidate("sign", result); - }, + }); - "throws when encoded tx does not match decoded tx - prepared payment": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const payment = await client.preparePayment(address, { - source: { - address, - maxAmount: { - value: "1.1234567", - currency: "drops", - }, - }, - destination: { - address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r", - amount: { - value: "1.1234567", - currency: "drops", - }, - }, - }); - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - assert.throws(() => { - client.sign(payment.txJSON, secret); - }, /^1.1234567 is an illegal amount/); - }, - - "throws when encoded tx does not match decoded tx - prepared order": async ( - client, - address, - mockRippled - ) => { - mockRippled.addResponse("server_info", rippled.server_info.normal); - mockRippled.addResponse("fee", rippled.fee); - mockRippled.addResponse("ledger_current", rippled.ledger_current); - mockRippled.addResponse("account_info", rippled.account_info.normal); - const order = { - direction: "sell", - quantity: { - currency: "USD", - counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - value: "3.140000", - }, - totalPrice: { - currency: "XRP", - value: "31415", - }, - }; - const prepared = await client.prepareOrder(address, order, { - sequence: 123, - }); - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - try { - client.sign(prepared.txJSON, secret); - return await Promise.reject(new Error("client.sign should have thrown")); - } catch (error) { - assert.equal(error.name, "ValidationError"); - assert.equal( - error.message, - "Serialized transaction does not match original txJSON. See `error.data`" - ); - assert.deepEqual(error.data.diff, { - TakerGets: { - value: "3.14", - }, - }); - } - }, - - "throws when encoded tx does not match decoded tx - AccountSet": async ( - client, - address - ) => { + it("throws when encoded tx does not match decoded tx - AccountSet", async function () { const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const request = { // TODO: This fails when address is X-address @@ -338,14 +185,11 @@ export default { }; assert.throws(() => { - client.sign(request.txJSON, secret); + this.client.sign(request.txJSON, secret); }, /1\.2 is an illegal amount/); - }, + }); - "throws when encoded tx does not match decoded tx - higher fee": async ( - client, - address - ) => { + it("throws when encoded tx does not match decoded tx - higher fee", async function () { const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const request = { // TODO: This fails when address is X-address @@ -358,14 +202,16 @@ export default { }; assert.throws(() => { - client.sign(request.txJSON, secret); + this.client.sign(request.txJSON, secret); }, /1123456\.7 is an illegal amount/); - }, + }); - "throws when Fee exceeds maxFeeXRP (in drops)": async (client, address) => { + it("permits fee exceeding 2000000 drops when maxFeeXRP is higher than 2 XRP", async function () { + this.client._maxFeeXRP = "2.1"; const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; const request = { - txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, + // TODO: This fails when address is X-address + txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, instructions: { fee: "2.01", sequence: 23, @@ -373,61 +219,209 @@ export default { }, }; - assert.throws(() => { - client.sign(request.txJSON, secret); - }, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./); - }, + const result = this.client.sign(request.txJSON, secret); - "throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP": async ( - client, - address - ) => { - client._maxFeeXRP = "1.9"; - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const request = { - txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, - instructions: { - fee: "2.01", - sequence: 23, - maxLedgerVersion: 8820051, - }, + const expectedResponse = { + signedTransaction: + "12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304", + id: "061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864", }; - assert.throws(() => { - client.sign(request.txJSON, secret); - }, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./); - }, + assert.deepEqual(result, expectedResponse); + schemaValidator.schemaValidate("sign", result); + }); - "permits fee exceeding 2000000 drops when maxFeeXRP is higher than 2 XRP": - async (client, address) => { - client._maxFeeXRP = "2.1"; - const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; - const request = { - // TODO: This fails when address is X-address - txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, - instructions: { - fee: "2.01", - sequence: 23, - maxLedgerVersion: 8820051, - }, - }; - - const result = client.sign(request.txJSON, secret); - - const expectedResponse = { - signedTransaction: - "12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304", - id: "061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864", - }; - - assert.deepEqual(result, expectedResponse); - schemaValidator.schemaValidate("sign", result); - }, - - "sign with ticket": async (client, address) => { + it("sign with ticket", async function () { const secret = "sn7n5R1cR5Y3fRFkuWXA94Ts1frVJ"; - const result = client.sign(REQUEST_FIXTURES.ticket.txJSON, secret); + const result = this.client.sign(REQUEST_FIXTURES.ticket.txJSON, secret); assert.deepEqual(result, RESPONSE_FIXTURES.ticket); schemaValidator.schemaValidate("sign", result); - }, -}; + }); + + addressTests.forEach(function (test) { + describe(test.type, function () { + it("throws when Fee exceeds maxFeeXRP (in drops)", async function () { + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + const request = { + txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${test.address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, + instructions: { + fee: "2.01", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + + assert.throws(() => { + this.client.sign(request.txJSON, secret); + }, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./); + }); + + it("throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP", async function () { + this.client._maxFeeXRP = "1.9"; + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + const request = { + txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"${test.address}","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"2010000","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`, + instructions: { + fee: "2.01", + sequence: 23, + maxLedgerVersion: 8820051, + }, + }; + + assert.throws(() => { + this.client.sign(request.txJSON, secret); + }, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./); + }); + + it("sign with paths", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + const payment = { + source: { + address: test.address, + amount: { + currency: "drops", + value: "100", + }, + }, + destination: { + address: "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj", + minAmount: { + currency: "USD", + value: "0.00004579644712312366", + counterparty: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc", + }, + }, + // eslint-disable-next-line no-useless-escape + paths: + '[[{"currency":"USD","issuer":"rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc"}]]', + }; + const ret = await this.client.preparePayment(test.address, payment, { + sequence: 1, + maxLedgerVersion: 15696358, + }); + const result = this.client.sign(ret.txJSON, secret); + assert.deepEqual(result, { + signedTransaction: + "12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900", + id: "78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796", + }); + schemaValidator.schemaValidate("sign", result); + }); + + it("succeeds - prepared payment", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = await this.client.preparePayment(test.address, { + source: { + address: test.address, + maxAmount: { + value: "1", + currency: "drops", + }, + }, + destination: { + address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r", + amount: { + value: "1", + currency: "drops", + }, + }, + }); + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + const result = this.client.sign(payment.txJSON, secret); + const expectedResult = { + signedTransaction: + "12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648", + id: "88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700", + }; + assert.deepEqual(result, expectedResult); + schemaValidator.schemaValidate("sign", result); + }); + + it("throws when encoded tx does not match decoded tx - prepared payment", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const payment = await this.client.preparePayment(test.address, { + source: { + address: test.address, + maxAmount: { + value: "1.1234567", + currency: "drops", + }, + }, + destination: { + address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r", + amount: { + value: "1.1234567", + currency: "drops", + }, + }, + }); + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + assert.throws(() => { + this.client.sign(payment.txJSON, secret); + }, /^1.1234567 is an illegal amount/); + }); + + it("throws when encoded tx does not match decoded tx - prepared order", async function () { + this.mockRippled.addResponse("server_info", rippled.server_info.normal); + this.mockRippled.addResponse("fee", rippled.fee); + this.mockRippled.addResponse("ledger_current", rippled.ledger_current); + this.mockRippled.addResponse( + "account_info", + rippled.account_info.normal + ); + const order = { + direction: "sell", + quantity: { + currency: "USD", + counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", + value: "3.140000", + }, + totalPrice: { + currency: "XRP", + value: "31415", + }, + }; + const prepared = await this.client.prepareOrder(test.address, order, { + sequence: 123, + }); + const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV"; + try { + this.client.sign(prepared.txJSON, secret); + return await Promise.reject( + new Error("this.client.sign should have thrown") + ); + } catch (error) { + assert.equal(error.name, "ValidationError"); + assert.equal( + error.message, + "Serialized transaction does not match original txJSON. See `error.data`" + ); + assert.deepEqual(error.data.diff, { + TakerGets: { + value: "3.14", + }, + }); + } + }); + }); + }); +}); diff --git a/test/localRunner.html b/test/localRunner.html index aff4a3fb..b188111a 100644 --- a/test/localRunner.html +++ b/test/localRunner.html @@ -18,7 +18,7 @@ mocha.ui('bdd') - + diff --git a/test/localRunnerMin.html b/test/localRunnerMin.html index 2f557fc7..611047dd 100644 --- a/test/localRunnerMin.html +++ b/test/localRunnerMin.html @@ -18,7 +18,7 @@ mocha.ui('bdd') - + diff --git a/test/rippleClient.ts b/test/rippleClient.ts deleted file mode 100644 index 63c9f3bf..00000000 --- a/test/rippleClient.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Client } from "xrpl-local"; - -import addresses from "./fixtures/addresses.json"; -import setupClient from "./setupClient"; -import { getAllPublicMethods, loadTestSuites } from "./testUtils"; - -/** - * Client Test Runner. - * - * Background: "test/api-test.ts" had hit 4000+ lines of test code and 300+ - * individual tests. Additionally, a new address format was added which - * forced us to copy-paste duplicate the test file to test both the old forms - * of address. This added a significant maintenance burden. - * - * This test runner allows us to split our tests by Client method, and - * automatically load, validate, and run them. Each tests accepts arguments to - * test with, which allows us to re-run tests across different data - * (ex: different address styles). - * - * Additional benefits: - * - Throw errors when we detect the absence of tests. - * - Type the Client object under test and catch typing issues (currently untyped). - * - Sets the stage for more cleanup, like moving test-specific fixtures closer to their tests. - */ -describe("Client [Test Runner]", function () { - beforeEach(setupClient.setup); - afterEach(setupClient.teardown); - - // Collect all the tests: - const allPublicMethods = getAllPublicMethods(new Client("wss://")); - // doesn't need the client, just needs to instantiate to get public methods - - const allTestSuites = loadTestSuites(); - - // Run all the tests: - for (const { name: methodName, tests, config } of allTestSuites) { - describe(`${methodName}`, function () { - // Run each test that does not use an address. - for (const [testName, fn] of tests) { - if (fn.length === 1) { - it(testName, function () { - return fn(this.client, addresses.ACCOUNT, this.mockRippled); - }); - } - } - // Run each test with a classic address. - describe(`[Classic Address]`, function () { - for (const [testName, fn] of tests) { - if (fn.length >= 2) { - it(testName, function () { - return fn(this.client, addresses.ACCOUNT, this.mockRippled); - }); - } - } - }); - // Run each test with an X-address. - if (!config.skipXAddress) { - describe(`[X-address]`, function () { - for (const [testName, fn] of tests) { - if (fn.length >= 2) { - it(testName, function () { - return fn(this.client, addresses.ACCOUNT_X, this.mockRippled); - }); - } - } - }); - } - }); - } - - // Report any missing tests. - const allTestedMethods = new Set(allTestSuites.map((s) => s.name)); - for (const methodName of allPublicMethods) { - if (!allTestedMethods.has(methodName)) { - // TODO: Once migration is complete, remove `.skip()` so that missing tests are reported as failures. - it.skip(`${methodName} - no test suite found`, function () { - throw new Error( - `Test file not found! Create file "test/client/${methodName}/index.ts".` - ); - }); - } - } -}); diff --git a/test/runClientTests.ts b/test/runClientTests.ts new file mode 100644 index 00000000..40ccfdbd --- /dev/null +++ b/test/runClientTests.ts @@ -0,0 +1,73 @@ +import fs from "fs"; +import path from "path"; + +import { Client } from "xrpl-local"; + +/** + * Client Test Runner. + * + * Throws errors when we detect the absence of tests. + * Puts all the client methods under one "describe" umbrella. + */ +describe("Client [Test Runner]", function () { + // doesn't need a functional client, just needs to instantiate to get a list of public methods + // (to determine what methods are missing from ) + const allPublicMethods = getAllPublicMethods(new Client("wss://")); + + const allTestSuites = loadTestSuites(); + + // Report any missing tests. + const allTestedMethods = new Set(allTestSuites.map((s) => s.name)); + for (const methodName of allPublicMethods) { + if (!allTestedMethods.has(methodName)) { + // TODO: Once migration is complete, remove `.skip()` so that missing tests are reported as failures. + it.skip(`${methodName} - no test suite found`, function () { + throw new Error( + `Test file not found! Create file "test/client/${methodName}.ts".` + ); + }); + } + } +}); + +function getAllPublicMethods(client: Client) { + return Array.from( + new Set([ + ...Object.getOwnPropertyNames(client), + ...Object.getOwnPropertyNames(Client.prototype), + ]) + ).filter((key) => !key.startsWith("_")); // removes private methods +} + +/** + * When the test suite is loaded, we represent it with the following + * data structure containing tests and metadata about the suite. + * If no test suite exists, we return this object with `isMissing: true` + * so that we can report it. + */ +interface LoadedTestSuite { + name: string; + tests: Array<[string, () => void | PromiseLike]>; +} + +function loadTestSuites(): LoadedTestSuite[] { + const allTests: any[] = fs.readdirSync(path.join(__dirname, "client"), { + encoding: "utf8", + }); + return allTests + .map((methodName) => { + if (methodName.startsWith(".DS_Store")) { + return null; + } + if (methodName.endsWith(".ts")) { + methodName = methodName.slice(0, -3); + } + const testSuite = require(`./client/${methodName}`); + return { + name: methodName, + config: testSuite.config || {}, + tests: Object.entries(testSuite.default || {}), + } as LoadedTestSuite; + }) + .filter(Boolean) as LoadedTestSuite[]; +} diff --git a/test/testUtils.ts b/test/testUtils.ts index 0fce9782..aa3e2fce 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -1,44 +1,17 @@ -import fs from "fs"; import net from "net"; -import path from "path"; import { assert } from "chai"; import _ from "lodash"; -import { Client } from "xrpl-local"; +import addresses from "./fixtures/addresses.json"; /** - * The test function. It takes a Client object and then some other data to - * test (currently: an address). May be called multiple times with different - * arguments, to test different types of data. + * Setup to run tests on both classic addresses and X-addresses. */ -export type TestFn = ( - client: Client, - address: string, - mockRippled?: any -) => void | PromiseLike; - -/** - * A suite of tests to run. Maps the test name to the test function. - */ -export interface TestSuite { - [testName: string]: TestFn; -} - -/** - * When the test suite is loaded, we represent it with the following - * data structure containing tests and metadata about the suite. - * If no test suite exists, we return this object with `isMissing: true` - * so that we can report it. - */ -interface LoadedTestSuite { - name: string; - tests: Array<[string, TestFn]>; - config: { - /** Set to true to skip re-running tests with an X-address. */ - skipXAddress?: boolean; - }; -} +export const addressTests = [ + { type: "Classic Address", address: addresses.ACCOUNT }, + { type: "X-Address", address: addresses.ACCOUNT_X }, +]; /** * Check the response against the expected result. Optionally validate @@ -119,37 +92,6 @@ export function getFreePort() { }); } -export function getAllPublicMethods(client: Client) { - return Array.from( - new Set([ - ...Object.getOwnPropertyNames(client), - ...Object.getOwnPropertyNames(Client.prototype), - ]) - ).filter((key) => !key.startsWith("_")); -} - -export function loadTestSuites(): LoadedTestSuite[] { - const allTests: any[] = fs.readdirSync(path.join(__dirname, "client"), { - encoding: "utf8", - }); - return allTests - .map((methodName) => { - if (methodName.startsWith(".DS_Store")) { - return null; - } - if (methodName.endsWith(".ts")) { - methodName = methodName.slice(0, -3); - } - const testSuite = require(`./client/${methodName}`); - return { - name: methodName, - config: testSuite.config || {}, - tests: Object.entries(testSuite.default || {}), - } as LoadedTestSuite; - }) - .filter(Boolean) as LoadedTestSuite[]; -} - /** * Ignore WebSocket DisconnectErrors. Useful for making requests where we don't * care about the response and plan to teardown the test before the response diff --git a/test/wallet/index.ts b/test/wallet/index.ts index 6960f11e..bbd0f4f3 100644 --- a/test/wallet/index.ts +++ b/test/wallet/index.ts @@ -1,183 +1,188 @@ -import {assert} from 'chai' -import ECDSA from '../../src/common/ecdsa' -import Wallet from '../../src/Wallet' +import { assert } from "chai"; + +import ECDSA from "../../src/common/ecdsa"; +import Wallet from "../../src/Wallet"; /** - * Wallet testing + * Wallet testing. * - * Provides tests for Wallet class + * Provides tests for Wallet class. */ -describe('Wallet', () => { - describe('fromSeed', () => { - const seed = 'ssL9dv2W5RK8L3tuzQxYY6EaZhSxW' - const publicKey = - '030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' - const privateKey = - '00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F' - - it('derives a wallet using default algorithm', () => { - const wallet = Wallet.fromSeed(seed) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) +describe("Wallet", function () { + describe("fromSeed", function () { + const seed = "ssL9dv2W5RK8L3tuzQxYY6EaZhSxW"; + const publicKey = + "030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D"; + const privateKey = + "00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F"; - it('derives a wallet using algorithm ecdsa-secp256k1', () => { - const algorithm = ECDSA.secp256k1 - const wallet = Wallet.fromSeed(seed, algorithm) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) + it("derives a wallet using default algorithm", function () { + const wallet = Wallet.fromSeed(seed); - it('derives a wallet using algorithm ed25519', () => { - const algorithm = ECDSA.ed25519 - const wallet = Wallet.fromSeed(seed, algorithm) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) - }) + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); - describe('fromMnemonic', () => { - const mnemonic = - 'try milk link drift aware pass obtain again music stick pluck fold' - const publicKey = - '0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6' - const privateKey = - '008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3' - - it('derives a wallet using default derivation path', () => { - const wallet = Wallet.fromMnemonic(mnemonic) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) + it("derives a wallet using algorithm ecdsa-secp256k1", function () { + const algorithm = ECDSA.secp256k1; + const wallet = Wallet.fromSeed(seed, algorithm); - it('derives a wallet using an input derivation path', () => { - const derivationPath = "m/44'/144'/0'/0/0" - const wallet = Wallet.fromMnemonic(mnemonic, derivationPath) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) - }) + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); - describe('fromEntropy', () => { - const entropy: number[] = new Array(16).fill(0) - const publicKey: string = - '0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284' - const privateKey: string = - '002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665' - const publicKeyED25519: string = - 'ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F' - const privateKeyED25519: string = - 'ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D' + it("derives a wallet using algorithm ed25519", function () { + const algorithm = ECDSA.ed25519; + const wallet = Wallet.fromSeed(seed, algorithm); - it('derives a wallet using entropy', () => { - const wallet = Wallet.fromEntropy(entropy) - - assert.equal(wallet.publicKey, publicKeyED25519) - assert.equal(wallet.privateKey, privateKeyED25519) - }) + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); + }); - it('derives a wallet using algorithm ecdsa-secp256k1', () => { - const algorithm = ECDSA.secp256k1 - const wallet = Wallet.fromEntropy(entropy, algorithm) - - assert.equal(wallet.publicKey, publicKey) - assert.equal(wallet.privateKey, privateKey) - }) + describe("fromMnemonic", function () { + const mnemonic = + "try milk link drift aware pass obtain again music stick pluck fold"; + const publicKey = + "0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6"; + const privateKey = + "008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3"; - it('derives a wallet using algorithm ed25519', () => { - const algorithm = ECDSA.ed25519 - const wallet = Wallet.fromEntropy(entropy, algorithm) - - assert.equal(wallet.publicKey, publicKeyED25519) - assert.equal(wallet.privateKey, privateKeyED25519) - }) - }) + it("derives a wallet using default derivation path", function () { + const wallet = Wallet.fromMnemonic(mnemonic); - describe('signTransaction', () => { - const publicKey = - '030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' - const privateKey = - '00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F' - const address = 'rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc' - - it('signs a transaction offline', () => { - const txJSON = { - TransactionType: 'Payment', - Account: address, - Destination: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r', - Amount: '20000000', - Sequence: 1, - Fee: '12', - SigningPubKey: publicKey - } - const wallet = new Wallet(publicKey, privateKey) - const signedTx: {signedTransaction: string; id: string} = - wallet.signTransaction(txJSON) + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); - assert.hasAllKeys(signedTx, ['id', 'signedTransaction']) - assert.isString(signedTx.id) - assert.isString(signedTx.signedTransaction) - }) - }) + it("derives a wallet using an input derivation path", function () { + const derivationPath = "m/44'/144'/0'/0/0"; + const wallet = Wallet.fromMnemonic(mnemonic, derivationPath); - describe('verifyTransaction', () => { - const publicKey = - '030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' - const privateKey = - '00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F' - const prepared = { - signedTransaction: - '1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648', - id: '30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A' - } - - it('returns true when verifying a transaction signed by the same wallet', () => { - const wallet = new Wallet(publicKey, privateKey) - const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction) - - assert.equal(isVerified, true) - }) + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); + }); - it('returns false when verifying a transaction signed by a different wallet', () => { - const diffPublicKey = - '02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8' - const diffPrivateKey = - '00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A' - const wallet = new Wallet(diffPublicKey, diffPrivateKey) - const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction) - - assert.equal(isVerified, false) - }) - }) + describe("fromEntropy", function () { + const entropy: number[] = new Array(16).fill(0); + const publicKey = + "0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284"; + const privateKey = + "002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665"; + const publicKeyED25519 = + "ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F"; + const privateKeyED25519 = + "ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D"; - describe('getXAddress', () => { - const publicKey = - '030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D' - const privateKey = - '00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F' - const wallet = new Wallet(publicKey, privateKey) - const tag = 1337 - const mainnetXAddress = 'X7gJ5YK8abHf2eTPWPFHAAot8Knck11QGqmQ7a6a3Z8PJvk' - const testnetXAddress = 'T7bq3e7kxYq9pwDz8UZhqAZoEkcRGTXSNr5immvcj3DYRaV' - - it('returns a Testnet X-address when test is true', () => { - const result = wallet.getXAddress(tag, true) - assert.equal(result, testnetXAddress) - }) - - it('returns a Mainnet X-address when test is false', () => { - const result = wallet.getXAddress(tag, false) - assert.equal(result, mainnetXAddress) - }) + it("derives a wallet using entropy", function () { + const wallet = Wallet.fromEntropy(entropy); - it("returns a Mainnet X-address when test isn't provided", () => { - const result = wallet.getXAddress(tag) - assert.equal(result, mainnetXAddress) - }) - }) -}) + assert.equal(wallet.publicKey, publicKeyED25519); + assert.equal(wallet.privateKey, privateKeyED25519); + }); + + it("derives a wallet using algorithm ecdsa-secp256k1", function () { + const algorithm = ECDSA.secp256k1; + const wallet = Wallet.fromEntropy(entropy, algorithm); + + assert.equal(wallet.publicKey, publicKey); + assert.equal(wallet.privateKey, privateKey); + }); + + it("derives a wallet using algorithm ed25519", function () { + const algorithm = ECDSA.ed25519; + const wallet = Wallet.fromEntropy(entropy, algorithm); + + assert.equal(wallet.publicKey, publicKeyED25519); + assert.equal(wallet.privateKey, privateKeyED25519); + }); + }); + + describe("signTransaction", function () { + const publicKey = + "030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D"; + const privateKey = + "00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F"; + const address = "rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc"; + + it("signs a transaction offline", function () { + const txJSON = { + TransactionType: "Payment", + Account: address, + Destination: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r", + Amount: "20000000", + Sequence: 1, + Fee: "12", + SigningPubKey: publicKey, + }; + const wallet = new Wallet(publicKey, privateKey); + const signedTx: { signedTransaction: string; id: string } = + wallet.signTransaction(txJSON); + + assert.hasAllKeys(signedTx, ["id", "signedTransaction"]); + assert.isString(signedTx.id); + assert.isString(signedTx.signedTransaction); + }); + }); + + describe("verifyTransaction", function () { + const publicKey = + "030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D"; + const privateKey = + "00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F"; + const prepared = { + signedTransaction: + "1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648", + id: "30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A", + }; + + it("returns true when verifying a transaction signed by the same wallet", function () { + const wallet = new Wallet(publicKey, privateKey); + const isVerified: boolean = wallet.verifyTransaction( + prepared.signedTransaction + ); + + assert.equal(isVerified, true); + }); + + it("returns false when verifying a transaction signed by a different wallet", function () { + const diffPublicKey = + "02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"; + const diffPrivateKey = + "00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A"; + const wallet = new Wallet(diffPublicKey, diffPrivateKey); + const isVerified: boolean = wallet.verifyTransaction( + prepared.signedTransaction + ); + + assert.equal(isVerified, false); + }); + }); + + describe("getXAddress", function () { + const publicKey = + "030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D"; + const privateKey = + "00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F"; + const wallet = new Wallet(publicKey, privateKey); + const tag = 1337; + const mainnetXAddress = "X7gJ5YK8abHf2eTPWPFHAAot8Knck11QGqmQ7a6a3Z8PJvk"; + const testnetXAddress = "T7bq3e7kxYq9pwDz8UZhqAZoEkcRGTXSNr5immvcj3DYRaV"; + + it("returns a Testnet X-address when test is true", function () { + const result = wallet.getXAddress(tag, true); + assert.equal(result, testnetXAddress); + }); + + it("returns a Mainnet X-address when test is false", function () { + const result = wallet.getXAddress(tag, false); + assert.equal(result, mainnetXAddress); + }); + + it("returns a Mainnet X-address when test isn't provided", function () { + const result = wallet.getXAddress(tag); + assert.equal(result, mainnetXAddress); + }); + }); +});