Browse Source

proposals and working group fixtures refactored

Gleb Urvanov 4 years ago
parent
commit
57d098665d
27 changed files with 2310 additions and 1760 deletions
  1. 1 1
      tests/network-tests/package.json
  2. 0 100
      tests/network-tests/src/iznik/tests/impl/electingCouncil.ts
  3. 0 86
      tests/network-tests/src/iznik/tests/impl/membershipCreation.ts
  4. 53 15
      tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts
  5. 50 15
      tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts
  6. 0 124
      tests/network-tests/src/iznik/tests/proposals/impl/electionParametersProposal.ts
  7. 941 291
      tests/network-tests/src/iznik/tests/proposals/impl/proposalsModule.ts
  8. 0 46
      tests/network-tests/src/iznik/tests/proposals/impl/setLeadProposal.ts
  9. 0 64
      tests/network-tests/src/iznik/tests/proposals/impl/spendingProposal.ts
  10. 0 46
      tests/network-tests/src/iznik/tests/proposals/impl/textProposal.ts
  11. 0 52
      tests/network-tests/src/iznik/tests/proposals/impl/updateRuntime.ts
  12. 0 55
      tests/network-tests/src/iznik/tests/proposals/impl/validatorCountProposal.ts
  13. 0 59
      tests/network-tests/src/iznik/tests/proposals/impl/workingGroupMintCapacityProposal.ts
  14. 229 159
      tests/network-tests/src/iznik/tests/proposals/manageLeaderRole.ts
  15. 50 15
      tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts
  16. 51 15
      tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts
  17. 44 15
      tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts
  18. 52 16
      tests/network-tests/src/iznik/tests/proposals/updateRuntimeTest.ts
  19. 50 15
      tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts
  20. 62 29
      tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts
  21. 81 71
      tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts
  22. 10 13
      tests/network-tests/src/iznik/tests/workingGroup/impl/workingGroupModule.ts
  23. 182 124
      tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts
  24. 125 89
      tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts
  25. 113 83
      tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts
  26. 114 84
      tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts
  27. 102 78
      tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts

+ 1 - 1
tests/network-tests/package.json

@@ -7,7 +7,7 @@
     "test": "tap --files src/nicaea/tests/proposals/*Test.ts --files src/nicaea/tests/workingGroup/*Test.ts -T",
     "test-migration-constantinople": "tap --files src/rome/tests/romeRuntimeUpgradeTest.ts --files src/constantinople/tests/electingCouncilTest.ts -T",
     "test-migration-nicaea": "tap --files src/constantinople/tests/proposals/updateRuntimeTest.ts --files src/nicaea/tests/electingCouncilTest.ts -T",
-    "debug": "tap --files src/iznik/tests/workingGroup/*Test.ts -T",
+    "debug": "tap --files src/iznik/tests/proposals/manageLeaderRole.ts -T",
     "lint": "eslint . --quiet --ext .ts",
     "checks": "yarn lint && tsc --noEmit --pretty && prettier ./ --check",
     "format": "prettier ./ --write "

+ 0 - 100
tests/network-tests/src/iznik/tests/impl/electingCouncil.ts

@@ -1,100 +0,0 @@
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../utils/apiWrapper'
-import { Keyring } from '@polkadot/api'
-import BN from 'bn.js'
-import { Seat } from '@nicaea/types/council'
-import { assert } from 'chai'
-import { v4 as uuid } from 'uuid'
-import { Utils } from '../../utils/utils'
-import tap from 'tap'
-
-export function councilTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  k: number,
-  sudoUri: string,
-  greaterStake: BN,
-  lesserStake: BN
-) {
-  let sudo: KeyringPair
-
-  tap.test('Electing a council test', async () => {
-    // Setup goes here because M keypairs are generated after before() function
-    sudo = keyring.addFromUri(sudoUri)
-    let now = await apiWrapper.getBestBlock()
-    const applyForCouncilFee: BN = apiWrapper.estimateApplyForCouncilFee(greaterStake)
-    const voteForCouncilFee: BN = apiWrapper.estimateVoteForCouncilFee(sudo.address, sudo.address, greaterStake)
-    const salt: string[] = []
-    m1KeyPairs.forEach(() => {
-      salt.push(''.concat(uuid().replace(/-/g, '')))
-    })
-    const revealVoteFee: BN = apiWrapper.estimateRevealVoteFee(sudo.address, salt[0])
-
-    // Topping the balances
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, applyForCouncilFee.add(greaterStake))
-    await apiWrapper.transferBalanceToAccounts(sudo, m1KeyPairs, voteForCouncilFee.add(revealVoteFee).add(greaterStake))
-
-    // First K members stake more
-    await apiWrapper.sudoStartAnnouncingPerion(sudo, now.addn(100))
-    await apiWrapper.batchApplyForCouncilElection(m2KeyPairs.slice(0, k), greaterStake)
-    m2KeyPairs.slice(0, k).forEach((keyPair) =>
-      apiWrapper.getCouncilElectionStake(keyPair.address).then((stake) => {
-        assert(
-          stake.eq(greaterStake),
-          `${keyPair.address} not applied correctrly for council election with stake ${stake} versus expected ${greaterStake}`
-        )
-      })
-    )
-
-    // Last members stake less
-    await apiWrapper.batchApplyForCouncilElection(m2KeyPairs.slice(k), lesserStake)
-    m2KeyPairs.slice(k).forEach((keyPair) =>
-      apiWrapper.getCouncilElectionStake(keyPair.address).then((stake) => {
-        assert(
-          stake.eq(lesserStake),
-          `${keyPair.address} not applied correctrly for council election with stake ${stake} versus expected ${lesserStake}`
-        )
-      })
-    )
-
-    // Voting
-    await apiWrapper.sudoStartVotingPerion(sudo, now.addn(100))
-    await apiWrapper.batchVoteForCouncilMember(
-      m1KeyPairs.slice(0, k),
-      m2KeyPairs.slice(0, k),
-      salt.slice(0, k),
-      lesserStake
-    )
-    await apiWrapper.batchVoteForCouncilMember(m1KeyPairs.slice(k), m2KeyPairs.slice(k), salt.slice(k), greaterStake)
-
-    // Revealing
-    await apiWrapper.sudoStartRevealingPerion(sudo, now.addn(100))
-    await apiWrapper.batchRevealVote(m1KeyPairs.slice(0, k), m2KeyPairs.slice(0, k), salt.slice(0, k))
-    await apiWrapper.batchRevealVote(m1KeyPairs.slice(k), m2KeyPairs.slice(k), salt.slice(k))
-    now = await apiWrapper.getBestBlock()
-
-    // Resolving election
-    // 3 is to ensure the revealing block is in future
-    await apiWrapper.sudoStartRevealingPerion(sudo, now.addn(3))
-    await Utils.wait(apiWrapper.getBlockDuration().muln(2.5).toNumber())
-    const seats: Seat[] = await apiWrapper.getCouncil()
-
-    // Preparing collections to increase assertion readability
-    const m2addresses: string[] = m2KeyPairs.map((keyPair) => keyPair.address)
-    const m1addresses: string[] = m1KeyPairs.map((keyPair) => keyPair.address)
-    const members: string[] = seats.map((seat) => seat.member.toString())
-    const bakers: string[] = seats.map((seat) => seat.backers.map((baker) => baker.member.toString())).flat()
-
-    // Assertions
-    m2addresses.forEach((address) => assert(members.includes(address), `Account ${address} is not in the council`))
-    m1addresses.forEach((address) => assert(bakers.includes(address), `Account ${address} is not in the voters`))
-    seats.forEach((seat) =>
-      assert(
-        Utils.getTotalStake(seat).eq(greaterStake.add(lesserStake)),
-        `Member ${seat.member} has unexpected stake ${Utils.getTotalStake(seat)}`
-      )
-    )
-  })
-}

+ 0 - 86
tests/network-tests/src/iznik/tests/impl/membershipCreation.ts

@@ -1,86 +0,0 @@
-import { Keyring } from '@polkadot/keyring'
-import { assert } from 'chai'
-import { KeyringPair } from '@polkadot/keyring/types'
-import BN from 'bn.js'
-import { ApiWrapper } from '../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import tap from 'tap'
-
-export function membershipTest(
-  apiWrapper: ApiWrapper,
-  nKeyPairs: KeyringPair[],
-  keyring: Keyring,
-  n: number,
-  paidTerms: number,
-  sudoUri: string
-) {
-  let sudo: KeyringPair
-  let aKeyPair: KeyringPair
-  let membershipFee: BN
-  let membershipTransactionFee: BN
-
-  tap.test('Membership creation test setup', async () => {
-    sudo = keyring.addFromUri(sudoUri)
-    for (let i = 0; i < n; i++) {
-      nKeyPairs.push(keyring.addFromUri(i + uuid().substring(0, 8)))
-    }
-    aKeyPair = keyring.addFromUri(uuid().substring(0, 8))
-    membershipFee = await apiWrapper.getMembershipFee(paidTerms)
-    membershipTransactionFee = apiWrapper.estimateBuyMembershipFee(
-      sudo,
-      paidTerms,
-      'member_name_which_is_longer_than_expected'
-    )
-    await apiWrapper.transferBalanceToAccounts(sudo, nKeyPairs, membershipTransactionFee.add(new BN(membershipFee)))
-    await apiWrapper.transferBalance(sudo, aKeyPair.address, membershipTransactionFee)
-  })
-
-  tap.test('Buy membeship is accepted with sufficient funds', async () => {
-    await Promise.all(
-      nKeyPairs.map(async (keyPair, index) => {
-        await apiWrapper.buyMembership(keyPair, paidTerms, `new_member_${index}${keyPair.address.substring(0, 8)}`)
-      })
-    )
-    nKeyPairs.forEach((keyPair, index) =>
-      apiWrapper
-        .getMemberIds(keyPair.address)
-        .then((membership) => assert(membership.length > 0, `Account ${keyPair.address} is not a member`))
-    )
-  })
-
-  tap.test('Account A can not buy the membership with insufficient funds', async () => {
-    await apiWrapper
-      .getBalance(aKeyPair.address)
-      .then((balance) =>
-        assert(
-          balance.toBn() < membershipFee.add(membershipTransactionFee),
-          'Account A already have sufficient balance to purchase membership'
-        )
-      )
-    await apiWrapper.buyMembership(aKeyPair, paidTerms, `late_member_${aKeyPair.address.substring(0, 8)}`, true)
-    apiWrapper
-      .getMemberIds(aKeyPair.address)
-      .then((membership) => assert(membership.length === 0, 'Account A is a member'))
-  })
-
-  tap.test('Account A was able to buy the membership with sufficient funds', async () => {
-    await apiWrapper.transferBalance(sudo, aKeyPair.address, membershipFee.add(membershipTransactionFee))
-    apiWrapper
-      .getBalance(aKeyPair.address)
-      .then((balance) =>
-        assert(balance.toBn() >= membershipFee, 'The account balance is insufficient to purchase membership')
-      )
-    await apiWrapper.buyMembership(aKeyPair, paidTerms, `late_member_${aKeyPair.address.substring(0, 8)}`)
-    apiWrapper
-      .getMemberIds(aKeyPair.address)
-      .then((membership) => assert(membership.length > 0, 'Account A is a not member'))
-  })
-}
-
-export function createKeyPairs(keyring: Keyring, n: number): KeyringPair[] {
-  const nKeyPairs: KeyringPair[] = []
-  for (let i = 0; i < n; i++) {
-    nKeyPairs.push(keyring.addFromUri(i + uuid().substring(0, 8)))
-  }
-  return nKeyPairs
-}

+ 53 - 15
tests/network-tests/src/iznik/tests/proposals/contentWorkingGroupMintCapacityProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { workingGroupMintCapacityProposalTest } from './impl/workingGroupMintCapacityProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,32 +7,73 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { ContentWorkingGroupMintCapacityProposalFixture } from './impl/proposalsModule'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Validator count proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
   const mintingCapacityIncrement: BN = new BN(+process.env.MINTING_CAPACITY_INCREMENT!)
