Browse Source

started writing unit tests for ClaimReward fixture

ignazio 3 years ago
parent
commit
84198c5854

+ 2 - 2
runtime-modules/content/src/errors.rs

@@ -107,7 +107,7 @@ decl_error! {
         RationaleNotProvidedByModerator,
 
         /// Insufficient balance
-        InsufficientBalance,
+        UnsufficientBalance,
 
         /// Insufficient treasury balance
         InsufficientTreasuryBalance,
@@ -125,7 +125,7 @@ decl_error! {
         TotalRewardLimitExceeded,
 
         /// Cashout amount too small
-        InsufficientCashoutAmount,
+        UnsufficientCashoutAmount,
 
         /// Reward account is none
         RewardAccountNotFoundInChannel,

+ 14 - 11
runtime-modules/content/src/lib.rs

@@ -298,7 +298,7 @@ pub struct ChannelRecord<MemberId: Ord, CuratorGroupId, AccountId, Balance> {
     /// moderator set
     moderator_set: BTreeSet<MemberId>,
     /// Cumulative cashout
-    prior_cumulative_cashout: Balance,
+    cumulative_payout_earned: Balance,
 }
 
 // Channel alias type for simplification.
@@ -729,7 +729,7 @@ pub type PostDeletionParameters<T> = PostDeletionParametersRecord<<T as frame_sy
 #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, Debug)]
 pub struct PullPaymentElement<ChannelId, Balance, Hash> {
     channel_id: ChannelId,
-    amount_earned: Balance,
+    cumulative_payout_claimed: Balance,
     reason: Hash,
 }
 
@@ -1034,7 +1034,7 @@ decl_module! {
                 reward_account: params.reward_account.clone(),
                 collaborators: params.collaborators.clone(),
                 moderator_set: params.moderator_set.clone(),
-                prior_cumulative_cashout: BalanceOf::<T>::default(),
+                cumulative_payout_earned: BalanceOf::<T>::default(),
             };
 
             // add channel to onchain state
@@ -1740,7 +1740,7 @@ decl_module! {
 
             ensure!(
                 Balances::<T>::usable_balance(&sender) >= initial_bloat_bond,
-                Error::<T>::InsufficientBalance,
+                Error::<T>::UnsufficientBalance,
             );
             //
             // == MUTATION SAFE ==
@@ -1973,11 +1973,14 @@ decl_module! {
             ensure_actor_authorized_to_claim_payment::<T>(origin, &actor, &channel.owner)?;
 
             let cashout = item
-                .amount_earned
-                .saturating_sub(channel.prior_cumulative_cashout);
+                .cumulative_payout_claimed
+                .saturating_sub(channel.cumulative_payout_earned);
 
-            ensure!(<MaxRewardAllowed<T>>::get() > item.amount_earned, Error::<T>::TotalRewardLimitExceeded);
-            ensure!(<MinCashoutAllowed<T>>::get() < cashout, Error::<T>::InsufficientCashoutAmount);
+            ensure!(
+                <MaxRewardAllowed<T>>::get() > item.cumulative_payout_claimed,
+                Error::<T>::TotalRewardLimitExceeded
+            );
+            ensure!(<MinCashoutAllowed<T>>::get() < cashout, Error::<T>::UnsufficientCashoutAmount);
             Self::verify_proof(&proof, &item)?;
 
             //
@@ -1987,11 +1990,11 @@ decl_module! {
             Self::transfer_reward(cashout, &channel.reward_account.unwrap());
             ChannelById::<T>::mutate(
                 &item.channel_id,
-                |channel| channel.prior_cumulative_cashout =
-                    channel.prior_cumulative_cashout.saturating_add(item.amount_earned)
+                |channel| channel.cumulative_payout_earned =
+                    channel.cumulative_payout_earned.saturating_add(item.cumulative_payout_claimed)
             );
 
-            Self::deposit_event(RawEvent::ChannelRewardUpdated(item.amount_earned, item.channel_id));
+            Self::deposit_event(RawEvent::ChannelRewardUpdated(item.cumulative_payout_claimed, item.channel_id));
 
             Ok(())
         }

+ 20 - 24
runtime-modules/content/src/tests/fixtures.rs

@@ -117,7 +117,7 @@ impl CreateChannelFixture {
                         collaborators: self.params.collaborators.clone(),
                         moderator_set: self.params.moderator_set.clone(),
                         num_videos: Zero::zero(),
-                        prior_cumulative_cashout: Zero::zero(),
+                        cumulative_payout_earned: Zero::zero(),
                     },
                     self.params.clone(),
                 ))
@@ -419,7 +419,7 @@ impl UpdateChannelFixture {
                                 .unwrap_or(channel_pre.collaborators),
                             num_videos: channel_pre.num_videos,
                             moderator_set: channel_pre.moderator_set,
-                            prior_cumulative_cashout: BalanceOf::<Test>::zero(),
+                            cumulative_payout_earned: BalanceOf::<Test>::zero(),
                         },
                         self.params.clone(),
                     ))
