Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ edition = '2018'
name = 'joystream-node-runtime'
# Follow convention: https://github.com/Joystream/substrate-runtime-joystream/issues/1
# {Authoring}.{Spec}.{Impl} of the RuntimeVersion
version = '6.0.0'
version = '6.1.0'

[features]
default = ['std']
Expand Down
31 changes: 30 additions & 1 deletion src/content_working_group/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,10 @@ pub static MSG_APPLY_ON_CURATOR_OPENING_UNSIGNED_ORIGIN: &str = "Unsigned origin
pub static MSG_APPLY_ON_CURATOR_OPENING_MEMBER_ID_INVALID: &str = "Member id is invalid";
pub static MSG_APPLY_ON_CURATOR_OPENING_SIGNER_NOT_CONTROLLER_ACCOUNT: &str =
"Signer does not match controller account";
static MSG_ORIGIN_IS_NIETHER_MEMBER_CONTROLLER_OR_ROOT: &str =
pub static MSG_ORIGIN_IS_NIETHER_MEMBER_CONTROLLER_OR_ROOT: &str =
"Origin must be controller or root account of member";
pub static MSG_MEMBER_HAS_ACTIVE_APPLICATION_ON_OPENING: &str =
"Member already has an active application on the opening";

/// The exit stage of a lead involvement in the working group.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
Expand Down Expand Up @@ -1726,6 +1728,12 @@ decl_module! {
hiring::Module::<T>::ensure_can_add_application(curator_opening.opening_id, opt_role_stake_balance, opt_application_stake_balance)
)?;

// Ensure member does not have an active application to this opening
Self::ensure_member_has_no_active_application_on_opening(
curator_opening.curator_applications,
member_id
)?;

//
// == MUTATION SAFE ==
//
Expand Down Expand Up @@ -2055,6 +2063,27 @@ impl<T: Trait> versioned_store_permissions::CredentialChecker<T> for Module<T> {
}

impl<T: Trait> Module<T> {
fn ensure_member_has_no_active_application_on_opening(
curator_applications: CuratorApplicationIdSet<T>,
member_id: T::MemberId,
) -> Result<(), &'static str> {
for curator_application_id in curator_applications {
let curator_application = CuratorApplicationById::<T>::get(curator_application_id);
// Look for application by the member for the opening
if curator_application.member_id != member_id {
continue;
}
// Get application details
let application = <hiring::ApplicationById<T>>::get(curator_application.application_id);
// Return error if application is in active stage
if application.stage == hiring::ApplicationStage::Active {
return Err(MSG_MEMBER_HAS_ACTIVE_APPLICATION_ON_OPENING);
}
}
// Member does not have any active applications to the opening
Ok(())
}

fn ensure_can_register_role_on_member(
member_id: &T::MemberId,
role: role_types::Role,
Expand Down
74 changes: 73 additions & 1 deletion src/content_working_group/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use hiring;
use rstd::collections::btree_map::BTreeMap;
use rstd::collections::btree_set::BTreeSet;
use runtime_primitives::traits::One;
use srml_support::{StorageLinkedMap, StorageValue};
use srml_support::{assert_err, assert_ok, StorageLinkedMap, StorageValue};

/// DIRTY IMPORT BECAUSE
/// InputValidationLengthConstraint has not been factored out yet!!!
Expand Down Expand Up @@ -747,6 +747,78 @@ fn apply_on_curator_opening_success() {
});
}

#[test]
fn multiple_applications_by_same_member_to_opening_fails() {
TestExternalitiesBuilder::<Test>::default()
.build()
.execute_with(|| {
/*
* Setup
*/

let normal_opening_constructed = setup_normal_accepting_opening();

// Add curator membership

let curator_applicant_root_and_controller_account = 72618;

let curator_applicant_member_id = add_member(
curator_applicant_root_and_controller_account,
to_vec("IwillTrytoapplyhere"),
);

let curator_applicant_role_account = 8881111;

let role_stake_balance = get_baseline_opening_policy()
.role_staking_policy
.unwrap()
.amount;
let application_stake_balance = get_baseline_opening_policy()
.application_staking_policy
.unwrap()
.amount;
let total_balance = role_stake_balance + application_stake_balance;

let source_account = curator_applicant_root_and_controller_account;

// Credit staking source account with enough funds for two applications,
// because we don't want our second application to fail for lack of funds
let _ = balances::Module::<Test>::deposit_creating(&source_account, total_balance * 2);

let human_readable_text = generate_valid_length_buffer(&ChannelHandleConstraint::get());

/*
* Test
*/

// First application should work
assert_ok!(ContentWorkingGroup::apply_on_curator_opening(
Origin::signed(curator_applicant_root_and_controller_account),
curator_applicant_member_id,
normal_opening_constructed.curator_opening_id,
curator_applicant_role_account,
Some(role_stake_balance),
Some(application_stake_balance),
human_readable_text.clone()
));

// Second application should fail since
// first application is still active
assert_err!(
ContentWorkingGroup::apply_on_curator_opening(
Origin::signed(curator_applicant_root_and_controller_account),
curator_applicant_member_id,
normal_opening_constructed.curator_opening_id,
curator_applicant_role_account,
Some(role_stake_balance),
Some(application_stake_balance),
human_readable_text
),
MSG_MEMBER_HAS_ACTIVE_APPLICATION_ON_OPENING
);
});
}

struct UpdateCuratorRoleAccountFixture {
pub origin: Origin,
pub member_id: <Test as members::Trait>::MemberId,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("joystream-node"),
impl_name: create_runtime_str!("joystream-node"),
authoring_version: 6,
spec_version: 0,
spec_version: 1,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
};
Expand Down