mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-24 22:25:48 +00:00
build: Initial linting setup (#1560)
* sets up linting config and runs `yarn lint --fix` once, so that all changes will show up correctly in future PRs. * Note that there are still a lot of linter errors.
This commit is contained in:
committed by
Mayukha Vadari
parent
12cfed5c17
commit
8b95ee5fab
@@ -1,37 +1,38 @@
|
||||
import assert from 'assert-diff'
|
||||
import {ExponentialBackoff} from '../src/client/backoff'
|
||||
import assert from "assert-diff";
|
||||
|
||||
describe('ExponentialBackoff', function () {
|
||||
it('duration() return value starts with the min value', function () {
|
||||
import { ExponentialBackoff } from "../src/client/backoff";
|
||||
|
||||
describe("ExponentialBackoff", function () {
|
||||
it("duration() return value starts with the min value", function () {
|
||||
// default: 100ms
|
||||
assert(new ExponentialBackoff().duration(), 100)
|
||||
assert(new ExponentialBackoff({min: 100}).duration(), 100)
|
||||
assert(new ExponentialBackoff({min: 123}).duration(), 123)
|
||||
})
|
||||
assert(new ExponentialBackoff().duration(), 100);
|
||||
assert(new ExponentialBackoff({ min: 100 }).duration(), 100);
|
||||
assert(new ExponentialBackoff({ min: 123 }).duration(), 123);
|
||||
});
|
||||
|
||||
it('duration() return value increases when called multiple times', function () {
|
||||
const backoff = new ExponentialBackoff({min: 100, max: 1000})
|
||||
assert.strictEqual(backoff.duration(), 100)
|
||||
assert.strictEqual(backoff.duration(), 200)
|
||||
assert.strictEqual(backoff.duration(), 400)
|
||||
assert.strictEqual(backoff.duration(), 800)
|
||||
})
|
||||
it("duration() return value increases when called multiple times", function () {
|
||||
const backoff = new ExponentialBackoff({ min: 100, max: 1000 });
|
||||
assert.strictEqual(backoff.duration(), 100);
|
||||
assert.strictEqual(backoff.duration(), 200);
|
||||
assert.strictEqual(backoff.duration(), 400);
|
||||
assert.strictEqual(backoff.duration(), 800);
|
||||
});
|
||||
|
||||
it('duration() never returns greater than the max value', function () {
|
||||
const backoff = new ExponentialBackoff({min: 300, max: 1000})
|
||||
assert.strictEqual(backoff.duration(), 300)
|
||||
assert.strictEqual(backoff.duration(), 600)
|
||||
assert.strictEqual(backoff.duration(), 1000)
|
||||
assert.strictEqual(backoff.duration(), 1000)
|
||||
})
|
||||
it("duration() never returns greater than the max value", function () {
|
||||
const backoff = new ExponentialBackoff({ min: 300, max: 1000 });
|
||||
assert.strictEqual(backoff.duration(), 300);
|
||||
assert.strictEqual(backoff.duration(), 600);
|
||||
assert.strictEqual(backoff.duration(), 1000);
|
||||
assert.strictEqual(backoff.duration(), 1000);
|
||||
});
|
||||
|
||||
it('reset() will reset the duration() value', function () {
|
||||
const backoff = new ExponentialBackoff({min: 100, max: 1000})
|
||||
assert.strictEqual(backoff.duration(), 100)
|
||||
assert.strictEqual(backoff.duration(), 200)
|
||||
assert.strictEqual(backoff.duration(), 400)
|
||||
backoff.reset()
|
||||
assert.strictEqual(backoff.duration(), 100)
|
||||
assert.strictEqual(backoff.duration(), 200)
|
||||
})
|
||||
})
|
||||
it("reset() will reset the duration() value", function () {
|
||||
const backoff = new ExponentialBackoff({ min: 100, max: 1000 });
|
||||
assert.strictEqual(backoff.duration(), 100);
|
||||
assert.strictEqual(backoff.duration(), 200);
|
||||
assert.strictEqual(backoff.duration(), 400);
|
||||
backoff.reset();
|
||||
assert.strictEqual(backoff.duration(), 100);
|
||||
assert.strictEqual(backoff.duration(), 200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
import _ from 'lodash'
|
||||
import assert from 'assert-diff'
|
||||
import setupClient from './setupClient'
|
||||
import responses from './fixtures/responses'
|
||||
import rippled from './fixtures/rippled'
|
||||
import {ignoreWebSocketDisconnect} from './testUtils'
|
||||
import assert from "assert-diff";
|
||||
import _ from "lodash";
|
||||
|
||||
const TIMEOUT = 20000
|
||||
import responses from "./fixtures/responses";
|
||||
import rippled from "./fixtures/rippled";
|
||||
import setupClient from "./setupClient";
|
||||
import { ignoreWebSocketDisconnect } from "./testUtils";
|
||||
|
||||
const TIMEOUT = 20000;
|
||||
|
||||
function checkResult(expected, response) {
|
||||
if (expected.txJSON) {
|
||||
assert(response.txJSON)
|
||||
assert.deepEqual(JSON.parse(response.txJSON), JSON.parse(expected.txJSON))
|
||||
assert(response.txJSON);
|
||||
assert.deepEqual(JSON.parse(response.txJSON), JSON.parse(expected.txJSON));
|
||||
}
|
||||
assert.deepEqual(_.omit(response, 'txJSON'), _.omit(expected, 'txJSON'))
|
||||
return response
|
||||
assert.deepEqual(_.omit(response, "txJSON"), _.omit(expected, "txJSON"));
|
||||
return response;
|
||||
}
|
||||
|
||||
describe('BroadcastClient', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
beforeEach(setupClient.setupBroadcast)
|
||||
afterEach(setupClient.teardown)
|
||||
describe("BroadcastClient", function () {
|
||||
this.timeout(TIMEOUT);
|
||||
beforeEach(setupClient.setupBroadcast);
|
||||
afterEach(setupClient.teardown);
|
||||
|
||||
it('base', function () {
|
||||
it("base", function () {
|
||||
this.mocks.forEach((mock) => {
|
||||
mock.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
})
|
||||
assert(this.client.isConnected())
|
||||
return this.client
|
||||
.request({command: "server_info"})
|
||||
.then(response => {
|
||||
return checkResult(responses.getServerInfo, response.result.info)
|
||||
})
|
||||
})
|
||||
mock.addResponse({ command: "server_info" }, rippled.server_info.normal);
|
||||
});
|
||||
assert(this.client.isConnected());
|
||||
return this.client.request({ command: "server_info" }).then((response) => {
|
||||
return checkResult(responses.getServerInfo, response.result.info);
|
||||
});
|
||||
});
|
||||
|
||||
it('error propagation', function (done) {
|
||||
const data = {error: 'type', error_message: 'info'}
|
||||
it("error propagation", function (done) {
|
||||
const data = { error: "type", error_message: "info" };
|
||||
this.mocks.forEach((mock) => {
|
||||
mock.addResponse({command: 'echo'}, data)
|
||||
})
|
||||
this.client.once('error', (type, info) => {
|
||||
assert.strictEqual(type, 'type')
|
||||
assert.strictEqual(info, 'info')
|
||||
done()
|
||||
})
|
||||
mock.addResponse({ command: "echo" }, data);
|
||||
});
|
||||
this.client.once("error", (type, info) => {
|
||||
assert.strictEqual(type, "type");
|
||||
assert.strictEqual(info, "info");
|
||||
done();
|
||||
});
|
||||
this.client._clients[1].connection
|
||||
.request({
|
||||
command: 'echo',
|
||||
data
|
||||
command: "echo",
|
||||
data,
|
||||
})
|
||||
.catch(ignoreWebSocketDisconnect)
|
||||
})
|
||||
})
|
||||
.catch(ignoreWebSocketDisconnect);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,30 +1,35 @@
|
||||
import assert from 'assert'
|
||||
import puppeteer from 'puppeteer'
|
||||
import { expect, assert } from "chai";
|
||||
import puppeteer from "puppeteer";
|
||||
|
||||
describe("Browser Tests", () => {
|
||||
it("Integration Tests", async () => {
|
||||
const browser = await puppeteer.launch({"headless": true});
|
||||
try {
|
||||
const page = await browser.newPage().catch();
|
||||
await page.goto(`file:///${__dirname}/../localIntegrationRunner.html`);
|
||||
describe("Browser Tests", function () {
|
||||
it("Integration Tests", async function () {
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
try {
|
||||
const page = await browser.newPage().catch();
|
||||
await page.goto(`file:///${__dirname}/../localIntegrationRunner.html`);
|
||||
|
||||
await page.waitForFunction('document.querySelector("body").innerText.includes("submit multisigned transaction")');
|
||||
await page.waitForFunction(
|
||||
'document.querySelector("body").innerText.includes("submit multisigned transaction")'
|
||||
);
|
||||
|
||||
const fails = await page.evaluate(() => {
|
||||
return document.querySelector('.failures').textContent
|
||||
})
|
||||
const passes = await page.evaluate(() => {
|
||||
return document.querySelector('.passes').textContent
|
||||
})
|
||||
const fails = await page.evaluate(() => {
|
||||
const element = document.querySelector(".failures");
|
||||
|
||||
assert.equal(fails, "failures: 0")
|
||||
assert.notEqual(passes, "passes: 0")
|
||||
return element == null ? null : element.textContent;
|
||||
});
|
||||
const passes = await page.evaluate(() => {
|
||||
const element = document.querySelector(".passes");
|
||||
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
assert(false)
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
}).timeout(40000)
|
||||
})
|
||||
return element == null ? null : element.textContent;
|
||||
});
|
||||
|
||||
expect(fails).to.equal("failures: 0");
|
||||
expect(passes).to.not.equal("passes: 0");
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
assert(false);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
}).timeout(40000);
|
||||
});
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import assert from 'assert-diff'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const {combine: REQUEST_FIXTURES} = requests
|
||||
const {combine: RESPONSE_FIXTURES} = responses
|
||||
import assert from "assert-diff";
|
||||
import binary from "ripple-binary-codec";
|
||||
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const { combine: REQUEST_FIXTURES } = requests;
|
||||
const { combine: RESPONSE_FIXTURES } = responses;
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -12,18 +14,18 @@ const {combine: RESPONSE_FIXTURES} = responses
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'combine': async (client, address) => {
|
||||
const combined = client.combine(REQUEST_FIXTURES.setDomain)
|
||||
assertResultMatch(combined, RESPONSE_FIXTURES.single, 'sign')
|
||||
async combine(client, address) {
|
||||
const combined = client.combine(REQUEST_FIXTURES.setDomain);
|
||||
assertResultMatch(combined, RESPONSE_FIXTURES.single, "sign");
|
||||
},
|
||||
|
||||
'combine - different transactions': async (client, address) => {
|
||||
const request = [REQUEST_FIXTURES.setDomain[0]]
|
||||
const tx = binary.decode(REQUEST_FIXTURES.setDomain[0])
|
||||
tx.Flags = 0
|
||||
request.push(binary.encode(tx))
|
||||
"combine - different transactions": async (client, address) => {
|
||||
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)
|
||||
}, /txJSON is not the same for all signedTransactions/)
|
||||
}
|
||||
}
|
||||
client.combine(request);
|
||||
}, /txJSON is not the same for all signedTransactions/);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import {Client} from 'xrpl-local'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { Client } from "xrpl-local";
|
||||
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -8,22 +10,22 @@ import {Client} from 'xrpl-local'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'Client - implicit server port': () => {
|
||||
new Client('wss://s1.ripple.com')
|
||||
"Client - implicit server port": () => {
|
||||
new Client("wss://s1.ripple.com");
|
||||
},
|
||||
|
||||
'Client invalid options': () => {
|
||||
// @ts-ignore - This is intentionally invalid
|
||||
assert.throws(() => new Client({invalid: true}))
|
||||
"Client invalid options": () => {
|
||||
// @ts-expect-error - This is intentionally invalid
|
||||
assert.throws(() => new Client({ invalid: true }));
|
||||
},
|
||||
|
||||
'Client valid options': () => {
|
||||
const client = new Client('wss://s:1')
|
||||
const privateConnectionUrl = (client.connection as any)._url
|
||||
assert.deepEqual(privateConnectionUrl, 'wss://s:1')
|
||||
"Client valid options": () => {
|
||||
const client = new Client("wss://s:1");
|
||||
const privateConnectionUrl = (client.connection as any)._url;
|
||||
assert.deepEqual(privateConnectionUrl, "wss://s:1");
|
||||
},
|
||||
|
||||
'Client invalid server uri': () => {
|
||||
assert.throws(() => new Client('wss//s:1'))
|
||||
}
|
||||
}
|
||||
"Client invalid server uri": () => {
|
||||
assert.throws(() => new Client("wss//s:1"));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import {Client} from '../../src'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { Client } from "../../src";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -8,24 +9,24 @@ import {Client} from '../../src'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'returns address for public key': async (client, address) => {
|
||||
"returns address for public key": async (client, address) => {
|
||||
assert.equal(
|
||||
Client.deriveXAddress({
|
||||
publicKey:
|
||||
'035332FBA71D705BD5D97014A833BE2BBB25BEFCD3506198E14AFEA241B98C2D06',
|
||||
"035332FBA71D705BD5D97014A833BE2BBB25BEFCD3506198E14AFEA241B98C2D06",
|
||||
tag: false,
|
||||
test: false
|
||||
test: false,
|
||||
}),
|
||||
'XVZVpQj8YSVpNyiwXYSqvQoQqgBttTxAZwMcuJd4xteQHyt'
|
||||
)
|
||||
"XVZVpQj8YSVpNyiwXYSqvQoQqgBttTxAZwMcuJd4xteQHyt"
|
||||
);
|
||||
assert.equal(
|
||||
Client.deriveXAddress({
|
||||
publicKey:
|
||||
'035332FBA71D705BD5D97014A833BE2BBB25BEFCD3506198E14AFEA241B98C2D06',
|
||||
"035332FBA71D705BD5D97014A833BE2BBB25BEFCD3506198E14AFEA241B98C2D06",
|
||||
tag: false,
|
||||
test: true
|
||||
test: true,
|
||||
}),
|
||||
'TVVrSWtmQQssgVcmoMBcFQZKKf56QscyWLKnUyiuZW8ALU4'
|
||||
)
|
||||
}
|
||||
}
|
||||
"TVVrSWtmQQssgVcmoMBcFQZKKf56QscyWLKnUyiuZW8ALU4"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -7,13 +8,13 @@ import {TestSuite} from '../testUtils'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'RippleError with data': async (client, address) => {
|
||||
const error = new client.errors.RippleError('_message_', '_data_')
|
||||
assert.strictEqual(error.toString(), "[RippleError(_message_, '_data_')]")
|
||||
"RippleError with data": async (client, address) => {
|
||||
const error = new client.errors.RippleError("_message_", "_data_");
|
||||
assert.strictEqual(error.toString(), "[RippleError(_message_, '_data_')]");
|
||||
},
|
||||
|
||||
'NotFoundError default message': async (client, address) => {
|
||||
const error = new client.errors.NotFoundError()
|
||||
assert.strictEqual(error.toString(), '[NotFoundError(Not found)]')
|
||||
}
|
||||
}
|
||||
"NotFoundError default message": async (client, address) => {
|
||||
const error = new client.errors.NotFoundError();
|
||||
assert.strictEqual(error.toString(), "[NotFoundError(Not found)]");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// import {Client} from 'xrpl-local'
|
||||
// import requests from '../fixtures/requests'
|
||||
// import responses from '../fixtures/responses'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
// function checkSortingOfOrders(orders) {
|
||||
// let previousRate = '0'
|
||||
@@ -56,7 +56,6 @@ export default <TestSuite>{
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -88,7 +87,6 @@ export default <TestSuite>{
|
||||
// assert.deepEqual(orderbook, responses.getOrderbook.normal)
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'with XRP': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
@@ -99,7 +97,6 @@ export default <TestSuite>{
|
||||
// currency: 'XRP'
|
||||
// }
|
||||
// }
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -131,7 +128,6 @@ export default <TestSuite>{
|
||||
// assert.deepEqual(orderbook, responses.getOrderbook.withXRP)
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'sample XRP/JPY book has orders sorted correctly': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
@@ -143,9 +139,7 @@ export default <TestSuite>{
|
||||
// issuer: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS'
|
||||
// }
|
||||
// }
|
||||
|
||||
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -178,7 +172,6 @@ export default <TestSuite>{
|
||||
// return checkSortingOfOrders(orderbook.asks)
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'sample USD/XRP book has orders sorted correctly': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// counter: {currency: 'XRP'},
|
||||
@@ -187,9 +180,7 @@ export default <TestSuite>{
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
|
||||
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -224,7 +215,6 @@ export default <TestSuite>{
|
||||
// )
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'sorted so that best deals come first': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
@@ -236,7 +226,6 @@ export default <TestSuite>{
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -265,7 +254,6 @@ export default <TestSuite>{
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
|
||||
// const bidRates = orderbook.bids.map(
|
||||
// (bid) => bid.properties.makerExchangeRate
|
||||
// )
|
||||
@@ -279,7 +267,6 @@ export default <TestSuite>{
|
||||
// assert.deepEqual(askRates.map((x) => Number(x)).sort(), askRates)
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'currency & counterparty are correct': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
@@ -291,7 +278,6 @@ export default <TestSuite>{
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -320,7 +306,6 @@ export default <TestSuite>{
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
|
||||
// const orders = [...orderbook.bids, ...orderbook.asks]
|
||||
// orders.forEach((order) => {
|
||||
// const quantity = order.specification.quantity
|
||||
@@ -333,7 +318,6 @@ export default <TestSuite>{
|
||||
// })
|
||||
// })
|
||||
// },
|
||||
|
||||
// 'direction is correct for bids and asks': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
@@ -345,7 +329,6 @@ export default <TestSuite>{
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
@@ -374,7 +357,6 @@ export default <TestSuite>{
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
|
||||
// assert(
|
||||
// orderbook.bids.every((bid) => bid.specification.direction === 'buy')
|
||||
// )
|
||||
@@ -383,4 +365,4 @@ export default <TestSuite>{
|
||||
// )
|
||||
// })
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import rippledAccountLines from '../fixtures/rippled/accountLines'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import rippledAccountLines from "../fixtures/rippled/accountLines";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -9,54 +9,82 @@ import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'getBalances': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippledAccountLines.normal)
|
||||
mockRippled.addResponse({command: 'ledger'}, rippled.ledger.normal)
|
||||
const result = await client.getBalances(address)
|
||||
assertResultMatch(result, responses.getBalances, 'getBalances')
|
||||
async getBalances(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_lines" },
|
||||
rippledAccountLines.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "ledger" }, rippled.ledger.normal);
|
||||
const result = await client.getBalances(address);
|
||||
assertResultMatch(result, responses.getBalances, "getBalances");
|
||||
},
|
||||
|
||||
'getBalances - limit': async (client, address, mockRippled) => {
|
||||
const options = {limit: 3, ledgerVersion: 123456}
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippledAccountLines.normal)
|
||||
mockRippled.addResponse({command: 'ledger'}, rippled.ledger.normal)
|
||||
const expectedResponse = responses.getBalances.slice(0, 3)
|
||||
const result = await client.getBalances(address, options)
|
||||
assertResultMatch(result, expectedResponse, 'getBalances')
|
||||
"getBalances - limit": async (client, address, mockRippled) => {
|
||||
const options = { limit: 3, ledgerVersion: 123456 };
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_lines" },
|
||||
rippledAccountLines.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "ledger" }, rippled.ledger.normal);
|
||||
const expectedResponse = responses.getBalances.slice(0, 3);
|
||||
const result = await client.getBalances(address, options);
|
||||
assertResultMatch(result, expectedResponse, "getBalances");
|
||||
},
|
||||
|
||||
'getBalances - limit & currency': async (client, address, mockRippled) => {
|
||||
const options = {currency: 'USD', limit: 3}
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippledAccountLines.normal)
|
||||
mockRippled.addResponse({command: 'ledger'}, rippled.ledger.normal)
|
||||
"getBalances - limit & currency": async (client, address, mockRippled) => {
|
||||
const options = { currency: "USD", limit: 3 };
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_lines" },
|
||||
rippledAccountLines.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "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')
|
||||
.filter((item) => item.currency === "USD")
|
||||
.slice(0, 3);
|
||||
const result = await client.getBalances(address, options);
|
||||
assertResultMatch(result, expectedResponse, "getBalances");
|
||||
},
|
||||
|
||||
'getBalances - limit & currency & issuer': async (client, address, mockRippled) => {
|
||||
"getBalances - limit & currency & issuer": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
const options = {
|
||||
currency: 'USD',
|
||||
counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
|
||||
limit: 3
|
||||
}
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippledAccountLines.normal)
|
||||
mockRippled.addResponse({command: 'ledger'}, rippled.ledger.normal)
|
||||
|
||||
currency: "USD",
|
||||
counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||
limit: 3,
|
||||
};
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_lines" },
|
||||
rippledAccountLines.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "ledger" }, rippled.ledger.normal);
|
||||
|
||||
const expectedResponse = responses.getBalances
|
||||
.filter(
|
||||
(item) =>
|
||||
item.currency === 'USD' &&
|
||||
item.counterparty === 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
item.currency === "USD" &&
|
||||
item.counterparty === "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
|
||||
)
|
||||
.slice(0, 3)
|
||||
const result = await client.getBalances(address, options)
|
||||
assertResultMatch(result, expectedResponse, 'getBalances')
|
||||
}
|
||||
}
|
||||
.slice(0, 3);
|
||||
const result = await client.getBalances(address, options);
|
||||
assertResultMatch(result, expectedResponse, "getBalances");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from 'assert-diff'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -8,54 +9,78 @@ import {TestSuite} from '../testUtils'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'getFee': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '0.000012')
|
||||
async getFee(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "0.000012");
|
||||
},
|
||||
|
||||
'getFee default': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
client._feeCushion = undefined
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '0.000012')
|
||||
"getFee default": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
client._feeCushion = undefined as unknown as number;
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "0.000012");
|
||||
},
|
||||
|
||||
'getFee - high load_factor': async (client, address, mockRippled) => {
|
||||
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.highLoadFactor)
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '2')
|
||||
"getFee - high load_factor": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.highLoadFactor
|
||||
);
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "2");
|
||||
},
|
||||
|
||||
'getFee - high load_factor with custom maxFeeXRP': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.highLoadFactor)
|
||||
"getFee - high load_factor with custom maxFeeXRP": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
client._maxFeeXRP = "51540";
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "51539.607552");
|
||||
},
|
||||
|
||||
'getFee custom cushion': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
client._feeCushion = 1.4
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '0.000014')
|
||||
"getFee custom cushion": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
client._feeCushion = 1.4;
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "0.000014");
|
||||
},
|
||||
|
||||
// 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({command: 'server_info'}, rippled.server_info.normal)
|
||||
client._feeCushion = 0.9
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '0.000009')
|
||||
"getFee cushion less than 1.0": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
client._feeCushion = 0.9;
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "0.000009");
|
||||
},
|
||||
|
||||
'getFee reporting': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
const fee = await client.getFee()
|
||||
assert.strictEqual(fee, '0.000012')
|
||||
}
|
||||
}
|
||||
"getFee reporting": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
const fee = await client.getFee();
|
||||
assert.strictEqual(fee, "0.000012");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import assert from 'assert-diff'
|
||||
import responses from '../fixtures/responses'
|
||||
import requests from '../fixtures/requests'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {TestSuite, assertResultMatch, assertRejects} from '../testUtils'
|
||||
import { BookOffersRequest } from '../../src'
|
||||
import assert from "assert-diff";
|
||||
|
||||
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 BigNumber from 'bignumber.js'
|
||||
|
||||
// function checkSortingOfOrders(orders) {
|
||||
@@ -41,11 +42,17 @@ import { BookOffersRequest } from '../../src'
|
||||
// }
|
||||
|
||||
function isUSD(currency: string) {
|
||||
return currency === 'USD' || currency === '0000000000000000000000005553440000000000'
|
||||
return (
|
||||
currency === "USD" ||
|
||||
currency === "0000000000000000000000005553440000000000"
|
||||
);
|
||||
}
|
||||
|
||||
function isBTC(currency: string) {
|
||||
return currency === 'BTC' || currency === '0000000000000000000000004254430000000000'
|
||||
return (
|
||||
currency === "BTC" ||
|
||||
currency === "0000000000000000000000004254430000000000"
|
||||
);
|
||||
}
|
||||
|
||||
function normalRippledResponse(request: BookOffersRequest): object {
|
||||
@@ -53,23 +60,27 @@ function normalRippledResponse(request: BookOffersRequest): object {
|
||||
isBTC(request.taker_gets.currency) &&
|
||||
isUSD(request.taker_pays.currency)
|
||||
) {
|
||||
return rippled.book_offers.fabric.requestBookOffersBidsResponse(request)
|
||||
} else if (
|
||||
return rippled.book_offers.fabric.requestBookOffersBidsResponse(request);
|
||||
}
|
||||
if (
|
||||
isUSD(request.taker_gets.currency) &&
|
||||
isBTC(request.taker_pays.currency)
|
||||
) {
|
||||
return rippled.book_offers.fabric.requestBookOffersAsksResponse(request)
|
||||
return rippled.book_offers.fabric.requestBookOffersAsksResponse(request);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
function xrpRippledResponse(request: BookOffersRequest): object {
|
||||
if (request.taker_pays.issuer === 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw') {
|
||||
return rippled.book_offers.xrp_usd
|
||||
} else if (
|
||||
request.taker_gets.issuer === 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw'
|
||||
) {
|
||||
return rippled.book_offers.usd_xrp
|
||||
if (request.taker_pays.issuer === "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw") {
|
||||
return rippled.book_offers.xrp_usd;
|
||||
}
|
||||
if (request.taker_gets.issuer === "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw") {
|
||||
return rippled.book_offers.usd_xrp;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,34 +89,34 @@ function xrpRippledResponse(request: BookOffersRequest): object {
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'normal': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'book_offers'}, normalRippledResponse)
|
||||
async normal(client, address, mockRippled) {
|
||||
mockRippled.addResponse({ command: "book_offers" }, normalRippledResponse);
|
||||
const response = await client.getOrderbook(
|
||||
address,
|
||||
requests.getOrderbook.normal,
|
||||
{limit: 20}
|
||||
)
|
||||
assertResultMatch(response, responses.getOrderbook.normal, 'getOrderbook')
|
||||
{ limit: 20 }
|
||||
);
|
||||
assertResultMatch(response, responses.getOrderbook.normal, "getOrderbook");
|
||||
},
|
||||
|
||||
'invalid options': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'book_offers'}, normalRippledResponse)
|
||||
"invalid options": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "book_offers" }, normalRippledResponse);
|
||||
assertRejects(
|
||||
client.getOrderbook(address, requests.getOrderbook.normal, {
|
||||
// @ts-ignore
|
||||
invalid: 'options'
|
||||
// @ts-expect-error
|
||||
invalid: "options",
|
||||
}),
|
||||
client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'with XRP': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'book_offers'}, xrpRippledResponse)
|
||||
"with XRP": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "book_offers" }, xrpRippledResponse);
|
||||
const response = await client.getOrderbook(
|
||||
address,
|
||||
requests.getOrderbook.withXRP
|
||||
)
|
||||
assertResultMatch(response, responses.getOrderbook.withXRP, 'getOrderbook')
|
||||
);
|
||||
assertResultMatch(response, responses.getOrderbook.withXRP, "getOrderbook");
|
||||
},
|
||||
|
||||
// 'sample XRP/JPY book has orders sorted correctly': async (client, address, mockRippled) => {
|
||||
@@ -140,55 +151,69 @@ export default <TestSuite>{
|
||||
// },
|
||||
|
||||
// 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({command: 'book_offers'}, normalRippledResponse)
|
||||
"sorted so that best deals come first [bad test]": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "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
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'currency & counterparty are correct': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'book_offers'}, normalRippledResponse)
|
||||
"currency & counterparty are correct": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "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)
|
||||
})
|
||||
);
|
||||
[...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);
|
||||
});
|
||||
},
|
||||
|
||||
'direction is correct for bids and asks': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'book_offers'}, normalRippledResponse)
|
||||
"direction is correct for bids and asks": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "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'))
|
||||
}
|
||||
}
|
||||
);
|
||||
assert(response.bids.every((bid) => bid.specification.direction === "buy"));
|
||||
assert(
|
||||
response.asks.every((ask) => ask.specification.direction === "sell")
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import assert from 'assert-diff'
|
||||
import { assertRejects, TestSuite } from '../testUtils'
|
||||
import requests from '../fixtures/requests'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import addresses from "../fixtures/addresses.json";
|
||||
import requests from "../fixtures/requests";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, TestSuite } from "../testUtils";
|
||||
// import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import addresses from '../fixtures/addresses.json'
|
||||
const {getPaths: REQUEST_FIXTURES} = requests
|
||||
const { getPaths: REQUEST_FIXTURES } = requests;
|
||||
// const {getPaths: RESPONSE_FIXTURES} = responses
|
||||
|
||||
const rippledResponse = rippled.path_find.generate.generateIOUPaymentPaths(
|
||||
@@ -12,7 +13,7 @@ const rippledResponse = rippled.path_find.generate.generateIOUPaymentPaths(
|
||||
REQUEST_FIXTURES.normal.source.address,
|
||||
REQUEST_FIXTURES.normal.destination.address,
|
||||
REQUEST_FIXTURES.normal.destination.amount
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -46,12 +47,12 @@ export default <TestSuite>{
|
||||
// const response = await client.getPaths(REQUEST_FIXTURES.XrpToXrp)
|
||||
// assertResultMatch(response, RESPONSE_FIXTURES.XrpToXrp, 'getPaths')
|
||||
// },
|
||||
'source with issuer': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"source with issuer": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths(REQUEST_FIXTURES.issuer),
|
||||
client.errors.NotFoundError
|
||||
)
|
||||
);
|
||||
},
|
||||
// 'XRP 2 XRP - not enough': async (client) => {
|
||||
// return assertRejects(
|
||||
@@ -59,52 +60,52 @@ export default <TestSuite>{
|
||||
// client.errors.NotFoundError
|
||||
// )
|
||||
// },
|
||||
'invalid PathFind': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"invalid PathFind": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
assert.throws(() => {
|
||||
client.getPaths(REQUEST_FIXTURES.invalid)
|
||||
}, /Cannot specify both source.amount/)
|
||||
client.getPaths(REQUEST_FIXTURES.invalid);
|
||||
}, /Cannot specify both source.amount/);
|
||||
},
|
||||
'does not accept currency': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"does not accept currency": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths(REQUEST_FIXTURES.NotAcceptCurrency),
|
||||
client.errors.NotFoundError
|
||||
)
|
||||
);
|
||||
},
|
||||
'no paths': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"no paths": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths(REQUEST_FIXTURES.NoPaths),
|
||||
client.errors.NotFoundError
|
||||
)
|
||||
);
|
||||
},
|
||||
'no paths source amount': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"no paths source amount": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths(REQUEST_FIXTURES.NoPathsSource),
|
||||
client.errors.NotFoundError
|
||||
)
|
||||
);
|
||||
},
|
||||
'no paths with source currencies': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"no paths with source currencies": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths(REQUEST_FIXTURES.NoPathsWithCurrencies),
|
||||
client.errors.NotFoundError
|
||||
)
|
||||
);
|
||||
},
|
||||
'error: srcActNotFound': async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ripple_path_find'}, rippledResponse)
|
||||
"error: srcActNotFound": async (client, _, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ripple_path_find" }, rippledResponse);
|
||||
return assertRejects(
|
||||
client.getPaths({
|
||||
...REQUEST_FIXTURES.normal,
|
||||
source: {address: addresses.NOTFOUND}
|
||||
source: { address: addresses.NOTFOUND },
|
||||
}),
|
||||
client.errors.RippleError
|
||||
)
|
||||
);
|
||||
},
|
||||
// 'send all': async (client) => {
|
||||
// const response = await client.getPaths(REQUEST_FIXTURES.sendAll)
|
||||
// assertResultMatch(response, RESPONSE_FIXTURES.sendAll, 'getPaths')
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import addresses from '../fixtures/addresses.json'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled/accountLines'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const {getTrustlines: RESPONSE_FIXTURES} = responses
|
||||
import addresses from "../fixtures/addresses.json";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled/accountLines";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const { getTrustlines: RESPONSE_FIXTURES } = responses;
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,46 +11,63 @@ const {getTrustlines: RESPONSE_FIXTURES} = responses
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'getTrustlines - filtered': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippled.normal)
|
||||
const options = {currency: 'USD'}
|
||||
const result = await client.getTrustlines(address, options)
|
||||
assertResultMatch(result, RESPONSE_FIXTURES.filtered, 'getTrustlines')
|
||||
"getTrustlines - filtered": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "account_lines" }, rippled.normal);
|
||||
const options = { currency: "USD" };
|
||||
const result = await client.getTrustlines(address, options);
|
||||
assertResultMatch(result, RESPONSE_FIXTURES.filtered, "getTrustlines");
|
||||
},
|
||||
|
||||
'getTrustlines - more than 400 items': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippled.manyItems)
|
||||
const options = {limit: 401}
|
||||
const result = await client.getTrustlines(address, options)
|
||||
"getTrustlines - more than 400 items": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "account_lines" }, rippled.manyItems);
|
||||
const options = { limit: 401 };
|
||||
const result = await client.getTrustlines(address, options);
|
||||
assertResultMatch(
|
||||
result,
|
||||
RESPONSE_FIXTURES.moreThan400Items,
|
||||
'getTrustlines'
|
||||
)
|
||||
"getTrustlines"
|
||||
);
|
||||
},
|
||||
|
||||
'getTrustlines - no options': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippled.normal)
|
||||
await client.getTrustlines(address)
|
||||
"getTrustlines - no options": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "account_lines" }, rippled.normal);
|
||||
await client.getTrustlines(address);
|
||||
},
|
||||
|
||||
'getTrustlines - ripplingDisabled works properly': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippled.ripplingDisabled)
|
||||
const result = await client.getTrustlines(address)
|
||||
"getTrustlines - ripplingDisabled works properly": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_lines" },
|
||||
rippled.ripplingDisabled
|
||||
);
|
||||
const result = await client.getTrustlines(address);
|
||||
assertResultMatch(
|
||||
result,
|
||||
RESPONSE_FIXTURES.ripplingDisabled,
|
||||
'getTrustlines'
|
||||
)
|
||||
"getTrustlines"
|
||||
);
|
||||
},
|
||||
|
||||
'getTrustlines - ledger version option': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_lines'}, rippled.manyItems)
|
||||
const result = await client.getTrustlines(addresses.FOURTH_ACCOUNT, {ledgerVersion: 5})
|
||||
"getTrustlines - ledger version option": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "account_lines" }, rippled.manyItems);
|
||||
const result = await client.getTrustlines(addresses.FOURTH_ACCOUNT, {
|
||||
ledgerVersion: 5,
|
||||
});
|
||||
assertResultMatch(
|
||||
result,
|
||||
RESPONSE_FIXTURES.moreThan400Items,
|
||||
'getTrustlines'
|
||||
)
|
||||
"getTrustlines"
|
||||
);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -8,29 +9,36 @@ import rippled from '../fixtures/rippled'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'returns true when there is another page': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ledger_data'}, rippled.ledger_data.first_page)
|
||||
// @ts-ignore
|
||||
const response = await client.request({command: 'ledger_data'})
|
||||
assert(client.hasNextPage(response))
|
||||
"returns true when there is another page": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_data" },
|
||||
rippled.ledger_data.first_page
|
||||
);
|
||||
const response = await client.request({ command: "ledger_data" });
|
||||
assert(client.hasNextPage(response));
|
||||
},
|
||||
|
||||
'returns false when there are no more pages': async (client, address, mockRippled) => {
|
||||
const rippledResponse = function(request: Request) : object {
|
||||
if ('marker' in request) {
|
||||
return rippled.ledger_data.last_page
|
||||
} else {
|
||||
return rippled.ledger_data.first_page
|
||||
"returns false when there are no more pages": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
const rippledResponse = function (request: Request): object {
|
||||
if ("marker" in request) {
|
||||
return rippled.ledger_data.last_page;
|
||||
}
|
||||
}
|
||||
mockRippled.addResponse({command: 'ledger_data'}, rippledResponse)
|
||||
// @ts-ignore
|
||||
const response = await client.request({command: 'ledger_data'})
|
||||
return rippled.ledger_data.first_page;
|
||||
};
|
||||
mockRippled.addResponse({ command: "ledger_data" }, rippledResponse);
|
||||
const response = await client.request({ command: "ledger_data" });
|
||||
const responseNextPage = await client.requestNextPage(
|
||||
// @ts-ignore
|
||||
{command: 'ledger_data'},
|
||||
{ command: "ledger_data" },
|
||||
response
|
||||
)
|
||||
assert(!client.hasNextPage(responseNextPage))
|
||||
}
|
||||
}
|
||||
);
|
||||
assert(!client.hasNextPage(responseNextPage));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -7,9 +8,9 @@ import {TestSuite} from '../testUtils'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'disconnect & isConnected': async (client, address) => {
|
||||
assert.strictEqual(client.isConnected(), true)
|
||||
await client.disconnect()
|
||||
assert.strictEqual(client.isConnected(), false)
|
||||
}
|
||||
}
|
||||
"disconnect & isConnected": async (client, address) => {
|
||||
assert.strictEqual(client.isConnected(), true);
|
||||
await client.disconnect();
|
||||
assert.strictEqual(client.isConnected(), false);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import addresses from '../fixtures/addresses.json'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import addresses from "../fixtures/addresses.json";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
export default <TestSuite>{
|
||||
'returns true for valid address': async (client, address) => {
|
||||
assert(client.isValidAddress('rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K'))
|
||||
assert(client.isValidAddress(addresses.ACCOUNT_X))
|
||||
assert(client.isValidAddress(addresses.ACCOUNT_T))
|
||||
"returns true for valid address": async (client, address) => {
|
||||
assert(client.isValidAddress("rLczgQHxPhWtjkaQqn3Q6UM8AbRbbRvs5K"));
|
||||
assert(client.isValidAddress(addresses.ACCOUNT_X));
|
||||
assert(client.isValidAddress(addresses.ACCOUNT_T));
|
||||
},
|
||||
|
||||
'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)))
|
||||
}
|
||||
}
|
||||
"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)));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
export default <TestSuite>{
|
||||
'returns true for valid secret': async (client, address) => {
|
||||
assert(client.isValidSecret('snsakdSrZSLkYpCXxfRkS4Sh96PMK'))
|
||||
"returns true for valid secret": async (client, address) => {
|
||||
assert(client.isValidSecret("snsakdSrZSLkYpCXxfRkS4Sh96PMK"));
|
||||
},
|
||||
|
||||
'returns false for invalid secret': async (client, address) => {
|
||||
assert(!client.isValidSecret('foobar'))
|
||||
}
|
||||
}
|
||||
"returns false for invalid secret": async (client, address) => {
|
||||
assert(!client.isValidSecret("foobar"));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,33 +11,51 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareCheckCancel': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async prepareCheckCancel(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareCheckCancel(
|
||||
address,
|
||||
requests.prepareCheckCancel.normal
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCancel.normal, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCancel.normal, "prepare");
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareCheckCancel(
|
||||
address,
|
||||
requests.prepareCheckCancel.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCancel.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCancel.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,45 +11,72 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareCheckCash amount': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareCheckCash amount": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareCheckCash(
|
||||
address,
|
||||
requests.prepareCheckCash.amount
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCash.amount, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCash.amount, "prepare");
|
||||
},
|
||||
|
||||
'prepareCheckCash deliverMin': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareCheckCash deliverMin": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareCheckCash(
|
||||
address,
|
||||
requests.prepareCheckCash.deliverMin
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCash.deliverMin, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCash.deliverMin, "prepare");
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareCheckCash(
|
||||
address,
|
||||
requests.prepareCheckCash.amount,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCash.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCash.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,50 +11,77 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareCheckCreate': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async prepareCheckCreate(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const result = await client.prepareCheckCreate(
|
||||
address,
|
||||
requests.prepareCheckCreate.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCreate.normal, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCreate.normal, "prepare");
|
||||
},
|
||||
|
||||
'prepareCheckCreate full': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareCheckCreate full": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareCheckCreate(
|
||||
address,
|
||||
requests.prepareCheckCreate.full
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCreate.full, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCreate.full, "prepare");
|
||||
},
|
||||
|
||||
'prepareCheckCreate with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareCheckCreate with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareCheckCreate(
|
||||
address,
|
||||
requests.prepareCheckCreate.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareCheckCreate.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(result, responses.prepareCheckCreate.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,58 +11,89 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareEscrowCancellation': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async prepareEscrowCancellation(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareEscrowCancellation(
|
||||
address,
|
||||
requests.prepareEscrowCancellation.normal,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowCancellation.normal,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'prepareEscrowCancellation with memos': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareEscrowCancellation with memos": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareEscrowCancellation(
|
||||
address,
|
||||
requests.prepareEscrowCancellation.memos
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowCancellation.memos,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareEscrowCancellation(
|
||||
address,
|
||||
requests.prepareEscrowCancellation.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowCancellation.ticket,
|
||||
'prepare'
|
||||
)
|
||||
}
|
||||
}
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertRejects, assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
export const config = {
|
||||
// TODO: The mock server right now returns a hard-coded string, no matter
|
||||
// what "Account" value you pass. We'll need it to support more accurate
|
||||
// responses before we can turn these tests on.
|
||||
skipXAddress: true
|
||||
}
|
||||
skipXAddress: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -17,64 +18,108 @@ export const config = {
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareEscrowCreation': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async prepareEscrowCreation(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const result = await client.prepareEscrowCreation(
|
||||
address,
|
||||
requests.prepareEscrowCreation.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareEscrowCreation.normal, 'prepare')
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowCreation.normal,
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'prepareEscrowCreation full': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareEscrowCreation full": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareEscrowCreation(
|
||||
address,
|
||||
requests.prepareEscrowCreation.full
|
||||
)
|
||||
assertResultMatch(result, responses.prepareEscrowCreation.full, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareEscrowCreation.full, "prepare");
|
||||
},
|
||||
|
||||
'prepareEscrowCreation - invalid': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const escrow = Object.assign({}, requests.prepareEscrowCreation.full)
|
||||
delete escrow.amount // Make invalid
|
||||
"prepareEscrowCreation - invalid": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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,
|
||||
'instance.escrowCreation requires property "amount"'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000396',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000396",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareEscrowCreation(
|
||||
address,
|
||||
requests.prepareEscrowCreation.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareEscrowCreation.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowCreation.ticket,
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {TestSuite, assertRejects, assertResultMatch} from '../testUtils'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { TestSuite, assertRejects, assertResultMatch } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,44 +11,75 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareEscrowExecution': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async prepareEscrowExecution(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareEscrowExecution(
|
||||
address,
|
||||
requests.prepareEscrowExecution.normal,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowExecution.normal,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'prepareEscrowExecution - simple': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareEscrowExecution - simple": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareEscrowExecution(
|
||||
address,
|
||||
requests.prepareEscrowExecution.simple
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowExecution.simple,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'prepareEscrowExecution - no condition': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareEscrowExecution - no condition": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
await assertRejects(
|
||||
client.prepareEscrowExecution(
|
||||
address,
|
||||
@@ -56,14 +88,27 @@ export default <TestSuite>{
|
||||
),
|
||||
client.errors.ValidationError,
|
||||
'"condition" and "fulfillment" fields on EscrowFinish must only be specified together.'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'prepareEscrowExecution - no fulfillment': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepareEscrowExecution - no fulfillment": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
await assertRejects(
|
||||
client.prepareEscrowExecution(
|
||||
address,
|
||||
@@ -72,28 +117,37 @@ export default <TestSuite>{
|
||||
),
|
||||
client.errors.ValidationError,
|
||||
'"condition" and "fulfillment" fields on EscrowFinish must only be specified together.'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000396',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000396",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareEscrowExecution(
|
||||
address,
|
||||
requests.prepareEscrowExecution.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareEscrowExecution.ticket,
|
||||
'prepare'
|
||||
)
|
||||
}
|
||||
}
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertRejects, assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,52 +11,88 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'buy order': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrder.buy
|
||||
const result = await client.prepareOrder(address, request)
|
||||
assertResultMatch(result, responses.prepareOrder.buy, 'prepare')
|
||||
"buy order": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = requests.prepareOrder.buy;
|
||||
const result = await client.prepareOrder(address, request);
|
||||
assertResultMatch(result, responses.prepareOrder.buy, "prepare");
|
||||
},
|
||||
|
||||
'buy order with expiration': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrder.expiration
|
||||
const response = responses.prepareOrder.expiration
|
||||
"buy order with expiration": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
);
|
||||
assertResultMatch(result, response, "prepare");
|
||||
},
|
||||
|
||||
'sell order': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrder.sell
|
||||
"sell order": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareOrder.sell, "prepare");
|
||||
},
|
||||
|
||||
'invalid': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = Object.assign({}, requests.prepareOrder.sell)
|
||||
delete request.direction // Make invalid
|
||||
async invalid(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = { ...requests.prepareOrder.sell };
|
||||
delete request.direction; // Make invalid
|
||||
await assertRejects(
|
||||
client.prepareOrder(
|
||||
address,
|
||||
@@ -64,21 +101,34 @@ export default <TestSuite>{
|
||||
),
|
||||
client.errors.ValidationError,
|
||||
'instance.order requires property "direction"'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrder.sell
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
}
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareOrder(
|
||||
address,
|
||||
request,
|
||||
localInstructions
|
||||
);
|
||||
assertResultMatch(result, responses.prepareOrder.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertRejects, assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,90 +11,134 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'prepareOrderCancellation': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrderCancellation.simple
|
||||
async prepareOrderCancellation(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'no instructions': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrderCancellation.simple
|
||||
const result = await client.prepareOrderCancellation(address, request)
|
||||
"no instructions": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = requests.prepareOrderCancellation.simple;
|
||||
const result = await client.prepareOrderCancellation(address, request);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareOrderCancellation.noInstructions,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'with memos': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrderCancellation.withMemos
|
||||
const result = await client.prepareOrderCancellation(address, request)
|
||||
"with memos": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = requests.prepareOrderCancellation.withMemos;
|
||||
const result = await client.prepareOrderCancellation(address, request);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareOrderCancellation.withMemos,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'invalid': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = Object.assign(
|
||||
{},
|
||||
requests.prepareOrderCancellation.withMemos
|
||||
)
|
||||
delete request.orderSequence // Make invalid
|
||||
async invalid(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = {
|
||||
...requests.prepareOrderCancellation.withMemos,
|
||||
};
|
||||
delete request.orderSequence; // Make invalid
|
||||
|
||||
await assertRejects(
|
||||
client.prepareOrderCancellation(address, request),
|
||||
client.errors.ValidationError,
|
||||
'instance.orderCancellation requires property "orderSequence"'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const request = requests.prepareOrderCancellation.simple
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const request = requests.prepareOrderCancellation.simple;
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareOrderCancellation(
|
||||
address,
|
||||
request,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareOrderCancellation.ticket,
|
||||
'prepare'
|
||||
)
|
||||
}
|
||||
}
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,13 @@
|
||||
import assert from 'assert-diff'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
const {preparePaymentChannelClaim: REQUEST_FIXTURES} = requests
|
||||
const {preparePaymentChannelClaim: RESPONSE_FIXTURES} = responses
|
||||
import assert from "assert-diff";
|
||||
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } 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.
|
||||
@@ -13,126 +15,182 @@ const {preparePaymentChannelClaim: RESPONSE_FIXTURES} = responses
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'default': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async default(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const response = await client.preparePaymentChannelClaim(
|
||||
address,
|
||||
REQUEST_FIXTURES.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.normal, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.normal, "prepare");
|
||||
},
|
||||
|
||||
'with renew': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with renew": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const response = await client.preparePaymentChannelClaim(
|
||||
address,
|
||||
REQUEST_FIXTURES.renew,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.renew, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.renew, "prepare");
|
||||
},
|
||||
|
||||
'with close': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with close": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const response = await client.preparePaymentChannelClaim(
|
||||
address,
|
||||
REQUEST_FIXTURES.close,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.close, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.close, "prepare");
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const response = await client.preparePaymentChannelClaim(
|
||||
address,
|
||||
REQUEST_FIXTURES.normal,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.ticket, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, RESPONSE_FIXTURES.ticket, "prepare");
|
||||
},
|
||||
|
||||
'rejects Promise on preparePaymentChannelClaim with renew and close': async (
|
||||
"rejects Promise on preparePaymentChannelClaim with renew and close": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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)
|
||||
)
|
||||
`Expected method to reject. Prepared transaction: ${JSON.stringify(
|
||||
prepared
|
||||
)}`
|
||||
);
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.name, 'ValidationError')
|
||||
assert.strictEqual(err.name, "ValidationError");
|
||||
assert.strictEqual(
|
||||
err.message,
|
||||
'"renew" and "close" flags on PaymentChannelClaim are mutually exclusive'
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
'rejects Promise on preparePaymentChannelClaim with no signature': async (
|
||||
"rejects Promise on preparePaymentChannelClaim with no signature": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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)
|
||||
)
|
||||
`Expected method to reject. Prepared transaction: ${JSON.stringify(
|
||||
prepared
|
||||
)}`
|
||||
);
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.name, 'ValidationError')
|
||||
assert.strictEqual(err.name, "ValidationError");
|
||||
assert.strictEqual(
|
||||
err.message,
|
||||
'"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
export const config = {
|
||||
// TODO: The mock server right now returns a hard-coded string, no matter
|
||||
// what "Account" value you pass. We'll need it to support more accurate
|
||||
// responses before we can turn these tests on.
|
||||
skipXAddress: true
|
||||
}
|
||||
skipXAddress: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -17,62 +18,93 @@ export const config = {
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'preparePaymentChannelCreate': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async preparePaymentChannelCreate(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const result = await client.preparePaymentChannelCreate(
|
||||
address,
|
||||
requests.preparePaymentChannelCreate.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelCreate.normal,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'preparePaymentChannelCreate full': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"preparePaymentChannelCreate full": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.preparePaymentChannelCreate(
|
||||
address,
|
||||
requests.preparePaymentChannelCreate.full
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelCreate.full,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'preparePaymentChannelCreate with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"preparePaymentChannelCreate with ticket": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.preparePaymentChannelCreate(
|
||||
address,
|
||||
requests.preparePaymentChannelCreate.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelCreate.ticket,
|
||||
'prepare'
|
||||
)
|
||||
}
|
||||
}
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,62 +11,89 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'preparePaymentChannelFund': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async preparePaymentChannelFund(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012'
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
};
|
||||
const result = await client.preparePaymentChannelFund(
|
||||
address,
|
||||
requests.preparePaymentChannelFund.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelFund.normal,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'preparePaymentChannelFund full': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"preparePaymentChannelFund full": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.preparePaymentChannelFund(
|
||||
address,
|
||||
requests.preparePaymentChannelFund.full
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelFund.full,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.preparePaymentChannelFund(
|
||||
address,
|
||||
requests.preparePaymentChannelFund.normal,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.preparePaymentChannelFund.ticket,
|
||||
'prepare'
|
||||
)
|
||||
}
|
||||
}
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import assert from 'assert-diff'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import assert from "assert-diff";
|
||||
|
||||
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";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -11,334 +14,513 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'simple test': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"simple test": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
requests.prepareSettings.domain,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.flags, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.flags, "prepare");
|
||||
},
|
||||
'no maxLedgerVersion': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"no maxLedgerVersion": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
requests.prepareSettings.domain,
|
||||
{
|
||||
maxLedgerVersion: null
|
||||
maxLedgerVersion: null as unknown as undefined,
|
||||
}
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.noMaxLedgerVersion,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'no instructions': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"no instructions": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
requests.prepareSettings.domain
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.noInstructions,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'regularKey': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const regularKey = {regularKey: 'rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD'}
|
||||
async regularKey(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const regularKey = { regularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD" };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
regularKey,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.regularKey, 'prepare')
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.regularKey,
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'remove regularKey': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const regularKey = {regularKey: null}
|
||||
"remove regularKey": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const regularKey = { regularKey: null };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
regularKey,
|
||||
regularKey as unknown as FormattedSettings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.removeRegularKey,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'flag set': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {requireDestinationTag: true}
|
||||
"flag set": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = { requireDestinationTag: true };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.flagSet, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.flagSet, "prepare");
|
||||
},
|
||||
'flag clear': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {requireDestinationTag: false}
|
||||
"flag clear": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = { requireDestinationTag: false };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.flagClear, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.flagClear, "prepare");
|
||||
},
|
||||
'set depositAuth flag': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {depositAuth: true}
|
||||
"set depositAuth flag": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = { depositAuth: true };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.flagSetDepositAuth,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'clear depositAuth flag': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {depositAuth: false}
|
||||
"clear depositAuth flag": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = { depositAuth: false };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.flagClearDepositAuth,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'integer field clear': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {transferRate: null}
|
||||
"integer field clear": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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)
|
||||
);
|
||||
assert(response);
|
||||
assert.strictEqual(JSON.parse(response.txJSON).TransferRate, 0);
|
||||
},
|
||||
'set transferRate': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = {transferRate: 1}
|
||||
"set transferRate": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = { transferRate: 1 };
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.setTransferRate,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'set signers': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = requests.prepareSettings.signers.normal
|
||||
"set signers": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.signers, "prepare");
|
||||
},
|
||||
'signers no threshold': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = requests.prepareSettings.signers.noThreshold
|
||||
"signers no threshold": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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)
|
||||
)
|
||||
`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')
|
||||
);
|
||||
assert.strictEqual(err.name, "ValidationError");
|
||||
}
|
||||
},
|
||||
'signers no weights': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = requests.prepareSettings.signers.noWeights
|
||||
"signers no weights": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = requests.prepareSettings.signers.noWeights;
|
||||
const localInstructions = {
|
||||
signersCount: 1,
|
||||
...instructionsWithMaxLedgerVersionOffset
|
||||
}
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
};
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.noWeights, 'prepare')
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.noWeights, "prepare");
|
||||
},
|
||||
'fee for multisign': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"fee for multisign": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
signersCount: 4,
|
||||
...instructionsWithMaxLedgerVersionOffset
|
||||
}
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
};
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
requests.prepareSettings.domain,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.flagsMultisign,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'no signer list': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const settings = requests.prepareSettings.noSignerEntries
|
||||
"no signer list": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const settings = requests.prepareSettings.noSignerEntries;
|
||||
const localInstructions = {
|
||||
signersCount: 1,
|
||||
...instructionsWithMaxLedgerVersionOffset
|
||||
}
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
};
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
assertResultMatch(
|
||||
response,
|
||||
responses.prepareSettings.noSignerList,
|
||||
'prepare'
|
||||
)
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
'invalid': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async invalid(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
// domain must be a string
|
||||
const settings = Object.assign({}, requests.prepareSettings.domain, {
|
||||
domain: 123
|
||||
})
|
||||
const settings = { ...requests.prepareSettings.domain, domain: 123 };
|
||||
const localInstructions = {
|
||||
signersCount: 4,
|
||||
...instructionsWithMaxLedgerVersionOffset
|
||||
}
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
settings,
|
||||
localInstructions
|
||||
)
|
||||
);
|
||||
throw new Error(
|
||||
'Expected method to reject. Prepared transaction: ' +
|
||||
JSON.stringify(response)
|
||||
)
|
||||
`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')
|
||||
"instance.settings.domain is not of a type(s) string"
|
||||
);
|
||||
assert.strictEqual(err.name, "ValidationError");
|
||||
}
|
||||
},
|
||||
'offline': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
async offline(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
|
||||
const settings = requests.prepareSettings.domain
|
||||
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')
|
||||
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({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"prepare settings with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const instructions = {
|
||||
ticketSequence: 23,
|
||||
maxLedgerVersion: 8820051,
|
||||
fee: '0.000012'
|
||||
}
|
||||
fee: "0.000012",
|
||||
};
|
||||
const response = await client.prepareSettings(
|
||||
address,
|
||||
requests.prepareSettings.domain,
|
||||
instructions
|
||||
)
|
||||
assertResultMatch(response, responses.prepareSettings.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(response, responses.prepareSettings.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {assertResultMatch, TestSuite} from '../testUtils'
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertResultMatch, TestSuite } from "../testUtils";
|
||||
// import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
// import requests from '../fixtures/requests'
|
||||
// import {ValidationError} from 'xrpl-local/common/errors'
|
||||
// import binary from 'ripple-binary-codec'
|
||||
@@ -19,48 +19,70 @@ import rippled from '../fixtures/rippled'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'creates a ticket successfully with a sequence number': async (
|
||||
"creates a ticket successfully with a sequence number": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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')
|
||||
fee: "0.000012",
|
||||
},
|
||||
};
|
||||
const response = await client.prepareTicketCreate(address, 2);
|
||||
assertResultMatch(response, expected, "prepare");
|
||||
},
|
||||
|
||||
'creates a ticket successfully with another ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"creates a ticket successfully with another ticket": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "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'
|
||||
}
|
||||
}
|
||||
fee: "0.000012",
|
||||
},
|
||||
};
|
||||
const instructions = {
|
||||
maxLedgerVersion: 8819954,
|
||||
ticketSequence: 23,
|
||||
fee: '0.000012'
|
||||
}
|
||||
const response = await client.prepareTicketCreate(address, 1, instructions)
|
||||
assertResultMatch(response, expected, 'prepare')
|
||||
}
|
||||
}
|
||||
fee: "0.000012",
|
||||
};
|
||||
const response = await client.prepareTicketCreate(address, 1, instructions);
|
||||
assertResultMatch(response, expected, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,9 @@
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {assertRejects, assertResultMatch, TestSuite} from '../testUtils'
|
||||
const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, assertResultMatch, TestSuite } from "../testUtils";
|
||||
|
||||
const instructionsWithMaxLedgerVersionOffset = { maxLedgerVersionOffset: 100 };
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -10,51 +11,87 @@ const instructionsWithMaxLedgerVersionOffset = {maxLedgerVersionOffset: 100}
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'simple': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async simple(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.simple,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(result, responses.prepareTrustline.simple, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareTrustline.simple, "prepare");
|
||||
},
|
||||
|
||||
'frozen': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async frozen(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.frozen
|
||||
)
|
||||
assertResultMatch(result, responses.prepareTrustline.frozen, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareTrustline.frozen, "prepare");
|
||||
},
|
||||
|
||||
'complex': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
async complex(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.complex,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(result, responses.prepareTrustline.complex, 'prepare')
|
||||
);
|
||||
assertResultMatch(result, responses.prepareTrustline.complex, "prepare");
|
||||
},
|
||||
|
||||
'invalid': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const trustline = Object.assign({}, requests.prepareTrustline.complex)
|
||||
delete trustline.limit // Make invalid
|
||||
async invalid(client, address, mockRippled) {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const trustline = { ...requests.prepareTrustline.complex };
|
||||
delete trustline.limit; // Make invalid
|
||||
|
||||
await assertRejects(
|
||||
client.prepareTrustline(
|
||||
@@ -64,37 +101,59 @@ export default <TestSuite>{
|
||||
),
|
||||
client.errors.ValidationError,
|
||||
'instance.trustline requires property "limit"'
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'xaddress-issuer': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"xaddress-issuer": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const result = await client.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.issuedXAddress,
|
||||
instructionsWithMaxLedgerVersionOffset
|
||||
)
|
||||
assertResultMatch(result, responses.prepareTrustline.issuedXAddress, 'prepare')
|
||||
);
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.prepareTrustline.issuedXAddress,
|
||||
"prepare"
|
||||
);
|
||||
},
|
||||
|
||||
'with ticket': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"with ticket": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const localInstructions = {
|
||||
...instructionsWithMaxLedgerVersionOffset,
|
||||
maxFee: '0.000012',
|
||||
ticketSequence: 23
|
||||
}
|
||||
maxFee: "0.000012",
|
||||
ticketSequence: 23,
|
||||
};
|
||||
const result = await client.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.simple,
|
||||
localInstructions
|
||||
)
|
||||
assertResultMatch(result, responses.prepareTrustline.ticket, 'prepare')
|
||||
}
|
||||
}
|
||||
);
|
||||
assertResultMatch(result, responses.prepareTrustline.ticket, "prepare");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {TestSuite, assertResultMatch} from '../testUtils'
|
||||
import responses from "../fixtures/responses";
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { TestSuite, assertResultMatch } from "../testUtils";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -8,31 +8,41 @@ import {TestSuite, assertResultMatch} from '../testUtils'
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'request account_objects': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_objects', account: address}, rippled.account_objects.normal)
|
||||
const result = await client.request({command: 'account_objects',
|
||||
account: address
|
||||
})
|
||||
"request account_objects": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_objects", account: address },
|
||||
rippled.account_objects.normal
|
||||
);
|
||||
const result = await client.request({
|
||||
command: "account_objects",
|
||||
account: address,
|
||||
});
|
||||
|
||||
assertResultMatch(
|
||||
result.result,
|
||||
responses.getAccountObjects,
|
||||
'AccountObjectsResponse'
|
||||
)
|
||||
"AccountObjectsResponse"
|
||||
);
|
||||
},
|
||||
|
||||
'request account_objects - invalid options': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'account_objects', account: address}, rippled.account_objects.normal)
|
||||
// @ts-ignore Intentionally no local validation of these options
|
||||
const result = await client.request({command: 'account_objects',
|
||||
"request account_objects - invalid options": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_objects", account: address },
|
||||
rippled.account_objects.normal
|
||||
);
|
||||
const result = await client.request({
|
||||
command: "account_objects",
|
||||
account: address,
|
||||
invalid: 'options'
|
||||
})
|
||||
});
|
||||
|
||||
assertResultMatch(
|
||||
result.result,
|
||||
responses.getAccountObjects,
|
||||
'AccountObjectsResponse'
|
||||
)
|
||||
}
|
||||
}
|
||||
"AccountObjectsResponse"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import assert from 'assert-diff'
|
||||
import {assertRejects, TestSuite} from '../testUtils'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import assert from "assert-diff";
|
||||
|
||||
const rippledResponse = function(request: Request) : object {
|
||||
if ('marker' in request) {
|
||||
return rippled.ledger_data.last_page
|
||||
} else {
|
||||
return rippled.ledger_data.first_page
|
||||
import rippled from "../fixtures/rippled";
|
||||
import { assertRejects, TestSuite } from "../testUtils";
|
||||
|
||||
const rippledResponse = function (request: Request): object {
|
||||
if ("marker" in request) {
|
||||
return rippled.ledger_data.last_page;
|
||||
}
|
||||
}
|
||||
return rippled.ledger_data.first_page;
|
||||
};
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -16,37 +16,35 @@ const rippledResponse = function(request: Request) : object {
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'requests the next page': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ledger_data'}, rippledResponse)
|
||||
// @ts-ignore
|
||||
const response = await client.request({command: 'ledger_data'})
|
||||
"requests the next page": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({ command: "ledger_data" }, rippledResponse);
|
||||
const response = await client.request({ command: "ledger_data" });
|
||||
const responseNextPage = await client.requestNextPage(
|
||||
// @ts-ignore
|
||||
{command: 'ledger_data'},
|
||||
{ command: "ledger_data" },
|
||||
response
|
||||
)
|
||||
);
|
||||
assert.equal(
|
||||
// @ts-ignore
|
||||
responseNextPage.result.state[0].index,
|
||||
'000B714B790C3C79FEE00D17C4DEB436B375466F29679447BA64F265FD63D731'
|
||||
)
|
||||
"000B714B790C3C79FEE00D17C4DEB436B375466F29679447BA64F265FD63D731"
|
||||
);
|
||||
},
|
||||
|
||||
'rejects when there are no more pages': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'ledger_data'}, rippledResponse)
|
||||
// @ts-ignore
|
||||
const response = await client.request({command: 'ledger_data'})
|
||||
"rejects when there are no more pages": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({ command: "ledger_data" }, rippledResponse);
|
||||
const response = await client.request({ command: "ledger_data" });
|
||||
const responseNextPage = await client.requestNextPage(
|
||||
// @ts-ignore
|
||||
{command: 'ledger_data'},
|
||||
{ command: "ledger_data" },
|
||||
response
|
||||
)
|
||||
assert(!client.hasNextPage(responseNextPage))
|
||||
);
|
||||
assert(!client.hasNextPage(responseNextPage));
|
||||
await assertRejects(
|
||||
// @ts-ignore
|
||||
client.requestNextPage({command: 'ledger_data'}, responseNextPage),
|
||||
client.requestNextPage({ command: "ledger_data" }, responseNextPage),
|
||||
Error,
|
||||
'response does not have a next page'
|
||||
)
|
||||
}
|
||||
}
|
||||
"response does not have a next page"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import assert from 'assert-diff'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import * as schemaValidator from 'xrpl-local/common/schema-validator'
|
||||
import assert from "assert-diff";
|
||||
import binary from "ripple-binary-codec";
|
||||
|
||||
const {sign: REQUEST_FIXTURES} = requests
|
||||
const {sign: RESPONSE_FIXTURES} = responses
|
||||
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";
|
||||
|
||||
const { sign: REQUEST_FIXTURES } = requests;
|
||||
const { sign: RESPONSE_FIXTURES } = responses;
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -15,413 +17,453 @@ const {sign: RESPONSE_FIXTURES} = responses
|
||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'sign': async (client, address) => {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret)
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.normal)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
async sign(client, address) {
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
const result = 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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"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",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const txParams = JSON.stringify(lowercaseMemoTxJson);
|
||||
const result = client.sign(txParams, secret);
|
||||
assert.deepEqual(result, {
|
||||
signedTransaction: '120000228000000023000022B8240000000C2E0000270F201B00D5A36761400000000098968068400000000000000C73210305E09ED602D40AB1AF65646A4007C2DAC17CB6CDACDE301E74FB2D728EA057CF744730450221009C00E8439E017CA622A5A1EE7643E26B4DE9C808DE2ABE45D33479D49A4CEC66022062175BE8733442FA2A4D9A35F85A57D58252AE7B19A66401FE238B36FA28E5A081146C1856D0E36019EA75C56D7E8CBA6E35F9B3F71583147FB49CD110A1C46838788CD12764E3B0F837E0DDF9EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1F1',
|
||||
id: '41B9CB78D8E18A796CDD4B0BC6FB0EA19F64C4F25FDE23049197852CAB71D10D'
|
||||
})
|
||||
},
|
||||
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({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
"sign with paths": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
const payment = {
|
||||
source: {
|
||||
address: address,
|
||||
address,
|
||||
amount: {
|
||||
currency: 'drops',
|
||||
value: '100'
|
||||
}
|
||||
currency: "drops",
|
||||
value: "100",
|
||||
},
|
||||
},
|
||||
destination: {
|
||||
address: 'rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj',
|
||||
address: "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj",
|
||||
minAmount: {
|
||||
currency: 'USD',
|
||||
value: '0.00004579644712312366',
|
||||
counterparty: 'rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc'
|
||||
}
|
||||
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)
|
||||
paths:
|
||||
'[[{"currency":"USD","issuer":"rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc"}]]',
|
||||
};
|
||||
const ret = await client.preparePayment(address, payment, {
|
||||
sequence: 1,
|
||||
maxLedgerVersion: 15696358,
|
||||
});
|
||||
const result = client.sign(ret.txJSON, secret);
|
||||
assert.deepEqual(result, {
|
||||
signedTransaction: '12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900',
|
||||
id: '78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796'
|
||||
})
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
signedTransaction:
|
||||
"12000022800200002400000001201B00EF81E661EC6386F26FC0FFFF0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461968400000000000000C6940000000000000646AD3504529A0465E2E0000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D1664619732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200A693FB5CA6B21250EBDFD8CFF526EE0DF7C9E4E31EB0660692E75E6A93BF5F802203CC39463DDA21386898CA31E18AD1A6828647D65741DD637BAD71BC83E29DB9481145E7B112523F68D2F5E879DB4EAC51C6698A693048314CA6EDC7A28252DAEA6F2045B24F4D7C333E146170112300000000000000000000000005553440000000000054F6F784A58F9EFB0A9EB90B83464F9D166461900",
|
||||
id: "78874FE5F5299FEE3EA85D3CF6C1FB1F1D46BB08F716662A3E3D1F0ADE4EF796",
|
||||
});
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'already signed': async (client, address) => {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, secret)
|
||||
"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/)
|
||||
const tx = JSON.stringify(binary.decode(result.signedTransaction));
|
||||
client.sign(tx, secret);
|
||||
}, /txJSON must not contain "TxnSignature" or "Signers" properties/);
|
||||
},
|
||||
|
||||
'EscrowExecution': async (client, address) => {
|
||||
const secret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb'
|
||||
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, secret)
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.escrow)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
async EscrowExecution(client, address) {
|
||||
const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
|
||||
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, secret);
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.escrow);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'signAs': async (client, address) => {
|
||||
const txJSON = REQUEST_FIXTURES.signAs
|
||||
const secret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb'
|
||||
async signAs(client, address) {
|
||||
const txJSON = REQUEST_FIXTURES.signAs;
|
||||
const secret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
|
||||
const signature = client.sign(JSON.stringify(txJSON), secret, {
|
||||
signAs: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
})
|
||||
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs)
|
||||
signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
});
|
||||
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs);
|
||||
},
|
||||
|
||||
'withKeypair': async (client, address) => {
|
||||
async withKeypair(client, address) {
|
||||
const keypair = {
|
||||
privateKey:
|
||||
'00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A',
|
||||
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A",
|
||||
publicKey:
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
}
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair)
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.normal)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8",
|
||||
};
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair);
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.normal);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'withKeypair already signed': async (client, address) => {
|
||||
"withKeypair already signed": async (client, address) => {
|
||||
const keypair = {
|
||||
privateKey:
|
||||
'00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A',
|
||||
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A",
|
||||
publicKey:
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
}
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair)
|
||||
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8",
|
||||
};
|
||||
const result = client.sign(REQUEST_FIXTURES.normal.txJSON, keypair);
|
||||
assert.throws(() => {
|
||||
const tx = JSON.stringify(binary.decode(result.signedTransaction))
|
||||
client.sign(tx, keypair)
|
||||
}, /txJSON must not contain "TxnSignature" or "Signers" properties/)
|
||||
const tx = JSON.stringify(binary.decode(result.signedTransaction));
|
||||
client.sign(tx, keypair);
|
||||
}, /txJSON must not contain "TxnSignature" or "Signers" properties/);
|
||||
},
|
||||
|
||||
'withKeypair EscrowExecution': async (client, address) => {
|
||||
"withKeypair EscrowExecution": async (client, address) => {
|
||||
const keypair = {
|
||||
privateKey:
|
||||
'001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7',
|
||||
"001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7",
|
||||
publicKey:
|
||||
'0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020'
|
||||
}
|
||||
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair)
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.escrow)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
};
|
||||
const result = client.sign(REQUEST_FIXTURES.escrow.txJSON, keypair);
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.escrow);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'withKeypair signAs': async (client, address) => {
|
||||
const txJSON = REQUEST_FIXTURES.signAs
|
||||
"withKeypair signAs": async (client, address) => {
|
||||
const txJSON = REQUEST_FIXTURES.signAs;
|
||||
const keypair = {
|
||||
privateKey:
|
||||
'001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7',
|
||||
"001ACAAEDECE405B2A958212629E16F2EB46B153EEE94CDD350FDEFF52795525B7",
|
||||
publicKey:
|
||||
'0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020'
|
||||
}
|
||||
"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||
};
|
||||
const signature = client.sign(JSON.stringify(txJSON), keypair, {
|
||||
signAs: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
})
|
||||
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs)
|
||||
signAs: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
});
|
||||
assert.deepEqual(signature, RESPONSE_FIXTURES.signAs);
|
||||
},
|
||||
|
||||
'succeeds - prepared payment': async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
"succeeds - prepared payment": async (client, address, mockRippled) => {
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const payment = await client.preparePayment(address, {
|
||||
source: {
|
||||
address: address,
|
||||
address,
|
||||
maxAmount: {
|
||||
value: '1',
|
||||
currency: 'drops'
|
||||
}
|
||||
value: "1",
|
||||
currency: "drops",
|
||||
},
|
||||
},
|
||||
destination: {
|
||||
address: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r',
|
||||
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
|
||||
amount: {
|
||||
value: '1',
|
||||
currency: 'drops'
|
||||
}
|
||||
}
|
||||
})
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
const result = client.sign(payment.txJSON, secret)
|
||||
value: "1",
|
||||
currency: "drops",
|
||||
},
|
||||
},
|
||||
});
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
const result = client.sign(payment.txJSON, secret);
|
||||
const expectedResult = {
|
||||
signedTransaction:
|
||||
'12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648',
|
||||
id: '88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700'
|
||||
}
|
||||
assert.deepEqual(result, expectedResult)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
"12000022800000002400000017201B008694F261400000000000000168400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100A9C91D4CFAE45686146EE0B56D4C53A2E7C2D672FB834D43E0BE2D2E9106519A022075DDA2F92DE552B0C45D83D4E6D35889B3FBF51BFBBD9B25EBF70DE3C96D0D6681145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648",
|
||||
id: "88D6B913C66279EA31ADC25C5806C48B2D4E5680261666790A736E1961217700",
|
||||
};
|
||||
assert.deepEqual(result, expectedResult);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'succeeds - no flags': async (client, address) => {
|
||||
"succeeds - no flags": async (client, address) => {
|
||||
const txJSON =
|
||||
'{"TransactionType":"Payment","Account":"r45Rev1EXGxy2hAUmJPCne97KUE7qyrD3j","Destination":"rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r","Amount":"20000000","Sequence":1,"Fee":"12"}'
|
||||
const secret = 'shotKgaEotpcYsshSE39vmSnBDRim'
|
||||
const result = client.sign(txJSON, secret)
|
||||
'{"TransactionType":"Payment","Account":"r45Rev1EXGxy2hAUmJPCne97KUE7qyrD3j","Destination":"rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r","Amount":"20000000","Sequence":1,"Fee":"12"}';
|
||||
const secret = "shotKgaEotpcYsshSE39vmSnBDRim";
|
||||
const result = client.sign(txJSON, secret);
|
||||
const expectedResult = {
|
||||
signedTransaction:
|
||||
'1200002400000001614000000001312D0068400000000000000C7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100C104B7B97C31FACA4597E7D6FCF13BD85BD11375963A62A0AC45B0061236E39802207784F157F6A98DFC85B051CDDF61CC3084C4F5750B82674801C8E9950280D1998114EE3046A5DDF8422C40DDB93F1D522BB4FE6419158314FDB08D07AAA0EB711793A3027304D688E10C3648',
|
||||
id: '0596925967F541BF332FF6756645B2576A9858414B5B363DC3D34915BE8A70D6'
|
||||
}
|
||||
const decoded = binary.decode(result.signedTransaction)
|
||||
"1200002400000001614000000001312D0068400000000000000C7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100C104B7B97C31FACA4597E7D6FCF13BD85BD11375963A62A0AC45B0061236E39802207784F157F6A98DFC85B051CDDF61CC3084C4F5750B82674801C8E9950280D1998114EE3046A5DDF8422C40DDB93F1D522BB4FE6419158314FDB08D07AAA0EB711793A3027304D688E10C3648",
|
||||
id: "0596925967F541BF332FF6756645B2576A9858414B5B363DC3D34915BE8A70D6",
|
||||
};
|
||||
const decoded = binary.decode(result.signedTransaction);
|
||||
assert(
|
||||
decoded.Flags == null,
|
||||
`Flags = ${decoded.Flags}, should be undefined`
|
||||
)
|
||||
assert.deepEqual(result, expectedResult)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
);
|
||||
assert.deepEqual(result, expectedResult);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'sign succeeds with source.amount/destination.minAmount': async (
|
||||
"sign succeeds with source.amount/destination.minAmount": async (
|
||||
client,
|
||||
address
|
||||
) => {
|
||||
// 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)
|
||||
'{"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 expectedResult = {
|
||||
signedTransaction:
|
||||
'12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376',
|
||||
id: '1C558AA9B926C24FB6BBD6950B2DB1350A83F9F12E4385208867907019761A2D'
|
||||
}
|
||||
const decoded = binary.decode(result.signedTransaction)
|
||||
"12000022800200002400000017201B0086955361EC6386F26FC0FFFF0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A68400000000000000C69D4438D7EA4C6800000000000000000000000000047425000000000000C155FFE99C8C91F67083CEFFDB69EBFE76348CA6AD4446F8C5D8A5E0B0000000000000000000000005553440000000000DC596C88BCDE4E818D416FCDEEBF2C8656BADC9A7321022B05847086686F9D0499B13136B94AD4323EE1B67D4C429ECC987AB35ACFA34574473045022100D9634523D8E232D4A7807A71856023D82AC928FA29848571B820867898413B5F022041AC00EC1F81A26A6504EBF844A38CC3204694EF2CC1A97A87632721631F93DA81145E7B112523F68D2F5E879DB4EAC51C6698A6930483149F500E50C2F016CA01945E5A1E5846B61EF2D376",
|
||||
id: "1C558AA9B926C24FB6BBD6950B2DB1350A83F9F12E4385208867907019761A2D",
|
||||
};
|
||||
const decoded = binary.decode(result.signedTransaction);
|
||||
assert(
|
||||
decoded.Flags === 2147614720,
|
||||
`Flags = ${decoded.Flags}, should be 2147614720`
|
||||
)
|
||||
assert.deepEqual(result, expectedResult)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
);
|
||||
assert.deepEqual(result, expectedResult);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'throws when encoded tx does not match decoded tx - prepared payment': async (
|
||||
"throws when encoded tx does not match decoded tx - prepared payment": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const payment = await client.preparePayment(address, {
|
||||
source: {
|
||||
address: address,
|
||||
address,
|
||||
maxAmount: {
|
||||
value: '1.1234567',
|
||||
currency: 'drops'
|
||||
}
|
||||
value: "1.1234567",
|
||||
currency: "drops",
|
||||
},
|
||||
},
|
||||
destination: {
|
||||
address: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r',
|
||||
address: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
|
||||
amount: {
|
||||
value: '1.1234567',
|
||||
currency: 'drops'
|
||||
}
|
||||
}
|
||||
})
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
value: "1.1234567",
|
||||
currency: "drops",
|
||||
},
|
||||
},
|
||||
});
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
assert.throws(() => {
|
||||
client.sign(payment.txJSON, secret)
|
||||
}, /^Error: 1\.1234567 is an illegal amount/)
|
||||
client.sign(payment.txJSON, secret);
|
||||
}, /^Error: 1\.1234567 is an illegal amount/);
|
||||
},
|
||||
|
||||
'throws when encoded tx does not match decoded tx - prepared order': async (
|
||||
"throws when encoded tx does not match decoded tx - prepared order": async (
|
||||
client,
|
||||
address,
|
||||
mockRippled
|
||||
) => {
|
||||
mockRippled.addResponse({command: 'server_info'}, rippled.server_info.normal)
|
||||
mockRippled.addResponse({command: 'fee'}, rippled.fee)
|
||||
mockRippled.addResponse({command: 'ledger_current'}, rippled.ledger_current)
|
||||
mockRippled.addResponse({command: 'account_info'}, rippled.account_info.normal)
|
||||
mockRippled.addResponse(
|
||||
{ command: "server_info" },
|
||||
rippled.server_info.normal
|
||||
);
|
||||
mockRippled.addResponse({ command: "fee" }, rippled.fee);
|
||||
mockRippled.addResponse(
|
||||
{ command: "ledger_current" },
|
||||
rippled.ledger_current
|
||||
);
|
||||
mockRippled.addResponse(
|
||||
{ command: "account_info" },
|
||||
rippled.account_info.normal
|
||||
);
|
||||
const order = {
|
||||
direction: 'sell',
|
||||
direction: "sell",
|
||||
quantity: {
|
||||
currency: 'USD',
|
||||
counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
|
||||
value: '3.140000'
|
||||
currency: "USD",
|
||||
counterparty: "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||
value: "3.140000",
|
||||
},
|
||||
totalPrice: {
|
||||
currency: 'XRP',
|
||||
value: '31415'
|
||||
}
|
||||
}
|
||||
const prepared = await client.prepareOrder(address, order, {sequence: 123})
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
currency: "XRP",
|
||||
value: "31415",
|
||||
},
|
||||
};
|
||||
const prepared = await client.prepareOrder(address, order, {
|
||||
sequence: 123,
|
||||
});
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
try {
|
||||
client.sign(prepared.txJSON, secret)
|
||||
return Promise.reject(new Error('client.sign should have thrown'))
|
||||
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.name, "ValidationError");
|
||||
assert.equal(
|
||||
error.message,
|
||||
'Serialized transaction does not match original txJSON. See `error.data`'
|
||||
)
|
||||
"Serialized transaction does not match original txJSON. See `error.data`"
|
||||
);
|
||||
assert.deepEqual(error.data.diff, {
|
||||
TakerGets: {
|
||||
value: '3.14'
|
||||
}
|
||||
})
|
||||
value: "3.14",
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
'throws when encoded tx does not match decoded tx - AccountSet': async (
|
||||
"throws when encoded tx does not match decoded tx - AccountSet": async (
|
||||
client,
|
||||
address
|
||||
) => {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
const request = {
|
||||
// TODO: This fails when address is X-address
|
||||
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1.2","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
|
||||
instructions: {
|
||||
fee: '0.0000012',
|
||||
fee: "0.0000012",
|
||||
sequence: 23,
|
||||
maxLedgerVersion: 8820051
|
||||
}
|
||||
}
|
||||
maxLedgerVersion: 8820051,
|
||||
},
|
||||
};
|
||||
|
||||
assert.throws(() => {
|
||||
client.sign(request.txJSON, secret)
|
||||
}, /Error: 1\.2 is an illegal amount/)
|
||||
client.sign(request.txJSON, secret);
|
||||
}, /Error: 1\.2 is an illegal amount/);
|
||||
},
|
||||
|
||||
'throws when encoded tx does not match decoded tx - higher fee': async (
|
||||
"throws when encoded tx does not match decoded tx - higher fee": async (
|
||||
client,
|
||||
address
|
||||
) => {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
const secret = "shsWGZcmZz6YsWWmcnpfr6fLTdtFV";
|
||||
const request = {
|
||||
// TODO: This fails when address is X-address
|
||||
txJSON: `{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"6578616D706C652E636F6D","LastLedgerSequence":8820051,"Fee":"1123456.7","Sequence":23,"SigningPubKey":"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8"}`,
|
||||
instructions: {
|
||||
fee: '1.1234567',
|
||||
fee: "1.1234567",
|
||||
sequence: 23,
|
||||
maxLedgerVersion: 8820051
|
||||
}
|
||||
}
|
||||
maxLedgerVersion: 8820051,
|
||||
},
|
||||
};
|
||||
|
||||
assert.throws(() => {
|
||||
client.sign(request.txJSON, secret)
|
||||
}, /Error: 1123456\.7 is an illegal amount/)
|
||||
client.sign(request.txJSON, secret);
|
||||
}, /Error: 1123456\.7 is an illegal amount/);
|
||||
},
|
||||
|
||||
'throws when Fee exceeds maxFeeXRP (in drops)': async (client, address) => {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
"throws when Fee exceeds maxFeeXRP (in drops)": async (client, address) => {
|
||||
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',
|
||||
fee: "2.01",
|
||||
sequence: 23,
|
||||
maxLedgerVersion: 8820051
|
||||
}
|
||||
}
|
||||
maxLedgerVersion: 8820051,
|
||||
},
|
||||
};
|
||||
|
||||
assert.throws(() => {
|
||||
client.sign(request.txJSON, secret)
|
||||
}, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./)
|
||||
client.sign(request.txJSON, secret);
|
||||
}, /Fee" should not exceed "2000000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./);
|
||||
},
|
||||
|
||||
'throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP': async (
|
||||
"throws when Fee exceeds maxFeeXRP (in drops) - custom maxFeeXRP": async (
|
||||
client,
|
||||
address
|
||||
) => {
|
||||
client._maxFeeXRP = '1.9'
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
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',
|
||||
fee: "2.01",
|
||||
sequence: 23,
|
||||
maxLedgerVersion: 8820051
|
||||
}
|
||||
}
|
||||
maxLedgerVersion: 8820051,
|
||||
},
|
||||
};
|
||||
|
||||
assert.throws(() => {
|
||||
client.sign(request.txJSON, secret)
|
||||
}, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./)
|
||||
client.sign(request.txJSON, secret);
|
||||
}, /Fee" should not exceed "1900000"\. To use a higher fee, set `maxFeeXRP` in the Client constructor\./);
|
||||
},
|
||||
|
||||
'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
|
||||
}
|
||||
}
|
||||
"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 result = client.sign(request.txJSON, secret);
|
||||
|
||||
const expectedResponse = {
|
||||
signedTransaction:
|
||||
'12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304',
|
||||
id: '061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864'
|
||||
}
|
||||
const expectedResponse = {
|
||||
signedTransaction:
|
||||
"12000322800000002400000017201B008695536840000000001EAB90732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402200203F219F5371D2C6506888B1B02B27E74998F7A42D412C32FE319AC1A5B8DEF02205959A1B02253ACCCE542759E9886466C56D16B04676FA492AD34AA0E877E91F381145E7B112523F68D2F5E879DB4EAC51C6698A69304",
|
||||
id: "061D5593E0A117F389826419CAC049A73C7CFCA65A20B788781D41240143D864",
|
||||
};
|
||||
|
||||
assert.deepEqual(result, expectedResponse)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
assert.deepEqual(result, expectedResponse);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
"sign with ticket": async (client, address) => {
|
||||
const secret = "sn7n5R1cR5Y3fRFkuWXA94Ts1frVJ";
|
||||
const result = client.sign(REQUEST_FIXTURES.ticket.txJSON, secret);
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.ticket);
|
||||
schemaValidator.schemaValidate("sign", result);
|
||||
},
|
||||
|
||||
'sign with ticket': async (client, address) => {
|
||||
const secret = 'sn7n5R1cR5Y3fRFkuWXA94Ts1frVJ'
|
||||
const result = client.sign(REQUEST_FIXTURES.ticket.txJSON, secret)
|
||||
assert.deepEqual(result, RESPONSE_FIXTURES.ticket)
|
||||
schemaValidator.schemaValidate('sign', result)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,541 +1,529 @@
|
||||
import _ from 'lodash'
|
||||
import net from 'net'
|
||||
import assert from 'assert-diff'
|
||||
import setupClient from './setupClient'
|
||||
import {Client} from 'xrpl-local'
|
||||
import {ignoreWebSocketDisconnect} from './testUtils'
|
||||
import {Connection} from 'xrpl-local/client'
|
||||
import rippled from './fixtures/rippled'
|
||||
import net from "net";
|
||||
|
||||
const TIMEOUT = 200000 // how long before each test case times out
|
||||
const isBrowser = (process as any).browser
|
||||
import assert from "assert-diff";
|
||||
import _ from "lodash";
|
||||
|
||||
import { Client } from "xrpl-local";
|
||||
import { Connection } from "xrpl-local/client";
|
||||
|
||||
import rippled from "./fixtures/rippled";
|
||||
import setupClient from "./setupClient";
|
||||
import { ignoreWebSocketDisconnect } from "./testUtils";
|
||||
|
||||
const TIMEOUT = 200000; // how long before each test case times out
|
||||
const isBrowser = (process as any).browser;
|
||||
|
||||
function createServer() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = net.createServer()
|
||||
server.on('listening', function () {
|
||||
resolve(server)
|
||||
})
|
||||
server.on('error', function (error) {
|
||||
reject(error)
|
||||
})
|
||||
server.listen(0, '0.0.0.0')
|
||||
})
|
||||
const server = net.createServer();
|
||||
server.on("listening", function () {
|
||||
resolve(server);
|
||||
});
|
||||
server.on("error", function (error) {
|
||||
reject(error);
|
||||
});
|
||||
server.listen(0, "0.0.0.0");
|
||||
});
|
||||
}
|
||||
|
||||
describe('Connection', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
beforeEach(setupClient.setup)
|
||||
afterEach(setupClient.teardown)
|
||||
describe("Connection", function () {
|
||||
this.timeout(TIMEOUT);
|
||||
beforeEach(setupClient.setup);
|
||||
afterEach(setupClient.teardown);
|
||||
|
||||
it('default options', function () {
|
||||
const connection: any = new Connection('url')
|
||||
assert.strictEqual(connection._url, 'url')
|
||||
assert(connection._config.proxy == null)
|
||||
assert(connection._config.authorization == null)
|
||||
})
|
||||
it("default options", function () {
|
||||
const connection: any = new Connection("url");
|
||||
assert.strictEqual(connection._url, "url");
|
||||
assert(connection._config.proxy == null);
|
||||
assert(connection._config.authorization == null);
|
||||
});
|
||||
|
||||
describe('trace', () => {
|
||||
const mockedRequestData = {mocked: 'request'}
|
||||
const mockedResponse = JSON.stringify({mocked: 'response', id: 0})
|
||||
describe("trace", function () {
|
||||
const mockedRequestData = { mocked: "request" };
|
||||
const mockedResponse = JSON.stringify({ mocked: "response", id: 0 });
|
||||
const expectedMessages = [
|
||||
// We add the ID here, since it's not a part of the user-provided request.
|
||||
['send', JSON.stringify({...mockedRequestData, id: 0})],
|
||||
['receive', mockedResponse]
|
||||
]
|
||||
const originalConsoleLog = console.log
|
||||
["send", JSON.stringify({ ...mockedRequestData, id: 0 })],
|
||||
["receive", mockedResponse],
|
||||
];
|
||||
const originalConsoleLog = console.log;
|
||||
|
||||
afterEach(() => {
|
||||
console.log = originalConsoleLog
|
||||
})
|
||||
afterEach(function () {
|
||||
console.log = originalConsoleLog;
|
||||
});
|
||||
|
||||
it('as false', function () {
|
||||
const messages = []
|
||||
console.log = (id, message) => messages.push([id, message])
|
||||
const connection: any = new Connection('url', {trace: false})
|
||||
connection._ws = {send: function () {}}
|
||||
connection.request(mockedRequestData)
|
||||
connection._onMessage(mockedResponse)
|
||||
assert.deepEqual(messages, [])
|
||||
})
|
||||
it("as false", function () {
|
||||
const messages: any[] = [];
|
||||
console.log = (id, message) => messages.push([id, message]);
|
||||
const connection: any = new Connection("url", { trace: false });
|
||||
connection._ws = { send() {} };
|
||||
connection.request(mockedRequestData);
|
||||
connection._onMessage(mockedResponse);
|
||||
assert.deepEqual(messages, []);
|
||||
});
|
||||
|
||||
it('as true', function () {
|
||||
const messages = []
|
||||
console.log = (id, message) => messages.push([id, message])
|
||||
const connection: any = new Connection('url', {trace: true})
|
||||
connection._ws = {send: function () {}}
|
||||
connection.request(mockedRequestData)
|
||||
connection._onMessage(mockedResponse)
|
||||
assert.deepEqual(messages, expectedMessages)
|
||||
})
|
||||
it("as true", function () {
|
||||
const messages: any[] = [];
|
||||
console.log = (id, message) => messages.push([id, message]);
|
||||
const connection: any = new Connection("url", { trace: true });
|
||||
connection._ws = { send() {} };
|
||||
connection.request(mockedRequestData);
|
||||
connection._onMessage(mockedResponse);
|
||||
assert.deepEqual(messages, expectedMessages);
|
||||
});
|
||||
|
||||
it('as a function', function () {
|
||||
const messages = []
|
||||
const connection: any = new Connection('url', {
|
||||
trace: (id, message) => messages.push([id, message])
|
||||
})
|
||||
connection._ws = {send: function () {}}
|
||||
connection.request(mockedRequestData)
|
||||
connection._onMessage(mockedResponse)
|
||||
assert.deepEqual(messages, expectedMessages)
|
||||
})
|
||||
})
|
||||
it("as a function", function () {
|
||||
const messages: any[] = [];
|
||||
const connection: any = new Connection("url", {
|
||||
trace: (id, message) => messages.push([id, message]),
|
||||
});
|
||||
connection._ws = { send() {} };
|
||||
connection.request(mockedRequestData);
|
||||
connection._onMessage(mockedResponse);
|
||||
assert.deepEqual(messages, expectedMessages);
|
||||
});
|
||||
});
|
||||
|
||||
it('with proxy', function (done) {
|
||||
it("with proxy", function (done) {
|
||||
if (isBrowser) {
|
||||
done()
|
||||
return
|
||||
done();
|
||||
return;
|
||||
}
|
||||
createServer().then((server: any) => {
|
||||
const port = server.address().port
|
||||
const expect = 'CONNECT localhost'
|
||||
server.on('connection', (socket) => {
|
||||
socket.on('data', (data) => {
|
||||
const got = data.toString('ascii', 0, expect.length)
|
||||
assert.strictEqual(got, expect)
|
||||
server.close()
|
||||
connection.disconnect()
|
||||
done()
|
||||
})
|
||||
})
|
||||
const port = server.address().port;
|
||||
const expect = "CONNECT localhost";
|
||||
server.on("connection", (socket) => {
|
||||
socket.on("data", (data) => {
|
||||
const got = data.toString("ascii", 0, expect.length);
|
||||
assert.strictEqual(got, expect);
|
||||
server.close();
|
||||
connection.disconnect();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
const options = {
|
||||
proxy: 'ws://localhost:' + port,
|
||||
authorization: 'authorization',
|
||||
trustedCertificates: ['path/to/pem']
|
||||
}
|
||||
const connection = new Connection(
|
||||
this.client.connection._url,
|
||||
options
|
||||
)
|
||||
proxy: `ws://localhost:${port}`,
|
||||
authorization: "authorization",
|
||||
trustedCertificates: ["path/to/pem"],
|
||||
};
|
||||
const connection = new Connection(this.client.connection._url, options);
|
||||
connection.connect().catch((err) => {
|
||||
assert(err instanceof this.client.errors.NotConnectedError)
|
||||
})
|
||||
}, done)
|
||||
})
|
||||
assert(err instanceof this.client.errors.NotConnectedError);
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('Multiply disconnect calls', function () {
|
||||
this.client.disconnect()
|
||||
return this.client.disconnect()
|
||||
})
|
||||
it("Multiply disconnect calls", function () {
|
||||
this.client.disconnect();
|
||||
return this.client.disconnect();
|
||||
});
|
||||
|
||||
it('reconnect', function () {
|
||||
return this.client.connection.reconnect()
|
||||
})
|
||||
it("reconnect", function () {
|
||||
return this.client.connection.reconnect();
|
||||
});
|
||||
|
||||
it('NotConnectedError', function () {
|
||||
const connection = new Connection('url')
|
||||
return connection.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
it("NotConnectedError", function () {
|
||||
const connection = new Connection("url");
|
||||
return connection
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then(() => {
|
||||
assert(false, 'Should throw NotConnectedError')
|
||||
assert(false, "Should throw NotConnectedError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(error instanceof this.client.errors.NotConnectedError)
|
||||
})
|
||||
})
|
||||
assert(error instanceof this.client.errors.NotConnectedError);
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw NotConnectedError if server not responding ', function (done) {
|
||||
it("should throw NotConnectedError if server not responding ", function (done) {
|
||||
if (isBrowser) {
|
||||
const phantomTest = /PhantomJS/
|
||||
if (phantomTest.test(navigator.userAgent)) {
|
||||
if (navigator.userAgent.includes("PhantomJS")) {
|
||||
// inside PhantomJS this one just hangs, so skip as not very relevant
|
||||
done()
|
||||
return
|
||||
done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Address where no one listens
|
||||
const connection = new Connection(
|
||||
'ws://testripple.circleci.com:129'
|
||||
)
|
||||
connection.on('error', done)
|
||||
const connection = new Connection("ws://testripple.circleci.com:129");
|
||||
connection.on("error", done);
|
||||
connection.connect().catch((error) => {
|
||||
assert(error instanceof this.client.errors.NotConnectedError)
|
||||
done()
|
||||
})
|
||||
})
|
||||
assert(error instanceof this.client.errors.NotConnectedError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('DisconnectedError', async function () {
|
||||
this.mockRippled.suppressOutput = true
|
||||
it("DisconnectedError", async function () {
|
||||
this.mockRippled.suppressOutput = true;
|
||||
this.mockRippled.on(`request_server_info`, function (request, conn) {
|
||||
assert.strictEqual(request.command, 'server_info')
|
||||
conn.close()
|
||||
})
|
||||
assert.strictEqual(request.command, "server_info");
|
||||
conn.close();
|
||||
});
|
||||
return this.client
|
||||
.request({command: "server_info"})
|
||||
.request({ command: "server_info" })
|
||||
.then(() => {
|
||||
assert(false, 'Should throw DisconnectedError')
|
||||
assert(false, "Should throw DisconnectedError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(error instanceof this.client.errors.DisconnectedError)
|
||||
})
|
||||
})
|
||||
assert(error instanceof this.client.errors.DisconnectedError);
|
||||
});
|
||||
});
|
||||
|
||||
it('TimeoutError', function () {
|
||||
this.client.connection._ws.send = function (message, options, callback) {
|
||||
callback(null)
|
||||
}
|
||||
const request = {command: 'server_info'}
|
||||
it("TimeoutError", function () {
|
||||
this.client.connection._ws.send = function (message, callback) {
|
||||
callback(null);
|
||||
};
|
||||
const request = { command: "server_info" };
|
||||
return this.client.connection
|
||||
.request(request, 10)
|
||||
.then(() => {
|
||||
assert(false, 'Should throw TimeoutError')
|
||||
assert(false, "Should throw TimeoutError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(error instanceof this.client.errors.TimeoutError)
|
||||
})
|
||||
})
|
||||
assert(error instanceof this.client.errors.TimeoutError);
|
||||
});
|
||||
});
|
||||
|
||||
it('DisconnectedError on send', function () {
|
||||
this.client.connection._ws.send = function (message, options, callback) {
|
||||
callback({message: 'not connected'})
|
||||
}
|
||||
it("DisconnectedError on send", function () {
|
||||
this.client.connection._ws.send = function (message, callback) {
|
||||
callback({ message: "not connected" });
|
||||
};
|
||||
return this.client
|
||||
.request({command: "server_info"})
|
||||
.request({ command: "server_info" })
|
||||
.then(() => {
|
||||
assert(false, 'Should throw DisconnectedError')
|
||||
assert(false, "Should throw DisconnectedError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(error instanceof this.client.errors.DisconnectedError)
|
||||
assert.strictEqual(error.message, 'not connected')
|
||||
})
|
||||
})
|
||||
console.log(error);
|
||||
assert(error instanceof this.client.errors.DisconnectedError);
|
||||
assert.strictEqual(error.message, "not connected");
|
||||
});
|
||||
});
|
||||
|
||||
it('DisconnectedError on initial _onOpen send', async function () {
|
||||
it("DisconnectedError on initial _onOpen send", async function () {
|
||||
// _onOpen previously could throw PromiseRejectionHandledWarning: Promise rejection was handled asynchronously
|
||||
// do not rely on the client.setup hook to test this as it bypasses the case, disconnect client connection first
|
||||
await this.client.disconnect()
|
||||
await this.client.disconnect();
|
||||
|
||||
// stub _onOpen to only run logic relevant to test case
|
||||
this.client.connection._onOpen = () => {
|
||||
// overload websocket send on open when _ws exists
|
||||
this.client.connection._ws.send = function (data, options, cb) {
|
||||
// recent ws throws this error instead of calling back
|
||||
throw new Error('WebSocket is not open: readyState 0 (CONNECTING)')
|
||||
}
|
||||
const request = {command: 'subscribe', streams: ['ledger']}
|
||||
return this.client.connection.request(request)
|
||||
}
|
||||
throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
|
||||
};
|
||||
const request = { command: "subscribe", streams: ["ledger"] };
|
||||
return this.client.connection.request(request);
|
||||
};
|
||||
|
||||
try {
|
||||
await this.client.connect()
|
||||
await this.client.connect();
|
||||
} catch (error) {
|
||||
assert(error instanceof this.client.errors.DisconnectedError)
|
||||
assert(error instanceof this.client.errors.DisconnectedError);
|
||||
assert.strictEqual(
|
||||
error.message,
|
||||
'WebSocket is not open: readyState 0 (CONNECTING)'
|
||||
)
|
||||
"WebSocket is not open: readyState 0 (CONNECTING)"
|
||||
);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('ResponseFormatError', function () {
|
||||
it("ResponseFormatError", function () {
|
||||
return this.client
|
||||
.request({command: 'test_command', data: {unrecognizedResponse: true}})
|
||||
.request({
|
||||
command: "test_command",
|
||||
data: { unrecognizedResponse: true },
|
||||
})
|
||||
.then(() => {
|
||||
assert(false, 'Should throw ResponseFormatError')
|
||||
assert(false, "Should throw ResponseFormatError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(error instanceof this.client.errors.ResponseFormatError)
|
||||
})
|
||||
})
|
||||
assert(error instanceof this.client.errors.ResponseFormatError);
|
||||
});
|
||||
});
|
||||
|
||||
it('reconnect on unexpected close', function (done) {
|
||||
this.client.connection.on('connected', () => {
|
||||
done()
|
||||
})
|
||||
it("reconnect on unexpected close", function (done) {
|
||||
this.client.connection.on("connected", () => {
|
||||
done();
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.client.connection._ws.close()
|
||||
}, 1)
|
||||
})
|
||||
this.client.connection._ws.close();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
describe('reconnection test', function () {
|
||||
it('reconnect on several unexpected close', function (done) {
|
||||
describe("reconnection test", function () {
|
||||
it("reconnect on several unexpected close", function (done) {
|
||||
if (isBrowser) {
|
||||
const phantomTest = /PhantomJS/
|
||||
if (phantomTest.test(navigator.userAgent)) {
|
||||
if (navigator.userAgent.includes("PhantomJS")) {
|
||||
// inside PhantomJS this one just hangs, so skip as not very relevant
|
||||
done()
|
||||
return
|
||||
done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.timeout(70001)
|
||||
const self = this
|
||||
this.timeout(70001);
|
||||
const self = this;
|
||||
function breakConnection() {
|
||||
self.client.connection
|
||||
.request({
|
||||
command: 'test_command',
|
||||
data: {disconnectIn: 10}
|
||||
command: "test_command",
|
||||
data: { disconnectIn: 10 },
|
||||
})
|
||||
.catch(ignoreWebSocketDisconnect)
|
||||
.catch(ignoreWebSocketDisconnect);
|
||||
}
|
||||
|
||||
let connectsCount = 0
|
||||
let disconnectsCount = 0
|
||||
let reconnectsCount = 0
|
||||
let code = 0
|
||||
this.client.connection.on('reconnecting', () => {
|
||||
reconnectsCount += 1
|
||||
})
|
||||
this.client.connection.on('disconnected', (_code) => {
|
||||
code = _code
|
||||
disconnectsCount += 1
|
||||
})
|
||||
const num = 3
|
||||
this.client.connection.on('connected', () => {
|
||||
connectsCount += 1
|
||||
let connectsCount = 0;
|
||||
let disconnectsCount = 0;
|
||||
let reconnectsCount = 0;
|
||||
let code = 0;
|
||||
this.client.connection.on("reconnecting", () => {
|
||||
reconnectsCount += 1;
|
||||
});
|
||||
this.client.connection.on("disconnected", (_code) => {
|
||||
code = _code;
|
||||
disconnectsCount += 1;
|
||||
});
|
||||
const num = 3;
|
||||
this.client.connection.on("connected", () => {
|
||||
connectsCount += 1;
|
||||
if (connectsCount < num) {
|
||||
breakConnection()
|
||||
breakConnection();
|
||||
}
|
||||
if (connectsCount === num) {
|
||||
if (disconnectsCount !== num) {
|
||||
done(
|
||||
new Error(
|
||||
'disconnectsCount must be equal to ' +
|
||||
num +
|
||||
'(got ' +
|
||||
disconnectsCount +
|
||||
' instead)'
|
||||
`disconnectsCount must be equal to ${num}(got ${disconnectsCount} instead)`
|
||||
)
|
||||
)
|
||||
);
|
||||
} else if (reconnectsCount !== num) {
|
||||
done(
|
||||
new Error(
|
||||
'reconnectsCount must be equal to ' +
|
||||
num +
|
||||
' (got ' +
|
||||
reconnectsCount +
|
||||
' instead)'
|
||||
`reconnectsCount must be equal to ${num} (got ${reconnectsCount} instead)`
|
||||
)
|
||||
)
|
||||
);
|
||||
} else if (code !== 1006) {
|
||||
done(
|
||||
new Error(
|
||||
'disconnect must send code 1006 (got ' + code + ' instead)'
|
||||
)
|
||||
)
|
||||
new Error(`disconnect must send code 1006 (got ${code} instead)`)
|
||||
);
|
||||
} else {
|
||||
done()
|
||||
done();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
breakConnection()
|
||||
})
|
||||
})
|
||||
breakConnection();
|
||||
});
|
||||
});
|
||||
|
||||
it('reconnect event on heartbeat failure', function (done) {
|
||||
it("reconnect event on heartbeat failure", function (done) {
|
||||
if (isBrowser) {
|
||||
const phantomTest = /PhantomJS/
|
||||
if (phantomTest.test(navigator.userAgent)) {
|
||||
if (navigator.userAgent.includes("PhantomJS")) {
|
||||
// inside PhantomJS this one just hangs, so skip as not very relevant
|
||||
done()
|
||||
return
|
||||
done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Set the heartbeat to less than the 1 second ping response
|
||||
this.client.connection._config.timeout = 500
|
||||
this.client.connection._config.timeout = 500;
|
||||
// Drop the test runner timeout, since this should be a quick test
|
||||
this.timeout(5000)
|
||||
this.timeout(5000);
|
||||
// Hook up a listener for the reconnect event
|
||||
this.client.connection.on('reconnect', () => done())
|
||||
this.client.connection.on("reconnect", () => done());
|
||||
// Trigger a heartbeat
|
||||
this.client.connection._heartbeat().catch((error) => {
|
||||
/* ignore - test expects heartbeat failure */
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('heartbeat failure and reconnect failure', function (done) {
|
||||
it("heartbeat failure and reconnect failure", function (done) {
|
||||
if (isBrowser) {
|
||||
const phantomTest = /PhantomJS/
|
||||
if (phantomTest.test(navigator.userAgent)) {
|
||||
if (navigator.userAgent.includes("PhantomJS")) {
|
||||
// inside PhantomJS this one just hangs, so skip as not very relevant
|
||||
done()
|
||||
return
|
||||
done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Set the heartbeat to less than the 1 second ping response
|
||||
this.client.connection._config.timeout = 500
|
||||
this.client.connection._config.timeout = 500;
|
||||
// Drop the test runner timeout, since this should be a quick test
|
||||
this.timeout(5000)
|
||||
this.timeout(5000);
|
||||
// fail on reconnect/connection
|
||||
this.client.connection.reconnect = async () => {
|
||||
throw new Error('error on reconnect')
|
||||
}
|
||||
throw new Error("error on reconnect");
|
||||
};
|
||||
// Hook up a listener for the reconnect error event
|
||||
this.client.on('error', (error, message) => {
|
||||
if (error === 'reconnect' && message === 'error on reconnect') {
|
||||
return done()
|
||||
this.client.on("error", (error, message) => {
|
||||
if (error === "reconnect" && message === "error on reconnect") {
|
||||
return done();
|
||||
}
|
||||
return done(new Error('Expected error on reconnect'))
|
||||
})
|
||||
return done(new Error("Expected error on reconnect"));
|
||||
});
|
||||
// Trigger a heartbeat
|
||||
this.client.connection._heartbeat()
|
||||
})
|
||||
this.client.connection._heartbeat();
|
||||
});
|
||||
|
||||
it('should emit disconnected event with code 1000 (CLOSE_NORMAL)', function (done) {
|
||||
this.client.once('disconnected', (code) => {
|
||||
assert.strictEqual(code, 1000)
|
||||
done()
|
||||
})
|
||||
this.client.disconnect()
|
||||
})
|
||||
it("should emit disconnected event with code 1000 (CLOSE_NORMAL)", function (done) {
|
||||
this.client.once("disconnected", (code) => {
|
||||
assert.strictEqual(code, 1000);
|
||||
done();
|
||||
});
|
||||
this.client.disconnect();
|
||||
});
|
||||
|
||||
it('should emit disconnected event with code 1006 (CLOSE_ABNORMAL)', function (done) {
|
||||
this.client.connection.once('error', (error) => {
|
||||
done(new Error('should not throw error, got ' + String(error)))
|
||||
})
|
||||
this.client.connection.once('disconnected', (code) => {
|
||||
assert.strictEqual(code, 1006)
|
||||
done()
|
||||
})
|
||||
it("should emit disconnected event with code 1006 (CLOSE_ABNORMAL)", function (done) {
|
||||
this.client.connection.once("error", (error) => {
|
||||
done(new Error(`should not throw error, got ${String(error)}`));
|
||||
});
|
||||
this.client.connection.once("disconnected", (code) => {
|
||||
assert.strictEqual(code, 1006);
|
||||
done();
|
||||
});
|
||||
this.client.connection
|
||||
.request({
|
||||
command: 'test_command',
|
||||
data: {disconnectIn: 10}
|
||||
command: "test_command",
|
||||
data: { disconnectIn: 10 },
|
||||
})
|
||||
.catch(ignoreWebSocketDisconnect)
|
||||
})
|
||||
.catch(ignoreWebSocketDisconnect);
|
||||
});
|
||||
|
||||
it('should emit connected event on after reconnect', function (done) {
|
||||
this.client.once('connected', done)
|
||||
this.client.connection._ws.close()
|
||||
})
|
||||
it("should emit connected event on after reconnect", function (done) {
|
||||
this.client.once("connected", done);
|
||||
this.client.connection._ws.close();
|
||||
});
|
||||
|
||||
it('Multiply connect calls', function () {
|
||||
it("Multiply connect calls", function () {
|
||||
return this.client.connect().then(() => {
|
||||
return this.client.connect()
|
||||
})
|
||||
})
|
||||
return this.client.connect();
|
||||
});
|
||||
});
|
||||
|
||||
it('Cannot connect because no server', function () {
|
||||
const connection = new Connection(undefined as string)
|
||||
it("Cannot connect because no server", function () {
|
||||
const connection = new Connection(undefined as unknown as string);
|
||||
return connection
|
||||
.connect()
|
||||
.then(() => {
|
||||
assert(false, 'Should throw ConnectionError')
|
||||
assert(false, "Should throw ConnectionError");
|
||||
})
|
||||
.catch((error) => {
|
||||
assert(
|
||||
error instanceof this.client.errors.ConnectionError,
|
||||
'Should throw ConnectionError'
|
||||
)
|
||||
})
|
||||
})
|
||||
"Should throw ConnectionError"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('connect multiserver error', function () {
|
||||
it("connect multiserver error", function () {
|
||||
assert.throws(function () {
|
||||
new Client({
|
||||
servers: ['wss://server1.com', 'wss://server2.com']
|
||||
} as any)
|
||||
}, this.client.errors.RippleError)
|
||||
})
|
||||
servers: ["wss://server1.com", "wss://server2.com"],
|
||||
} as any);
|
||||
}, this.client.errors.RippleError);
|
||||
});
|
||||
|
||||
it('connect throws error', function (done) {
|
||||
this.client.once('error', (type, info) => {
|
||||
assert.strictEqual(type, 'type')
|
||||
assert.strictEqual(info, 'info')
|
||||
done()
|
||||
})
|
||||
this.client.connection.emit('error', 'type', 'info')
|
||||
})
|
||||
it("connect throws error", function (done) {
|
||||
this.client.once("error", (type, info) => {
|
||||
assert.strictEqual(type, "type");
|
||||
assert.strictEqual(info, "info");
|
||||
done();
|
||||
});
|
||||
this.client.connection.emit("error", "type", "info");
|
||||
});
|
||||
|
||||
it('emit stream messages', function (done) {
|
||||
let transactionCount = 0
|
||||
let pathFindCount = 0
|
||||
this.client.connection.on('transaction', () => {
|
||||
transactionCount++
|
||||
})
|
||||
this.client.connection.on('path_find', () => {
|
||||
pathFindCount++
|
||||
})
|
||||
this.client.connection.on('response', (message) => {
|
||||
assert.strictEqual(message.id, 1)
|
||||
assert.strictEqual(transactionCount, 1)
|
||||
assert.strictEqual(pathFindCount, 1)
|
||||
done()
|
||||
})
|
||||
it("emit stream messages", function (done) {
|
||||
let transactionCount = 0;
|
||||
let pathFindCount = 0;
|
||||
this.client.connection.on("transaction", () => {
|
||||
transactionCount++;
|
||||
});
|
||||
this.client.connection.on("path_find", () => {
|
||||
pathFindCount++;
|
||||
});
|
||||
this.client.connection.on("response", (message) => {
|
||||
assert.strictEqual(message.id, 1);
|
||||
assert.strictEqual(transactionCount, 1);
|
||||
assert.strictEqual(pathFindCount, 1);
|
||||
done();
|
||||
});
|
||||
|
||||
this.client.connection._onMessage(
|
||||
JSON.stringify({
|
||||
type: 'transaction'
|
||||
type: "transaction",
|
||||
})
|
||||
)
|
||||
);
|
||||
this.client.connection._onMessage(
|
||||
JSON.stringify({
|
||||
type: 'path_find'
|
||||
type: "path_find",
|
||||
})
|
||||
)
|
||||
);
|
||||
this.client.connection._onMessage(
|
||||
JSON.stringify({
|
||||
type: 'response',
|
||||
id: 1
|
||||
type: "response",
|
||||
id: 1,
|
||||
})
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('invalid message id', function (done) {
|
||||
this.client.on('error', (errorCode, errorMessage, message) => {
|
||||
assert.strictEqual(errorCode, 'badMessage')
|
||||
assert.strictEqual(errorMessage, 'valid id not found in response')
|
||||
assert.strictEqual(message, '{"type":"response","id":"must be integer"}')
|
||||
done()
|
||||
})
|
||||
it("invalid message id", function (done) {
|
||||
this.client.on("error", (errorCode, errorMessage, message) => {
|
||||
assert.strictEqual(errorCode, "badMessage");
|
||||
assert.strictEqual(errorMessage, "valid id not found in response");
|
||||
assert.strictEqual(message, '{"type":"response","id":"must be integer"}');
|
||||
done();
|
||||
});
|
||||
this.client.connection._onMessage(
|
||||
JSON.stringify({
|
||||
type: 'response',
|
||||
id: 'must be integer'
|
||||
type: "response",
|
||||
id: "must be integer",
|
||||
})
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('propagates error message', function (done) {
|
||||
this.client.on('error', (errorCode, errorMessage, data) => {
|
||||
assert.strictEqual(errorCode, 'slowDown')
|
||||
assert.strictEqual(errorMessage, 'slow down')
|
||||
assert.deepEqual(data, {error: 'slowDown', error_message: 'slow down'})
|
||||
done()
|
||||
})
|
||||
it("propagates error message", function (done) {
|
||||
this.client.on("error", (errorCode, errorMessage, data) => {
|
||||
assert.strictEqual(errorCode, "slowDown");
|
||||
assert.strictEqual(errorMessage, "slow down");
|
||||
assert.deepEqual(data, { error: "slowDown", error_message: "slow down" });
|
||||
done();
|
||||
});
|
||||
this.client.connection._onMessage(
|
||||
JSON.stringify({
|
||||
error: 'slowDown',
|
||||
error_message: 'slow down'
|
||||
error: "slowDown",
|
||||
error_message: "slow down",
|
||||
})
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("propagates RippledError data", function (done) {
|
||||
const request = { command: "subscribe", streams: "validations" };
|
||||
this.mockRippled.addResponse(request, rippled.subscribe.error);
|
||||
|
||||
it('propagates RippledError data', function (done) {
|
||||
const request = {command: 'subscribe', streams: 'validations'}
|
||||
this.mockRippled.addResponse(request, rippled.subscribe.error)
|
||||
this.client.request(request).catch((error) => {
|
||||
assert.strictEqual(error.name, 'RippledError')
|
||||
assert.strictEqual(error.data.error, 'invalidParams')
|
||||
assert.strictEqual(error.message, 'Invalid parameters.')
|
||||
assert.strictEqual(error.data.error_code, 31)
|
||||
assert.strictEqual(error.data.error_message, 'Invalid parameters.')
|
||||
assert.strictEqual(error.name, "RippledError");
|
||||
assert.strictEqual(error.data.error, "invalidParams");
|
||||
assert.strictEqual(error.message, "Invalid parameters.");
|
||||
assert.strictEqual(error.data.error_code, 31);
|
||||
assert.strictEqual(error.data.error_message, "Invalid parameters.");
|
||||
assert.deepEqual(error.data.request, {
|
||||
command: 'subscribe',
|
||||
command: "subscribe",
|
||||
id: 0,
|
||||
streams: 'validations'
|
||||
})
|
||||
assert.strictEqual(error.data.status, 'error')
|
||||
assert.strictEqual(error.data.type, 'response')
|
||||
done()
|
||||
})
|
||||
})
|
||||
streams: "validations",
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('unrecognized message type', function (done) {
|
||||
it("unrecognized message type", function (done) {
|
||||
// This enables us to automatically support any
|
||||
// new messages added by rippled in the future.
|
||||
this.client.connection.on('unknown', (event) => {
|
||||
assert.deepEqual(event, {type: 'unknown'})
|
||||
done()
|
||||
})
|
||||
this.client.connection.on("unknown", (event) => {
|
||||
assert.deepEqual(event, { type: "unknown" });
|
||||
done();
|
||||
});
|
||||
|
||||
this.client.connection._onMessage(JSON.stringify({type: 'unknown'}))
|
||||
})
|
||||
this.client.connection._onMessage(JSON.stringify({ type: "unknown" }));
|
||||
});
|
||||
|
||||
// it('should clean up websocket connection if error after websocket is opened', async function () {
|
||||
// await this.client.disconnect()
|
||||
@@ -555,34 +543,35 @@ describe('Connection', function () {
|
||||
// }
|
||||
// })
|
||||
|
||||
it('should try to reconnect on empty subscribe response on reconnect', function (done) {
|
||||
this.timeout(23000)
|
||||
this.client.on('error', (error) => {
|
||||
done(error || new Error('Should not emit error.'))
|
||||
})
|
||||
let disconnectedCount = 0
|
||||
this.client.on('connected', () => {
|
||||
it("should try to reconnect on empty subscribe response on reconnect", function (done) {
|
||||
this.timeout(23000);
|
||||
this.client.on("error", (error) => {
|
||||
done(error || new Error("Should not emit error."));
|
||||
});
|
||||
let disconnectedCount = 0;
|
||||
this.client.on("connected", () => {
|
||||
done(
|
||||
disconnectedCount !== 1
|
||||
? new Error('Wrong number of disconnects')
|
||||
? new Error("Wrong number of disconnects")
|
||||
: undefined
|
||||
)
|
||||
})
|
||||
this.client.on('disconnected', () => {
|
||||
disconnectedCount++
|
||||
})
|
||||
);
|
||||
});
|
||||
this.client.on("disconnected", () => {
|
||||
disconnectedCount++;
|
||||
});
|
||||
this.client.connection.request({
|
||||
command: 'test_command',
|
||||
data: {disconnectIn: 5}
|
||||
})
|
||||
})
|
||||
command: "test_command",
|
||||
data: { disconnectIn: 5 },
|
||||
});
|
||||
});
|
||||
|
||||
it('should not crash on error', async function (done) {
|
||||
this.mockRippled.suppressOutput = true
|
||||
this.client.connection.request({
|
||||
command: 'test_garbage'
|
||||
})
|
||||
.then(() => new Error('Should not have succeeded'))
|
||||
.catch(done())
|
||||
})
|
||||
})
|
||||
it("should not crash on error", async function (done) {
|
||||
this.mockRippled.suppressOutput = true;
|
||||
this.client.connection
|
||||
.request({
|
||||
command: "test_garbage",
|
||||
})
|
||||
.then(() => new Error("Should not have succeeded"))
|
||||
.catch(done());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,49 +1,54 @@
|
||||
import _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import wallet from './wallet'
|
||||
import requests from '../fixtures/requests'
|
||||
import {Client} from 'xrpl-local'
|
||||
import {payTo, ledgerAccept} from './utils'
|
||||
import {errors} from 'xrpl-local/common'
|
||||
import {isValidSecret} from 'xrpl-local/utils'
|
||||
import { generateXAddress } from '../../src/utils/generateAddress'
|
||||
import { isValidXAddress } from 'ripple-address-codec'
|
||||
import assert from "assert";
|
||||
|
||||
import _ from "lodash";
|
||||
import { isValidXAddress } from "ripple-address-codec";
|
||||
|
||||
import { Client } from "xrpl-local";
|
||||
import { errors } from "xrpl-local/common";
|
||||
import { isValidSecret } from "xrpl-local/utils";
|
||||
|
||||
import { generateXAddress } from "../../src/utils/generateAddress";
|
||||
import requests from "../fixtures/requests";
|
||||
|
||||
import { payTo, ledgerAccept } from "./utils";
|
||||
import wallet from "./wallet";
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
const INTERVAL = 1000 // how long to wait between checks for validated ledger
|
||||
const TIMEOUT = 20000;
|
||||
const INTERVAL = 1000; // how long to wait between checks for validated ledger
|
||||
|
||||
const HOST = process.env.HOST ?? "0.0.0.0"
|
||||
const PORT = process.env.PORT ?? "6006"
|
||||
const serverUrl = `ws://${HOST}:${PORT}`
|
||||
const HOST = process.env.HOST ?? "0.0.0.0";
|
||||
const PORT = process.env.PORT ?? "6006";
|
||||
const serverUrl = `ws://${HOST}:${PORT}`;
|
||||
|
||||
console.log(serverUrl)
|
||||
console.log(serverUrl);
|
||||
|
||||
function acceptLedger(client) {
|
||||
return client.connection.request({command: 'ledger_accept'})
|
||||
return client.connection.request({ command: "ledger_accept" });
|
||||
}
|
||||
|
||||
function verifyTransaction(testcase, hash, type, options, txData, account) {
|
||||
console.log('VERIFY...')
|
||||
console.log("VERIFY...");
|
||||
return testcase.client
|
||||
.request({
|
||||
command: 'tx',
|
||||
command: "tx",
|
||||
transaction: hash,
|
||||
min_ledger: options.minLedgerVersion,
|
||||
max_ledger: options.maxLedgerVersion
|
||||
}).then((data) => {
|
||||
assert(data && data.result)
|
||||
assert.strictEqual(data.result.TransactionType, type)
|
||||
assert.strictEqual(data.result.Account, account)
|
||||
assert.strictEqual(data.result.meta.TransactionResult, 'tesSUCCESS')
|
||||
max_ledger: options.maxLedgerVersion,
|
||||
})
|
||||
.then((data) => {
|
||||
assert(data && data.result);
|
||||
assert.strictEqual(data.result.TransactionType, type);
|
||||
assert.strictEqual(data.result.Account, account);
|
||||
assert.strictEqual(data.result.meta.TransactionResult, "tesSUCCESS");
|
||||
if (testcase.transactions != null) {
|
||||
testcase.transactions.push(hash)
|
||||
testcase.transactions.push(hash);
|
||||
}
|
||||
return {txJSON: JSON.stringify(txData), id: hash, tx: data}
|
||||
return { txJSON: JSON.stringify(txData), id: hash, tx: data };
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error instanceof errors.PendingLedgerVersionError) {
|
||||
console.log('NOT VALIDATED YET...')
|
||||
console.log("NOT VALIDATED YET...");
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(
|
||||
() =>
|
||||
@@ -56,12 +61,12 @@ function verifyTransaction(testcase, hash, type, options, txData, account) {
|
||||
account
|
||||
).then(resolve, reject),
|
||||
INTERVAL
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
console.log(error.stack)
|
||||
assert(false, 'Transaction not successful: ' + error.message)
|
||||
})
|
||||
console.log(error.stack);
|
||||
assert(false, `Transaction not successful: ${error.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
function testTransaction(
|
||||
@@ -72,27 +77,27 @@ function testTransaction(
|
||||
address = wallet.getAddress(),
|
||||
secret = wallet.getSecret()
|
||||
) {
|
||||
const txJSON = prepared.txJSON
|
||||
assert(txJSON, 'missing txJSON')
|
||||
const txData = JSON.parse(txJSON)
|
||||
assert.strictEqual(txData.Account, address)
|
||||
const signedData = testcase.client.sign(txJSON, secret)
|
||||
console.log('PREPARED...')
|
||||
const txJSON = prepared.txJSON;
|
||||
assert(txJSON, "missing txJSON");
|
||||
const txData = JSON.parse(txJSON);
|
||||
assert.strictEqual(txData.Account, address);
|
||||
const signedData = testcase.client.sign(txJSON, secret);
|
||||
console.log("PREPARED...");
|
||||
return testcase.client
|
||||
.request({command: 'submit', tx_blob: signedData.signedTransaction})
|
||||
.request({ command: "submit", tx_blob: signedData.signedTransaction })
|
||||
.then((response) =>
|
||||
testcase.test.title.indexOf('multisign') !== -1
|
||||
testcase.test.title.indexOf("multisign") !== -1
|
||||
? acceptLedger(testcase.client).then(() => response)
|
||||
: response
|
||||
)
|
||||
.then((response) => {
|
||||
console.log('SUBMITTED...')
|
||||
assert.strictEqual(response.result.engine_result, 'tesSUCCESS')
|
||||
console.log("SUBMITTED...");
|
||||
assert.strictEqual(response.result.engine_result, "tesSUCCESS");
|
||||
const options = {
|
||||
minLedgerVersion: lastClosedLedgerVersion,
|
||||
maxLedgerVersion: txData.LastLedgerSequence
|
||||
}
|
||||
ledgerAccept(testcase.client)
|
||||
maxLedgerVersion: txData.LastLedgerSequence,
|
||||
};
|
||||
ledgerAccept(testcase.client);
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(
|
||||
() =>
|
||||
@@ -105,71 +110,81 @@ function testTransaction(
|
||||
address
|
||||
).then(resolve, reject),
|
||||
INTERVAL
|
||||
)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setup(this: any, server = serverUrl) {
|
||||
this.client = new Client(server)
|
||||
console.log('CONNECTING...')
|
||||
this.client = new Client(server);
|
||||
console.log("CONNECTING...");
|
||||
return this.client.connect().then(
|
||||
() => {
|
||||
console.log('CONNECTED...')
|
||||
console.log("CONNECTED...");
|
||||
},
|
||||
(error) => {
|
||||
console.log('ERROR:', error)
|
||||
throw error
|
||||
console.log("ERROR:", error);
|
||||
throw error;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const masterAccount = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
const masterSecret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb'
|
||||
const masterAccount = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
const masterSecret = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
|
||||
|
||||
function makeTrustLine(testcase, address, secret) {
|
||||
const client = testcase.client
|
||||
const client = testcase.client;
|
||||
const specification = {
|
||||
currency: 'USD',
|
||||
currency: "USD",
|
||||
counterparty: masterAccount,
|
||||
limit: '1341.1',
|
||||
ripplingDisabled: true
|
||||
}
|
||||
limit: "1341.1",
|
||||
ripplingDisabled: true,
|
||||
};
|
||||
const trust = client
|
||||
.prepareTrustline(address, specification, {})
|
||||
.then((data) => {
|
||||
const signed = client.sign(data.txJSON, secret)
|
||||
const signed = client.sign(data.txJSON, secret);
|
||||
if (address === wallet.getAddress()) {
|
||||
testcase.transactions.push(signed.id)
|
||||
testcase.transactions.push(signed.id);
|
||||
}
|
||||
return client.request({command: 'submit', tx_blob: signed.signedTransaction})
|
||||
return client.request({
|
||||
command: "submit",
|
||||
tx_blob: signed.signedTransaction,
|
||||
});
|
||||
})
|
||||
.then(() => ledgerAccept(client))
|
||||
return trust
|
||||
.then(() => ledgerAccept(client));
|
||||
return trust;
|
||||
}
|
||||
|
||||
function makeOrder(client, address, specification, secret) {
|
||||
return client
|
||||
.prepareOrder(address, specification)
|
||||
.then((data) => client.sign(data.txJSON, secret))
|
||||
.then((signed) => client.request({command: 'submit', tx_blob: signed.signedTransaction}))
|
||||
.then(() => ledgerAccept(client))
|
||||
.then((signed) =>
|
||||
client.request({ command: "submit", tx_blob: signed.signedTransaction })
|
||||
)
|
||||
.then(() => ledgerAccept(client));
|
||||
}
|
||||
|
||||
function setupAccounts(testcase) {
|
||||
const client = testcase.client
|
||||
const client = testcase.client;
|
||||
|
||||
const promise = payTo(client, 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM')
|
||||
const promise = payTo(client, "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM")
|
||||
.then(() => payTo(client, wallet.getAddress()))
|
||||
.then(() => payTo(client, testcase.newWallet.xAddress))
|
||||
.then(() => payTo(client, 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc'))
|
||||
.then(() => payTo(client, 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'))
|
||||
.then(() => payTo(client, "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc"))
|
||||
.then(() => payTo(client, "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q"))
|
||||
.then(() => {
|
||||
return client
|
||||
.prepareSettings(masterAccount, {defaultRipple: true})
|
||||
.prepareSettings(masterAccount, { defaultRipple: true })
|
||||
.then((data) => client.sign(data.txJSON, masterSecret))
|
||||
.then((signed) => client.request({command: 'submit', tx_blob: signed.signedTransaction}))
|
||||
.then(() => ledgerAccept(client))
|
||||
.then((signed) =>
|
||||
client.request({
|
||||
command: "submit",
|
||||
tx_blob: signed.signedTransaction,
|
||||
})
|
||||
)
|
||||
.then(() => ledgerAccept(client));
|
||||
})
|
||||
.then(() =>
|
||||
makeTrustLine(testcase, wallet.getAddress(), wallet.getSecret())
|
||||
@@ -181,57 +196,57 @@ function setupAccounts(testcase) {
|
||||
testcase.newWallet.secret
|
||||
)
|
||||
)
|
||||
.then(() => payTo(client, wallet.getAddress(), '123', 'USD', masterAccount))
|
||||
.then(() => payTo(client, 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'))
|
||||
.then(() => payTo(client, wallet.getAddress(), "123", "USD", masterAccount))
|
||||
.then(() => payTo(client, "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q"))
|
||||
.then(() => {
|
||||
const orderSpecification = {
|
||||
direction: 'buy',
|
||||
direction: "buy",
|
||||
quantity: {
|
||||
currency: 'USD',
|
||||
value: '432',
|
||||
counterparty: masterAccount
|
||||
currency: "USD",
|
||||
value: "432",
|
||||
counterparty: masterAccount,
|
||||
},
|
||||
totalPrice: {
|
||||
currency: 'XRP',
|
||||
value: '432'
|
||||
}
|
||||
}
|
||||
currency: "XRP",
|
||||
value: "432",
|
||||
},
|
||||
};
|
||||
return makeOrder(
|
||||
testcase.client,
|
||||
testcase.newWallet.xAddress,
|
||||
orderSpecification,
|
||||
testcase.newWallet.secret
|
||||
)
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
const orderSpecification = {
|
||||
direction: 'buy',
|
||||
direction: "buy",
|
||||
quantity: {
|
||||
currency: 'XRP',
|
||||
value: '1741'
|
||||
currency: "XRP",
|
||||
value: "1741",
|
||||
},
|
||||
totalPrice: {
|
||||
currency: 'USD',
|
||||
value: '171',
|
||||
counterparty: masterAccount
|
||||
}
|
||||
}
|
||||
currency: "USD",
|
||||
value: "171",
|
||||
counterparty: masterAccount,
|
||||
},
|
||||
};
|
||||
return makeOrder(
|
||||
testcase.client,
|
||||
masterAccount,
|
||||
orderSpecification,
|
||||
masterSecret
|
||||
)
|
||||
})
|
||||
return promise
|
||||
);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
function teardown(this: any) {
|
||||
return this.client.disconnect()
|
||||
return this.client.disconnect();
|
||||
}
|
||||
|
||||
function suiteSetup(this: any) {
|
||||
this.transactions = []
|
||||
this.transactions = [];
|
||||
|
||||
return (
|
||||
setup
|
||||
@@ -241,208 +256,209 @@ function suiteSetup(this: any) {
|
||||
// two times to give time to server to send `ledgerClosed` event
|
||||
// so getLedgerVersion will return right value
|
||||
.then(() => ledgerAccept(this.client))
|
||||
.then(() => this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
})
|
||||
.then(response => response.result.ledger_index))
|
||||
.then(() =>
|
||||
this.client
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then((response) => response.result.ledger_index)
|
||||
)
|
||||
.then((ledgerVersion) => {
|
||||
this.startLedgerVersion = ledgerVersion
|
||||
this.startLedgerVersion = ledgerVersion;
|
||||
})
|
||||
.then(() => setupAccounts(this))
|
||||
.then(() => teardown.bind(this)())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
describe('integration tests', function () {
|
||||
const address = wallet.getAddress()
|
||||
const instructions = {maxLedgerVersionOffset: 10}
|
||||
this.timeout(TIMEOUT)
|
||||
describe("integration tests", function () {
|
||||
const address = wallet.getAddress();
|
||||
const instructions = { maxLedgerVersionOffset: 10 };
|
||||
this.timeout(TIMEOUT);
|
||||
|
||||
before(suiteSetup)
|
||||
beforeEach(_.partial(setup, serverUrl))
|
||||
afterEach(teardown)
|
||||
before(suiteSetup);
|
||||
beforeEach(_.partial(setup, serverUrl));
|
||||
afterEach(teardown);
|
||||
|
||||
it('trustline', function () {
|
||||
return this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
})
|
||||
.then(response => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.simple,
|
||||
instructions
|
||||
)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, 'TrustSet', ledgerVersion, prepared)
|
||||
)
|
||||
})
|
||||
})
|
||||
it("trustline", function () {
|
||||
return this.client
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then((response) => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.prepareTrustline(
|
||||
address,
|
||||
requests.prepareTrustline.simple,
|
||||
instructions
|
||||
)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, "TrustSet", ledgerVersion, prepared)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('payment', function () {
|
||||
const amount = {currency: 'XRP', value: '0.000001'}
|
||||
it("payment", function () {
|
||||
const amount = { currency: "XRP", value: "0.000001" };
|
||||
const paymentSpecification = {
|
||||
source: {
|
||||
address: address,
|
||||
maxAmount: amount
|
||||
address,
|
||||
maxAmount: amount,
|
||||
},
|
||||
destination: {
|
||||
address: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc',
|
||||
amount: amount
|
||||
}
|
||||
}
|
||||
return this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
})
|
||||
.then(response => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.preparePayment(address, paymentSpecification, instructions)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, 'Payment', ledgerVersion, prepared)
|
||||
)
|
||||
})
|
||||
})
|
||||
address: "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc",
|
||||
amount,
|
||||
},
|
||||
};
|
||||
return this.client
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then((response) => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.preparePayment(address, paymentSpecification, instructions)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, "Payment", ledgerVersion, prepared)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('order', function () {
|
||||
it("order", function () {
|
||||
const orderSpecification = {
|
||||
direction: 'buy',
|
||||
direction: "buy",
|
||||
quantity: {
|
||||
currency: 'USD',
|
||||
value: '237',
|
||||
counterparty: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'
|
||||
currency: "USD",
|
||||
value: "237",
|
||||
counterparty: "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q",
|
||||
},
|
||||
totalPrice: {
|
||||
currency: 'XRP',
|
||||
value: '0.0002'
|
||||
}
|
||||
}
|
||||
currency: "XRP",
|
||||
value: "0.0002",
|
||||
},
|
||||
};
|
||||
const expectedOrder = {
|
||||
flags: 0,
|
||||
quality: "1.185",
|
||||
taker_gets: '200',
|
||||
taker_gets: "200",
|
||||
taker_pays: {
|
||||
currency: 'USD',
|
||||
value: '237',
|
||||
issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'
|
||||
}
|
||||
}
|
||||
return this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
})
|
||||
.then(response => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.prepareOrder(address, orderSpecification, instructions)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, 'OfferCreate', ledgerVersion, prepared)
|
||||
)
|
||||
.then((result) => {
|
||||
const txData = JSON.parse(result.txJSON)
|
||||
return this.client.request({
|
||||
command: 'account_offers',
|
||||
account: address
|
||||
}).then(response => response.result.offers)
|
||||
.then((orders) => {
|
||||
assert(orders && orders.length > 0)
|
||||
const createdOrder = (
|
||||
orders.filter((order) => {
|
||||
return order.seq === txData.Sequence
|
||||
currency: "USD",
|
||||
value: "237",
|
||||
issuer: "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q",
|
||||
},
|
||||
};
|
||||
return this.client
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then((response) => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
return this.client
|
||||
.prepareOrder(address, orderSpecification, instructions)
|
||||
.then((prepared) =>
|
||||
testTransaction(this, "OfferCreate", ledgerVersion, prepared)
|
||||
)
|
||||
.then((result) => {
|
||||
const txData = JSON.parse(result.txJSON);
|
||||
return this.client
|
||||
.request({
|
||||
command: "account_offers",
|
||||
account: address,
|
||||
})
|
||||
)[0]
|
||||
assert(createdOrder)
|
||||
delete createdOrder.seq
|
||||
assert.deepEqual(createdOrder, expectedOrder)
|
||||
return txData
|
||||
.then((response) => response.result.offers)
|
||||
.then((orders) => {
|
||||
assert(orders && orders.length > 0);
|
||||
const createdOrder = orders.filter((order) => {
|
||||
return order.seq === txData.Sequence;
|
||||
})[0];
|
||||
assert(createdOrder);
|
||||
delete createdOrder.seq;
|
||||
assert.deepEqual(createdOrder, expectedOrder);
|
||||
return txData;
|
||||
});
|
||||
})
|
||||
})
|
||||
.then((txData) =>
|
||||
this.client
|
||||
.prepareOrderCancellation(
|
||||
address,
|
||||
{orderSequence: txData.Sequence},
|
||||
instructions
|
||||
)
|
||||
.then((prepared) =>
|
||||
testTransaction(
|
||||
this,
|
||||
'OfferCancel',
|
||||
ledgerVersion,
|
||||
prepared
|
||||
.then((txData) =>
|
||||
this.client
|
||||
.prepareOrderCancellation(
|
||||
address,
|
||||
{ orderSequence: txData.Sequence },
|
||||
instructions
|
||||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
})
|
||||
.then((prepared) =>
|
||||
testTransaction(this, "OfferCancel", ledgerVersion, prepared)
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('isConnected', function () {
|
||||
assert(this.client.isConnected())
|
||||
})
|
||||
it("isConnected", function () {
|
||||
assert(this.client.isConnected());
|
||||
});
|
||||
|
||||
it('getFee', function () {
|
||||
it("getFee", function () {
|
||||
return this.client.getFee().then((fee) => {
|
||||
assert.strictEqual(typeof fee, 'string')
|
||||
assert(!isNaN(Number(fee)))
|
||||
assert(parseFloat(fee) === Number(fee))
|
||||
})
|
||||
})
|
||||
assert.strictEqual(typeof fee, "string");
|
||||
assert(!isNaN(Number(fee)));
|
||||
assert(parseFloat(fee) === Number(fee));
|
||||
});
|
||||
});
|
||||
|
||||
it('getTrustlines', function () {
|
||||
const fixture = requests.prepareTrustline.simple
|
||||
const { currency, counterparty } = fixture
|
||||
const options = { currency, counterparty }
|
||||
it("getTrustlines", function () {
|
||||
const fixture = requests.prepareTrustline.simple;
|
||||
const { currency, counterparty } = fixture;
|
||||
const options = { currency, counterparty };
|
||||
return this.client.getTrustlines(address, options).then((data) => {
|
||||
assert(data && data.length > 0 && data[0] && data[0].specification)
|
||||
const specification = data[0].specification
|
||||
assert.strictEqual(Number(specification.limit), Number(fixture.limit))
|
||||
assert.strictEqual(specification.currency, fixture.currency)
|
||||
assert.strictEqual(specification.counterparty, fixture.counterparty)
|
||||
})
|
||||
})
|
||||
assert(data && data.length > 0 && data[0] && data[0].specification);
|
||||
const specification = data[0].specification;
|
||||
assert.strictEqual(Number(specification.limit), Number(fixture.limit));
|
||||
assert.strictEqual(specification.currency, fixture.currency);
|
||||
assert.strictEqual(specification.counterparty, fixture.counterparty);
|
||||
});
|
||||
});
|
||||
|
||||
it('getBalances', function () {
|
||||
const fixture = requests.prepareTrustline.simple
|
||||
const { currency, counterparty } = fixture
|
||||
const options = { currency, counterparty }
|
||||
it("getBalances", function () {
|
||||
const fixture = requests.prepareTrustline.simple;
|
||||
const { currency, counterparty } = fixture;
|
||||
const options = { currency, counterparty };
|
||||
return this.client.getBalances(address, options).then((data) => {
|
||||
assert(data && data.length > 0 && data[0])
|
||||
assert.strictEqual(data[0].currency, fixture.currency)
|
||||
assert.strictEqual(data[0].counterparty, fixture.counterparty)
|
||||
})
|
||||
})
|
||||
assert(data && data.length > 0 && data[0]);
|
||||
assert.strictEqual(data[0].currency, fixture.currency);
|
||||
assert.strictEqual(data[0].counterparty, fixture.counterparty);
|
||||
});
|
||||
});
|
||||
|
||||
it('getOrderbook', function () {
|
||||
it("getOrderbook", function () {
|
||||
const orderbook = {
|
||||
base: {
|
||||
currency: 'XRP'
|
||||
currency: "XRP",
|
||||
},
|
||||
counter: {
|
||||
currency: 'USD',
|
||||
counterparty: masterAccount
|
||||
}
|
||||
}
|
||||
currency: "USD",
|
||||
counterparty: masterAccount,
|
||||
},
|
||||
};
|
||||
return this.client.getOrderbook(address, orderbook).then((book) => {
|
||||
assert(book && book.bids && book.bids.length > 0)
|
||||
assert(book.asks && book.asks.length > 0)
|
||||
const bid = book.bids[0]
|
||||
assert(bid && bid.specification && bid.specification.quantity)
|
||||
assert(bid.specification.totalPrice)
|
||||
assert.strictEqual(bid.specification.direction, 'buy')
|
||||
assert.strictEqual(bid.specification.quantity.currency, 'XRP')
|
||||
assert.strictEqual(bid.specification.totalPrice.currency, 'USD')
|
||||
const ask = book.asks[0]
|
||||
assert(ask && ask.specification && ask.specification.quantity)
|
||||
assert(ask.specification.totalPrice)
|
||||
assert.strictEqual(ask.specification.direction, 'sell')
|
||||
assert.strictEqual(ask.specification.quantity.currency, 'XRP')
|
||||
assert.strictEqual(ask.specification.totalPrice.currency, 'USD')
|
||||
})
|
||||
})
|
||||
assert(book && book.bids && book.bids.length > 0);
|
||||
assert(book.asks && book.asks.length > 0);
|
||||
const bid = book.bids[0];
|
||||
assert(bid && bid.specification && bid.specification.quantity);
|
||||
assert(bid.specification.totalPrice);
|
||||
assert.strictEqual(bid.specification.direction, "buy");
|
||||
assert.strictEqual(bid.specification.quantity.currency, "XRP");
|
||||
assert.strictEqual(bid.specification.totalPrice.currency, "USD");
|
||||
const ask = book.asks[0];
|
||||
assert(ask && ask.specification && ask.specification.quantity);
|
||||
assert(ask.specification.totalPrice);
|
||||
assert.strictEqual(ask.specification.direction, "sell");
|
||||
assert.strictEqual(ask.specification.quantity.currency, "XRP");
|
||||
assert.strictEqual(ask.specification.totalPrice.currency, "USD");
|
||||
});
|
||||
});
|
||||
|
||||
// it('getPaths', function () {
|
||||
// const pathfind = {
|
||||
@@ -501,100 +517,104 @@ describe('integration tests', function () {
|
||||
// })
|
||||
// })
|
||||
|
||||
it('generateWallet', function () {
|
||||
const newWallet = generateXAddress()
|
||||
assert(newWallet && newWallet.xAddress && newWallet.secret)
|
||||
assert(isValidXAddress(newWallet.xAddress))
|
||||
assert(isValidSecret(newWallet.secret))
|
||||
})
|
||||
})
|
||||
it("generateWallet", function () {
|
||||
const newWallet = generateXAddress();
|
||||
assert(newWallet && newWallet.xAddress && newWallet.secret);
|
||||
assert(isValidXAddress(newWallet.xAddress));
|
||||
assert(isValidSecret(newWallet.secret));
|
||||
});
|
||||
});
|
||||
|
||||
describe('integration tests - standalone rippled', function () {
|
||||
const instructions = {maxLedgerVersionOffset: 10}
|
||||
this.timeout(TIMEOUT)
|
||||
describe("integration tests - standalone rippled", function () {
|
||||
const instructions = { maxLedgerVersionOffset: 10 };
|
||||
this.timeout(TIMEOUT);
|
||||
|
||||
beforeEach(_.partial(setup, serverUrl))
|
||||
afterEach(teardown)
|
||||
const address = 'r5nx8ZkwEbFztnc8Qyi22DE9JYjRzNmvs'
|
||||
const secret = 'ss6F8381Br6wwpy9p582H8sBt19J3'
|
||||
const signer1address = 'rQDhz2ZNXmhxzCYwxU6qAbdxsHA4HV45Y2'
|
||||
const signer1secret = 'shK6YXzwYfnFVn3YZSaMh5zuAddKx'
|
||||
const signer2address = 'r3RtUvGw9nMoJ5FuHxuoVJvcENhKtuF9ud'
|
||||
const signer2secret = 'shUHQnL4EH27V4EiBrj6EfhWvZngF'
|
||||
beforeEach(_.partial(setup, serverUrl));
|
||||
afterEach(teardown);
|
||||
const address = "r5nx8ZkwEbFztnc8Qyi22DE9JYjRzNmvs";
|
||||
const secret = "ss6F8381Br6wwpy9p582H8sBt19J3";
|
||||
const signer1address = "rQDhz2ZNXmhxzCYwxU6qAbdxsHA4HV45Y2";
|
||||
const signer1secret = "shK6YXzwYfnFVn3YZSaMh5zuAddKx";
|
||||
const signer2address = "r3RtUvGw9nMoJ5FuHxuoVJvcENhKtuF9ud";
|
||||
const signer2secret = "shUHQnL4EH27V4EiBrj6EfhWvZngF";
|
||||
|
||||
it('submit multisigned transaction', function () {
|
||||
it("submit multisigned transaction", function () {
|
||||
const signers = {
|
||||
threshold: 2,
|
||||
weights: [
|
||||
{address: signer1address, weight: 1},
|
||||
{address: signer2address, weight: 1}
|
||||
]
|
||||
}
|
||||
let minLedgerVersion = null
|
||||
{ address: signer1address, weight: 1 },
|
||||
{ address: signer2address, weight: 1 },
|
||||
],
|
||||
};
|
||||
let minLedgerVersion = null;
|
||||
return payTo(this.client, address)
|
||||
.then(() => {
|
||||
return this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated'
|
||||
})
|
||||
.then(response => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
minLedgerVersion = ledgerVersion
|
||||
return this.client
|
||||
.prepareSettings(address, {signers}, instructions)
|
||||
.then((prepared) => {
|
||||
return testTransaction(
|
||||
this,
|
||||
'SignerListSet',
|
||||
ledgerVersion,
|
||||
prepared,
|
||||
address,
|
||||
secret
|
||||
)
|
||||
})
|
||||
})
|
||||
return this.client
|
||||
.request({
|
||||
command: "ledger",
|
||||
ledger_index: "validated",
|
||||
})
|
||||
.then((response) => response.result.ledger_index)
|
||||
.then((ledgerVersion) => {
|
||||
minLedgerVersion = ledgerVersion;
|
||||
return this.client
|
||||
.prepareSettings(address, { signers }, instructions)
|
||||
.then((prepared) => {
|
||||
return testTransaction(
|
||||
this,
|
||||
"SignerListSet",
|
||||
ledgerVersion,
|
||||
prepared,
|
||||
address,
|
||||
secret
|
||||
);
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
const multisignInstructions = Object.assign({}, instructions, {
|
||||
signersCount: 2
|
||||
})
|
||||
const multisignInstructions = { ...instructions, signersCount: 2 };
|
||||
return this.client
|
||||
.prepareSettings(
|
||||
address,
|
||||
{domain: 'example.com'},
|
||||
{ domain: "example.com" },
|
||||
multisignInstructions
|
||||
)
|
||||
.then((prepared) => {
|
||||
const signed1 = this.client.sign(prepared.txJSON, signer1secret, {
|
||||
signAs: signer1address
|
||||
})
|
||||
signAs: signer1address,
|
||||
});
|
||||
const signed2 = this.client.sign(prepared.txJSON, signer2secret, {
|
||||
signAs: signer2address
|
||||
})
|
||||
signAs: signer2address,
|
||||
});
|
||||
const combined = this.client.combine([
|
||||
signed1.signedTransaction,
|
||||
signed2.signedTransaction
|
||||
])
|
||||
signed2.signedTransaction,
|
||||
]);
|
||||
return this.client
|
||||
.request({command: 'submit', tx_blob: combined.signedTransaction})
|
||||
.then((response) => acceptLedger(this.client).then(() => response))
|
||||
.request({
|
||||
command: "submit",
|
||||
tx_blob: combined.signedTransaction,
|
||||
})
|
||||
.then((response) =>
|
||||
acceptLedger(this.client).then(() => response)
|
||||
)
|
||||
.then((response) => {
|
||||
assert.strictEqual(response.result.engine_result, 'tesSUCCESS')
|
||||
const options = {minLedgerVersion}
|
||||
assert.strictEqual(response.result.engine_result, "tesSUCCESS");
|
||||
const options = { minLedgerVersion };
|
||||
return verifyTransaction(
|
||||
this,
|
||||
combined.id,
|
||||
'AccountSet',
|
||||
"AccountSet",
|
||||
options,
|
||||
{},
|
||||
address
|
||||
)
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error.message)
|
||||
throw error
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
console.log(error.message);
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import _ from 'lodash'
|
||||
import {Server as WebSocketServer} from 'ws'
|
||||
import {EventEmitter2} from 'eventemitter2'
|
||||
import {getFreePort} from './testUtils'
|
||||
import { Request } from '../src'
|
||||
import { EventEmitter2 } from "eventemitter2";
|
||||
import _ from "lodash";
|
||||
import { Server as WebSocketServer } from "ws";
|
||||
|
||||
import type { Request } from "../src";
|
||||
|
||||
import { getFreePort } from "./testUtils";
|
||||
|
||||
function createResponse(request, response, overrides = {}) {
|
||||
const result = Object.assign({}, response.result, overrides)
|
||||
const result = { ...response.result, ...overrides };
|
||||
const change =
|
||||
response.result && !_.isEmpty(overrides)
|
||||
? {id: request.id, result: result}
|
||||
: {id: request.id}
|
||||
return JSON.stringify(Object.assign({}, response, change))
|
||||
? { id: request.id, result }
|
||||
: { id: request.id };
|
||||
return JSON.stringify({ ...response, ...change });
|
||||
}
|
||||
|
||||
function ping(conn, request) {
|
||||
@@ -19,105 +20,111 @@ function ping(conn, request) {
|
||||
conn.send(
|
||||
createResponse(request, {
|
||||
result: {},
|
||||
status: 'success',
|
||||
type: 'response'
|
||||
status: "success",
|
||||
type: "response",
|
||||
})
|
||||
)
|
||||
}, 1000 * 2)
|
||||
);
|
||||
}, 1000 * 2);
|
||||
}
|
||||
|
||||
// We mock out WebSocketServer in these tests and add a lot of custom
|
||||
// properties not defined on the normal WebSocketServer object.
|
||||
type MockedWebSocketServer = any
|
||||
type MockedWebSocketServer = any;
|
||||
|
||||
export function createMockRippled(port) {
|
||||
const mock = new WebSocketServer({port: port}) as MockedWebSocketServer
|
||||
Object.assign(mock, EventEmitter2.prototype)
|
||||
const mock = new WebSocketServer({ port }) as MockedWebSocketServer;
|
||||
Object.assign(mock, EventEmitter2.prototype);
|
||||
|
||||
mock.responses = {}
|
||||
mock.suppressOutput = false
|
||||
mock.responses = {};
|
||||
mock.suppressOutput = false;
|
||||
|
||||
mock.on('connection', function (this: MockedWebSocketServer, conn: any) {
|
||||
this.socket = conn
|
||||
conn.on('message', function (requestJSON) {
|
||||
mock.on("connection", function (this: MockedWebSocketServer, conn: any) {
|
||||
this.socket = conn;
|
||||
conn.on("message", function (requestJSON) {
|
||||
try {
|
||||
const request = JSON.parse(requestJSON)
|
||||
if (request.command === 'ping') {
|
||||
ping(conn, request)
|
||||
} else if (request.command === 'test_command') {
|
||||
mock.testCommand(conn, request)
|
||||
}else if (request.command in mock.responses) {
|
||||
conn.send(createResponse(request, mock.getResponse(request)))
|
||||
const request = JSON.parse(requestJSON);
|
||||
if (request.command === "ping") {
|
||||
ping(conn, request);
|
||||
} else if (request.command === "test_command") {
|
||||
mock.testCommand(conn, request);
|
||||
} else if (request.command in mock.responses) {
|
||||
conn.send(createResponse(request, mock.getResponse(request)));
|
||||
} else {
|
||||
throw new Error(`No event handler registered in mock rippled for ${request.command}`)
|
||||
throw new Error(
|
||||
`No event handler registered in mock rippled for ${request.command}`
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
if (!mock.suppressOutput)
|
||||
console.error('Error: ' + err.message)
|
||||
conn.close(4000, err.message)
|
||||
if (!mock.suppressOutput) {
|
||||
console.error(`Error: ${err.message}`);
|
||||
}
|
||||
conn.close(4000, err.message);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// Adds a mocked response
|
||||
// If an object is passed in for `response`, then the response is static for the command
|
||||
// If a function is passed in for `response`, then the response can be determined by the exact request shape
|
||||
mock.addResponse = (request: Request, response: object | ((r: Request) => object)) => {
|
||||
const command = request.command
|
||||
mock.responses[command] = response
|
||||
}
|
||||
mock.addResponse = (
|
||||
request: Request,
|
||||
response: object | ((r: Request) => object)
|
||||
) => {
|
||||
const command = request.command;
|
||||
mock.responses[command] = response;
|
||||
};
|
||||
|
||||
mock.getResponse = (request: Request) : object => {
|
||||
mock.getResponse = (request: Request): object => {
|
||||
if (!(request.command in mock.responses)) {
|
||||
throw new Error(`No handler for ${request.command}`)
|
||||
throw new Error(`No handler for ${request.command}`);
|
||||
}
|
||||
const functionOrObject = mock.responses[request.command]
|
||||
if (typeof functionOrObject === 'function') {
|
||||
return functionOrObject(request)
|
||||
const functionOrObject = mock.responses[request.command];
|
||||
if (typeof functionOrObject === "function") {
|
||||
return functionOrObject(request);
|
||||
}
|
||||
return functionOrObject
|
||||
}
|
||||
return functionOrObject;
|
||||
};
|
||||
|
||||
mock.testCommand = function testCommand(conn, request) {
|
||||
if (request.data.disconnectIn) {
|
||||
setTimeout(conn.terminate.bind(conn), request.data.disconnectIn)
|
||||
setTimeout(conn.terminate.bind(conn), request.data.disconnectIn);
|
||||
conn.send(
|
||||
createResponse(request, {
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {}
|
||||
status: "success",
|
||||
type: "response",
|
||||
result: {},
|
||||
})
|
||||
)
|
||||
);
|
||||
} else if (request.data.openOnOtherPort) {
|
||||
getFreePort().then((newPort) => {
|
||||
createMockRippled(newPort)
|
||||
createMockRippled(newPort);
|
||||
conn.send(
|
||||
createResponse(request, {
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {port: newPort}
|
||||
status: "success",
|
||||
type: "response",
|
||||
result: { port: newPort },
|
||||
})
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
} else if (request.data.closeServerAndReopen) {
|
||||
setTimeout(() => {
|
||||
conn.terminate()
|
||||
conn.terminate();
|
||||
mock.close.call(mock, () => {
|
||||
setTimeout(() => {
|
||||
createMockRippled(port)
|
||||
}, request.data.closeServerAndReopen)
|
||||
})
|
||||
}, 10)
|
||||
createMockRippled(port);
|
||||
}, request.data.closeServerAndReopen);
|
||||
});
|
||||
}, 10);
|
||||
} else if (request.data.unrecognizedResponse) {
|
||||
conn.send(
|
||||
createResponse(request, {
|
||||
status: 'unrecognized',
|
||||
type: 'response',
|
||||
result: {}
|
||||
status: "unrecognized",
|
||||
type: "response",
|
||||
result: {},
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return mock
|
||||
return mock;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
const port = 34371
|
||||
import {createMockRippled} from './mockRippled'
|
||||
import { createMockRippled } from "./mockRippled";
|
||||
|
||||
const port = 34371;
|
||||
|
||||
function main() {
|
||||
// @ts-expect-error -- mocha.
|
||||
if (global.describe) {
|
||||
// we are running inside mocha, exiting
|
||||
return
|
||||
return;
|
||||
}
|
||||
console.log('starting server on port ' + port)
|
||||
createMockRippled(port)
|
||||
console.log('starting server on port ' + String(port + 1))
|
||||
createMockRippled(port + 1)
|
||||
console.log(`starting server on port ${port}`);
|
||||
createMockRippled(port);
|
||||
console.log(`starting server on port ${String(port + 1)}`);
|
||||
createMockRippled(port + 1);
|
||||
}
|
||||
|
||||
main()
|
||||
main();
|
||||
|
||||
@@ -1,78 +1,77 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyAccountDelete } from './../../src/models/transactions/accountDelete'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyAccountDelete } from "../../src/models/transactions/accountDelete";
|
||||
|
||||
/**
|
||||
* AccountDelete Transaction Verification Testing
|
||||
* AccountDelete Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('AccountDelete Transaction Verification', function () {
|
||||
|
||||
it (`verifies valid AccountDelete`, () => {
|
||||
const validAccountDelete = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
|
||||
DestinationTag: 13,
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648
|
||||
} as any
|
||||
|
||||
assert.doesNotThrow(() => verifyAccountDelete(validAccountDelete))
|
||||
})
|
||||
describe("AccountDelete Transaction Verification", function () {
|
||||
it(`verifies valid AccountDelete`, function () {
|
||||
const validAccountDelete = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
|
||||
DestinationTag: 13,
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648,
|
||||
} as any;
|
||||
|
||||
assert.doesNotThrow(() => verifyAccountDelete(validAccountDelete));
|
||||
});
|
||||
|
||||
it (`throws w/ missing Destination`, () => {
|
||||
const invalidDestination = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648
|
||||
} as any
|
||||
it(`throws w/ missing Destination`, function () {
|
||||
const invalidDestination = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648,
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestination),
|
||||
ValidationError,
|
||||
"AccountDelete: missing field Destination"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestination),
|
||||
ValidationError,
|
||||
"AccountDelete: missing field Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Destination`, () => {
|
||||
const invalidDestination = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: 65478965,
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648
|
||||
} as any
|
||||
it(`throws w/ invalid Destination`, function () {
|
||||
const invalidDestination = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: 65478965,
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648,
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestination),
|
||||
ValidationError,
|
||||
"AccountDelete: invalid Destination"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestination),
|
||||
ValidationError,
|
||||
"AccountDelete: invalid Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid DestinationTag`, () => {
|
||||
const invalidDestinationTag = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
|
||||
DestinationTag: "gvftyujnbv",
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648
|
||||
} as any
|
||||
it(`throws w/ invalid DestinationTag`, function () {
|
||||
const invalidDestinationTag = {
|
||||
TransactionType: "AccountDelete",
|
||||
Account: "rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm",
|
||||
Destination: "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
|
||||
DestinationTag: "gvftyujnbv",
|
||||
Fee: "5000000",
|
||||
Sequence: 2470665,
|
||||
Flags: 2147483648,
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestinationTag),
|
||||
ValidationError,
|
||||
"AccountDelete: invalid DestinationTag"
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountDelete(invalidDestinationTag),
|
||||
ValidationError,
|
||||
"AccountDelete: invalid DestinationTag"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,110 +1,111 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyAccountSet } from './../../src/models/transactions/accountSet'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyAccountSet } from "../../src/models/transactions/accountSet";
|
||||
|
||||
/**
|
||||
* AccountSet Transaction Verification Testing
|
||||
* AccountSet Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('AccountSet Transaction Verification', function () {
|
||||
describe("AccountSet Transaction Verification", function () {
|
||||
let account;
|
||||
|
||||
let account
|
||||
beforeEach(function () {
|
||||
account = {
|
||||
TransactionType: "AccountSet",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee: "12",
|
||||
Sequence: 5,
|
||||
Domain: "6578616D706C652E636F6D",
|
||||
SetFlag: 5,
|
||||
MessageKey:
|
||||
"03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
} as any;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
account = {
|
||||
TransactionType : "AccountSet",
|
||||
Account : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee : "12",
|
||||
Sequence : 5,
|
||||
Domain : "6578616D706C652E636F6D",
|
||||
SetFlag : 5,
|
||||
MessageKey : "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB"
|
||||
} as any
|
||||
})
|
||||
it(`verifies valid AccountSet`, function () {
|
||||
assert.doesNotThrow(() => verifyAccountSet(account));
|
||||
});
|
||||
|
||||
it (`verifies valid AccountSet`, () => {
|
||||
assert.doesNotThrow(() => verifyAccountSet(account))
|
||||
})
|
||||
it(`throws w/ invalid SetFlag (out of range)`, function () {
|
||||
account.SetFlag = 12;
|
||||
|
||||
it (`throws w/ invalid SetFlag (out of range)`, () => {
|
||||
account.SetFlag = 12
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid SetFlag"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid SetFlag"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid SetFlag (incorrect type)`, function () {
|
||||
account.SetFlag = "abc";
|
||||
|
||||
it (`throws w/ invalid SetFlag (incorrect type)`, () => {
|
||||
account.SetFlag = 'abc'
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid SetFlag"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid SetFlag"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid ClearFlag`, () => {
|
||||
account.ClearFlag = 12
|
||||
it(`throws w/ invalid ClearFlag`, function () {
|
||||
account.ClearFlag = 12;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid ClearFlag"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid ClearFlag"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Domain`, () => {
|
||||
account.Domain = 6578616
|
||||
it(`throws w/ invalid Domain`, function () {
|
||||
account.Domain = 6578616;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid Domain"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid Domain"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid EmailHash`, () => {
|
||||
account.EmailHash = 657861645678909876543456789876543
|
||||
it(`throws w/ invalid EmailHash`, function () {
|
||||
account.EmailHash = 657861645678909876543456789876543;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid EmailHash"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid EmailHash"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid MessageKey`, () => {
|
||||
account.MessageKey = 65786165678908765456789567890678
|
||||
it(`throws w/ invalid MessageKey`, function () {
|
||||
account.MessageKey = 65786165678908765456789567890678;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid MessageKey"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid MessageKey"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid TransferRate`, () => {
|
||||
account.TransferRate = "1000000001"
|
||||
it(`throws w/ invalid TransferRate`, function () {
|
||||
account.TransferRate = "1000000001";
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid TransferRate"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid TransferRate"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid TickSize`, () => {
|
||||
account.TickSize = 20
|
||||
it(`throws w/ invalid TickSize`, function () {
|
||||
account.TickSize = 20;
|
||||
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid TickSize"
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyAccountSet(account),
|
||||
ValidationError,
|
||||
"AccountSet: invalid TickSize"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,225 +1,232 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyBaseTransaction } from './../../src/models/transactions/common'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyBaseTransaction } from "../../src/models/transactions/common";
|
||||
|
||||
/**
|
||||
* Transaction Verification Testing
|
||||
* Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('Transaction Verification', function () {
|
||||
it(`Verifies all optional BaseTransaction`, () => {
|
||||
const txJson = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Fee: "12",
|
||||
Sequence: 100,
|
||||
AccountTxnID: "DEADBEEF",
|
||||
Flags: 15,
|
||||
LastLedgerSequence: 1383,
|
||||
Memos: [
|
||||
{
|
||||
Memo: {
|
||||
MemoType: "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
||||
MemoData: "72656e74"
|
||||
}
|
||||
},
|
||||
{
|
||||
Memo: {
|
||||
MemoFormat: "687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
||||
MemoData: "72656e74"
|
||||
}
|
||||
},
|
||||
{
|
||||
Memo: {
|
||||
MemoType: "72656e74"
|
||||
}
|
||||
}
|
||||
],
|
||||
Signers: [
|
||||
{
|
||||
Account: "r....",
|
||||
TxnSignature: "DEADBEEF",
|
||||
SigningPubKey: "hex-string"
|
||||
}
|
||||
],
|
||||
SourceTag: 31,
|
||||
SigningPublicKey: "03680DD274EE55594F7244F489CD38CF3A5A1A4657122FB8143E185B2BA043DF36",
|
||||
TicketSequence: 10,
|
||||
TxnSignature: "3045022100C6708538AE5A697895937C758E99A595B57A16393F370F11B8D4C032E80B532002207776A8E85BB9FAF460A92113B9C60F170CD964196B1F084E0DAB65BAEC368B66"
|
||||
}
|
||||
describe("Transaction Verification", function () {
|
||||
it(`Verifies all optional BaseTransaction`, function () {
|
||||
const txJson = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Fee: "12",
|
||||
Sequence: 100,
|
||||
AccountTxnID: "DEADBEEF",
|
||||
Flags: 15,
|
||||
LastLedgerSequence: 1383,
|
||||
Memos: [
|
||||
{
|
||||
Memo: {
|
||||
MemoType:
|
||||
"687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
||||
MemoData: "72656e74",
|
||||
},
|
||||
},
|
||||
{
|
||||
Memo: {
|
||||
MemoFormat:
|
||||
"687474703a2f2f6578616d706c652e636f6d2f6d656d6f2f67656e65726963",
|
||||
MemoData: "72656e74",
|
||||
},
|
||||
},
|
||||
{
|
||||
Memo: {
|
||||
MemoType: "72656e74",
|
||||
},
|
||||
},
|
||||
],
|
||||
Signers: [
|
||||
{
|
||||
Account: "r....",
|
||||
TxnSignature: "DEADBEEF",
|
||||
SigningPubKey: "hex-string",
|
||||
},
|
||||
],
|
||||
SourceTag: 31,
|
||||
SigningPublicKey:
|
||||
"03680DD274EE55594F7244F489CD38CF3A5A1A4657122FB8143E185B2BA043DF36",
|
||||
TicketSequence: 10,
|
||||
TxnSignature:
|
||||
"3045022100C6708538AE5A697895937C758E99A595B57A16393F370F11B8D4C032E80B532002207776A8E85BB9FAF460A92113B9C60F170CD964196B1F084E0DAB65BAEC368B66",
|
||||
};
|
||||
|
||||
assert.doesNotThrow(() => verifyBaseTransaction(txJson))
|
||||
})
|
||||
assert.doesNotThrow(() => verifyBaseTransaction(txJson));
|
||||
});
|
||||
|
||||
it(`Verifies only required BaseTransaction`, () => {
|
||||
const txJson = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
}
|
||||
|
||||
assert.doesNotThrow(() => verifyBaseTransaction(txJson))
|
||||
})
|
||||
it(`Verifies only required BaseTransaction`, function () {
|
||||
const txJson = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
};
|
||||
|
||||
it (`Handles invalid Fee`, () => {
|
||||
const invalidFee = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Fee: 1000
|
||||
} as any
|
||||
assert.doesNotThrow(() => verifyBaseTransaction(txJson));
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidFee),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Fee"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid Fee`, function () {
|
||||
const invalidFee = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Fee: 1000,
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid Sequence`, () => {
|
||||
const invalidSeq = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Sequence: "145"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidFee),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Fee"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSeq),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Sequence"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid Sequence`, function () {
|
||||
const invalidSeq = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Sequence: "145",
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid AccountTxnID`, () => {
|
||||
const invalidID = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
AccountTxnID: ["WRONG"]
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSeq),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Sequence"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidID),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid AccountTxnID"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid AccountTxnID`, function () {
|
||||
const invalidID = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
AccountTxnID: ["WRONG"],
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid LastLedgerSequence`, () => {
|
||||
const invalidLastLedgerSequence = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
LastLedgerSequence: "1000"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidID),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid AccountTxnID"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidLastLedgerSequence),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid LastLedgerSequence"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid LastLedgerSequence`, function () {
|
||||
const invalidLastLedgerSequence = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
LastLedgerSequence: "1000",
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid SourceTag`, () => {
|
||||
const invalidSourceTag = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
SourceTag: ["ARRAY"]
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidLastLedgerSequence),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid LastLedgerSequence"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSourceTag),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid SourceTag"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid SourceTag`, function () {
|
||||
const invalidSourceTag = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
SourceTag: ["ARRAY"],
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid SigningPubKey`, () => {
|
||||
const invalidSigningPubKey = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
SigningPubKey: 1000
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSourceTag),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid SourceTag"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigningPubKey),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid SigningPubKey"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid SigningPubKey`, function () {
|
||||
const invalidSigningPubKey = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
SigningPubKey: 1000,
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid TicketSequence`, () => {
|
||||
const invalidTicketSequence = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
TicketSequence: "1000"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigningPubKey),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid SigningPubKey"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidTicketSequence),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid TicketSequence"
|
||||
)
|
||||
})
|
||||
it(`Handles invalid TicketSequence`, function () {
|
||||
const invalidTicketSequence = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
TicketSequence: "1000",
|
||||
} as any;
|
||||
|
||||
it (`Handles invalid TxnSignature`, () => {
|
||||
const invalidTxnSignature = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
TxnSignature: 1000
|
||||
} as any
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidTxnSignature),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid TxnSignature"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidTicketSequence),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid TicketSequence"
|
||||
);
|
||||
});
|
||||
|
||||
it (`Handles invalid Signers`, () => {
|
||||
const invalidSigners = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Signers: []
|
||||
} as any
|
||||
it(`Handles invalid TxnSignature`, function () {
|
||||
const invalidTxnSignature = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
TxnSignature: 1000,
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigners),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Signers"
|
||||
)
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidTxnSignature),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid TxnSignature"
|
||||
);
|
||||
});
|
||||
|
||||
const invalidSigners2 = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Signers: [
|
||||
{
|
||||
"Account": "r...."
|
||||
}
|
||||
]
|
||||
} as any
|
||||
it(`Handles invalid Signers`, function () {
|
||||
const invalidSigners = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Signers: [],
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigners2),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Signers"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigners),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Signers"
|
||||
);
|
||||
|
||||
it (`Handles invalid Memo`, () => {
|
||||
const invalidMemo = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Memos: [{
|
||||
Memo: {
|
||||
MemoData: "HI",
|
||||
Address: "WRONG"
|
||||
}
|
||||
}]
|
||||
} as any
|
||||
const invalidSigners2 = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Signers: [
|
||||
{
|
||||
Account: "r....",
|
||||
},
|
||||
],
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidMemo),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Memos"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidSigners2),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Signers"
|
||||
);
|
||||
});
|
||||
|
||||
it(`Handles invalid Memo`, function () {
|
||||
const invalidMemo = {
|
||||
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",
|
||||
TransactionType: "Payment",
|
||||
Memos: [
|
||||
{
|
||||
Memo: {
|
||||
MemoData: "HI",
|
||||
Address: "WRONG",
|
||||
},
|
||||
},
|
||||
],
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyBaseTransaction(invalidMemo),
|
||||
ValidationError,
|
||||
"BaseTransaction: invalid Memos"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyCheckCancel} from './../../src/models/transactions/checkCancel'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyCheckCancel } from "../../src/models/transactions/checkCancel";
|
||||
|
||||
/**
|
||||
* CheckCancel Transaction Verification Testing
|
||||
* CheckCancel Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('CheckCancel Transaction Verification', function () {
|
||||
describe("CheckCancel Transaction Verification", function () {
|
||||
it(`verifies valid CheckCancel`, function () {
|
||||
const validCheckCancel = {
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
TransactionType: "CheckCancel",
|
||||
CheckID:
|
||||
"49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
|
||||
} as any;
|
||||
|
||||
it (`verifies valid CheckCancel`, () => {
|
||||
const validCheckCancel = {
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
TransactionType : "CheckCancel",
|
||||
CheckID : "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0"
|
||||
} as any
|
||||
assert.doesNotThrow(() => verifyCheckCancel(validCheckCancel));
|
||||
});
|
||||
|
||||
assert.doesNotThrow(() => verifyCheckCancel(validCheckCancel))
|
||||
})
|
||||
it(`throws w/ invalid CheckCancel`, function () {
|
||||
const invalidCheckID = {
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
TransactionType: "CheckCancel",
|
||||
CheckID: 496473456789876545678909876545678,
|
||||
} as any;
|
||||
|
||||
it (`throws w/ invalid CheckCancel`, () => {
|
||||
const invalidCheckID = {
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
TransactionType : "CheckCancel",
|
||||
CheckID : 496473456789876545678909876545678
|
||||
} as any
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCancel(invalidCheckID),
|
||||
ValidationError,
|
||||
"CheckCancel: invalid CheckID"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCancel(invalidCheckID),
|
||||
ValidationError,
|
||||
"CheckCancel: invalid CheckID"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,84 +1,89 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyCheckCash } from './../../src/models/transactions/checkCash'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyCheckCash } from "../../src/models/transactions/checkCash";
|
||||
|
||||
/**
|
||||
* CheckCash Transaction Verification Testing
|
||||
* CheckCash Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('CheckCash Transaction Verification', function () {
|
||||
|
||||
it (`verifies valid CheckCash`, () => {
|
||||
const validCheckCash = {
|
||||
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType : "CheckCash",
|
||||
Amount : "100000000",
|
||||
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
|
||||
Fee : "12"
|
||||
} as any
|
||||
|
||||
assert.doesNotThrow(() => verifyCheckCash(validCheckCash))
|
||||
})
|
||||
describe("CheckCash Transaction Verification", function () {
|
||||
it(`verifies valid CheckCash`, function () {
|
||||
const validCheckCash = {
|
||||
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType: "CheckCash",
|
||||
Amount: "100000000",
|
||||
CheckID:
|
||||
"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
it (`throws w/ invalid CheckID`, () => {
|
||||
const invalidCheckID = {
|
||||
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType : "CheckCash",
|
||||
Amount : "100000000",
|
||||
CheckID : 83876645678909854567890
|
||||
} as any
|
||||
assert.doesNotThrow(() => verifyCheckCash(validCheckCash));
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidCheckID),
|
||||
ValidationError,
|
||||
"CheckCash: invalid CheckID"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid CheckID`, function () {
|
||||
const invalidCheckID = {
|
||||
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType: "CheckCash",
|
||||
Amount: "100000000",
|
||||
CheckID: 83876645678909854567890,
|
||||
} as any;
|
||||
|
||||
it (`throws w/ invalid Amount`, () => {
|
||||
const invalidAmount = {
|
||||
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType : "CheckCash",
|
||||
Amount : 100000000,
|
||||
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidCheckID),
|
||||
ValidationError,
|
||||
"CheckCash: invalid CheckID"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidAmount),
|
||||
ValidationError,
|
||||
"CheckCash: invalid Amount"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid Amount`, function () {
|
||||
const invalidAmount = {
|
||||
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType: "CheckCash",
|
||||
Amount: 100000000,
|
||||
CheckID:
|
||||
"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
|
||||
} as any;
|
||||
|
||||
it (`throws w/ having both Amount and DeliverMin`, () => {
|
||||
const invalidDeliverMin = {
|
||||
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType : "CheckCash",
|
||||
Amount : "100000000",
|
||||
DeliverMin: 852156963,
|
||||
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidAmount),
|
||||
ValidationError,
|
||||
"CheckCash: invalid Amount"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidDeliverMin),
|
||||
ValidationError,
|
||||
"CheckCash: cannot have both Amount and DeliverMin"
|
||||
)
|
||||
})
|
||||
it(`throws w/ having both Amount and DeliverMin`, function () {
|
||||
const invalidDeliverMin = {
|
||||
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType: "CheckCash",
|
||||
Amount: "100000000",
|
||||
DeliverMin: 852156963,
|
||||
CheckID:
|
||||
"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
|
||||
} as any;
|
||||
|
||||
it (`throws w/ invalid DeliverMin`, () => {
|
||||
const invalidDeliverMin = {
|
||||
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType : "CheckCash",
|
||||
DeliverMin: 852156963,
|
||||
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
|
||||
} as any
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidDeliverMin),
|
||||
ValidationError,
|
||||
"CheckCash: cannot have both Amount and DeliverMin"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidDeliverMin),
|
||||
ValidationError,
|
||||
"CheckCash: invalid DeliverMin"
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`throws w/ invalid DeliverMin`, function () {
|
||||
const invalidDeliverMin = {
|
||||
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
TransactionType: "CheckCash",
|
||||
DeliverMin: 852156963,
|
||||
CheckID:
|
||||
"838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCash(invalidDeliverMin),
|
||||
ValidationError,
|
||||
"CheckCash: invalid DeliverMin"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,123 +1,127 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyCheckCreate } from './../../src/models/transactions/checkCreate'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyCheckCreate } from "../../src/models/transactions/checkCreate";
|
||||
|
||||
/**
|
||||
* CheckCreate Transaction Verification Testing
|
||||
* CheckCreate Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('CheckCreate Transaction Verification', function () {
|
||||
|
||||
it (`verifies valid CheckCreate`, () => {
|
||||
const validCheck = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax : "100000000",
|
||||
Expiration : 570113521,
|
||||
InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag : 1,
|
||||
Fee : "12"
|
||||
} as any
|
||||
|
||||
assert.doesNotThrow(() => verifyCheckCreate(validCheck))
|
||||
})
|
||||
describe("CheckCreate Transaction Verification", function () {
|
||||
it(`verifies valid CheckCreate`, function () {
|
||||
const validCheck = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax: "100000000",
|
||||
Expiration: 570113521,
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag: 1,
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.doesNotThrow(() => verifyCheckCreate(validCheck));
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Destination`, () => {
|
||||
const invalidDestination = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : 7896214563214789632154,
|
||||
SendMax : "100000000",
|
||||
Expiration : 570113521,
|
||||
InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag : 1,
|
||||
Fee : "12"
|
||||
} as any
|
||||
it(`throws w/ invalid Destination`, function () {
|
||||
const invalidDestination = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: 7896214563214789632154,
|
||||
SendMax: "100000000",
|
||||
Expiration: 570113521,
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag: 1,
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidDestination),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid Destination"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidDestination),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid SendMax`, () => {
|
||||
const invalidSendMax = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax : 100000000,
|
||||
Expiration : 570113521,
|
||||
InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag : 1,
|
||||
Fee : "12"
|
||||
} as any
|
||||
it(`throws w/ invalid SendMax`, function () {
|
||||
const invalidSendMax = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax: 100000000,
|
||||
Expiration: 570113521,
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag: 1,
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidSendMax),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid SendMax"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidSendMax),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid SendMax"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid DestinationTag`, () => {
|
||||
const invalidDestinationTag = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax : "100000000",
|
||||
Expiration : 570113521,
|
||||
InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag : "1",
|
||||
Fee : "12"
|
||||
} as any
|
||||
it(`throws w/ invalid DestinationTag`, function () {
|
||||
const invalidDestinationTag = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax: "100000000",
|
||||
Expiration: 570113521,
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag: "1",
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidDestinationTag),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid DestinationTag"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidDestinationTag),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid DestinationTag"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Expiration`, () => {
|
||||
const invalidExpiration = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax : "100000000",
|
||||
Expiration : "570113521",
|
||||
InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag : 1,
|
||||
Fee : "12"
|
||||
} as any
|
||||
it(`throws w/ invalid Expiration`, function () {
|
||||
const invalidExpiration = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax: "100000000",
|
||||
Expiration: "570113521",
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
DestinationTag: 1,
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidExpiration),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid Expiration"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidExpiration),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid Expiration"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid InvoiceID`, () => {
|
||||
const invalidInvoiceID = {
|
||||
TransactionType : "CheckCreate",
|
||||
Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax : "100000000",
|
||||
Expiration : 570113521,
|
||||
InvoiceID : 7896545655285446963258531,
|
||||
DestinationTag : 1,
|
||||
Fee : "12"
|
||||
} as any
|
||||
it(`throws w/ invalid InvoiceID`, function () {
|
||||
const invalidInvoiceID = {
|
||||
TransactionType: "CheckCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
SendMax: "100000000",
|
||||
Expiration: 570113521,
|
||||
InvoiceID: 7896545655285446963258531,
|
||||
DestinationTag: 1,
|
||||
Fee: "12",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidInvoiceID),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid InvoiceID"
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyCheckCreate(invalidInvoiceID),
|
||||
ValidationError,
|
||||
"CheckCreate: invalid InvoiceID"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,83 +1,85 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyDepositPreauth } from './../../src/models/transactions/depositPreauth'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyDepositPreauth } from "../../src/models/transactions/depositPreauth";
|
||||
|
||||
/**
|
||||
* DepositPreauth Transaction Verification Testing
|
||||
* DepositPreauth Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('DepositPreauth Transaction Verification', () => {
|
||||
let depositPreauth
|
||||
describe("DepositPreauth Transaction Verification", function () {
|
||||
let depositPreauth;
|
||||
|
||||
beforeEach(() => {
|
||||
depositPreauth = {
|
||||
TransactionType: 'DepositPreauth',
|
||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||
} as any
|
||||
})
|
||||
beforeEach(function () {
|
||||
depositPreauth = {
|
||||
TransactionType: "DepositPreauth",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
} as any;
|
||||
});
|
||||
|
||||
it ('verifies valid DepositPreauth when only Authorize is provided', () => {
|
||||
depositPreauth.Authorize = 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW'
|
||||
assert.doesNotThrow(() => verifyDepositPreauth(depositPreauth))
|
||||
})
|
||||
it("verifies valid DepositPreauth when only Authorize is provided", function () {
|
||||
depositPreauth.Authorize = "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW";
|
||||
assert.doesNotThrow(() => verifyDepositPreauth(depositPreauth));
|
||||
});
|
||||
|
||||
it ('verifies valid DepositPreauth when only Unauthorize is provided', () => {
|
||||
depositPreauth.Unauthorize = 'raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n'
|
||||
assert.doesNotThrow(() => verifyDepositPreauth(depositPreauth))
|
||||
})
|
||||
it("verifies valid DepositPreauth when only Unauthorize is provided", function () {
|
||||
depositPreauth.Unauthorize = "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n";
|
||||
assert.doesNotThrow(() => verifyDepositPreauth(depositPreauth));
|
||||
});
|
||||
|
||||
it ('throws when both Authorize and Unauthorize are provided', () => {
|
||||
depositPreauth.Authorize = 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW'
|
||||
depositPreauth.Unauthorize = 'raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n'
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: can't provide both Authorize and Unauthorize fields"
|
||||
)
|
||||
})
|
||||
it("throws when both Authorize and Unauthorize are provided", function () {
|
||||
depositPreauth.Authorize = "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW";
|
||||
depositPreauth.Unauthorize = "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n";
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: can't provide both Authorize and Unauthorize fields"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when neither Authorize nor Unauthorize are provided', () => {
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
'DepositPreauth: must provide either Authorize or Unauthorize field'
|
||||
)
|
||||
})
|
||||
it("throws when neither Authorize nor Unauthorize are provided", function () {
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: must provide either Authorize or Unauthorize field"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when Authorize is not a string', () => {
|
||||
depositPreauth.Authorize = 1234
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
'DepositPreauth: Authorize must be a string'
|
||||
)
|
||||
})
|
||||
it("throws when Authorize is not a string", function () {
|
||||
depositPreauth.Authorize = 1234;
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Authorize must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when an Account attempts to preauthorize its own address', () => {
|
||||
depositPreauth.Authorize = depositPreauth.Account
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Account can't preauthorize its own address"
|
||||
)
|
||||
})
|
||||
it("throws when an Account attempts to preauthorize its own address", function () {
|
||||
depositPreauth.Authorize = depositPreauth.Account;
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Account can't preauthorize its own address"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when Unauthorize is not a string', () => {
|
||||
depositPreauth.Unauthorize = 1234
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
'DepositPreauth: Unauthorize must be a string'
|
||||
)
|
||||
})
|
||||
it("throws when Unauthorize is not a string", function () {
|
||||
depositPreauth.Unauthorize = 1234;
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Unauthorize must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when an Account attempts to unauthorize its own address', () => {
|
||||
depositPreauth.Unauthorize = depositPreauth.Account
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Account can't unauthorize its own address"
|
||||
)
|
||||
})
|
||||
})
|
||||
it("throws when an Account attempts to unauthorize its own address", function () {
|
||||
depositPreauth.Unauthorize = depositPreauth.Account;
|
||||
assert.throws(
|
||||
() => verifyDepositPreauth(depositPreauth),
|
||||
ValidationError,
|
||||
"DepositPreauth: Account can't unauthorize its own address"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,65 +1,66 @@
|
||||
import { verifyEscrowCancel } from './../../src/models/transactions/escrowCancel'
|
||||
import { assert } from 'chai'
|
||||
import { ValidationError } from '../../src/common/errors'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "../../src/common/errors";
|
||||
import { verifyEscrowCancel } from "../../src/models/transactions/escrowCancel";
|
||||
|
||||
/**
|
||||
* Transaction Verification Testing
|
||||
* Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('Transaction Verification', function () {
|
||||
let cancel
|
||||
describe("Transaction Verification", function () {
|
||||
let cancel;
|
||||
|
||||
beforeEach(() => {
|
||||
cancel = {
|
||||
TransactionType: "EscrowCancel",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Owner: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
OfferSequence: 7,
|
||||
}
|
||||
})
|
||||
beforeEach(function () {
|
||||
cancel = {
|
||||
TransactionType: "EscrowCancel",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Owner: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
OfferSequence: 7,
|
||||
};
|
||||
});
|
||||
|
||||
it (`Valid EscrowCancel`, () => {
|
||||
assert.doesNotThrow(() => verifyEscrowCancel(cancel))
|
||||
})
|
||||
it(`Valid EscrowCancel`, function () {
|
||||
assert.doesNotThrow(() => verifyEscrowCancel(cancel));
|
||||
});
|
||||
|
||||
it (`Invalid EscrowCancel missing owner`, () => {
|
||||
delete cancel.Owner
|
||||
it(`Invalid EscrowCancel missing owner`, function () {
|
||||
delete cancel.Owner;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
'EscrowCancel: missing Owner'
|
||||
)
|
||||
})
|
||||
|
||||
it (`Invalid EscrowCancel missing offerSequence`, () => {
|
||||
delete cancel.OfferSequence
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
"EscrowCancel: missing Owner"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
'EscrowCancel: missing OfferSequence'
|
||||
)
|
||||
})
|
||||
it(`Invalid EscrowCancel missing offerSequence`, function () {
|
||||
delete cancel.OfferSequence;
|
||||
|
||||
it (`Invalid OfferSequence`, () => {
|
||||
cancel.Owner = 10
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
"EscrowCancel: missing OfferSequence"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
'EscrowCancel: Owner must be a string'
|
||||
)
|
||||
})
|
||||
it(`Invalid OfferSequence`, function () {
|
||||
cancel.Owner = 10;
|
||||
|
||||
it (`Invalid owner`, () => {
|
||||
cancel.OfferSequence = "10"
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
"EscrowCancel: Owner must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
'EscrowCancel: OfferSequence must be a number'
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`Invalid owner`, function () {
|
||||
cancel.OfferSequence = "10";
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCancel(cancel),
|
||||
ValidationError,
|
||||
"EscrowCancel: OfferSequence must be a number"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,132 +1,135 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyEscrowCreate } from './../../src/models/transactions/escrowCreate'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyEscrowCreate } from "../../src/models/transactions/escrowCreate";
|
||||
|
||||
/**
|
||||
* EscrowCreate Transaction Verification Testing
|
||||
* EscrowCreate Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('EscrowCreate Transaction Verification', function () {
|
||||
let escrow
|
||||
describe("EscrowCreate Transaction Verification", function () {
|
||||
let escrow;
|
||||
|
||||
beforeEach(() => {
|
||||
escrow = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "EscrowCreate",
|
||||
Amount: "10000",
|
||||
Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
CancelAfter: 533257958,
|
||||
FinishAfter: 533171558,
|
||||
Condition: "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
DestinationTag: 23480,
|
||||
SourceTag: 11747
|
||||
}
|
||||
})
|
||||
|
||||
it (`verifies valid EscrowCreate`, () => {
|
||||
assert.doesNotThrow(() => verifyEscrowCreate(escrow))
|
||||
})
|
||||
beforeEach(function () {
|
||||
escrow = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "EscrowCreate",
|
||||
Amount: "10000",
|
||||
Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
CancelAfter: 533257958,
|
||||
FinishAfter: 533171558,
|
||||
Condition:
|
||||
"A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
DestinationTag: 23480,
|
||||
SourceTag: 11747,
|
||||
};
|
||||
});
|
||||
|
||||
it (`Missing amount`, () => {
|
||||
delete escrow.Amount
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: missing field Amount"
|
||||
)
|
||||
})
|
||||
it(`verifies valid EscrowCreate`, function () {
|
||||
assert.doesNotThrow(() => verifyEscrowCreate(escrow));
|
||||
});
|
||||
|
||||
it (`Missing destination`, () => {
|
||||
delete escrow.Destination
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: missing field Destination"
|
||||
)
|
||||
})
|
||||
it(`Missing amount`, function () {
|
||||
delete escrow.Amount;
|
||||
|
||||
it (`throws w/ invalid Destination`, () => {
|
||||
escrow.Destination = 10
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: missing field Amount"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Destination must be a string"
|
||||
)
|
||||
})
|
||||
it(`Missing destination`, function () {
|
||||
delete escrow.Destination;
|
||||
|
||||
it (`throws w/ invalid Amount`, () => {
|
||||
escrow.Amount = 1000
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: missing field Destination"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Amount must be a string"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid Destination`, function () {
|
||||
escrow.Destination = 10;
|
||||
|
||||
it (`invalid CancelAfter`, () => {
|
||||
escrow.CancelAfter = "100"
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: CancelAfter must be a number"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Destination must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`invalid FinishAfter`, () => {
|
||||
escrow.FinishAfter = "1000"
|
||||
it(`throws w/ invalid Amount`, function () {
|
||||
escrow.Amount = 1000;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: FinishAfter must be a number"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Amount must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`invalid Condition`, () => {
|
||||
escrow.Condition = 0x141243
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Condition must be a string"
|
||||
)
|
||||
})
|
||||
it(`invalid CancelAfter`, function () {
|
||||
escrow.CancelAfter = "100";
|
||||
|
||||
it (`invalid DestinationTag`, () => {
|
||||
escrow.DestinationTag = "100"
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: DestinationTag must be a number"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: CancelAfter must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it (`Missing both CancelAfter and FinishAfter`, () => {
|
||||
delete escrow.CancelAfter
|
||||
delete escrow.FinishAfter
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Either CancelAfter or FinishAfter must be specified"
|
||||
)
|
||||
})
|
||||
it(`invalid FinishAfter`, function () {
|
||||
escrow.FinishAfter = "1000";
|
||||
|
||||
it (`Missing both Condition and FinishAfter`, () => {
|
||||
delete escrow.Condition
|
||||
delete escrow.FinishAfter
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Either Condition or FinishAfter must be specified"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: FinishAfter must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid Condition`, function () {
|
||||
escrow.Condition = 0x141243;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Condition must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid DestinationTag`, function () {
|
||||
escrow.DestinationTag = "100";
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: DestinationTag must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it(`Missing both CancelAfter and FinishAfter`, function () {
|
||||
delete escrow.CancelAfter;
|
||||
delete escrow.FinishAfter;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Either CancelAfter or FinishAfter must be specified"
|
||||
);
|
||||
});
|
||||
|
||||
it(`Missing both Condition and FinishAfter`, function () {
|
||||
delete escrow.Condition;
|
||||
delete escrow.FinishAfter;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowCreate(escrow),
|
||||
ValidationError,
|
||||
"EscrowCreate: Either Condition or FinishAfter must be specified"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,75 +1,76 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyEscrowFinish } from './../../src/models/transactions/escrowFinish'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyEscrowFinish } from "../../src/models/transactions/escrowFinish";
|
||||
|
||||
/**
|
||||
* EscrowFinish Transaction Verification Testing
|
||||
* EscrowFinish Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('EscrowFinish Transaction Verification', function () {
|
||||
let escrow
|
||||
describe("EscrowFinish Transaction Verification", function () {
|
||||
let escrow;
|
||||
|
||||
beforeEach(() => {
|
||||
escrow = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "EscrowFinish",
|
||||
Owner: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
OfferSequence: 7,
|
||||
Condition: "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
Fulfillment: "A0028000"
|
||||
}
|
||||
})
|
||||
it (`verifies valid EscrowFinish`, () => {
|
||||
assert.doesNotThrow(() => verifyEscrowFinish(escrow))
|
||||
})
|
||||
beforeEach(function () {
|
||||
escrow = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "EscrowFinish",
|
||||
Owner: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
OfferSequence: 7,
|
||||
Condition:
|
||||
"A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||
Fulfillment: "A0028000",
|
||||
};
|
||||
});
|
||||
it(`verifies valid EscrowFinish`, function () {
|
||||
assert.doesNotThrow(() => verifyEscrowFinish(escrow));
|
||||
});
|
||||
|
||||
it (`verifies valid EscrowFinish w/o optional`, () => {
|
||||
delete escrow.Condition
|
||||
delete escrow.Fulfillment
|
||||
|
||||
assert.doesNotThrow(() => verifyEscrowFinish(escrow))
|
||||
})
|
||||
it(`verifies valid EscrowFinish w/o optional`, function () {
|
||||
delete escrow.Condition;
|
||||
delete escrow.Fulfillment;
|
||||
|
||||
assert.doesNotThrow(() => verifyEscrowFinish(escrow));
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Owner`, () => {
|
||||
escrow.Owner = 0x15415253
|
||||
|
||||
it(`throws w/ invalid Owner`, function () {
|
||||
escrow.Owner = 0x15415253;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Owner must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Owner must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid OfferSequence`, () => {
|
||||
escrow.OfferSequence = "10"
|
||||
it(`throws w/ invalid OfferSequence`, function () {
|
||||
escrow.OfferSequence = "10";
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: OfferSequence must be a number"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: OfferSequence must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Condition`, () => {
|
||||
escrow.Condition = 10
|
||||
it(`throws w/ invalid Condition`, function () {
|
||||
escrow.Condition = 10;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Condition must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Condition must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Fulfillment`, () => {
|
||||
escrow.Fulfillment = 0x142341
|
||||
it(`throws w/ invalid Fulfillment`, function () {
|
||||
escrow.Fulfillment = 0x142341;
|
||||
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Fulfillment must be a string"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyEscrowFinish(escrow),
|
||||
ValidationError,
|
||||
"EscrowFinish: Fulfillment must be a string"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,53 +1,57 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyOfferCancel } from './../../src/models/transactions/offerCancel'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyOfferCancel } from "../../src/models/transactions/offerCancel";
|
||||
|
||||
/**
|
||||
* OfferCancel Transaction Verification Testing
|
||||
* OfferCancel Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('OfferCancel Transaction Verification', function () {
|
||||
let offer
|
||||
|
||||
beforeEach(() => {
|
||||
offer = {
|
||||
Account: "rnKiczmiQkZFiDES8THYyLA2pQohC5C6EF",
|
||||
Fee: "10",
|
||||
LastLedgerSequence: 65477334,
|
||||
OfferSequence: 60797528,
|
||||
Sequence: 60797535,
|
||||
SigningPubKey: "0361BFD43D1EEA54B77CC152887312949EBF052997FBFFCDAF6F2653164B55B21...",
|
||||
TransactionType: "OfferCancel",
|
||||
TxnSignature: "30450221008C43BDCFC68B4793857CA47DF454C07E5B45D3F80E8E6785CAB9292...",
|
||||
date: "2021-08-06T21:04:11Z"
|
||||
} as any
|
||||
})
|
||||
describe("OfferCancel Transaction Verification", function () {
|
||||
let offer;
|
||||
|
||||
it (`verifies valid OfferCancel`, () => {
|
||||
assert.doesNotThrow(() => verifyOfferCancel(offer))
|
||||
})
|
||||
beforeEach(function () {
|
||||
offer = {
|
||||
Account: "rnKiczmiQkZFiDES8THYyLA2pQohC5C6EF",
|
||||
Fee: "10",
|
||||
LastLedgerSequence: 65477334,
|
||||
OfferSequence: 60797528,
|
||||
Sequence: 60797535,
|
||||
SigningPubKey:
|
||||
"0361BFD43D1EEA54B77CC152887312949EBF052997FBFFCDAF6F2653164B55B21...",
|
||||
TransactionType: "OfferCancel",
|
||||
TxnSignature:
|
||||
"30450221008C43BDCFC68B4793857CA47DF454C07E5B45D3F80E8E6785CAB9292...",
|
||||
date: "2021-08-06T21:04:11Z",
|
||||
} as any;
|
||||
});
|
||||
|
||||
it (`verifies valid OfferCancel with flags`, () => {
|
||||
offer.Flags = 2147483648
|
||||
assert.doesNotThrow(() => verifyOfferCancel(offer))
|
||||
})
|
||||
it(`verifies valid OfferCancel`, function () {
|
||||
assert.doesNotThrow(() => verifyOfferCancel(offer));
|
||||
});
|
||||
|
||||
it (`throws w/ OfferSequence must be a number`, () => {
|
||||
offer.OfferSequence = '99'
|
||||
assert.throws(
|
||||
() => verifyOfferCancel(offer),
|
||||
ValidationError,
|
||||
"OfferCancel: OfferSequence must be a number"
|
||||
)
|
||||
})
|
||||
it(`verifies valid OfferCancel with flags`, function () {
|
||||
offer.Flags = 2147483648;
|
||||
assert.doesNotThrow(() => verifyOfferCancel(offer));
|
||||
});
|
||||
|
||||
it (`throws w/ missing OfferSequence`, () => {
|
||||
delete offer.OfferSequence
|
||||
assert.throws(
|
||||
() => verifyOfferCancel(offer),
|
||||
ValidationError,
|
||||
"OfferCancel: missing field OfferSequence"
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`throws w/ OfferSequence must be a number`, function () {
|
||||
offer.OfferSequence = "99";
|
||||
assert.throws(
|
||||
() => verifyOfferCancel(offer),
|
||||
ValidationError,
|
||||
"OfferCancel: OfferSequence must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it(`throws w/ missing OfferSequence`, function () {
|
||||
delete offer.OfferSequence;
|
||||
assert.throws(
|
||||
() => verifyOfferCancel(offer),
|
||||
ValidationError,
|
||||
"OfferCancel: missing field OfferSequence"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,177 +1,191 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyOfferCreate } from './../../src/models/transactions/offerCreate'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyOfferCreate } from "../../src/models/transactions/offerCreate";
|
||||
|
||||
/**
|
||||
* OfferCreate Transaction Verification Testing
|
||||
* OfferCreate Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('OfferCreate Transaction Verification', function () {
|
||||
it (`verifies valid OfferCreate`, () => {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
Expiration: 10,
|
||||
OfferSequence: 12,
|
||||
TakerGets: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TakerPays: "12928290425",
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer))
|
||||
describe("OfferCreate Transaction Verification", function () {
|
||||
it(`verifies valid OfferCreate`, function () {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
Expiration: 10,
|
||||
OfferSequence: 12,
|
||||
TakerGets: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TakerPays: "12928290425",
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
const offer2 = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer));
|
||||
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer2))
|
||||
const offer2 = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer2));
|
||||
|
||||
const offer3 = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
TakerGets: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
const offer3 = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
TakerGets: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer3))
|
||||
})
|
||||
assert.doesNotThrow(() => verifyOfferCreate(offer3));
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Expiration`, () => {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
Expiration: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
it(`throws w/ invalid Expiration`, function () {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
Expiration: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid Expiration"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid Expiration"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid OfferSequence`, () => {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
it(`throws w/ invalid OfferSequence`, function () {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid OfferSequence"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid OfferSequence"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid TakerPays`, () => {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: 10,
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
it(`throws w/ invalid TakerPays`, function () {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: "12928290425",
|
||||
TakerPays: 10,
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid TakerPays"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid TakerPays"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid TakerGets`, () => {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey: "03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: 11,
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009"
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature: "3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any
|
||||
it(`throws w/ invalid TakerGets`, function () {
|
||||
const offer = {
|
||||
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",
|
||||
Fee: "10",
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 65453019,
|
||||
Sequence: 40949322,
|
||||
SigningPubKey:
|
||||
"03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22",
|
||||
OfferSequence: "11",
|
||||
TakerGets: 11,
|
||||
TakerPays: {
|
||||
currency: "DSH",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "43.11584856965009",
|
||||
},
|
||||
TransactionType: "OfferCreate",
|
||||
TxnSignature:
|
||||
"3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91",
|
||||
} as any;
|
||||
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid TakerGets"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyOfferCreate(offer),
|
||||
ValidationError,
|
||||
"OfferCreate: invalid TakerGets"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,98 +1,102 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyPaymentChannelClaim } from './../../src/models/transactions/paymentChannelClaim'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyPaymentChannelClaim } from "../../src/models/transactions/paymentChannelClaim";
|
||||
|
||||
/**
|
||||
* PaymentChannelClaim Transaction Verification Testing
|
||||
* PaymentChannelClaim Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('PaymentChannelClaim Transaction Verification', function () {
|
||||
let channel
|
||||
describe("PaymentChannelClaim Transaction Verification", function () {
|
||||
let channel;
|
||||
|
||||
beforeEach(() => {
|
||||
channel = {
|
||||
"Account": "r...",
|
||||
"TransactionType": "PaymentChannelClaim",
|
||||
"Channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
"Balance": "1000000",
|
||||
"Amount": "1000000",
|
||||
"Signature": "30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B",
|
||||
"PublicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A"
|
||||
}
|
||||
})
|
||||
beforeEach(function () {
|
||||
channel = {
|
||||
Account: "r...",
|
||||
TransactionType: "PaymentChannelClaim",
|
||||
Channel:
|
||||
"C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
Balance: "1000000",
|
||||
Amount: "1000000",
|
||||
Signature:
|
||||
"30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B",
|
||||
PublicKey:
|
||||
"32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A",
|
||||
};
|
||||
});
|
||||
|
||||
it (`verifies valid PaymentChannelClaim`, () => {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelClaim(channel))
|
||||
})
|
||||
it(`verifies valid PaymentChannelClaim`, function () {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelClaim(channel));
|
||||
});
|
||||
|
||||
it (`verifies valid PaymentChannelClaim w/o optional`, () => {
|
||||
delete channel.Balance
|
||||
delete channel.Amount
|
||||
delete channel.Signature
|
||||
delete channel.PublicKey
|
||||
|
||||
assert.doesNotThrow(() => verifyPaymentChannelClaim(channel))
|
||||
})
|
||||
it(`verifies valid PaymentChannelClaim w/o optional`, function () {
|
||||
delete channel.Balance;
|
||||
delete channel.Amount;
|
||||
delete channel.Signature;
|
||||
delete channel.PublicKey;
|
||||
|
||||
it (`throws w/ missing Channel`, () => {
|
||||
delete channel.Channel
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: missing Channel"
|
||||
)
|
||||
})
|
||||
assert.doesNotThrow(() => verifyPaymentChannelClaim(channel));
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Channel`, () => {
|
||||
channel.Channel = 100
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Channel must be a string"
|
||||
)
|
||||
})
|
||||
it(`throws w/ missing Channel`, function () {
|
||||
delete channel.Channel;
|
||||
|
||||
it (`throws w/ invalid Balance`, () => {
|
||||
channel.Balance = 100
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Balance must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: missing Channel"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Amount`, () => {
|
||||
channel.Amount = 1000
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Amount must be a string"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid Channel`, function () {
|
||||
channel.Channel = 100;
|
||||
|
||||
it (`throws w/ invalid Signature`, () => {
|
||||
channel.Signature = 1000
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Signature must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Channel must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid PublicKey`, () => {
|
||||
channel.PublicKey = ["100000"]
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: PublicKey must be a string"
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`throws w/ invalid Balance`, function () {
|
||||
channel.Balance = 100;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Balance must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`throws w/ invalid Amount`, function () {
|
||||
channel.Amount = 1000;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Amount must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`throws w/ invalid Signature`, function () {
|
||||
channel.Signature = 1000;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: Signature must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`throws w/ invalid PublicKey`, function () {
|
||||
channel.PublicKey = ["100000"];
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelClaim(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelClaim: PublicKey must be a string"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,140 +1,141 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyPaymentChannelCreate } from './../../src/models/transactions/paymentChannelCreate'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyPaymentChannelCreate } from "../../src/models/transactions/paymentChannelCreate";
|
||||
|
||||
/**
|
||||
* PaymentChannelCreate Transaction Verification Testing
|
||||
* PaymentChannelCreate Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('PaymentChannelCreate Transaction Verification', function () {
|
||||
let channel
|
||||
describe("PaymentChannelCreate Transaction Verification", function () {
|
||||
let channel;
|
||||
|
||||
beforeEach(() => {
|
||||
channel = {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"TransactionType": "PaymentChannelCreate",
|
||||
"Amount": "10000",
|
||||
"Destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
"SettleDelay": 86400,
|
||||
"PublicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A",
|
||||
"CancelAfter": 533171558,
|
||||
"DestinationTag": 23480,
|
||||
"SourceTag": 11747
|
||||
}
|
||||
})
|
||||
|
||||
it (`verifies valid PaymentChannelCreate`, () => {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelCreate(channel))
|
||||
})
|
||||
beforeEach(function () {
|
||||
channel = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "PaymentChannelCreate",
|
||||
Amount: "10000",
|
||||
Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
SettleDelay: 86400,
|
||||
PublicKey:
|
||||
"32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A",
|
||||
CancelAfter: 533171558,
|
||||
DestinationTag: 23480,
|
||||
SourceTag: 11747,
|
||||
};
|
||||
});
|
||||
|
||||
it (`verifies valid PaymentChannelCreate w/o optional`, () => {
|
||||
delete channel.CancelAfter
|
||||
delete channel.DestinationTag
|
||||
delete channel.SourceTag
|
||||
it(`verifies valid PaymentChannelCreate`, function () {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelCreate(channel));
|
||||
});
|
||||
|
||||
assert.doesNotThrow(() => verifyPaymentChannelCreate(channel))
|
||||
})
|
||||
it(`verifies valid PaymentChannelCreate w/o optional`, function () {
|
||||
delete channel.CancelAfter;
|
||||
delete channel.DestinationTag;
|
||||
delete channel.SourceTag;
|
||||
|
||||
it (`missing Amount`, () => {
|
||||
delete channel.Amount
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing Amount"
|
||||
)
|
||||
})
|
||||
assert.doesNotThrow(() => verifyPaymentChannelCreate(channel));
|
||||
});
|
||||
|
||||
it(`missing Amount`, function () {
|
||||
delete channel.Amount;
|
||||
|
||||
it (`missing Destination`, () => {
|
||||
delete channel.Destination
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing Destination"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing Amount"
|
||||
);
|
||||
});
|
||||
|
||||
it (`missing SettleDelay`, () => {
|
||||
delete channel.SettleDelay
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing SettleDelay"
|
||||
)
|
||||
})
|
||||
it(`missing Destination`, function () {
|
||||
delete channel.Destination;
|
||||
|
||||
it (`missing PublicKey`, () => {
|
||||
delete channel.PublicKey
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing PublicKey"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`invalid Amount`, () => {
|
||||
channel.Amount = 1000
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: Amount must be a string"
|
||||
)
|
||||
})
|
||||
it(`missing SettleDelay`, function () {
|
||||
delete channel.SettleDelay;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing SettleDelay"
|
||||
);
|
||||
});
|
||||
|
||||
it (`invalid Destination`, () => {
|
||||
channel.Destination = 10;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: Destination must be a string"
|
||||
)
|
||||
})
|
||||
it(`missing PublicKey`, function () {
|
||||
delete channel.PublicKey;
|
||||
|
||||
it (`invalid SettleDelay`, () => {
|
||||
channel.SettleDelay = "10"
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: SettleDelay must be a number"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: missing PublicKey"
|
||||
);
|
||||
});
|
||||
|
||||
it (`invalid PublicKey`, () => {
|
||||
channel.PublicKey = 10
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: PublicKey must be a string"
|
||||
)
|
||||
})
|
||||
it(`invalid Amount`, function () {
|
||||
channel.Amount = 1000;
|
||||
|
||||
it (`invalid DestinationTag`, () => {
|
||||
channel.DestinationTag = "10"
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: Amount must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: DestinationTag must be a number"
|
||||
)
|
||||
})
|
||||
it(`invalid Destination`, function () {
|
||||
channel.Destination = 10;
|
||||
|
||||
it (`invalid CancelAfter`, () => {
|
||||
channel.CancelAfter = "100"
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: CancelAfter must be a number"
|
||||
)
|
||||
})
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: Destination must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid SettleDelay`, function () {
|
||||
channel.SettleDelay = "10";
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: SettleDelay must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid PublicKey`, function () {
|
||||
channel.PublicKey = 10;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: PublicKey must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid DestinationTag`, function () {
|
||||
channel.DestinationTag = "10";
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: DestinationTag must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it(`invalid CancelAfter`, function () {
|
||||
channel.CancelAfter = "100";
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelCreate(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelCreate: CancelAfter must be a number"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,83 +1,85 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyPaymentChannelFund } from './../../src/models/transactions/paymentChannelFund'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyPaymentChannelFund } from "../../src/models/transactions/paymentChannelFund";
|
||||
|
||||
/**
|
||||
* PaymentChannelFund Transaction Verification Testing
|
||||
* PaymentChannelFund Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('PaymentChannelFund Transaction Verification', function () {
|
||||
let channel
|
||||
describe("PaymentChannelFund Transaction Verification", function () {
|
||||
let channel;
|
||||
|
||||
beforeEach(() => {
|
||||
channel = {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"TransactionType": "PaymentChannelFund",
|
||||
"Channel": "C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
"Amount": "200000",
|
||||
"Expiration": 543171558
|
||||
}
|
||||
})
|
||||
|
||||
it (`verifies valid PaymentChannelFund`, () => {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelFund(channel))
|
||||
})
|
||||
beforeEach(function () {
|
||||
channel = {
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
TransactionType: "PaymentChannelFund",
|
||||
Channel:
|
||||
"C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198",
|
||||
Amount: "200000",
|
||||
Expiration: 543171558,
|
||||
};
|
||||
});
|
||||
|
||||
it (`verifies valid PaymentChannelFund w/o optional`, () => {
|
||||
delete channel.Expiration
|
||||
|
||||
assert.doesNotThrow(() => verifyPaymentChannelFund(channel))
|
||||
})
|
||||
it(`verifies valid PaymentChannelFund`, function () {
|
||||
assert.doesNotThrow(() => verifyPaymentChannelFund(channel));
|
||||
});
|
||||
|
||||
it (`throws w/ missing Amount`, () => {
|
||||
delete channel.Amount
|
||||
it(`verifies valid PaymentChannelFund w/o optional`, function () {
|
||||
delete channel.Expiration;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: missing Amount"
|
||||
)
|
||||
})
|
||||
assert.doesNotThrow(() => verifyPaymentChannelFund(channel));
|
||||
});
|
||||
|
||||
it (`throws w/ missing Channel`, () => {
|
||||
delete channel.Channel
|
||||
it(`throws w/ missing Amount`, function () {
|
||||
delete channel.Amount;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: missing Channel"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: missing Amount"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Amount`, () => {
|
||||
channel.Amount = 100
|
||||
it(`throws w/ missing Channel`, function () {
|
||||
delete channel.Channel;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Amount must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: missing Channel"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Channel`, () => {
|
||||
channel.Channel = 1000
|
||||
it(`throws w/ invalid Amount`, function () {
|
||||
channel.Amount = 100;
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Channel must be a string"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Amount must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid Expiration`, () => {
|
||||
channel.Expiration = "1000"
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Expiration must be a number"
|
||||
)
|
||||
})
|
||||
it(`throws w/ invalid Channel`, function () {
|
||||
channel.Channel = 1000;
|
||||
|
||||
})
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Channel must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it(`throws w/ invalid Expiration`, function () {
|
||||
channel.Expiration = "1000";
|
||||
|
||||
assert.throws(
|
||||
() => verifyPaymentChannelFund(channel),
|
||||
ValidationError,
|
||||
"PaymentChannelFund: Expiration must be a number"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,132 +1,140 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { PaymentTransactionFlagsEnum, verifyPaymentTransaction } from './../../src/models/transactions/paymentTransaction'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import {
|
||||
PaymentTransactionFlagsEnum,
|
||||
verifyPaymentTransaction,
|
||||
} from "../../src/models/transactions/paymentTransaction";
|
||||
|
||||
/**
|
||||
* PaymentTransaction Verification Testing
|
||||
* PaymentTransaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('Payment Transaction Verification', () => {
|
||||
let paymentTransaction
|
||||
describe("Payment Transaction Verification", function () {
|
||||
let paymentTransaction;
|
||||
|
||||
beforeEach(() => {
|
||||
paymentTransaction = {
|
||||
TransactionType: 'Payment',
|
||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||
Amount: '1234',
|
||||
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
|
||||
DestinationTag: 1,
|
||||
InvoiceID: '6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
|
||||
Paths: [[{ account: 'aw0efji', currency: 'XRP', issuer: 'apsoeijf90wp34fh'}]],
|
||||
SendMax: '100000000',
|
||||
} as any
|
||||
})
|
||||
beforeEach(function () {
|
||||
paymentTransaction = {
|
||||
TransactionType: "Payment",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
Amount: "1234",
|
||||
Destination: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
||||
DestinationTag: 1,
|
||||
InvoiceID:
|
||||
"6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
||||
Paths: [
|
||||
[{ account: "aw0efji", currency: "XRP", issuer: "apsoeijf90wp34fh" }],
|
||||
],
|
||||
SendMax: "100000000",
|
||||
} as any;
|
||||
});
|
||||
|
||||
it (`verifies valid PaymentTransaction`, () => {
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction))
|
||||
})
|
||||
it(`verifies valid PaymentTransaction`, function () {
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction));
|
||||
});
|
||||
|
||||
it (`throws when Amount is missing`, () => {
|
||||
delete paymentTransaction.Amount
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: missing field Amount'
|
||||
)
|
||||
})
|
||||
it(`throws when Amount is missing`, function () {
|
||||
delete paymentTransaction.Amount;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: missing field Amount"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when Amount is invalid`, () => {
|
||||
paymentTransaction.Amount = 1234
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: invalid Amount'
|
||||
)
|
||||
})
|
||||
it(`throws when Amount is invalid`, function () {
|
||||
paymentTransaction.Amount = 1234;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: invalid Amount"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when Destination is missing`, () => {
|
||||
delete paymentTransaction.Destination
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: missing field Destination'
|
||||
)
|
||||
})
|
||||
it(`throws when Destination is missing`, function () {
|
||||
delete paymentTransaction.Destination;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: missing field Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when Destination is invalid`, () => {
|
||||
paymentTransaction.Destination = 7896214
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: invalid Destination'
|
||||
)
|
||||
})
|
||||
it(`throws when Destination is invalid`, function () {
|
||||
paymentTransaction.Destination = 7896214;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: invalid Destination"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when DestinationTag is not a number`, () => {
|
||||
paymentTransaction.DestinationTag = '1'
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: DestinationTag must be a number'
|
||||
)
|
||||
})
|
||||
it(`throws when DestinationTag is not a number`, function () {
|
||||
paymentTransaction.DestinationTag = "1";
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: DestinationTag must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when InvoiceID is not a string`, () => {
|
||||
paymentTransaction.InvoiceID = 19832
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: InvoiceID must be a string'
|
||||
)
|
||||
})
|
||||
it(`throws when InvoiceID is not a string`, function () {
|
||||
paymentTransaction.InvoiceID = 19832;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: InvoiceID must be a string"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when Paths is invalid`, () => {
|
||||
paymentTransaction.Paths = [[{ account: 123 }]]
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: invalid Paths'
|
||||
)
|
||||
})
|
||||
it(`throws when Paths is invalid`, function () {
|
||||
paymentTransaction.Paths = [[{ account: 123 }]];
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: invalid Paths"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when SendMax is invalid`, () => {
|
||||
paymentTransaction.SendMax = 100000000
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: invalid SendMax'
|
||||
)
|
||||
})
|
||||
it(`throws when SendMax is invalid`, function () {
|
||||
paymentTransaction.SendMax = 100000000;
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: invalid SendMax"
|
||||
);
|
||||
});
|
||||
|
||||
it (`verifies valid DeliverMin with tfPartialPayment flag set as a number`, () => {
|
||||
paymentTransaction.DeliverMin = '10000'
|
||||
paymentTransaction.Flags = PaymentTransactionFlagsEnum.tfPartialPayment,
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction))
|
||||
})
|
||||
it(`verifies valid DeliverMin with tfPartialPayment flag set as a number`, function () {
|
||||
paymentTransaction.DeliverMin = "10000";
|
||||
(paymentTransaction.Flags = PaymentTransactionFlagsEnum.tfPartialPayment),
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction));
|
||||
});
|
||||
|
||||
it (`verifies valid DeliverMin with tfPartialPayment flag set as a boolean`, () => {
|
||||
paymentTransaction.DeliverMin = '10000'
|
||||
paymentTransaction.Flags = { tfPartialPayment: true }
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction))
|
||||
})
|
||||
it(`verifies valid DeliverMin with tfPartialPayment flag set as a boolean`, function () {
|
||||
paymentTransaction.DeliverMin = "10000";
|
||||
paymentTransaction.Flags = { tfPartialPayment: true };
|
||||
assert.doesNotThrow(() => verifyPaymentTransaction(paymentTransaction));
|
||||
});
|
||||
|
||||
it (`throws when DeliverMin is invalid`, () => {
|
||||
paymentTransaction.DeliverMin = 10000
|
||||
paymentTransaction.Flags = { tfPartialPayment: true }
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: invalid DeliverMin'
|
||||
)
|
||||
})
|
||||
it(`throws when DeliverMin is invalid`, function () {
|
||||
paymentTransaction.DeliverMin = 10000;
|
||||
paymentTransaction.Flags = { tfPartialPayment: true };
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: invalid DeliverMin"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws when tfPartialPayment flag is missing with valid DeliverMin`, () => {
|
||||
paymentTransaction.DeliverMin = '10000'
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
'PaymentTransaction: tfPartialPayment flag required with DeliverMin'
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`throws when tfPartialPayment flag is missing with valid DeliverMin`, function () {
|
||||
paymentTransaction.DeliverMin = "10000";
|
||||
assert.throws(
|
||||
() => verifyPaymentTransaction(paymentTransaction),
|
||||
ValidationError,
|
||||
"PaymentTransaction: tfPartialPayment flag required with DeliverMin"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifySetRegularKey } from './../../src/models/transactions/setRegularKey'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifySetRegularKey } from "../../src/models/transactions/setRegularKey";
|
||||
|
||||
/**
|
||||
* SetRegularKey Transaction Verification Testing
|
||||
* SetRegularKey Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('SetRegularKey Transaction Verification', function () {
|
||||
let account
|
||||
describe("SetRegularKey Transaction Verification", function () {
|
||||
let account;
|
||||
|
||||
beforeEach(() => {
|
||||
account = {
|
||||
TransactionType : "SetRegularKey",
|
||||
Account : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee : "12",
|
||||
Flags : 0,
|
||||
RegularKey : "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD"
|
||||
} as any
|
||||
})
|
||||
beforeEach(function () {
|
||||
account = {
|
||||
TransactionType: "SetRegularKey",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee: "12",
|
||||
Flags: 0,
|
||||
RegularKey: "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD",
|
||||
} as any;
|
||||
});
|
||||
|
||||
it (`verifies valid SetRegularKey`, () => {
|
||||
assert.doesNotThrow(() => verifySetRegularKey(account))
|
||||
})
|
||||
it(`verifies valid SetRegularKey`, function () {
|
||||
assert.doesNotThrow(() => verifySetRegularKey(account));
|
||||
});
|
||||
|
||||
it (`verifies w/o SetRegularKey`, () => {
|
||||
account.RegularKey = undefined
|
||||
assert.doesNotThrow(() => verifySetRegularKey(account))
|
||||
})
|
||||
it(`verifies w/o SetRegularKey`, function () {
|
||||
account.RegularKey = undefined;
|
||||
assert.doesNotThrow(() => verifySetRegularKey(account));
|
||||
});
|
||||
|
||||
it (`throws w/ invalid RegularKey`, () => {
|
||||
account.RegularKey = 12369846963
|
||||
it(`throws w/ invalid RegularKey`, function () {
|
||||
account.RegularKey = 12369846963;
|
||||
|
||||
assert.throws(
|
||||
() => verifySetRegularKey(account),
|
||||
ValidationError,
|
||||
"SetRegularKey: RegularKey must be a string"
|
||||
)
|
||||
})
|
||||
|
||||
})
|
||||
assert.throws(
|
||||
() => verifySetRegularKey(account),
|
||||
ValidationError,
|
||||
"SetRegularKey: RegularKey must be a string"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,77 +1,78 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifySignerListSet } from './../../src/models/transactions/signerListSet'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifySignerListSet } from "../../src/models/transactions/signerListSet";
|
||||
|
||||
/**
|
||||
* SignerListSet Transaction Verification Testing
|
||||
* SignerListSet Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('SignerListSet Transaction Verification', function () {
|
||||
let SignerListSetTx
|
||||
describe("SignerListSet Transaction Verification", function () {
|
||||
let SignerListSetTx;
|
||||
|
||||
beforeEach(() => {
|
||||
SignerListSetTx = {
|
||||
Flags: 0,
|
||||
TransactionType: "SignerListSet",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee: "12",
|
||||
SignerQuorum: 3,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
SignerWeight: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
SignerWeight: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
|
||||
SignerWeight: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
} as any
|
||||
})
|
||||
|
||||
it (`verifies valid SignerListSet`, () => {
|
||||
assert.doesNotThrow(() => verifySignerListSet(SignerListSetTx))
|
||||
})
|
||||
beforeEach(function () {
|
||||
SignerListSetTx = {
|
||||
Flags: 0,
|
||||
TransactionType: "SignerListSet",
|
||||
Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
Fee: "12",
|
||||
SignerQuorum: 3,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
|
||||
SignerWeight: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
} as any;
|
||||
});
|
||||
|
||||
it(`verifies valid SignerListSet`, function () {
|
||||
assert.doesNotThrow(() => verifySignerListSet(SignerListSetTx));
|
||||
});
|
||||
|
||||
it (`throws w/ missing SignerQuorum`, () => {
|
||||
SignerListSetTx.SignerQuorum = undefined
|
||||
it(`throws w/ missing SignerQuorum`, function () {
|
||||
SignerListSetTx.SignerQuorum = undefined;
|
||||
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: missing field SignerQuorum"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: missing field SignerQuorum"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ empty SignerEntries`, () => {
|
||||
SignerListSetTx.SignerEntries = []
|
||||
it(`throws w/ empty SignerEntries`, function () {
|
||||
SignerListSetTx.SignerEntries = [];
|
||||
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: need atleast 1 member in SignerEntries"
|
||||
)
|
||||
})
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: need atleast 1 member in SignerEntries"
|
||||
);
|
||||
});
|
||||
|
||||
it (`throws w/ invalid SignerEntries`, () => {
|
||||
SignerListSetTx.SignerEntries = "khgfgyhujk"
|
||||
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: invalid SignerEntries"
|
||||
)
|
||||
})
|
||||
})
|
||||
it(`throws w/ invalid SignerEntries`, function () {
|
||||
SignerListSetTx.SignerEntries = "khgfgyhujk";
|
||||
|
||||
assert.throws(
|
||||
() => verifySignerListSet(SignerListSetTx),
|
||||
ValidationError,
|
||||
"SignerListSet: invalid SignerEntries"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,69 +1,71 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyTicketCreate } from './../../src/models/transactions/ticketCreate'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyTicketCreate } from "../../src/models/transactions/ticketCreate";
|
||||
|
||||
/**
|
||||
* TicketCreate Transaction Verification Testing
|
||||
* TicketCreate Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('TicketCreate Transaction Verification', () => {
|
||||
let ticketCreate
|
||||
describe("TicketCreate Transaction Verification", function () {
|
||||
let ticketCreate;
|
||||
|
||||
beforeEach(() => {
|
||||
ticketCreate = {
|
||||
TransactionType: 'TicketCreate',
|
||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||
TicketCount: 150,
|
||||
} as any
|
||||
})
|
||||
beforeEach(function () {
|
||||
ticketCreate = {
|
||||
TransactionType: "TicketCreate",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
TicketCount: 150,
|
||||
} as any;
|
||||
});
|
||||
|
||||
it ('verifies valid TicketCreate', () => {
|
||||
assert.doesNotThrow(() => verifyTicketCreate(ticketCreate))
|
||||
})
|
||||
it("verifies valid TicketCreate", function () {
|
||||
assert.doesNotThrow(() => verifyTicketCreate(ticketCreate));
|
||||
});
|
||||
|
||||
it ('throws when TicketCount is missing', () => {
|
||||
delete ticketCreate.TicketCount
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
'TicketCreate: missing field TicketCount'
|
||||
)
|
||||
})
|
||||
it("throws when TicketCount is missing", function () {
|
||||
delete ticketCreate.TicketCount;
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
"TicketCreate: missing field TicketCount"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when TicketCount is not a number', () => {
|
||||
ticketCreate.TicketCount = '150'
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
'TicketCreate: TicketCount must be a number'
|
||||
)
|
||||
})
|
||||
it("throws when TicketCount is not a number", function () {
|
||||
ticketCreate.TicketCount = "150";
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
"TicketCreate: TicketCount must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when TicketCount is not an integer', () => {
|
||||
ticketCreate.TicketCount = 12.5
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
'TicketCreate: TicketCount must be an integer from 1 to 250'
|
||||
)
|
||||
})
|
||||
it("throws when TicketCount is not an integer", function () {
|
||||
ticketCreate.TicketCount = 12.5;
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
"TicketCreate: TicketCount must be an integer from 1 to 250"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when TicketCount is < 1', () => {
|
||||
ticketCreate.TicketCount = 0
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
'TicketCreate: TicketCount must be an integer from 1 to 250'
|
||||
)
|
||||
})
|
||||
it("throws when TicketCount is < 1", function () {
|
||||
ticketCreate.TicketCount = 0;
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
"TicketCreate: TicketCount must be an integer from 1 to 250"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when TicketCount is > 250', () => {
|
||||
ticketCreate.TicketCount = 251
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
'TicketCreate: TicketCount must be an integer from 1 to 250'
|
||||
)
|
||||
})
|
||||
})
|
||||
it("throws when TicketCount is > 250", function () {
|
||||
ticketCreate.TicketCount = 251;
|
||||
assert.throws(
|
||||
() => verifyTicketCreate(ticketCreate),
|
||||
ValidationError,
|
||||
"TicketCreate: TicketCount must be an integer from 1 to 250"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,66 +1,68 @@
|
||||
import { ValidationError } from 'xrpl-local/common/errors'
|
||||
import { verifyTrustSet } from './../../src/models/transactions/trustSet'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { ValidationError } from "xrpl-local/common/errors";
|
||||
|
||||
import { verifyTrustSet } from "../../src/models/transactions/trustSet";
|
||||
|
||||
/**
|
||||
* TrustSet Transaction Verification Testing
|
||||
* TrustSet Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('TrustSet Transaction Verification', () => {
|
||||
let trustSet
|
||||
describe("TrustSet Transaction Verification", function () {
|
||||
let trustSet;
|
||||
|
||||
beforeEach(() => {
|
||||
trustSet = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||
LimitAmount: {
|
||||
currency: 'XRP',
|
||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
||||
value: '4329.23'
|
||||
},
|
||||
QualityIn: 1234,
|
||||
QualityOut: 4321,
|
||||
} as any
|
||||
})
|
||||
beforeEach(function () {
|
||||
trustSet = {
|
||||
TransactionType: "TrustSet",
|
||||
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
||||
LimitAmount: {
|
||||
currency: "XRP",
|
||||
issuer: "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
||||
value: "4329.23",
|
||||
},
|
||||
QualityIn: 1234,
|
||||
QualityOut: 4321,
|
||||
} as any;
|
||||
});
|
||||
|
||||
it ('verifies valid TrustSet', () => {
|
||||
assert.doesNotThrow(() => verifyTrustSet(trustSet))
|
||||
})
|
||||
it("verifies valid TrustSet", function () {
|
||||
assert.doesNotThrow(() => verifyTrustSet(trustSet));
|
||||
});
|
||||
|
||||
it ('throws when LimitAmount is missing', () => {
|
||||
delete trustSet.LimitAmount
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
'TrustSet: missing field LimitAmount'
|
||||
)
|
||||
})
|
||||
it("throws when LimitAmount is missing", function () {
|
||||
delete trustSet.LimitAmount;
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
"TrustSet: missing field LimitAmount"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when LimitAmount is invalid', () => {
|
||||
trustSet.LimitAmount = 1234
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
'TrustSet: invalid LimitAmount'
|
||||
)
|
||||
})
|
||||
it("throws when LimitAmount is invalid", function () {
|
||||
trustSet.LimitAmount = 1234;
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
"TrustSet: invalid LimitAmount"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when QualityIn is not a number', () => {
|
||||
trustSet.QualityIn = '1234'
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
'TrustSet: QualityIn must be a number'
|
||||
)
|
||||
})
|
||||
it("throws when QualityIn is not a number", function () {
|
||||
trustSet.QualityIn = "1234";
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
"TrustSet: QualityIn must be a number"
|
||||
);
|
||||
});
|
||||
|
||||
it ('throws when QualityOut is not a number', () => {
|
||||
trustSet.QualityOut = '4321'
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
'TrustSet: QualityOut must be a number'
|
||||
)
|
||||
})
|
||||
})
|
||||
it("throws when QualityOut is not a number", function () {
|
||||
trustSet.QualityOut = "4321";
|
||||
assert.throws(
|
||||
() => verifyTrustSet(trustSet),
|
||||
ValidationError,
|
||||
"TrustSet: QualityOut must be a number"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import { isFlagEnabled } from '../../src/models/utils'
|
||||
import { assert } from 'chai'
|
||||
import { assert } from "chai";
|
||||
|
||||
import { isFlagEnabled } from "../../src/models/utils";
|
||||
|
||||
/**
|
||||
* Utils Testing
|
||||
* Utils Testing.
|
||||
*
|
||||
* Provides tests for utils used in models
|
||||
* Provides tests for utils used in models.
|
||||
*/
|
||||
describe('Models Utils', () => {
|
||||
describe('isFlagEnabled', () => {
|
||||
let flags
|
||||
const flag1 = 0x00010000
|
||||
const flag2 = 0x00020000
|
||||
describe("Models Utils", function () {
|
||||
describe("isFlagEnabled", function () {
|
||||
let flags;
|
||||
const flag1 = 0x00010000;
|
||||
const flag2 = 0x00020000;
|
||||
|
||||
beforeEach(() => {
|
||||
flags = 0x00000000
|
||||
})
|
||||
beforeEach(function () {
|
||||
flags = 0x00000000;
|
||||
});
|
||||
|
||||
it('verifies a flag is enabled', () => {
|
||||
flags += flag1 + flag2
|
||||
assert.isTrue(isFlagEnabled(flags, flag1))
|
||||
})
|
||||
it("verifies a flag is enabled", function () {
|
||||
flags += flag1 + flag2;
|
||||
assert.isTrue(isFlagEnabled(flags, flag1));
|
||||
});
|
||||
|
||||
it('verifies a flag is not enabled', () => {
|
||||
flags += flag2
|
||||
assert.isFalse(isFlagEnabled(flags, flag1))
|
||||
})
|
||||
})
|
||||
})
|
||||
it("verifies a flag is not enabled", function () {
|
||||
flags += flag2;
|
||||
assert.isFalse(isFlagEnabled(flags, flag1));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
131
test/rangeset.ts
131
test/rangeset.ts
@@ -1,79 +1,80 @@
|
||||
import assert from 'assert'
|
||||
import RangeSet from 'xrpl-local/client/rangeSet'
|
||||
import assert from "assert";
|
||||
|
||||
describe('RangeSet', function () {
|
||||
it('addRange()/addValue()', function () {
|
||||
const r = new RangeSet()
|
||||
import RangeSet from "xrpl-local/client/rangeSet";
|
||||
|
||||
r.addRange(4, 5)
|
||||
r.addRange(7, 10)
|
||||
r.addRange(1, 2)
|
||||
r.addValue(3)
|
||||
describe("RangeSet", function () {
|
||||
it("addRange()/addValue()", function () {
|
||||
const r = new RangeSet();
|
||||
|
||||
assert.deepEqual(r.serialize(), '1-5,7-10')
|
||||
})
|
||||
r.addRange(4, 5);
|
||||
r.addRange(7, 10);
|
||||
r.addRange(1, 2);
|
||||
r.addValue(3);
|
||||
|
||||
it('addValue()/addRange() -- malformed', function () {
|
||||
const r = new RangeSet()
|
||||
assert.deepEqual(r.serialize(), "1-5,7-10");
|
||||
});
|
||||
|
||||
it("addValue()/addRange() -- malformed", function () {
|
||||
const r = new RangeSet();
|
||||
assert.throws(function () {
|
||||
r.addRange(2, 1)
|
||||
})
|
||||
})
|
||||
r.addRange(2, 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('parseAndAddRanges()', function () {
|
||||
const r = new RangeSet()
|
||||
r.parseAndAddRanges('4-5,7-10,1-2,3-3')
|
||||
assert.deepEqual(r.serialize(), '1-5,7-10')
|
||||
})
|
||||
it('parseAndAddRanges() -- single ledger', function () {
|
||||
const r = new RangeSet()
|
||||
it("parseAndAddRanges()", function () {
|
||||
const r = new RangeSet();
|
||||
r.parseAndAddRanges("4-5,7-10,1-2,3-3");
|
||||
assert.deepEqual(r.serialize(), "1-5,7-10");
|
||||
});
|
||||
it("parseAndAddRanges() -- single ledger", function () {
|
||||
const r = new RangeSet();
|
||||
|
||||
r.parseAndAddRanges('3')
|
||||
assert.strictEqual(r.serialize(), '3-3')
|
||||
assert(r.containsValue(3))
|
||||
assert(!r.containsValue(0))
|
||||
assert(!r.containsValue(2))
|
||||
assert(!r.containsValue(4))
|
||||
assert(r.containsRange(3, 3))
|
||||
assert(!r.containsRange(2, 3))
|
||||
assert(!r.containsRange(3, 4))
|
||||
r.parseAndAddRanges("3");
|
||||
assert.strictEqual(r.serialize(), "3-3");
|
||||
assert(r.containsValue(3));
|
||||
assert(!r.containsValue(0));
|
||||
assert(!r.containsValue(2));
|
||||
assert(!r.containsValue(4));
|
||||
assert(r.containsRange(3, 3));
|
||||
assert(!r.containsRange(2, 3));
|
||||
assert(!r.containsRange(3, 4));
|
||||
|
||||
r.parseAndAddRanges('1-5')
|
||||
assert.strictEqual(r.serialize(), '1-5')
|
||||
assert(r.containsValue(3))
|
||||
assert(r.containsValue(1))
|
||||
assert(r.containsValue(5))
|
||||
assert(!r.containsValue(6))
|
||||
assert(!r.containsValue(0))
|
||||
assert(r.containsRange(1, 5))
|
||||
assert(r.containsRange(2, 4))
|
||||
assert(!r.containsRange(1, 6))
|
||||
assert(!r.containsRange(0, 3))
|
||||
})
|
||||
r.parseAndAddRanges("1-5");
|
||||
assert.strictEqual(r.serialize(), "1-5");
|
||||
assert(r.containsValue(3));
|
||||
assert(r.containsValue(1));
|
||||
assert(r.containsValue(5));
|
||||
assert(!r.containsValue(6));
|
||||
assert(!r.containsValue(0));
|
||||
assert(r.containsRange(1, 5));
|
||||
assert(r.containsRange(2, 4));
|
||||
assert(!r.containsRange(1, 6));
|
||||
assert(!r.containsRange(0, 3));
|
||||
});
|
||||
|
||||
it('containsValue()', function () {
|
||||
const r = new RangeSet()
|
||||
it("containsValue()", function () {
|
||||
const r = new RangeSet();
|
||||
|
||||
r.addRange(32570, 11005146)
|
||||
r.addValue(11005147)
|
||||
r.addRange(32570, 11005146);
|
||||
r.addValue(11005147);
|
||||
|
||||
assert.strictEqual(r.containsValue(1), false)
|
||||
assert.strictEqual(r.containsValue(32569), false)
|
||||
assert.strictEqual(r.containsValue(32570), true)
|
||||
assert.strictEqual(r.containsValue(50000), true)
|
||||
assert.strictEqual(r.containsValue(11005146), true)
|
||||
assert.strictEqual(r.containsValue(11005147), true)
|
||||
assert.strictEqual(r.containsValue(11005148), false)
|
||||
assert.strictEqual(r.containsValue(12000000), false)
|
||||
})
|
||||
assert.strictEqual(r.containsValue(1), false);
|
||||
assert.strictEqual(r.containsValue(32569), false);
|
||||
assert.strictEqual(r.containsValue(32570), true);
|
||||
assert.strictEqual(r.containsValue(50000), true);
|
||||
assert.strictEqual(r.containsValue(11005146), true);
|
||||
assert.strictEqual(r.containsValue(11005147), true);
|
||||
assert.strictEqual(r.containsValue(11005148), false);
|
||||
assert.strictEqual(r.containsValue(12000000), false);
|
||||
});
|
||||
|
||||
it('reset()', function () {
|
||||
const r = new RangeSet()
|
||||
it("reset()", function () {
|
||||
const r = new RangeSet();
|
||||
|
||||
r.addRange(4, 5)
|
||||
r.addRange(7, 10)
|
||||
r.reset()
|
||||
r.addRange(4, 5);
|
||||
r.addRange(7, 10);
|
||||
r.reset();
|
||||
|
||||
assert.deepEqual(r.serialize(), '')
|
||||
})
|
||||
})
|
||||
assert.deepEqual(r.serialize(), "");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import setupClient from './setupClient'
|
||||
import {Client} from 'xrpl-local'
|
||||
import addresses from './fixtures/addresses.json'
|
||||
import {getAllPublicMethods, loadTestSuites} from './testUtils'
|
||||
import { Client } from "xrpl-local";
|
||||
|
||||
import addresses from "./fixtures/addresses.json";
|
||||
import setupClient from "./setupClient";
|
||||
import { getAllPublicMethods, loadTestSuites } from "./testUtils";
|
||||
|
||||
/**
|
||||
* Client Test Runner
|
||||
* 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
|
||||
@@ -21,62 +22,62 @@ import {getAllPublicMethods, loadTestSuites} from './testUtils'
|
||||
* - 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)
|
||||
describe("Client [Test Runner]", function () {
|
||||
beforeEach(setupClient.setup);
|
||||
afterEach(setupClient.teardown);
|
||||
|
||||
// Collect all the tests:
|
||||
const allPublicMethods = getAllPublicMethods(new Client("wss://"))
|
||||
const allPublicMethods = getAllPublicMethods(new Client("wss://"));
|
||||
// doesn't need the client, just needs to instantiate to get public methods
|
||||
|
||||
const allTestSuites = loadTestSuites()
|
||||
const allTestSuites = loadTestSuites();
|
||||
|
||||
// Run all the tests:
|
||||
for (const {name: methodName, tests, config} of allTestSuites) {
|
||||
describe(`${methodName}`, () => {
|
||||
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)
|
||||
})
|
||||
return fn(this.client, addresses.ACCOUNT, this.mockRippled);
|
||||
});
|
||||
}
|
||||
}
|
||||
// Run each test with a classic address.
|
||||
describe(`[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)
|
||||
})
|
||||
return fn(this.client, addresses.ACCOUNT, this.mockRippled);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
// Run each test with an X-address.
|
||||
if (!config.skipXAddress) {
|
||||
describe(`[X-address]`, () => {
|
||||
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)
|
||||
})
|
||||
return fn(this.client, addresses.ACCOUNT_X, this.mockRippled);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Report any missing tests.
|
||||
const allTestedMethods = new Set(allTestSuites.map((s) => s.name))
|
||||
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`, () => {
|
||||
it.skip(`${methodName} - no test suite found`, function () {
|
||||
throw new Error(
|
||||
`Test file not found! Create file "test/client/${methodName}/index.ts".`
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,181 +1,181 @@
|
||||
import assert from 'assert-diff'
|
||||
import _ from 'lodash'
|
||||
import {Client} from 'xrpl-local'
|
||||
import {RecursiveData} from 'xrpl-local/ledger/utils'
|
||||
import {assertRejects} from './testUtils'
|
||||
import addresses from './fixtures/addresses.json'
|
||||
import setupClient from './setupClient'
|
||||
import {toRippledAmount} from '../src'
|
||||
import * as schemaValidator from 'xrpl-local/common/schema-validator'
|
||||
import {validate} from 'xrpl-local/common'
|
||||
import assert from "assert-diff";
|
||||
import _ from "lodash";
|
||||
|
||||
import { Client } from "xrpl-local";
|
||||
import { validate } from "xrpl-local/common";
|
||||
import * as schemaValidator from "xrpl-local/common/schema-validator";
|
||||
import {
|
||||
RecursiveData,
|
||||
renameCounterpartyToIssuerInOrder,
|
||||
compareTransactions,
|
||||
getRecursive
|
||||
} from 'xrpl-local/ledger/utils'
|
||||
getRecursive,
|
||||
} from "xrpl-local/ledger/utils";
|
||||
|
||||
const address = addresses.ACCOUNT
|
||||
assert.options.strict = true
|
||||
import { toRippledAmount } from "../src";
|
||||
|
||||
import addresses from "./fixtures/addresses.json";
|
||||
import setupClient from "./setupClient";
|
||||
import { assertRejects } from "./testUtils";
|
||||
|
||||
const address = addresses.ACCOUNT;
|
||||
assert.options.strict = true;
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
const TIMEOUT = 20000;
|
||||
|
||||
describe('Client', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
beforeEach(setupClient.setup)
|
||||
afterEach(setupClient.teardown)
|
||||
describe("Client", function () {
|
||||
this.timeout(TIMEOUT);
|
||||
beforeEach(setupClient.setup);
|
||||
afterEach(setupClient.teardown);
|
||||
|
||||
it('Client - implicit server port', function () {
|
||||
new Client('wss://s1.ripple.com')
|
||||
})
|
||||
it("Client - implicit server port", function () {
|
||||
new Client("wss://s1.ripple.com");
|
||||
});
|
||||
|
||||
it('Client invalid options', function () {
|
||||
// @ts-ignore - This is intentionally invalid
|
||||
assert.throws(() => new Client({invalid: true}))
|
||||
})
|
||||
it("Client invalid options", function () {
|
||||
// @ts-expect-error - This is intentionally invalid
|
||||
assert.throws(() => new Client({ invalid: true }));
|
||||
});
|
||||
|
||||
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')
|
||||
})
|
||||
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");
|
||||
});
|
||||
|
||||
it('Client invalid server uri', function () {
|
||||
assert.throws(() => new Client('wss//s:1'))
|
||||
})
|
||||
it("Client invalid server uri", function () {
|
||||
assert.throws(() => new Client("wss//s:1"));
|
||||
});
|
||||
|
||||
it('Client connect() times out after 2 seconds', function () {
|
||||
it("Client connect() times out after 2 seconds", function () {
|
||||
// TODO: Use a timer mock like https://jestjs.io/docs/en/timer-mocks
|
||||
// to test that connect() times out after 2 seconds.
|
||||
})
|
||||
});
|
||||
|
||||
describe('[private] schema-validator', function () {
|
||||
it('valid', function () {
|
||||
describe("[private] schema-validator", function () {
|
||||
it("valid", function () {
|
||||
assert.doesNotThrow(function () {
|
||||
schemaValidator.schemaValidate(
|
||||
'hash256',
|
||||
'0F7ED9F40742D8A513AE86029462B7A6768325583DF8EE21B7EC663019DD6A0F'
|
||||
)
|
||||
})
|
||||
})
|
||||
"hash256",
|
||||
"0F7ED9F40742D8A513AE86029462B7A6768325583DF8EE21B7EC663019DD6A0F"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('invalid', function () {
|
||||
it("invalid", function () {
|
||||
assert.throws(function () {
|
||||
schemaValidator.schemaValidate('hash256', 'invalid')
|
||||
}, this.client.errors.ValidationError)
|
||||
})
|
||||
schemaValidator.schemaValidate("hash256", "invalid");
|
||||
}, this.client.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('invalid - empty value', function () {
|
||||
it("invalid - empty value", function () {
|
||||
assert.throws(function () {
|
||||
schemaValidator.schemaValidate('hash256', '')
|
||||
}, this.client.errors.ValidationError)
|
||||
})
|
||||
schemaValidator.schemaValidate("hash256", "");
|
||||
}, this.client.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('schema not found error', function () {
|
||||
it("schema not found error", function () {
|
||||
assert.throws(function () {
|
||||
schemaValidator.schemaValidate('unexisting', 'anything')
|
||||
}, /no schema/)
|
||||
})
|
||||
})
|
||||
schemaValidator.schemaValidate("unexisting", "anything");
|
||||
}, /no schema/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[private] validator', function () {
|
||||
it('validateLedgerRange', function () {
|
||||
describe("[private] validator", function () {
|
||||
it("validateLedgerRange", function () {
|
||||
const options = {
|
||||
minLedgerVersion: 20000,
|
||||
maxLedgerVersion: 10000
|
||||
}
|
||||
const thunk = _.partial(validate.getTransactions, {address, options})
|
||||
assert.throws(thunk, this.client.errors.ValidationError)
|
||||
maxLedgerVersion: 10000,
|
||||
};
|
||||
const thunk = _.partial(validate.getTransactions, { address, options });
|
||||
assert.throws(thunk, this.client.errors.ValidationError);
|
||||
assert.throws(
|
||||
thunk,
|
||||
/minLedgerVersion must not be greater than maxLedgerVersion/
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('secret', function () {
|
||||
it("secret", function () {
|
||||
function validateSecret(secret) {
|
||||
validate.sign({txJSON: '', secret})
|
||||
validate.sign({ txJSON: "", secret });
|
||||
}
|
||||
assert.doesNotThrow(
|
||||
_.partial(validateSecret, 'shzjfakiK79YQdMjy4h8cGGfQSV6u')
|
||||
)
|
||||
_.partial(validateSecret, "shzjfakiK79YQdMjy4h8cGGfQSV6u")
|
||||
);
|
||||
assert.throws(
|
||||
_.partial(validateSecret, 'shzjfakiK79YQdMjy4h8cGGfQSV6v'),
|
||||
_.partial(validateSecret, "shzjfakiK79YQdMjy4h8cGGfQSV6v"),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
assert.throws(
|
||||
_.partial(validateSecret, 1),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
assert.throws(
|
||||
_.partial(validateSecret, ''),
|
||||
_.partial(validateSecret, ""),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
assert.throws(
|
||||
_.partial(validateSecret, 's!!!'),
|
||||
_.partial(validateSecret, "s!!!"),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
assert.throws(
|
||||
_.partial(validateSecret, 'passphrase'),
|
||||
_.partial(validateSecret, "passphrase"),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
);
|
||||
// 32 0s is a valid hex repr of seed bytes
|
||||
const hex = new Array(33).join('0')
|
||||
const hex = new Array(33).join("0");
|
||||
assert.throws(
|
||||
_.partial(validateSecret, hex),
|
||||
this.client.errors.ValidationError
|
||||
)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('common utils - toRippledAmount', async () => {
|
||||
const amount = {issuer: 'is', currency: 'c', value: 'v'}
|
||||
it("common utils - toRippledAmount", async function () {
|
||||
const amount = { issuer: "is", currency: "c", value: "v" };
|
||||
assert.deepEqual(toRippledAmount(amount), {
|
||||
issuer: 'is',
|
||||
currency: 'c',
|
||||
value: 'v'
|
||||
})
|
||||
})
|
||||
issuer: "is",
|
||||
currency: "c",
|
||||
value: "v",
|
||||
});
|
||||
});
|
||||
|
||||
it('ledger utils - renameCounterpartyToIssuerInOrder', async () => {
|
||||
it("ledger utils - renameCounterpartyToIssuerInOrder", async function () {
|
||||
const order = {
|
||||
taker_gets: {counterparty: '1', currency: 'XRP'},
|
||||
taker_pays: {counterparty: '1', currency: 'XRP'}
|
||||
}
|
||||
taker_gets: { counterparty: "1", currency: "XRP" },
|
||||
taker_pays: { counterparty: "1", currency: "XRP" },
|
||||
};
|
||||
const expected = {
|
||||
taker_gets: {issuer: '1', currency: 'XRP'},
|
||||
taker_pays: {issuer: '1', currency: 'XRP'}
|
||||
}
|
||||
assert.deepEqual(
|
||||
renameCounterpartyToIssuerInOrder(order),
|
||||
expected
|
||||
)
|
||||
})
|
||||
taker_gets: { issuer: "1", currency: "XRP" },
|
||||
taker_pays: { issuer: "1", currency: "XRP" },
|
||||
};
|
||||
assert.deepEqual(renameCounterpartyToIssuerInOrder(order), expected);
|
||||
});
|
||||
|
||||
it('ledger utils - compareTransactions', async () => {
|
||||
// @ts-ignore
|
||||
assert.strictEqual(compareTransactions({}, {}), 0)
|
||||
let first: any = {outcome: {ledgerVersion: 1, indexInLedger: 100}}
|
||||
let second: any = {outcome: {ledgerVersion: 1, indexInLedger: 200}}
|
||||
assert.strictEqual(compareTransactions(first, second), -1)
|
||||
first = {outcome: {ledgerVersion: 1, indexInLedger: 100}}
|
||||
second = {outcome: {ledgerVersion: 1, indexInLedger: 100}}
|
||||
assert.strictEqual(compareTransactions(first, second), 0)
|
||||
first = {outcome: {ledgerVersion: 1, indexInLedger: 200}}
|
||||
second = {outcome: {ledgerVersion: 1, indexInLedger: 100}}
|
||||
assert.strictEqual(compareTransactions(first, second), 1)
|
||||
})
|
||||
it("ledger utils - compareTransactions", async function () {
|
||||
// @ts-expect-error
|
||||
assert.strictEqual(compareTransactions({}, {}), 0);
|
||||
let first: any = { outcome: { ledgerVersion: 1, indexInLedger: 100 } };
|
||||
let second: any = { outcome: { ledgerVersion: 1, indexInLedger: 200 } };
|
||||
assert.strictEqual(compareTransactions(first, second), -1);
|
||||
first = { outcome: { ledgerVersion: 1, indexInLedger: 100 } };
|
||||
second = { outcome: { ledgerVersion: 1, indexInLedger: 100 } };
|
||||
assert.strictEqual(compareTransactions(first, second), 0);
|
||||
first = { outcome: { ledgerVersion: 1, indexInLedger: 200 } };
|
||||
second = { outcome: { ledgerVersion: 1, indexInLedger: 100 } };
|
||||
assert.strictEqual(compareTransactions(first, second), 1);
|
||||
});
|
||||
|
||||
it('ledger utils - getRecursive', async () => {
|
||||
it("ledger utils - getRecursive", async function () {
|
||||
function getter(marker) {
|
||||
return new Promise<RecursiveData>((resolve, reject) => {
|
||||
if (marker != null) {
|
||||
reject(new Error())
|
||||
return
|
||||
reject(new Error());
|
||||
return;
|
||||
}
|
||||
resolve({marker: 'A', results: [1]})
|
||||
})
|
||||
resolve({ marker: "A", results: [1] });
|
||||
});
|
||||
}
|
||||
await assertRejects(getRecursive(getter, 10), Error)
|
||||
})
|
||||
})
|
||||
await assertRejects(getRecursive(getter, 10), Error);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,41 +1,36 @@
|
||||
import {Client, BroadcastClient} from 'xrpl-local'
|
||||
import {createMockRippled} from './mockRippled'
|
||||
import {getFreePort} from './testUtils'
|
||||
import { Client, BroadcastClient } from "xrpl-local";
|
||||
|
||||
import { createMockRippled } from "./mockRippled";
|
||||
import { getFreePort } from "./testUtils";
|
||||
|
||||
function setupMockRippledConnection(testcase, port) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
testcase.mockRippled = createMockRippled(port)
|
||||
testcase._mockedServerPort = port
|
||||
testcase.client = new Client('ws://localhost:' + port)
|
||||
testcase.client
|
||||
.connect()
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
testcase.mockRippled = createMockRippled(port);
|
||||
testcase._mockedServerPort = port;
|
||||
testcase.client = new Client(`ws://localhost:${port}`);
|
||||
testcase.client.connect().then(resolve).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
function setupMockRippledConnectionForBroadcast(testcase, ports) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const servers = ports.map((port) => 'ws://localhost:' + port)
|
||||
testcase.mocks = ports.map((port) => createMockRippled(port))
|
||||
testcase.client = new BroadcastClient(servers)
|
||||
testcase.client
|
||||
.connect()
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
const servers = ports.map((port) => `ws://localhost:${port}`);
|
||||
testcase.mocks = ports.map((port) => createMockRippled(port));
|
||||
testcase.client = new BroadcastClient(servers);
|
||||
testcase.client.connect().then(resolve).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
function setup(this: any) {
|
||||
return getFreePort().then((port) => {
|
||||
return setupMockRippledConnection(this, port)
|
||||
})
|
||||
return setupMockRippledConnection(this, port);
|
||||
});
|
||||
}
|
||||
|
||||
function setupBroadcast(this: any) {
|
||||
return Promise.all([getFreePort(), getFreePort()]).then((ports) => {
|
||||
return setupMockRippledConnectionForBroadcast(this, ports)
|
||||
})
|
||||
return setupMockRippledConnectionForBroadcast(this, ports);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown(this: any, done) {
|
||||
@@ -43,18 +38,18 @@ function teardown(this: any, done) {
|
||||
.disconnect()
|
||||
.then(() => {
|
||||
if (this.mockRippled != null) {
|
||||
this.mockRippled.close()
|
||||
this.mockRippled.close();
|
||||
} else {
|
||||
this.mocks.forEach((mock) => mock.close())
|
||||
this.mocks.forEach((mock) => mock.close());
|
||||
}
|
||||
setImmediate(done)
|
||||
setImmediate(done);
|
||||
})
|
||||
.catch(done)
|
||||
.catch(done);
|
||||
}
|
||||
|
||||
export default {
|
||||
setup: setup,
|
||||
teardown: teardown,
|
||||
setupBroadcast: setupBroadcast,
|
||||
createMockRippled: createMockRippled
|
||||
}
|
||||
setup,
|
||||
teardown,
|
||||
setupBroadcast,
|
||||
createMockRippled,
|
||||
};
|
||||
|
||||
@@ -1,55 +1,46 @@
|
||||
import {Client, BroadcastClient} from 'xrpl-local'
|
||||
import { Client, BroadcastClient } from "xrpl-local";
|
||||
|
||||
const port = 34371
|
||||
const baseUrl = 'ws://testripple.circleci.com:'
|
||||
const port = 34371;
|
||||
const baseUrl = "ws://testripple.circleci.com:";
|
||||
|
||||
function setup(this: any, port_ = port) {
|
||||
const tclient = new Client(baseUrl + port_)
|
||||
const tclient = new Client(baseUrl + port_);
|
||||
return tclient
|
||||
.connect()
|
||||
.then(() => {
|
||||
return tclient.connection.request({
|
||||
// TODO: resolve when we redo the testing framework
|
||||
// @ts-ignore
|
||||
command: 'test_command',
|
||||
data: {openOnOtherPort: true}
|
||||
})
|
||||
command: "test_command",
|
||||
data: { openOnOtherPort: true },
|
||||
});
|
||||
})
|
||||
.then((got) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// @ts-ignore
|
||||
this.client = new Client(baseUrl + got.port)
|
||||
this.client
|
||||
.connect()
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
this.client = new Client(baseUrl + got.port);
|
||||
this.client.connect().then(resolve).catch(reject);
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return tclient.disconnect()
|
||||
})
|
||||
return tclient.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
function setupBroadcast(this: any) {
|
||||
const servers = [port, port + 1].map((port_) => baseUrl + port_)
|
||||
this.client = new BroadcastClient(servers)
|
||||
const servers = [port, port + 1].map((port_) => baseUrl + port_);
|
||||
this.client = new BroadcastClient(servers);
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
this.client
|
||||
.connect()
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
this.client.connect().then(resolve).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown(this: any) {
|
||||
if (this.client.isConnected()) {
|
||||
return this.client.disconnect()
|
||||
return this.client.disconnect();
|
||||
}
|
||||
return undefined
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export default {
|
||||
setup: setup,
|
||||
teardown: teardown,
|
||||
setupBroadcast: setupBroadcast
|
||||
}
|
||||
setup,
|
||||
teardown,
|
||||
setupBroadcast,
|
||||
};
|
||||
|
||||
@@ -1,59 +1,63 @@
|
||||
import assert from 'assert'
|
||||
import {SHAMap, NodeType} from '../src/utils/hashes/shamap'
|
||||
const TYPE_TRANSACTION_NO_METADATA = NodeType.TRANSACTION_NO_METADATA
|
||||
import assert from "assert";
|
||||
|
||||
var HEX_ZERO =
|
||||
'00000000000000000000000000000000' + '00000000000000000000000000000000'
|
||||
import { SHAMap, NodeType } from "../src/utils/hashes/shamap";
|
||||
|
||||
const TYPE_TRANSACTION_NO_METADATA = NodeType.TRANSACTION_NO_METADATA;
|
||||
|
||||
const HEX_ZERO =
|
||||
"00000000000000000000000000000000" + "00000000000000000000000000000000";
|
||||
|
||||
/**
|
||||
* Generates data to hash for testing
|
||||
* Generates data to hash for testing.
|
||||
*
|
||||
* @param v
|
||||
*/
|
||||
function intToVuc(v: number): string {
|
||||
var ret = ''
|
||||
let ret = "";
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
ret += '0'
|
||||
ret += v.toString(16).toUpperCase()
|
||||
for (let i = 0; i < 32; i++) {
|
||||
ret += "0";
|
||||
ret += v.toString(16).toUpperCase();
|
||||
}
|
||||
return ret
|
||||
return ret;
|
||||
}
|
||||
|
||||
function fillShamapTest(shamap: any, keys: string[], hashes: string[]) {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var data = intToVuc(i)
|
||||
shamap.addItem(keys[i].toUpperCase(), data, TYPE_TRANSACTION_NO_METADATA)
|
||||
assert.equal(shamap.hash, hashes[i])
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const data = intToVuc(i);
|
||||
shamap.addItem(keys[i].toUpperCase(), data, TYPE_TRANSACTION_NO_METADATA);
|
||||
assert.equal(shamap.hash, hashes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
describe('SHAMap', function () {
|
||||
describe('#addItem', function () {
|
||||
it('will add new nodes to v1', function () {
|
||||
var keys = [
|
||||
'b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'b92881fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'b92691fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'b92791fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'b91891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'b99891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'f22891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8',
|
||||
'292891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8'
|
||||
]
|
||||
describe("SHAMap", function () {
|
||||
describe("#addItem", function () {
|
||||
it("will add new nodes to v1", function () {
|
||||
const keys = [
|
||||
"b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"b92881fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"b92691fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"b92791fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"b91891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"b99891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"f22891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
"292891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8",
|
||||
];
|
||||
|
||||
var hashesv1 = [
|
||||
'B7387CFEA0465759ADC718E8C42B52D2309D179B326E239EB5075C64B6281F7F',
|
||||
'FBC195A9592A54AB44010274163CB6BA95F497EC5BA0A8831845467FB2ECE266',
|
||||
'4E7D2684B65DFD48937FFB775E20175C43AF0C94066F7D5679F51AE756795B75',
|
||||
'7A2F312EB203695FFD164E038E281839EEF06A1B99BFC263F3CECC6C74F93E07',
|
||||
'395A6691A372387A703FB0F2C6D2C405DAF307D0817F8F0E207596462B0E3A3E',
|
||||
'D044C0A696DE3169CC70AE216A1564D69DE96582865796142CE7D98A84D9DDE4',
|
||||
'76DCC77C4027309B5A91AD164083264D70B77B5E43E08AEDA5EBF94361143615',
|
||||
'DF4220E93ADC6F5569063A01B4DC79F8DB9553B6A3222ADE23DEA02BBE7230E5'
|
||||
]
|
||||
const hashesv1 = [
|
||||
"B7387CFEA0465759ADC718E8C42B52D2309D179B326E239EB5075C64B6281F7F",
|
||||
"FBC195A9592A54AB44010274163CB6BA95F497EC5BA0A8831845467FB2ECE266",
|
||||
"4E7D2684B65DFD48937FFB775E20175C43AF0C94066F7D5679F51AE756795B75",
|
||||
"7A2F312EB203695FFD164E038E281839EEF06A1B99BFC263F3CECC6C74F93E07",
|
||||
"395A6691A372387A703FB0F2C6D2C405DAF307D0817F8F0E207596462B0E3A3E",
|
||||
"D044C0A696DE3169CC70AE216A1564D69DE96582865796142CE7D98A84D9DDE4",
|
||||
"76DCC77C4027309B5A91AD164083264D70B77B5E43E08AEDA5EBF94361143615",
|
||||
"DF4220E93ADC6F5569063A01B4DC79F8DB9553B6A3222ADE23DEA02BBE7230E5",
|
||||
];
|
||||
|
||||
var shamapv1 = new SHAMap()
|
||||
assert.equal(shamapv1.hash, HEX_ZERO)
|
||||
fillShamapTest(shamapv1, keys, hashesv1)
|
||||
})
|
||||
})
|
||||
})
|
||||
const shamapv1 = new SHAMap();
|
||||
assert.equal(shamapv1.hash, HEX_ZERO);
|
||||
fillShamapTest(shamapv1, keys, hashesv1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import net from 'net'
|
||||
import _ from 'lodash'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import {Client} from 'xrpl-local'
|
||||
import assert from 'assert-diff'
|
||||
import fs from "fs";
|
||||
import net from "net";
|
||||
import path from "path";
|
||||
|
||||
import assert from "assert-diff";
|
||||
import _ from "lodash";
|
||||
|
||||
import { Client } from "xrpl-local";
|
||||
|
||||
/**
|
||||
* The test function. It takes a Client object and then some other data to
|
||||
@@ -14,13 +16,13 @@ export type TestFn = (
|
||||
client: Client,
|
||||
address: string,
|
||||
mockRippled?: any
|
||||
) => void | PromiseLike<void>
|
||||
) => void | PromiseLike<void>;
|
||||
|
||||
/**
|
||||
* A suite of tests to run. Maps the test name to the test function.
|
||||
*/
|
||||
export interface TestSuite {
|
||||
[testName: string]: TestFn
|
||||
[testName: string]: TestFn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,17 +32,21 @@ export interface TestSuite {
|
||||
* so that we can report it.
|
||||
*/
|
||||
interface LoadedTestSuite {
|
||||
name: string
|
||||
tests: [string, TestFn][]
|
||||
name: string;
|
||||
tests: Array<[string, TestFn]>;
|
||||
config: {
|
||||
/** Set to true to skip re-running tests with an X-address. */
|
||||
skipXAddress?: boolean
|
||||
}
|
||||
skipXAddress?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the response against the expected result. Optionally validate
|
||||
* that response against a given schema as well.
|
||||
*
|
||||
* @param response - Response received from the method.
|
||||
* @param expected - Expected response from the method.
|
||||
* @param schemaName - Name of the schema used to validate the shape of the response.
|
||||
*/
|
||||
export function assertResultMatch(
|
||||
response: any,
|
||||
@@ -48,29 +54,33 @@ export function assertResultMatch(
|
||||
schemaName?: string
|
||||
) {
|
||||
if (expected.txJSON) {
|
||||
assert(response.txJSON)
|
||||
assert(response.txJSON);
|
||||
assert.deepEqual(
|
||||
JSON.parse(response.txJSON),
|
||||
JSON.parse(expected.txJSON),
|
||||
'checkResult: txJSON must match'
|
||||
)
|
||||
"checkResult: txJSON must match"
|
||||
);
|
||||
}
|
||||
if (expected.tx_json) {
|
||||
assert(response.tx_json)
|
||||
assert(response.tx_json);
|
||||
assert.deepEqual(
|
||||
response.tx_json,
|
||||
expected.tx_json,
|
||||
'checkResult: tx_json must match'
|
||||
)
|
||||
"checkResult: tx_json must match"
|
||||
);
|
||||
}
|
||||
assert.deepEqual(
|
||||
_.omit(response, ['txJSON', 'tx_json']),
|
||||
_.omit(expected, ['txJSON', 'tx_json'])
|
||||
)
|
||||
_.omit(response, ["txJSON", "tx_json"]),
|
||||
_.omit(expected, ["txJSON", "tx_json"])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the promise rejects with an expected error.
|
||||
*
|
||||
* @param promise - The promise returned by the method.
|
||||
* @param instanceOf - Expected error type that the method will throw.
|
||||
* @param message - Expected error message/substring of the error message.
|
||||
*/
|
||||
export async function assertRejects(
|
||||
promise: PromiseLike<any>,
|
||||
@@ -78,14 +88,14 @@ export async function assertRejects(
|
||||
message?: string | RegExp
|
||||
) {
|
||||
try {
|
||||
await promise
|
||||
assert(false, 'Expected an error to be thrown')
|
||||
await promise;
|
||||
assert(false, "Expected an error to be thrown");
|
||||
} catch (error) {
|
||||
assert(error instanceof instanceOf, error.message)
|
||||
if (typeof message === 'string') {
|
||||
assert.strictEqual(error.message, message)
|
||||
assert(error instanceof instanceOf, error.message);
|
||||
if (typeof message === "string") {
|
||||
assert.strictEqual(error.message, message);
|
||||
} else if (message instanceof RegExp) {
|
||||
assert(message.test(error.message))
|
||||
assert(message.test(error.message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,61 +103,63 @@ export async function assertRejects(
|
||||
// using a free port instead of a constant port enables parallelization
|
||||
export function getFreePort() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = net.createServer()
|
||||
let port
|
||||
server.on('listening', function () {
|
||||
port = (server.address() as any).port
|
||||
server.close()
|
||||
})
|
||||
server.on('close', function () {
|
||||
resolve(port)
|
||||
})
|
||||
server.on('error', function (error) {
|
||||
reject(error)
|
||||
})
|
||||
server.listen(0)
|
||||
})
|
||||
const server = net.createServer();
|
||||
let port;
|
||||
server.on("listening", function () {
|
||||
port = (server.address() as any).port;
|
||||
server.close();
|
||||
});
|
||||
server.on("close", function () {
|
||||
resolve(port);
|
||||
});
|
||||
server.on("error", function (error) {
|
||||
reject(error);
|
||||
});
|
||||
server.listen(0);
|
||||
});
|
||||
}
|
||||
|
||||
export function getAllPublicMethods(client: Client) {
|
||||
return Array.from(
|
||||
new Set([
|
||||
...Object.getOwnPropertyNames(client),
|
||||
...Object.getOwnPropertyNames(Client.prototype)
|
||||
...Object.getOwnPropertyNames(Client.prototype),
|
||||
])
|
||||
).filter((key) => !key.startsWith('_'))
|
||||
).filter((key) => !key.startsWith("_"));
|
||||
}
|
||||
|
||||
export function loadTestSuites(): LoadedTestSuite[] {
|
||||
const allTests = fs.readdirSync(path.join(__dirname, 'client'), {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
const allTests: any[] = fs.readdirSync(path.join(__dirname, "client"), {
|
||||
encoding: "utf8",
|
||||
});
|
||||
return allTests
|
||||
.map((methodName) => {
|
||||
if (methodName.startsWith('.DS_Store')) {
|
||||
return null
|
||||
if (methodName.startsWith(".DS_Store")) {
|
||||
return null;
|
||||
}
|
||||
if (methodName.endsWith('.ts')) {
|
||||
methodName = methodName.slice(0, -3)
|
||||
if (methodName.endsWith(".ts")) {
|
||||
methodName = methodName.slice(0, -3);
|
||||
}
|
||||
const testSuite = require(`./client/${methodName}`)
|
||||
const testSuite = require(`./client/${methodName}`);
|
||||
return {
|
||||
name: methodName,
|
||||
config: testSuite.config || {},
|
||||
tests: Object.entries(testSuite.default || {})
|
||||
} as LoadedTestSuite
|
||||
tests: Object.entries(testSuite.default || {}),
|
||||
} as LoadedTestSuite;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.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
|
||||
* has come back.
|
||||
*
|
||||
* @param error - Thrown error.
|
||||
*/
|
||||
export function ignoreWebSocketDisconnect(error: Error): void {
|
||||
if (error.message === 'websocket was closed') {
|
||||
return
|
||||
if (error.message === "websocket was closed") {
|
||||
return;
|
||||
}
|
||||
throw error
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig-base.json",
|
||||
}
|
||||
@@ -1,147 +1,147 @@
|
||||
import assert from 'assert-diff'
|
||||
import {computeLedgerHeaderHash} from '../../src/utils'
|
||||
import {ValidationError} from '../../src/common/errors'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import {assertResultMatch} from '../testUtils'
|
||||
const {computeLedgerHash: REQUEST_FIXTURES} = requests
|
||||
import assert from "assert-diff";
|
||||
|
||||
import { ValidationError } from "../../src/common/errors";
|
||||
import { computeLedgerHeaderHash } from "../../src/utils";
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import { assertResultMatch } from "../testUtils";
|
||||
|
||||
const { computeLedgerHash: REQUEST_FIXTURES } = requests;
|
||||
|
||||
function getNewLedger() {
|
||||
return JSON.parse(JSON.stringify(responses.getLedger.full))
|
||||
return JSON.parse(JSON.stringify(responses.getLedger.full));
|
||||
}
|
||||
|
||||
describe('Compute Ledger Hash', function () {
|
||||
it('given corrupt data - should fail', () => {
|
||||
const ledger = getNewLedger()
|
||||
// @ts-ignore - Change Amount to 12000000000
|
||||
describe("Compute Ledger Hash", function () {
|
||||
it("given corrupt data - should fail", function () {
|
||||
const ledger = getNewLedger();
|
||||
ledger.transactions[0].rawTransaction =
|
||||
'{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Amount":"12000000000","Destination":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Fee":"10","Flags":0,"Sequence":62,"SigningPubKey":"034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E","TransactionType":"Payment","TxnSignature":"3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639","hash":"3B1A4E1C9BB6A7208EB146BCDB86ECEA6068ED01466D933528CA2B4C64F753EF","meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"4C6ACBD635B0F07101F7FA25871B0925F8836155462152172755845CE691C49E","NewFields":{"Account":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Balance":"10000000000","Sequence":1}}},{"ModifiedNode":{"FinalFields":{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Balance":"981481999380","Flags":0,"OwnerCount":0,"Sequence":63},"LedgerEntryType":"AccountRoot","LedgerIndex":"B33FDD5CF3445E1A7F2BE9B06336BEBD73A5E3EE885D3EF93F7E3E2992E46F1A","PreviousFields":{"Balance":"991481999390","Sequence":62},"PreviousTxnID":"2485FDC606352F1B0785DA5DE96FB9DBAF43EB60ECBB01B7F6FA970F512CDA5F","PreviousTxnLgrSeq":31317}}],"TransactionIndex":0,"TransactionResult":"tesSUCCESS"},"ledger_index":38129}'
|
||||
ledger.parentCloseTime = ledger.closeTime
|
||||
let hash
|
||||
'{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Amount":"12000000000","Destination":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Fee":"10","Flags":0,"Sequence":62,"SigningPubKey":"034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E","TransactionType":"Payment","TxnSignature":"3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639","hash":"3B1A4E1C9BB6A7208EB146BCDB86ECEA6068ED01466D933528CA2B4C64F753EF","meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"4C6ACBD635B0F07101F7FA25871B0925F8836155462152172755845CE691C49E","NewFields":{"Account":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Balance":"10000000000","Sequence":1}}},{"ModifiedNode":{"FinalFields":{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Balance":"981481999380","Flags":0,"OwnerCount":0,"Sequence":63},"LedgerEntryType":"AccountRoot","LedgerIndex":"B33FDD5CF3445E1A7F2BE9B06336BEBD73A5E3EE885D3EF93F7E3E2992E46F1A","PreviousFields":{"Balance":"991481999390","Sequence":62},"PreviousTxnID":"2485FDC606352F1B0785DA5DE96FB9DBAF43EB60ECBB01B7F6FA970F512CDA5F","PreviousTxnLgrSeq":31317}}],"TransactionIndex":0,"TransactionResult":"tesSUCCESS"},"ledger_index":38129}';
|
||||
ledger.parentCloseTime = ledger.closeTime;
|
||||
let hash;
|
||||
try {
|
||||
hash = computeLedgerHeaderHash(ledger, {computeTreeHashes: true})
|
||||
hash = computeLedgerHeaderHash(ledger, { computeTreeHashes: true });
|
||||
} catch (error) {
|
||||
assert(error instanceof ValidationError)
|
||||
assert(error instanceof ValidationError);
|
||||
assert.strictEqual(
|
||||
error.message,
|
||||
'transactionHash in header does not match computed hash of transactions'
|
||||
)
|
||||
"transactionHash in header does not match computed hash of transactions"
|
||||
);
|
||||
assert.deepStrictEqual(error.data, {
|
||||
transactionHashInHeader:
|
||||
'DB83BF807416C5B3499A73130F843CF615AB8E797D79FE7D330ADF1BFA93951A',
|
||||
"DB83BF807416C5B3499A73130F843CF615AB8E797D79FE7D330ADF1BFA93951A",
|
||||
computedHashOfTransactions:
|
||||
'EAA1ADF4D627339450F0E95EA88B7069186DD64230BAEBDCF3EEC4D616A9FC68'
|
||||
})
|
||||
return
|
||||
"EAA1ADF4D627339450F0E95EA88B7069186DD64230BAEBDCF3EEC4D616A9FC68",
|
||||
});
|
||||
return;
|
||||
}
|
||||
assert(
|
||||
false,
|
||||
'Should throw ValidationError instead of producing hash: ' + hash
|
||||
)
|
||||
})
|
||||
`Should throw ValidationError instead of producing hash: ${hash}`
|
||||
);
|
||||
});
|
||||
|
||||
it('given ledger without raw transactions - should throw', () => {
|
||||
const ledger = getNewLedger()
|
||||
// @ts-ignore - Delete rawTransaction
|
||||
delete ledger.transactions[0].rawTransaction
|
||||
ledger.parentCloseTime = ledger.closeTime
|
||||
let hash
|
||||
it("given ledger without raw transactions - should throw", function () {
|
||||
const ledger = getNewLedger();
|
||||
delete ledger.transactions[0].rawTransaction;
|
||||
ledger.parentCloseTime = ledger.closeTime;
|
||||
let hash;
|
||||
try {
|
||||
hash = computeLedgerHeaderHash(ledger, {computeTreeHashes: true})
|
||||
hash = computeLedgerHeaderHash(ledger, { computeTreeHashes: true });
|
||||
} catch (error) {
|
||||
assert(error instanceof ValidationError)
|
||||
assert(error instanceof ValidationError);
|
||||
assert.strictEqual(
|
||||
error.message,
|
||||
'ledger' + ' is missing raw transactions'
|
||||
)
|
||||
return
|
||||
"ledger" + " is missing raw transactions"
|
||||
);
|
||||
return;
|
||||
}
|
||||
assert(
|
||||
false,
|
||||
'Should throw ValidationError instead of producing hash: ' + hash
|
||||
)
|
||||
})
|
||||
`Should throw ValidationError instead of producing hash: ${hash}`
|
||||
);
|
||||
});
|
||||
|
||||
it('given ledger without state or transactions - only compute ledger hash', () => {
|
||||
const ledger = getNewLedger()
|
||||
it("given ledger without state or transactions - only compute ledger hash", function () {
|
||||
const ledger = getNewLedger();
|
||||
assert.strictEqual(
|
||||
// @ts-ignore
|
||||
ledger.transactions[0].rawTransaction,
|
||||
'{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Amount":"10000000000","Destination":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Fee":"10","Flags":0,"Sequence":62,"SigningPubKey":"034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E","TransactionType":"Payment","TxnSignature":"3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639","hash":"3B1A4E1C9BB6A7208EB146BCDB86ECEA6068ED01466D933528CA2B4C64F753EF","meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"4C6ACBD635B0F07101F7FA25871B0925F8836155462152172755845CE691C49E","NewFields":{"Account":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Balance":"10000000000","Sequence":1}}},{"ModifiedNode":{"FinalFields":{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Balance":"981481999380","Flags":0,"OwnerCount":0,"Sequence":63},"LedgerEntryType":"AccountRoot","LedgerIndex":"B33FDD5CF3445E1A7F2BE9B06336BEBD73A5E3EE885D3EF93F7E3E2992E46F1A","PreviousFields":{"Balance":"991481999390","Sequence":62},"PreviousTxnID":"2485FDC606352F1B0785DA5DE96FB9DBAF43EB60ECBB01B7F6FA970F512CDA5F","PreviousTxnLgrSeq":31317}}],"TransactionIndex":0,"TransactionResult":"tesSUCCESS"},"ledger_index":38129}'
|
||||
)
|
||||
ledger.parentCloseTime = ledger.closeTime
|
||||
const computeLedgerHash = computeLedgerHeaderHash
|
||||
);
|
||||
ledger.parentCloseTime = ledger.closeTime;
|
||||
const computeLedgerHash = computeLedgerHeaderHash;
|
||||
function testCompute(ledger, expectedError) {
|
||||
let hash = computeLedgerHash(ledger)
|
||||
let hash = computeLedgerHash(ledger);
|
||||
assert.strictEqual(
|
||||
hash,
|
||||
'E6DB7365949BF9814D76BCC730B01818EB9136A89DB224F3F9F5AAE4569D758E'
|
||||
)
|
||||
"E6DB7365949BF9814D76BCC730B01818EB9136A89DB224F3F9F5AAE4569D758E"
|
||||
);
|
||||
// fail if required to compute tree hashes
|
||||
try {
|
||||
hash = computeLedgerHash(ledger, {computeTreeHashes: true})
|
||||
hash = computeLedgerHash(ledger, { computeTreeHashes: true });
|
||||
} catch (error) {
|
||||
assert(error instanceof ValidationError)
|
||||
assert.strictEqual(error.message, expectedError)
|
||||
return
|
||||
assert(error instanceof ValidationError);
|
||||
assert.strictEqual(error.message, expectedError);
|
||||
return;
|
||||
}
|
||||
assert(
|
||||
false,
|
||||
'Should throw ValidationError instead of producing hash: ' + hash
|
||||
)
|
||||
`Should throw ValidationError instead of producing hash: ${hash}`
|
||||
);
|
||||
}
|
||||
|
||||
const transactions = ledger.transactions
|
||||
delete ledger.transactions
|
||||
testCompute(ledger, 'transactions property is missing from the ledger')
|
||||
delete ledger.rawState
|
||||
testCompute(ledger, 'transactions property is missing from the ledger')
|
||||
ledger.transactions = transactions
|
||||
testCompute(ledger, 'rawState property is missing from the ledger')
|
||||
})
|
||||
const transactions = ledger.transactions;
|
||||
delete ledger.transactions;
|
||||
testCompute(ledger, "transactions property is missing from the ledger");
|
||||
delete ledger.rawState;
|
||||
testCompute(ledger, "transactions property is missing from the ledger");
|
||||
ledger.transactions = transactions;
|
||||
testCompute(ledger, "rawState property is missing from the ledger");
|
||||
});
|
||||
|
||||
it('wrong hash', () => {
|
||||
const ledger = getNewLedger()
|
||||
assertResultMatch(ledger, responses.getLedger.full, 'getLedger')
|
||||
it("wrong hash", function () {
|
||||
const ledger = getNewLedger();
|
||||
assertResultMatch(ledger, responses.getLedger.full, "getLedger");
|
||||
const newLedger = {
|
||||
...ledger,
|
||||
parentCloseTime: ledger.closeTime,
|
||||
stateHash:
|
||||
'D9ABF622DA26EEEE48203085D4BC23B0F77DC6F8724AC33D975DA3CA492D2E44'
|
||||
}
|
||||
"D9ABF622DA26EEEE48203085D4BC23B0F77DC6F8724AC33D975DA3CA492D2E44",
|
||||
};
|
||||
assert.throws(() => {
|
||||
computeLedgerHeaderHash(newLedger)
|
||||
}, /does not match computed hash of state/)
|
||||
})
|
||||
computeLedgerHeaderHash(newLedger);
|
||||
}, /does not match computed hash of state/);
|
||||
});
|
||||
|
||||
it('computeLedgerHash', () => {
|
||||
const header = REQUEST_FIXTURES.header
|
||||
const ledgerHash = computeLedgerHeaderHash(header)
|
||||
it("computeLedgerHash", function () {
|
||||
const header = REQUEST_FIXTURES.header;
|
||||
const ledgerHash = computeLedgerHeaderHash(header);
|
||||
assert.strictEqual(
|
||||
ledgerHash,
|
||||
'F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349'
|
||||
)
|
||||
})
|
||||
"F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349"
|
||||
);
|
||||
});
|
||||
|
||||
it('computeLedgerHash - with transactions', () => {
|
||||
it("computeLedgerHash - with transactions", function () {
|
||||
const header = {
|
||||
...REQUEST_FIXTURES.header,
|
||||
transactionHash: undefined,
|
||||
rawTransactions: JSON.stringify(REQUEST_FIXTURES.transactions)
|
||||
}
|
||||
const ledgerHash = computeLedgerHeaderHash(header)
|
||||
rawTransactions: JSON.stringify(REQUEST_FIXTURES.transactions),
|
||||
};
|
||||
const ledgerHash = computeLedgerHeaderHash(header);
|
||||
assert.strictEqual(
|
||||
ledgerHash,
|
||||
'F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349'
|
||||
)
|
||||
})
|
||||
"F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349"
|
||||
);
|
||||
});
|
||||
|
||||
it('computeLedgerHash - incorrent transaction_hash', () => {
|
||||
const header = Object.assign({}, REQUEST_FIXTURES.header, {
|
||||
it("computeLedgerHash - incorrent transaction_hash", function () {
|
||||
const header = {
|
||||
...REQUEST_FIXTURES.header,
|
||||
transactionHash:
|
||||
'325EACC5271322539EEEC2D6A5292471EF1B3E72AE7180533EFC3B8F0AD435C9'
|
||||
})
|
||||
header.rawTransactions = JSON.stringify(REQUEST_FIXTURES.transactions)
|
||||
assert.throws(() => computeLedgerHeaderHash(header))
|
||||
})
|
||||
})
|
||||
"325EACC5271322539EEEC2D6A5292471EF1B3E72AE7180533EFC3B8F0AD435C9",
|
||||
};
|
||||
header.rawTransactions = JSON.stringify(REQUEST_FIXTURES.transactions);
|
||||
assert.throws(() => computeLedgerHeaderHash(header));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,123 +1,124 @@
|
||||
import assert from 'assert-diff'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {dropsToXrp} from '../../src/utils'
|
||||
import assert from "assert-diff";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
describe('Drops To XRP', function () {
|
||||
it('works with a typical amount', () => {
|
||||
const xrp = dropsToXrp('2000000')
|
||||
assert.strictEqual(xrp, '2', '2 million drops equals 2 XRP')
|
||||
})
|
||||
import { dropsToXrp } from "../../src/utils";
|
||||
|
||||
it('works with fractions', () => {
|
||||
let xrp = dropsToXrp('3456789')
|
||||
assert.strictEqual(xrp, '3.456789', '3,456,789 drops equals 3.456789 XRP')
|
||||
describe("Drops To XRP", function () {
|
||||
it("works with a typical amount", function () {
|
||||
const xrp = dropsToXrp("2000000");
|
||||
assert.strictEqual(xrp, "2", "2 million drops equals 2 XRP");
|
||||
});
|
||||
|
||||
xrp = dropsToXrp('3400000')
|
||||
assert.strictEqual(xrp, '3.4', '3,400,000 drops equals 3.4 XRP')
|
||||
it("works with fractions", function () {
|
||||
let xrp = dropsToXrp("3456789");
|
||||
assert.strictEqual(xrp, "3.456789", "3,456,789 drops equals 3.456789 XRP");
|
||||
|
||||
xrp = dropsToXrp('1')
|
||||
assert.strictEqual(xrp, '0.000001', '1 drop equals 0.000001 XRP')
|
||||
xrp = dropsToXrp("3400000");
|
||||
assert.strictEqual(xrp, "3.4", "3,400,000 drops equals 3.4 XRP");
|
||||
|
||||
xrp = dropsToXrp('1.0')
|
||||
assert.strictEqual(xrp, '0.000001', '1.0 drops equals 0.000001 XRP')
|
||||
xrp = dropsToXrp("1");
|
||||
assert.strictEqual(xrp, "0.000001", "1 drop equals 0.000001 XRP");
|
||||
|
||||
xrp = dropsToXrp('1.00')
|
||||
assert.strictEqual(xrp, '0.000001', '1.00 drops equals 0.000001 XRP')
|
||||
})
|
||||
xrp = dropsToXrp("1.0");
|
||||
assert.strictEqual(xrp, "0.000001", "1.0 drops equals 0.000001 XRP");
|
||||
|
||||
it('works with zero', () => {
|
||||
let xrp = dropsToXrp('0')
|
||||
assert.strictEqual(xrp, '0', '0 drops equals 0 XRP')
|
||||
xrp = dropsToXrp("1.00");
|
||||
assert.strictEqual(xrp, "0.000001", "1.00 drops equals 0.000001 XRP");
|
||||
});
|
||||
|
||||
it("works with zero", function () {
|
||||
let xrp = dropsToXrp("0");
|
||||
assert.strictEqual(xrp, "0", "0 drops equals 0 XRP");
|
||||
|
||||
// negative zero is equivalent to zero
|
||||
xrp = dropsToXrp('-0')
|
||||
assert.strictEqual(xrp, '0', '-0 drops equals 0 XRP')
|
||||
xrp = dropsToXrp("-0");
|
||||
assert.strictEqual(xrp, "0", "-0 drops equals 0 XRP");
|
||||
|
||||
xrp = dropsToXrp('0.00')
|
||||
assert.strictEqual(xrp, '0', '0.00 drops equals 0 XRP')
|
||||
xrp = dropsToXrp("0.00");
|
||||
assert.strictEqual(xrp, "0", "0.00 drops equals 0 XRP");
|
||||
|
||||
xrp = dropsToXrp('000000000')
|
||||
assert.strictEqual(xrp, '0', '000000000 drops equals 0 XRP')
|
||||
})
|
||||
xrp = dropsToXrp("000000000");
|
||||
assert.strictEqual(xrp, "0", "000000000 drops equals 0 XRP");
|
||||
});
|
||||
|
||||
it('works with a negative value', () => {
|
||||
const xrp = dropsToXrp('-2000000')
|
||||
assert.strictEqual(xrp, '-2', '-2 million drops equals -2 XRP')
|
||||
})
|
||||
it("works with a negative value", function () {
|
||||
const xrp = dropsToXrp("-2000000");
|
||||
assert.strictEqual(xrp, "-2", "-2 million drops equals -2 XRP");
|
||||
});
|
||||
|
||||
it('works with a value ending with a decimal point', () => {
|
||||
let xrp = dropsToXrp('2000000.')
|
||||
assert.strictEqual(xrp, '2', '2000000. drops equals 2 XRP')
|
||||
it("works with a value ending with a decimal point", function () {
|
||||
let xrp = dropsToXrp("2000000.");
|
||||
assert.strictEqual(xrp, "2", "2000000. drops equals 2 XRP");
|
||||
|
||||
xrp = dropsToXrp('-2000000.')
|
||||
assert.strictEqual(xrp, '-2', '-2000000. drops equals -2 XRP')
|
||||
})
|
||||
xrp = dropsToXrp("-2000000.");
|
||||
assert.strictEqual(xrp, "-2", "-2000000. drops equals -2 XRP");
|
||||
});
|
||||
|
||||
it('works with BigNumber objects', () => {
|
||||
let xrp = dropsToXrp(new BigNumber(2000000))
|
||||
assert.strictEqual(xrp, '2', '(BigNumber) 2 million drops equals 2 XRP')
|
||||
it("works with BigNumber objects", function () {
|
||||
let xrp = dropsToXrp(new BigNumber(2000000));
|
||||
assert.strictEqual(xrp, "2", "(BigNumber) 2 million drops equals 2 XRP");
|
||||
|
||||
xrp = dropsToXrp(new BigNumber(-2000000))
|
||||
assert.strictEqual(xrp, '-2', '(BigNumber) -2 million drops equals -2 XRP')
|
||||
xrp = dropsToXrp(new BigNumber(-2000000));
|
||||
assert.strictEqual(xrp, "-2", "(BigNumber) -2 million drops equals -2 XRP");
|
||||
|
||||
xrp = dropsToXrp(new BigNumber(2345678))
|
||||
xrp = dropsToXrp(new BigNumber(2345678));
|
||||
assert.strictEqual(
|
||||
xrp,
|
||||
'2.345678',
|
||||
'(BigNumber) 2,345,678 drops equals 2.345678 XRP'
|
||||
)
|
||||
"2.345678",
|
||||
"(BigNumber) 2,345,678 drops equals 2.345678 XRP"
|
||||
);
|
||||
|
||||
xrp = dropsToXrp(new BigNumber(-2345678))
|
||||
xrp = dropsToXrp(new BigNumber(-2345678));
|
||||
assert.strictEqual(
|
||||
xrp,
|
||||
'-2.345678',
|
||||
'(BigNumber) -2,345,678 drops equals -2.345678 XRP'
|
||||
)
|
||||
})
|
||||
"-2.345678",
|
||||
"(BigNumber) -2,345,678 drops equals -2.345678 XRP"
|
||||
);
|
||||
});
|
||||
|
||||
it('works with a number', () => {
|
||||
it("works with a number", function () {
|
||||
// This is not recommended. Use strings or BigNumber objects to avoid precision errors.
|
||||
let xrp = dropsToXrp(2000000)
|
||||
assert.strictEqual(xrp, '2', '(number) 2 million drops equals 2 XRP')
|
||||
xrp = dropsToXrp(-2000000)
|
||||
assert.strictEqual(xrp, '-2', '(number) -2 million drops equals -2 XRP')
|
||||
})
|
||||
let xrp = dropsToXrp(2000000);
|
||||
assert.strictEqual(xrp, "2", "(number) 2 million drops equals 2 XRP");
|
||||
xrp = dropsToXrp(-2000000);
|
||||
assert.strictEqual(xrp, "-2", "(number) -2 million drops equals -2 XRP");
|
||||
});
|
||||
|
||||
it('throws with an amount with too many decimal places', () => {
|
||||
it("throws with an amount with too many decimal places", function () {
|
||||
assert.throws(() => {
|
||||
dropsToXrp('1.2')
|
||||
}, /has too many decimal places/)
|
||||
dropsToXrp("1.2");
|
||||
}, /has too many decimal places/);
|
||||
|
||||
assert.throws(() => {
|
||||
dropsToXrp('0.10')
|
||||
}, /has too many decimal places/)
|
||||
})
|
||||
dropsToXrp("0.10");
|
||||
}, /has too many decimal places/);
|
||||
});
|
||||
|
||||
it('throws with an invalid value', () => {
|
||||
it("throws with an invalid value", function () {
|
||||
assert.throws(() => {
|
||||
dropsToXrp('FOO')
|
||||
}, /invalid value/)
|
||||
dropsToXrp("FOO");
|
||||
}, /invalid value/);
|
||||
|
||||
assert.throws(() => {
|
||||
dropsToXrp('1e-7')
|
||||
}, /invalid value/)
|
||||
dropsToXrp("1e-7");
|
||||
}, /invalid value/);
|
||||
|
||||
assert.throws(() => {
|
||||
dropsToXrp('2,0')
|
||||
}, /invalid value/)
|
||||
dropsToXrp("2,0");
|
||||
}, /invalid value/);
|
||||
|
||||
assert.throws(() => {
|
||||
dropsToXrp('.')
|
||||
}, /dropsToXrp: invalid value '\.', should be a BigNumber or string-encoded number\./)
|
||||
})
|
||||
dropsToXrp(".");
|
||||
}, /dropsToXrp: invalid value '\.', should be a BigNumber or string-encoded number\./);
|
||||
});
|
||||
|
||||
it('throws with an amount more than one decimal point', () => {
|
||||
it("throws with an amount more than one decimal point", function () {
|
||||
assert.throws(() => {
|
||||
dropsToXrp('1.0.0')
|
||||
}, /dropsToXrp: invalid value '1\.0\.0'/)
|
||||
dropsToXrp("1.0.0");
|
||||
}, /dropsToXrp: invalid value '1\.0\.0'/);
|
||||
|
||||
assert.throws(() => {
|
||||
dropsToXrp('...')
|
||||
}, /dropsToXrp: invalid value '\.\.\.'/)
|
||||
})
|
||||
})
|
||||
dropsToXrp("...");
|
||||
}, /dropsToXrp: invalid value '\.\.\.'/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,231 +1,247 @@
|
||||
import assert from 'assert-diff'
|
||||
import responses from '../fixtures/responses'
|
||||
import {generateXAddress, GenerateAddressOptions} from '../../src/utils/generateAddress'
|
||||
import ECDSA from '../../src/common/ecdsa'
|
||||
import {UnexpectedError} from '../../src/common/errors'
|
||||
import assert from "assert-diff";
|
||||
|
||||
describe('Generate Address', function () {
|
||||
it('generateAddress', () => {
|
||||
import ECDSA from "../../src/common/ecdsa";
|
||||
import { UnexpectedError } from "../../src/common/errors";
|
||||
import {
|
||||
generateXAddress,
|
||||
GenerateAddressOptions,
|
||||
} from "../../src/utils/generateAddress";
|
||||
import responses from "../fixtures/responses";
|
||||
|
||||
describe("Generate Address", function () {
|
||||
it("generateAddress", function () {
|
||||
// GIVEN entropy of all zeros
|
||||
function random() {
|
||||
return new Array(16).fill(0)
|
||||
return new Array(16).fill(0);
|
||||
}
|
||||
|
||||
assert.deepEqual(
|
||||
// WHEN generating an address
|
||||
generateXAddress({entropy: random()}),
|
||||
generateXAddress({ entropy: random() }),
|
||||
|
||||
// THEN we get the expected return value
|
||||
responses.generateXAddress
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('generateAddress invalid entropy', () => {
|
||||
it("generateAddress invalid entropy", function () {
|
||||
assert.throws(() => {
|
||||
// GIVEN entropy of 1 byte
|
||||
function random() {
|
||||
return new Array(1).fill(0)
|
||||
return new Array(1).fill(0);
|
||||
}
|
||||
|
||||
// WHEN generating an address
|
||||
generateXAddress({entropy: random()})
|
||||
generateXAddress({ entropy: random() });
|
||||
|
||||
// THEN an UnexpectedError is thrown
|
||||
// because 16 bytes of entropy are required
|
||||
}, UnexpectedError)
|
||||
})
|
||||
}, UnexpectedError);
|
||||
});
|
||||
|
||||
it('generateAddress with no options object', () => {
|
||||
it("generateAddress with no options object", function () {
|
||||
// GIVEN no options
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress()
|
||||
const account = generateXAddress();
|
||||
|
||||
// THEN we get an object with an xAddress starting with 'x' and a secret starting with 's'
|
||||
assert(account.xAddress.startsWith('X'), 'Address must start with `X`')
|
||||
assert(account.secret.startsWith('s'), 'Secret must start with `s`')
|
||||
})
|
||||
assert(account.xAddress.startsWith("X"), "Address must start with `X`");
|
||||
assert(account.secret.startsWith("s"), "Secret must start with `s`");
|
||||
});
|
||||
|
||||
it('generateAddress with empty options object', () => {
|
||||
it("generateAddress with empty options object", function () {
|
||||
// GIVEN an empty options object
|
||||
const options = {}
|
||||
const options = {};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get an object with an xAddress starting with 'x' and a secret starting with 's'
|
||||
assert(account.xAddress.startsWith('X'), 'Address must start with `X`')
|
||||
assert(account.secret.startsWith('s'), 'Secret must start with `s`')
|
||||
})
|
||||
assert(account.xAddress.startsWith("X"), "Address must start with `X`");
|
||||
assert(account.secret.startsWith("s"), "Secret must start with `s`");
|
||||
});
|
||||
|
||||
it('generateAddress with algorithm `ecdsa-secp256k1`', () => {
|
||||
it("generateAddress with algorithm `ecdsa-secp256k1`", function () {
|
||||
// GIVEN we want to use 'ecdsa-secp256k1'
|
||||
const options: GenerateAddressOptions = {algorithm: ECDSA.secp256k1, includeClassicAddress: true}
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.secp256k1,
|
||||
includeClassicAddress: true,
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get an object with an address starting with 'r' and a secret starting with 's' (not 'sEd')
|
||||
assert(account.classicAddress.startsWith('r'), 'Address must start with `r`')
|
||||
assert(
|
||||
account.classicAddress?.startsWith("r"),
|
||||
"Address must start with `r`"
|
||||
);
|
||||
assert.deepEqual(
|
||||
account.secret.slice(0, 1),
|
||||
's',
|
||||
"s",
|
||||
`Secret ${account.secret} must start with 's'`
|
||||
)
|
||||
);
|
||||
assert.notStrictEqual(
|
||||
account.secret.slice(0, 3),
|
||||
'sEd',
|
||||
"sEd",
|
||||
`secp256k1 secret ${account.secret} must not start with 'sEd'`
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('generateAddress with algorithm `ed25519`', () => {
|
||||
it("generateAddress with algorithm `ed25519`", function () {
|
||||
// GIVEN we want to use 'ed25519'
|
||||
const options: GenerateAddressOptions = {algorithm: ECDSA.ed25519, includeClassicAddress: true}
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.ed25519,
|
||||
includeClassicAddress: true,
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get an object with an address starting with 'r' and a secret starting with 'sEd'
|
||||
assert(account.classicAddress.startsWith('r'), 'Address must start with `r`')
|
||||
assert(
|
||||
account.classicAddress?.startsWith("r"),
|
||||
"Address must start with `r`"
|
||||
);
|
||||
assert.deepEqual(
|
||||
account.secret.slice(0, 3),
|
||||
'sEd',
|
||||
"sEd",
|
||||
`Ed25519 secret ${account.secret} must start with 'sEd'`
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('generateAddress with algorithm `ecdsa-secp256k1` and given entropy', () => {
|
||||
// GIVEN we want to use 'ecdsa-secp256k1' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.secp256k1,
|
||||
entropy: new Array(16).fill(0)
|
||||
}
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, responses.generateXAddress)
|
||||
})
|
||||
|
||||
it('generateAddress with algorithm `ed25519` and given entropy', () => {
|
||||
// GIVEN we want to use 'ed25519' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.ed25519,
|
||||
entropy: new Array(16).fill(0)
|
||||
}
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, {
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: 'X7xq1YJ4xmLSGGLhuakFQB9CebWYthQkgsvFC4LGFH871HB',
|
||||
secret: 'sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE'
|
||||
})
|
||||
})
|
||||
|
||||
it('generateAddress with algorithm `ecdsa-secp256k1` and given entropy; include classic address', () => {
|
||||
it("generateAddress with algorithm `ecdsa-secp256k1` and given entropy", function () {
|
||||
// GIVEN we want to use 'ecdsa-secp256k1' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.secp256k1,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true
|
||||
}
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, responses.generateAddress)
|
||||
})
|
||||
assert.deepEqual(account, responses.generateXAddress);
|
||||
});
|
||||
|
||||
it('generateAddress with algorithm `ed25519` and given entropy; include classic address', () => {
|
||||
it("generateAddress with algorithm `ed25519` and given entropy", function () {
|
||||
// GIVEN we want to use 'ed25519' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.ed25519,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true
|
||||
}
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, {
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: 'X7xq1YJ4xmLSGGLhuakFQB9CebWYthQkgsvFC4LGFH871HB',
|
||||
xAddress: "X7xq1YJ4xmLSGGLhuakFQB9CebWYthQkgsvFC4LGFH871HB",
|
||||
secret: "sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE",
|
||||
});
|
||||
});
|
||||
|
||||
secret: 'sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE',
|
||||
classicAddress: 'r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7',
|
||||
address: 'r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7'
|
||||
})
|
||||
})
|
||||
|
||||
it('generateAddress with algorithm `ecdsa-secp256k1` and given entropy; include classic address; for test network use', () => {
|
||||
it("generateAddress with algorithm `ecdsa-secp256k1` and given entropy; include classic address", function () {
|
||||
// GIVEN we want to use 'ecdsa-secp256k1' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.secp256k1,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true,
|
||||
test: true
|
||||
}
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
const response = Object.assign({}, responses.generateAddress, {
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: 'TVG3TcCD58BD6MZqsNuTihdrhZwR8SzvYS8U87zvHsAcNw4'
|
||||
})
|
||||
assert.deepEqual(account, response)
|
||||
})
|
||||
assert.deepEqual(account, responses.generateAddress);
|
||||
});
|
||||
|
||||
it('generateAddress with algorithm `ed25519` and given entropy; include classic address; for test network use', () => {
|
||||
it("generateAddress with algorithm `ed25519` and given entropy; include classic address", function () {
|
||||
// GIVEN we want to use 'ed25519' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.ed25519,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true,
|
||||
test: true
|
||||
}
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, {
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: 'T7t4HeTMF5tT68agwuVbJwu23ssMPeh8dDtGysZoQiij1oo',
|
||||
secret: 'sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE',
|
||||
classicAddress: 'r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7',
|
||||
address: 'r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7'
|
||||
})
|
||||
})
|
||||
xAddress: "X7xq1YJ4xmLSGGLhuakFQB9CebWYthQkgsvFC4LGFH871HB",
|
||||
|
||||
it('generateAddress for test network use', () => {
|
||||
secret: "sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE",
|
||||
classicAddress: "r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7",
|
||||
address: "r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7",
|
||||
});
|
||||
});
|
||||
|
||||
it("generateAddress with algorithm `ecdsa-secp256k1` and given entropy; include classic address; for test network use", function () {
|
||||
// GIVEN we want to use 'ecdsa-secp256k1' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.secp256k1,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true,
|
||||
test: true,
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
const response = {
|
||||
...responses.generateAddress, // generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: "TVG3TcCD58BD6MZqsNuTihdrhZwR8SzvYS8U87zvHsAcNw4",
|
||||
};
|
||||
assert.deepEqual(account, response);
|
||||
});
|
||||
|
||||
it("generateAddress with algorithm `ed25519` and given entropy; include classic address; for test network use", function () {
|
||||
// GIVEN we want to use 'ed25519' with entropy of zero
|
||||
const options: GenerateAddressOptions = {
|
||||
algorithm: ECDSA.ed25519,
|
||||
entropy: new Array(16).fill(0),
|
||||
includeClassicAddress: true,
|
||||
test: true,
|
||||
};
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get the expected return value
|
||||
assert.deepEqual(account, {
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
xAddress: "T7t4HeTMF5tT68agwuVbJwu23ssMPeh8dDtGysZoQiij1oo",
|
||||
secret: "sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE",
|
||||
classicAddress: "r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7",
|
||||
address: "r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7",
|
||||
});
|
||||
});
|
||||
|
||||
it("generateAddress for test network use", function () {
|
||||
// GIVEN we want an address for test network use
|
||||
const options: GenerateAddressOptions = {test: true}
|
||||
const options: GenerateAddressOptions = { test: true };
|
||||
|
||||
// WHEN generating an address
|
||||
const account = generateXAddress(options)
|
||||
const account = generateXAddress(options);
|
||||
|
||||
// THEN we get an object with xAddress starting with 'T' and a secret starting with 's'
|
||||
|
||||
// generateAddress return value always includes xAddress to encourage X-address adoption
|
||||
assert.deepEqual(
|
||||
account.xAddress.slice(0, 1),
|
||||
'T',
|
||||
'Test addresses start with T'
|
||||
)
|
||||
"T",
|
||||
"Test addresses start with T"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
account.secret.slice(0, 1),
|
||||
's',
|
||||
"s",
|
||||
`Secret ${account.secret} must start with 's'`
|
||||
)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,161 +1,163 @@
|
||||
import assert from 'assert'
|
||||
import fs from 'fs'
|
||||
import assert from "assert";
|
||||
import fs from "fs";
|
||||
|
||||
import {
|
||||
computeStateTreeHash,
|
||||
computeTransactionTreeHash,
|
||||
computeAccountRootIndex,
|
||||
computeStateTreeHash,
|
||||
computeTransactionTreeHash,
|
||||
computeAccountRootIndex,
|
||||
computeTrustlineHash,
|
||||
computeOfferIndex,
|
||||
computeSignerListIndex,
|
||||
computeEscrowHash,
|
||||
computePaymentChannelHash
|
||||
} from '../../src/utils/hashes'
|
||||
computePaymentChannelHash,
|
||||
} from "../../src/utils/hashes";
|
||||
|
||||
/**
|
||||
* Expects a corresponding ledger dump in $repo/test/fixtures/rippled folder
|
||||
* Expects a corresponding ledger dump in $repo/test/fixtures/rippled folder.
|
||||
*
|
||||
* @param ledgerIndex
|
||||
*/
|
||||
function createLedgerTest(ledgerIndex: number) {
|
||||
describe(String(ledgerIndex), function () {
|
||||
var path =
|
||||
__dirname + '/../fixtures/rippled/ledgerFull' + ledgerIndex + '.json'
|
||||
const path = `${__dirname}/../fixtures/rippled/ledgerFull${ledgerIndex}.json`;
|
||||
|
||||
var ledgerRaw = fs.readFileSync(path, {encoding: 'utf8'})
|
||||
var ledgerJSON = JSON.parse(ledgerRaw)
|
||||
const ledgerRaw = fs.readFileSync(path, { encoding: "utf8" });
|
||||
const ledgerJSON = JSON.parse(ledgerRaw);
|
||||
|
||||
var hasAccounts =
|
||||
const hasAccounts =
|
||||
Array.isArray(ledgerJSON.accountState) &&
|
||||
ledgerJSON.accountState.length > 0
|
||||
ledgerJSON.accountState.length > 0;
|
||||
|
||||
if (hasAccounts) {
|
||||
it('has account_hash of ' + ledgerJSON.account_hash, function () {
|
||||
it(`has account_hash of ${ledgerJSON.account_hash}`, function () {
|
||||
assert.equal(
|
||||
ledgerJSON.account_hash,
|
||||
computeStateTreeHash(ledgerJSON.accountState)
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
it('has transaction_hash of ' + ledgerJSON.transaction_hash, function () {
|
||||
it(`has transaction_hash of ${ledgerJSON.transaction_hash}`, function () {
|
||||
assert.equal(
|
||||
ledgerJSON.transaction_hash,
|
||||
computeTransactionTreeHash(ledgerJSON.transactions)
|
||||
)
|
||||
})
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('Ledger', function () {
|
||||
describe("Ledger", function () {
|
||||
// This is the first recorded ledger with a non empty transaction set
|
||||
createLedgerTest(38129)
|
||||
createLedgerTest(38129);
|
||||
// Because, why not.
|
||||
createLedgerTest(40000)
|
||||
createLedgerTest(40000);
|
||||
// 1311 AffectedNodes, no accounts
|
||||
createLedgerTest(7501326)
|
||||
createLedgerTest(7501326);
|
||||
|
||||
describe('calcAccountRootEntryHash', function () {
|
||||
it('will calculate the AccountRoot entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function () {
|
||||
var account = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
var expectedEntryHash =
|
||||
'2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8'
|
||||
var actualEntryHash = computeAccountRootIndex(account)
|
||||
describe("calcAccountRootEntryHash", function () {
|
||||
it("will calculate the AccountRoot entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", function () {
|
||||
const account = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
const expectedEntryHash =
|
||||
"2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8";
|
||||
const actualEntryHash = computeAccountRootIndex(account);
|
||||
|
||||
assert.equal(actualEntryHash, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
assert.equal(actualEntryHash, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calcRippleStateEntryHash', function () {
|
||||
it('will calculate the RippleState entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh and rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY in USD', function () {
|
||||
var account1 = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
var account2 = 'rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY'
|
||||
var currency = 'USD'
|
||||
describe("calcRippleStateEntryHash", function () {
|
||||
it("will calculate the RippleState entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh and rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY in USD", function () {
|
||||
const account1 = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
const account2 = "rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY";
|
||||
const currency = "USD";
|
||||
|
||||
var expectedEntryHash =
|
||||
'C683B5BB928F025F1E860D9D69D6C554C2202DE0D45877ADB3077DA4CB9E125C'
|
||||
var actualEntryHash1 = computeTrustlineHash(
|
||||
const expectedEntryHash =
|
||||
"C683B5BB928F025F1E860D9D69D6C554C2202DE0D45877ADB3077DA4CB9E125C";
|
||||
const actualEntryHash1 = computeTrustlineHash(
|
||||
account1,
|
||||
account2,
|
||||
currency
|
||||
)
|
||||
var actualEntryHash2 = computeTrustlineHash(
|
||||
);
|
||||
const actualEntryHash2 = computeTrustlineHash(
|
||||
account2,
|
||||
account1,
|
||||
currency
|
||||
)
|
||||
);
|
||||
|
||||
assert.equal(actualEntryHash1, expectedEntryHash)
|
||||
assert.equal(actualEntryHash2, expectedEntryHash)
|
||||
})
|
||||
assert.equal(actualEntryHash1, expectedEntryHash);
|
||||
assert.equal(actualEntryHash2, expectedEntryHash);
|
||||
});
|
||||
|
||||
it('will calculate the RippleState entry hash for r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV and rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj in UAM', function () {
|
||||
var account1 = 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV'
|
||||
var account2 = 'rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj'
|
||||
var currency = 'UAM'
|
||||
it("will calculate the RippleState entry hash for r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV and rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj in UAM", function () {
|
||||
const account1 = "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV";
|
||||
const account2 = "rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj";
|
||||
const currency = "UAM";
|
||||
|
||||
var expectedEntryHash =
|
||||
'AE9ADDC584358E5847ADFC971834E471436FC3E9DE6EA1773DF49F419DC0F65E'
|
||||
var actualEntryHash1 = computeTrustlineHash(
|
||||
const expectedEntryHash =
|
||||
"AE9ADDC584358E5847ADFC971834E471436FC3E9DE6EA1773DF49F419DC0F65E";
|
||||
const actualEntryHash1 = computeTrustlineHash(
|
||||
account1,
|
||||
account2,
|
||||
currency
|
||||
)
|
||||
var actualEntryHash2 = computeTrustlineHash(
|
||||
);
|
||||
const actualEntryHash2 = computeTrustlineHash(
|
||||
account2,
|
||||
account1,
|
||||
currency
|
||||
)
|
||||
);
|
||||
|
||||
assert.equal(actualEntryHash1, expectedEntryHash)
|
||||
assert.equal(actualEntryHash2, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
assert.equal(actualEntryHash1, expectedEntryHash);
|
||||
assert.equal(actualEntryHash2, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calcOfferEntryHash', function () {
|
||||
it('will calculate the Offer entry hash for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw, sequence 137', function () {
|
||||
var account = 'r32UufnaCGL82HubijgJGDmdE5hac7ZvLw'
|
||||
var sequence = 137
|
||||
var expectedEntryHash =
|
||||
'03F0AED09DEEE74CEF85CD57A0429D6113507CF759C597BABB4ADB752F734CE3'
|
||||
var actualEntryHash = computeOfferIndex(account, sequence)
|
||||
describe("calcOfferEntryHash", function () {
|
||||
it("will calculate the Offer entry hash for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw, sequence 137", function () {
|
||||
const account = "r32UufnaCGL82HubijgJGDmdE5hac7ZvLw";
|
||||
const sequence = 137;
|
||||
const expectedEntryHash =
|
||||
"03F0AED09DEEE74CEF85CD57A0429D6113507CF759C597BABB4ADB752F734CE3";
|
||||
const actualEntryHash = computeOfferIndex(account, sequence);
|
||||
|
||||
assert.equal(actualEntryHash, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
assert.equal(actualEntryHash, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
|
||||
describe('computeSignerListIndex', function () {
|
||||
it('will calculate the SignerList index for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw', function () {
|
||||
var account = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'
|
||||
var expectedEntryHash =
|
||||
'778365D5180F5DF3016817D1F318527AD7410D83F8636CF48C43E8AF72AB49BF'
|
||||
var actualEntryHash = computeSignerListIndex(account)
|
||||
assert.equal(actualEntryHash, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
describe("computeSignerListIndex", function () {
|
||||
it("will calculate the SignerList index for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw", function () {
|
||||
const account = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
const expectedEntryHash =
|
||||
"778365D5180F5DF3016817D1F318527AD7410D83F8636CF48C43E8AF72AB49BF";
|
||||
const actualEntryHash = computeSignerListIndex(account);
|
||||
assert.equal(actualEntryHash, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calcEscrowEntryHash', function () {
|
||||
it('will calculate the Escrow entry hash for rDx69ebzbowuqztksVDmZXjizTd12BVr4x, sequence 84', function () {
|
||||
var account = 'rDx69ebzbowuqztksVDmZXjizTd12BVr4x'
|
||||
var sequence = 84
|
||||
var expectedEntryHash =
|
||||
'61E8E8ED53FA2CEBE192B23897071E9A75217BF5A410E9CB5B45AAB7AECA567A'
|
||||
var actualEntryHash = computeEscrowHash(account, sequence)
|
||||
describe("calcEscrowEntryHash", function () {
|
||||
it("will calculate the Escrow entry hash for rDx69ebzbowuqztksVDmZXjizTd12BVr4x, sequence 84", function () {
|
||||
const account = "rDx69ebzbowuqztksVDmZXjizTd12BVr4x";
|
||||
const sequence = 84;
|
||||
const expectedEntryHash =
|
||||
"61E8E8ED53FA2CEBE192B23897071E9A75217BF5A410E9CB5B45AAB7AECA567A";
|
||||
const actualEntryHash = computeEscrowHash(account, sequence);
|
||||
|
||||
assert.equal(actualEntryHash, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
assert.equal(actualEntryHash, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calcPaymentChannelEntryHash', function () {
|
||||
it('will calculate the PaymentChannel entry hash for rDx69ebzbowuqztksVDmZXjizTd12BVr4x and rLFtVprxUEfsH54eCWKsZrEQzMDsx1wqso, sequence 82', function () {
|
||||
var account = 'rDx69ebzbowuqztksVDmZXjizTd12BVr4x'
|
||||
var dstAccount = 'rLFtVprxUEfsH54eCWKsZrEQzMDsx1wqso'
|
||||
var sequence = 82
|
||||
var expectedEntryHash =
|
||||
'E35708503B3C3143FB522D749AAFCC296E8060F0FB371A9A56FAE0B1ED127366'
|
||||
var actualEntryHash = computePaymentChannelHash(
|
||||
describe("calcPaymentChannelEntryHash", function () {
|
||||
it("will calculate the PaymentChannel entry hash for rDx69ebzbowuqztksVDmZXjizTd12BVr4x and rLFtVprxUEfsH54eCWKsZrEQzMDsx1wqso, sequence 82", function () {
|
||||
const account = "rDx69ebzbowuqztksVDmZXjizTd12BVr4x";
|
||||
const dstAccount = "rLFtVprxUEfsH54eCWKsZrEQzMDsx1wqso";
|
||||
const sequence = 82;
|
||||
const expectedEntryHash =
|
||||
"E35708503B3C3143FB522D749AAFCC296E8060F0FB371A9A56FAE0B1ED127366";
|
||||
const actualEntryHash = computePaymentChannelHash(
|
||||
account,
|
||||
dstAccount,
|
||||
sequence
|
||||
)
|
||||
);
|
||||
|
||||
assert.equal(actualEntryHash, expectedEntryHash)
|
||||
})
|
||||
})
|
||||
})
|
||||
assert.equal(actualEntryHash, expectedEntryHash);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
import {assertResultMatch} from '../testUtils'
|
||||
import responses from '../fixtures/responses'
|
||||
import signPaymentChannelClaim from '../../src/utils/signPaymentChannelClaim'
|
||||
import signPaymentChannelClaim from "../../src/utils/signPaymentChannelClaim";
|
||||
import responses from "../fixtures/responses";
|
||||
import { assertResultMatch } from "../testUtils";
|
||||
|
||||
describe("signPaymentChannelClaim", function () {
|
||||
it("basic signature matches", function () {
|
||||
const channel =
|
||||
"3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037";
|
||||
const amount = ".00001";
|
||||
const privateKey =
|
||||
"ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A";
|
||||
|
||||
const result = signPaymentChannelClaim(channel, amount, privateKey);
|
||||
|
||||
describe('signPaymentChannelClaim', function () {
|
||||
it('basic signature matches', () => {
|
||||
|
||||
const channel = "3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037"
|
||||
const amount = ".00001"
|
||||
const privateKey = 'ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A'
|
||||
|
||||
const result = signPaymentChannelClaim(
|
||||
channel,
|
||||
amount,
|
||||
privateKey
|
||||
)
|
||||
|
||||
assertResultMatch(
|
||||
result,
|
||||
responses.signPaymentChannelClaim,
|
||||
'signPaymentChannelClaim'
|
||||
)
|
||||
})
|
||||
})
|
||||
"signPaymentChannelClaim"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import {verifyPaymentChannelClaim} from '../../src'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
import {assertResultMatch} from '../testUtils'
|
||||
import { verifyPaymentChannelClaim } from "../../src";
|
||||
import requests from "../fixtures/requests";
|
||||
import responses from "../fixtures/responses";
|
||||
import { assertResultMatch } from "../testUtils";
|
||||
|
||||
describe('Verify Payment Channel Claim', function () {
|
||||
it('basic verification works', () => {
|
||||
describe("Verify Payment Channel Claim", function () {
|
||||
it("basic verification works", function () {
|
||||
const publicKey =
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8";
|
||||
const result = verifyPaymentChannelClaim(
|
||||
requests.signPaymentChannelClaim.channel,
|
||||
requests.signPaymentChannelClaim.amount,
|
||||
responses.signPaymentChannelClaim,
|
||||
publicKey
|
||||
)
|
||||
assertResultMatch(result, true, 'verifyPaymentChannelClaim')
|
||||
})
|
||||
);
|
||||
assertResultMatch(result, true, "verifyPaymentChannelClaim");
|
||||
});
|
||||
|
||||
it('invalid payment channel claim fails', () => {
|
||||
it("invalid payment channel claim fails", function () {
|
||||
const publicKey =
|
||||
'03A6523FE4281DA48A6FD77FAF3CB77F5C7001ABA0B32BCEDE0369AC009758D7D9'
|
||||
"03A6523FE4281DA48A6FD77FAF3CB77F5C7001ABA0B32BCEDE0369AC009758D7D9";
|
||||
const result = verifyPaymentChannelClaim(
|
||||
requests.signPaymentChannelClaim.channel,
|
||||
requests.signPaymentChannelClaim.amount,
|
||||
responses.signPaymentChannelClaim,
|
||||
publicKey
|
||||
)
|
||||
assertResultMatch(result, false, 'verifyPaymentChannelClaim')
|
||||
})
|
||||
})
|
||||
);
|
||||
assertResultMatch(result, false, "verifyPaymentChannelClaim");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,108 +1,109 @@
|
||||
import assert from 'assert-diff'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {xrpToDrops} from '../../src/utils'
|
||||
import assert from "assert-diff";
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
describe('XRP To Drops', function () {
|
||||
it('works with a typical amount', () => {
|
||||
const drops = xrpToDrops('2')
|
||||
assert.strictEqual(drops, '2000000', '2 XRP equals 2 million drops')
|
||||
})
|
||||
import { xrpToDrops } from "../../src/utils";
|
||||
|
||||
it('works with fractions', () => {
|
||||
let drops = xrpToDrops('3.456789')
|
||||
assert.strictEqual(drops, '3456789', '3.456789 XRP equals 3,456,789 drops')
|
||||
drops = xrpToDrops('3.400000')
|
||||
assert.strictEqual(drops, '3400000', '3.400000 XRP equals 3,400,000 drops')
|
||||
drops = xrpToDrops('0.000001')
|
||||
assert.strictEqual(drops, '1', '0.000001 XRP equals 1 drop')
|
||||
drops = xrpToDrops('0.0000010')
|
||||
assert.strictEqual(drops, '1', '0.0000010 XRP equals 1 drop')
|
||||
})
|
||||
describe("XRP To Drops", function () {
|
||||
it("works with a typical amount", function () {
|
||||
const drops = xrpToDrops("2");
|
||||
assert.strictEqual(drops, "2000000", "2 XRP equals 2 million drops");
|
||||
});
|
||||
|
||||
it('works with zero', () => {
|
||||
let drops = xrpToDrops('0')
|
||||
assert.strictEqual(drops, '0', '0 XRP equals 0 drops')
|
||||
drops = xrpToDrops('-0') // negative zero is equivalent to zero
|
||||
assert.strictEqual(drops, '0', '-0 XRP equals 0 drops')
|
||||
drops = xrpToDrops('0.000000')
|
||||
assert.strictEqual(drops, '0', '0.000000 XRP equals 0 drops')
|
||||
drops = xrpToDrops('0.0000000')
|
||||
assert.strictEqual(drops, '0', '0.0000000 XRP equals 0 drops')
|
||||
})
|
||||
it("works with fractions", function () {
|
||||
let drops = xrpToDrops("3.456789");
|
||||
assert.strictEqual(drops, "3456789", "3.456789 XRP equals 3,456,789 drops");
|
||||
drops = xrpToDrops("3.400000");
|
||||
assert.strictEqual(drops, "3400000", "3.400000 XRP equals 3,400,000 drops");
|
||||
drops = xrpToDrops("0.000001");
|
||||
assert.strictEqual(drops, "1", "0.000001 XRP equals 1 drop");
|
||||
drops = xrpToDrops("0.0000010");
|
||||
assert.strictEqual(drops, "1", "0.0000010 XRP equals 1 drop");
|
||||
});
|
||||
|
||||
it('works with a negative value', () => {
|
||||
const drops = xrpToDrops('-2')
|
||||
assert.strictEqual(drops, '-2000000', '-2 XRP equals -2 million drops')
|
||||
})
|
||||
it("works with zero", function () {
|
||||
let drops = xrpToDrops("0");
|
||||
assert.strictEqual(drops, "0", "0 XRP equals 0 drops");
|
||||
drops = xrpToDrops("-0"); // negative zero is equivalent to zero
|
||||
assert.strictEqual(drops, "0", "-0 XRP equals 0 drops");
|
||||
drops = xrpToDrops("0.000000");
|
||||
assert.strictEqual(drops, "0", "0.000000 XRP equals 0 drops");
|
||||
drops = xrpToDrops("0.0000000");
|
||||
assert.strictEqual(drops, "0", "0.0000000 XRP equals 0 drops");
|
||||
});
|
||||
|
||||
it('works with a value ending with a decimal point', () => {
|
||||
let drops = xrpToDrops('2.')
|
||||
assert.strictEqual(drops, '2000000', '2. XRP equals 2000000 drops')
|
||||
drops = xrpToDrops('-2.')
|
||||
assert.strictEqual(drops, '-2000000', '-2. XRP equals -2000000 drops')
|
||||
})
|
||||
it("works with a negative value", function () {
|
||||
const drops = xrpToDrops("-2");
|
||||
assert.strictEqual(drops, "-2000000", "-2 XRP equals -2 million drops");
|
||||
});
|
||||
|
||||
it('works with BigNumber objects', () => {
|
||||
let drops = xrpToDrops(new BigNumber(2))
|
||||
it("works with a value ending with a decimal point", function () {
|
||||
let drops = xrpToDrops("2.");
|
||||
assert.strictEqual(drops, "2000000", "2. XRP equals 2000000 drops");
|
||||
drops = xrpToDrops("-2.");
|
||||
assert.strictEqual(drops, "-2000000", "-2. XRP equals -2000000 drops");
|
||||
});
|
||||
|
||||
it("works with BigNumber objects", function () {
|
||||
let drops = xrpToDrops(new BigNumber(2));
|
||||
assert.strictEqual(
|
||||
drops,
|
||||
'2000000',
|
||||
'(BigNumber) 2 XRP equals 2 million drops'
|
||||
)
|
||||
drops = xrpToDrops(new BigNumber(-2))
|
||||
"2000000",
|
||||
"(BigNumber) 2 XRP equals 2 million drops"
|
||||
);
|
||||
drops = xrpToDrops(new BigNumber(-2));
|
||||
assert.strictEqual(
|
||||
drops,
|
||||
'-2000000',
|
||||
'(BigNumber) -2 XRP equals -2 million drops'
|
||||
)
|
||||
})
|
||||
"-2000000",
|
||||
"(BigNumber) -2 XRP equals -2 million drops"
|
||||
);
|
||||
});
|
||||
|
||||
it('works with a number', () => {
|
||||
it("works with a number", function () {
|
||||
// This is not recommended. Use strings or BigNumber objects to avoid precision errors.
|
||||
let drops = xrpToDrops(2)
|
||||
let drops = xrpToDrops(2);
|
||||
assert.strictEqual(
|
||||
drops,
|
||||
'2000000',
|
||||
'(number) 2 XRP equals 2 million drops'
|
||||
)
|
||||
drops = xrpToDrops(-2)
|
||||
"2000000",
|
||||
"(number) 2 XRP equals 2 million drops"
|
||||
);
|
||||
drops = xrpToDrops(-2);
|
||||
assert.strictEqual(
|
||||
drops,
|
||||
'-2000000',
|
||||
'(number) -2 XRP equals -2 million drops'
|
||||
)
|
||||
})
|
||||
"-2000000",
|
||||
"(number) -2 XRP equals -2 million drops"
|
||||
);
|
||||
});
|
||||
|
||||
it('throws with an amount with too many decimal places', () => {
|
||||
it("throws with an amount with too many decimal places", function () {
|
||||
assert.throws(() => {
|
||||
xrpToDrops('1.1234567')
|
||||
}, /has too many decimal places/)
|
||||
xrpToDrops("1.1234567");
|
||||
}, /has too many decimal places/);
|
||||
assert.throws(() => {
|
||||
xrpToDrops('0.0000001')
|
||||
}, /has too many decimal places/)
|
||||
})
|
||||
xrpToDrops("0.0000001");
|
||||
}, /has too many decimal places/);
|
||||
});
|
||||
|
||||
it('throws with an invalid value', () => {
|
||||
it("throws with an invalid value", function () {
|
||||
assert.throws(() => {
|
||||
xrpToDrops('FOO')
|
||||
}, /invalid value/)
|
||||
xrpToDrops("FOO");
|
||||
}, /invalid value/);
|
||||
assert.throws(() => {
|
||||
xrpToDrops('1e-7')
|
||||
}, /invalid value/)
|
||||
xrpToDrops("1e-7");
|
||||
}, /invalid value/);
|
||||
assert.throws(() => {
|
||||
xrpToDrops('2,0')
|
||||
}, /invalid value/)
|
||||
xrpToDrops("2,0");
|
||||
}, /invalid value/);
|
||||
assert.throws(() => {
|
||||
xrpToDrops('.')
|
||||
}, /xrpToDrops: invalid value '\.', should be a BigNumber or string-encoded number\./)
|
||||
})
|
||||
xrpToDrops(".");
|
||||
}, /xrpToDrops: invalid value '\.', should be a BigNumber or string-encoded number\./);
|
||||
});
|
||||
|
||||
it('throws with an amount more than one decimal point', () => {
|
||||
it("throws with an amount more than one decimal point", function () {
|
||||
assert.throws(() => {
|
||||
xrpToDrops('1.0.0')
|
||||
}, /xrpToDrops: invalid value '1\.0\.0'/)
|
||||
xrpToDrops("1.0.0");
|
||||
}, /xrpToDrops: invalid value '1\.0\.0'/);
|
||||
assert.throws(() => {
|
||||
xrpToDrops('...')
|
||||
}, /xrpToDrops: invalid value '\.\.\.'/)
|
||||
})
|
||||
})
|
||||
xrpToDrops("...");
|
||||
}, /xrpToDrops: invalid value '\.\.\.'/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import ECDSA from '../../src/common/ecdsa'
|
||||
import Wallet from '../../src/Wallet'
|
||||
import assert from "assert-diff";
|
||||
|
||||
const entropy: number[] = new Array(16).fill(0)
|
||||
const publicKey: string =
|
||||
'0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284'
|
||||
const privateKey: string =
|
||||
'002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665'
|
||||
const publicKeyED25519: string =
|
||||
'ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F'
|
||||
const privateKeyED25519: string =
|
||||
'ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D'
|
||||
import ECDSA from "../../src/common/ecdsa";
|
||||
import Wallet from "../../src/Wallet";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
const entropy: number[] = new Array(16).fill(0);
|
||||
const publicKey =
|
||||
"0390A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284";
|
||||
const privateKey =
|
||||
"002512BBDFDBB77510883B7DCCBEF270B86DEAC8B64AC762873D75A1BEE6298665";
|
||||
const publicKeyED25519 =
|
||||
"ED1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F";
|
||||
const privateKeyED25519 =
|
||||
"ED0B6CBAC838DFE7F47EA1BD0DF00EC282FDF45510C92161072CCFB84035390C4D";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -19,36 +20,36 @@ const privateKeyED25519: string =
|
||||
* - Check out "test/api/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'Wallet.fromEntropy with entropy only': async (api) => {
|
||||
"Wallet.fromEntropy with entropy only": async (api) => {
|
||||
// WHEN deriving a wallet from an entropy
|
||||
const wallet = Wallet.fromEntropy(entropy)
|
||||
const wallet = Wallet.fromEntropy(entropy);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKeyED25519)
|
||||
assert.equal(wallet.privateKey, privateKeyED25519)
|
||||
assert.equal(wallet.publicKey, publicKeyED25519);
|
||||
assert.equal(wallet.privateKey, privateKeyED25519);
|
||||
},
|
||||
|
||||
'Wallet.fromEntropy with algorithm ecdsa-secp256k1': async (api) => {
|
||||
"Wallet.fromEntropy with algorithm ecdsa-secp256k1": async (api) => {
|
||||
// GIVEN an entropy using ecdsa-secp256k1
|
||||
const algorithm = ECDSA.secp256k1
|
||||
const algorithm = ECDSA.secp256k1;
|
||||
|
||||
// WHEN deriving a wallet from an entropy
|
||||
const wallet = Wallet.fromEntropy(entropy, algorithm)
|
||||
const wallet = Wallet.fromEntropy(entropy, algorithm);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
|
||||
'Wallet.fromEntropy with algorithm ed25519': async (api) => {
|
||||
"Wallet.fromEntropy with algorithm ed25519": async (api) => {
|
||||
// GIVEN an entropy using ed25519
|
||||
const algorithm = ECDSA.ed25519
|
||||
const algorithm = ECDSA.ed25519;
|
||||
|
||||
// WHEN deriving a wallet from an entropy
|
||||
const wallet = Wallet.fromEntropy(entropy, algorithm)
|
||||
const wallet = Wallet.fromEntropy(entropy, algorithm);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKeyED25519)
|
||||
assert.equal(wallet.privateKey, privateKeyED25519)
|
||||
assert.equal(wallet.publicKey, publicKeyED25519);
|
||||
assert.equal(wallet.privateKey, privateKeyED25519);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import Wallet from '../../src/Wallet'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import Wallet from "../../src/Wallet";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
const mnemonic =
|
||||
'try milk link drift aware pass obtain again music stick pluck fold'
|
||||
"try milk link drift aware pass obtain again music stick pluck fold";
|
||||
const publicKey =
|
||||
'0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6'
|
||||
"0257B550BA2FDCCF0ADDA3DEB2A5411700F3ADFDCC7C68E1DCD1E2B63E6B0C63E6";
|
||||
const privateKey =
|
||||
'008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3'
|
||||
"008F942B6E229C0E9CEE47E7A94253DABB6A9855F4BA2D8A741FA31851A1D423C3";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -15,25 +16,25 @@ const privateKey =
|
||||
* - Check out "test/api/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'Wallet.fromMnemonic using default derivation path': async (api) => {
|
||||
"Wallet.fromMnemonic using default derivation path": async (api) => {
|
||||
// GIVEN no derivation path
|
||||
// WHEN deriving a wallet from a mnemonic without a derivation path
|
||||
const wallet = Wallet.fromMnemonic(mnemonic)
|
||||
const wallet = Wallet.fromMnemonic(mnemonic);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
|
||||
'Wallet.fromMnemonic using an input derivation path': async (api) => {
|
||||
"Wallet.fromMnemonic using an input derivation path": async (api) => {
|
||||
// GIVEN a derivation path
|
||||
const derivationPath = "m/44'/144'/0'/0/0"
|
||||
const derivationPath = "m/44'/144'/0'/0/0";
|
||||
|
||||
// WHEN deriving a wallet from a mnemonic without a derivation path
|
||||
const wallet = Wallet.fromMnemonic(mnemonic, derivationPath)
|
||||
const wallet = Wallet.fromMnemonic(mnemonic, derivationPath);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import ECDSA from '../../src/common/ecdsa'
|
||||
import Wallet from '../../src/Wallet'
|
||||
import assert from "assert-diff";
|
||||
|
||||
const seed = 'ssL9dv2W5RK8L3tuzQxYY6EaZhSxW'
|
||||
import ECDSA from "../../src/common/ecdsa";
|
||||
import Wallet from "../../src/Wallet";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
const seed = "ssL9dv2W5RK8L3tuzQxYY6EaZhSxW";
|
||||
const publicKey =
|
||||
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D'
|
||||
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
|
||||
const privateKey =
|
||||
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
|
||||
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -15,36 +16,36 @@ const privateKey =
|
||||
* - Check out "test/api/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'Wallet.fromSeed with empty options object': async (api) => {
|
||||
"Wallet.fromSeed with empty options object": async (api) => {
|
||||
// WHEN deriving a wallet from a seed
|
||||
const wallet = Wallet.fromSeed(seed)
|
||||
const wallet = Wallet.fromSeed(seed);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
|
||||
'Wallet.fromSeed with algorithm ecdsa-secp256k1': async (api) => {
|
||||
"Wallet.fromSeed with algorithm ecdsa-secp256k1": async (api) => {
|
||||
// GIVEN we want to use ecdsa-secp256k1
|
||||
const algorithm = ECDSA.secp256k1
|
||||
const algorithm = ECDSA.secp256k1;
|
||||
|
||||
// WHEN deriving a wallet from a seed
|
||||
const wallet = Wallet.fromSeed(seed, algorithm)
|
||||
const wallet = Wallet.fromSeed(seed, algorithm);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
|
||||
'Wallet.fromSeed with algorithm ed25519': async (api) => {
|
||||
"Wallet.fromSeed with algorithm ed25519": async (api) => {
|
||||
// GIVEN we want to use ed25519
|
||||
const algorithm = ECDSA.ed25519
|
||||
const algorithm = ECDSA.ed25519;
|
||||
|
||||
// WHEN deriving a wallet from a seed
|
||||
const wallet = Wallet.fromSeed(seed, algorithm)
|
||||
const wallet = Wallet.fromSeed(seed, algorithm);
|
||||
|
||||
// THEN we get a wallet with a keypair (publicKey/privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey)
|
||||
assert.equal(wallet.privateKey, privateKey)
|
||||
assert.equal(wallet.publicKey, publicKey);
|
||||
assert.equal(wallet.privateKey, privateKey);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {TestSuite} from '../testUtils'
|
||||
import Wallet from '../../src/Wallet'
|
||||
import * as schemaValidator from 'xrpl-local/common/schema-validator'
|
||||
import * as schemaValidator from "xrpl-local/common/schema-validator";
|
||||
|
||||
import Wallet from "../../src/Wallet";
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
const publicKey =
|
||||
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D'
|
||||
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
|
||||
const privateKey =
|
||||
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
|
||||
const address = 'rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc'
|
||||
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
|
||||
const address = "rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc";
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -14,24 +15,24 @@ const address = 'rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc'
|
||||
* - Check out "test/api/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'sign transaction offline with txJSON': async (api) => {
|
||||
"sign transaction offline with txJSON": async (api) => {
|
||||
// GIVEN a transaction
|
||||
const txJSON = {
|
||||
TransactionType: 'Payment',
|
||||
TransactionType: "Payment",
|
||||
Account: address,
|
||||
Destination: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r',
|
||||
Amount: '20000000',
|
||||
Destination: "rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r",
|
||||
Amount: "20000000",
|
||||
Sequence: 1,
|
||||
Fee: '12',
|
||||
SigningPubKey: publicKey
|
||||
}
|
||||
const wallet = new Wallet(publicKey, privateKey)
|
||||
Fee: "12",
|
||||
SigningPubKey: publicKey,
|
||||
};
|
||||
const wallet = new Wallet(publicKey, privateKey);
|
||||
|
||||
// WHEN signing a transaction offline
|
||||
const signedTx: {signedTransaction: string; id: string} =
|
||||
wallet.signTransaction(txJSON)
|
||||
const signedTx: { signedTransaction: string; id: string } =
|
||||
wallet.signTransaction(txJSON);
|
||||
|
||||
// THEN we get a signedTransaction
|
||||
schemaValidator.schemaValidate('sign', signedTx)
|
||||
schemaValidator.schemaValidate("sign", signedTx);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import assert from 'assert-diff'
|
||||
import {TestSuite} from '../testUtils'
|
||||
import Wallet from 'xrpl-local/Wallet'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import Wallet from "xrpl-local/Wallet";
|
||||
|
||||
import { TestSuite } from "../testUtils";
|
||||
|
||||
const publicKey =
|
||||
'030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D'
|
||||
"030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D";
|
||||
const privateKey =
|
||||
'00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F'
|
||||
"00141BA006D3363D2FB2785E8DF4E44D3A49908780CB4FB51F6D217C08C021429F";
|
||||
const prepared = {
|
||||
signedTransaction:
|
||||
'1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648',
|
||||
id: '30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A'
|
||||
}
|
||||
"1200002400000001614000000001312D0068400000000000000C7321030E58CDD076E798C84755590AAF6237CA8FAE821070A59F648B517A30DC6F589D74473045022100CAF99A63B241F5F62B456C68A593D2835397101533BB5D0C4DC17362AC22046F022016A2CA2CF56E777B10E43B56541A4C2FB553E7E298CDD39F7A8A844DA491E51D81142AF1861DEC1316AEEC995C94FF9E2165B1B784608314FDB08D07AAA0EB711793A3027304D688E10C3648",
|
||||
id: "30D9ECA2A7FB568C5A8607E5850D9567572A9E7C6094C26BEFD4DC4C2CF2657A",
|
||||
};
|
||||
|
||||
/**
|
||||
* Every test suite exports their tests in the default object.
|
||||
@@ -18,29 +20,37 @@ const prepared = {
|
||||
* - Check out "test/api/index.ts" for more information about the test runner.
|
||||
*/
|
||||
export default <TestSuite>{
|
||||
'verify transaction offline when a signed transaction is valid': async (api) => {
|
||||
"verify transaction offline when a signed transaction is valid": async (
|
||||
api
|
||||
) => {
|
||||
// GIVEN a transaction that has been signed by the same wallet
|
||||
const wallet = new Wallet(publicKey, privateKey)
|
||||
const wallet = new Wallet(publicKey, privateKey);
|
||||
|
||||
// WHEN verifying a signed transaction
|
||||
const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction)
|
||||
const isVerified: boolean = wallet.verifyTransaction(
|
||||
prepared.signedTransaction
|
||||
);
|
||||
|
||||
// THEN we get a valid response
|
||||
assert.equal(isVerified, true)
|
||||
assert.equal(isVerified, true);
|
||||
},
|
||||
|
||||
"verify transaction offline when signed transaction isn't valid": async (api) => {
|
||||
"verify transaction offline when signed transaction isn't valid": async (
|
||||
api
|
||||
) => {
|
||||
// GIVEN a transaction that has been signed by a different wallet
|
||||
const diffPublicKey =
|
||||
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8";
|
||||
const diffPrivateKey =
|
||||
'00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A'
|
||||
const wallet = new Wallet(diffPublicKey, diffPrivateKey)
|
||||
"00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A";
|
||||
const wallet = new Wallet(diffPublicKey, diffPrivateKey);
|
||||
|
||||
// WHEN verifying a signed transaction
|
||||
const isVerified: boolean = wallet.verifyTransaction(prepared.signedTransaction)
|
||||
const isVerified: boolean = wallet.verifyTransaction(
|
||||
prepared.signedTransaction
|
||||
);
|
||||
|
||||
// THEN we get an invalid response
|
||||
assert.equal(isVerified, false)
|
||||
assert.equal(isVerified, false);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
import assert from 'assert-diff'
|
||||
import assert from "assert-diff";
|
||||
|
||||
import setupClient from './setupClient'
|
||||
import {getFaucetUrl, FaucetNetwork} from '../src/wallet/wallet-generation'
|
||||
import { getFaucetUrl, FaucetNetwork } from "../src/wallet/wallet-generation";
|
||||
|
||||
describe('Get Faucet URL', function () {
|
||||
beforeEach(setupClient.setup)
|
||||
afterEach(setupClient.teardown)
|
||||
import setupClient from "./setupClient";
|
||||
|
||||
it('returns the Devnet URL', function () {
|
||||
const expectedFaucet = FaucetNetwork.Devnet
|
||||
this.client.connection._url = FaucetNetwork.Devnet
|
||||
describe("Get Faucet URL", function () {
|
||||
beforeEach(setupClient.setup);
|
||||
afterEach(setupClient.teardown);
|
||||
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet)
|
||||
})
|
||||
it("returns the Devnet URL", function () {
|
||||
const expectedFaucet = FaucetNetwork.Devnet;
|
||||
this.client.connection._url = FaucetNetwork.Devnet;
|
||||
|
||||
it('returns the Testnet URL', function () {
|
||||
const expectedFaucet = FaucetNetwork.Testnet
|
||||
this.client.connection._url = FaucetNetwork.Testnet
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet);
|
||||
});
|
||||
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet)
|
||||
})
|
||||
it("returns the Testnet URL", function () {
|
||||
const expectedFaucet = FaucetNetwork.Testnet;
|
||||
this.client.connection._url = FaucetNetwork.Testnet;
|
||||
|
||||
it('returns the Testnet URL with the XRPL Labs server', function () {
|
||||
const expectedFaucet = FaucetNetwork.Testnet
|
||||
this.client.connection._url = 'wss://testnet.xrpl-labs.com'
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet);
|
||||
});
|
||||
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet)
|
||||
})
|
||||
it("returns the Testnet URL with the XRPL Labs server", function () {
|
||||
const expectedFaucet = FaucetNetwork.Testnet;
|
||||
this.client.connection._url = "wss://testnet.xrpl-labs.com";
|
||||
|
||||
it('returns undefined if not a Testnet or Devnet server URL', function () {
|
||||
assert.strictEqual(getFaucetUrl(this.client), expectedFaucet);
|
||||
});
|
||||
|
||||
it("returns undefined if not a Testnet or Devnet server URL", function () {
|
||||
// Info: setupClient.setup creates a connection to 'localhost'
|
||||
assert.strictEqual(getFaucetUrl(this.client), undefined)
|
||||
})
|
||||
})
|
||||
assert.strictEqual(getFaucetUrl(this.client), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user