@@ -1266,10 +1266,10 @@ impl ClaimChannelRewardFixture {
         Self {
             sender: DEFAULT_MEMBER_ACCOUNT_ID,
             actor: ContentActor::Member(DEFAULT_MEMBER_ID),
-            payments: create_some_pull_payments(),
+            payments: create_some_pull_payments_helper(),
             item: PullPayment::<Test> {
                 channel_id: ChannelId::one(),
-                amount_earned: BalanceOf::<Test>::one(),
+                cumulative_payout_claimed: BalanceOf::<Test>::one(),
                 reason: Hashing::hash_of(&b"reason".to_vec()),
             },
         }
@@ -1283,6 +1283,10 @@ impl ClaimChannelRewardFixture {
         Self { actor, ..self }
     }
 
+    pub fn with_payments(self, payments: Vec<PullPayment<Test>>) -> Self {
+        Self { payments, ..self }
+    }
+
     pub fn with_item(self, item: PullPayment<Test>) -> Self {
         Self { item, ..self }
     }
@@ -1290,7 +1294,7 @@ impl ClaimChannelRewardFixture {
     pub fn call_and_assert(&self, expected_result: DispatchResult) {
         let origin = Origin::signed(self.sender.clone());
         let _balance_pre = Balances::<Test>::usable_balance(self.sender);
-        let cashout_pre = Content::channel_by_id(self.item.channel_id).prior_cumulative_cashout;
+        let cashout = Content::channel_by_id(self.item.channel_id).cumulative_payout_earned;
 
         let actual_result = Content::claim_channel_reward(
             origin,
@@ -1298,23 +1302,20 @@ impl ClaimChannelRewardFixture {
             build_merkle_path_helper(&self.payments, 1),
             self.item.clone(),
         );
-        let cashout_post = Content::channel_by_id(self.item.channel_id).prior_cumulative_cashout;
         let _balance_post = Balances::<Test>::usable_balance(self.sender);
 
         assert_eq!(actual_result, expected_result);
 
         if actual_result.is_ok() {
-            assert_eq!(cashout_post, cashout_pre.saturating_add(item.amount_earned));
+            assert_eq!(cashout, self.item.cumulative_payout_claimed);
 
             assert_eq!(
                 System::events().last().unwrap().event,
                 MetaEvent::content(RawEvent::ChannelRewardUpdated(
-                    self.item.amount_earned,
+                    self.item.cumulative_payout_claimed,
                     self.item.channel_id
                 ))
             );
-        } else {
-            assert_eq!(cashout_post, cashout_pre);
         }
     }
 }
@@ -1548,17 +1549,13 @@ fn index_path_helper(len: usize, index: usize) -> Vec<IndexItem> {
     return path;
 }
 
-fn generate_merkle_root_helper<E: Encode>(
-    collection: &[E],
-) -> Result<Vec<HashOutput>, &'static str> {
+fn generate_merkle_root_helper<E: Encode>(collection: &[E]) -> Vec<HashOutput> {
     // generates merkle root from the ordered sequence collection.
     // The resulting vector is structured as follows: elements in range
     // [0..collection.len()) will be the tree leaves (layer 0), elements in range
     // [collection.len()..collection.len()/2) will be the nodes in the next to last layer (layer 1)
     // [layer_n_length..layer_n_length/2) will be the number of nodes in layer(n+1)
-    if collection.len() == 0 {
-        return Err("empty vector");
-    }
+    assert!(!collection.is_empty());
     let mut out = Vec::new();
     for e in collection.iter() {
         out.push(Hashing::hash(&e.encode()));
@@ -1583,22 +1580,19 @@ fn generate_merkle_root_helper<E: Encode>(
                 &[out[last_len - 1], out[last_len - 1]].encode(),
             ));
         }
-        let new_len: usize = out
-            .len()
-            .checked_sub(last_len)
-            .ok_or("unsigned underflow")?;
+        let new_len: usize = out.len() - last_len;
         rem = new_len % 2;
         max_len = new_len >> 1;
         start = last_len;
     }
-    Ok(out)
+    out
 }
 
 fn build_merkle_path_helper<E: Encode + Clone>(
     collection: &[E],
     idx: usize,
 ) -> Vec<ProofElement<Test>> {
-    let merkle_tree = generate_merkle_root_helper(collection)?;
+    let merkle_tree = generate_merkle_root_helper(collection);
     // builds the actual merkle path with the hashes needed for the proof
     let index_path = index_path_helper(collection.len(), idx + 1);
     index_path
@@ -1614,10 +1608,12 @@ fn build_merkle_path_helper<E: Encode + Clone>(
 fn create_some_pull_payments_helper() -> Vec<PullPayment<Test>> {
     let mut payments = Vec::new();
     for i in 0..PAYMENTS_NUMBER {
-        payment.push(PullPayment::<Test> {
+        payments.push(PullPayment::<Test> {
             channel_id: ChannelId::from(i % 5),
-            amount_earned: BalanceOf::<Test>::from(i),
+            cumulative_payout_claimed: BalanceOf::<Test>::from(i),
             reason: Hashing::hash_of(&b"reason".to_vec()),
         });
     }
+
+    payments
 }

+ 131 - 1
runtime-modules/content/src/tests/merkle.rs

@@ -1,5 +1,5 @@
 #![cfg(test)]
-
+use super::curators::add_curator_to_new_group;
 use super::fixtures::*;
 use super::mock::*;
 use crate::*;
@@ -58,6 +58,136 @@ fn successful_commitment_update_by_lead_account() {
     })
 }
 
+#[test]
+fn unsuccessful_reward_claim_with_member_auth_failed() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        ClaimChannelRewardFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_with_curator_auth_failed() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        let default_curator_group_id = Content::next_curator_group_id() - 1;
+        ClaimChannelRewardFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::CuratorAuthFailed.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_by_lead() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        let default_curator_group_id = Content::next_curator_group_id() - 1;
+        ClaimChannelRewardFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::ActorCannotOwnChannel.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_by_unath_member() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        ClaimChannelRewardFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_by_unauth_curator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        let unauthorized_curator_group_id = add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        ClaimChannelRewardFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                unauthorized_curator_group_id,
+                UNAUTHORIZED_CURATOR_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_with_unsufficient_cashout() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        let item = PullPayment::<Test> {
+            channel_id: ChannelId::one(),
+            cumulative_payout_claimed: Content::min_cashout_allowed() - 1,
+            reason: Hashing::hash_of(&b"reason".to_vec()),
+        };
+        ClaimChannelRewardFixture::default()
+            .with_payments(vec![item.clone()])
+            .with_item(item)
+            .call_and_assert(Err(Error::<Test>::UnsufficientCashoutAmount.into()))
+    })
+}
+
+#[test]
+fn unsuccessful_reward_claim_with_reward_limit_exceeded() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        let item = PullPayment::<Test> {
+            channel_id: ChannelId::one(),
+            cumulative_payout_claimed: Content::max_reward_allowed() + 1,
+            reason: Hashing::hash_of(&b"reason".to_vec()),
+        };
+        ClaimChannelRewardFixture::default()
+            .with_payments(vec![item.clone()])
+            .with_item(item)
+            .call_and_assert(Err(Error::<Test>::TotalRewardLimitExceeded.into()))
+    })
+}
+
 // fn setup_channels_scenario(
 //     num_channels: u64,
 //     payments_params: &Vec<(u64, BalanceOf<Test>)>,

+ 1 - 1
runtime-modules/content/src/tests/posts.rs

@@ -67,7 +67,7 @@ pub fn unsuccessful_post_creation_with_insufficient_balance() {
         create_default_member_owned_channel_with_video();
         slash_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID);
 
-        CreatePostFixture::default().call_and_assert(Err(Error::<Test>::InsufficientBalance.into()))
+        CreatePostFixture::default().call_and_assert(Err(Error::<Test>::UnsufficientBalance.into()))
     })
 }