-  const durationInBlocks = 29
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const durationInBlocks = 29
 
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  workingGroupMintCapacityProposalTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri, mintingCapacityIncrement)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const contentWorkingGroupMintCapacityProposalFixture: ContentWorkingGroupMintCapacityProposalFixture = new ContentWorkingGroupMintCapacityProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    sudo,
+    mintingCapacityIncrement
+  )
+  tap.test('Content working group mint capacity test', async () =>
+    contentWorkingGroupMintCapacityProposalFixture.runner(false)
+  )
+
   closeApi(apiWrapper)
 })

+ 50 - 15
tests/network-tests/src/iznik/tests/proposals/electionParametersProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { electionParametersProposalTest } from './impl/electionParametersProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,31 +7,69 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { Utils } from '../../utils/utils'
+import { ElectionParametersProposalFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Election parameters proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
-  const durationInBlocks = 29
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const durationInBlocks = 29
 
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  electionParametersProposalTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const electionParametersProposalFixture: ElectionParametersProposalFixture = new ElectionParametersProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    sudo
+  )
+  tap.test('Election parameters proposal test', async () => electionParametersProposalFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 0 - 124
tests/network-tests/src/iznik/tests/proposals/impl/electionParametersProposal.ts

@@ -1,124 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import { assert } from 'chai'
-import tap from 'tap'
-
-export function electionParametersProposalTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string
-) {
-  let sudo: KeyringPair
-
-  tap.test('Election parameters proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-    const announcingPeriod: BN = await apiWrapper.getAnnouncingPeriod()
-    const votingPeriod: BN = await apiWrapper.getVotingPeriod()
-    const revealingPeriod: BN = await apiWrapper.getRevealingPeriod()
-    const councilSize: BN = await apiWrapper.getCouncilSize()
-    const candidacyLimit: BN = await apiWrapper.getCandidacyLimit()
-    const newTermDuration: BN = await apiWrapper.getNewTermDuration()
-    const minCouncilStake: BN = await apiWrapper.getMinCouncilStake()
-    const minVotingStake: BN = await apiWrapper.getMinVotingStake()
-
-    // Proposal stake calculation
-    const proposalStake: BN = new BN(200000)
-    const proposalFee: BN = apiWrapper.estimateProposeElectionParametersFee(
-      description,
-      description,
-      proposalStake,
-      announcingPeriod,
-      votingPeriod,
-      revealingPeriod,
-      councilSize,
-      candidacyLimit,
-      newTermDuration,
-      minCouncilStake,
-      minVotingStake
-    )
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-    // Proposal creation
-    const proposedAnnouncingPeriod: BN = announcingPeriod.subn(1)
-    const proposedVotingPeriod: BN = votingPeriod.addn(1)
-    const proposedRevealingPeriod: BN = revealingPeriod.addn(1)
-    const proposedCouncilSize: BN = councilSize.addn(1)
-    const proposedCandidacyLimit: BN = candidacyLimit.addn(1)
-    const proposedNewTermDuration: BN = newTermDuration.addn(1)
-    const proposedMinCouncilStake: BN = minCouncilStake.addn(1)
-    const proposedMinVotingStake: BN = minVotingStake.addn(1)
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeElectionParameters(
-      m1KeyPairs[0],
-      proposalTitle,
-      description,
-      proposalStake,
-      proposedAnnouncingPeriod,
-      proposedVotingPeriod,
-      proposedRevealingPeriod,
-      proposedCouncilSize,
-      proposedCandidacyLimit,
-      proposedNewTermDuration,
-      proposedMinCouncilStake,
-      proposedMinVotingStake
-    )
-    const proposalNumber = await proposalPromise
-
-    // Approving the proposal
-    const proposalExecutionPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await proposalExecutionPromise
-
-    // Assertions
-    const newAnnouncingPeriod: BN = await apiWrapper.getAnnouncingPeriod()
-    const newVotingPeriod: BN = await apiWrapper.getVotingPeriod()
-    const newRevealingPeriod: BN = await apiWrapper.getRevealingPeriod()
-    const newCouncilSize: BN = await apiWrapper.getCouncilSize()
-    const newCandidacyLimit: BN = await apiWrapper.getCandidacyLimit()
-    const newNewTermDuration: BN = await apiWrapper.getNewTermDuration()
-    const newMinCouncilStake: BN = await apiWrapper.getMinCouncilStake()
-    const newMinVotingStake: BN = await apiWrapper.getMinVotingStake()
-    assert(
-      proposedAnnouncingPeriod.eq(newAnnouncingPeriod),
-      `Announcing period has unexpected value ${newAnnouncingPeriod}, expected ${proposedAnnouncingPeriod}`
-    )
-    assert(
-      proposedVotingPeriod.eq(newVotingPeriod),
-      `Voting period has unexpected value ${newVotingPeriod}, expected ${proposedVotingPeriod}`
-    )
-    assert(
-      proposedRevealingPeriod.eq(newRevealingPeriod),
-      `Revealing has unexpected value ${newRevealingPeriod}, expected ${proposedRevealingPeriod}`
-    )
-    assert(
-      proposedCouncilSize.eq(newCouncilSize),
-      `Council size has unexpected value ${newCouncilSize}, expected ${proposedCouncilSize}`
-    )
-    assert(
-      proposedCandidacyLimit.eq(newCandidacyLimit),
-      `Candidacy limit has unexpected value ${newCandidacyLimit}, expected ${proposedCandidacyLimit}`
-    )
-    assert(
-      proposedNewTermDuration.eq(newNewTermDuration),
-      `New term duration has unexpected value ${newNewTermDuration}, expected ${proposedNewTermDuration}`
-    )
-    assert(
-      proposedMinCouncilStake.eq(newMinCouncilStake),
-      `Min council stake has unexpected value ${newMinCouncilStake}, expected ${proposedMinCouncilStake}`
-    )
-    assert(
-      proposedMinVotingStake.eq(newMinVotingStake),
-      `Min voting stake has unexpected value ${newMinVotingStake}, expected ${proposedMinVotingStake}`
-    )
-  })
-}

+ 941 - 291
tests/network-tests/src/iznik/tests/proposals/impl/proposalsModule.ts

@@ -4,312 +4,962 @@ import { v4 as uuid } from 'uuid'
 import BN from 'bn.js'
 import { WorkingGroupOpening } from '../../../dto/workingGroupOpening'
 import { FillOpeningParameters } from '../../../dto/fillOpeningParameters'
+import { Fixture } from '../../../utils/fixture'
+import { Bytes } from '@polkadot/types'
+import { assert } from 'chai'
 
