From 6c6dade6360458e79955e77e6b829bcce45081b0 Mon Sep 17 00:00:00 2001 From: Denis Angell Date: Thu, 16 Feb 2023 18:49:37 -0500 Subject: [PATCH] integration tests --- packages/xrpl/test/integration/setup.ts | 124 +++++++++++++++++- .../transactions/escrowCancel.test.ts | 110 +++++++++++++--- .../transactions/escrowCreate.test.ts | 51 ++++++- .../transactions/escrowFinish.test.ts | 98 ++++++++++++-- .../transactions/paymentChannelClaim.test.ts | 55 +++++++- .../transactions/paymentChannelCreate.test.ts | 60 ++++++++- .../transactions/paymentChannelFund.test.ts | 58 +++++++- 7 files changed, 499 insertions(+), 57 deletions(-) diff --git a/packages/xrpl/test/integration/setup.ts b/packages/xrpl/test/integration/setup.ts index 288b3cd5..017896e2 100644 --- a/packages/xrpl/test/integration/setup.ts +++ b/packages/xrpl/test/integration/setup.ts @@ -1,11 +1,14 @@ import { Client, Wallet } from '../../src' +import { AccountSet, TrustSet, Payment } from '../../src/models/transactions' import serverUrl from './serverUrl' -import { fundAccount } from './utils' +import { fundAccount, ledgerAccept } from './utils' export interface XrplIntegrationTestContext { client: Client wallet: Wallet + destination: Wallet + gateway: Wallet } export async function teardownClient( @@ -29,18 +32,137 @@ async function connectWithRetry(client: Client, tries = 0): Promise { }) } +// eslint-disable-next-line max-params -- need comments +async function initToken( + client: Client, + wallet: Wallet, + destination: Wallet, + gateway: Wallet, +): Promise { + const atx: AccountSet = { + TransactionType: 'AccountSet', + Account: gateway.classicAddress, + SetFlag: 8, + } + const atxr = await client.submit(atx, { + wallet: gateway, + }) + if (atxr.result.engine_result !== 'tesSUCCESS') { + // eslint-disable-next-line no-console -- happens only when something goes wrong + console.log(atxr) + } + await ledgerAccept(client) + + const wtl: TrustSet = { + TransactionType: 'TrustSet', + Account: wallet.classicAddress, + LimitAmount: { + currency: 'USD', + issuer: gateway.classicAddress, + value: '100000', + }, + } + + const wtlr = await client.submit(wtl, { + wallet, + }) + if (wtlr.result.engine_result !== 'tesSUCCESS') { + // eslint-disable-next-line no-console -- happens only when something goes wrong + console.log(wtlr) + } + await ledgerAccept(client) + + const dtl: TrustSet = { + TransactionType: 'TrustSet', + Account: destination.classicAddress, + LimitAmount: { + currency: 'USD', + issuer: gateway.classicAddress, + value: '100000', + }, + } + + const dtlr = await client.submit(dtl, { + wallet: destination, + }) + if (wtlr.result.engine_result !== 'tesSUCCESS') { + // eslint-disable-next-line no-console -- happens only when something goes wrong + console.log(dtlr) + } + await ledgerAccept(client) + + const wp: Payment = { + TransactionType: 'Payment', + Account: gateway.classicAddress, + Destination: wallet.classicAddress, + Amount: { + currency: 'USD', + issuer: gateway.classicAddress, + value: '10000', + }, + } + + const wpr = await client.submit(wp, { + wallet: gateway, + }) + if (wpr.result.engine_result !== 'tesSUCCESS') { + // eslint-disable-next-line no-console -- happens only when something goes wrong + console.log(wpr) + } + await ledgerAccept(client) + + const dp: Payment = { + TransactionType: 'Payment', + Account: gateway.classicAddress, + Destination: destination.classicAddress, + Amount: { + currency: 'USD', + issuer: gateway.classicAddress, + value: '10000', + }, + } + + const dpr = await client.submit(dp, { + wallet: gateway, + }) + if (dpr.result.engine_result !== 'tesSUCCESS') { + // eslint-disable-next-line no-console -- happens only when something goes wrong + console.log(dpr) + } + await ledgerAccept(client) +} + export async function setupClient( server = serverUrl, + token?: boolean | false, ): Promise { const context: XrplIntegrationTestContext = { client: new Client(server, { timeout: 200000 }), wallet: Wallet.generate(), + destination: Wallet.generate(), + gateway: Wallet.generate(), } return connectWithRetry(context.client).then(async () => { await fundAccount(context.client, context.wallet, { count: 20, delayMs: 1000, }) + if (token) { + await fundAccount(context.client, context.destination, { + count: 20, + delayMs: 1000, + }) + await fundAccount(context.client, context.gateway, { + count: 20, + delayMs: 1000, + }) + await initToken( + context.client, + context.wallet, + context.destination, + context.gateway, + ) + } return context }) } diff --git a/packages/xrpl/test/integration/transactions/escrowCancel.test.ts b/packages/xrpl/test/integration/transactions/escrowCancel.test.ts index 13b2854b..a0f7638e 100644 --- a/packages/xrpl/test/integration/transactions/escrowCancel.test.ts +++ b/packages/xrpl/test/integration/transactions/escrowCancel.test.ts @@ -7,13 +7,7 @@ import { teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { - // calculateWaitTimeForTransaction, - generateFundedWallet, - // getXRPBalance, - testTransaction, - submitTransaction, -} from '../utils' +import { testTransaction, submitTransaction } from '../utils' // TODO: Fix these tests // NOTE: Because ledger accept is called among multiple tests, the actual ledger close time is not @@ -30,16 +24,13 @@ describe('EscrowCancel', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - // Funding the wallet can take some time, so we do it first BEFORE getting the ledger close_time. - const wallet1 = await generateFundedWallet(testContext.client) - // get the most recent close_time from the standalone container for cancel & finish after. const CLOSE_TIME: number = ( await testContext.client.request({ @@ -54,7 +45,7 @@ describe('EscrowCancel', function () { Account: testContext.wallet.classicAddress, TransactionType: 'EscrowCreate', Amount: '10000', - Destination: wallet1.classicAddress, + Destination: testContext.destination.classicAddress, CancelAfter: CLOSE_TIME + 3, FinishAfter: CLOSE_TIME + 2, } @@ -74,12 +65,101 @@ describe('EscrowCancel', function () { }) ).result.account_objects - assert.equal(accountObjects.length, 1) + assert.equal(accountObjects.length, 2) const sequence = ( await testContext.client.request({ command: 'tx', - transaction: accountObjects[0].PreviousTxnID, + transaction: accountObjects[1].PreviousTxnID, + }) + ).result.Sequence + + if (!sequence) { + throw new Error('sequence did not exist') + } + + const cancelTx: EscrowCancel = { + TransactionType: 'EscrowCancel', + Account: testContext.wallet.classicAddress, + Owner: testContext.wallet.classicAddress, + OfferSequence: sequence, + } + + // We set the CancelAfter timer to be 3 seconds after the last ledger close_time. We need to wait this long + // before we can cancel the escrow. + // const cancelAfterTimerPromise = new Promise((resolve) => { + // setTimeout(resolve, waitTimeInMs) + // }) + + // Make sure we wait long enough before canceling the escrow. + // await cancelAfterTimerPromise + + // await testTransaction(testContext.client, cancelTx, testContext.wallet, { + // count: 20, + // delayMs: 2000, + // }) + + await submitTransaction({ + client: testContext.client, + transaction: cancelTx, + wallet: testContext.wallet, + }) + + // Make sure the Destination wallet did not receive any XRP. + // assert.equal( + // await getXRPBalance(testContext.client, wallet1), + // initialBalanceWallet1, + // ) + }, + TIMEOUT, + ) + it( + 'test token', + async () => { + // get the most recent close_time from the standalone container for cancel & finish after. + const CLOSE_TIME: number = ( + await testContext.client.request({ + command: 'ledger', + ledger_index: 'validated', + }) + ).result.ledger.close_time + + // const waitTimeInMs = calculateWaitTimeForTransaction(CLOSE_TIME) + + const createTx: EscrowCreate = { + Account: testContext.wallet.classicAddress, + TransactionType: 'EscrowCreate', + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, + CancelAfter: CLOSE_TIME + 3, + FinishAfter: CLOSE_TIME + 2, + } + + await testTransaction(testContext.client, createTx, testContext.wallet) + + // const initialBalanceWallet1 = await getXRPBalance( + // testContext.client, + // wallet1, + // ) + + // check that the object was actually created + const accountObjects = ( + await testContext.client.request({ + command: 'account_objects', + account: testContext.wallet.classicAddress, + }) + ).result.account_objects + + assert.equal(accountObjects.length, 2) + + const sequence = ( + await testContext.client.request({ + command: 'tx', + transaction: accountObjects[1].PreviousTxnID, }) ).result.Sequence diff --git a/packages/xrpl/test/integration/transactions/escrowCreate.test.ts b/packages/xrpl/test/integration/transactions/escrowCreate.test.ts index 43a593f8..52f75e06 100644 --- a/packages/xrpl/test/integration/transactions/escrowCreate.test.ts +++ b/packages/xrpl/test/integration/transactions/escrowCreate.test.ts @@ -7,7 +7,7 @@ import { teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { generateFundedWallet, testTransaction } from '../utils' +import { testTransaction } from '../utils' // how long before each test case times out const TIMEOUT = 20000 @@ -16,15 +16,13 @@ describe('EscrowCreate', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - const wallet2 = await generateFundedWallet(testContext.client) - // get the most recent close_time from the standalone container for finish after. const CLOSE_TIME: number = ( await testContext.client.request({ @@ -37,7 +35,7 @@ describe('EscrowCreate', function () { Account: testContext.wallet.classicAddress, TransactionType: 'EscrowCreate', Amount: '10000', - Destination: wallet2.classicAddress, + Destination: testContext.destination.classicAddress, FinishAfter: CLOSE_TIME + 2, } @@ -51,7 +49,46 @@ describe('EscrowCreate', function () { account: testContext.wallet.classicAddress, }) ).result.account_objects.length, - 1, + 2, + ) + }, + TIMEOUT, + ) + + it( + 'test token', + async () => { + // get the most recent close_time from the standalone container for finish after. + const CLOSE_TIME: number = ( + await testContext.client.request({ + command: 'ledger', + ledger_index: 'validated', + }) + ).result.ledger.close_time + + const tx: EscrowCreate = { + Account: testContext.wallet.classicAddress, + TransactionType: 'EscrowCreate', + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, + FinishAfter: CLOSE_TIME + 2, + } + + await testTransaction(testContext.client, tx, testContext.wallet) + + // check that the object was actually created + assert.equal( + ( + await testContext.client.request({ + command: 'account_objects', + account: testContext.wallet.classicAddress, + }) + ).result.account_objects.length, + 2, ) }, TIMEOUT, diff --git a/packages/xrpl/test/integration/transactions/escrowFinish.test.ts b/packages/xrpl/test/integration/transactions/escrowFinish.test.ts index f93319f2..b9ec0875 100644 --- a/packages/xrpl/test/integration/transactions/escrowFinish.test.ts +++ b/packages/xrpl/test/integration/transactions/escrowFinish.test.ts @@ -9,7 +9,6 @@ import { } from '../setup' import { calculateWaitTimeForTransaction, - generateFundedWallet, getXRPBalance, testTransaction, } from '../utils' @@ -21,15 +20,13 @@ describe('EscrowFinish', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - const wallet1 = await generateFundedWallet(testContext.client) - // get the most recent close_time from the standalone container for cancel & finish after. const CLOSE_TIME: number = ( await testContext.client.request({ @@ -40,13 +37,11 @@ describe('EscrowFinish', function () { const waitTimeInMs = calculateWaitTimeForTransaction(CLOSE_TIME) - const AMOUNT = 10000 - const createTx: EscrowCreate = { Account: testContext.wallet.classicAddress, TransactionType: 'EscrowCreate', - Amount: AMOUNT.toString(), - Destination: wallet1.classicAddress, + Amount: '10000', + Destination: testContext.destination.classicAddress, FinishAfter: CLOSE_TIME + 2, } @@ -56,7 +51,10 @@ describe('EscrowFinish', function () { await testTransaction(testContext.client, createTx, testContext.wallet) - const initialBalance = await getXRPBalance(testContext.client, wallet1) + const initialBalance = await getXRPBalance( + testContext.client, + testContext.destination, + ) // check that the object was actually created const accountObjects = ( @@ -66,12 +64,12 @@ describe('EscrowFinish', function () { }) ).result.account_objects - assert.equal(accountObjects.length, 1) + assert.equal(accountObjects.length, 2) const sequence = ( await testContext.client.request({ command: 'tx', - transaction: accountObjects[0].PreviousTxnID, + transaction: accountObjects[1].PreviousTxnID, }) ).result.Sequence @@ -86,9 +84,81 @@ describe('EscrowFinish', function () { await testTransaction(testContext.client, finishTx, testContext.wallet) - const expectedBalance = String(Number(initialBalance) + Number(AMOUNT)) + const expectedBalance = String(Number(initialBalance) + Number('10000')) assert.equal( - await getXRPBalance(testContext.client, wallet1), + await getXRPBalance(testContext.client, testContext.destination), + expectedBalance, + ) + }, + TIMEOUT, + ) + it( + 'test token', + async () => { + // get the most recent close_time from the standalone container for cancel & finish after. + const CLOSE_TIME: number = ( + await testContext.client.request({ + command: 'ledger', + ledger_index: 'validated', + }) + ).result.ledger.close_time + + const waitTimeInMs = calculateWaitTimeForTransaction(CLOSE_TIME) + + const createTx: EscrowCreate = { + Account: testContext.wallet.classicAddress, + TransactionType: 'EscrowCreate', + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, + FinishAfter: CLOSE_TIME + 2, + } + + const finishAfterPromise = new Promise((resolve) => { + setTimeout(resolve, waitTimeInMs) + }) + + await testTransaction(testContext.client, createTx, testContext.wallet) + + const initialBalance = await getXRPBalance( + testContext.client, + testContext.destination, + ) + + // check that the object was actually created + const accountObjects = ( + await testContext.client.request({ + command: 'account_objects', + account: testContext.wallet.classicAddress, + }) + ).result.account_objects + + assert.equal(accountObjects.length, 2) + + const sequence = ( + await testContext.client.request({ + command: 'tx', + transaction: accountObjects[1].PreviousTxnID, + }) + ).result.Sequence + + const finishTx: EscrowFinish = { + TransactionType: 'EscrowFinish', + Account: testContext.wallet.classicAddress, + Owner: testContext.wallet.classicAddress, + OfferSequence: sequence!, + } + + await finishAfterPromise + + await testTransaction(testContext.client, finishTx, testContext.wallet) + + const expectedBalance = String(Number(initialBalance)) + assert.equal( + await getXRPBalance(testContext.client, testContext.destination), expectedBalance, ) }, diff --git a/packages/xrpl/test/integration/transactions/paymentChannelClaim.test.ts b/packages/xrpl/test/integration/transactions/paymentChannelClaim.test.ts index 85f52fa4..6819afea 100644 --- a/packages/xrpl/test/integration/transactions/paymentChannelClaim.test.ts +++ b/packages/xrpl/test/integration/transactions/paymentChannelClaim.test.ts @@ -5,7 +5,7 @@ import { teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { generateFundedWallet, testTransaction } from '../utils' +import { testTransaction } from '../utils' // how long before each test case times out const TIMEOUT = 20000 @@ -15,19 +15,18 @@ describe('PaymentChannelClaim', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - const wallet2 = await generateFundedWallet(testContext.client) const paymentChannelCreate: PaymentChannelCreate = { TransactionType: 'PaymentChannelCreate', Account: testContext.wallet.classicAddress, Amount: '100', - Destination: wallet2.classicAddress, + Destination: testContext.destination.classicAddress, SettleDelay: 86400, PublicKey: testContext.wallet.publicKey, } @@ -48,7 +47,7 @@ describe('PaymentChannelClaim', function () { TransactionType: 'PaymentChannelClaim', Channel: hashPaymentChannel( testContext.wallet.classicAddress, - wallet2.classicAddress, + testContext.destination.classicAddress, paymentChannelResponse.result.tx_json.Sequence ?? 0, ), Amount: '100', @@ -62,4 +61,48 @@ describe('PaymentChannelClaim', function () { }, TIMEOUT, ) + it( + 'test token', + async () => { + const paymentChannelCreate: PaymentChannelCreate = { + TransactionType: 'PaymentChannelCreate', + Account: testContext.wallet.classicAddress, + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, + SettleDelay: 86400, + PublicKey: testContext.wallet.publicKey, + } + + const paymentChannelResponse = await testContext.client.submit( + paymentChannelCreate, + { wallet: testContext.wallet }, + ) + + const paymentChannelClaim: PaymentChannelClaim = { + Account: testContext.wallet.classicAddress, + TransactionType: 'PaymentChannelClaim', + Channel: hashPaymentChannel( + testContext.wallet.classicAddress, + testContext.destination.classicAddress, + paymentChannelResponse.result.tx_json.Sequence ?? 0, + ), + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + } + + await testTransaction( + testContext.client, + paymentChannelClaim, + testContext.wallet, + ) + }, + TIMEOUT, + ) }) diff --git a/packages/xrpl/test/integration/transactions/paymentChannelCreate.test.ts b/packages/xrpl/test/integration/transactions/paymentChannelCreate.test.ts index f3d8fb3c..2262ff30 100644 --- a/packages/xrpl/test/integration/transactions/paymentChannelCreate.test.ts +++ b/packages/xrpl/test/integration/transactions/paymentChannelCreate.test.ts @@ -1,32 +1,78 @@ -import { PaymentChannelCreate } from '../../../src' +import { PaymentChannelCreate, hashes, PaymentChannelClaim } from '../../../src' import serverUrl from '../serverUrl' import { setupClient, teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { generateFundedWallet, testTransaction } from '../utils' +import { testTransaction } from '../utils' // how long before each test case times out const TIMEOUT = 20000 +const { hashPaymentChannel } = hashes -describe('PaymentChannelCreate', function () { +describe('PaymentChannelClaim', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - const wallet2 = await generateFundedWallet(testContext.client) const paymentChannelCreate: PaymentChannelCreate = { TransactionType: 'PaymentChannelCreate', Account: testContext.wallet.classicAddress, Amount: '100', - Destination: wallet2.classicAddress, + Destination: testContext.destination.classicAddress, + SettleDelay: 86400, + PublicKey: testContext.wallet.publicKey, + } + + const paymentChannelResponse = await testContext.client.submit( + paymentChannelCreate, + { wallet: testContext.wallet }, + ) + + await testTransaction( + testContext.client, + paymentChannelCreate, + testContext.wallet, + ) + + const paymentChannelClaim: PaymentChannelClaim = { + Account: testContext.wallet.classicAddress, + TransactionType: 'PaymentChannelClaim', + Channel: hashPaymentChannel( + testContext.wallet.classicAddress, + testContext.destination.classicAddress, + paymentChannelResponse.result.tx_json.Sequence ?? 0, + ), + Amount: '100', + } + + await testTransaction( + testContext.client, + paymentChannelClaim, + testContext.wallet, + ) + }, + TIMEOUT, + ) + it( + 'test token', + async () => { + const paymentChannelCreate: PaymentChannelCreate = { + TransactionType: 'PaymentChannelCreate', + Account: testContext.wallet.classicAddress, + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, SettleDelay: 86400, PublicKey: testContext.wallet.publicKey, } diff --git a/packages/xrpl/test/integration/transactions/paymentChannelFund.test.ts b/packages/xrpl/test/integration/transactions/paymentChannelFund.test.ts index be5117e2..74aed25f 100644 --- a/packages/xrpl/test/integration/transactions/paymentChannelFund.test.ts +++ b/packages/xrpl/test/integration/transactions/paymentChannelFund.test.ts @@ -5,29 +5,28 @@ import { teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { generateFundedWallet, testTransaction } from '../utils' +import { testTransaction } from '../utils' // how long before each test case times out const TIMEOUT = 20000 const { hashPaymentChannel } = hashes -describe('PaymentChannelFund', function () { +describe('PaymentChannelClaim', function () { let testContext: XrplIntegrationTestContext beforeEach(async () => { - testContext = await setupClient(serverUrl) + testContext = await setupClient(serverUrl, true) }) afterEach(async () => teardownClient(testContext)) it( - 'base', + 'test xrp', async () => { - const wallet2 = await generateFundedWallet(testContext.client) const paymentChannelCreate: PaymentChannelCreate = { TransactionType: 'PaymentChannelCreate', Account: testContext.wallet.classicAddress, Amount: '100', - Destination: wallet2.classicAddress, + Destination: testContext.destination.classicAddress, SettleDelay: 86400, PublicKey: testContext.wallet.publicKey, } @@ -36,6 +35,7 @@ describe('PaymentChannelFund', function () { paymentChannelCreate, { wallet: testContext.wallet }, ) + await testTransaction( testContext.client, paymentChannelCreate, @@ -47,7 +47,7 @@ describe('PaymentChannelFund', function () { TransactionType: 'PaymentChannelFund', Channel: hashPaymentChannel( testContext.wallet.classicAddress, - wallet2.classicAddress, + testContext.destination.classicAddress, paymentChannelResponse.result.tx_json.Sequence ?? 0, ), Amount: '100', @@ -61,4 +61,48 @@ describe('PaymentChannelFund', function () { }, TIMEOUT, ) + it( + 'test token', + async () => { + const paymentChannelCreate: PaymentChannelCreate = { + TransactionType: 'PaymentChannelCreate', + Account: testContext.wallet.classicAddress, + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + Destination: testContext.destination.classicAddress, + SettleDelay: 86400, + PublicKey: testContext.wallet.publicKey, + } + + const paymentChannelResponse = await testContext.client.submit( + paymentChannelCreate, + { wallet: testContext.wallet }, + ) + + const paymentChannelFund: PaymentChannelFund = { + Account: testContext.wallet.classicAddress, + TransactionType: 'PaymentChannelFund', + Channel: hashPaymentChannel( + testContext.wallet.classicAddress, + testContext.destination.classicAddress, + paymentChannelResponse.result.tx_json.Sequence ?? 0, + ), + Amount: { + currency: 'USD', + issuer: testContext.gateway.classicAddress, + value: '100', + }, + } + + await testTransaction( + testContext.client, + paymentChannelFund, + testContext.wallet, + ) + }, + TIMEOUT, + ) })