git.delta.rocks / unique-network / refs/commits / 3050b513cda0

difftreelog

test add event asserts (#982)

Max Andreev2023-09-06parent: #ec8104e.patch.diff
in: master
* add events asserts

* fix eslint

* eslint fix - unused vars

7 files changed

modifiedtests/src/benchmarks/nesting/index.tsdiffbeforeafterboth
--- a/tests/src/benchmarks/nesting/index.ts
+++ b/tests/src/benchmarks/nesting/index.ts
@@ -1,17 +1,11 @@
 import {EthUniqueHelper, usingEthPlaygrounds} from '../../eth/util';
 import {readFile} from 'fs/promises';
-import {
-  ICrossAccountId,
-} from '../../util/playgrounds/types';
 import {IKeyringPair} from '@polkadot/types/types';
-import {UniqueNFTCollection} from '../../util/playgrounds/unique';
 import {Contract} from 'web3-eth-contract';
-import {createObjectCsvWriter} from 'csv-writer';
-import {convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from '../utils/common';
+import {convertToTokens} from '../utils/common';
 import {makeNames} from '../../util';
 import {ContractImports} from '../../eth/util/playgrounds/types';
 import {RMRKNestableMintable} from './ABIGEN';
-import {rm} from 'fs';
 
 const {dirname} = makeNames(import.meta.url);
 
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
before · tests/src/eth/nesting/nest.test.ts
1import {IKeyringPair} from '@polkadot/types/types';2import {Contract} from 'web3-eth-contract';34import {itEth, EthUniqueHelper, usingEthPlaygrounds, expect} from '../util';56const createNestingCollection = async (7  helper: EthUniqueHelper,8  owner: string,9  mergeDeprecated = false,10): Promise<{ collectionId: number, collectionAddress: string, contract: Contract }> => {11  const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');1213  const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner, mergeDeprecated);14  await contract.methods.setCollectionNesting([true, false, []]).send({from: owner});1516  return {collectionId, collectionAddress, contract};17};181920describe('EVM nesting tests group', () => {21  let donor: IKeyringPair;2223  before(async function() {24    await usingEthPlaygrounds(async (_, privateKey) => {25      donor = await privateKey({url: import.meta.url});26    });27  });2829  describe('Integration Test: EVM Nesting', () => {30    itEth('NFT: allows an Owner to nest/unnest their token', async ({helper}) => {31      const owner = await helper.eth.createAccountWithBalance(donor);32      const {collectionId, contract} = await createNestingCollection(helper, owner);3334      // Create a token to be nested to35      const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});36      const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;37      const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);3839      // Create a nested token40      const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});41      const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;42      expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);4344      // Create a token to be nested and nest45      const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});46      const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;4748      await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});49      expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(targetNftTokenAddress);5051      // Unnest token back52      await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner});53      expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);54    });5556    itEth('NFT: collectionNesting()', async ({helper}) => {57      const owner = await helper.eth.createAccountWithBalance(donor);58      const {collectionAddress: unnestedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');59      const unnestedContract = await helper.ethNativeContract.collection(unnestedCollectionAddress, 'nft', owner);60      expect(await unnestedContract.methods.collectionNesting().call({from: owner})).to.be.like([false, false, []]);6162      const {contract} = await createNestingCollection(helper, owner);63      expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([true, false, []]);64      await contract.methods.setCollectionNesting([true, false, [unnestedCollectionAddress]]).send({from: owner});65      expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([true, false, [unnestedCollectionAddress]]);66      await contract.methods.setCollectionNesting([false, true, [unnestedCollectionAddress]]).send({from: owner});67      expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([false, true, [unnestedCollectionAddress]]);68      await contract.methods.setCollectionNesting([false, false, []]).send({from: owner});69      expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([false, false, []]);70    });7172    // Sof-deprecated73    itEth('NFT: collectionNestingRestrictedCollectionIds() & collectionNestingPermissions', async ({helper}) => {74      const owner = await helper.eth.createAccountWithBalance(donor);75      const {collectionId: unnestedCollsectionId, collectionAddress: unnsetedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');76      const unnestedContract = await helper.ethNativeContract.collection(unnsetedCollectionAddress, 'nft', owner, true);77      expect(await unnestedContract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([false, []]);7879      const {contract} = await createNestingCollection(helper, owner, true);80      expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, []]);81      await contract.methods['setCollectionNesting(bool,address[])'](true, [unnsetedCollectionAddress]).send({from: owner});82      expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, [unnestedCollsectionId.toString()]]);83      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['1', false], ['0', true]]);84      await contract.methods['setCollectionNesting(bool)'](false).send({from: owner});85      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['1', false], ['0', false]]);86    });8788    itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {89      const owner = await helper.eth.createAccountWithBalance(donor);9091      const {collectionId: collectionIdA, contract: contractA} = await createNestingCollection(helper, owner);92      const {contract: contractB} = await createNestingCollection(helper, owner);93      await contractA.methods.setCollectionNesting([true, false, [contractA.options.address, contractB.options.address]]).send({from: owner});9495      // Create a token to nest into96      const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});97      const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;98      const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);99100      // Create a token for nesting in the same collection as the target101      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});102      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;103104      // Create a token for nesting in a different collection105      const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});106      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;107108      // Nest109      await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});110      expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);111112      await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});113      expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);114    });115  });116117  describe('Negative Test: EVM Nesting', () => {118    itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {119      const owner = await helper.eth.createAccountWithBalance(donor);120121      const {collectionId, contract} = await createNestingCollection(helper, owner);122      await contract.methods.setCollectionNesting([false, false, []]).send({from: owner});123124      // Create a token to nest into125      const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});126      const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;127      const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);128129      // Create a token to nest130      const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});131      const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;132133      // Try to nest134      await expect(contract.methods135        .transfer(targetNftTokenAddress, nftTokenId)136        .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');137    });138139    itEth('NFT: disallows a non-Owner to nest someone else\'s token', async ({helper}) => {140      const owner = await helper.eth.createAccountWithBalance(donor);141      const malignant = await helper.eth.createAccountWithBalance(donor);142143      const {collectionId, contract} = await createNestingCollection(helper, owner);144145      // Mint a token146      const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});147      const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;148      const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);149150      // Mint a token belonging to a different account151      const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});152      const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;153154      // Try to nest one token in another as a non-owner account155      await expect(contract.methods156        .transfer(targetTokenAddress, tokenId)157        .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');158    });159160    itEth('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({helper}) => {161      const owner = await helper.eth.createAccountWithBalance(donor);162      const malignant = await helper.eth.createAccountWithBalance(donor);163164      const {collectionId: collectionIdA, contract: contractA} = await createNestingCollection(helper, owner);165      const {collectionId: collectionIdB, contract: contractB} = await createNestingCollection(helper, owner);166167      await contractA.methods.setCollectionNesting([true, false, [contractA.options.address, contractB.options.address]]).send({from: owner});168169      // Create a token in one collection170      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});171      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;172      const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);173174      // Create a token in another collection175      const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});176      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;177178      // Try to drag someone else's token into the other collection and nest179      await expect(contractB.methods180        .transfer(nftTokenAddressA, nftTokenIdB)181        .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');182    });183184    itEth('NFT: disallows to nest token in an unlisted collection', async ({helper}) => {185      const owner = await helper.eth.createAccountWithBalance(donor);186187      const {collectionId: collectionIdA, contract: contractA} = await createNestingCollection(helper, owner);188      const {contract: contractB} = await createNestingCollection(helper, owner);189190      await contractA.methods.setCollectionNesting([true, false, [contractA.options.address]]).send({from: owner});191192      // Create a token in one collection193      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});194      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;195      const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);196197      // Create a token in another collection198      const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});199      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;200201202      // Try to nest into a token in the other collection, disallowed in the first203      await expect(contractB.methods204        .transfer(nftTokenAddressA, nftTokenIdB)205        .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');206    });207  });208209  describe('Fungible', () => {210    async function createFungibleCollection(helper: EthUniqueHelper, owner: string, mode: 'ft' | 'native ft') {211      if(mode === 'ft') {212        const {collectionAddress} = await helper.eth.createFungibleCollection(owner, '', 18, '', '');213        const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);214        await contract.methods.mint(owner, 100n).send({from: owner});215        return {collectionAddress, contract};216      }217218      // native ft219      const collectionAddress = helper.ethAddress.fromCollectionId(0);220      const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);221      return {collectionAddress, contract};222    }223224    [225      {mode: 'ft' as const},226      {mode: 'native ft' as const},227    ].map(testCase => {228      itEth(`Allow nest [${testCase.mode}]`, async ({helper}) => {229        const owner = await helper.eth.createAccountWithBalance(donor);230        const {collectionId: targetCollectionId, contract: targetContract} = await createNestingCollection(helper, owner);231        const {contract: ftContract} = await createFungibleCollection(helper, owner, testCase.mode);232233        const mintingTargetTokenIdResult = await targetContract.methods.mint(owner).send({from: owner});234        const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;235        const targetTokenAddress = helper.ethAddress.fromTokenId(targetCollectionId, targetTokenId);236237        await ftContract.methods.transfer(targetTokenAddress, 10n).send({from: owner});238        expect(await ftContract.methods.balanceOf(targetTokenAddress).call({from: owner})).to.be.equal('10');239      });240    });241242    [243      {mode: 'ft' as const},244      {mode: 'native ft' as const},245    ].map(testCase => {246      itEth(`Allow partial/full unnest [${testCase.mode}]`, async ({helper}) => {247        const owner = await helper.eth.createAccountWithBalance(donor);248        const {collectionId: targetCollectionId, contract: targetContract} = await createNestingCollection(helper, owner);249        const {contract: ftContract} = await createFungibleCollection(helper, owner, testCase.mode);250251        const mintingTargetTokenIdResult = await targetContract.methods.mint(owner).send({from: owner});252        const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;253        const targetTokenAddress = helper.ethAddress.fromTokenId(targetCollectionId, targetTokenId);254255        await ftContract.methods.transfer(targetTokenAddress, 10n).send({from: owner});256257        await ftContract.methods.transferFrom(targetTokenAddress, owner, 5n).send({from: owner});258        expect(await ftContract.methods.balanceOf(targetTokenAddress).call({from: owner})).to.be.equal('5');259260        await ftContract.methods.transferFrom(targetTokenAddress, owner, 5n).send({from: owner});261        expect(await ftContract.methods.balanceOf(targetTokenAddress).call({from: owner})).to.be.equal('0');262      });263    });264265    [266      {mode: 'ft' as const},267      {mode: 'native ft' as const},268    ].map(testCase => {269      itEth(`Disallow nest into collection without nesting permission [${testCase.mode}] (except for native fungible collection)`, async ({helper}) => {270        const owner = await helper.eth.createAccountWithBalance(donor);271        const {collectionId: targetCollectionId, contract: targetContract} = await createNestingCollection(helper, owner);272        await targetContract.methods.setCollectionNesting([false, false, []]).send({from: owner});273274        const {contract: ftContract} = await createFungibleCollection(helper, owner, testCase.mode);275276        const mintingTargetTokenIdResult = await targetContract.methods.mint(owner).send({from: owner});277        const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;278        const targetTokenAddress = helper.ethAddress.fromTokenId(targetCollectionId, targetTokenId);279280        if(testCase.mode === 'ft') {281          await expect(ftContract.methods.transfer(targetTokenAddress, 10n).call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');282        } else {283          await expect(ftContract.methods.transfer(targetTokenAddress, 10n).call({from: owner})).to.be.not.rejected;284        }285      });286    });287  });288});
modifiedtests/src/fetchMetadata.tsdiffbeforeafterboth
--- a/tests/src/fetchMetadata.ts
+++ b/tests/src/fetchMetadata.ts
@@ -1,16 +1,16 @@
-import { writeFile } from "fs/promises";
-import { join } from "path";
-import { exit } from "process";
-import { fileURLToPath } from "url";
+import {writeFile} from 'fs/promises';
+import {join} from 'path';
+import {exit} from 'process';
+import {fileURLToPath} from 'url';
 
 const url = process.env.RPC_URL;