-export async function createWorkingGroupLeaderOpening(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  applicationStake: BN,
-  roleStake: BN,
-  workingGroup: string
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing working group lead opening proposal ' + uuid().substring(0, 8)
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(100000)
-  const proposalFee: BN = apiWrapper.estimateProposeCreateWorkingGroupLeaderOpeningFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Opening construction
-  const opening = new WorkingGroupOpening()
-    .setMaxActiveApplicants(new BN(m1KeyPairs.length))
-    .setMaxReviewPeriodLength(new BN(32))
-    .setApplicationStakingPolicyAmount(new BN(applicationStake))
-    .setApplicationCrowdedOutUnstakingPeriodLength(new BN(1))
-    .setApplicationExpiredUnstakingPeriodLength(new BN(1))
-    .setRoleStakingPolicyAmount(new BN(roleStake))
-    .setRoleCrowdedOutUnstakingPeriodLength(new BN(1))
-    .setRoleExpiredUnstakingPeriodLength(new BN(1))
-    .setSlashableMaxCount(new BN(1))
-    .setSlashableMaxPercentPtsPerTime(new BN(100))
-    .setSuccessfulApplicantApplicationStakeUnstakingPeriod(new BN(1))
-    .setFailedApplicantApplicationStakeUnstakingPeriod(new BN(1))
-    .setFailedApplicantRoleStakeUnstakingPeriod(new BN(1))
-    .setTerminateApplicationStakeUnstakingPeriod(new BN(1))
-    .setTerminateRoleStakeUnstakingPeriod(new BN(1))
-    .setExitRoleApplicationStakeUnstakingPeriod(new BN(1))
-    .setExitRoleStakeUnstakingPeriod(new BN(1))
-    .setText(uuid().substring(0, 8))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeCreateWorkingGroupLeaderOpening(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    opening,
-    workingGroup
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class CreateWorkingGroupLeaderOpeningFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private applicationStake: BN
+  private roleStake: BN
+  private workingGroup: string
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    applicationStake: BN,
+    roleStake: BN,
+    workingGroup: string
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.applicationStake = applicationStake
+    this.roleStake = roleStake
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing working group lead opening proposal ' + uuid().substring(0, 8)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(100000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeCreateWorkingGroupLeaderOpeningFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Opening construction
+    const opening = new WorkingGroupOpening()
+      .setMaxActiveApplicants(new BN(this.m1KeyPairs.length))
+      .setMaxReviewPeriodLength(new BN(32))
+      .setApplicationStakingPolicyAmount(new BN(this.applicationStake))
+      .setApplicationCrowdedOutUnstakingPeriodLength(new BN(1))
+      .setApplicationExpiredUnstakingPeriodLength(new BN(1))
+      .setRoleStakingPolicyAmount(new BN(this.roleStake))
+      .setRoleCrowdedOutUnstakingPeriodLength(new BN(1))
+      .setRoleExpiredUnstakingPeriodLength(new BN(1))
+      .setSlashableMaxCount(new BN(1))
+      .setSlashableMaxPercentPtsPerTime(new BN(100))
+      .setSuccessfulApplicantApplicationStakeUnstakingPeriod(new BN(1))
+      .setFailedApplicantApplicationStakeUnstakingPeriod(new BN(1))
+      .setFailedApplicantRoleStakeUnstakingPeriod(new BN(1))
+      .setTerminateApplicationStakeUnstakingPeriod(new BN(1))
+      .setTerminateRoleStakeUnstakingPeriod(new BN(1))
+      .setExitRoleApplicationStakeUnstakingPeriod(new BN(1))
+      .setExitRoleStakeUnstakingPeriod(new BN(1))
+      .setText(uuid().substring(0, 8))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeCreateWorkingGroupLeaderOpening(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      opening,
+      this.workingGroup
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function beginWorkingGroupLeaderApplicationReview(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  openingId: BN,
-  workingGroup: string
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing begin working group lead application review proposal ' + uuid().substring(0, 8)
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(25000)
-  const proposalFee: BN = apiWrapper.estimateProposeBeginWorkingGroupLeaderApplicationReviewFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeBeginWorkingGroupLeaderApplicationReview(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    openingId,
-    workingGroup
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class BeginWorkingGroupLeaderApplicationReviewFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private openingId: BN
+  private workingGroup: string
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    openingId: BN,
+    workingGroup: string
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.openingId = openingId
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing begin working group lead application review proposal ' + uuid().substring(0, 8)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(25000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeBeginWorkingGroupLeaderApplicationReviewFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeBeginWorkingGroupLeaderApplicationReview(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      this.openingId,
+      this.workingGroup
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function fillLeaderOpeningProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  applicantRoleAccountAddress: string,
-  sudo: KeyringPair,
-  firstRewardInterval: BN,
-  rewardInterval: BN,
-  payoutAmount: BN,
-  openingId: BN,
-  workingGroup: WorkingGroups
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing fill opening proposal ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(50000)
-  const proposalFee: BN = apiWrapper.estimateProposeFillLeaderOpeningFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const applicationId: BN = (
-    await apiWrapper.getActiveApplicationsIdsByRoleAccount(applicantRoleAccountAddress, workingGroup)
-  )[0]
-  const now = await apiWrapper.getBestBlock()
-  const fillOpeningParameters: FillOpeningParameters = new FillOpeningParameters()
-    .setAmountPerPayout(payoutAmount)
-    .setNextPaymentAtBlock(now.add(firstRewardInterval))
-    .setPayoutInterval(rewardInterval)
-    .setOpeningId(openingId)
-    .setSuccessfulApplicationId(applicationId)
-    .setWorkingGroup(workingGroupString)
-
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeFillLeaderOpening(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    fillOpeningParameters
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class FillLeaderOpeningProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private applicantRoleAccountAddress: string
+  private sudo: KeyringPair
+  private firstRewardInterval: BN
+  private rewardInterval: BN
+  private payoutAmount: BN
+  private openingId: BN
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    applicantRoleAccountAddress: string,
+    sudo: KeyringPair,
+    firstRewardInterval: BN,
+    rewardInterval: BN,
+    payoutAmount: BN,
+    openingId: BN,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.applicantRoleAccountAddress = applicantRoleAccountAddress
+    this.sudo = sudo
+    this.firstRewardInterval = firstRewardInterval
+    this.rewardInterval = rewardInterval
+    this.payoutAmount = payoutAmount
+    this.openingId = openingId
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing fill opening proposal ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeFillLeaderOpeningFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const applicationId: BN = (
+      await this.apiWrapper.getActiveApplicationsIdsByRoleAccount(this.applicantRoleAccountAddress, this.workingGroup)
+    )[0]
+    const now = await this.apiWrapper.getBestBlock()
+    const fillOpeningParameters: FillOpeningParameters = new FillOpeningParameters()
+      .setAmountPerPayout(this.payoutAmount)
+      .setNextPaymentAtBlock(now.add(this.firstRewardInterval))
+      .setPayoutInterval(this.rewardInterval)
+      .setOpeningId(this.openingId)
+      .setSuccessfulApplicationId(applicationId)
+      .setWorkingGroup(workingGroupString)
+
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeFillLeaderOpening(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      fillOpeningParameters
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function terminateLeaderRoleProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  leaderRoleAccountAddress: string,
-  sudo: KeyringPair,
-  slash: boolean,
-  workingGroup: WorkingGroups
-) {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing begin working group lead application review proposal ' + uuid().substring(0, 8)
-  const rationale: string = 'Testing leader termination ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(leaderRoleAccountAddress, workingGroup)
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(100000)
-  const proposalFee: BN = apiWrapper.estimateProposeTerminateLeaderRoleFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeTerminateLeaderRole(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    workerId,
-    rationale,
-    slash,
-    workingGroupString
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class TerminateLeaderRoleProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private leaderRoleAccountAddress: string
+  private sudo: KeyringPair
+  private slash: boolean
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    leaderRoleAccountAddress: string,
+    sudo: KeyringPair,
+    slash: boolean,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.leaderRoleAccountAddress = leaderRoleAccountAddress
+    this.sudo = sudo
+    this.slash = slash
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing begin working group lead application review proposal ' + uuid().substring(0, 8)
+    const rationale: string = 'Testing leader termination ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+    const workerId: BN = await this.apiWrapper.getWorkerIdByRoleAccount(
+      this.leaderRoleAccountAddress,
+      this.workingGroup
+    )
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(100000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeTerminateLeaderRoleFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeTerminateLeaderRole(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      workerId,
+      rationale,
+      this.slash,
+      workingGroupString
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function setLeaderRewardProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  payoutAmount: BN,
-  workingGroup: WorkingGroups
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing set leader reward proposal ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-  const workerId: BN = (await apiWrapper.getLeadWorkerId(workingGroup))!
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(50000)
-  const proposalFee: BN = apiWrapper.estimateProposeLeaderRewardFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeLeaderReward(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    workerId,
-    payoutAmount,
-    workingGroupString
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class SetLeaderRewardProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private payoutAmount: BN
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    payoutAmount: BN,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.payoutAmount = payoutAmount
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing set leader reward proposal ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+    const workerId: BN = (await this.apiWrapper.getLeadWorkerId(this.workingGroup))!
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeLeaderRewardFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeLeaderReward(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      workerId,
+      this.payoutAmount,
+      workingGroupString
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function decreaseLeaderStakeProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  stakeDecrement: BN,
-  workingGroup: WorkingGroups
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing decrease leader stake proposal ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-  const workerId: BN = (await apiWrapper.getLeadWorkerId(workingGroup))!
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(50000)
-  const proposalFee: BN = apiWrapper.estimateProposeDecreaseLeaderStakeFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeDecreaseLeaderStake(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    workerId,
-    stakeDecrement,
-    workingGroupString
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class DecreaseLeaderStakeProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private stakeDecrement: BN
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    stakeDecrement: BN,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.stakeDecrement = stakeDecrement
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing decrease leader stake proposal ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+    const workerId: BN = (await this.apiWrapper.getLeadWorkerId(this.workingGroup))!
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeDecreaseLeaderStakeFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeDecreaseLeaderStake(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      workerId,
+      this.stakeDecrement,
+      workingGroupString
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function slashLeaderProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  slashAmount: BN,
-  workingGroup: WorkingGroups
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing slash leader stake proposal ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-  const workerId: BN = (await apiWrapper.getLeadWorkerId(workingGroup))!
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(50000)
-  const proposalFee: BN = apiWrapper.estimateProposeSlashLeaderStakeFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeSlashLeaderStake(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    workerId,
-    slashAmount,
-    workingGroupString
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class SlashLeaderProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private slashAmount: BN
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    slashAmount: BN,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.slashAmount = slashAmount
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing slash leader stake proposal ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+    const workerId: BN = (await this.apiWrapper.getLeadWorkerId(this.workingGroup))!
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeSlashLeaderStakeFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeSlashLeaderStake(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      workerId,
+      this.slashAmount,
+      workingGroupString
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function workingGroupMintCapacityProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  mintCapacity: BN,
-  workingGroup: WorkingGroups
-): Promise<BN> {
-  // Setup
-  const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-  const description: string = 'Testing working group mint capacity proposal ' + uuid().substring(0, 8)
-  const workingGroupString: string = apiWrapper.getWorkingGroupString(workingGroup)
-
-  // Proposal stake calculation
-  const proposalStake: BN = new BN(50000)
-  const proposalFee: BN = apiWrapper.estimateProposeWorkingGroupMintCapacityFee()
-  await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-  // Proposal creation
-  const proposalPromise = apiWrapper.expectProposalCreated()
-  await apiWrapper.proposeWorkingGroupMintCapacity(
-    m1KeyPairs[0],
-    proposalTitle,
-    description,
-    proposalStake,
-    mintCapacity,
-    workingGroupString
-  )
-  const proposalNumber: BN = await proposalPromise
-  return proposalNumber
+export class WorkingGroupMintCapacityProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private mintCapacity: BN
+  private workingGroup: WorkingGroups
+
+  private result: BN | undefined
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    mintCapacity: BN,
+    workingGroup: WorkingGroups
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.sudo = sudo
+    this.mintCapacity = mintCapacity
+    this.workingGroup = workingGroup
+  }
+
+  public getResult(): BN | undefined {
+    return this.result
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing working group mint capacity proposal ' + uuid().substring(0, 8)
+    const workingGroupString: string = this.apiWrapper.getWorkingGroupString(this.workingGroup)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeWorkingGroupMintCapacityFee()
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeWorkingGroupMintCapacity(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      this.mintCapacity,
+      workingGroupString
+    )
+    const proposalNumber: BN = await proposalPromise
+    this.result = proposalNumber
+  }
 }
 
-export async function voteForProposal(
-  apiWrapper: ApiWrapper,
-  m2KeyPairs: KeyringPair[],
-  sudo: KeyringPair,
-  proposalNumber: BN
-): Promise<void> {
-  const proposalVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-  await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, proposalVoteFee)
-
-  // Approving the proposal
-  const proposalExecutionPromise = apiWrapper.expectProposalFinalized()
-  await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-  await proposalExecutionPromise
+export class ElectionParametersProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+
+  constructor(apiWrapper: ApiWrapper, m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[], sudo: KeyringPair) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+    const announcingPeriod: BN = await this.apiWrapper.getAnnouncingPeriod()
+    const votingPeriod: BN = await this.apiWrapper.getVotingPeriod()
+    const revealingPeriod: BN = await this.apiWrapper.getRevealingPeriod()
+    const councilSize: BN = await this.apiWrapper.getCouncilSize()
+    const candidacyLimit: BN = await this.apiWrapper.getCandidacyLimit()
+    const newTermDuration: BN = await this.apiWrapper.getNewTermDuration()
+    const minCouncilStake: BN = await this.apiWrapper.getMinCouncilStake()
+    const minVotingStake: BN = await this.apiWrapper.getMinVotingStake()
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(200000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeElectionParametersFee(
+      description,
+      description,
+      proposalStake,
+      announcingPeriod,
+      votingPeriod,
+      revealingPeriod,
+      councilSize,
+      candidacyLimit,
+      newTermDuration,
+      minCouncilStake,
+      minVotingStake
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposedAnnouncingPeriod: BN = announcingPeriod.subn(1)
+    const proposedVotingPeriod: BN = votingPeriod.addn(1)
+    const proposedRevealingPeriod: BN = revealingPeriod.addn(1)
+    const proposedCouncilSize: BN = councilSize.addn(1)
+    const proposedCandidacyLimit: BN = candidacyLimit.addn(1)
+    const proposedNewTermDuration: BN = newTermDuration.addn(1)
+    const proposedMinCouncilStake: BN = minCouncilStake.addn(1)
+    const proposedMinVotingStake: BN = minVotingStake.addn(1)
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeElectionParameters(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      proposedAnnouncingPeriod,
+      proposedVotingPeriod,
+      proposedRevealingPeriod,
+      proposedCouncilSize,
+      proposedCandidacyLimit,
+      proposedNewTermDuration,
+      proposedMinCouncilStake,
+      proposedMinVotingStake
+    )
+    const proposalNumber = await proposalPromise
+
+    // Approving the proposal
+    const proposalExecutionPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await proposalExecutionPromise
+
+    // Assertions
+    const newAnnouncingPeriod: BN = await this.apiWrapper.getAnnouncingPeriod()
+    const newVotingPeriod: BN = await this.apiWrapper.getVotingPeriod()
+    const newRevealingPeriod: BN = await this.apiWrapper.getRevealingPeriod()
+    const newCouncilSize: BN = await this.apiWrapper.getCouncilSize()
+    const newCandidacyLimit: BN = await this.apiWrapper.getCandidacyLimit()
+    const newNewTermDuration: BN = await this.apiWrapper.getNewTermDuration()
+    const newMinCouncilStake: BN = await this.apiWrapper.getMinCouncilStake()
+    const newMinVotingStake: BN = await this.apiWrapper.getMinVotingStake()
+    assert(
+      proposedAnnouncingPeriod.eq(newAnnouncingPeriod),
+      `Announcing period has unexpected value ${newAnnouncingPeriod}, expected ${proposedAnnouncingPeriod}`
+    )
+    assert(
+      proposedVotingPeriod.eq(newVotingPeriod),
+      `Voting period has unexpected value ${newVotingPeriod}, expected ${proposedVotingPeriod}`
+    )
+    assert(
+      proposedRevealingPeriod.eq(newRevealingPeriod),
+      `Revealing has unexpected value ${newRevealingPeriod}, expected ${proposedRevealingPeriod}`
+    )
+    assert(
+      proposedCouncilSize.eq(newCouncilSize),
+      `Council size has unexpected value ${newCouncilSize}, expected ${proposedCouncilSize}`
+    )
+    assert(
+      proposedCandidacyLimit.eq(newCandidacyLimit),
+      `Candidacy limit has unexpected value ${newCandidacyLimit}, expected ${proposedCandidacyLimit}`
+    )
+    assert(
+      proposedNewTermDuration.eq(newNewTermDuration),
+      `New term duration has unexpected value ${newNewTermDuration}, expected ${proposedNewTermDuration}`
+    )
+    assert(
+      proposedMinCouncilStake.eq(newMinCouncilStake),
+      `Min council stake has unexpected value ${newMinCouncilStake}, expected ${proposedMinCouncilStake}`
+    )
+    assert(
+      proposedMinVotingStake.eq(newMinVotingStake),
+      `Min voting stake has unexpected value ${newMinVotingStake}, expected ${proposedMinVotingStake}`
+    )
+  }
+}
+
+export class SetLeadProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+
+  constructor(apiWrapper: ApiWrapper, m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[], sudo: KeyringPair) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(50000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeLeadFee(
+      description,
+      description,
+      proposalStake,
+      this.sudo.address
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeLead(this.m1KeyPairs[0], proposalTitle, description, proposalStake, this.m1KeyPairs[1])
+    const proposalNumber = await proposalPromise
+
+    // Approving the proposal
+    const proposalExecutionPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await proposalExecutionPromise
+    const newLead: string = await this.apiWrapper.getCurrentLeadAddress()
+    assert(
+      newLead === this.m1KeyPairs[1].address,
+      `New lead has unexpected value ${newLead}, expected ${this.m1KeyPairs[1].address}`
+    )
+  }
+}
+
+export class SpendingProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private spendingBalance: BN
+  private mintCapacity: BN
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    m2KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    spendingBalance: BN,
+    mintCapacity: BN
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+    this.spendingBalance = spendingBalance
+    this.mintCapacity = mintCapacity
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const description = 'spending proposal which is used for API network testing with some mock data'
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+
+    // Topping the balances
+    const proposalStake: BN = new BN(25000)
+    const runtimeProposalFee: BN = this.apiWrapper.estimateProposeSpendingFee(
+      description,
+      description,
+      proposalStake,
+      this.spendingBalance,
+      this.sudo.address
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+    await this.apiWrapper.sudoSetCouncilMintCapacity(this.sudo, this.mintCapacity)
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeSpending(
+      this.m1KeyPairs[0],
+      'testing spending' + uuid().substring(0, 8),
+      'spending to test proposal functionality' + uuid().substring(0, 8),
+      proposalStake,
+      this.spendingBalance,
+      this.sudo.address
+    )
+    const proposalNumber = await proposalPromise
+
+    // Approving spending proposal
+    const balanceBeforeMinting: BN = await this.apiWrapper.getBalance(this.sudo.address)
+    const spendingPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await spendingPromise
+    const balanceAfterMinting: BN = await this.apiWrapper.getBalance(this.sudo.address)
+    assert(
+      balanceAfterMinting.sub(balanceBeforeMinting).eq(this.spendingBalance),
+      `member ${
+        this.m1KeyPairs[0].address
+      } has unexpected balance ${balanceAfterMinting}, expected ${balanceBeforeMinting.add(this.spendingBalance)}`
+    )
+  }
+}
+
+export class TextProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+
+  constructor(apiWrapper: ApiWrapper, m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[], sudo: KeyringPair) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing text proposal ' + uuid().substring(0, 8)
+    const proposalText: string = 'Text of the testing proposal ' + uuid().substring(0, 8)
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(25000)
+    const runtimeProposalFee: BN = this.apiWrapper.estimateProposeTextFee(
+      proposalStake,
+      description,
+      description,
+      proposalText
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeText(this.m1KeyPairs[0], proposalStake, proposalTitle, description, proposalText)
+    const proposalNumber = await proposalPromise
+
+    // Approving text proposal
+    const textProposalPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await textProposalPromise
+  }
+}
+
+export class ValidatorCountProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private validatorCountIncrement: BN
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    m2KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    validatorCountIncrement: BN
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+    this.validatorCountIncrement = validatorCountIncrement
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(100000)
+    const proposalFee: BN = this.apiWrapper.estimateProposeValidatorCountFee(description, description, proposalStake)
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, proposalFee.add(proposalStake))
+    const validatorCount: BN = await this.apiWrapper.getValidatorCount()
+
+    // Proposal creation
+    const proposedValidatorCount: BN = validatorCount.add(this.validatorCountIncrement)
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeValidatorCount(
+      this.m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      proposedValidatorCount
+    )
+    const proposalNumber = await proposalPromise
+
+    // Approving the proposal
+    const proposalExecutionPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await proposalExecutionPromise
+    const newValidatorCount: BN = await this.apiWrapper.getValidatorCount()
+    assert(
+      proposedValidatorCount.eq(newValidatorCount),
+      `Validator count has unexpeccted value ${newValidatorCount}, expected ${proposedValidatorCount}`
+    )
+  }
+}
+
+export class ContentWorkingGroupMintCapacityProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private mintingCapacityIncrement: BN
+
+  constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    m2KeyPairs: KeyringPair[],
+    sudo: KeyringPair,
+    mintingCapacityIncrement: BN
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+    this.mintingCapacityIncrement = mintingCapacityIncrement
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const description = 'Mint capacity proposal which is used for API network testing'
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    const initialMintingCapacity: BN = await this.apiWrapper.getContentWorkingGroupMintCapacity()
+
+    // Topping the balances
+    const proposalStake: BN = new BN(50000)
+    const runtimeProposalFee: BN = this.apiWrapper.estimateProposeContentWorkingGroupMintCapacityFee(
+      description,
+      description,
+      proposalStake,
+      initialMintingCapacity.add(this.mintingCapacityIncrement)
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+
+    // Proposal creation
+    const proposedMintingCapacity: BN = initialMintingCapacity.add(this.mintingCapacityIncrement)
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeContentWorkingGroupMintCapacity(
+      this.m1KeyPairs[0],
+      'testing mint capacity' + uuid().substring(0, 8),
+      'mint capacity to test proposal functionality' + uuid().substring(0, 8),
+      proposalStake,
+      proposedMintingCapacity
+    )
+    const proposalNumber = await proposalPromise
+
+    // Approving mint capacity proposal
+    const mintCapacityPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await mintCapacityPromise
+    const newMintingCapacity: BN = await this.apiWrapper.getContentWorkingGroupMintCapacity()
+    assert(
+      proposedMintingCapacity.eq(newMintingCapacity),
+      `Content working group has unexpected minting capacity ${newMintingCapacity}, expected ${proposedMintingCapacity}`
+    )
+  }
+}
+
+export class UpdateRuntimeFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+
+  constructor(apiWrapper: ApiWrapper, m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[], sudo: KeyringPair) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    // Setup
+    const runtime: Bytes = await this.apiWrapper.getRuntime()
+    const description = 'runtime upgrade proposal which is used for API network testing'
+    const runtimeVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+
+    // Topping the balances
+    const proposalStake: BN = new BN(1000000)
+    const runtimeProposalFee: BN = this.apiWrapper.estimateProposeRuntimeUpgradeFee(
+      proposalStake,
+      description,
+      description,
+      runtime
+    )
+    await this.apiWrapper.transferBalance(this.sudo, this.m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, runtimeVoteFee)
+
+    // Proposal creation
+    const proposalPromise = this.apiWrapper.expectProposalCreated()
+    await this.apiWrapper.proposeRuntime(
+      this.m1KeyPairs[0],
+      proposalStake,
+      'testing runtime' + uuid().substring(0, 8),
+      'runtime to test proposal functionality' + uuid().substring(0, 8),
+      runtime
+    )
+    const proposalNumber = await proposalPromise
+
+    // Approving runtime update proposal
+    const runtimePromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, proposalNumber)
+    await runtimePromise
+  }
+}
+
+export class VoteForProposalFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m2KeyPairs: KeyringPair[]
+  private sudo: KeyringPair
+  private proposalNumber: BN
+
+  constructor(apiWrapper: ApiWrapper, m2KeyPairs: KeyringPair[], sudo: KeyringPair, proposalNumber: BN) {
+    this.apiWrapper = apiWrapper
+    this.m2KeyPairs = m2KeyPairs
+    this.sudo = sudo
+    this.proposalNumber = proposalNumber
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    const proposalVoteFee: BN = this.apiWrapper.estimateVoteForProposalFee()
+    await this.apiWrapper.transferBalanceToAccounts(this.sudo, this.m2KeyPairs, proposalVoteFee)
+
+    // Approving the proposal
+    const proposalExecutionPromise = this.apiWrapper.expectProposalFinalized()
+    await this.apiWrapper.batchApproveProposal(this.m2KeyPairs, this.proposalNumber)
+    await proposalExecutionPromise
+  }
 }

+ 0 - 46
tests/network-tests/src/iznik/tests/proposals/impl/setLeadProposal.ts

@@ -1,46 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import { assert } from 'chai'
-import tap from 'tap'
-
-export function setLeadProposalTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string
-) {
-  let sudo: KeyringPair
-
-  tap.test('Lead proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-
-    // Proposal stake calculation
-    const proposalStake: BN = new BN(50000)
-    const proposalFee: BN = apiWrapper.estimateProposeLeadFee(description, description, proposalStake, sudo.address)
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-
-    // Proposal creation
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeLead(m1KeyPairs[0], proposalTitle, description, proposalStake, m1KeyPairs[1])
-    const proposalNumber = await proposalPromise
-
-    // Approving the proposal
-    const proposalExecutionPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await proposalExecutionPromise
-    const newLead: string = await apiWrapper.getCurrentLeadAddress()
-    assert(
-      newLead === m1KeyPairs[1].address,
-      `New lead has unexpected value ${newLead}, expected ${m1KeyPairs[1].address}`
-    )
-  })
-}

+ 0 - 64
tests/network-tests/src/iznik/tests/proposals/impl/spendingProposal.ts

@@ -1,64 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import { assert } from 'chai'
-import tap from 'tap'
-
-export function spendingProposalTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string,
-  spendingBalance: BN,
-  mintCapacity: BN
-) {
-  let sudo: KeyringPair
-
-  tap.test('Spending proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const description = 'spending proposal which is used for API network testing with some mock data'
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-
-    // Topping the balances
-    const proposalStake: BN = new BN(25000)
-    const runtimeProposalFee: BN = apiWrapper.estimateProposeSpendingFee(
-      description,
-      description,
-      proposalStake,
-      spendingBalance,
-      sudo.address
-    )
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-    await apiWrapper.sudoSetCouncilMintCapacity(sudo, mintCapacity)
-
-    // Proposal creation
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeSpending(
-      m1KeyPairs[0],
-      'testing spending' + uuid().substring(0, 8),
-      'spending to test proposal functionality' + uuid().substring(0, 8),
-      proposalStake,
-      spendingBalance,
-      sudo.address
-    )
-    const proposalNumber = await proposalPromise
-
-    // Approving spending proposal
-    const balanceBeforeMinting: BN = await apiWrapper.getBalance(sudo.address)
-    const spendingPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await spendingPromise
-    const balanceAfterMinting: BN = await apiWrapper.getBalance(sudo.address)
-    assert(
-      balanceAfterMinting.sub(balanceBeforeMinting).eq(spendingBalance),
-      `member ${
-        m1KeyPairs[0].address
-      } has unexpected balance ${balanceAfterMinting}, expected ${balanceBeforeMinting.add(spendingBalance)}`
-    )
-  })
-}

