difftreelog
Tests: add balance state asserts
in: master
3 files changed
tests/src/app-promotion.test.tsdiffbeforeafterboth--- a/tests/src/app-promotion.test.ts
+++ b/tests/src/app-promotion.test.ts
@@ -63,16 +63,21 @@
});
describe('app-promotions.stake extrinsic', () => {
- it('should change balance state to "locked", add it to "staked" map, and increase "totalStaked" amount', async () => {
+ it('should "lock" some balance in system.account, add it to "staked" map, and increase "totalStaked" amount', async () => {
await usingPlaygrounds(async (helper) => {
const totalStakedBefore = await helper.staking.getTotalStaked();
- const [staker] = await helper.arrange.createAccounts([400n], alice);
+ const [staker, recepient] = await helper.arrange.createAccounts([400n, 0n], alice);
// Minimum stake amount is 100:
await expect(helper.staking.stake(staker, 100n * nominal - 1n)).to.be.eventually.rejected;
await helper.staking.stake(staker, 100n * nominal);
+
+ // Staker balance is: miscFrozen: 100, feeFrozen: 100, reserved: 0n, free less than 300...
+ // ...so he can not transfer 300
+ expect (await helper.balance.getSubstrateFull(staker.address)).to.contain({miscFrozen: 100n * nominal, feeFrozen: 100n * nominal, reserved: 0n});
+ await expect(helper.balance.transferToSubstrate(staker, recepient.address, 300n * nominal)).to.be.rejected;
+
expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(100n * nominal);
-
// TODO add helpers to assert bigints. Check balance close to 100
expect(await helper.balance.getSubstrate(staker.address) - 99n * nominal >= (nominal / 2n)).to.be.true;
expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);
@@ -121,17 +126,27 @@
it('should change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {
await usingPlaygrounds(async helper => {
const totalStakedBefore = await helper.staking.getTotalStaked();
- const [staker] = await helper.arrange.createAccounts([1000n], alice);
+ const [staker, recepient] = await helper.arrange.createAccounts([600n, 0n], alice);
await helper.staking.stake(staker, 500n * nominal);
await helper.staking.unstake(staker);
+ // Stakers balance now: {free: <100n, reserved: 500n, miscFrozen: 0, feeFrozen: 0};
+ // Staker can not transfer
+ // TODO expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 500n * nominal, miscFrozen: 0n, feeFrozen: 0n});
+ await expect(helper.balance.transferToSubstrate(staker, recepient.address, 100n * nominal)).to.be.rejected;
+
expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(500n * nominal);
expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);
expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);
+
+ // Wait for unstaking period. Balance now free ~600, and reserved, frozen, miscFrozeb 0n
+ await waitForRelayBlock(helper.api!, 20);
+ expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 0n * nominal, miscFrozen: 0n, feeFrozen: 0n});
+ expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(599n);
});
});
- it('should remove multiple stakes', async () => {
+ it('should successfully unstake multiple stakes', async () => {
await usingPlaygrounds(async helper => {
const [staker] = await helper.arrange.createAccounts([1000n], alice);
await helper.staking.stake(staker, 100n * nominal);
@@ -154,6 +169,11 @@
expect(pendingUnstake).to.be.equal(600n * nominal);
expect(stakedPerBlock).to.be.deep.equal([]);
expect(unstakedPerBlock).to.be.deep.equal([600n * nominal]);
+
+ expect (await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 0n, feeFrozen: 600n * nominal, miscFrozen: 600n * nominal});
+ await waitForRelayBlock(helper.api!, 20);
+ expect (await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 0n, feeFrozen: 0n, miscFrozen: 0n});
+ expect (await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);
});
});
@@ -200,6 +220,8 @@
const [staker] = await helper.arrange.createAccounts([1000n], alice);
await helper.staking.stake(staker, 100n * nominal);
await helper.staking.unstake(staker);
+ await waitForRelayBlock(helper.api!, 20);
+ // expect balance unlocked
expect.fail('Not implemented');
});
});
tests/src/util/playgrounds/types.tsdiffbeforeafterboth123 tokenSymbol: string[]123 tokenSymbol: string[]124}124}125126export interface ISubstrateBalance {127 free: bigint,128 reserved: bigint,129 miscFrozen: bigint,130 feeFrozen: bigint131}125132126export type TSubstrateAccount = string;133export type TSubstrateAccount = string;127export type TEthereumAccount = string;134export type TEthereumAccount = string;tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -9,7 +9,7 @@
import {ApiInterfaceEvents} from '@polkadot/api/types';
import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';
import {IKeyringPair} from '@polkadot/types/types';
-import {IApiListeners, IChainEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';
+import {IApiListeners, IChainEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, TUniqueNetworks} from './types';
const crossAccountIdFromLower = (lowerAddress: ICrossAccountIdLower): ICrossAccountId => {
const address = {} as ICrossAccountId;
@@ -1894,6 +1894,16 @@
}
/**
+ * Get full substrate balance including free, miscFrozen, feeFrozen, and reserved
+ * @param address substrate address
+ * @returns
+ */
+ async getSubstrateFull(address: TSubstrateAccount): Promise<ISubstrateBalance> {
+ const accountInfo = (await this.helper.callRpc('api.query.system.account', [address])).data;
+ return {free: accountInfo.free.toBigInt(), miscFrozen: accountInfo.miscFrozen.toBigInt(), feeFrozen: accountInfo.feeFrozen.toBigInt(), reserved: accountInfo.reserved.toBigInt()};
+ }
+
+ /**
* Get ethereum address balance
* @param address ethereum address
* @example getEthereum("0x9F0583DbB855d...")