From a5e0c8d3203bff58be7623413e102376526a5efb Mon Sep 17 00:00:00 2001 From: Amiya Behera Date: Sun, 11 Aug 2024 14:29:34 +0530 Subject: [PATCH] department funding tests --- .../department-funding/src/extras.rs | 26 ++++ custom-pallets/department-funding/src/lib.rs | 4 +- custom-pallets/department-funding/src/mock.rs | 1 + .../department-funding/src/tests.rs | 115 +++++++++++++++++- 4 files changed, 142 insertions(+), 4 deletions(-) diff --git a/custom-pallets/department-funding/src/extras.rs b/custom-pallets/department-funding/src/extras.rs index a81b7f6..df1547c 100644 --- a/custom-pallets/department-funding/src/extras.rs +++ b/custom-pallets/department-funding/src/extras.rs @@ -48,6 +48,32 @@ impl Pallet { } } + /// Ensures that a department can stake based on its current funding status and the time elapsed since the last status change. + /// + /// # Parameters + /// - `department_id`: The identifier of the department for which staking is being checked. + /// + /// # Returns + /// - `Ok(DepartmentFundingStatus)`: If the department can proceed with staking. The returned value contains the current block number and sets the status to `Processing`. + /// - `Err(DispatchError)`: If the department cannot stake due to one of the following reasons: + /// - **`FundingStatus::Processing`**: The department is already in the `Processing` state, meaning that a funding operation is currently ongoing. + /// - **`FundingStatus::Failed`**: The department's last funding attempt failed, and the required waiting period (defined by `TIME_FOR_STAKING_FUNDING_STATUS_FAILED`) has not yet passed. + /// - **`FundingStatus::Success`**: The department's last funding attempt succeeded, and the required waiting period (defined by `TIME_FOR_STAKING_FUNDING_STATUS_PASSED`) has not yet passed. + /// - **`ConditionDontMatch`**: If the department's funding status doesn't match any known conditions. + /// + /// # Logic + /// 1. **Current Block Time**: The function first retrieves the current block number to timestamp the new funding status if applicable. + /// 2. **Existing Status Check**: It checks if there is an existing funding status for the given department: + /// - **Processing**: If the status is `Processing`, staking cannot proceed, and an error is returned. + /// - **Failed**: If the status is `Failed`, it checks if the required waiting period has passed since the failure. If the time has passed, staking can proceed; otherwise, an error is returned. + /// - **Success**: If the status is `Success`, it similarly checks if the required waiting period has passed. If it has, staking can proceed; otherwise, an error is returned. + /// - **Other Conditions**: If the status does not match any of the above, an error is returned. + /// 3. **No Existing Status**: If there is no existing status, staking is allowed, and the department's status is set to `Processing`. + /// + /// # Errors + /// - **`FundingStatusProcessing`**: Returned if the department is already in the `Processing` state. + /// - **`ReapplicationTimeNotReached`**: Returned if the department is trying to reapply before the required waiting period has passed. + /// - **`ConditionDontMatch`**: Returned if the department's funding status doesn't match any known conditions. pub fn ensure_can_stake_using_status( department_id: DepartmentId, ) -> Result, FundingStatus>, DispatchError> { diff --git a/custom-pallets/department-funding/src/lib.rs b/custom-pallets/department-funding/src/lib.rs index 8a27f93..70a3fb0 100644 --- a/custom-pallets/department-funding/src/lib.rs +++ b/custom-pallets/department-funding/src/lib.rs @@ -125,7 +125,7 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn get_department_required_funds)] + #[pallet::getter(fn department_required_funds)] pub type DepartmentRequiredFunds = StorageMap<_, Blake2_128Concat, DepartmentRequiredFundId, DepartmentRequiredFund>; @@ -261,7 +261,7 @@ pub mod pallet { origin: OriginFor, department_required_fund_id: DepartmentRequiredFundId, ) -> DispatchResult { - let who = ensure_signed(origin)?; + let _who = ensure_signed(origin)?; Self::ensure_validation_to_do(department_required_fund_id)?; let department_id = Self::get_department_id_from_department_required_fund_id( department_required_fund_id, diff --git a/custom-pallets/department-funding/src/mock.rs b/custom-pallets/department-funding/src/mock.rs index c2fb919..f704afd 100644 --- a/custom-pallets/department-funding/src/mock.rs +++ b/custom-pallets/department-funding/src/mock.rs @@ -23,6 +23,7 @@ frame_support::construct_runtime!( SchellingGameShared: pallet_schelling_game_shared, SortitionSumGame: pallet_sortition_sum_game, Departments: pallet_departments, + Timestamp: pallet_timestamp, } ); #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] diff --git a/custom-pallets/department-funding/src/tests.rs b/custom-pallets/department-funding/src/tests.rs index b44278c..400b369 100644 --- a/custom-pallets/department-funding/src/tests.rs +++ b/custom-pallets/department-funding/src/tests.rs @@ -1,18 +1,129 @@ +use crate::types::TippingName; use crate::{mock::*, Error, Event}; use frame_support::{assert_noop, assert_ok}; +use pallet_support::Content; #[test] fn it_works_for_default_value() { new_test_ext().execute_with(|| { // Go past genesis block so events get deposited System::set_block_number(1); + + let account_id = 1; + let department_id = 1; + let tipping_name = TippingName::SmallTipper; + let funding_needed = 10_000u64.into(); // Dispatch a signed extrinsic. + let department_account_id = 5; + let content_department: Content = Content::IPFS( + "bafkreiaiq24be2iioasr6ftyaum3icmj7amtjkom2jeokov5k5ojwzhvqy" + .as_bytes() + .to_vec(), + ); + assert_ok!(Departments::create_department( + RuntimeOrigin::signed(department_account_id), + content_department.clone() + )); + + let content: Content = Content::IPFS( + "bafkreiaiq24be2iioasr6ftyaum3icmj7amtjkom2jeokov5k5ojwzhvqy" + .as_bytes() + .to_vec(), + ); + + assert_ok!(DepartmentFunding::create_department_required_fund( + RuntimeOrigin::signed(account_id), + department_id, + content.clone(), + tipping_name, + funding_needed + )); + + // Check that the department fund was stored correctly + let department_fund_id = DepartmentFunding::next_department_required_fund_id() - 1; + let stored_fund = DepartmentFunding::department_required_funds(department_fund_id).unwrap(); + + assert_eq!(stored_fund.department_id, department_id); + assert_eq!(stored_fund.content, content); + assert_eq!(stored_fund.tipping_name, tipping_name); + assert_eq!(stored_fund.funding_needed, funding_needed); + assert_eq!(stored_fund.creator, account_id); + + // Verify that the correct event was emitted + System::assert_last_event( + Event::DepartmentFundCreated { + account: account_id, + department_required_fund_id: department_fund_id, + } + .into(), + ); }); } #[test] -fn correct_error_for_none_value() { +fn create_department_required_fund_fails_if_funding_more_than_tipping_value() { new_test_ext().execute_with(|| { - // Ensure the expected error is thrown when no value is present. + System::set_block_number(1); + let department_account_id = 5; + let content_department: Content = Content::IPFS( + "bafkreiaiq24be2iioasr6ftyaum3icmj7amtjkom2jeokov5k5ojwzhvqy" + .as_bytes() + .to_vec(), + ); + assert_ok!(Departments::create_department( + RuntimeOrigin::signed(department_account_id), + content_department.clone() + )); + let account_id = 1; + let department_id = 1; + let tipping_name = TippingName::SmallTipper; + let funding_needed = 20_000u64.into(); + + let content: Content = Content::IPFS( + "bafkreiaiq24be2iioasr6ftyaum3icmj7amtjkom2jeokov5k5ojwzhvqy" + .as_bytes() + .to_vec(), + ); + + // Dispatch the extrinsic, should fail due to funding_needed exceeding max tipping value + assert_noop!( + DepartmentFunding::create_department_required_fund( + RuntimeOrigin::signed(account_id), + department_id, + content, + tipping_name, + funding_needed + ), + Error::::FundingMoreThanTippingValue + ); + }); +} + +#[test] +fn create_department_required_fund_fails_if_department_does_not_exist() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let account_id = 1; + let department_id = 999; // Assuming this department ID does not exist + let tipping_name = TippingName::SmallTipper; + let funding_needed = 50u64.into(); + + let content: Content = Content::IPFS( + "bafkreiaiq24be2iioasr6ftyaum3icmj7amtjkom2jeokov5k5ojwzhvqy" + .as_bytes() + .to_vec(), + ); + + // Dispatch the extrinsic, should fail because the department does not exist + assert_noop!( + DepartmentFunding::create_department_required_fund( + RuntimeOrigin::signed(account_id), + department_id, + content, + tipping_name, + funding_needed + ), + >::DepartmentDontExists + ); }); }