+ 0 - 46
tests/network-tests/src/iznik/tests/proposals/impl/textProposal.ts

@@ -1,46 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import tap from 'tap'
-
-export function textProposalTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string
-) {
-  let sudo: KeyringPair
-
-  tap.test('Text proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-    const description: string = 'Testing text proposal ' + uuid().substring(0, 8)
-    const proposalText: string = 'Text of the testing proposal ' + uuid().substring(0, 8)
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-
-    // Proposal stake calculation
-    const proposalStake: BN = new BN(25000)
-    const runtimeProposalFee: BN = apiWrapper.estimateProposeTextFee(
-      proposalStake,
-      description,
-      description,
-      proposalText
-    )
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
-
-    // Proposal creation
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeText(m1KeyPairs[0], proposalStake, proposalTitle, description, proposalText)
-    const proposalNumber = await proposalPromise
-
-    // Approving text proposal
-    const textProposalPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await textProposalPromise
-  })
-}

+ 0 - 52
tests/network-tests/src/iznik/tests/proposals/impl/updateRuntime.ts

@@ -1,52 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { Bytes } from '@polkadot/types'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import tap from 'tap'
-
-export function updateRuntimeTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string
-) {
-  let sudo: KeyringPair
-
-  tap.test('\n\tUpgrading the runtime test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const runtime: Bytes = await apiWrapper.getRuntime()
-    const description = 'runtime upgrade proposal which is used for API network testing'
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-
-    // Topping the balances
-    const proposalStake: BN = new BN(1000000)
-    const runtimeProposalFee: BN = apiWrapper.estimateProposeRuntimeUpgradeFee(
-      proposalStake,
-      description,
-      description,
-      runtime
-    )
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-
-    // Proposal creation
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeRuntime(
-      m1KeyPairs[0],
-      proposalStake,
-      'testing runtime' + uuid().substring(0, 8),
-      'runtime to test proposal functionality' + uuid().substring(0, 8),
-      runtime
-    )
-    const proposalNumber = await proposalPromise
-
-    // Approving runtime update proposal
-    const runtimePromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await runtimePromise
-  })
-}

