Files
pwap/backend/integration-tests/pez-treasury.live.test.js
T
pezkuwichain 413bcea9da fix: resolve all ESLint errors in launchpad pages
## TypeScript Fixes
- Remove unused imports (useTranslation, TrendingUp, CheckCircle2)
- Replace 'any' types with proper type annotations
- Add PresaleData interface for type safety
- Fix error handling with proper Error type casting

## React Hooks Fixes
- Move loadPresaleData function before useEffect
- Add eslint-disable comments for exhaustive-deps warnings
- Prevent function definition hoisting issues

## Code Quality
- Remove duplicate loadPresaleData function in PresaleDetail
- Proper error message handling with type assertions
- Clean imports and unused variables

All 11 ESLint errors resolved, 0 warnings remaining.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 18:40:11 +03:00

191 lines
7.8 KiB
JavaScript

/**
* @file: pez-treasury.live.test.js
* @description: Live integration tests for the PezTreasury pallet.
*
* @preconditions:
* 1. A local Pezkuwi dev node must be running and accessible at `ws://127.0.0.1:8082`.
* 2. The node must have the `pezTreasury` pallet.
* 3. The tests require a funded sudo account (`//Alice`).
*/
import { ApiPromise, WsProvider, Keyring } from '@polkadot/api';
import { BN } from '@polkadot/util';
import { jest } from '@jest/globals';
// ========================================
// TEST CONFIGURATION
// ========================================
const WS_ENDPOINT = 'ws://127.0.0.1:8082';
jest.setTimeout(300000); // 5 minutes, as this involves waiting for many blocks (months)
// ========================================
// TEST SETUP & TEARDOWN
// ========================================
let api;
let keyring;
let sudo, alice;
// Helper to wait for N finalized blocks
const waitForBlocks = async (count) => {
let blocksLeft = count;
return new Promise(resolve => {
const unsubscribe = api.rpc.chain.subscribeFinalizedHeads(() => {
blocksLeft--;
if (blocksLeft <= 0) {
unsubscribe();
resolve();
}
});
});
};
// Helper to send a transaction and wait for it to be finalized
const sendAndFinalize = (tx, signer) => {
return new Promise((resolve, reject) => {
tx.signAndSend(signer, ({ status, dispatchError }) => {
if (status.isFinalized) {
if (dispatchError) {
const decoded = api.registry.findMetaError(dispatchError.asModule);
reject(new Error(`${decoded.section}.${decoded.name}`));
} else {
resolve();
}
}
}).catch(reject);
});
};
// Helper to get Pez balance
const getPezBalance = async (address) => {
const accountInfo = await api.query.system.account(address);
return new BN(accountInfo.data.free.toString());
};
// Account IDs for treasury pots (from mock.rs)
let treasuryAccountId, incentivePotAccountId, governmentPotAccountId;
beforeAll(async () => {
const wsProvider = new WsProvider(WS_ENDPOINT);
api = await ApiPromise.create({ provider: wsProvider });
keyring = new Keyring({ type: 'sr25519' });
sudo = keyring.addFromUri('//Alice');
alice = keyring.addFromUri('//Bob'); // Non-root user for BadOrigin tests
// Get actual account IDs from the pallet (if exposed as getters)
// Assuming the pallet exposes these as storage maps or constants for JS access
// If not, we'd need to get them from the chain state using a more complex method
treasuryAccountId = (await api.query.pezTreasury.treasuryAccountId()).toString();
incentivePotAccountId = (await api.query.pezTreasury.incentivePotAccountId()).toString();
governmentPotAccountId = (await api.query.pezTreasury.governmentPotAccountId()).toString();
console.log('Connected to node and initialized accounts for PezTreasury tests.');
console.log(`Treasury Account ID: ${treasuryAccountId}`);
console.log(`Incentive Pot Account ID: ${incentivePotAccountId}`);
console.log(`Government Pot Account ID: ${governmentPotAccountId}`);
}, 40000);
afterAll(async () => {
if (api) await api.disconnect();
console.log('Disconnected from node.');
});
describe('PezTreasury Pallet Live Workflow', () => {
// We run the tests in a single, sequential `it` block to manage state
// across different periods without complex cleanup.
it('should execute a full treasury lifecycle including genesis, initialization, monthly releases, and halving', async () => {
// Constants from the pallet (assuming they are exposed)
const BLOCKS_PER_MONTH = api.consts.pezTreasury.blocksPerMonth.toNumber();
const HALVING_PERIOD_MONTHS = api.consts.pezTreasury.halvingPeriodMonths.toNumber();
const PARITY = new BN(1_000_000_000_000); // 10^12 for 1 PEZ
// -----------------------------------------------------------------
// PHASE 1: GENESIS DISTRIBUTION
// -----------------------------------------------------------------
console.log('PHASE 1: Performing genesis distribution...');
await sendAndFinalize(api.tx.pezTreasury.doGenesisDistribution(), sudo);
const treasuryBalanceAfterGenesis = await getPezBalance(treasuryAccountId);
expect(treasuryBalanceAfterGenesis.gt(new BN(0))).toBe(true);
console.log(`Treasury balance after genesis: ${treasuryBalanceAfterGenesis}`);
// Verify cannot distribute twice
await expect(
sendAndFinalize(api.tx.pezTreasury.doGenesisDistribution(), sudo)
).rejects.toThrow('pezTreasury.GenesisDistributionAlreadyDone');
console.log('Verified: Genesis distribution cannot be done twice.');
// -----------------------------------------------------------------
// PHASE 2: INITIALIZE TREASURY
// -----------------------------------------------------------------
console.log('PHASE 2: Initializing treasury...');
await sendAndFinalize(api.tx.pezTreasury.initializeTreasury(), sudo);
let halvingInfo = await api.query.pezTreasury.halvingInfo();
expect(halvingInfo.currentPeriod.toNumber()).toBe(0);
expect(halvingInfo.monthlyAmount.gt(new BN(0))).toBe(true);
console.log(`Treasury initialized. Initial monthly amount: ${halvingInfo.monthlyAmount}`);
// Verify cannot initialize twice
await expect(
sendAndFinalize(api.tx.pezTreasury.initializeTreasury(), sudo)
).rejects.toThrow('pezTreasury.TreasuryAlreadyInitialized');
console.log('Verified: Treasury cannot be initialized twice.');
// -----------------------------------------------------------------
// PHASE 3: MONTHLY RELEASES (Before Halving)
// -----------------------------------------------------------------
console.log('PHASE 3: Performing monthly releases (before halving)...');
const initialMonthlyAmount = halvingInfo.monthlyAmount;
const monthsToReleaseBeforeHalving = HALVING_PERIOD_MONTHS - 1; // Release up to 47th month
for (let month = 0; month < monthsToReleaseBeforeHalving; month++) {
console.log(`Releasing for month ${month}... (Current Block: ${(await api.rpc.chain.getHeader()).number.toNumber()})`);
await waitForBlocks(BLOCKS_PER_MONTH + 1); // +1 to ensure we are past the boundary
await sendAndFinalize(api.tx.pezTreasury.releaseMonthlyFunds(), sudo);
const nextReleaseMonth = (await api.query.pezTreasury.nextReleaseMonth()).toNumber();
expect(nextReleaseMonth).toBe(month + 1);
}
console.log(`Released funds for ${monthsToReleaseBeforeHalving} months.`);
// -----------------------------------------------------------------
// PHASE 4: HALVING
// -----------------------------------------------------------------
console.log('PHASE 4: Triggering halving at month 48...');
// Release the 48th month, which should trigger halving
await waitForBlocks(BLOCKS_PER_MONTH + 1);
await sendAndFinalize(api.tx.pezTreasury.releaseMonthlyFunds(), sudo);
halvingInfo = await api.query.pezTreasury.halvingInfo();
expect(halvingInfo.currentPeriod.toNumber()).toBe(1);
expect(halvingInfo.monthlyAmount.toString()).toBe(initialMonthlyAmount.div(new BN(2)).toString());
console.log(`Halving successful. New monthly amount: ${halvingInfo.monthlyAmount}`);
// -----------------------------------------------------------------
// PHASE 5: VERIFY BAD ORIGIN
// -----------------------------------------------------------------
console.log('PHASE 5: Verifying BadOrigin errors...');
// Try to initialize treasury as non-root
await expect(
sendAndFinalize(api.tx.pezTreasury.initializeTreasury(), alice)
).rejects.toThrow('system.BadOrigin');
console.log('Verified: Non-root cannot initialize treasury.');
// Try to release funds as non-root
await expect(
sendAndFinalize(api.tx.pezTreasury.releaseMonthlyFunds(), alice)
).rejects.toThrow('system.BadOrigin');
console.log('Verified: Non-root cannot release monthly funds.');
});
});