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, democracyVotingPeriod, democracyEnactmentPeriod, clearCouncil, clearTechComm, initTechComm, ITechComms} from './util.js';5import type {ICounselors} from './util.js';67describeGov('Governance: Elect Sudo', () => {8 let sudoer: IKeyringPair;9 let donor: IKeyringPair;10 let counselors: ICounselors;11 let techComm: ITechComms;1213 const moreThanHalfCouncilThreshold = 3;1415 before(async function() {16 await usingPlaygrounds(async (helper, privateKey) => {17 requirePalletsOrSkip(this, helper, [Pallets.Council]);1819 sudoer = await privateKey('//Alice');20 donor = await privateKey({url: import.meta.url});21 counselors = await initCouncil(donor, sudoer);22 techComm = await initTechComm(donor, sudoer);23 });24 });2526 after(async () => {27 await clearCouncil(sudoer);28 await clearTechComm(sudoer);29 });3031 itSub('Democracy can elect a sudo account', async ({helper}) => {32 const [newAccount] = await helper.arrange.createAccounts([1000n], donor);33 const newSudoKey = newAccount.address;3435 36 afterEach(async () => {37 38 await usingPlaygrounds(async (helper) => {39 await helper.executeExtrinsic(40 newAccount,41 'api.tx.sudo.setKey',42 [sudoer.address],43 false,44 );45 });46 });4748 const democracyProposal = helper.constructApiCall('api.tx.utility.dispatchAs', [49 {50 system: {51 Signed: sudoer.address,52 },53 },54 helper.constructApiCall('api.tx.sudo.setKey', [newSudoKey]),55 ]);5657 const councilProposal = await helper.democracy.externalProposeDefaultCall(democracyProposal);5859 const proposeResult = await helper.council.collective.propose(60 counselors.filip,61 councilProposal,62 moreThanHalfCouncilThreshold,63 );6465 const councilProposedEvent = Event.Council.Proposed.expect(proposeResult);66 const proposalIndex = councilProposedEvent.proposalIndex;67 const proposalHash = councilProposedEvent.proposalHash;6869 await helper.council.collective.vote(counselors.alex, proposalHash, proposalIndex, true);70 await helper.council.collective.vote(counselors.charu, proposalHash, proposalIndex, true);71 await helper.council.collective.vote(counselors.filip, proposalHash, proposalIndex, true);7273 await helper.council.collective.close(counselors.filip, proposalHash, proposalIndex);7475 const democracyStartedEvent = await helper.wait.expectEvent(democracyLaunchPeriod, Event.Democracy.Started);76 const democracyReferendumIndex = democracyStartedEvent.referendumIndex;77 const democracyThreshold = democracyStartedEvent.threshold;7879 expect(democracyThreshold).to.be.equal('SuperMajorityAgainst');8081 await helper.democracy.vote(newAccount, democracyReferendumIndex, {82 Standard: {83 vote: {84 aye: true,85 conviction: 1,86 },87 balance: 800n,88 },89 });9091 const passedReferendumEvent = await helper.wait.expectEvent(democracyVotingPeriod, Event.Democracy.Passed);92 expect(passedReferendumEvent.referendumIndex).to.be.equal(democracyReferendumIndex);9394 await helper.wait.expectEvent(democracyEnactmentPeriod, Event.Scheduler.Dispatched);95 const currentSudoKey = await helper.callRpc('api.query.sudo.key', [])96 .then(k => k.toString());97 expect(currentSudoKey).to.be.equal(newSudoKey);98 });99});