+ 0 - 55
tests/network-tests/src/iznik/tests/proposals/impl/validatorCountProposal.ts

@@ -1,55 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import { assert } from 'chai'
-import tap from 'tap'
-
-export function validatorCountProposal(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string,
-  validatorCountIncrement: BN
-) {
-  let sudo: KeyringPair
-
-  tap.test('Validator count proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-
-    // Proposal stake calculation
-    const proposalStake: BN = new BN(100000)
-    const proposalFee: BN = apiWrapper.estimateProposeValidatorCountFee(description, description, proposalStake)
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake))
-    const validatorCount: BN = await apiWrapper.getValidatorCount()
-
-    // Proposal creation
-    const proposedValidatorCount: BN = validatorCount.add(validatorCountIncrement)
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeValidatorCount(
-      m1KeyPairs[0],
-      proposalTitle,
-      description,
-      proposalStake,
-      proposedValidatorCount
-    )
-    const proposalNumber = await proposalPromise
-
-    // Approving the proposal
-    const proposalExecutionPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await proposalExecutionPromise
-    const newValidatorCount: BN = await apiWrapper.getValidatorCount()
-    assert(
-      proposedValidatorCount.eq(newValidatorCount),
-      `Validator count has unexpeccted value ${newValidatorCount}, expected ${proposedValidatorCount}`
-    )
-  })
-}

+ 0 - 59
tests/network-tests/src/iznik/tests/proposals/impl/workingGroupMintCapacityProposal.ts

@@ -1,59 +0,0 @@
-import { Keyring } from '@polkadot/api'
-import { KeyringPair } from '@polkadot/keyring/types'
-import { ApiWrapper } from '../../../utils/apiWrapper'
-import { v4 as uuid } from 'uuid'
-import BN from 'bn.js'
-import { assert } from 'chai'
-import tap from 'tap'
-
-export function workingGroupMintCapacityProposalTest(
-  apiWrapper: ApiWrapper,
-  m1KeyPairs: KeyringPair[],
-  m2KeyPairs: KeyringPair[],
-  keyring: Keyring,
-  sudoUri: string,
-  mintingCapacityIncrement: BN
-) {
-  let sudo: KeyringPair
-
-  tap.test('Mint capacity proposal test', async () => {
-    // Setup
-    sudo = keyring.addFromUri(sudoUri)
-    const description = 'Mint capacity proposal which is used for API network testing'
-    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee()
-    const initialMintingCapacity: BN = await apiWrapper.getContentWorkingGroupMintCapacity()
-
-    // Topping the balances
-    const proposalStake: BN = new BN(50000)
-    const runtimeProposalFee: BN = apiWrapper.estimateProposeContentWorkingGroupMintCapacityFee(
-      description,
-      description,
-      proposalStake,
-      initialMintingCapacity.add(mintingCapacityIncrement)
-    )
-    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, runtimeProposalFee.add(proposalStake))
-    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee)
-
-    // Proposal creation
-    const proposedMintingCapacity: BN = initialMintingCapacity.add(mintingCapacityIncrement)
-    const proposalPromise = apiWrapper.expectProposalCreated()
-    await apiWrapper.proposeContentWorkingGroupMintCapacity(
-      m1KeyPairs[0],
-      'testing mint capacity' + uuid().substring(0, 8),
-      'mint capacity to test proposal functionality' + uuid().substring(0, 8),
-      proposalStake,
-      proposedMintingCapacity
-    )
-    const proposalNumber = await proposalPromise
-
-    // Approving mint capacity proposal
-    const mintCapacityPromise = apiWrapper.expectProposalFinalized()
-    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber)
-    await mintCapacityPromise
-    const newMintingCapacity: BN = await apiWrapper.getContentWorkingGroupMintCapacity()
-    assert(
-      proposedMintingCapacity.eq(newMintingCapacity),
-      `Content working group has unexpected minting capacity ${newMintingCapacity}, expected ${proposedMintingCapacity}`
-    )
-  })
-}

+ 229 - 159
tests/network-tests/src/iznik/tests/proposals/manageLeaderRole.ts

@@ -1,6 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -9,42 +7,47 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
 import {
-  createWorkingGroupLeaderOpening,
-  voteForProposal,
-  beginWorkingGroupLeaderApplicationReview,
-  fillLeaderOpeningProposal,
-  terminateLeaderRoleProposal,
-  setLeaderRewardProposal,
-  decreaseLeaderStakeProposal,
-  slashLeaderProposal,
+  BeginWorkingGroupLeaderApplicationReviewFixture,
+  CreateWorkingGroupLeaderOpeningFixture,
+  DecreaseLeaderStakeProposalFixture,
+  FillLeaderOpeningProposalFixture,
+  SetLeaderRewardProposalFixture,
+  SlashLeaderProposalFixture,
+  TerminateLeaderRoleProposalFixture,
+  VoteForProposalFixture,
 } from './impl/proposalsModule'
 import {
-  applyForOpening,
-  expectLeadOpeningAdded,
-  expectLeaderSet,
-  expectBeganApplicationReview,
-  expectLeaderRoleTerminated,
-  expectLeaderRewardAmountUpdated,
-  expectLeaderStakeDecreased,
-  expectLeaderSlashed,
+  ApplyForOpeningFixture,
+  ExpectBeganApplicationReviewFixture,
+  ExpectLeaderRewardAmountUpdatedFixture,
+  ExpectLeaderRoleTerminatedFixture,
+  ExpectLeaderSetFixture,
+  ExpectLeaderSlashedFixture,
+  ExpectLeaderStakeDecreasedFixture,
+  ExpectLeadOpeningAddedFixture,
 } from '../workingGroup/impl/workingGroupModule'
-import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
-import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Set lead proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-  const leadKeyPair: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const leadKeyPair: KeyringPair[] = Utils.createKeyPairs(keyring, 1)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
@@ -58,176 +61,243 @@ tap.mocha.describe('Set lead proposal scenario', async () => {
   const slashAmount: BN = new BN(process.env.SLASH_AMOUNT!)
   const durationInBlocks = 70
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
 
-  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture()
-  tap.test('Buy membeship is accepted with sufficient funds', async () =>
-    happyCaseFixture.runner(apiWrapper, sudo, m1KeyPairs, keyring, N, paidTerms)
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
   )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
 
-  tap.test('Buy membeship is accepted with sufficient funds', async () =>
-    happyCaseFixture.runner(apiWrapper, sudo, m2KeyPairs, keyring, N, paidTerms)
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
   )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
 
-  tap.test('Buy membeship is accepted with sufficient funds', async () =>
-    happyCaseFixture.runner(apiWrapper, sudo, leadKeyPair, keyring, 1, paidTerms)
+  const leaderMembershipFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
   )
+  tap.test('Buy membership for lead', async () => leaderMembershipFixture.runner(false))
 
-  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture()
-  tap.test('Elect council', async () =>
-    electCouncilFixture.runner(apiWrapper, m1KeyPairs, m2KeyPairs, K, sudo, greaterStake, lesserStake)
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
   )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
 
-  // membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  // membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  // membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
-  // councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-
-  let createOpeningProposalId: BN
-  let openingId: BN
-  tap.test(
-    'Propose create leader opening',
-    async () =>
-      (createOpeningProposalId = await createWorkingGroupLeaderOpening(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        'Storage'
-      ))
+  const createWorkingGroupLeaderOpeningFixture: CreateWorkingGroupLeaderOpeningFixture = new CreateWorkingGroupLeaderOpeningFixture(
+    apiWrapper,
+    m1KeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    'Storage'
   )
+  tap.test('Propose create leader opening', async () => createWorkingGroupLeaderOpeningFixture.runner(false))
+
+  let voteForCreateOpeningProposalFixture: VoteForProposalFixture
+  let expectLeadOpeningAddedFixture: ExpectLeadOpeningAddedFixture = new ExpectLeadOpeningAddedFixture(apiWrapper)
   tap.test('Approve add opening proposal', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, createOpeningProposalId)
-    openingId = await expectLeadOpeningAdded(apiWrapper)
+    voteForCreateOpeningProposalFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      createWorkingGroupLeaderOpeningFixture.getResult()!
+    )
+    voteForCreateOpeningProposalFixture.runner(false)
+    await expectLeadOpeningAddedFixture.runner(false)
   })
 
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        new BN(openingId),
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  let beginReviewProposalId: BN
-  tap.test(
-    'Propose begin leader application review',
-    async () =>
-      (beginReviewProposalId = await beginWorkingGroupLeaderApplicationReview(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        new BN(openingId),
-        'Storage'
-      ))
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      applicationStake,
+      roleStake,
+      new BN(expectLeadOpeningAddedFixture.getResult()!),
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginWorkingGroupLeaderApplicationReviewFixture: BeginWorkingGroupLeaderApplicationReviewFixture
+  tap.test('Propose begin leader application review', async () => {
+    beginWorkingGroupLeaderApplicationReviewFixture = new BeginWorkingGroupLeaderApplicationReviewFixture(
+      apiWrapper,
+      m1KeyPairs,
+      sudo,
+      new BN(expectLeadOpeningAddedFixture.getResult()!),
+      'Storage'
+    )
+    await beginWorkingGroupLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let voteForBeginReviewProposal: VoteForProposalFixture
+  let expectBeganApplicationReviewFixture: ExpectBeganApplicationReviewFixture = new ExpectBeganApplicationReviewFixture(
+    apiWrapper
   )
-  tap.test('Approve begin review proposal', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, beginReviewProposalId)
-    expectBeganApplicationReview(apiWrapper)
+  tap.test('Approve begin application review', async () => {
+    voteForBeginReviewProposal = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      beginWorkingGroupLeaderApplicationReviewFixture.getResult()!
+    )
+    voteForBeginReviewProposal.runner(false)
+    await expectBeganApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningProposalFixture: FillLeaderOpeningProposalFixture
+  tap.test('Propose fill leader opening', async () => {
+    fillLeaderOpeningProposalFixture = new FillLeaderOpeningProposalFixture(
+      apiWrapper,
+      m1KeyPairs,
+      leadKeyPair[0].address,
+      sudo,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      new BN(expectLeadOpeningAddedFixture.getResult()!),
+      WorkingGroups.StorageWorkingGroup
+    )
+    await fillLeaderOpeningProposalFixture.runner(false)
   })
 
-  let fillLeaderOpeningProposalId: BN
-  tap.test(
-    'Propose fill leader opening',
-    async () =>
-      (fillLeaderOpeningProposalId = await fillLeaderOpeningProposal(
-        apiWrapper,
-        m1KeyPairs,
-        leadKeyPair[0].address,
-        sudo,
-        firstRewardInterval,
-        rewardInterval,
-        payoutAmount,
-        new BN(openingId),
-        WorkingGroups.StorageWorkingGroup
-      ))
+  let voteForFillLeaderProposalFixture: VoteForProposalFixture
+  const expectLeaderSetFixture: ExpectLeaderSetFixture = new ExpectLeaderSetFixture(
+    apiWrapper,
+    leadKeyPair[0].address,
+    WorkingGroups.StorageWorkingGroup
   )
   tap.test('Approve fill leader opening', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, fillLeaderOpeningProposalId)
-    await expectLeaderSet(apiWrapper, leadKeyPair[0].address, WorkingGroups.StorageWorkingGroup)
+    voteForFillLeaderProposalFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      fillLeaderOpeningProposalFixture.getResult()!
+    )
+    voteForFillLeaderProposalFixture.runner(false)
+    await expectLeaderSetFixture.runner(false)
   })
 
-  let rewardProposalId: BN
-  tap.test(
-    'Propose leader reward',
-    async () =>
-      (rewardProposalId = await setLeaderRewardProposal(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        alteredPayoutAmount,
-        WorkingGroups.StorageWorkingGroup
-      ))
+  const setLeaderRewardProposalFixture: SetLeaderRewardProposalFixture = new SetLeaderRewardProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    sudo,
+    alteredPayoutAmount,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Propose leader reward', async () => setLeaderRewardProposalFixture.runner(false))
+
+  let voteForeLeaderRewardFixture: VoteForProposalFixture
+  const expectLeaderRewardAmountUpdatedFixture: ExpectLeaderRewardAmountUpdatedFixture = new ExpectLeaderRewardAmountUpdatedFixture(
+    apiWrapper,
+    alteredPayoutAmount,
+    WorkingGroups.StorageWorkingGroup
   )
   tap.test('Approve new leader reward', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, rewardProposalId)
-    await expectLeaderRewardAmountUpdated(apiWrapper, alteredPayoutAmount, WorkingGroups.StorageWorkingGroup)
+    voteForeLeaderRewardFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      setLeaderRewardProposalFixture.getResult()!
+    )
+    voteForeLeaderRewardFixture.runner(false)
+    await expectLeaderRewardAmountUpdatedFixture.runner(false)
   })
 