-if (!url) throw new Error('RPC_URL is not set');
+if(!url) throw new Error('RPC_URL is not set');
 
 const srcDir = fileURLToPath(new URL('.', import.meta.url));
 
-for (let i = 0; i < 10; i++) {
+for(let i = 0; i < 10; i++) {
   try {
-    console.log(`Trying to fetch metadata, retry ${i + 1}/${10}`)
+    console.log(`Trying to fetch metadata, retry ${i + 1}/${10}`);
     const response = await fetch(url, {
       method: 'POST',
       headers: {
modifiedtests/src/governance/technicalCommittee.test.tsdiffbeforeafterboth
--- a/tests/src/governance/technicalCommittee.test.ts
+++ b/tests/src/governance/technicalCommittee.test.ts
@@ -36,8 +36,8 @@
     });
   });
 
-  async function proposalFromAllCommittee(proposal: any) {
-    return await usingPlaygrounds(async (helper) => {
+  function proposalFromAllCommittee(proposal: any) {
+    return usingPlaygrounds(async (helper) => {
       expect((await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON().length).to.be.equal(allTechCommitteeThreshold);
       const proposeResult = await helper.technicalCommittee.collective.propose(
         techcomms.andy,
@@ -54,7 +54,13 @@
       await helper.technicalCommittee.collective.vote(techcomms.constantine, proposalHash, proposalIndex, true);
       await helper.technicalCommittee.collective.vote(techcomms.greg, proposalHash, proposalIndex, true);
 
-      return await helper.technicalCommittee.collective.close(techcomms.andy, proposalHash, proposalIndex);
+      const closeResult = await helper.technicalCommittee.collective.close(techcomms.andy, proposalHash, proposalIndex);
+      Event.TechnicalCommittee.Closed.expect(closeResult);
+      Event.TechnicalCommittee.Approved.expect(closeResult);
+      const {result} = Event.TechnicalCommittee.Executed.expect(closeResult);
+      expect(result).to.eq('Ok');
+
+      return closeResult;
     });
   }
 
@@ -64,16 +70,16 @@
 
     await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);
 
-    await expect(proposalFromAllCommittee(helper.democracy.fastTrackCall(preimageHash, democracyFastTrackVotingPeriod, 0)))
-      .to.be.fulfilled;
+    const fastTrackProposal = await proposalFromAllCommittee(helper.democracy.fastTrackCall(preimageHash, democracyFastTrackVotingPeriod, 0));
+    Event.Democracy.Started.expect(fastTrackProposal);
   });
 
   itSub('TechComm can cancel Democracy proposals', async ({helper}) => {
     const proposeResult = await helper.getSudo().democracy.propose(sudoer, dummyProposalCall(helper), 0n);
     const proposalIndex = Event.Democracy.Proposed.expect(proposeResult).proposalIndex;
 
-    await expect(proposalFromAllCommittee(helper.democracy.cancelProposalCall(proposalIndex)))
-      .to.be.fulfilled;
+    const cancelProposal = await proposalFromAllCommittee(helper.democracy.cancelProposalCall(proposalIndex));
+    Event.Democracy.ProposalCanceled.expect(cancelProposal);
   });
 
   itSub('TechComm can cancel ongoing Democracy referendums', async ({helper}) => {
@@ -81,19 +87,19 @@
     const startedEvent = await helper.wait.expectEvent(democracyLaunchPeriod, Event.Democracy.Started);
     const referendumIndex = startedEvent.referendumIndex;
 
-    await expect(proposalFromAllCommittee(helper.democracy.emergencyCancelCall(referendumIndex)))
-      .to.be.fulfilled;
+    const emergencyCancelProposal = await proposalFromAllCommittee(helper.democracy.emergencyCancelCall(referendumIndex));
+    Event.Democracy.Cancelled.expect(emergencyCancelProposal);
   });
-
 
   itSub('TechComm member can veto Democracy proposals', async ({helper}) => {
     const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);
     await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);
 
-    await expect(helper.technicalCommittee.collective.execute(
+    const vetoExternalCall = await helper.technicalCommittee.collective.execute(
       techcomms.andy,
       helper.democracy.vetoExternalCall(preimageHash),
-    )).to.be.fulfilled;
+    );
+    Event.Democracy.Vetoed.expect(vetoExternalCall);
   });
 
   itSub('TechComm can cancel Fellowship referendums', async ({helper}) => {
@@ -108,7 +114,8 @@
       defaultEnactmentMoment,
     );
     const referendumIndex = Event.FellowshipReferenda.Submitted.expect(submitResult).referendumIndex;
-    await expect(proposalFromAllCommittee(helper.fellowship.referenda.cancelCall(referendumIndex))).to.be.fulfilled;
+    const cancelProposal = await proposalFromAllCommittee(helper.fellowship.referenda.cancelCall(referendumIndex));
+    Event.FellowshipReferenda.Cancelled.expect(cancelProposal);
   });
 
   itSub.skip('TechComm member can add a Fellowship member', async ({helper}) => {
modifiedtests/src/maintenance.seqtest.tsdiffbeforeafterboth
--- a/tests/src/maintenance.seqtest.ts
+++ b/tests/src/maintenance.seqtest.ts
@@ -18,7 +18,6 @@
 import {ApiPromise} from '@polkadot/api';
 import {expect, itSched, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util';
 import {itEth} from './eth/util';
-import {UniqueHelper} from './util/playgrounds/unique';
 import {main as correctState} from './migrations/correctStateAfterMaintenance';
 
 async function maintenanceEnabled(api: ApiPromise): Promise<boolean> {
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -174,6 +174,20 @@
     static Passed = this.Method('Passed', data => ({
       referendumIndex: eventJsonData<number>(data, 0),
     }));
+
+    static ProposalCanceled = this.Method('ProposalCanceled', data => ({
+      propIndex: eventJsonData<number>(data, 0),
+    }));
+
+    static Cancelled = this.Method('Cancelled', data => ({
+      propIndex: eventJsonData<number>(data, 0),
+    }));
+
+    static Vetoed = this.Method('Vetoed', data => ({
+      who: eventHumanData(data, 0),
+      proposalHash: eventHumanData(data, 1),
+      until: eventJsonData<number>(data, 1),
+    }));
   };
 
   static Council = class extends EventSection('council') {
@@ -188,6 +202,9 @@
       yes: eventJsonData<number>(data, 1),
       no: eventJsonData<number>(data, 2),
     }));
+    static Executed = this.Method('Executed', data => ({
+      proposalHash: eventHumanData(data, 0),
+    }));
   };
 
   static TechnicalCommittee = class extends EventSection('technicalCommittee') {
@@ -202,6 +219,13 @@
       yes: eventJsonData<number>(data, 1),
       no: eventJsonData<number>(data, 2),
     }));
