Explorar el Código

refactored membership and council fixtures

Gleb Urvanov hace 4 años
padre
commit
3f3b0ead30

+ 1 - 1
.prettierrc.js

@@ -1,3 +1,3 @@
 module.exports = {
-  ...require('@joystream/prettier-config'),
+  ...require('./devops/prettier-config'),
 }

+ 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/nicaea/tests/workingGroup/*Test.ts -T",
+    "debug": "tap --files src/iznik/tests/workingGroup/*Test.ts -T",
     "lint": "eslint . --quiet --ext .ts",
     "checks": "yarn lint && tsc --noEmit --pretty && prettier ./ --check",
     "format": "prettier ./ --write "

+ 40 - 13
tests/network-tests/src/iznik/tests/electingCouncilTest.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 { setTestTimeout } from '../utils/setTestTimeout'
@@ -9,30 +7,59 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { ApiWrapper } from '../utils/apiWrapper'
 import { closeApi } from './impl/closeApi'
+import { BuyMembershipHappyCaseFixture } from './impl/membershipModule'
+import { ElectCouncilFixture } from './impl/councilElectionModule'
+import { Utils } from '../utils/utils'
 
 tap.mocha.describe('Electing council 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 = 25
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
+  const durationInBlocks = 25
 
   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)
+
+  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))
+
   closeApi(apiWrapper)
 })

+ 137 - 0
tests/network-tests/src/iznik/tests/impl/councilElectionModule.ts

@@ -0,0 +1,137 @@
+import { ApiWrapper } from '../../utils/apiWrapper'
+import { KeyringPair } from '@polkadot/keyring/types'
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Seat } from '@nicaea/types/council'
+import { v4 as uuid } from 'uuid'
+import { Utils } from '../../utils/utils'
+import { Fixture } from '../../utils/fixture'
+
+export class ElectCouncilFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private m1KeyPairs: KeyringPair[]
+  private m2KeyPairs: KeyringPair[]
+  private k: number
+  private sudo: KeyringPair
+  private greaterStake: BN
+  private lesserStake: BN
+
+  public constructor(
+    apiWrapper: ApiWrapper,
+    m1KeyPairs: KeyringPair[],
+    m2KeyPairs: KeyringPair[],
+    k: number,
+    sudo: KeyringPair,
+    greaterStake: BN,
+    lesserStake: BN
+  ) {
+    this.apiWrapper = apiWrapper
+    this.m1KeyPairs = m1KeyPairs
+    this.m2KeyPairs = m2KeyPairs
+    this.k = k
+    this.sudo = sudo
+    this.greaterStake = greaterStake
+    this.lesserStake = lesserStake
+  }
+
+  public async runner(expectFailure: boolean): Promise<void> {
+    let now = await this.apiWrapper.getBestBlock()
+    const applyForCouncilFee: BN = this.apiWrapper.estimateApplyForCouncilFee(this.greaterStake)
+    const voteForCouncilFee: BN = this.apiWrapper.estimateVoteForCouncilFee(
+      this.sudo.address,
+      this.sudo.address,
+      this.greaterStake
+    )
+    const salt: string[] = []
+    this.m1KeyPairs.forEach(() => {
+      salt.push(''.concat(uuid().replace(/-/g, '')))
+    })
+    const revealVoteFee: BN = this.apiWrapper.estimateRevealVoteFee(this.sudo.address, salt[0])
+
+    // Topping the balances
+    await this.apiWrapper.transferBalanceToAccounts(
+      this.sudo,
+      this.m2KeyPairs,
+      applyForCouncilFee.add(this.greaterStake)
+    )
+    await this.apiWrapper.transferBalanceToAccounts(
+      this.sudo,
+      this.m1KeyPairs,
+      voteForCouncilFee.add(revealVoteFee).add(this.greaterStake)
+    )
+
+    // First K members stake more
+    await this.apiWrapper.sudoStartAnnouncingPerion(this.sudo, now.addn(100))
+    await this.apiWrapper.batchApplyForCouncilElection(this.m2KeyPairs.slice(0, this.k), this.greaterStake)
+    this.m2KeyPairs.slice(0, this.k).forEach((keyPair) =>
+      this.apiWrapper.getCouncilElectionStake(keyPair.address).then((stake) => {
+        assert(
+          stake.eq(this.greaterStake),
+          `${keyPair.address} not applied correctrly for council election with stake ${stake} versus expected ${this.greaterStake}`
+        )
+      })
+    )
+
+    // Last members stake less
+    await this.apiWrapper.batchApplyForCouncilElection(this.m2KeyPairs.slice(this.k), this.lesserStake)
+    this.m2KeyPairs.slice(this.k).forEach((keyPair) =>
+      this.apiWrapper.getCouncilElectionStake(keyPair.address).then((stake) => {
+        assert(
+          stake.eq(this.lesserStake),
+          `${keyPair.address} not applied correctrly for council election with stake ${stake} versus expected ${this.lesserStake}`
+        )
+      })
+    )
+
+    // Voting
+    await this.apiWrapper.sudoStartVotingPerion(this.sudo, now.addn(100))
+    await this.apiWrapper.batchVoteForCouncilMember(
+      this.m1KeyPairs.slice(0, this.k),
+      this.m2KeyPairs.slice(0, this.k),
+      salt.slice(0, this.k),
+      this.lesserStake
+    )
+    await this.apiWrapper.batchVoteForCouncilMember(
+      this.m1KeyPairs.slice(this.k),
+      this.m2KeyPairs.slice(this.k),
+      salt.slice(this.k),
+      this.greaterStake
+    )
+
+    // Revealing
+    await this.apiWrapper.sudoStartRevealingPerion(this.sudo, now.addn(100))
+    await this.apiWrapper.batchRevealVote(
+      this.m1KeyPairs.slice(0, this.k),
+      this.m2KeyPairs.slice(0, this.k),
+      salt.slice(0, this.k)
+    )
+    await this.apiWrapper.batchRevealVote(
+      this.m1KeyPairs.slice(this.k),
+      this.m2KeyPairs.slice(this.k),
+      salt.slice(this.k)
+    )
+    now = await this.apiWrapper.getBestBlock()
+
+    // Resolving election
+    // 3 is to ensure the revealing block is in future
+    await this.apiWrapper.sudoStartRevealingPerion(this.sudo, now.addn(3))
+    await Utils.wait(this.apiWrapper.getBlockDuration().muln(2.5).toNumber())
+    const seats: Seat[] = await this.apiWrapper.getCouncil()
+
+    // Preparing collections to increase assertion readability
+    const m2addresses: string[] = this.m2KeyPairs.map((keyPair) => keyPair.address)
+    const m1addresses: string[] = this.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(this.greaterStake.add(this.lesserStake)),
+        `Member ${seat.member} has unexpected stake ${Utils.getTotalStake(seat)}`
+      )
+    )
+  }
+}

+ 57 - 50
tests/network-tests/src/iznik/tests/impl/membershipModule.ts

@@ -1,80 +1,82 @@
 import { ApiWrapper } from '../../utils/apiWrapper'
 import { KeyringPair } from '@polkadot/keyring/types'
-import { Keyring } from '@polkadot/api'
-import { v4 as uuid } from 'uuid'
 import BN from 'bn.js'
 import { assert } from 'chai'
+import { Fixture } from '../../utils/fixture'
 
-export class BuyMembershipHappyCaseFixture {
-  private keyPairs: KeyringPair[] = []
+export class BuyMembershipHappyCaseFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private sudo: KeyringPair
+  private keyPairs: KeyringPair[]
+  private paidTerms: number
 
-  public getKeyPairs(): KeyringPair[] {
-    return this.keyPairs
+  public constructor(apiWrapper: ApiWrapper, sudo: KeyringPair, keyPairs: KeyringPair[], paidTerms: number) {
+    this.apiWrapper = apiWrapper
+    this.sudo = sudo
+    this.keyPairs = keyPairs
+    this.paidTerms = paidTerms
   }
 
-  public async runner(
-    apiWrapper: ApiWrapper,
-    sudo: KeyringPair,
-    keyPairs: KeyringPair[],
-    keyring: Keyring,
-    n: number,
-    paidTerms: number
-  ): Promise<void> {
-    // Account creation
-    for (let i = 0; i < n; i++) {
-      keyPairs.push(keyring.addFromUri(i + uuid().substring(0, 8)))
-    }
-
+  public async runner(expectFailure: boolean): Promise<void> {
     // Fee estimation and transfer
-    const membershipFee: BN = await apiWrapper.getMembershipFee(paidTerms)
-    const membershipTransactionFee: BN = apiWrapper.estimateBuyMembershipFee(
-      sudo,
-      paidTerms,
+    const membershipFee: BN = await this.apiWrapper.getMembershipFee(this.paidTerms)
+    const membershipTransactionFee: BN = this.apiWrapper.estimateBuyMembershipFee(
+      this.sudo,
+      this.paidTerms,
       'member_name_which_is_longer_than_expected'
     )
-    await apiWrapper.transferBalanceToAccounts(sudo, keyPairs, membershipTransactionFee.add(new BN(membershipFee)))
+    await this.apiWrapper.transferBalanceToAccounts(
+      this.sudo,
+      this.keyPairs,
+      membershipTransactionFee.add(new BN(membershipFee))
+    )
 
     // Buying membership
     await Promise.all(
-      keyPairs.map(async (keyPair, index) => {
-        await apiWrapper.buyMembership(keyPair, paidTerms, `new_member_${index}${keyPair.address.substring(0, 8)}`)
+      this.keyPairs.map(async (keyPair, index) => {
+        await this.apiWrapper.buyMembership(
+          keyPair,
+          this.paidTerms,
+          `new_member_${index}${keyPair.address.substring(0, 8)}`
+        )
       })
     )
 
     // Assertions
-    keyPairs.forEach((keyPair, index) =>
-      apiWrapper
+    this.keyPairs.forEach((keyPair) =>
+      this.apiWrapper
         .getMemberIds(keyPair.address)
         .then((membership) => assert(membership.length > 0, `Account ${keyPair.address} is not a member`))
     )
-
-    this.keyPairs = keyPairs
   }
 }
 
-export class BuyMembershipWithInsufficienFunds {
-  public async runner(
-    apiWrapper: ApiWrapper,
-    sudo: KeyringPair,
-    aKeyPair: KeyringPair,
-    keyring: Keyring,
-    paidTerms: number
-  ) {
-    // Account creation
-    aKeyPair = keyring.addFromUri(uuid().substring(0, 8))
+export class BuyMembershipWithInsufficienFundsFixture implements Fixture {
+  private apiWrapper: ApiWrapper
+  private sudo: KeyringPair
+  private aKeyPair: KeyringPair
+  private paidTerms: number
+
+  public constructor(apiWrapper: ApiWrapper, sudo: KeyringPair, aKeyPair: KeyringPair, paidTerms: number) {
+    this.apiWrapper = apiWrapper
+    this.sudo = sudo
+    this.aKeyPair = aKeyPair
+    this.paidTerms = paidTerms
+  }
 
+  public async runner(expectFailure: boolean) {
     // Fee estimation and transfer
-    const membershipFee: BN = await apiWrapper.getMembershipFee(paidTerms)
-    const membershipTransactionFee: BN = apiWrapper.estimateBuyMembershipFee(
-      sudo,
-      paidTerms,
+    const membershipFee: BN = await this.apiWrapper.getMembershipFee(this.paidTerms)
+    const membershipTransactionFee: BN = this.apiWrapper.estimateBuyMembershipFee(
+      this.sudo,
+      this.paidTerms,
       'member_name_which_is_longer_than_expected'
     )
-    await apiWrapper.transferBalance(sudo, aKeyPair.address, membershipTransactionFee)
+    await this.apiWrapper.transferBalance(this.sudo, this.aKeyPair.address, membershipTransactionFee)
 
     // Balance assertion
-    await apiWrapper
-      .getBalance(aKeyPair.address)
+    await this.apiWrapper
+      .getBalance(this.aKeyPair.address)
       .then((balance) =>
         assert(
           balance.toBn() < membershipFee.add(membershipTransactionFee),
@@ -83,11 +85,16 @@ export class BuyMembershipWithInsufficienFunds {
       )
 
     // Buying memebership
-    await apiWrapper.buyMembership(aKeyPair, paidTerms, `late_member_${aKeyPair.address.substring(0, 8)}`, true)
+    await this.apiWrapper.buyMembership(
+      this.aKeyPair,
+      this.paidTerms,
+      `late_member_${this.aKeyPair.address.substring(0, 8)}`,
+      true
+    )
 
     // Assertions
-    apiWrapper
-      .getMemberIds(aKeyPair.address)
+    this.apiWrapper
+      .getMemberIds(this.aKeyPair.address)
       .then((membership) => assert(membership.length === 0, 'Account A is a member'))
   }
 }

+ 34 - 9
tests/network-tests/src/iznik/tests/membershipCreationTest.ts

@@ -1,5 +1,4 @@
 import { KeyringPair } from '@polkadot/keyring/types'
-import { membershipTest } from './impl/membershipCreation'
 import { Keyring, WsProvider } from '@polkadot/api'
 import { initConfig } from '../utils/config'
 import { setTestTimeout } from '../utils/setTestTimeout'
@@ -7,25 +6,51 @@ import tap from 'tap'
 import { registerJoystreamTypes } from '@nicaea/types'
 import { ApiWrapper } from '../utils/apiWrapper'
 import { closeApi } from './impl/closeApi'
+import { BuyMembershipHappyCaseFixture, BuyMembershipWithInsufficienFundsFixture } from './impl/membershipModule'
+import { Utils } from '../utils/utils'
 
 tap.mocha.describe('Membership creation scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: KeyringPair[] = []
-  let aKeyPair: KeyringPair
-  const keyring = new Keyring({ type: 'sr25519' })
-  const N: number = +process.env.MEMBERSHIP_CREATION_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 durationInBlocks = 7
-
+  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 nKeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  let aKeyPair: KeyringPair[] = Utils.createKeyPairs(keyring, 1)
+  const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!
+
+  const durationInBlocks = 7
+
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Buy membeship is accepted with sufficient funds', async () => happyCaseFixture.runner(false))
+
+  const insufficientFundsFixture: BuyMembershipWithInsufficienFundsFixture = new BuyMembershipWithInsufficienFundsFixture(
+    apiWrapper,
+    sudo,
+    aKeyPair[0],
+    paidTerms
+  )
+  tap.test('Account A can not buy the membership with insufficient funds', async () =>
+    insufficientFundsFixture.runner(false)
+  )
+
+  const buyMembershipAfterAccountTopUp = new BuyMembershipHappyCaseFixture(apiWrapper, sudo, aKeyPair, paidTerms)
+  tap.test('Account A was able to buy the membership with sufficient funds', async () =>
+    buyMembershipAfterAccountTopUp.runner(false)
+  )
+
   closeApi(apiWrapper)
 })

+ 25 - 4
tests/network-tests/src/iznik/tests/proposals/manageLeaderRole.ts

@@ -29,6 +29,8 @@ import {
   expectLeaderStakeDecreased,
   expectLeaderSlashed,
 } from '../workingGroup/impl/workingGroupModule'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { ElectCouncilFixture } from '../impl/councilElectionModule'
 
 tap.mocha.describe('Set lead proposal scenario', async () => {
   initConfig()
@@ -61,10 +63,29 @@ tap.mocha.describe('Set lead proposal scenario', async () => {
   const sudo: KeyringPair = keyring.addFromUri(sudoUri)
 
   setTestTimeout(apiWrapper, durationInBlocks)
-  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)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture()
+  tap.test('Buy membeship is accepted with sufficient funds', async () =>
+    happyCaseFixture.runner(apiWrapper, sudo, m1KeyPairs, keyring, N, paidTerms)
+  )
+
+  tap.test('Buy membeship is accepted with sufficient funds', async () =>
+    happyCaseFixture.runner(apiWrapper, sudo, m2KeyPairs, keyring, N, paidTerms)
+  )
+
+  tap.test('Buy membeship is accepted with sufficient funds', async () =>
+    happyCaseFixture.runner(apiWrapper, sudo, leadKeyPair, keyring, 1, paidTerms)
+  )
+
+  const electCouncilFixture: ElectCouncilFixture = new ElectCouncilFixture()
+  tap.test('Elect council', async () =>
+    electCouncilFixture.runner(apiWrapper, m1KeyPairs, m2KeyPairs, K, sudo, greaterStake, lesserStake)
+  )
+
+  // 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

+ 27 - 12
tests/network-tests/src/iznik/tests/workingGroup/atLeastValueBugTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -16,19 +15,25 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.LONG_REWARD_INTERVAL!)
@@ -38,13 +43,23 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   const durationInBlocks = 48
   const openingActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 27 - 12
tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsLeadTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -21,19 +20,25 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap = require('tap')
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Manage worker as worker scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.LONG_REWARD_INTERVAL!)
@@ -43,13 +48,23 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
   const durationInBlocks = 60
   const openingActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 27 - 12
tests/network-tests/src/iznik/tests/workingGroup/manageWorkerAsWorkerTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -21,19 +20,25 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap = require('tap')
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Manage worker as worker scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.LONG_REWARD_INTERVAL!)
@@ -43,13 +48,23 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
   const durationInBlocks = 38
   const openingActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 27 - 12
tests/network-tests/src/iznik/tests/workingGroup/workerApplicationHappyCaseTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -19,19 +18,25 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.LONG_REWARD_INTERVAL!)
@@ -41,13 +46,23 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   const durationInBlocks = 48
   const openingActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 28 - 13
tests/network-tests/src/iznik/tests/workingGroup/workerApplicationRejectionCaseTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest, createKeyPairs } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -18,19 +17,26 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: KeyringPair[] = Utils.createKeyPairs(keyring, N)
+  const leadKeyPair: KeyringPair[] = Utils.createKeyPairs(keyring, 1)
+  const nonMemberKeyPairs = 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.LONG_REWARD_INTERVAL!)
@@ -41,14 +47,23 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   const openingActivationDelay: BN = new BN(100)
   const leadOpeningActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-  const nonMemberKeyPairs = createKeyPairs(keyring, N)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 27 - 12
tests/network-tests/src/iznik/tests/workingGroup/workerPayout.ts → tests/network-tests/src/iznik/tests/workingGroup/workerPayoutTest.ts

@@ -5,7 +5,6 @@ import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper'
 import { WsProvider, Keyring } from '@polkadot/api'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { setTestTimeout } from '../../utils/setTestTimeout'
-import { membershipTest } from '../impl/membershipCreation'
 import {
   addWorkerOpening,
   applyForOpening,
@@ -20,19 +19,25 @@ import {
 } from './impl/workingGroupModule'
 import BN from 'bn.js'
 import tap from 'tap'
+import { BuyMembershipHappyCaseFixture } from '../impl/membershipModule'
+import { Utils } from '../../utils/utils'
 
 tap.mocha.describe('Worker application happy case scenario', async () => {
   initConfig()
   registerJoystreamTypes()
 
-  const nKeyPairs: 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.WORKING_GROUP_N!
+  const nKeyPairs: 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 applicationStake: BN = new BN(process.env.WORKING_GROUP_APPLICATION_STAKE!)
   const roleStake: BN = new BN(process.env.WORKING_GROUP_ROLE_STAKE!)
   const firstRewardInterval: BN = new BN(process.env.SHORT_FIRST_REWARD_INTERVAL!)
@@ -43,13 +48,23 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
   const durationInBlocks = 48
   const openingActivationDelay: BN = new BN(0)
 
-  const provider = new WsProvider(nodeUrl)
-  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider)
-  const sudo: KeyringPair = keyring.addFromUri(sudoUri)
-
   setTestTimeout(apiWrapper, durationInBlocks)
-  membershipTest(apiWrapper, nKeyPairs, keyring, N, paidTerms, sudoUri)
-  membershipTest(apiWrapper, leadKeyPair, keyring, 1, paidTerms, sudoUri)
+
+  const happyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    nKeyPairs,
+    paidTerms
+  )
+  tap.test('Creating a set of members', async () => happyCaseFixture.runner(false))
+
+  const leaderHappyCaseFixture: BuyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(
+    apiWrapper,
+    sudo,
+    leadKeyPair,
+    paidTerms
+  )
+  tap.test('Buying membership for leader account', async () => leaderHappyCaseFixture.runner(false))
 
   let leadOpenignId: BN
   tap.test(

+ 3 - 0
tests/network-tests/src/iznik/utils/fixture.ts

@@ -0,0 +1,3 @@
+export interface Fixture {
+  runner(expectFailure: boolean): Promise<void>
+}

+ 11 - 1
tests/network-tests/src/iznik/utils/utils.ts

@@ -3,8 +3,10 @@ import { compactToU8a, stringToU8a } from '@polkadot/util'
 import { blake2AsHex } from '@polkadot/util-crypto'
 import BN from 'bn.js'
 import fs from 'fs'
-import { decodeAddress } from '@polkadot/keyring'
+import Keyring, { decodeAddress } from '@polkadot/keyring'
 import { Seat } from '@nicaea/types/council'
+import { KeyringPair } from '@polkadot/keyring/types'
+import { v4 as uuid } from 'uuid'
 
 export class Utils {
   private static LENGTH_ADDRESS = 32 + 1 // publicKey + prefix
@@ -50,4 +52,12 @@ export class Utils {
   public static camelToSnakeCase(key: string): string {
     return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
   }
+
+  public static 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
+  }
 }