-  let decreaseStakeProposalId: BN
-  let newStake: BN
-  tap.test(
-    'Propose decrease stake',
-    async () =>
-      (decreaseStakeProposalId = await decreaseLeaderStakeProposal(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        stakeDecrement,
-        WorkingGroups.StorageWorkingGroup
-      ))
+  const decreaseLeaderStakeProposalFixture: DecreaseLeaderStakeProposalFixture = new DecreaseLeaderStakeProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    sudo,
+    stakeDecrement,
+    WorkingGroups.StorageWorkingGroup
   )
+  let newStake: BN
+  tap.test('Propose decrease stake', async () => decreaseLeaderStakeProposalFixture.runner(false))
+
+  let voteForDecreaseStakeProposal: VoteForProposalFixture
+  let expectLeaderStakeDecreasedFixture: ExpectLeaderStakeDecreasedFixture
   tap.test('Approve decreased leader stake', async () => {
     newStake = applicationStake.sub(stakeDecrement)
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, decreaseStakeProposalId)
-    await expectLeaderStakeDecreased(apiWrapper, newStake, WorkingGroups.StorageWorkingGroup)
+    voteForFillLeaderProposalFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      decreaseLeaderStakeProposalFixture.getResult()!
+    )
+    voteForFillLeaderProposalFixture.runner(false)
+    expectLeaderStakeDecreasedFixture = new ExpectLeaderStakeDecreasedFixture(
+      apiWrapper,
+      newStake,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await expectLeaderStakeDecreasedFixture.runner(false)
   })
 
-  let slashProposalId: BN
-  tap.test(
-    'Propose leader slash',
-    async () =>
-      (slashProposalId = await slashLeaderProposal(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        slashAmount,
-        WorkingGroups.StorageWorkingGroup
-      ))
+  const slashLeaderProposalFixture: SlashLeaderProposalFixture = new SlashLeaderProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    sudo,
+    slashAmount,
+    WorkingGroups.StorageWorkingGroup
   )
+  tap.test('Propose leader slash', async () => slashLeaderProposalFixture.runner(false))
+
+  let voteForSlashProposalFixture: VoteForProposalFixture
+  let expectLeaderSlashedFixture: ExpectLeaderSlashedFixture
   tap.test('Approve leader slash', async () => {
     newStake = newStake.sub(slashAmount)
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, slashProposalId)
-    await expectLeaderSlashed(apiWrapper, newStake, WorkingGroups.StorageWorkingGroup)
+    voteForSlashProposalFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      slashLeaderProposalFixture.getResult()!
+    )
+    voteForSlashProposalFixture.runner(false)
+    expectLeaderSlashedFixture = new ExpectLeaderSlashedFixture(apiWrapper, newStake, WorkingGroups.StorageWorkingGroup)
+    await expectLeaderSlashedFixture.runner(false)
   })
 
-  let terminateLeaderRoleProposalId: BN
-  tap.test(
-    'Propose terminate leader role',
-    async () =>
-      (terminateLeaderRoleProposalId = await terminateLeaderRoleProposal(
-        apiWrapper,
-        m1KeyPairs,
-        leadKeyPair[0].address,
-        sudo,
-        false,
-        WorkingGroups.StorageWorkingGroup
-      ))
+  const terminateLeaderRoleProposalFixture: TerminateLeaderRoleProposalFixture = new TerminateLeaderRoleProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    leadKeyPair[0].address,
+    sudo,
+    false,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Propose terminate leader role', async () => terminateLeaderRoleProposalFixture.runner(false))
+
+  let voteForLeaderRoleTerminationFixture: VoteForProposalFixture
+  const expectLeaderRoleTerminatedFixture: ExpectLeaderRoleTerminatedFixture = new ExpectLeaderRoleTerminatedFixture(
+    apiWrapper,
+    WorkingGroups.StorageWorkingGroup
   )
   tap.test('Approve leader role termination', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, terminateLeaderRoleProposalId)
-    await expectLeaderRoleTerminated(apiWrapper, WorkingGroups.StorageWorkingGroup)
+    voteForLeaderRoleTerminationFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      terminateLeaderRoleProposalFixture.getResult()!
+    )
+    voteForLeaderRoleTerminationFixture.runner(false)
+    await expectLeaderRoleTerminatedFixture.runner(false)
   })
 
   closeApi(apiWrapper)

+ 50 - 15
tests/network-tests/src/iznik/tests/proposals/setLeadProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { setLeadProposalTest } from './impl/setLeadProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,31 +7,69 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { SetLeadProposalFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Set lead proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
-  const durationInBlocks = 29
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const durationInBlocks = 29
 
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  setLeadProposalTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const setLeadProposalFixture: SetLeadProposalFixture = new SetLeadProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    sudo
+  )
+  tap.test('Set lead proposal test', async () => setLeadProposalFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 51 - 15
tests/network-tests/src/iznik/tests/proposals/spendingProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { spendingProposalTest } from './impl/spendingProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,19 +7,27 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { SpendingProposalFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Spending proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
@@ -30,13 +35,44 @@ tap.mocha.describe('Spending proposal scenario', async () => {
   const mintCapacity: BN = new BN(+process.env.COUNCIL_MINTING_CAPACITY!)
   const durationInBlocks = 29
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  spendingProposalTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri, spendingBalance, mintCapacity)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const spendingProposalFixture: SpendingProposalFixture = new SpendingProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    sudo,
+    spendingBalance,
+    mintCapacity
+  )
+  tap.test('Spending proposal test', async () => spendingProposalFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 44 - 15
tests/network-tests/src/iznik/tests/proposals/textProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { textProposalTest } from './impl/textProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,31 +7,63 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { TextProposalFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Text proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
   const durationInBlocks = 28
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  textProposalTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const textProposalFixture: TextProposalFixture = new TextProposalFixture(apiWrapper, m1KeyPairs, m2KeyPairs, sudo)
+  tap.test('Text proposal test', async () => textProposalFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 52 - 16
tests/network-tests/src/iznik/tests/proposals/updateRuntimeTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { updateRuntimeTest } from './impl/updateRuntime'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,32 +7,71 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { UpdateRuntimeFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Update runtime scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
   const durationInBlocks = 54
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  updateRuntimeTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri)
-  membershipTest(apiWrapper, new Array<KeyringPair>(), keyring, N, paidTerms, sudoUri)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const updateRuntimeFixture: UpdateRuntimeFixture = new UpdateRuntimeFixture(apiWrapper, m1KeyPairs, m2KeyPairs, sudo)
+  tap.test('Upgrade runtime', async () => updateRuntimeFixture.runner(false))
+
+  const thirdMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    Utils.createKeyPairs(keyring, N),
+    paidTerms
+  )
+  tap.test('Creating third set of members', async () => thirdMemberSetFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 50 - 15
tests/network-tests/src/iznik/tests/proposals/validatorCountProposalTest.ts

@@ -1,7 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
-import { validatorCountProposal } from './impl/validatorCountProposal'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -10,32 +7,70 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper } from '../../utils/apiWrapper'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { ValidatorCountProposalFixture } from './impl/proposalsModule'
 
 tap.mocha.describe('Validator count proposal scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
   const validatorCountIncrement: BN = new BN(+process.env.VALIDATOR_COUNT_INCREMENT!)
   const durationInBlocks = 29
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
-  validatorCountProposal(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri, validatorCountIncrement)
+
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
+  const validatorCountProposalFixture: ValidatorCountProposalFixture = new ValidatorCountProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    sudo,
+    validatorCountIncrement
+  )
+  tap.test('Validator count proposal', async () => validatorCountProposalFixture.runner(false))
+
   closeApi(apiWrapper)
 })

+ 62 - 29
tests/network-tests/src/iznik/tests/proposals/workingGroupMintCapacityProposalTest.ts

@@ -1,6 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from '../impl/membershipCreation'
-import { councilTest } from '../impl/electingCouncil'
 import { initConfig } from '../../utils/config'
 import { Keyring, WsProvider } from '@polkadot/api'
 import BN from 'bn.js'
@@ -9,54 +7,89 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { closeApi } from '../impl/closeApi'
 import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
-import { voteForProposal, workingGroupMintCapacityProposal } from './impl/proposalsModule'
-import { expectMintCapacityChanged } from '../workingGroup/impl/workingGroupModule'
+import { Utils } from '../../utils/utils'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
+import { VoteForProposalFixture, WorkingGroupMintCapacityProposalFixture } from './impl/proposalsModule'
+import { ExpectMintCapacityChangedFixture } from '../workingGroup/impl/workingGroupModule'
 
 tap.mocha.describe('Set storage working group mint capacity scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const m1KeyPairs: KeyringPair[] = []
-  const m2KeyPairs: KeyringPair[] = []
-
+  const nodeUrl: string = process.env.NODE_URL!
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
+  const provider = new WsProvider(nodeUrl)
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
+
   const N: number = +process.env.MEMBERSHIP_CREATION_N!
+  const m1KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const m2KeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+
   const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
-  const nodeUrl: string = process.env.NODE_URL!
-  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!
   const K: number = +process.env.COUNCIL_ELECTION_K!
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!)
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!)
   const mintCapacityIncrement: BN = new BN(process.env.MINT_CAPACITY_INCREMENT!)
   const durationInBlocks = 30
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri)
-  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake)
 
-  let mintCapacityProposalId: BN
+  const firstMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m1KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating first set of members', async () => firstMemberSetFixture.runner(false))
+
+  const secondMemberSetFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    m2KeyPairs,
+    paidTerms
+  )
+  tap.test('Creating second set of members', async () => secondMemberSetFixture.runner(false))
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture(
+    apiWrapper,
+    m1KeyPairs,
+    m2KeyPairs,
+    K,
+    sudo,
+    greaterStake,
+    lesserStake
+  )
+  tap.test('Elect council', async () => electCouncilFixture.runner(false))
+
   const newMintCapacity: BN = (await apiWrapper.getWorkingGroupMintCapacity(WorkingGroups.StorageWorkingGroup)).add(
     mintCapacityIncrement
   )
