git.delta.rocks / unique-network / refs/commits / c9b1f9ac6704

difftreelog

source

js-packages/tests/sub/governance/technicalCommittee.test.ts17.4 KiBsourcehistory
1import type {IKeyringPair} from '@polkadot/types/types';2import {usingPlaygrounds, itSub, expect, Pallets, requirePalletsOrSkip, describeGov} from '@unique/test-utils/util.js';3import {Event} from '@unique/test-utils';4import {initCouncil, democracyLaunchPeriod, democracyFastTrackVotingPeriod, clearCouncil, clearTechComm, clearFellowship, defaultEnactmentMoment, dummyProposal, dummyProposalCall, fellowshipPropositionOrigin, initFellowship, initTechComm, hardResetFellowshipReferenda, hardResetDemocracy, hardResetGovScheduler} from './util.js';5import type {ITechComms} from './util.js';67describeGov('Governance: Technical Committee tests', () => {8  let sudoer: IKeyringPair;9  let techcomms: ITechComms;10  let donor: IKeyringPair;11  let preImageHash: string;121314  const allTechCommitteeThreshold = 3;1516  before(async function() {17    await usingPlaygrounds(async (helper, privateKey) => {18      requirePalletsOrSkip(this, helper, [Pallets.TechnicalCommittee]);19      sudoer = await privateKey('//Alice');20      donor = await privateKey({url: import.meta.url});2122      techcomms = await initTechComm(donor, sudoer);2324      const proposalCall = await helper.constructApiCall('api.tx.balances.forceSetBalance', [donor.address, 20n * 10n ** 25n]);25      preImageHash = await helper.preimage.notePreimageFromCall(sudoer, proposalCall, true);26    });27  });2829  after(async () => {30    await usingPlaygrounds(async (helper) => {31      await clearTechComm(sudoer);3233      await helper.preimage.unnotePreimage(sudoer, preImageHash);34      await hardResetFellowshipReferenda(sudoer);35      await hardResetDemocracy(sudoer);36      await hardResetGovScheduler(sudoer);37    });38  });3940  function proposalFromAllCommittee(proposal: any) {41    return usingPlaygrounds(async (helper) => {42      expect((await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON().length).to.be.equal(allTechCommitteeThreshold);43      const proposeResult = await helper.technicalCommittee.collective.propose(44        techcomms.andy,45        proposal,46        allTechCommitteeThreshold,47      );4849      const commiteeProposedEvent = Event.TechnicalCommittee.Proposed.expect(proposeResult);50      const proposalIndex = commiteeProposedEvent.proposalIndex;51      const proposalHash = commiteeProposedEvent.proposalHash;525354      await helper.technicalCommittee.collective.vote(techcomms.andy, proposalHash, proposalIndex, true);55      await helper.technicalCommittee.collective.vote(techcomms.constantine, proposalHash, proposalIndex, true);56      await helper.technicalCommittee.collective.vote(techcomms.greg, proposalHash, proposalIndex, true);5758      const closeResult = await helper.technicalCommittee.collective.close(techcomms.andy, proposalHash, proposalIndex);59      Event.TechnicalCommittee.Closed.expect(closeResult);60      Event.TechnicalCommittee.Approved.expect(closeResult);61      const {result} = Event.TechnicalCommittee.Executed.expect(closeResult);62      expect(result).to.eq('Ok');6364      return closeResult;65    });66  }6768  itSub('TechComm can fast-track Democracy proposals', async ({helper}) => {69    const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);70    await helper.wait.parachainBlockMultiplesOf(35n);7172    await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);7374    const fastTrackProposal = await proposalFromAllCommittee(helper.democracy.fastTrackCall(preimageHash, democracyFastTrackVotingPeriod, 0));75    Event.Democracy.Started.expect(fastTrackProposal);76  });7778  itSub('TechComm can cancel Democracy proposals', async ({helper}) => {79    const proposeResult = await helper.getSudo().democracy.propose(sudoer, dummyProposalCall(helper), 0n);80    const proposalIndex = Event.Democracy.Proposed.expect(proposeResult).proposalIndex;8182    const cancelProposal = await proposalFromAllCommittee(helper.democracy.cancelProposalCall(proposalIndex));83    Event.Democracy.ProposalCanceled.expect(cancelProposal);84  });8586  itSub('TechComm can cancel ongoing Democracy referendums', async ({helper}) => {87    await helper.getSudo().democracy.externalProposeDefault(sudoer, dummyProposalCall(helper));88    const startedEvent = await helper.wait.expectEvent(democracyLaunchPeriod, Event.Democracy.Started);89    const referendumIndex = startedEvent.referendumIndex;9091    const emergencyCancelProposal = await proposalFromAllCommittee(helper.democracy.emergencyCancelCall(referendumIndex));92    Event.Democracy.Cancelled.expect(emergencyCancelProposal);93  });9495  itSub('TechComm member can veto Democracy proposals', async ({helper}) => {96    const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);97    await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);9899    const vetoExternalCall = await helper.technicalCommittee.collective.execute(100      techcomms.andy,101      helper.democracy.vetoExternalCall(preimageHash),102    );103    Event.Democracy.Vetoed.expect(vetoExternalCall);104  });105106  itSub('TechComm can cancel Fellowship referendums', async ({helper}) => {107    const fellowship = await initFellowship(donor, sudoer);108    const fellowshipProposer = fellowship[5][0];109    const proposal = dummyProposal(helper);110111    const submitResult = await helper.fellowship.referenda.submit(112      fellowshipProposer,113      fellowshipPropositionOrigin,114      proposal,115      defaultEnactmentMoment,116    );117    const referendumIndex = Event.FellowshipReferenda.Submitted.expect(submitResult).referendumIndex;118    const cancelProposal = await proposalFromAllCommittee(helper.fellowship.referenda.cancelCall(referendumIndex));119    Event.FellowshipReferenda.Cancelled.expect(cancelProposal);120  });121122  itSub.skip('TechComm member can add a Fellowship member', async ({helper}) => {123    const newFellowshipMember = helper.arrange.createEmptyAccount();124    await expect(helper.technicalCommittee.collective.execute(125      techcomms.andy,126      helper.fellowship.collective.addMemberCall(newFellowshipMember.address),127    )).to.be.fulfilled;128    const fellowshipMembers = (await helper.callRpc('api.query.fellowshipCollective.members')).toJSON();129    expect(fellowshipMembers).to.contains(newFellowshipMember.address);130    await clearFellowship(sudoer);131  });132133  itSub('[Negative] TechComm cannot submit regular democracy proposal', async ({helper}) => {134    const councilProposal = await helper.democracy.proposeCall(dummyProposalCall(helper), 0n);135136    await expect(proposalFromAllCommittee(councilProposal)).to.be.rejectedWith('BadOrigin');137  });138139  itSub('[Negative] TechComm cannot externally propose SuperMajorityAgainst', async ({helper}) => {140    const commiteeProposal = await helper.democracy.externalProposeDefaultCall(dummyProposalCall(helper));141142    await expect(proposalFromAllCommittee(commiteeProposal)).to.be.rejectedWith('BadOrigin');143  });144145  itSub('[Negative] TechComm cannot externally propose SimpleMajority', async ({helper}) => {146    const commiteeProposal = await helper.democracy.externalProposeMajorityCall(dummyProposalCall(helper));147148    await expect(proposalFromAllCommittee(commiteeProposal)).to.be.rejectedWith('BadOrigin');149  });150151  itSub('[Negative] TechComm cannot externally propose SuperMajorityApprove', async ({helper}) => {152    const commiteeProposal = await helper.democracy.externalProposeCall(dummyProposalCall(helper));153154    await expect(proposalFromAllCommittee(commiteeProposal)).to.be.rejectedWith('BadOrigin');155  });156157  itSub('[Negative] TechComm member cannot submit regular democracy proposal', async ({helper}) => {158    const memberProposal = await helper.democracy.proposeCall(dummyProposalCall(helper), 0n);159160    await expect(helper.technicalCommittee.collective.execute(161      techcomms.andy,162      memberProposal,163    )).to.be.rejectedWith('BadOrigin');164  });165166  itSub('[Negative] TechComm member cannot externally propose SuperMajorityAgainst', async ({helper}) => {167    const memberProposal = await helper.democracy.externalProposeDefaultCall(dummyProposalCall(helper));168169    await expect(helper.technicalCommittee.collective.execute(170      techcomms.andy,171      memberProposal,172    )).to.be.rejectedWith('BadOrigin');173  });174175  itSub('[Negative] TechComm member cannot externally propose SimpleMajority', async ({helper}) => {176    const memberProposal = await helper.democracy.externalProposeMajorityCall(dummyProposalCall(helper));177178    await expect(helper.technicalCommittee.collective.execute(179      techcomms.andy,180      memberProposal,181    )).to.be.rejectedWith('BadOrigin');182  });183184  itSub('[Negative] TechComm member cannot externally propose SuperMajorityApprove', async ({helper}) => {185    const memberProposal = await helper.democracy.externalProposeCall(dummyProposalCall(helper));186187    await expect(helper.technicalCommittee.collective.execute(188      techcomms.andy,189      memberProposal,190    )).to.be.rejectedWith('BadOrigin');191  });192193194  itSub.skip('[Negative] TechComm cannot promote/demote Fellowship member', async () => {195196  });197198  itSub.skip('[Negative] TechComm member cannot promote/demote Fellowship member', async () => {199200  });201202  itSub('[Negative] TechComm cannot add/remove a Council member', async ({helper}) => {203    const newCouncilMember = helper.arrange.createEmptyAccount();204    const addMemberProposal = helper.council.membership.addMemberCall(newCouncilMember.address);205    const removeMemberProposal = helper.council.membership.removeMemberCall(newCouncilMember.address);206207    await expect(proposalFromAllCommittee(addMemberProposal)).to.be.rejectedWith('BadOrigin');208    await expect(proposalFromAllCommittee(removeMemberProposal)).to.be.rejectedWith('BadOrigin');209  });210211  itSub('[Negative] TechComm member cannot add/remove a Council member', async ({helper}) => {212    const newCouncilMember = helper.arrange.createEmptyAccount();213    const addMemberProposal = helper.council.membership.addMemberCall(newCouncilMember.address);214    const removeMemberProposal = helper.council.membership.removeMemberCall(newCouncilMember.address);215216    await expect(helper.technicalCommittee.collective.execute(217      techcomms.andy,218      addMemberProposal,219    )).to.be.rejectedWith('BadOrigin');220    await expect(helper.technicalCommittee.collective.execute(221      techcomms.andy,222      removeMemberProposal,223    )).to.be.rejectedWith('BadOrigin');224  });225226  itSub('[Negative] TechComm cannot set/clear Council prime member', async ({helper}) => {227    const counselors = await initCouncil(donor, sudoer);228    const proposalForSet = await helper.council.membership.setPrimeCall(counselors.charu.address);229    const proposalForClear = await helper.council.membership.clearPrimeCall();230231    await expect(proposalFromAllCommittee(proposalForSet)).to.be.rejectedWith('BadOrigin');232    await expect(proposalFromAllCommittee(proposalForClear)).to.be.rejectedWith('BadOrigin');233    await clearCouncil(sudoer);234  });235236  itSub('[Negative] TechComm member cannot set/clear Council prime member', async ({helper}) => {237    const counselors = await initCouncil(donor, sudoer);238    const proposalForSet = await helper.council.membership.setPrimeCall(counselors.charu.address);239    const proposalForClear = await helper.council.membership.clearPrimeCall();240241    await expect(helper.technicalCommittee.collective.execute(242      techcomms.andy,243      proposalForSet,244    )).to.be.rejectedWith('BadOrigin');245    await expect(helper.technicalCommittee.collective.execute(246      techcomms.andy,247      proposalForClear,248    )).to.be.rejectedWith('BadOrigin');249    await clearCouncil(sudoer);250  });251252  itSub('[Negative] TechComm cannot add/remove a TechComm member', async ({helper}) => {253    const newCommMember = helper.arrange.createEmptyAccount();254    const addMemberProposal = helper.council.membership.addMemberCall(newCommMember.address);255    const removeMemberProposal = helper.council.membership.removeMemberCall(newCommMember.address);256257    await expect(proposalFromAllCommittee(addMemberProposal)).to.be.rejectedWith('BadOrigin');258    await expect(proposalFromAllCommittee(removeMemberProposal)).to.be.rejectedWith('BadOrigin');259  });260261  itSub('[Negative] TechComm member cannot add/remove a TechComm member', async ({helper}) => {262    const newCommMember = helper.arrange.createEmptyAccount();263    const addMemberProposal = helper.council.membership.addMemberCall(newCommMember.address);264    const removeMemberProposal = helper.council.membership.removeMemberCall(newCommMember.address);265266    await expect(helper.technicalCommittee.collective.execute(267      techcomms.andy,268      addMemberProposal,269    )).to.be.rejectedWith('BadOrigin');270    await expect(helper.technicalCommittee.collective.execute(271      techcomms.andy,272      removeMemberProposal,273    )).to.be.rejectedWith('BadOrigin');274  });275276  itSub('[Negative] TechComm cannot remove a Fellowship member', async ({helper}) => {277    const fellowship = await initFellowship(donor, sudoer);278279    await expect(proposalFromAllCommittee(helper.fellowship.collective.removeMemberCall(fellowship[5][0].address, 5))).to.be.rejectedWith('BadOrigin');280    await clearFellowship(sudoer);281  });282283  itSub('[Negative] TechComm member cannot remove a Fellowship member', async ({helper}) => {284    const fellowship = await initFellowship(donor, sudoer);285286    await expect(helper.technicalCommittee.collective.execute(287      techcomms.andy,288      helper.fellowship.collective.removeMemberCall(fellowship[5][0].address, 5),289    )).to.be.rejectedWith('BadOrigin');290    await clearFellowship(sudoer);291  });292293  itSub('[Negative] TechComm member cannot fast-track Democracy proposals', async ({helper}) => {294    const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);295    await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);296297    await expect(helper.technicalCommittee.collective.execute(298      techcomms.andy,299      helper.democracy.fastTrackCall(preimageHash, democracyFastTrackVotingPeriod, 0),300    )).to.be.rejectedWith('BadOrigin');301  });302303  itSub('[Negative] TechComm member cannot cancel Democracy proposals', async ({helper}) => {304    const proposeResult = await helper.getSudo().democracy.propose(sudoer, dummyProposalCall(helper), 0n);305    const proposalIndex = Event.Democracy.Proposed.expect(proposeResult).proposalIndex;306307    await expect(helper.technicalCommittee.collective.execute(308      techcomms.andy,309      helper.democracy.cancelProposalCall(proposalIndex),310    ))311      .to.be.rejectedWith('BadOrigin');312  });313314  itSub('[Negative] TechComm member cannot cancel ongoing Democracy referendums', async ({helper}) => {315    await helper.getSudo().democracy.externalProposeDefault(sudoer, dummyProposalCall(helper));316    const startedEvent = await helper.wait.expectEvent(democracyLaunchPeriod, Event.Democracy.Started);317    const referendumIndex = startedEvent.referendumIndex;318319    await expect(helper.technicalCommittee.collective.execute(320      techcomms.andy,321      helper.democracy.emergencyCancelCall(referendumIndex),322    )).to.be.rejectedWith('BadOrigin');323  });324325  itSub('[Negative] TechComm cannot blacklist Democracy proposals', async ({helper}) => {326    const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);327    await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);328329    await expect(proposalFromAllCommittee(helper.democracy.blacklistCall(preimageHash))).to.be.rejectedWith('BadOrigin');330  });331332  itSub('[Negative] TechComm member cannot blacklist Democracy proposals', async ({helper}) => {333    const preimageHash = await helper.preimage.notePreimageFromCall(sudoer, dummyProposalCall(helper), true);334    await helper.getSudo().democracy.externalProposeDefaultWithPreimage(sudoer, preimageHash);335336    await expect(helper.technicalCommittee.collective.execute(337      techcomms.andy,338      helper.democracy.blacklistCall(preimageHash),339    )).to.be.rejectedWith('BadOrigin');340  });341342  itSub.skip('[Negative] TechComm member cannot veto external Democracy proposals until the cool-off period pass', async () => {343344  });345346  itSub('[Negative] TechComm member cannot cancel Fellowship referendums', async ({helper}) => {347    const fellowship = await initFellowship(donor, sudoer);348    const fellowshipProposer = fellowship[5][0];349    const proposal = dummyProposal(helper);350351    const submitResult = await helper.fellowship.referenda.submit(352      fellowshipProposer,353      fellowshipPropositionOrigin,354      proposal,355      defaultEnactmentMoment,356    );357358    const referendumIndex = Event.FellowshipReferenda.Submitted.expect(submitResult).referendumIndex;359360    await expect(helper.technicalCommittee.collective.execute(361      techcomms.andy,362      helper.fellowship.referenda.cancelCall(referendumIndex),363    )).to.be.rejectedWith('BadOrigin');364  });365366  itSub('[Negative] TechComm referendum cannot be closed until the voting threshold is met', async ({helper}) => {367    const committeeSize = (await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON().length as any as number;368    expect(committeeSize).is.greaterThan(1);369    const proposeResult = await helper.technicalCommittee.collective.propose(370      techcomms.andy,371      dummyProposalCall(helper),372      committeeSize,373    );374375    const committeeProposedEvent = Event.TechnicalCommittee.Proposed.expect(proposeResult);376    const proposalIndex = committeeProposedEvent.proposalIndex;377    const proposalHash = committeeProposedEvent.proposalHash;378379    await helper.technicalCommittee.collective.vote(techcomms.constantine, proposalHash, proposalIndex, true);380381    await expect(helper.technicalCommittee.collective.close(techcomms.andy, proposalHash, proposalIndex)).to.be.rejectedWith('TooEarly');382  });383});