import {afterAll, beforeAll, expect, suite, test} from 'vitest' import * as dotenv from 'dotenv' import fs from 'fs' import {init, KeyringPair, Substrate, SubstrateUnique} from "../index"; import { Address } from '../utils'; declare module 'vitest' { export interface Suite { chain: SubstrateUnique keyring1: KeyringPair keyring2: KeyringPair keyringAlice: KeyringPair keyringBob: KeyringPair } } beforeAll(async (context) => { const config = dotenv.parse(fs.readFileSync('./src/test/.test.env').toString('utf8')) await init() const chain = new Substrate.Unique() await chain.connect(config.NODE_SUB) context.chain = chain context.keyring1 = Substrate.signer.keyringFromSeed(config.SUB_SEED_1) context.keyring2 = Substrate.signer.keyringFromSeed(config.SUB_SEED_2) context.keyringAlice = Substrate.signer.keyringFromSeed(config.SUB_SEED_ALICE) context.keyringBob = Substrate.signer.keyringFromSeed(config.SUB_SEED_BOB) }) afterAll(async (context) => { const {chain, keyring1, keyring2} = context const [balance1, balance2] = await Promise.all([ chain.getBalance(keyring1.address), chain.getBalance(keyring2.address), ]) console.log(`After all balance of ${keyring1.address} is ${chain.coin.formatFullLength(balance1)}`) console.log(`After all balance of ${keyring2.address} is ${chain.coin.formatFullLength(balance2)}`) }) const transferCoins = async (chain: SubstrateUnique, from: KeyringPair, to: KeyringPair) => { const threshold = chain.coin.coinsToWei(`1000`) // 1000 QTZ const balanceBefore = await chain.getBalance(to.address) const toSend = (balanceBefore < threshold) ? threshold - balanceBefore : 1n console.log( `Transferring ${chain.coin.formatFullLength(toSend)} ` + `from ${from.address} to ${to.address}. ` + `Balance before is ${chain.coin.format(balanceBefore, chain.coin.decimals)}` ) await chain .transferCoins({toAddress: to.address, amountInWei: toSend}) .signAndSend(from) const balanceAfter = await chain.getBalance(to.address) console.log( `Balance of ${to.address} after is ` + chain.coin.format(balanceAfter, chain.coin.decimals) ) expect(balanceAfter - balanceBefore).toBe(toSend) } suite('extrinsics', async () => { test('isConnected', async (ctx) => { const {chain} = ctx.meta.suite.file! expect(chain.isConnected).toBe(true) }) test('transfer tokens', async (ctx) => { const {chain, keyring1, keyring2, keyringAlice, keyringBob} = ctx.meta.suite.file! await Promise.all([ transferCoins(chain, keyringAlice, keyring1), transferCoins(chain, keyringBob, keyring2) ]) }) }) suite('CollectionSponsor tests', async () => { test('Set sponsor for collection', async (ctx) => { const {chain, keyring1} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const setCollectionSponsorResult = await chain.setCollectionSponsor({ collectionId: createCollectionResult.collectionId, newSponsorAddress: keyring1.address }) .signAndSend(keyring1); expect(setCollectionSponsorResult.isSuccess).toBe(true); }) test('Remove collection sponsor', async (ctx) => { const {chain, keyring1} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const setCollectionSponsorResult = await chain.setCollectionSponsor({ collectionId: createCollectionResult.collectionId, newSponsorAddress: keyring1.address }) .signAndSend(keyring1); expect(setCollectionSponsorResult.isSuccess).toBe(true); const removeCollectionSponsorResult = await chain.removeCollectionSponsor({ collectionId: createCollectionResult.collectionId }) .signAndSend(keyring1) expect(removeCollectionSponsorResult.isSuccess).toBe(true) }) test('Confirm sponsorship', async (ctx) => { const {chain, keyring1, keyringBob} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const setCollectionSponsorResult = await chain.setCollectionSponsor({ collectionId: createCollectionResult.collectionId, newSponsorAddress: keyringBob.address }) .signAndSend(keyring1) expect(setCollectionSponsorResult.isSuccess).toBe(true) const confirmCollectionSponsorResult = await chain.confirmSponsorship({collectionId: createCollectionResult.collectionId}) .signAndSend(keyringBob) expect(confirmCollectionSponsorResult.isSuccess).toBe(true) }) test('[Negative test]: Confirm sponsorship by another user', async (ctx) => { const {chain, keyring1, keyringBob} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const setCollectionSponsorResult = await chain.setCollectionSponsor({ collectionId: createCollectionResult.collectionId, newSponsorAddress: keyringBob.address }) .signAndSend(keyring1) expect(setCollectionSponsorResult.isSuccess).toBe(true) await expect(chain.confirmSponsorship({collectionId: createCollectionResult.collectionId}) .signAndSend(keyring1)) .rejects .toThrow('unique.ConfirmUnsetSponsorFail') }) }) suite('Add & remove collection Admin tests', async () => { test('Add & remove collection admin', async (ctx) => { const {chain, keyring1, keyring2} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const collectionId = createCollectionResult.collectionId; const addCollectionAdminResult = await chain.addCollectionAdmin({ collectionId: collectionId, newAdminAddress: keyring2.address }) .signAndSend(keyring1) expect(addCollectionAdminResult.isSuccess).toBe(true) const removeCollectionAdminResult = await chain.removeCollectionAdmin({ collectionId: collectionId, adminAddress: keyring2.address }) .signAndSend(keyring1) expect(removeCollectionAdminResult.isSuccess).toBe(true) }) test('[Negative test] add collection admin by not an owner', async (ctx) => { const {chain, keyring1, keyring2} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const collectionId = createCollectionResult.collectionId; await expect(chain.addCollectionAdmin({collectionId: collectionId, newAdminAddress: keyring2.address}) .signAndSend(keyring2)) .rejects .toThrow('common.NoPermission') }) test('[Negative test] Removing collection admin by non admin user', async (ctx) => { const {chain, keyring1, keyring2, keyringBob} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const collectionId = createCollectionResult.collectionId; const addCollectionAdminResult = await chain.addCollectionAdmin({ collectionId: collectionId, newAdminAddress: keyring2.address }) .signAndSend(keyring1) expect(addCollectionAdminResult.isSuccess).toBe(true) await expect(chain.removeCollectionAdmin({collectionId: collectionId, adminAddress: keyring2.address}) .signAndSend(keyringBob)) .rejects .toThrow('common.NoPermission') }) }) suite('ChangeCollectionOwner tests', async () => { test('ChangeCollectionOwner', async (ctx) => { const {chain, keyring1, keyring2, keyringBob} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const collectionId = createCollectionResult.collectionId; const changeOwnerResult = await chain.changeCollectionOwner({ collectionId: collectionId, newOwnerAddress: keyring2.address }).signAndSend(keyring1) expect(changeOwnerResult.isSuccess).toBe(true) //FIXME: change collectionById method asap const collection = await chain.getCollection(collectionId) expect(collection).not.toBeFalsy() expect(keyring2.address).toBe(Address.normalize.substrateAddress(collection!.owner.toString())) }) }) suite('Allow list tests', async () => { test('Add and remove in/from allow list', async (ctx) => { const {chain, keyring1, keyring2, keyringBob} = ctx.meta.suite.file! const createCollectionResult = await chain.createCollection({ collection: { name: 'test-name', description: 'test-descr', tokenPrefix: '0xff' } }) .signAndSend(keyring1) const addToAllowListResult = await chain.addToAllowList({ collectionId: createCollectionResult.collectionId, address: keyring2.address }) .signAndSend(keyring1) expect(addToAllowListResult.isSuccess).toBe(true) const removeFromAllowListResult = await chain.removeFromAllowList({ collectionId: createCollectionResult.collectionId, address: keyring2.address }) .signAndSend(keyring1) expect(removeFromAllowListResult.isSuccess).toBe(true) }) })