+    static Approved = this.Method('Approved', data => ({
+      proposalHash: eventHumanData(data, 0),
+    }));
+    static Executed = this.Method('Executed', data => ({
+      proposalHash: eventHumanData(data, 0),
+      result: eventHumanData(data, 1),
+    }));
   };
 
   static FellowshipReferenda = class extends EventSection('fellowshipReferenda') {
@@ -210,6 +234,11 @@
       trackId: eventJsonData<number>(data, 1),
       proposal: eventJsonData(data, 2),
     }));
+
+    static Cancelled = this.Method('Cancelled', data => ({
+      index: eventJsonData<number>(data, 0),
+      tally: eventJsonData(data, 1),
+    }));
   };
 
   static UniqueScheduler = schedulerSection('uniqueScheduler');
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -44,15 +44,11 @@
   MoonbeamAssetInfo,
   DemocracyStandardAccountVote,
   IEthCrossAccountId,
-  CollectionFlag,
   IPhasicEvent,
-  DemocracySplitAccount,
 } from './types';
 import {RuntimeDispatchInfo} from '@polkadot/types/interfaces';
 import type {Vec} from '@polkadot/types-codec';
-import {FrameSupportPreimagesBounded, FrameSupportScheduleDispatchTime, FrameSystemEventRecord, PalletBalancesIdAmount, PalletDemocracyConviction, PalletDemocracyVoteAccountVote} from '@polkadot/types/lookup';
-import {arrayUnzip} from '@polkadot/util';
-import {Event} from './unique.dev';
+import {FrameSystemEventRecord, PalletDemocracyConviction} from '@polkadot/types/lookup';
 
 export class CrossAccountId {
   Substrate!: TSubstrateAccount;