Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ extern crate parity_codec_derive;

pub mod governance;
use governance::{election, council, proposals};
pub mod storage;
use storage::{types};
mod memo;
mod traits;

use rstd::prelude::*;
#[cfg(feature = "std")]
use primitives::bytes;
use primitives::{Ed25519AuthorityId, OpaqueMetadata};
use runtime_primitives::{
ApplyResult, transaction_validity::TransactionValidity, Ed25519Signature, generic,
traits::{self, Convert, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str
traits::{self as runtime_traits, Convert, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str
};
use client::{
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
Expand Down Expand Up @@ -67,7 +70,7 @@ pub mod opaque {
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl traits::Extrinsic for UncheckedExtrinsic {
impl runtime_traits::Extrinsic for UncheckedExtrinsic {
fn is_signed(&self) -> Option<bool> {
None
}
Expand Down Expand Up @@ -224,6 +227,11 @@ impl memo::Trait for Runtime {
type Event = Event;
}

impl storage::types::Trait for Runtime {
type Event = Event;
type DataObjectTypeID = u64;
}

construct_runtime!(
pub enum Runtime with Log(InternalLog: DigestItem<Hash, Ed25519AuthorityId>) where
Block = Block,
Expand All @@ -244,6 +252,7 @@ construct_runtime!(
CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
Council: council::{Module, Call, Storage, Event<T>, Config<T>},
Memo: memo::{Module, Call, Storage, Event<T>},
DataObjectType: types::{Module, Call, Storage, Event<T>, Config<T>},
Comment thread
This conversation was marked as resolved.
Outdated
}
);

Expand Down
89 changes: 89 additions & 0 deletions src/storage/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#![cfg(test)]

use rstd::prelude::*;
pub use super::{types};
pub use system;

pub use primitives::{H256, Blake2Hasher};
pub use runtime_primitives::{
BuildStorage,
traits::{BlakeTwo256, OnFinalise, IdentityLookup},
testing::{Digest, DigestItem, Header, UintAuthorityId}
};

use srml_support::{impl_outer_origin, impl_outer_event};

impl_outer_origin! {
pub enum Origin for Test {}
}

impl_outer_event! {
pub enum MetaEvent for Test
{
types<T>,
}
}

// For testing the module, we construct most of a mock runtime. This means
// first constructing a configuration type (`Test`) which `impl`s each of the
// configuration traits of modules we want to use.
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test
{
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
type Event = MetaEvent;
type Log = DigestItem;
type Lookup = IdentityLookup<u64>;
}
impl types::Trait for Test
{
type Event = MetaEvent;
type DataObjectTypeID = u64;
}

pub struct ExtBuilder
{
first_data_object_type_id: u64,
}

impl Default for ExtBuilder
{
fn default() -> Self
{
Self {
first_data_object_type_id: 1,
}
}
}

impl ExtBuilder
{
pub fn first_data_object_type_id(mut self, first_data_object_type_id: u64) -> Self
{
self.first_data_object_type_id = first_data_object_type_id;
self
}
pub fn build(self) -> runtime_io::TestExternalities<Blake2Hasher>
{
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;

t.extend(types::GenesisConfig::<Test>{
first_data_object_type_id: self.first_data_object_type_id,
}.build_storage().unwrap().0);

t.into()
}
}


pub type System = system::Module<Test>;
pub type Types = types::Module<Test>;
pub type TestDataObjectType = types::DataObjectType<Test>;
6 changes: 6 additions & 0 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod types;

mod mock;
mod tests;
162 changes: 162 additions & 0 deletions src/storage/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#![cfg(test)]

use super::*;
use super::mock::*;

use runtime_io::with_externalities;
use srml_support::*;
use system::{self, Phase, EventRecord};

#[test]
fn initial_state()
{
const DEFAULT_FIRST_ID: u64 = 1000;

with_externalities(&mut ExtBuilder::default()
.first_data_object_type_id(DEFAULT_FIRST_ID).build(), ||
{
assert_eq!(Types::first_data_object_type_id(), DEFAULT_FIRST_ID);
});
}

#[test]
fn fail_register_without_root()
{
const DEFAULT_FIRST_ID: u64 = 1000;

with_externalities(&mut ExtBuilder::default()
.first_data_object_type_id(DEFAULT_FIRST_ID).build(), ||
{
let data: TestDataObjectType = TestDataObjectType {
id: None,
description: "foo".as_bytes().to_vec(),
active: false,
};
let res = Types::register_data_object_type(Origin::signed(1), data);
assert!(res.is_err());
});
}

#[test]
fn succeed_register_as_root()
{
const DEFAULT_FIRST_ID: u64 = 1000;

with_externalities(&mut ExtBuilder::default()
.first_data_object_type_id(DEFAULT_FIRST_ID).build(), ||
{
let data: TestDataObjectType = TestDataObjectType {
id: None,
description: "foo".as_bytes().to_vec(),
active: false,
};
let res = Types::register_data_object_type(Origin::ROOT, data);
assert!(res.is_ok());
});
}

#[test]
fn update_existing()
{
const DEFAULT_FIRST_ID: u64 = 1000;

with_externalities(&mut ExtBuilder::default()
.first_data_object_type_id(DEFAULT_FIRST_ID).build(), ||
{
// First register a type
let data: TestDataObjectType = TestDataObjectType {
id: None,
description: "foo".as_bytes().to_vec(),
active: false,
};
let id_res = Types::register_data_object_type(Origin::ROOT, data);
assert!(id_res.is_ok());
assert_eq!(*System::events().last().unwrap(),
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)),
}
);


// Now update it with new data - we need the ID to be the same as in
// returned by the previous call. First, though, try and fail without
let updated1: TestDataObjectType = TestDataObjectType {
id: None,
description: "bar".as_bytes().to_vec(),
active: false,
};
let res = Types::update_data_object_type(Origin::ROOT, updated1);
assert!(res.is_err());

// Now try with a bad ID
let updated2: TestDataObjectType = TestDataObjectType {
id: Some(DEFAULT_FIRST_ID + 1),
description: "bar".as_bytes().to_vec(),
active: false,
};
let res = Types::update_data_object_type(Origin::ROOT, updated2);
assert!(res.is_err());

// Finally with an existing ID, it should work.
let updated3: TestDataObjectType = TestDataObjectType {
id: Some(DEFAULT_FIRST_ID),
description: "bar".as_bytes().to_vec(),
active: false,
};
let res = Types::update_data_object_type(Origin::ROOT, updated3);
assert!(res.is_ok());
assert_eq!(*System::events().last().unwrap(),
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)),
}
);
});
}


#[test]
fn activate_existing()
{
const DEFAULT_FIRST_ID: u64 = 1000;

with_externalities(&mut ExtBuilder::default()
.first_data_object_type_id(DEFAULT_FIRST_ID).build(), ||
{
// First register a type
let data: TestDataObjectType = TestDataObjectType {
id: None,
description: "foo".as_bytes().to_vec(),
active: false,
};
let id_res = Types::register_data_object_type(Origin::ROOT, data);
assert!(id_res.is_ok());
assert_eq!(*System::events().last().unwrap(),
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)),
}
);

// Retrieve, and ensure it's not active.
let data = Types::data_object_type(DEFAULT_FIRST_ID);
assert!(data.is_some());
assert!(!data.unwrap().active);

// Now activate the data object type
let res = Types::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true);
assert!(res.is_ok());
assert_eq!(*System::events().last().unwrap(),
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)),
}
);

// Ensure that the item is actually activated.
let data = Types::data_object_type(DEFAULT_FIRST_ID);
assert!(data.is_some());
assert!(data.unwrap().active);
});
}
Loading