|
@@ -0,0 +1,165 @@
|
|
|
+#![cfg(test)]
|
|
|
+
|
|
|
+/////////////////// Configuration //////////////////////////////////////////////
|
|
|
+use crate::{Error, Event, Module, CouncilStage, GenesisConfig, Trait};
|
|
|
+
|
|
|
+use primitives::H256;
|
|
|
+use runtime_io;
|
|
|
+use sr_primitives::{
|
|
|
+ testing::Header,
|
|
|
+ traits::{BlakeTwo256, IdentityLookup},
|
|
|
+ Perbill,
|
|
|
+};
|
|
|
+use srml_support::{impl_outer_event, impl_outer_origin, parameter_types, StorageValue, StorageMap};
|
|
|
+use std::marker::PhantomData;
|
|
|
+use system::RawOrigin;
|
|
|
+use codec::{Encode};
|
|
|
+
|
|
|
+pub const USER_ADMIN: u64 = 1;
|
|
|
+pub const USER_REGULAR: u64 = 2;
|
|
|
+
|
|
|
+/////////////////// Runtime and Instances //////////////////////////////////////
|
|
|
+// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
|
|
|
+#[derive(Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct Runtime;
|
|
|
+
|
|
|
+// module instances
|
|
|
+
|
|
|
+#[derive(Clone, PartialEq, Eq, Debug)]
|
|
|
+pub struct Instance0;
|
|
|
+
|
|
|
+parameter_types! {
|
|
|
+ pub const MaxReferendumOptions: u64 = 10;
|
|
|
+ pub const VoteStageDuration: u64 = 5;
|
|
|
+ pub const RevealStageDuration: u64 = 5;
|
|
|
+ pub const MinimumStake: u64 = 10000;
|
|
|
+}
|
|
|
+
|
|
|
+impl Trait for Runtime {
|
|
|
+ type Event = TestEvent;
|
|
|
+
|
|
|
+ type Tmp = u64;
|
|
|
+
|
|
|
+ fn is_super_user(account_id: &<Self as system::Trait>::AccountId) -> bool {
|
|
|
+ *account_id == USER_ADMIN
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////// Module implementation //////////////////////////////////////
|
|
|
+
|
|
|
+impl_outer_origin! {
|
|
|
+ pub enum Origin for Runtime {}
|
|
|
+}
|
|
|
+
|
|
|
+mod event_mod {
|
|
|
+ pub use crate::Event;
|
|
|
+}
|
|
|
+
|
|
|
+impl_outer_event! {
|
|
|
+ pub enum TestEvent for Runtime {
|
|
|
+ event_mod<T>,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+impl system::Trait for Runtime {
|
|
|
+ type Origin = Origin;
|
|
|
+ type Index = u64;
|
|
|
+ type BlockNumber = u64;
|
|
|
+ type Call = ();
|
|
|
+ type Hash = H256;
|
|
|
+ type Hashing = BlakeTwo256;
|
|
|
+ type AccountId = u64;
|
|
|
+ type Lookup = IdentityLookup<Self::AccountId>;
|
|
|
+ type Header = Header;
|
|
|
+ type Event = TestEvent;
|
|
|
+ type BlockHashCount = BlockHashCount;
|
|
|
+ type MaximumBlockWeight = MaximumBlockWeight;
|
|
|
+ type MaximumBlockLength = MaximumBlockLength;
|
|
|
+ type AvailableBlockRatio = AvailableBlockRatio;
|
|
|
+ type Version = ();
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////// Data structures ////////////////////////////////////////////
|
|
|
+
|
|
|
+#[allow(dead_code)]
|
|
|
+#[derive(Clone)]
|
|
|
+pub enum OriginType<AccountId> {
|
|
|
+ Signed(AccountId),
|
|
|
+ //Inherent, <== did not find how to make such an origin yet
|
|
|
+ Root,
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////// Utility mocks //////////////////////////////////////////////
|
|
|
+
|
|
|
+pub fn default_genesis_config() -> GenesisConfig<Runtime> {
|
|
|
+ GenesisConfig::<Runtime> {
|
|
|
+ stage: (CouncilStage::default(), 0),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub fn build_test_externalities(
|
|
|
+ config: GenesisConfig<Runtime>,
|
|
|
+) -> runtime_io::TestExternalities {
|
|
|
+ let mut t = system::GenesisConfig::default()
|
|
|
+ .build_storage::<Runtime>()
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ config.assimilate_storage(&mut t).unwrap();
|
|
|
+
|
|
|
+ t.into()
|
|
|
+}
|
|
|
+
|
|
|
+pub struct InstanceMockUtils<T: Trait> {
|
|
|
+ _dummy: PhantomData<T>, // 0-sized data meant only to bound generic parameters
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Trait> InstanceMockUtils<T> {
|
|
|
+
|
|
|
+ pub fn mock_origin(origin: OriginType<T::AccountId>) -> T::Origin {
|
|
|
+ match origin {
|
|
|
+ OriginType::Signed(account_id) => T::Origin::from(RawOrigin::Signed(account_id)),
|
|
|
+ _ => panic!("not implemented"),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn origin_access<F: Fn(OriginType<T::AccountId>) -> ()>(
|
|
|
+ origin_account_id: T::AccountId,
|
|
|
+ f: F,
|
|
|
+ ) {
|
|
|
+ let config = default_genesis_config();
|
|
|
+
|
|
|
+ build_test_externalities(config).execute_with(|| {
|
|
|
+ let origin = OriginType::Signed(origin_account_id);
|
|
|
+
|
|
|
+ f(origin)
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////// Mocks of Module's actions //////////////////////////////////
|
|
|
+
|
|
|
+pub struct InstanceMocks<T: Trait> {
|
|
|
+ _dummy: PhantomData<T>, // 0-sized data meant only to bound generic parameters
|
|
|
+}
|
|
|
+
|
|
|
+impl<T: Trait> InstanceMocks<T> {
|
|
|
+
|
|
|
+ pub fn start_election_cycle(
|
|
|
+ origin: OriginType<T::AccountId>,
|
|
|
+ expected_result: Result<(), Error>,
|
|
|
+ ) -> () {
|
|
|
+ // check method returns expected result
|
|
|
+ assert_eq!(
|
|
|
+ Module::<T>::start_election_cycle(InstanceMockUtils::<T>::mock_origin(origin),),
|
|
|
+ expected_result,
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|