use frame_support::storage::StorageMap; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_support::{impl_outer_event, impl_outer_origin, parameter_types}; use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, Perbill, }; use std::marker::PhantomData; use system; use crate::{BalanceOf, Module, NegativeImbalance, Trait}; use common::constraints::InputValidationLengthConstraint; impl_outer_origin! { pub enum Origin for Test {} } mod working_group { pub use super::TestWorkingGroupInstance; pub use crate::Event; } mod membership_mod { pub use membership::Event; } impl_outer_event! { pub enum TestEvent for Test { balances, working_group TestWorkingGroupInstance , membership_mod, system, } } parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MinimumPeriod: u64 = 5; pub const StakePoolId: [u8; 8] = *b"joystake"; pub const ExistentialDeposit: u32 = 0; } // Workaround for https://github.com/rust-lang/rust/issues/26925 - remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; impl system::Trait for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); type Index = u64; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); type MaximumExtrinsicWeight = (); type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); type AccountData = balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); } impl hiring::Trait for Test { type OpeningId = u64; type ApplicationId = u64; type ApplicationDeactivatedHandler = (); type StakeHandlerProvider = hiring::Module; } impl minting::Trait for Test { type Currency = Balances; type MintId = u64; } impl stake::Trait for Test { type Currency = Balances; type StakePoolId = StakePoolId; type StakingEventsHandler = StakingEventsHandler; type StakeId = u64; type SlashId = u64; } impl membership::Trait for Test { type Event = TestEvent; type MemberId = u64; type PaidTermId = u64; type SubscriptionId = u64; type ActorId = u64; } impl common::currency::GovernanceCurrency for Test { type Currency = Balances; } impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; } impl balances::Trait for Test { type Balance = u64; type DustRemoval = (); type Event = TestEvent; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; } impl recurringrewards::Trait for Test { type PayoutStatusHandler = (); type RecipientId = u64; type RewardRelationshipId = u64; } pub type Balances = balances::Module; pub type System = system::Module; parameter_types! { pub const MaxWorkerNumberLimit: u32 = 3; } impl Trait for Test { type Event = TestEvent; type MaxWorkerNumberLimit = MaxWorkerNumberLimit; } pub type Membership = membership::Module; pub type TestWorkingGroupInstance = crate::Instance1; pub type TestWorkingGroup = Module; pub(crate) const WORKING_GROUP_MINT_CAPACITY: u64 = 40000; pub(crate) const WORKING_GROUP_CONSTRAINT_MIN: u16 = 1; pub(crate) const WORKING_GROUP_CONSTRAINT_DIFF: u16 = 40; pub fn build_test_externalities() -> sp_io::TestExternalities { let mut t = system::GenesisConfig::default() .build_storage::() .unwrap(); crate::GenesisConfig:: { phantom: Default::default(), working_group_mint_capacity: WORKING_GROUP_MINT_CAPACITY, opening_human_readable_text_constraint: InputValidationLengthConstraint::new( WORKING_GROUP_CONSTRAINT_MIN, WORKING_GROUP_CONSTRAINT_DIFF, ), worker_application_human_readable_text_constraint: InputValidationLengthConstraint::new( WORKING_GROUP_CONSTRAINT_MIN, WORKING_GROUP_CONSTRAINT_DIFF, ), worker_exit_rationale_text_constraint: InputValidationLengthConstraint::new( WORKING_GROUP_CONSTRAINT_MIN, WORKING_GROUP_CONSTRAINT_DIFF, ), worker_storage_size_constraint: crate::default_storage_size_constraint(), } .assimilate_storage(&mut t) .unwrap(); t.into() } pub struct StakingEventsHandler { pub marker: PhantomData, } impl> stake::StakingEventsHandler for StakingEventsHandler { /// Unstake remaining sum back to the source_account_id fn unstaked( stake_id: &::StakeId, _unstaked_amount: BalanceOf, remaining_imbalance: NegativeImbalance, ) -> NegativeImbalance { // Stake not related to a staked role managed by the hiring module. if !hiring::ApplicationIdByStakingId::::contains_key(*stake_id) { return remaining_imbalance; } let hiring_application_id = hiring::ApplicationIdByStakingId::::get(*stake_id); if crate::MemberIdByHiringApplicationId::::contains_key( hiring_application_id, ) { return >::refund_working_group_stake( *stake_id, remaining_imbalance, ); } remaining_imbalance } /// Empty handler for slashing fn slashed( _: &::StakeId, _: Option<::SlashId>, _: BalanceOf, _: BalanceOf, remaining_imbalance: NegativeImbalance, ) -> NegativeImbalance { remaining_imbalance } } // Recommendation from Parity on testing on_finalize // https://substrate.dev/docs/en/next/development/module/tests pub fn run_to_block(n: u64) { while System::block_number() < n { >::on_finalize(System::block_number()); >::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); >::on_initialize(System::block_number()); >::on_initialize(System::block_number()); } }