-  tap.test(
-    'Propose mint capacity',
-    async () =>
-      (mintCapacityProposalId = await workingGroupMintCapacityProposal(
-        apiWrapper,
-        m1KeyPairs,
-        sudo,
-        newMintCapacity,
-        WorkingGroups.StorageWorkingGroup
-      ))
+  const workingGroupMintCapacityProposalFixture: WorkingGroupMintCapacityProposalFixture = new WorkingGroupMintCapacityProposalFixture(
+    apiWrapper,
+    m1KeyPairs,
+    sudo,
+    newMintCapacity,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Propose mint capacity', async () => workingGroupMintCapacityProposalFixture.runner(false))
+
+  let voteForProposalFixture: VoteForProposalFixture
+  const expectMintCapacityChanged: ExpectMintCapacityChangedFixture = new ExpectMintCapacityChangedFixture(
+    apiWrapper,
+    newMintCapacity
   )
   tap.test('Approve mint capacity', async () => {
-    voteForProposal(apiWrapper, m2KeyPairs, sudo, mintCapacityProposalId)
-    await expectMintCapacityChanged(apiWrapper, newMintCapacity)
+    voteForProposalFixture = new VoteForProposalFixture(
+      apiWrapper,
+      m2KeyPairs,
+      sudo,
+      workingGroupMintCapacityProposalFixture.getResult()!
+    )
+    voteForProposalFixture.runner(false)
+    await expectMintCapacityChanged.runner(false)
   })
 
   closeApi(apiWrapper)

+ 81 - 71
tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts

@@ -6,12 +6,12 @@ import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
 import {
-  addWorkerOpening,
-  applyForOpening,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
+  AddLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  ApplyForOpeningFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  LeaveRoleFixture,
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
@@ -61,85 +61,95 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  // let leadOpenignId: BN
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
+    await fillLeaderOpeningFixture.runner(false)
+  })
+
+  const addWorkerOpeningWithoutStakeFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    new BN(0),
+    new BN(0),
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Add worker opening with 0 stake, expect failure', async () =>
+    addWorkerOpeningWithoutStakeFixture.runner(true)
   )
 
-  let workerOpenignId: BN
-  tap.test(
-    'Add worker opening with 0 stake, expect failure',
-    async () =>
-      (workerOpenignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        new BN(0),
-        new BN(0),
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        true
-      ))
+  const addWorkerOpeningWithoutUnstakingPeriodFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    new BN(0),
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test(
-    'Add worker opening with 0 unstaking period, expect failure',
-    async () =>
-      (workerOpenignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        new BN(0),
-        WorkingGroups.StorageWorkingGroup,
-        true
-      ))
+  tap.test('Add worker opening with 0 unstaking period, expect failure', async () =>
+    addWorkerOpeningWithoutUnstakingPeriodFixture.runner(true)
   )
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const leaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => leaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })

+ 10 - 13
tests/network-tests/src/iznik/tests/workingGroup/impl/workingGroupModule.ts

@@ -83,10 +83,11 @@ export class AddWorkerOpeningFixture implements Fixture {
     await this.apiWrapper.transferBalance(this.sudo, this.lead.address, addOpeningFee)
 
     // Worker opening creation
-    const addOpeningPromise: Promise<BN> = this.apiWrapper.expectOpeningAdded()
+    const addOpeningPromise: Promise<Event> = this.apiWrapper.expectEvent('OpeningAdded')
     await this.apiWrapper.addOpening(this.lead, opening, this.module, expectFailure)
     if (!expectFailure) {
-      const openingId: BN = await addOpeningPromise
+      const openingId: BN = ((await addOpeningPromise).data[0] as unknown) as BN
+      console.log('received opening id ' + openingId)
       this.result = openingId
     }
   }
@@ -152,9 +153,9 @@ export class AddLeaderOpeningFixture implements Fixture {
       .setText(uuid().substring(0, 8))
       .setOpeningType('leader')
 
-    const addOpeningPromise: Promise<BN> = this.apiWrapper.expectOpeningAdded()
+    const addOpeningPromise: Promise<Event> = this.apiWrapper.expectEvent('OpeningAdded')
     await this.apiWrapper.sudoAddOpening(this.sudo, opening, this.module)
-    const openingId: BN = await addOpeningPromise
+    const openingId: BN = ((await addOpeningPromise).data[0] as unknown) as BN
 
     this.result = openingId
   }
@@ -202,7 +203,6 @@ export class ApplyForOpeningFixture implements Fixture {
   private roleStake: BN
   private openingId: BN
   private module: WorkingGroups
-  private expectFailure: boolean
 
   public constructor(
     apiWrapper: ApiWrapper,
@@ -211,8 +211,7 @@ export class ApplyForOpeningFixture implements Fixture {
     applicationStake: BN,
     roleStake: BN,
     openingId: BN,
-    module: WorkingGroups,
-    expectFailure: boolean
+    module: WorkingGroups
   ) {
     this.apiWrapper = apiWrapper
     this.membersKeyPairs = membersKeyPairs
@@ -221,7 +220,6 @@ export class ApplyForOpeningFixture implements Fixture {
     this.roleStake = roleStake
     this.openingId = openingId
     this.module = module
-    this.expectFailure = expectFailure
   }
 
   public async runner(expectFailure: boolean): Promise<void> {
@@ -240,7 +238,7 @@ export class ApplyForOpeningFixture implements Fixture {
       this.applicationStake,
       uuid().substring(0, 8),
       this.module,
-      this.expectFailure
+      expectFailure
     )
   }
 }
@@ -644,8 +642,7 @@ export class DecreaseStakeFixture implements Fixture {
     membersKeyPairs: KeyringPair[],
     lead: KeyringPair,
     sudo: KeyringPair,
-    module: WorkingGroups,
-    expectFailure: boolean
+    module: WorkingGroups
   ) {
     this.apiWrapper = apiWrapper
     this.membersKeyPairs = membersKeyPairs
@@ -912,7 +909,7 @@ export class ExpectLeaderSetFixture implements Fixture {
   }
 }
 
-export class ExpectBeganApplicationReview implements Fixture {
+export class ExpectBeganApplicationReviewFixture implements Fixture {
   private apiWrapper: ApiWrapper
 
   private result: BN | undefined
@@ -1069,7 +1066,7 @@ export class ExpectLeaderSlashedFixture implements Fixture {
   }
 }
 
-export class ExpectMintCapacityChanged implements Fixture {
+export class ExpectMintCapacityChangedFixture implements Fixture {
   private apiWrapper: ApiWrapper
   private expectedMintCapacity: BN
 

+ 182 - 124
tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts

@@ -6,17 +6,18 @@ import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
 import {
-  addWorkerOpening,
-  applyForOpening,
-  beginApplicationReview,
-  fillOpening,
-  decreaseStake,
-  slash,
-  terminateRole,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
+  AddLeaderOpeningFixture,
+  ApplyForOpeningFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  WithdrawApplicationFixture,
+  BeginApplicationReviewFixture,
+  FillOpeningFixture,
+  LeaveRoleFixture,
+  DecreaseStakeFixture,
+  SlashFixture,
+  TerminateRoleFixture,
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap = require('tap')
@@ -66,157 +67,214 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillLeaderOpeningFixture.runner(false)
+  })
 
-  let openignId: BN
-  tap.test(
-    'Add worker opening',
-    async () =>
-      (openignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      ))
-  )
-  tap.test(
-    'Apply for worker opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.StorageWorkingGroup)
+  const addWorkerOpeningFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill worker opening', async () =>
-    fillOpening(
+  tap.test('Add worker opening', async () => addWorkerOpeningFixture.runner(false))
+
+  let applyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('First apply for worker opening', async () => {
+    applyForWorkerOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForWorkerOpeningFixture.runner(false)
+  })
+
+  let beginApplicationReviewFixture: BeginApplicationReviewFixture
+  tap.test('Begin application review', async () => {
+    beginApplicationReviewFixture = new BeginApplicationReviewFixture(
+      apiWrapper,
       leadKeyPair[0],
       sudo,
-      openignId,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginApplicationReviewFixture.runner(false)
+  })
+
+  let fillOpeningFixture: FillOpeningFixture
+  tap.test('Fill worker opening', async () => {
+    fillOpeningFixture = new FillOpeningFixture(
+      apiWrapper,
+      nKeyPairs,
+      leadKeyPair[0],
+      sudo,
+      addWorkerOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillOpeningFixture.runner(false)
+  })
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
-  tap.test('Decrease worker stake, expect failure', async () =>
-    decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.StorageWorkingGroup, true)
+  const leaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
+  tap.test('Leaving lead role', async () => leaveRoleFixture.runner(false))
 
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
+  const decreaseStakeFailureFixture: DecreaseStakeFixture = new DecreaseStakeFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  tap.test('Decrease worker stake, expect failure', async () => decreaseStakeFailureFixture.runner(true))
+
+  const addNewLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  tap.test('Add lead opening', async () => await addNewLeaderOpeningFixture.runner(false))
+
+  let applyForNewLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForNewLeaderOpeningFixture = new ApplyForOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      applicationStake,
+      roleStake,
+      addNewLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForNewLeaderOpeningFixture.runner(false)
+  })
+
+  let beginNewLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginNewLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addNewLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginNewLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillNewLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillNewLeaderOpeningFixture = new FillLeaderOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      addNewLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillNewLeaderOpeningFixture.runner(false)
+  })
 
-  tap.test('Decrease worker stake', async () =>
-    decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.StorageWorkingGroup, false)
+  const decreaseStakeFixture: DecreaseStakeFixture = new DecreaseStakeFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Slash worker', async () =>
-    slash(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.StorageWorkingGroup, false)
+  tap.test('Decrease worker stake', async () => decreaseStakeFixture.runner(false))
+
+  const slashFixture: SlashFixture = new SlashFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Terminate worker role', async () =>
-    terminateRole(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.StorageWorkingGroup, false)
+  tap.test('Slash worker', async () => slashFixture.runner(false))
+
+  const terminateRoleFixture: TerminateRoleFixture = new TerminateRoleFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
+  tap.test('Terminate worker role', async () => terminateRoleFixture.runner(false))
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const newLeaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => newLeaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })

+ 125 - 89
tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts

@@ -6,17 +6,16 @@ import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
 import {
-  addWorkerOpening,
-  applyForOpening,
-  beginApplicationReview,
-  fillOpening,
-  increaseStake,
-  updateRewardAccount,
-  updateRoleAccount,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
+  AddLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  ApplyForOpeningFixture,
+  BeginApplicationReviewFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  FillOpeningFixture,
+  IncreaseStakeFixture,
+  LeaveRoleFixture,
+  UpdateRewardAccountFixture,
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap = require('tap')
@@ -66,109 +65,146 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  // let leadOpenignId: BN
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillLeaderOpeningFixture.runner(false)
+  })
 
