From b62cd9ff94521b1dc629b92e7e46957a328b5523 Mon Sep 17 00:00:00 2001 From: Vova Lando Date: Wed, 11 Dec 2024 16:09:31 +0200 Subject: [PATCH] test: check account balance to ensure transaction result --- chopsticks/docker-compose.yml | 13 ++++++ tests/kalatori-api-test-suite/src/polkadot.ts | 44 +++++++++++++++---- .../tests/order.test.ts | 35 +++++++++++++-- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/chopsticks/docker-compose.yml b/chopsticks/docker-compose.yml index 4d6db64..101a4d2 100644 --- a/chopsticks/docker-compose.yml +++ b/chopsticks/docker-compose.yml @@ -11,6 +11,8 @@ services: volumes: - ./pd.yml:/app/config.yml command: ["chopsticks", "-c", "/app/config.yml", "-p", "8000", "--addr", "0.0.0.0"] + networks: + - kalatori-network chopsticks-polkadot-2: build: @@ -22,6 +24,8 @@ services: volumes: - ./pd-2.yml:/app/config.yml command: [ "chopsticks", "-c", "/app/config.yml", "-p", "8500", "--addr", "0.0.0.0" ] + networks: + - kalatori-network chopsticks-statemint: build: @@ -33,6 +37,8 @@ services: volumes: - ./pd-ah.yml:/app/config.yml command: ["chopsticks", "-c", "/app/config.yml", "-p", "9000", "--addr", "0.0.0.0"] + networks: + - kalatori-network chopsticks-statemint-2: build: @@ -44,3 +50,10 @@ services: volumes: - ./pd-ah-2.yml:/app/config.yml command: [ "chopsticks", "-c", "/app/config.yml", "-p", "9500", "--addr", "0.0.0.0" ] + networks: + - kalatori-network + + +networks: + kalatori-network: + external: true diff --git a/tests/kalatori-api-test-suite/src/polkadot.ts b/tests/kalatori-api-test-suite/src/polkadot.ts index 2c51fab..291f865 100644 --- a/tests/kalatori-api-test-suite/src/polkadot.ts +++ b/tests/kalatori-api-test-suite/src/polkadot.ts @@ -1,13 +1,9 @@ import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'; import { cryptoWaitReady, decodeAddress, encodeAddress } from '@polkadot/util-crypto'; - -export async function updateAccountBalance(api: ApiPromise, accountAddress: string, amount: bigint): Promise { - const keyring = new Keyring({ type: 'sr25519' }); - const alice = keyring.addFromUri('//Alice'); - - const transfer = api.tx.balances.transfer(accountAddress, amount); - await transfer.signAndSend(alice); -} +import { u32 } from '@polkadot/types'; +import type { AccountInfo } from '@polkadot/types/interfaces/system'; +import type { AssetBalance } from '@polkadot/types/interfaces/assets'; +import { BN } from '@polkadot/util'; export async function connectPolkadot(rpcUrl: string): Promise { const provider = new WsProvider(rpcUrl); @@ -16,6 +12,38 @@ export async function connectPolkadot(rpcUrl: string): Promise { return api; } +export const reverseDecimals = (amount: number, decimals: number): number => { + return amount / Math.pow(10, decimals); +}; + +export async function getDotBalance(rpcUrl: string, paymentAccount: string): Promise { + const provider = new WsProvider(rpcUrl); + const api = await ApiPromise.create({ provider }); + + const accountInfo = await api.query.system.account(paymentAccount); + + // @ts-ignore + const freeBalance = accountInfo.data.free.toBigInt(); + + return Number(freeBalance); +} + +export async function getAssetBalance(rpcUrl: string, paymentAccount: string, assetId: number): Promise { + const provider = new WsProvider(rpcUrl); + const api = await ApiPromise.create({ provider }); + const decodedAccount = decodeAddress(paymentAccount); + + // Query the balance for the specified asset and account + const assetIdU32 = new u32(api.registry, assetId); + const accountInfo = (await api.query.assets.account(assetIdU32, decodedAccount)).toJSON() as { balance: number}; + + if (accountInfo) { + return accountInfo.balance; + } else { + return 0; + } +} + export async function transferFunds(rpcUrl: string, paymentAccount: string, amount: number, assetId?: number) { const provider = new WsProvider(rpcUrl); const api = await ApiPromise.create({ provider }); diff --git a/tests/kalatori-api-test-suite/tests/order.test.ts b/tests/kalatori-api-test-suite/tests/order.test.ts index e9a23ef..cad2b3e 100644 --- a/tests/kalatori-api-test-suite/tests/order.test.ts +++ b/tests/kalatori-api-test-suite/tests/order.test.ts @@ -1,6 +1,5 @@ import request from 'supertest'; -import { connectPolkadot, transferFunds } from '../src/polkadot'; -import { ApiPromise } from '@polkadot/api'; +import {getAssetBalance, getDotBalance, reverseDecimals, transferFunds} from '../src/polkadot'; describe('Order Endpoint Blackbox Tests', () => { const baseUrl = process.env.DAEMON_HOST; @@ -14,7 +13,7 @@ describe('Order Endpoint Blackbox Tests', () => { }; const usdcOrderData = { - amount: 1, + amount: 10, currency: 'USDC', callback: 'https://example.com/callback' }; @@ -254,6 +253,9 @@ describe('Order Endpoint Blackbox Tests', () => { expect(repaidOrderDetails.payment_status).toBe('paid'); expect(repaidOrderDetails.withdrawal_status).toBe('completed'); + + const paymentAccountDotBalance = await getDotBalance(orderDetails.currency.rpc_url, paymentAccount); + expect(reverseDecimals(paymentAccountDotBalance,10)).toBe(0); }, 100000); it('should create, repay, and automatically withdraw an order in USDC', async () => { @@ -283,6 +285,9 @@ describe('Order Endpoint Blackbox Tests', () => { expect(repaidOrderDetails.payment_status).toBe('paid'); expect(repaidOrderDetails.withdrawal_status).toBe('completed'); + + const paymentAccountUsdcBalance = await getAssetBalance(orderDetails.currency.rpc_url, paymentAccount, orderDetails.currency.asset_id); + expect(reverseDecimals(paymentAccountUsdcBalance, 6)).toBe(0); }, 50000); it('should not automatically withdraw DOT order until fully repaid', async () => { @@ -305,6 +310,9 @@ describe('Order Endpoint Blackbox Tests', () => { // lets wait for the changes to get propagated on chain and app to catch them await new Promise(resolve => setTimeout(resolve, 15000)); + const halfAmountBalance = await getDotBalance(orderDetails.currency.rpc_url, paymentAccount); + expect(reverseDecimals(halfAmountBalance, 10)).toBe(orderDetails.amount/2); + let repaidOrderDetails = await getOrderDetails(orderId); expect(repaidOrderDetails.payment_status).toBe('pending'); expect(repaidOrderDetails.withdrawal_status).toBe('waiting'); @@ -323,6 +331,9 @@ describe('Order Endpoint Blackbox Tests', () => { repaidOrderDetails = await getOrderDetails(orderId); expect(repaidOrderDetails.payment_status).toBe('paid'); expect(repaidOrderDetails.withdrawal_status).toBe('completed'); + + const paymentAccountDotBalance = await getDotBalance(orderDetails.currency.rpc_url, paymentAccount); + expect(reverseDecimals(paymentAccountDotBalance, 10)).toBe(0); }, 100000); it('should not automatically withdraw USDC order until fully repaid', async () => { @@ -345,6 +356,9 @@ describe('Order Endpoint Blackbox Tests', () => { // lets wait for the changes to get propagated on chain and app to catch them await new Promise(resolve => setTimeout(resolve, 15000)); + const halfAmountBalance = await getAssetBalance(orderDetails.currency.rpc_url, paymentAccount, orderDetails.currency.asset_id); + expect(reverseDecimals(halfAmountBalance, 6)).toBe(halfAmount); + let repaidOrderDetails = await getOrderDetails(orderId); expect(repaidOrderDetails.payment_status).toBe('pending'); expect(repaidOrderDetails.withdrawal_status).toBe('waiting'); @@ -363,6 +377,9 @@ describe('Order Endpoint Blackbox Tests', () => { repaidOrderDetails = await getOrderDetails(orderId); expect(repaidOrderDetails.payment_status).toBe('paid'); expect(repaidOrderDetails.withdrawal_status).toBe('completed'); + + const paymentAccountUsdcBalance = await getAssetBalance(orderDetails.currency.rpc_url, paymentAccount, orderDetails.currency.asset_id); + expect(reverseDecimals(paymentAccountUsdcBalance, 6)).toBe(0); }, 100000); it('should not update order if received payment in wrong currency', async () => { @@ -400,6 +417,9 @@ describe('Order Endpoint Blackbox Tests', () => { // lets wait for the changes to get propagated on chain and app to catch them await new Promise(resolve => setTimeout(resolve, 15000)); + const halfAmountBalance = await getDotBalance(orderDetails.currency.rpc_url, paymentAccount); + expect(reverseDecimals(halfAmountBalance, 10)).toBe(orderDetails.amount/2); + const partiallyRepaidOrderDetails = await getOrderDetails(orderId); expect(partiallyRepaidOrderDetails.payment_status).toBe('pending'); expect(partiallyRepaidOrderDetails.withdrawal_status).toBe('waiting'); @@ -411,6 +431,9 @@ describe('Order Endpoint Blackbox Tests', () => { let forcedOrderDetails = await getOrderDetails(orderId); expect(forcedOrderDetails.payment_status).toBe('pending'); expect(forcedOrderDetails.withdrawal_status).toBe('forced'); + + const paymentAccountDotBalance = await getDotBalance(orderDetails.currency.rpc_url, paymentAccount); + expect(reverseDecimals(paymentAccountDotBalance, 10)).toBe(0); }, 100000); it('should be able to force withdraw partially repayed USDC order', async () => { @@ -425,6 +448,9 @@ describe('Order Endpoint Blackbox Tests', () => { // lets wait for the changes to get propagated on chain and app to catch them await new Promise(resolve => setTimeout(resolve, 15000)); + const halfAmountBalance = await getAssetBalance(orderDetails.currency.rpc_url, paymentAccount, orderDetails.currency.asset_id); + expect(reverseDecimals(halfAmountBalance, 6)).toBe(usdcOrderData.amount/2); + const partiallyRepaidOrderDetails = await getOrderDetails(orderId); expect(partiallyRepaidOrderDetails.payment_status).toBe('pending'); expect(partiallyRepaidOrderDetails.withdrawal_status).toBe('waiting'); @@ -436,6 +462,9 @@ describe('Order Endpoint Blackbox Tests', () => { let forcedOrderDetails = await getOrderDetails(orderId); expect(forcedOrderDetails.payment_status).toBe('pending'); expect(forcedOrderDetails.withdrawal_status).toBe('forced'); + + const paymentAccountUsdcBalance = await getAssetBalance(orderDetails.currency.rpc_url, paymentAccount, orderDetails.currency.asset_id); + expect(reverseDecimals(paymentAccountUsdcBalance, 6)).toBe(0); }, 100000); it('should return 404 for non-existing order on force withdrawal', async () => {