mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-06 17:27:59 +00:00
Compare commits
4 Commits
nn/blitz
...
mv/broadca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44e860f617 | ||
|
|
14d8753c15 | ||
|
|
90dae91fb9 | ||
|
|
537401e161 |
12
package-lock.json
generated
12
package-lock.json
generated
@@ -7677,9 +7677,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.2.5",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.5.tgz",
|
||||
"integrity": "sha512-al/ATFEffybdRMUIr5zMEWQdVnCGMUA9d3fXJ8dBVvBlzytPvIszoG9kZoR+94k6/i293RnVOXwMaWbXhNy9pQ==",
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
@@ -14384,9 +14384,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.2.5",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.5.tgz",
|
||||
"integrity": "sha512-al/ATFEffybdRMUIr5zMEWQdVnCGMUA9d3fXJ8dBVvBlzytPvIszoG9kZoR+94k6/i293RnVOXwMaWbXhNy9pQ==",
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
|
||||
@@ -16,9 +16,7 @@ describe('BroadcastClient', function () {
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
this.mocks.forEach((mock) => {
|
||||
mock.addResponse('server_info', rippled.server_info.normal)
|
||||
})
|
||||
this.mockRippled.addResponse('server_info', rippled.server_info.normal)
|
||||
assert(this.client.isConnected())
|
||||
this.client
|
||||
.request({ command: 'server_info' })
|
||||
@@ -29,9 +27,7 @@ describe('BroadcastClient', function () {
|
||||
|
||||
it('error propagation', function (done) {
|
||||
const data = { error: 'type', error_message: 'info' }
|
||||
this.mocks.forEach((mock) => {
|
||||
mock.addResponse('echo', data)
|
||||
})
|
||||
this.mockRippled.addResponse('echo', data)
|
||||
this.client.once('error', (type, info) => {
|
||||
assert.strictEqual(type, 'type')
|
||||
assert.strictEqual(info, 'info')
|
||||
|
||||
74
test/integration/transactions/escrowCancel.ts
Normal file
74
test/integration/transactions/escrowCancel.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
|
||||
import { EscrowCancel, EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, suiteClientSetup, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, getXRPBalance, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('EscrowCancel', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
before(suiteClientSetup)
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: this.wallet.getClassicAddress(),
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.getClassicAddress(),
|
||||
CancelAfter: CLOSE_TIME + 3,
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, createTx, this.wallet)
|
||||
|
||||
const initialBalanceWallet1 = await getXRPBalance(this.client, wallet1)
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.getClassicAddress(),
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await this.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
const cancelTx: EscrowCancel = {
|
||||
TransactionType: 'EscrowCancel',
|
||||
Account: this.wallet.getClassicAddress(),
|
||||
Owner: this.wallet.getClassicAddress(),
|
||||
OfferSequence: sequence,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, cancelTx, this.wallet)
|
||||
|
||||
assert.equal(
|
||||
await getXRPBalance(this.client, wallet1),
|
||||
initialBalanceWallet1,
|
||||
)
|
||||
})
|
||||
})
|
||||
51
test/integration/transactions/escrowCreate.ts
Normal file
51
test/integration/transactions/escrowCreate.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
|
||||
import { EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, suiteClientSetup, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('EscrowCreate', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
before(suiteClientSetup)
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
const tx: EscrowCreate = {
|
||||
Account: this.wallet.getClassicAddress(),
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.getClassicAddress(),
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, tx, this.wallet)
|
||||
|
||||
// check that the object was actually created
|
||||
assert.equal(
|
||||
(
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.getClassicAddress(),
|
||||
})
|
||||
).result.account_objects.length,
|
||||
1,
|
||||
)
|
||||
})
|
||||
})
|
||||
73
test/integration/transactions/escrowFinish.ts
Normal file
73
test/integration/transactions/escrowFinish.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
|
||||
import { EscrowFinish, EscrowCreate } from 'xrpl-local'
|
||||
|
||||
import serverUrl from '../serverUrl'
|
||||
import { setupClient, suiteClientSetup, teardownClient } from '../setup'
|
||||
import { generateFundedWallet, getXRPBalance, testTransaction } from '../utils'
|
||||
|
||||
// how long before each test case times out
|
||||
const TIMEOUT = 20000
|
||||
|
||||
describe('EscrowFinish', function () {
|
||||
this.timeout(TIMEOUT)
|
||||
|
||||
before(suiteClientSetup)
|
||||
beforeEach(_.partial(setupClient, serverUrl))
|
||||
afterEach(teardownClient)
|
||||
|
||||
it('base', async function () {
|
||||
// get the most recent close_time from the standalone container for cancel & finish after.
|
||||
const CLOSE_TIME: number = (
|
||||
await this.client.request({
|
||||
command: 'ledger',
|
||||
ledger_index: 'validated',
|
||||
})
|
||||
).result.ledger.close_time
|
||||
const wallet1 = await generateFundedWallet(this.client)
|
||||
|
||||
const AMOUNT = 10000
|
||||
|
||||
const createTx: EscrowCreate = {
|
||||
Account: this.wallet.getClassicAddress(),
|
||||
TransactionType: 'EscrowCreate',
|
||||
Amount: '10000',
|
||||
Destination: wallet1.getClassicAddress(),
|
||||
FinishAfter: CLOSE_TIME + 2,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, createTx, this.wallet)
|
||||
|
||||
const initialBalance = await getXRPBalance(this.client, wallet1)
|
||||
|
||||
// check that the object was actually created
|
||||
const accountObjects = (
|
||||
await this.client.request({
|
||||
command: 'account_objects',
|
||||
account: this.wallet.getClassicAddress(),
|
||||
})
|
||||
).result.account_objects
|
||||
|
||||
assert.equal(accountObjects.length, 1)
|
||||
|
||||
const sequence = (
|
||||
await this.client.request({
|
||||
command: 'tx',
|
||||
transaction: accountObjects[0].PreviousTxnID,
|
||||
})
|
||||
).result.Sequence
|
||||
|
||||
const finishTx: EscrowFinish = {
|
||||
TransactionType: 'EscrowFinish',
|
||||
Account: this.wallet.getClassicAddress(),
|
||||
Owner: this.wallet.getClassicAddress(),
|
||||
OfferSequence: sequence,
|
||||
}
|
||||
|
||||
await testTransaction(this.client, finishTx, this.wallet)
|
||||
|
||||
const expectedBalance = String(Number(initialBalance) + Number(AMOUNT))
|
||||
assert.equal(await getXRPBalance(this.client, wallet1), expectedBalance)
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,7 @@ import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
|
||||
import { Client, Wallet, Response } from 'xrpl-local'
|
||||
import { Client, Wallet, Response, AccountInfoRequest } from 'xrpl-local'
|
||||
import { Payment, Transaction } from 'xrpl-local/models/transactions'
|
||||
import { computeSignedTransactionHash } from 'xrpl-local/utils/hashes'
|
||||
|
||||
@@ -103,3 +103,14 @@ export async function testTransaction(
|
||||
await ledgerAccept(client)
|
||||
await verifySubmittedTransaction(client, signedTx as Transaction)
|
||||
}
|
||||
|
||||
export async function getXRPBalance(
|
||||
client: Client,
|
||||
wallet: Wallet,
|
||||
): Promise<string> {
|
||||
const request: AccountInfoRequest = {
|
||||
command: 'account_info',
|
||||
account: wallet.getClassicAddress(),
|
||||
}
|
||||
return (await client.request(request)).result.account_data.Balance
|
||||
}
|
||||
|
||||
@@ -47,6 +47,38 @@ export interface PortResponse extends BaseResponse {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- typing is too complicated otherwise
|
||||
type MockedWebSocketServer = any
|
||||
|
||||
class MockedWebSocketBroadcastServer {
|
||||
public mocks: MockedWebSocketServer[]
|
||||
public constructor(mocks: MockedWebSocketServer[]) {
|
||||
this.mocks = mocks
|
||||
}
|
||||
|
||||
public addResponse(
|
||||
command: string,
|
||||
response:
|
||||
| Response
|
||||
| ErrorResponse
|
||||
| ((r: Request) => Response | ErrorResponse),
|
||||
): void {
|
||||
this.mocks.forEach((mock) => {
|
||||
mock.addResponse(command, response)
|
||||
})
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.mocks.forEach((mock: { close: () => void }) => mock.close())
|
||||
}
|
||||
}
|
||||
|
||||
export function createBroadcastMockRippled(
|
||||
ports: number[],
|
||||
): MockedWebSocketBroadcastServer {
|
||||
// eslint-disable-next-line max-len -- Too many rules to disable
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async, @typescript-eslint/no-unsafe-return -- Typing is too complicated, not an async function
|
||||
const mocks = ports.map((port) => createMockRippled(port))
|
||||
return new MockedWebSocketBroadcastServer(mocks)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async -- Not a promise that's returned
|
||||
export default function createMockRippled(port: number): MockedWebSocketServer {
|
||||
const mock = new WebSocketServer({ port }) as MockedWebSocketServer
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types -- Necessary for test setup */
|
||||
import { Client, BroadcastClient } from 'xrpl-local'
|
||||
|
||||
import createMockRippled from './mockRippled'
|
||||
import createMockRippled, { createBroadcastMockRippled } from './mockRippled'
|
||||
import { getFreePort } from './testUtils'
|
||||
|
||||
async function setupMockRippledConnection(
|
||||
@@ -25,9 +25,7 @@ async function setupMockRippledConnectionForBroadcast(
|
||||
): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const servers = ports.map((port) => `ws://localhost:${port}`)
|
||||
// eslint-disable-next-line max-len -- Too many rules to disable
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async, @typescript-eslint/no-unsafe-return -- Typing is too complicated, not an async function
|
||||
testcase.mocks = ports.map((port) => createMockRippled(port))
|
||||
testcase.mockRippled = createBroadcastMockRippled(ports)
|
||||
testcase.client = new BroadcastClient(servers)
|
||||
testcase.client.connect().then(resolve).catch(reject)
|
||||
})
|
||||
@@ -50,15 +48,16 @@ function teardownClient(this: any, done: () => void): void {
|
||||
this.client
|
||||
.disconnect()
|
||||
.then(() => {
|
||||
// eslint-disable-next-line no-negated-condition -- Easier to read with negation
|
||||
if (this.mockRippled != null) {
|
||||
this.mockRippled.close()
|
||||
} else {
|
||||
this.mocks.forEach((mock: { close: () => void }) => mock.close())
|
||||
}
|
||||
this.mockRippled.close()
|
||||
setImmediate(done)
|
||||
})
|
||||
.catch(done)
|
||||
}
|
||||
|
||||
export { setupClient, teardownClient, setupBroadcast, createMockRippled }
|
||||
export {
|
||||
setupBroadcast,
|
||||
teardownClient,
|
||||
setupBroadcast as setupClient,
|
||||
setupClient as setupClientActual,
|
||||
createMockRippled,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user