-  let openignId: BN
-  tap.test(
-    'Add worker opening',
-    async () =>
-      (openignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      ))
-  )
-  tap.test(
-    'Apply for worker opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.StorageWorkingGroup)
+  const addWorkerOpeningFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill worker opening', async () =>
-    fillOpening(
+  tap.test('Add worker opening', async () => addWorkerOpeningFixture.runner(false))
+
+  let applyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('First apply for worker opening', async () => {
+    applyForWorkerOpeningFixture = new ApplyForOpeningFixture(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForWorkerOpeningFixture.runner(false)
+  })
+
+  let beginApplicationReviewFixture: BeginApplicationReviewFixture
+  tap.test('Begin application review', async () => {
+    beginApplicationReviewFixture = new BeginApplicationReviewFixture(
+      apiWrapper,
+      leadKeyPair[0],
+      sudo,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginApplicationReviewFixture.runner(false)
+  })
+
+  let fillOpeningFixture: FillOpeningFixture
+  tap.test('Fill worker opening', async () => {
+    fillOpeningFixture = new FillOpeningFixture(
       apiWrapper,
       nKeyPairs,
       leadKeyPair[0],
       sudo,
-      openignId,
+      addWorkerOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillOpeningFixture.runner(false)
+  })
 
-  tap.test('Increase worker stake', async () =>
-    increaseStake(apiWrapper, nKeyPairs, sudo, WorkingGroups.StorageWorkingGroup)
+  const increaseStakeFixture: IncreaseStakeFixture = new IncreaseStakeFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Update reward account', async () =>
-    updateRewardAccount(apiWrapper, nKeyPairs, keyring, sudo, WorkingGroups.StorageWorkingGroup)
+  tap.test('Increase worker stake', async () => increaseStakeFixture.runner(false))
+
+  const updateRewardAccountFixture: UpdateRewardAccountFixture = new UpdateRewardAccountFixture(
+    apiWrapper,
+    nKeyPairs,
+    keyring,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Update role account', async () =>
-    updateRoleAccount(apiWrapper, nKeyPairs, keyring, sudo, WorkingGroups.StorageWorkingGroup)
+  tap.test('Update reward account', async () => updateRewardAccountFixture.runner(false))
+
+  const updateRoleAccountFixture: UpdateRewardAccountFixture = new UpdateRewardAccountFixture(
+    apiWrapper,
+    nKeyPairs,
+    keyring,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
+  tap.test('Update role account', async () => updateRoleAccountFixture.runner(false))
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const newLeaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => newLeaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })

+ 113 - 83
tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts

@@ -5,21 +5,21 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import {
-  addWorkerOpening,
-  applyForOpening,
-  beginApplicationReview,
-  fillOpening,
-  withdrawApplicaiton,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
-} from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
 import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
 import { Utils } from '../../utils/utils'
+import {
+  AddLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  ApplyForOpeningFixture,
+  BeginApplicationReviewFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  FillOpeningFixture,
+  LeaveRoleFixture,
+  WithdrawApplicationFixture,
+} from './impl/workingGroupModule'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
@@ -64,112 +64,142 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  // let leadOpenignId: BN
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillLeaderOpeningFixture.runner(false)
+  })
 
-  let workerOpenignId: BN
-  tap.test(
-    'Add worker opening',
-    async () =>
-      (workerOpenignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      ))
+  const addWorkerOpeningFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Apply for worker opening', async () =>
-    applyForOpening(
+  tap.test('Add worker opening', async () => addWorkerOpeningFixture.runner(false))
+
+  let firstApplyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('First apply for worker opening', async () => {
+    firstApplyForWorkerOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      workerOpenignId,
-      WorkingGroups.StorageWorkingGroup,
-      false
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
+    await firstApplyForWorkerOpeningFixture.runner(false)
+  })
+
+  const withdrawApplicationFixture: WithdrawApplicationFixture = new WithdrawApplicationFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Withdraw worker application', async () =>
-    withdrawApplicaiton(apiWrapper, nKeyPairs, sudo, WorkingGroups.StorageWorkingGroup)
-  )
-  tap.test('Apply for worker opening', async () =>
-    applyForOpening(
+  tap.test('Withdraw worker application', async () => withdrawApplicationFixture.runner(false))
+
+  let secondApplyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('Second apply for worker opening', async () => {
+    secondApplyForWorkerOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      workerOpenignId,
-      WorkingGroups.StorageWorkingGroup,
-      false
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
-  )
-  tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId, WorkingGroups.StorageWorkingGroup)
-  )
-  tap.test('Fill worker opening', async () =>
-    fillOpening(
+    await secondApplyForWorkerOpeningFixture.runner(false)
+  })
+
+  let beginApplicationReviewFixture: BeginApplicationReviewFixture
+  tap.test('Begin application review', async () => {
+    beginApplicationReviewFixture = new BeginApplicationReviewFixture(
+      apiWrapper,
+      leadKeyPair[0],
+      sudo,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginApplicationReviewFixture.runner(false)
+  })
+
+  let fillOpeningFixture: FillOpeningFixture
+  tap.test('Fill worker opening', async () => {
+    fillOpeningFixture = new FillOpeningFixture(
       apiWrapper,
       nKeyPairs,
       leadKeyPair[0],
       sudo,
-      workerOpenignId,
+      addWorkerOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillOpeningFixture.runner(false)
+  })
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const leaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => leaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })

+ 114 - 84
tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts

@@ -5,20 +5,20 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import {
-  addWorkerOpening,
-  applyForOpening,
-  acceptApplications,
-  terminateApplications,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
-} from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
 import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
 import { Utils } from '../../utils/utils'
+import {
+  AcceptApplicationsFixture,
+  AddLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  ApplyForOpeningFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  LeaveRoleFixture,
+  TerminateApplicationsFixture,
+} from './impl/workingGroupModule'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
@@ -65,111 +65,141 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpeningActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    leadOpeningActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  // let leadOpenignId: BN
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillLeaderOpeningFixture.runner(false)
+  })
 
-  let openignId: BN
-  tap.test(
-    'Add worker opening',
-    async () =>
-      (openignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      ))
+  const addWorkerOpeningFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Apply for worker opening, expect failure', async () =>
-    applyForOpening(
+  tap.test('Add worker opening', async () => addWorkerOpeningFixture.runner(false))
+
+  let applyForWorkerOpeningBeforeAcceptanceFixture: ApplyForOpeningFixture
+  tap.test('Apply for worker opening, expect failure', async () => {
+    applyForWorkerOpeningBeforeAcceptanceFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      openignId,
-      WorkingGroups.StorageWorkingGroup,
-      true
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
-  )
-  tap.test('Begin accepting worker applications', async () =>
-    acceptApplications(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.StorageWorkingGroup)
-  )
-  tap.test('Apply for worker opening as non-member, expect failure', async () =>
-    applyForOpening(
+    await applyForWorkerOpeningBeforeAcceptanceFixture.runner(true)
+  })
+
+  let acceptApplicationsFixture: AcceptApplicationsFixture
+  tap.test('Begin accepting worker applications', async () => {
+    acceptApplicationsFixture = new AcceptApplicationsFixture(
+      apiWrapper,
+      leadKeyPair[0],
+      sudo,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    acceptApplicationsFixture.runner(false)
+  })
+
+  let applyForWorkerOpeningAsNonMemberFixture: ApplyForOpeningFixture
+  tap.test('Apply for worker opening as non-member, expect failure', async () => {
+    applyForWorkerOpeningAsNonMemberFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nonMemberKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      openignId,
-      WorkingGroups.StorageWorkingGroup,
-      true
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
-  )
-  tap.test('Apply for worker opening as member', async () =>
-    applyForOpening(
+    await applyForWorkerOpeningAsNonMemberFixture.runner(true)
+  })
+
+  let applyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for worker opening', async () => {
+    applyForWorkerOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      openignId,
-      WorkingGroups.StorageWorkingGroup,
-      false
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
+    await applyForWorkerOpeningFixture.runner(false)
+  })
+
+  const terminateApplicationsFixture: TerminateApplicationsFixture = new TerminateApplicationsFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Terminate worker applicaitons', async () =>
-    terminateApplications(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.StorageWorkingGroup)
-  )
+  tap.test('Terminate worker applicaitons', async () => terminateApplicationsFixture.runner(false))
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const leaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => leaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })

+ 102 - 78
tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts

@@ -6,16 +6,15 @@ import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
 import {
-  addWorkerOpening,
-  applyForOpening,
-  beginApplicationReview,
-  fillOpening,
-  addLeaderOpening,
-  beginLeaderApplicationReview,
-  fillLeaderOpening,
-  leaveRole,
-  awaitPayout,
-  setMintCapacity,
+  AddLeaderOpeningFixture,
+  AddWorkerOpeningFixture,
+  ApplyForOpeningFixture,
+  AwaitPayoutFixture,
+  BeginApplicationReviewFixture,
+  BeginLeaderApplicationReviewFixture,
+  FillLeaderOpeningFixture,
+  FillOpeningFixture,
+  LeaveRoleFixture,
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
@@ -66,102 +65,127 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   )
   tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
-  let leadOpenignId: BN
-  tap.test(
-    'Add lead opening',
-    async () =>
-      (leadOpenignId = await addLeaderOpening(
-        apiWrapper,
-        nKeyPairs,
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        WorkingGroups.StorageWorkingGroup
-      ))
-  )
-  tap.test(
-    'Apply for lead opening',
-    async () =>
-      await applyForOpening(
-        apiWrapper,
-        leadKeyPair,
-        sudo,
-        applicationStake,
-        roleStake,
-        leadOpenignId,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      )
-  )
-  tap.test('Begin lead application review', async () =>
-    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.StorageWorkingGroup)
+  const addLeaderOpeningFixture: AddLeaderOpeningFixture = new AddLeaderOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(
+  // let leadOpenignId: BN
+  tap.test('Add lead opening', async () => await addLeaderOpeningFixture.runner(false))
+
+  let applyForLeaderOpeningFixture: ApplyForOpeningFixture
+  tap.test('Apply for lead opening', async () => {
+    applyForLeaderOpeningFixture = new ApplyForOpeningFixture(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      applicationStake,
+      roleStake,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await applyForLeaderOpeningFixture.runner(false)
+  })
+
+  let beginLeaderApplicationReviewFixture: BeginLeaderApplicationReviewFixture
+  tap.test('Begin lead application review', async () => {
+    beginLeaderApplicationReviewFixture = new BeginLeaderApplicationReviewFixture(
+      apiWrapper,
+      sudo,
+      addLeaderOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginLeaderApplicationReviewFixture.runner(false)
+  })
+
+  let fillLeaderOpeningFixture: FillLeaderOpeningFixture
+  tap.test('Fill lead opening', async () => {
+    fillLeaderOpeningFixture = new FillLeaderOpeningFixture(
       apiWrapper,
       leadKeyPair,
       sudo,
-      leadOpenignId,
+      addLeaderOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillLeaderOpeningFixture.runner(false)
+  })
 
-  let workerOpenignId: BN
-  tap.test(
-    'Add worker opening',
-    async () =>
-      (workerOpenignId = await addWorkerOpening(
-        apiWrapper,
-        nKeyPairs,
-        leadKeyPair[0],
-        sudo,
-        applicationStake,
-        roleStake,
-        openingActivationDelay,
-        unstakingPeriod,
-        WorkingGroups.StorageWorkingGroup,
-        false
-      ))
+  const addWorkerOpeningFixture: AddWorkerOpeningFixture = new AddWorkerOpeningFixture(
+    apiWrapper,
+    nKeyPairs,
+    leadKeyPair[0],
+    sudo,
+    applicationStake,
+    roleStake,
+    openingActivationDelay,
+    unstakingPeriod,
+    WorkingGroups.StorageWorkingGroup
   )
-  tap.test('Apply for worker opening', async () =>
-    applyForOpening(
+  tap.test('Add worker opening', async () => addWorkerOpeningFixture.runner(false))
+
+  let applyForWorkerOpeningFixture: ApplyForOpeningFixture
+  tap.test('First apply for worker opening', async () => {
+    applyForWorkerOpeningFixture = new ApplyForOpeningFixture(
       apiWrapper,
       nKeyPairs,
       sudo,
       applicationStake,
       roleStake,
-      workerOpenignId,
-      WorkingGroups.StorageWorkingGroup,
-      false
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
     )
-  )
-  tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId, WorkingGroups.StorageWorkingGroup)
-  )
-  tap.test('Set mint capacity', async () =>
-    setMintCapacity(apiWrapper, sudo, mintCapacity, WorkingGroups.StorageWorkingGroup)
-  )
-  tap.test('Fill worker opening', async () =>
-    fillOpening(
+    await applyForWorkerOpeningFixture.runner(false)
+  })
+
+  let beginApplicationReviewFixture: BeginApplicationReviewFixture
+  tap.test('Begin application review', async () => {
+    beginApplicationReviewFixture = new BeginApplicationReviewFixture(
+      apiWrapper,
+      leadKeyPair[0],
+      sudo,
+      addWorkerOpeningFixture.getResult()!,
+      WorkingGroups.StorageWorkingGroup
+    )
+    await beginApplicationReviewFixture.runner(false)
+  })
+
+  let fillOpeningFixture: FillOpeningFixture
+  tap.test('Fill worker opening', async () => {
+    fillOpeningFixture = new FillOpeningFixture(
       apiWrapper,
       nKeyPairs,
       leadKeyPair[0],
       sudo,
-      workerOpenignId,
+      addWorkerOpeningFixture.getResult()!,
       firstRewardInterval,
       rewardInterval,
       payoutAmount,
       WorkingGroups.StorageWorkingGroup
     )
-  )
+    await fillOpeningFixture.runner(false)
+  })
 
-  tap.test('Await worker payout', async () => awaitPayout(apiWrapper, nKeyPairs, WorkingGroups.StorageWorkingGroup))
+  const awaitPayoutFixture: AwaitPayoutFixture = new AwaitPayoutFixture(
+    apiWrapper,
+    nKeyPairs,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Await worker payout', async () => awaitPayoutFixture.runner(false))
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.StorageWorkingGroup))
+  const leaveRoleFixture: LeaveRoleFixture = new LeaveRoleFixture(
+    apiWrapper,
+    leadKeyPair,
+    sudo,
+    WorkingGroups.StorageWorkingGroup
+  )
+  tap.test('Leaving lead role', async () => leaveRoleFixture.runner(false))
 
   closeApi(apiWrapper)
 })