Browse Source

Merge pull request #2996 from ignazio-bovo/giza_utest_content_extratests

Giza utest content extratests
Mokhtar Naamani 3 years ago
parent
commit
853bd13d9c

File diff suppressed because it is too large
+ 0 - 0
chain-metadata.json


+ 16 - 0
runtime-modules/content/src/lib.rs

@@ -1,3 +1,19 @@
+// Extrinsics list
+// - create channel
+// - update channel
+// - delete channel
+// - create video
+// - update video
+// - delete video
+// - update channel chensorship status
+// - update video chensorship status
+// - create channel category
+// - update channel category
+// - delete channel category
+// - create video category
+// - update video category
+// - delete video category
+
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
 #![recursion_limit = "256"]

+ 4 - 1
runtime-modules/content/src/permissions/mod.rs

@@ -261,13 +261,16 @@ pub fn ensure_actor_authorized_to_update_channel_assets<T: Trait>(
             Ok(())
         }
         ContentActor::Member(member_id) => {
-            // ensure valid member
+            // ensure member account and origin correspondence
             ensure_member_auth_success::<T>(sender, member_id)?;
             // ensure member is channel owner
             ensure_member_is_channel_owner::<T>(&channel.owner, member_id)?;
             Ok(())
         }
         ContentActor::Collaborator(member_id) => {
+            // ensure member account and origin correspondence
+            ensure_member_auth_success::<T>(sender, member_id)?;
+            // ensure valid collaborator
             ensure!(
                 channel.collaborators.contains(member_id),
                 Error::<T>::ActorNotAuthorized

+ 1344 - 664
runtime-modules/content/src/tests/channels.rs

@@ -1,811 +1,1491 @@
 #![cfg(test)]
 
 use super::curators;
+use super::fixtures::*;
 use super::mock::*;
 use crate::*;
-use frame_support::traits::Currency;
 use frame_support::{assert_err, assert_ok};
 
 #[test]
-fn successful_channel_deletion() {
+fn channel_censoring() {
     with_default_mock_builder(|| {
         // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-
-        // create an account with enought balance
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        // 3 assets added at creation
-        let assets = StorageAssetsRecord {
-            object_creation_list: vec![
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"second".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"third".to_vec(),
-                },
-            ],
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
-        let channel_id = NextChannelId::<Test>::get();
-
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
+        let channel_id = Content::next_channel_id();
+        assert_ok!(Content::create_channel(
+            Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
+            ContentActor::Member(DEFAULT_MEMBER_ID),
             ChannelCreationParametersRecord {
-                assets: Some(assets),
+                assets: None,
                 meta: None,
                 reward_account: None,
                 collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+            }
+        ));
 
-        // attempt to delete channel with non zero assets should result in error: objects
-        // are misspecified
-        delete_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
+        let group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+
+        // Curator can censor channels
+        let is_censored = true;
+        assert_ok!(Content::update_channel_censorship_status(
+            Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+            ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
             channel_id,
-            2u64,
-            Err(Error::<Test>::InvalidBagSizeSpecified.into()),
+            is_censored,
+            vec![]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCensorshipStatusUpdated(
+                ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
+                channel_id,
+                is_censored,
+                vec![]
+            ))
         );
 
-        // successful deletion because we empty the bag first
-        delete_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
+        let channel = Content::channel_by_id(channel_id);
+
+        assert!(channel.is_censored);
+
+        // Curator can un-censor channels
+        let is_censored = false;
+        assert_ok!(Content::update_channel_censorship_status(
+            Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+            ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
             channel_id,
-            3u64, // now assets are 0
-            Ok(()),
+            is_censored,
+            vec![]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCensorshipStatusUpdated(
+                ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
+                channel_id,
+                is_censored,
+                vec![]
+            ))
         );
 
-        // create a channel with no assets:
-        let empty_channel_id = Content::next_channel_id();
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
+        let channel = Content::channel_by_id(channel_id);
+
+        assert!(!channel.is_censored);
+
+        // Member cannot censor channels
+        let is_censored = true;
+        assert_err!(
+            Content::update_channel_censorship_status(
+                Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
+                ContentActor::Member(DEFAULT_MEMBER_ID),
+                channel_id,
+                is_censored,
+                vec![]
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+
+        let curator_channel_id = Content::next_channel_id();
+
+        // create curator channel
+        assert_ok!(Content::create_channel(
+            Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+            ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
             ChannelCreationParametersRecord {
                 assets: None,
                 meta: None,
                 reward_account: None,
                 collaborators: BTreeSet::new(),
-            },
-            Ok(()),
+            }
+        ));
+
+        // Curator cannot censor curator group channels
+        assert_err!(
+            Content::update_channel_censorship_status(
+                Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+                ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
+                curator_channel_id,
+                is_censored,
+                vec![]
+            ),
+            Error::<Test>::CannotCensoreCuratorGroupOwnedChannels
         );
 
-        delete_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            empty_channel_id,
-            0u64,
-            Ok(()),
+        // Lead can still censor curator group channels
+        assert_ok!(Content::update_channel_censorship_status(
+            Origin::signed(LEAD_ACCOUNT_ID),
+            ContentActor::Lead,
+            curator_channel_id,
+            is_censored,
+            vec![]
+        ));
+    })
+}
+
+// channel creation tests
+#[test]
+fn successful_channel_creation_with_member_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_creation_with_curator_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_lead_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        CreateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::ActorCannotOwnChannel.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_collaborator_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        CreateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::ActorCannotOwnChannel.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_uncorresponding_member_id_and_origin() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_uncorresponding_curator_id_and_origin() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::CuratorAuthFailed.into()));
+    })
+}
+
+#[test]
+fn successful_channel_creation_with_storage_upload_and_member_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_creation_with_storage_upload_and_curator_context() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_invalid_expected_data_size_fee() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets(StorageAssets::<Test> {
+                // setting a purposely high fee to trigger error
+                expected_data_size_fee: BalanceOf::<Test>::from(1_000_000u64),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::DataSizeFeeChanged.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_insufficient_balance() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::InsufficientBalance.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_no_bucket_available() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: STORAGE_BUCKET_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketIdCollectionsAreEmpty.into(),
+            ));
+
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: (0..(STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT + 1))
+                    .map(|_| DataObjectCreationParameters {
+                        size: 1,
+                        ipfs_content_id: vec![1u8],
+                    })
+                    .collect(),
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketIdCollectionsAreEmpty.into(),
+            ));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_data_limits_exceeded() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: VOUCHER_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(storage::Error::<Test>::MaxDataObjectSizeExceeded.into()));
+    })
+}
+
+#[test]
+fn successful_channel_creation_with_collaborators_set() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_collaborators(vec![COLLABORATOR_MEMBER_ID].into_iter().collect())
+            .call_and_assert(Ok(()));
+
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_collaborators(vec![COLLABORATOR_MEMBER_ID].into_iter().collect())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_creation_with_invalid_collaborators_set() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_collaborators(vec![COLLABORATOR_MEMBER_ID + 100].into_iter().collect())
+            .call_and_assert(Err(Error::<Test>::CollaboratorIsNotValidMember.into()));
+    })
+}
+
+#[test]
+fn successful_channel_creation_with_reward_account() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_reward_account(DEFAULT_MEMBER_ACCOUNT_ID)
+            .call_and_assert(Ok(()));
+
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_reward_account(DEFAULT_CURATOR_ACCOUNT_ID)
+            .call_and_assert(Ok(()));
+    })
+}
+
+// channel update tests
+#[test]
+fn unsuccessful_channel_update_with_uncorresponding_member_id_and_origin() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_uncorresponding_curator_id_and_origin() {
+    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();
+
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::CuratorAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_uncorresponding_collaborator_id_and_origin() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_invalid_channel_id() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_channel_id(ChannelId::zero())
+            .call_and_assert(Err(Error::<Test>::ChannelDoesNotExist.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_uploaded_by_collaborator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(COLLABORATOR_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_removed_by_collaborator() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_uploaded_by_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_removed_by_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_uploaded_by_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();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_removed_by_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();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_curator_channel_update_with_assets_uploaded_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);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_curator_channel_update_with_assets_uploaded_by_invalid_lead_origin() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_assets_removed_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_removed_by_invalid_lead_origin() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Lead)
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_uploaded_by_unauthorized_collaborator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(
+            UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID,
+            INITIAL_BALANCE,
         );
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(
+                UNAUTHORIZED_COLLABORATOR_MEMBER_ID,
+            ))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_removed_by_unauthorized_collaborator() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(
+                UNAUTHORIZED_COLLABORATOR_MEMBER_ID,
+            ))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_uploaded_by_unauthorized_member() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_removed_by_unathorized_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_uploaded_by_unauthorized_curator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                unauthorized_curator_group_id,
+                UNAUTHORIZED_CURATOR_ID,
+            ))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_assets_removed_by_unauthorized_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();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                unauthorized_curator_group_id,
+                UNAUTHORIZED_CURATOR_ID,
+            ))
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_member_channel_update_with_assets_uploaded_by_lead() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_member_channel_update_with_assets_removed_by_lead() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            // data objects ids start at index 1
+            .with_assets_to_remove((1..(DATA_OBJECTS_NUMBER as u64 - 1)).collect())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_collaborators_set_updated_by_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_collaborators_set_updated_by_unauthorized_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_collaborators_set_updated_by_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();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_collaborators_set_updated_by_unauthorized_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();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                unauthorized_curator_group_id,
+                UNAUTHORIZED_CURATOR_ID,
+            ))
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_collaborators_set_updated_by_collaborator() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_member_channel_update_with_collaborators_set_updated_by_lead() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn successful_curator_channel_update_with_collaborators_set_updated_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_curator_channel_update_with_collaborators_set_updated_by_invalid_lead_origin() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Lead)
+            .with_collaborators(BTreeSet::new())
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_reward_account_updated_by_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_reward_account(Some(None))
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_reward_account_updated_by_unauthorized_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();
+
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .with_reward_account(Some(None))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn successful_channel_update_with_reward_account_updated_by_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();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_reward_account(Some(None))
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_reward_account_updated_by_unauthorized_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();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        UpdateChannelFixture::default()
+            .with_sender(UNAUTHORIZED_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                unauthorized_curator_group_id,
+                UNAUTHORIZED_CURATOR_ID,
+            ))
+            .with_reward_account(Some(None))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_channel_update_with_reward_account_updated_by_collaborator() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_reward_account(Some(None))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_member_channel_update_with_reward_account_updated_by_lead() {
+    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();
+
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_reward_account(Some(None))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
     })
 }
 
 #[test]
-fn successful_channel_assets_deletion() {
+fn successful_curator_channel_update_with_reward_account_updated_by_lead() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-        // create an account with enought balance
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        // 3 assets
-        let assets = StorageAssetsRecord {
-            object_creation_list: vec![
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"second".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"third".to_vec(),
-                },
-            ],
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
-
-        let channel_id = NextChannelId::<Test>::get();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(assets),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
-
-        // delete assets
-        let assets_to_remove = [0u64, 1u64].iter().map(|&x| x).collect::<BTreeSet<_>>();
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        // delete channel assets
-        assert_ok!(Content::update_channel(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: assets_to_remove,
-                collaborators: None,
-            },
-        ));
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_reward_account(Some(None))
+            .call_and_assert(Ok(()));
     })
 }
 
 #[test]
-fn succesful_channel_update() {
+fn unsuccessful_curator_channel_update_with_reward_account_updated_by_invalid_lead_origin() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-
-        // create an account with enought balance
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        // 2 + 1 assets to be uploaded
-        let first_obj_id = Storage::<Test>::next_data_object_id();
-        let first_batch = StorageAssetsRecord {
-            object_creation_list: vec![
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"second".to_vec(),
-                },
-            ],
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
-        let first_batch_ids =
-            (first_obj_id..Storage::<Test>::next_data_object_id()).collect::<BTreeSet<_>>();
-
-        let second_batch = StorageAssetsRecord {
-            object_creation_list: vec![
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"second".to_vec(),
-                },
-            ],
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
-
-        let channel_id = NextChannelId::<Test>::get();
-
-        // create channel with first batch of assets
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(first_batch),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
-
-        // update channel by adding the second batch of assets
-        update_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            ChannelUpdateParametersRecord {
-                assets_to_upload: Some(second_batch),
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: BTreeSet::new(),
-                collaborators: None,
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        // update channel by removing the first batch of assets
-        update_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: first_batch_ids,
-                collaborators: None,
-            },
-            Ok(()),
-        );
+        UpdateChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Lead)
+            .with_reward_account(Some(None))
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
     })
 }
 
 #[test]
-fn succesful_channel_creation() {
+fn unsuccessful_channel_update_with_data_limits_exceeded() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-
-        // create an account with enought balance
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        // 3 assets to be uploaded
-        let assets = StorageAssetsRecord {
-            object_creation_list: vec![
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"second".to_vec(),
-                },
-                DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"third".to_vec(),
-                },
-            ],
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
-
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(assets),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: VOUCHER_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(storage::Error::<Test>::MaxDataObjectSizeExceeded.into()));
     })
 }
 
 #[test]
-fn lead_cannot_create_channel() {
+fn unsuccessful_channel_update_with_invalid_objects_id_to_remove() {
     with_default_mock_builder(|| {
-        create_initial_storage_buckets();
-        assert_err!(
-            Content::create_channel(
-                Origin::signed(LEAD_ORIGIN),
-                ContentActor::Lead,
-                ChannelCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                    reward_account: None,
-                    collaborators: BTreeSet::new(),
-                }
-            ),
-            Error::<Test>::ActorCannotOwnChannel
-        );
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_remove(
+                ((DATA_OBJECTS_NUMBER as u64 + 1)..(2 * DATA_OBJECTS_NUMBER as u64)).collect(),
+            )
+            .call_and_assert(Err(storage::Error::<Test>::DataObjectDoesntExist.into()));
     })
 }
 
 #[test]
-fn curator_owned_channels() {
+fn unsuccessful_channel_update_with_invalid_collaborators_set() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        // Curator group doesn't exist yet
-        assert_err!(
-            Content::create_channel(
-                Origin::signed(FIRST_CURATOR_ORIGIN),
-                ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-                ChannelCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                    reward_account: None,
-                    collaborators: BTreeSet::new(),
-                }
-            ),
-            Error::<Test>::CuratorGroupIsNotActive
-        );
-
-        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
-        assert_eq!(FIRST_CURATOR_GROUP_ID, group_id);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        // Curator from wrong group
-        assert_err!(
-            Content::create_channel(
-                Origin::signed(SECOND_CURATOR_ORIGIN),
-                ContentActor::Curator(FIRST_CURATOR_GROUP_ID, SECOND_CURATOR_ID),
-                ChannelCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                    reward_account: None,
-                    collaborators: BTreeSet::new(),
-                }
-            ),
-            Error::<Test>::CuratorIsNotAMemberOfGivenCuratorGroup
-        );
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_collaborators(vec![COLLABORATOR_MEMBER_ID + 100].into_iter().collect())
+            .call_and_assert(Err(Error::<Test>::CollaboratorIsNotValidMember.into()));
+    })
+}
 
-        // Curator in correct active group, but wrong origin
-        assert_err!(
-            Content::create_channel(
-                Origin::signed(SECOND_CURATOR_ORIGIN),
-                ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-                ChannelCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                    reward_account: None,
-                    collaborators: BTreeSet::new(),
-                }
-            ),
-            Error::<Test>::CuratorAuthFailed
-        );
+#[test]
+fn unsuccessful_channel_update_with_invalid_expected_data_size_fee() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        let channel_id = Content::next_channel_id();
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                // setting a purposely high fee to trigger error
+                expected_data_size_fee: BalanceOf::<Test>::from(1_000_000u64),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::DataSizeFeeChanged.into()));
+    })
+}
 
-        // Curator in correct active group, with correct origin
-        assert_ok!(Content::create_channel(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            }
-        ));
+#[test]
+fn unsuccessful_channel_update_with_insufficient_balance() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelCreated(
-                ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-                channel_id,
-                ChannelRecord {
-                    owner: ChannelOwner::CuratorGroup(FIRST_CURATOR_GROUP_ID),
-                    is_censored: false,
-                    reward_account: None,
-                    num_videos: 0,
-                    collaborators: BTreeSet::new(),
-                },
-                ChannelCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                    reward_account: None,
-                    collaborators: BTreeSet::new(),
-                }
-            ))
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+        slash_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID);
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::InsufficientBalance.into()));
+    })
+}
 
-        // Curator can update channel
-        assert_ok!(Content::update_channel(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            channel_id,
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: BTreeSet::new(),
-                collaborators: None,
-            }
-        ));
+#[test]
+fn unsuccessful_channel_update_with_no_bucket_with_sufficient_object_size_limit() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // Lead can update curator owned channels
-        assert_ok!(Content::update_channel(
-            Origin::signed(LEAD_ORIGIN),
-            ContentActor::Lead,
-            channel_id,
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: BTreeSet::new(),
-                collaborators: None,
-            }
-        ));
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: STORAGE_BUCKET_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectSizeLimitReached.into(),
+            ));
     })
 }
 
 #[test]
-fn invalid_member_cannot_create_channel() {
+fn unsuccessful_channel_update_with_no_bucket_with_sufficient_object_number_limit() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-        // Not a member
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(UNKNOWN_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Err(Error::<Test>::MemberAuthFailed.into()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        UpdateChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: (0..(STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT + 1))
+                    .map(|_| DataObjectCreationParameters {
+                        size: 1,
+                        ipfs_content_id: vec![1u8],
+                    })
+                    .collect(),
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectNumberLimitReached.into(),
+            ));
     })
 }
 
+// channel deletion tests
 #[test]
-fn invalid_member_cannot_update_channel() {
+fn successful_curator_channel_deletion_by_lead() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        update_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(UNKNOWN_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                collaborators: None,
-                assets_to_remove: BTreeSet::new(),
-            },
-            Err(Error::<Test>::MemberAuthFailed.into()),
-        );
+        DeleteChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Ok(()));
     })
 }
 
 #[test]
-fn invalid_member_cannot_delete_channel() {
+fn unsuccessful_curator_channel_deletion_by_invalid_lead_origin() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        delete_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(UNKNOWN_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            0u64,
-            Err(Error::<Test>::MemberAuthFailed.into()),
-        );
+        DeleteChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID + 100)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
     })
 }
 
 #[test]
-fn non_authorized_collaborators_cannot_update_channel() {
+fn unsuccessful_member_channel_deletion_by_lead() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
-
-        create_initial_storage_buckets();
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        DeleteChannelFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
 
-        // attempt for an non auth. collaborator to update channel assets
-        update_channel_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            ChannelUpdateParametersRecord {
-                assets_to_upload: Some(helper_generate_storage_assets(vec![5])),
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: vec![DataObjectId::<Test>::one()]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-                collaborators: None,
-            },
-            Err(Error::<Test>::ActorNotAuthorized.into()),
-        );
+#[test]
+fn unsuccessful_channel_deletion_by_collaborator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // add collaborators
-        update_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: BTreeSet::new(),
-                collaborators: Some(
-                    vec![COLLABORATOR_MEMBER_ID]
-                        .into_iter()
-                        .collect::<BTreeSet<_>>(),
-                ),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        // attempt for a valid collaborator to update channel fields outside
-        // of his scope
-        update_channel_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            ChannelUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                reward_account: Some(Some(COLLABORATOR_MEMBER_ORIGIN)),
-                assets_to_remove: BTreeSet::new(),
-                collaborators: None,
-            },
-            Err(Error::<Test>::ActorNotAuthorized.into()),
-        );
+        DeleteChannelFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
     })
 }
 
 #[test]
-fn authorized_collaborators_can_update_channel() {
+fn successful_channel_deletion_by_member() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
-
-        create_initial_storage_buckets();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: vec![COLLABORATOR_MEMBER_ID]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        // attempt for an auth. collaborator to update channel assets
-        update_channel_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            ChannelUpdateParametersRecord {
-                assets_to_upload: Some(helper_generate_storage_assets(vec![5])),
-                new_meta: None,
-                reward_account: None,
-                assets_to_remove: vec![DataObjectId::<Test>::one()]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-                collaborators: None,
-            },
-            Ok(()),
-        );
+        DeleteChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .call_and_assert(Ok(()));
     })
 }
 
 #[test]
-fn channel_censoring() {
+fn successful_channel_deletion_by_curator() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        let channel_id = Content::next_channel_id();
-        assert_ok!(Content::create_channel(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            }
-        ));
-
-        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
-
-        // Curator can censor channels
-        let is_censored = true;
-        assert_ok!(Content::update_channel_censorship_status(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-            channel_id,
-            is_censored,
-            vec![]
-        ));
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelCensorshipStatusUpdated(
-                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-                channel_id,
-                is_censored,
-                vec![]
+        let default_curator_group_id = Content::next_curator_group_id() - 1;
+        DeleteChannelFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
             ))
-        );
+            .call_and_assert(Ok(()));
+    })
+}
 
-        let channel = Content::channel_by_id(channel_id);
+#[test]
+fn unsuccessful_channel_deletion_by_unauthorized_member() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        assert!(channel.is_censored);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        // Curator can un-censor channels
-        let is_censored = false;
-        assert_ok!(Content::update_channel_censorship_status(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-            channel_id,
-            is_censored,
-            vec![]
-        ));
+        DeleteChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
 
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelCensorshipStatusUpdated(
-                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-                channel_id,
-                is_censored,
-                vec![]
-            ))
-        );
+#[test]
+fn unsuccessful_channel_deletion_by_unauthorized_curator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        let channel = Content::channel_by_id(channel_id);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        DeleteChannelFixture::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()));
+    })
+}
 
-        assert!(!channel.is_censored);
+#[test]
+fn unsuccessful_channel_deletion_by_uncorresponding_member_id_and_origin() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // Member cannot censor channels
-        let is_censored = true;
-        assert_err!(
-            Content::update_channel_censorship_status(
-                Origin::signed(FIRST_MEMBER_ORIGIN),
-                ContentActor::Member(FIRST_MEMBER_ID),
-                channel_id,
-                is_censored,
-                vec![]
-            ),
-            Error::<Test>::ActorNotAuthorized
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        let curator_channel_id = Content::next_channel_id();
+        DeleteChannelFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
 
-        // create curator channel
-        assert_ok!(Content::create_channel(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-            ChannelCreationParametersRecord {
-                assets: None,
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            }
-        ));
+#[test]
+fn unsuccessful_channel_deletion_by_uncorresponding_curator_id_and_origin() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // Curator cannot censor curator group channels
-        assert_err!(
-            Content::update_channel_censorship_status(
-                Origin::signed(FIRST_CURATOR_ORIGIN),
-                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
-                curator_channel_id,
-                is_censored,
-                vec![]
-            ),
-            Error::<Test>::CannotCensoreCuratorGroupOwnedChannels
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        // Lead can still censor curator group channels
-        assert_ok!(Content::update_channel_censorship_status(
-            Origin::signed(LEAD_ORIGIN),
-            ContentActor::Lead,
-            curator_channel_id,
-            is_censored,
-            vec![]
-        ));
+        let default_curator_group_id = Content::next_curator_group_id() - 1;
+        DeleteChannelFixture::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 channel_creation_doesnt_leave_bags_dangling() {
+fn unsuccessful_channel_deletion_with_invalid_channel_id() {
     with_default_mock_builder(|| {
-        // in order to emit events
         run_to_block(1);
 
-        create_initial_storage_buckets();
-        // number of assets big enought to make upload_data_objects throw
-        let asset_num = 100_000usize;
-        let mut object_creation_list =
-            Vec::<DataObjectCreationParameters>::with_capacity(asset_num);
-        for _i in 0..asset_num {
-            object_creation_list.push(DataObjectCreationParameters {
-                size: 1_000_000, // size big enought to make upload_data_objects throw
-                ipfs_content_id: b"test".to_vec(),
-            });
-        }
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        let assets = StorageAssetsRecord {
-            object_creation_list: object_creation_list,
-            expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-        };
+        DeleteChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_channel_id(Zero::zero())
+            .call_and_assert(Err(Error::<Test>::ChannelDoesNotExist.into()));
+    })
+}
 
-        let channel_id = NextChannelId::<Test>::get();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(assets),
-                meta: Some(vec![]),
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Err(storage::Error::<Test>::MaxDataObjectSizeExceeded.into()),
-        );
+#[test]
+fn unsuccessful_channel_deletion_with_invalid_bag_size() {
+    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();
+
+        assert!(DATA_OBJECTS_NUMBER > 0);
 
-        // ensure that no bag are left dangling
-        let dyn_bag = DynamicBagIdType::<MemberId, ChannelId>::Channel(channel_id);
-        let bag_id = storage::BagIdType::from(dyn_bag.clone());
-        assert!(<Test as Trait>::DataObjectStorage::ensure_bag_exists(&bag_id).is_err());
+        DeleteChannelFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            // default member owned channel has DATA_OBJECTS_NUMBER > 0 assets
+            .with_num_objects_to_delete(0u64)
+            .call_and_assert(Err(Error::<Test>::InvalidBagSizeSpecified.into()));
     })
 }

+ 27 - 20
runtime-modules/content/src/tests/curators.rs

@@ -7,15 +7,17 @@ use frame_support::{assert_err, assert_ok};
 pub fn add_curator_to_new_group(curator_id: CuratorId) -> CuratorGroupId {
     let curator_group_id = Content::next_curator_group_id();
     // create new group and add curator id to it
-    assert_ok!(Content::create_curator_group(Origin::signed(LEAD_ORIGIN)));
+    assert_ok!(Content::create_curator_group(Origin::signed(
+        LEAD_ACCOUNT_ID
+    )));
     assert_ok!(Content::add_curator_to_group(
-        Origin::signed(LEAD_ORIGIN),
+        Origin::signed(LEAD_ACCOUNT_ID),
         curator_group_id,
         curator_id
     ));
     // make group active
     assert_ok!(Content::set_curator_group_status(
-        Origin::signed(LEAD_ORIGIN),
+        Origin::signed(LEAD_ACCOUNT_ID),
         curator_group_id,
         true
     ));
@@ -29,7 +31,9 @@ fn curator_group_management() {
         run_to_block(1);
 
         let curator_group_id = Content::next_curator_group_id();
-        assert_ok!(Content::create_curator_group(Origin::signed(LEAD_ORIGIN)));
+        assert_ok!(Content::create_curator_group(Origin::signed(
+            LEAD_ACCOUNT_ID
+        )));
 
         assert_eq!(
             System::events().last().unwrap().event,
@@ -44,7 +48,7 @@ fn curator_group_management() {
 
         // Activate group
         assert_ok!(Content::set_curator_group_status(
-            Origin::signed(LEAD_ORIGIN),
+            Origin::signed(LEAD_ACCOUNT_ID),
             curator_group_id,
             true
         ));
@@ -60,35 +64,35 @@ fn curator_group_management() {
         // Cannot add non curators into group
         assert_err!(
             Content::add_curator_to_group(
-                Origin::signed(LEAD_ORIGIN),
+                Origin::signed(LEAD_ACCOUNT_ID),
                 curator_group_id,
-                MEMBERS_COUNT + 1 // not a curator
+                DEFAULT_CURATOR_ID + 1 // not a curator
             ),
             Error::<Test>::CuratorIdInvalid
         );
 
         // Add curator to group
         assert_ok!(Content::add_curator_to_group(
-            Origin::signed(LEAD_ORIGIN),
+            Origin::signed(LEAD_ACCOUNT_ID),
             curator_group_id,
-            FIRST_CURATOR_ID
+            DEFAULT_CURATOR_ID
         ));
 
         assert_eq!(
             System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::CuratorAdded(curator_group_id, FIRST_CURATOR_ID))
+            MetaEvent::content(RawEvent::CuratorAdded(curator_group_id, DEFAULT_CURATOR_ID))
         );
 
         // Ensure curator is in group
         let group = Content::curator_group_by_id(curator_group_id);
-        assert!(group.has_curator(&FIRST_CURATOR_ID));
+        assert!(group.has_curator(&DEFAULT_CURATOR_ID));
 
         // Cannot add same curator again
         assert_err!(
             Content::add_curator_to_group(
-                Origin::signed(LEAD_ORIGIN),
+                Origin::signed(LEAD_ACCOUNT_ID),
                 curator_group_id,
-                FIRST_CURATOR_ID
+                DEFAULT_CURATOR_ID
             ),
             Error::<Test>::CuratorIsAlreadyAMemberOfGivenCuratorGroup
         );
@@ -96,7 +100,7 @@ fn curator_group_management() {
         // Cannot remove curator if not in group
         assert_err!(
             Content::remove_curator_from_group(
-                Origin::signed(LEAD_ORIGIN),
+                Origin::signed(LEAD_ACCOUNT_ID),
                 curator_group_id,
                 MEMBERS_COUNT + 1 // not a curator
             ),
@@ -105,25 +109,28 @@ fn curator_group_management() {
 
         // Remove curator from group
         assert_ok!(Content::remove_curator_from_group(
-            Origin::signed(LEAD_ORIGIN),
+            Origin::signed(LEAD_ACCOUNT_ID),
             curator_group_id,
-            FIRST_CURATOR_ID
+            DEFAULT_CURATOR_ID
         ));
 
         assert_eq!(
             System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::CuratorRemoved(curator_group_id, FIRST_CURATOR_ID))
+            MetaEvent::content(RawEvent::CuratorRemoved(
+                curator_group_id,
+                DEFAULT_CURATOR_ID
+            ))
         );
 
         let group = Content::curator_group_by_id(curator_group_id);
-        assert!(!group.has_curator(&FIRST_CURATOR_ID));
+        assert!(!group.has_curator(&DEFAULT_CURATOR_ID));
 
         // Already removed cannot remove again
         assert_err!(
             Content::remove_curator_from_group(
-                Origin::signed(LEAD_ORIGIN),
+                Origin::signed(LEAD_ACCOUNT_ID),
                 curator_group_id,
-                FIRST_CURATOR_ID
+                DEFAULT_CURATOR_ID
             ),
             Error::<Test>::CuratorIsNotAMemberOfGivenCuratorGroup
         );

+ 891 - 0
runtime-modules/content/src/tests/fixtures.rs

@@ -0,0 +1,891 @@
+use super::curators;
+use super::mock::*;
+use crate::*;
+use frame_support::assert_ok;
+use frame_support::traits::Currency;
+
+// constants used
+pub const VOUCHER_OBJECTS_NUMBER_LIMIT: u64 = 40;
+pub const VOUCHER_OBJECTS_SIZE_LIMIT: u64 = 400;
+pub const STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT: u64 = 10;
+pub const STORAGE_BUCKET_OBJECTS_SIZE_LIMIT: u64 = 100;
+pub const STORAGE_BUCKET_ACCEPTING_BAGS: bool = true;
+pub const DATA_OBJECTS_NUMBER: u8 = 2;
+
+// type aliases
+type AccountId = <Test as frame_system::Trait>::AccountId;
+type VideoId = <Test as Trait>::VideoId;
+
+// fixtures
+pub struct CreateChannelFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    params: ChannelCreationParameters<Test>,
+}
+
+impl CreateChannelFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ID),
+            params: ChannelCreationParameters::<Test> {
+                assets: None,
+                meta: None,
+                reward_account: None,
+                collaborators: BTreeSet::new(),
+            },
+        }
+    }
+
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_assets(self, assets: StorageAssets<Test>) -> Self {
+        Self {
+            params: ChannelCreationParameters::<Test> {
+                assets: Some(assets),
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn with_collaborators(self, collaborators: BTreeSet<MemberId>) -> Self {
+        Self {
+            params: ChannelCreationParameters::<Test> {
+                collaborators: collaborators,
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn with_reward_account(self, reward_account: AccountId) -> Self {
+        Self {
+            params: ChannelCreationParameters::<Test> {
+                reward_account: Some(reward_account),
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let channel_id = Content::next_channel_id();
+        let channel_bag_id = Content::bag_id_for_channel(&channel_id);
+        let beg_obj_id = storage::NextDataObjectId::<Test>::get();
+        let actual_result =
+            Content::create_channel(origin, self.actor.clone(), self.params.clone());
+        let end_obj_id = storage::NextDataObjectId::<Test>::get();
+
+        assert_eq!(actual_result, expected_result);
+
+        let balance_post = Balances::usable_balance(self.sender);
+
+        if actual_result.is_ok() {
+            // ensure channel is on chain
+            assert_ok!(Content::ensure_channel_exists(&channel_id));
+
+            // channel counter increased
+            assert_eq!(
+                Content::next_channel_id(),
+                channel_id.saturating_add(One::one())
+            );
+
+            // dynamic bag for channel is created
+            assert_ok!(Storage::<Test>::ensure_bag_exists(&channel_bag_id));
+
+            // event correctly deposited
+            let owner = Content::actor_to_channel_owner(&self.actor).unwrap();
+            assert_eq!(
+                System::events().last().unwrap().event,
+                MetaEvent::content(RawEvent::ChannelCreated(
+                    self.actor.clone(),
+                    channel_id,
+                    ChannelRecord {
+                        owner: owner,
+                        is_censored: false,
+                        reward_account: self.params.reward_account.clone(),
+                        collaborators: self.params.collaborators.clone(),
+                        num_videos: Zero::zero(),
+                    },
+                    self.params.clone(),
+                ))
+            );
+
+            if let Some(assets) = self.params.assets.as_ref() {
+                // balance accounting is correct
+                let bag_deletion_prize = BalanceOf::<Test>::zero();
+                let objects_deletion_prize =
+                    assets
+                        .object_creation_list
+                        .iter()
+                        .fold(BalanceOf::<Test>::zero(), |acc, _| {
+                            acc.saturating_add(
+                                <Test as storage::Trait>::DataObjectDeletionPrize::get(),
+                            )
+                        });
+
+                assert_eq!(
+                    balance_pre.saturating_sub(balance_post),
+                    bag_deletion_prize.saturating_add(objects_deletion_prize),
+                );
+
+                assert!((beg_obj_id..end_obj_id).all(|id| {
+                    storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, id)
+                }));
+            }
+        } else {
+            assert_eq!(balance_post, balance_pre);
+            assert_eq!(beg_obj_id, end_obj_id);
+            assert!(!storage::Bags::<Test>::contains_key(&channel_bag_id));
+            assert!(!ChannelById::<Test>::contains_key(&channel_id));
+            assert_eq!(NextChannelId::<Test>::get(), channel_id);
+        }
+    }
+}
+
+pub struct CreateVideoFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    params: VideoCreationParameters<Test>,
+    channel_id: ChannelId,
+}
+
+impl CreateVideoFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ACCOUNT_ID),
+            params: VideoCreationParameters::<Test> {
+                assets: None,
+                meta: None,
+            },
+            channel_id: ChannelId::one(), // channel index starts at 1
+        }
+    }
+
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_channel_id(self, channel_id: ChannelId) -> Self {
+        Self { channel_id, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_assets(self, assets: StorageAssets<Test>) -> Self {
+        Self {
+            params: VideoCreationParameters::<Test> {
+                assets: Some(assets),
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let channel_bag_id = Content::bag_id_for_channel(&self.channel_id);
+        let video_id = Content::next_video_id();
+        let beg_obj_id = storage::NextDataObjectId::<Test>::get();
+
+        let actual_result = Content::create_video(
+            origin,
+            self.actor.clone(),
+            self.channel_id,
+            self.params.clone(),
+        );
+
+        let balance_post = Balances::usable_balance(self.sender);
+        let end_obj_id = storage::NextDataObjectId::<Test>::get();
+
+        assert_eq!(actual_result, expected_result);
+
+        if actual_result.is_ok() {
+            assert_ok!(Content::ensure_video_exists(&video_id));
+
+            assert_eq!(
+                Content::next_video_id(),
+                video_id.saturating_add(One::one())
+            );
+
+            assert_eq!(
+                System::events().last().unwrap().event,
+                MetaEvent::content(RawEvent::VideoCreated(
+                    self.actor,
+                    self.channel_id,
+                    video_id,
+                    self.params.clone(),
+                ))
+            );
+
+            if let Some(assets) = self.params.assets.as_ref() {
+                // balance accounting is correct
+                let bag_deletion_prize = BalanceOf::<Test>::zero();
+                let objects_deletion_prize =
+                    assets
+                        .object_creation_list
+                        .iter()
+                        .fold(BalanceOf::<Test>::zero(), |acc, _| {
+                            acc.saturating_add(
+                                <Test as storage::Trait>::DataObjectDeletionPrize::get(),
+                            )
+                        });
+
+                assert_eq!(
+                    balance_pre.saturating_sub(balance_post),
+                    bag_deletion_prize.saturating_add(objects_deletion_prize),
+                );
+
+                assert!((beg_obj_id..end_obj_id).all(|id| {
+                    storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, id)
+                }));
+            }
+        } else {
+            assert!(!VideoById::<Test>::contains_key(&video_id));
+
+            assert_eq!(Content::next_video_id(), video_id);
+
+            if self.params.assets.is_some() {
+                assert_eq!(balance_pre, balance_post,);
+
+                assert!(!(beg_obj_id..end_obj_id).any(|id| {
+                    storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, id)
+                }));
+            }
+        }
+    }
+}
+
+pub struct UpdateChannelFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    channel_id: ChannelId,
+    params: ChannelUpdateParameters<Test>,
+}
+
+impl UpdateChannelFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ACCOUNT_ID),
+            channel_id: ChannelId::one(), // channel index starts at 1
+            params: ChannelUpdateParameters::<Test> {
+                assets_to_upload: None,
+                new_meta: None,
+                reward_account: None,
+                assets_to_remove: BTreeSet::new(),
+                collaborators: None,
+            },
+        }
+    }
+
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_channel_id(self, channel_id: ChannelId) -> Self {
+        Self { channel_id, ..self }
+    }
+
+    pub fn with_assets_to_upload(self, assets: StorageAssets<Test>) -> Self {
+        Self {
+            params: ChannelUpdateParameters::<Test> {
+                assets_to_upload: Some(assets),
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn with_assets_to_remove(self, assets: BTreeSet<DataObjectId<Test>>) -> Self {
+        Self {
+            params: ChannelUpdateParameters::<Test> {
+                assets_to_remove: assets,
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn with_collaborators(self, collaborators: BTreeSet<MemberId>) -> Self {
+        Self {
+            params: ChannelUpdateParameters::<Test> {
+                collaborators: Some(collaborators),
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn with_reward_account(self, reward_account: Option<Option<AccountId>>) -> Self {
+        Self {
+            params: ChannelUpdateParameters::<Test> {
+                reward_account,
+                ..self.params
+            },
+            ..self
+        }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let channel_pre = Content::channel_by_id(&self.channel_id);
+        let bag_id_for_channel = Content::bag_id_for_channel(&self.channel_id);
+
+        let deletion_prize_deposited =
+            self.params
+                .assets_to_upload
+                .as_ref()
+                .map_or(BalanceOf::<Test>::zero(), |assets| {
+                    assets
+                        .object_creation_list
+                        .iter()
+                        .fold(BalanceOf::<Test>::zero(), |acc, _| {
+                            acc.saturating_add(
+                                <Test as storage::Trait>::DataObjectDeletionPrize::get(),
+                            )
+                        })
+                });
+
+        let deletion_prize_withdrawn = if !self.params.assets_to_remove.is_empty() {
+            self.params
+                .assets_to_remove
+                .iter()
+                .fold(BalanceOf::<Test>::zero(), |acc, id| {
+                    acc + storage::DataObjectsById::<Test>::get(&bag_id_for_channel, id)
+                        .deletion_prize
+                })
+        } else {
+            BalanceOf::<Test>::zero()
+        };
+
+        let beg_obj_id = storage::NextDataObjectId::<Test>::get();
+
+        let actual_result = Content::update_channel(
+            origin,
+            self.actor.clone(),
+            self.channel_id,
+            self.params.clone(),
+        );
+
+        let channel_post = Content::channel_by_id(&self.channel_id);
+        let end_obj_id = storage::NextDataObjectId::<Test>::get();
+        let balance_post = Balances::usable_balance(self.sender);
+
+        assert_eq!(actual_result, expected_result);
+
+        match actual_result {
+            Ok(()) => {
+                let owner = channel_post.owner.clone();
+                assert_eq!(
+                    System::events().last().unwrap().event,
+                    MetaEvent::content(RawEvent::ChannelUpdated(
+                        self.actor.clone(),
+                        self.channel_id,
+                        ChannelRecord {
+                            owner: owner,
+                            is_censored: channel_pre.is_censored,
+                            reward_account: self
+                                .params
+                                .reward_account
+                                .clone()
+                                .unwrap_or(channel_pre.reward_account),
+                            collaborators: self
+                                .params
+                                .collaborators
+                                .clone()
+                                .unwrap_or(channel_pre.collaborators),
+                            num_videos: channel_pre.num_videos,
+                        },
+                        self.params.clone(),
+                    ))
+                );
+
+                assert_eq!(
+                    balance_post.saturating_sub(balance_pre),
+                    deletion_prize_withdrawn.saturating_sub(deletion_prize_deposited),
+                );
+
+                if self.params.assets_to_upload.is_some() {
+                    assert!((beg_obj_id..end_obj_id).all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                    }));
+                }
+
+                assert!(!self.params.assets_to_remove.iter().any(|id| {
+                    storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                }));
+            }
+            Err(err) => {
+                assert_eq!(channel_pre, channel_post);
+                assert_eq!(balance_pre, balance_post);
+                assert_eq!(beg_obj_id, end_obj_id);
+
+                if err != storage::Error::<Test>::DataObjectDoesntExist.into() {
+                    assert!(self.params.assets_to_remove.iter().all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                    }))
+                }
+            }
+        }
+    }
+}
+
+pub struct UpdateVideoFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    video_id: VideoId,
+    params: VideoUpdateParameters<Test>,
+}
+
+impl UpdateVideoFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ID),
+            video_id: VideoId::one(),
+            params: VideoUpdateParameters::<Test> {
+                assets_to_upload: None,
+                assets_to_remove: BTreeSet::new(),
+                new_meta: None,
+            },
+        }
+    }
+
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_video_id(self, video_id: VideoId) -> Self {
+        Self { video_id, ..self }
+    }
+
+    pub fn with_assets_to_upload(self, assets: StorageAssets<Test>) -> Self {
+        Self {
+            params: VideoUpdateParameters::<Test> {
+                assets_to_upload: Some(assets),
+                ..self.params
+            },
+            ..self
+        }
+    }
+    pub fn with_assets_to_remove(self, assets: BTreeSet<DataObjectId<Test>>) -> Self {
+        Self {
+            params: VideoUpdateParameters::<Test> {
+                assets_to_remove: assets,
+                ..self.params
+            },
+            ..self
+        }
+    }
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let video_pre = Content::video_by_id(&self.video_id);
+        let bag_id_for_channel = Content::bag_id_for_channel(&video_pre.in_channel);
+        let beg_obj_id = storage::NextDataObjectId::<Test>::get();
+
+        let deletion_prize_deposited =
+            self.params
+                .assets_to_upload
+                .as_ref()
+                .map_or(BalanceOf::<Test>::zero(), |assets| {
+                    assets
+                        .object_creation_list
+                        .iter()
+                        .fold(BalanceOf::<Test>::zero(), |acc, _| {
+                            acc.saturating_add(
+                                <Test as storage::Trait>::DataObjectDeletionPrize::get(),
+                            )
+                        })
+                });
+
+        let deletion_prize_withdrawn = if !self.params.assets_to_remove.is_empty() {
+            self.params
+                .assets_to_remove
+                .iter()
+                .fold(BalanceOf::<Test>::zero(), |acc, obj_id| {
+                    acc + storage::DataObjectsById::<Test>::get(&bag_id_for_channel, obj_id)
+                        .deletion_prize
+                })
+        } else {
+            BalanceOf::<Test>::zero()
+        };
+
+        let actual_result = Content::update_video(
+            origin,
+            self.actor.clone(),
+            self.video_id,
+            self.params.clone(),
+        );
+
+        let end_obj_id = storage::NextDataObjectId::<Test>::get();
+        let balance_post = Balances::usable_balance(self.sender);
+        let video_post = Content::video_by_id(&self.video_id);
+
+        assert_eq!(actual_result, expected_result);
+
+        match actual_result {
+            Ok(()) => {
+                assert_eq!(
+                    System::events().last().unwrap().event,
+                    MetaEvent::content(RawEvent::VideoUpdated(
+                        self.actor.clone(),
+                        self.video_id,
+                        self.params.clone()
+                    ))
+                );
+
+                assert_eq!(
+                    balance_post.saturating_sub(balance_pre),
+                    deletion_prize_withdrawn.saturating_sub(deletion_prize_deposited),
+                );
+
+                if self.params.assets_to_upload.is_some() {
+                    assert!((beg_obj_id..end_obj_id).all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                    }));
+                }
+
+                assert!(!self.params.assets_to_remove.iter().any(|obj_id| {
+                    storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, obj_id)
+                }));
+            }
+            Err(err) => {
+                assert_eq!(video_pre, video_post);
+                assert_eq!(balance_pre, balance_post);
+                assert_eq!(beg_obj_id, end_obj_id);
+
+                if err != storage::Error::<Test>::DataObjectDoesntExist.into() {
+                    assert!(self.params.assets_to_remove.iter().all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                    }));
+                }
+            }
+        }
+    }
+}
+
+pub struct DeleteChannelFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    channel_id: ChannelId,
+    num_objects_to_delete: u64,
+}
+
+impl DeleteChannelFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ID),
+            channel_id: ChannelId::one(),
+            num_objects_to_delete: DATA_OBJECTS_NUMBER as u64,
+        }
+    }
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_num_objects_to_delete(self, num_objects_to_delete: u64) -> Self {
+        Self {
+            num_objects_to_delete,
+            ..self
+        }
+    }
+
+    pub fn with_channel_id(self, channel_id: ChannelId) -> Self {
+        Self { channel_id, ..self }
+    }
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let bag_id_for_channel = Content::bag_id_for_channel(&self.channel_id);
+        let bag_deletion_prize = storage::Bags::<Test>::get(&bag_id_for_channel)
+            .deletion_prize
+            .unwrap_or(BalanceOf::<Test>::zero());
+        let objects_deletion_prize =
+            storage::DataObjectsById::<Test>::iter_prefix(&bag_id_for_channel)
+                .fold(BalanceOf::<Test>::zero(), |acc, (_, obj)| {
+                    acc + obj.deletion_prize
+                });
+
+        let channel_objects_ids =
+            storage::DataObjectsById::<Test>::iter_prefix(&bag_id_for_channel)
+                .map(|(id, _)| id)
+                .collect::<BTreeSet<_>>();
+
+        let actual_result = Content::delete_channel(
+            origin,
+            self.actor.clone(),
+            self.channel_id,
+            self.num_objects_to_delete,
+        );
+
+        let balance_post = Balances::usable_balance(self.sender);
+        assert_eq!(actual_result, expected_result);
+
+        match actual_result {
+            Ok(()) => {
+                assert_eq!(
+                    System::events().last().unwrap().event,
+                    MetaEvent::content(RawEvent::ChannelDeleted(
+                        self.actor.clone(),
+                        self.channel_id,
+                    ))
+                );
+
+                let deletion_prize = bag_deletion_prize.saturating_add(objects_deletion_prize);
+
+                assert_eq!(balance_post.saturating_sub(balance_pre), deletion_prize,);
+                assert!(!<ChannelById<Test>>::contains_key(&self.channel_id));
+                assert!(!channel_objects_ids.iter().any(|id| {
+                    storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                }));
+                assert!(!storage::Bags::<Test>::contains_key(&bag_id_for_channel));
+            }
+
+            Err(err) => {
+                assert_eq!(balance_pre, balance_post);
+                if err != Error::<Test>::ChannelDoesNotExist.into() {
+                    assert!(ChannelById::<Test>::contains_key(&self.channel_id));
+                    assert!(channel_objects_ids.iter().all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&bag_id_for_channel, id)
+                    }));
+                    assert!(storage::Bags::<Test>::contains_key(&bag_id_for_channel));
+                }
+            }
+        }
+    }
+}
+
+pub struct DeleteVideoFixture {
+    sender: AccountId,
+    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
+    video_id: VideoId,
+    assets_to_remove: BTreeSet<DataObjectId<Test>>,
+}
+
+impl DeleteVideoFixture {
+    pub fn default() -> Self {
+        Self {
+            sender: DEFAULT_MEMBER_ACCOUNT_ID,
+            actor: ContentActor::Member(DEFAULT_MEMBER_ID),
+            video_id: VideoId::one(),
+            assets_to_remove: BTreeSet::new(),
+        }
+    }
+
+    pub fn with_sender(self, sender: AccountId) -> Self {
+        Self { sender, ..self }
+    }
+
+    pub fn with_actor(self, actor: ContentActor<CuratorGroupId, CuratorId, MemberId>) -> Self {
+        Self { actor, ..self }
+    }
+
+    pub fn with_assets_to_remove(self, assets_to_remove: BTreeSet<DataObjectId<Test>>) -> Self {
+        Self {
+            assets_to_remove,
+            ..self
+        }
+    }
+
+    pub fn with_video_id(self, video_id: VideoId) -> Self {
+        Self { video_id, ..self }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let origin = Origin::signed(self.sender.clone());
+        let balance_pre = Balances::usable_balance(self.sender);
+        let video_pre = <VideoById<Test>>::get(&self.video_id);
+        let channel_bag_id = Content::bag_id_for_channel(&video_pre.in_channel);
+        let deletion_prize =
+            self.assets_to_remove
+                .iter()
+                .fold(BalanceOf::<Test>::zero(), |acc, obj_id| {
+                    acc + storage::DataObjectsById::<Test>::get(&channel_bag_id, obj_id)
+                        .deletion_prize
+                });
+
+        let actual_result = Content::delete_video(
+            origin,
+            self.actor.clone(),
+            self.video_id,
+            self.assets_to_remove.clone(),
+        );
+
+        let balance_post = Balances::usable_balance(self.sender);
+
+        assert_eq!(actual_result, expected_result);
+
+        match actual_result {
+            Ok(()) => {
+                assert_eq!(
+                    System::events().last().unwrap().event,
+                    MetaEvent::content(RawEvent::VideoDeleted(self.actor.clone(), self.video_id,))
+                );
+
+                assert_eq!(balance_post.saturating_sub(balance_pre), deletion_prize);
+
+                assert!(!self.assets_to_remove.iter().any(|obj_id| {
+                    storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, obj_id)
+                }));
+
+                assert!(!<VideoById<Test>>::contains_key(&self.video_id));
+            }
+            Err(err) => {
+                assert_eq!(balance_pre, balance_post);
+
+                if err == storage::Error::<Test>::DataObjectDoesntExist.into() {
+                    let video_post = <VideoById<Test>>::get(&self.video_id);
+                    assert_eq!(video_pre, video_post);
+                    assert!(VideoById::<Test>::contains_key(&self.video_id));
+                } else if err == Error::<Test>::VideoDoesNotExist.into() {
+                    assert!(self.assets_to_remove.iter().all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, id)
+                    }));
+                } else {
+                    let video_post = <VideoById<Test>>::get(&self.video_id);
+                    assert_eq!(video_pre, video_post);
+                    assert!(VideoById::<Test>::contains_key(&self.video_id));
+                    assert!(self.assets_to_remove.iter().all(|id| {
+                        storage::DataObjectsById::<Test>::contains_key(&channel_bag_id, id)
+                    }));
+                }
+            }
+        }
+    }
+}
+
+// helper functions
+pub fn increase_account_balance_helper(account_id: u64, balance: u64) {
+    let _ = Balances::deposit_creating(&account_id, balance);
+}
+
+pub fn slash_account_balance_helper(account_id: u64) {
+    let _ = Balances::slash(&account_id, Balances::total_balance(&account_id));
+}
+
+pub fn create_data_object_candidates_helper(
+    starting_ipfs_index: u8,
+    number: u8,
+) -> Vec<DataObjectCreationParameters> {
+    let range = starting_ipfs_index..(starting_ipfs_index + number);
+
+    range
+        .into_iter()
+        .map(|idx| DataObjectCreationParameters {
+            size: 10 * idx as u64,
+            ipfs_content_id: vec![idx],
+        })
+        .collect()
+}
+
+pub fn create_data_objects_helper() -> Vec<DataObjectCreationParameters> {
+    create_data_object_candidates_helper(1, DATA_OBJECTS_NUMBER)
+}
+
+pub fn create_initial_storage_buckets_helper() {
+    // first set limits
+    assert_eq!(
+        Storage::<Test>::update_storage_buckets_voucher_max_limits(
+            Origin::signed(STORAGE_WG_LEADER_ACCOUNT_ID),
+            VOUCHER_OBJECTS_SIZE_LIMIT,
+            VOUCHER_OBJECTS_NUMBER_LIMIT,
+        ),
+        Ok(())
+    );
+
+    // create bucket(s)
+    assert_eq!(
+        Storage::<Test>::create_storage_bucket(
+            Origin::signed(STORAGE_WG_LEADER_ACCOUNT_ID),
+            None,
+            STORAGE_BUCKET_ACCEPTING_BAGS,
+            STORAGE_BUCKET_OBJECTS_SIZE_LIMIT,
+            STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT,
+        ),
+        Ok(())
+    );
+}
+
+pub fn create_default_member_owned_channel() {
+    CreateChannelFixture::default()
+        .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+        .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+        .with_assets(StorageAssets::<Test> {
+            expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+            object_creation_list: create_data_objects_helper(),
+        })
+        .with_reward_account(DEFAULT_MEMBER_ACCOUNT_ID)
+        .with_collaborators(vec![COLLABORATOR_MEMBER_ID].into_iter().collect())
+        .call_and_assert(Ok(()));
+}
+
+pub fn create_default_curator_owned_channel() {
+    let curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+    CreateChannelFixture::default()
+        .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+        .with_actor(ContentActor::Curator(curator_group_id, DEFAULT_CURATOR_ID))
+        .with_assets(StorageAssets::<Test> {
+            expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+            object_creation_list: create_data_objects_helper(),
+        })
+        .with_reward_account(DEFAULT_CURATOR_ACCOUNT_ID)
+        .with_collaborators(vec![COLLABORATOR_MEMBER_ID].into_iter().collect())
+        .call_and_assert(Ok(()));
+}
+
+pub fn create_default_member_owned_channel_with_video() {
+    create_default_member_owned_channel();
+    CreateVideoFixture::default()
+        .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+        .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+        .with_assets(StorageAssets::<Test> {
+            expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+            object_creation_list: create_data_objects_helper(),
+        })
+        .with_channel_id(NextChannelId::<Test>::get() - 1)
+        .call_and_assert(Ok(()));
+}
+
+pub fn create_default_curator_owned_channel_with_video() {
+    create_default_curator_owned_channel();
+    let curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+
+    CreateVideoFixture::default()
+        .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+        .with_actor(ContentActor::Curator(curator_group_id, DEFAULT_CURATOR_ID))
+        .with_assets(StorageAssets::<Test> {
+            expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+            object_creation_list: create_data_objects_helper(),
+        })
+        .with_channel_id(NextChannelId::<Test>::get() - 1)
+        .call_and_assert(Ok(()));
+}

+ 65 - 318
runtime-modules/content/src/tests/mock.rs

@@ -2,7 +2,7 @@
 
 use crate::*;
 use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, OnFinalize, OnInitialize};
+use frame_support::traits::{OnFinalize, OnInitialize};
 use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
 use sp_core::H256;
 use sp_runtime::{
@@ -20,39 +20,29 @@ pub type CuratorGroupId = <Test as ContentActorAuthenticator>::CuratorGroupId;
 pub type MemberId = <Test as MembershipTypes>::MemberId;
 pub type ChannelId = <Test as StorageOwnership>::ChannelId;
 
-/// Origins
-
-pub const LEAD_ORIGIN: u64 = 1;
-
-pub const FIRST_CURATOR_ORIGIN: u64 = 2;
-pub const SECOND_CURATOR_ORIGIN: u64 = 3;
-
-pub const FIRST_MEMBER_ORIGIN: u64 = 4;
-pub const SECOND_MEMBER_ORIGIN: u64 = 5;
-pub const UNKNOWN_ORIGIN: u64 = 7777;
-pub const UNKNOWN_MEMBER_ID: u64 = 7777;
+/// Accounts
+pub const DEFAULT_MEMBER_ACCOUNT_ID: u64 = 101;
+pub const DEFAULT_CURATOR_ACCOUNT_ID: u64 = 102;
+pub const LEAD_ACCOUNT_ID: u64 = 103;
+pub const COLLABORATOR_MEMBER_ACCOUNT_ID: u64 = 104;
+pub const UNAUTHORIZED_MEMBER_ACCOUNT_ID: u64 = 105;
+pub const UNAUTHORIZED_CURATOR_ACCOUNT_ID: u64 = 106;
+pub const UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID: u64 = 107;
+pub const UNAUTHORIZED_LEAD_ACCOUNT_ID: u64 = 108;
 
 // Members range from MemberId 1 to 10
 pub const MEMBERS_COUNT: MemberId = 10;
 
 /// Runtime Id's
+pub const DEFAULT_MEMBER_ID: MemberId = 201;
+pub const DEFAULT_CURATOR_ID: CuratorId = 202;
+pub const COLLABORATOR_MEMBER_ID: u64 = 204;
+pub const UNAUTHORIZED_MEMBER_ID: u64 = 205;
+pub const UNAUTHORIZED_CURATOR_ID: u64 = 206;
+pub const UNAUTHORIZED_COLLABORATOR_MEMBER_ID: u64 = 207;
 
-pub const FIRST_CURATOR_ID: CuratorId = 1;
-pub const SECOND_CURATOR_ID: CuratorId = 2;
-
-pub const FIRST_CURATOR_GROUP_ID: CuratorGroupId = 1;
-// pub const SECOND_CURATOR_GROUP_ID: CuratorGroupId = 2;
-
-pub const FIRST_MEMBER_ID: MemberId = 1;
-pub const SECOND_MEMBER_ID: MemberId = 2;
-
-// members that act as collaborators
-pub const COLLABORATOR_MEMBER_ORIGIN: MemberId = 8;
-pub const COLLABORATOR_MEMBER_ID: MemberId = 9;
-
-/// Constants
 // initial balancer for an account
-pub const INITIAL_BALANCE: u32 = 1_000_000;
+pub const INITIAL_BALANCE: u64 = 1000;
 
 impl_outer_origin! {
     pub enum Origin for Test {}
@@ -171,29 +161,65 @@ impl ContentActorAuthenticator for Test {
     type CuratorGroupId = u64;
 
     fn validate_member_id(member_id: &Self::MemberId) -> bool {
-        *member_id < MEMBERS_COUNT
+        match *member_id {
+            DEFAULT_MEMBER_ID => true,
+            UNAUTHORIZED_MEMBER_ID => true,
+            COLLABORATOR_MEMBER_ID => true,
+            UNAUTHORIZED_COLLABORATOR_MEMBER_ID => true,
+            _ => false,
+        }
     }
 
     fn is_lead(account_id: &Self::AccountId) -> bool {
-        let lead_account_id = ensure_signed(Origin::signed(LEAD_ORIGIN)).unwrap();
-        *account_id == lead_account_id
+        *account_id == ensure_signed(Origin::signed(LEAD_ACCOUNT_ID)).unwrap()
     }
 
     fn is_curator(curator_id: &Self::CuratorId, account_id: &Self::AccountId) -> bool {
-        let first_curator_account_id = ensure_signed(Origin::signed(FIRST_CURATOR_ORIGIN)).unwrap();
-        let second_curator_account_id =
-            ensure_signed(Origin::signed(SECOND_CURATOR_ORIGIN)).unwrap();
-        (first_curator_account_id == *account_id && FIRST_CURATOR_ID == *curator_id)
-            || (second_curator_account_id == *account_id && SECOND_CURATOR_ID == *curator_id)
+        match *curator_id {
+            DEFAULT_CURATOR_ID => {
+                *account_id == ensure_signed(Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID)).unwrap()
+            }
+
+            UNAUTHORIZED_CURATOR_ID => {
+                *account_id
+                    == ensure_signed(Origin::signed(UNAUTHORIZED_CURATOR_ACCOUNT_ID)).unwrap()
+            }
+
+            _ => false,
+        }
     }
 
     fn is_member(member_id: &Self::MemberId, account_id: &Self::AccountId) -> bool {
-        let unknown_member_account_id = ensure_signed(Origin::signed(UNKNOWN_ORIGIN)).unwrap();
-        *member_id < MEMBERS_COUNT && unknown_member_account_id != *account_id
+        match *member_id {
+            DEFAULT_MEMBER_ID => {
+                *account_id == ensure_signed(Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID)).unwrap()
+            }
+
+            UNAUTHORIZED_MEMBER_ID => {
+                *account_id
+                    == ensure_signed(Origin::signed(UNAUTHORIZED_MEMBER_ACCOUNT_ID)).unwrap()
+            }
+
+            UNAUTHORIZED_COLLABORATOR_MEMBER_ID => {
+                *account_id
+                    == ensure_signed(Origin::signed(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID))
+                        .unwrap()
+            }
+
+            COLLABORATOR_MEMBER_ID => {
+                *account_id
+                    == ensure_signed(Origin::signed(COLLABORATOR_MEMBER_ACCOUNT_ID)).unwrap()
+            }
+            _ => false,
+        }
     }
 
     fn is_valid_curator_id(curator_id: &Self::CuratorId) -> bool {
-        *curator_id == FIRST_CURATOR_ID || *curator_id == SECOND_CURATOR_ID
+        match *curator_id {
+            DEFAULT_CURATOR_ID => true,
+            UNAUTHORIZED_CURATOR_ID => true,
+            _ => false,
+        }
     }
 }
 
@@ -315,9 +341,6 @@ impl storage::Trait for Test {
     }
 }
 
-pub const DEFAULT_MEMBER_ID: u64 = 100;
-pub const DEFAULT_MEMBER_ACCOUNT_ID: u64 = 101;
-
 impl common::origin::ActorOriginValidator<Origin, u64, u64> for () {
     fn ensure_actor_origin(origin: Origin, member_id: u64) -> Result<u64, &'static str> {
         let signed_account_id = frame_system::ensure_signed(origin)?;
@@ -443,280 +466,4 @@ pub fn run_to_block(n: u64) {
 
 pub type CollectiveFlip = randomness_collective_flip::Module<Test>;
 
-pub fn create_channel_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    params: ChannelCreationParameters<Test>,
-    result: DispatchResult,
-) {
-    let channel_id = Content::next_channel_id();
-
-    assert_eq!(
-        Content::create_channel(Origin::signed(sender), actor.clone(), params.clone()),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        let owner = Content::actor_to_channel_owner(&actor).unwrap();
-
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelCreated(
-                actor.clone(),
-                channel_id,
-                ChannelRecord {
-                    owner: owner,
-                    is_censored: false,
-                    reward_account: params.reward_account.clone(),
-
-                    collaborators: params.collaborators.clone(),
-                    num_videos: 0,
-                },
-                params,
-            ))
-        );
-    }
-}
-
-pub fn update_channel_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    channel_id: ChannelId,
-    params: ChannelUpdateParameters<Test>,
-    result: DispatchResult,
-) {
-    let channel_pre = ChannelById::<Test>::get(channel_id.clone());
-
-    assert_eq!(
-        Content::update_channel(
-            Origin::signed(sender),
-            actor.clone(),
-            channel_id.clone(),
-            params.clone(),
-        ),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelUpdated(
-                actor.clone(),
-                channel_id,
-                ChannelRecord {
-                    owner: channel_pre.owner.clone(),
-                    is_censored: channel_pre.is_censored,
-                    reward_account: params
-                        .reward_account
-                        .map_or_else(|| channel_pre.reward_account.clone(), |account| account),
-                    collaborators: params
-                        .collaborators
-                        .clone()
-                        .unwrap_or(channel_pre.collaborators),
-                    num_videos: channel_pre.num_videos,
-                },
-                params,
-            ))
-        );
-    }
-}
-
-pub fn delete_channel_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    channel_id: ChannelId,
-    objects_num: u64,
-    result: DispatchResult,
-) {
-    assert_eq!(
-        Content::delete_channel(
-            Origin::signed(sender),
-            actor.clone(),
-            channel_id.clone(),
-            objects_num,
-        ),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::ChannelDeleted(actor.clone(), channel_id))
-        )
-    }
-}
-
-pub fn create_video_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    channel_id: ChannelId,
-    params: VideoCreationParameters<Test>,
-    result: DispatchResult,
-) {
-    let video_id = Content::next_video_id();
-    let num_videos_pre = Content::channel_by_id(channel_id).num_videos;
-
-    assert_eq!(
-        Content::create_video(
-            Origin::signed(sender),
-            actor.clone(),
-            channel_id.clone(),
-            params.clone()
-        ),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoCreated(
-                actor.clone(),
-                channel_id,
-                video_id,
-                params.clone(),
-            ))
-        );
-        assert_eq!(
-            num_videos_pre + 1,
-            Content::channel_by_id(channel_id).num_videos,
-        );
-    }
-}
-pub fn update_video_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    video_id: <Test as Trait>::VideoId,
-    params: VideoUpdateParameters<Test>,
-    result: DispatchResult,
-) {
-    // let channel_id = Content::video_by_id(video_id.clone()).in_channel;
-    // let num_videos_pre = Content::channel_by_id(channel_id).num_videos;
-
-    assert_eq!(
-        Content::update_video(
-            Origin::signed(sender),
-            actor.clone(),
-            video_id.clone(),
-            params.clone(),
-        ),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoUpdated(
-                actor.clone(),
-                video_id,
-                params.clone(),
-            ))
-        );
-    }
-}
-
-pub fn delete_video_mock(
-    sender: u64,
-    actor: ContentActor<CuratorGroupId, CuratorId, MemberId>,
-    video_id: <Test as Trait>::VideoId,
-    assets_to_remove: BTreeSet<DataObjectId<Test>>,
-    result: DispatchResult,
-) {
-    assert_eq!(
-        Content::delete_video(
-            Origin::signed(sender),
-            actor.clone(),
-            video_id.clone(),
-            assets_to_remove.clone(),
-        ),
-        result.clone(),
-    );
-
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoDeleted(actor.clone(), video_id))
-        );
-    }
-}
-
-// helper functions
-pub fn helper_generate_storage_assets(sizes: Vec<u64>) -> StorageAssets<Test> {
-    StorageAssetsRecord {
-        object_creation_list: sizes
-            .into_iter()
-            .map(|s| DataObjectCreationParameters {
-                size: s,
-                ipfs_content_id: s.encode(),
-            })
-            .collect::<Vec<_>>(),
-        expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-    }
-}
-
-pub fn helper_init_accounts(accounts: Vec<u64>) {
-    // give channel owner funds to permit collaborators to update assets
-    for acc in accounts.iter() {
-        let _ = balances::Module::<Test>::deposit_creating(
-            acc,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-    }
-}
-
-pub fn create_initial_storage_buckets() {
-    // first set limits
-    assert_eq!(
-        Storage::<Test>::update_storage_buckets_voucher_max_limits(
-            Origin::signed(STORAGE_WG_LEADER_ACCOUNT_ID),
-            400,
-            40
-        ),
-        Ok(())
-    );
-
-    // create bucket(s)
-    assert_eq!(
-        Storage::<Test>::create_storage_bucket(
-            Origin::signed(STORAGE_WG_LEADER_ACCOUNT_ID),
-            None,
-            true,
-            100,
-            10,
-        ),
-        Ok(())
-    );
-}
-
-pub fn create_channel_with_bag() {
-    // 3 assets added at creation
-    let assets = StorageAssetsRecord {
-        object_creation_list: vec![
-            DataObjectCreationParameters {
-                size: 3,
-                ipfs_content_id: b"first".to_vec(),
-            },
-            DataObjectCreationParameters {
-                size: 3,
-                ipfs_content_id: b"second".to_vec(),
-            },
-            DataObjectCreationParameters {
-                size: 3,
-                ipfs_content_id: b"third".to_vec(),
-            },
-        ],
-        expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-    };
-
-    // create channel
-    create_channel_mock(
-        FIRST_MEMBER_ORIGIN,
-        ContentActor::Member(FIRST_MEMBER_ID),
-        ChannelCreationParametersRecord {
-            assets: Some(assets),
-            meta: None,
-            reward_account: None,
-            collaborators: BTreeSet::new(),
-        },
-        Ok(()),
-    );
-}
+pub type Balances = balances::Module<Test>;

+ 1 - 0
runtime-modules/content/src/tests/mod.rs

@@ -2,5 +2,6 @@
 
 mod channels;
 mod curators;
+mod fixtures;
 mod mock;
 mod videos;

+ 975 - 504
runtime-modules/content/src/tests/videos.rs

@@ -1,294 +1,26 @@
 #![cfg(test)]
 use super::curators;
+use super::fixtures::*;
 use super::mock::*;
 use crate::*;
-use frame_support::traits::Currency;
 use frame_support::{assert_err, assert_ok};
 
-fn create_member_channel() -> ChannelId {
-    let channel_id = Content::next_channel_id();
-
-    // Member can create the channel
-    assert_ok!(Content::create_channel(
-        Origin::signed(FIRST_MEMBER_ORIGIN),
-        ContentActor::Member(FIRST_MEMBER_ID),
-        ChannelCreationParametersRecord {
-            assets: None,
-            meta: None,
-            reward_account: None,
-            collaborators: BTreeSet::<MemberId>::new(),
-        }
-    ));
-
-    channel_id
-}
-
-#[test]
-fn video_creation_successful() {
-    with_default_mock_builder(|| {
-        run_to_block(1);
-
-        create_initial_storage_buckets();
-
-        // depositi initial balance
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        let channel_id = NextChannelId::<Test>::get();
-
-        create_initial_storage_buckets();
-
-        create_channel_with_bag();
-
-        let params = VideoCreationParametersRecord {
-            assets: Some(StorageAssetsRecord {
-                object_creation_list: vec![
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"first".to_vec(),
-                    },
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"second".to_vec(),
-                    },
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"third".to_vec(),
-                    },
-                ],
-                expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-            }),
-            meta: Some(b"test".to_vec()),
-        };
-
-        create_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            params,
-            Ok(()),
-        )
-    })
-}
-
-#[test]
-fn video_update_successful() {
-    with_default_mock_builder(|| {
-        run_to_block(1);
-
-        create_initial_storage_buckets();
-        let _ = balances::Module::<Test>::deposit_creating(
-            &FIRST_MEMBER_ORIGIN,
-            <Test as balances::Trait>::Balance::from(INITIAL_BALANCE),
-        );
-
-        let channel_id = NextChannelId::<Test>::get();
-
-        create_channel_with_bag();
-
-        // create video with 3 assets
-        let params = VideoCreationParametersRecord {
-            assets: Some(StorageAssetsRecord {
-                object_creation_list: vec![
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"first".to_vec(),
-                    },
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"second".to_vec(),
-                    },
-                    DataObjectCreationParameters {
-                        size: 3,
-                        ipfs_content_id: b"third".to_vec(),
-                    },
-                ],
-                expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-            }),
-            meta: Some(b"test".to_vec()),
-        };
-
-        let video_id = Content::next_video_id();
-
-        let first_obj_id = Storage::<Test>::next_data_object_id();
-
-        create_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            params,
-            Ok(()),
-        );
-
-        // add 1 asset
-        let update_params = VideoUpdateParametersRecord {
-            assets_to_upload: Some(StorageAssetsRecord {
-                object_creation_list: vec![DataObjectCreationParameters {
-                    size: 3,
-                    ipfs_content_id: b"first".to_vec(),
-                }],
-                expected_data_size_fee: storage::DataObjectPerMegabyteFee::<Test>::get(),
-            }),
-            new_meta: None,
-            assets_to_remove: BTreeSet::new(),
-        };
-
-        let last_obj_id = Storage::<Test>::next_data_object_id();
-
-        update_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            video_id,
-            update_params,
-            Ok(()),
-        );
-
-        // remove all assets from the channel the video is in
-        update_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            video_id,
-            VideoUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                assets_to_remove: (first_obj_id..last_obj_id).collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
-    })
-}
-
 #[test]
-fn member_can_create_videos() {
+fn curators_can_censor_videos() {
     with_default_mock_builder(|| {
         // Run to block one to see emitted events
         run_to_block(1);
-        let channel_id = create_member_channel();
-
-        let video_id = Content::next_video_id();
-        assert_ok!(Content::create_video(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
-            channel_id,
-            VideoCreationParametersRecord {
-                assets: None,
-                meta: None,
-            }
-        ));
-
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoCreated(
-                ContentActor::Member(FIRST_MEMBER_ID),
-                channel_id,
-                video_id,
-                VideoCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                }
-            ))
-        );
-
-        // Video is created in correct channel
-        let video = Content::video_by_id(video_id);
-        assert_eq!(channel_id, video.in_channel);
-
-        // Can update own video
-        assert_ok!(Content::update_video(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
-            video_id,
-            VideoUpdateParametersRecord {
-                assets_to_upload: None,
-                new_meta: None,
-                assets_to_remove: BTreeSet::new(),
-            },
-        ));
 
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoUpdated(
-                ContentActor::Member(FIRST_MEMBER_ID),
-                video_id,
-                VideoUpdateParametersRecord {
-                    assets_to_upload: None,
-                    new_meta: None,
-                    assets_to_remove: BTreeSet::new(),
-                }
-            ))
-        );
-
-        // Member cannot create video in a channel they do not own
-        assert_err!(
-            Content::create_video(
-                Origin::signed(SECOND_MEMBER_ORIGIN),
-                ContentActor::Member(SECOND_MEMBER_ID),
-                channel_id,
-                VideoCreationParametersRecord {
-                    assets: None,
-                    meta: None,
-                }
-            ),
-            Error::<Test>::ActorNotAuthorized
-        );
-
-        // Member cannot update video in a channel they do not own
-        assert_err!(
-            Content::update_video(
-                Origin::signed(SECOND_MEMBER_ORIGIN),
-                ContentActor::Member(SECOND_MEMBER_ID),
-                video_id,
-                VideoUpdateParametersRecord {
-                    assets_to_upload: None,
-                    new_meta: None,
-                    assets_to_remove: BTreeSet::new(),
-                },
-            ),
-            Error::<Test>::ActorNotAuthorized
-        );
-
-        // Member cannot delete video in a channel they do not own
-        assert_err!(
-            Content::delete_video(
-                Origin::signed(SECOND_MEMBER_ORIGIN),
-                ContentActor::Member(SECOND_MEMBER_ID),
-                video_id,
-                BTreeSet::new(),
-            ),
-            Error::<Test>::ActorNotAuthorized
-        );
-
-        // Owner can delete their video
-        assert_ok!(Content::delete_video(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
-            video_id,
-            BTreeSet::new(),
-        ));
-
-        assert_eq!(
-            System::events().last().unwrap().event,
-            MetaEvent::content(RawEvent::VideoDeleted(
-                ContentActor::Member(FIRST_MEMBER_ID),
-                video_id
-            ))
-        );
-    })
-}
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-#[test]
-fn curators_can_censor_videos() {
-    with_default_mock_builder(|| {
-        // Run to block one to see emitted events
-        run_to_block(1);
-        let channel_id = create_member_channel();
+        let channel_id = NextChannelId::<Test>::get() - 1;
 
         let video_id = Content::next_video_id();
         assert_ok!(Content::create_video(
-            Origin::signed(FIRST_MEMBER_ORIGIN),
-            ContentActor::Member(FIRST_MEMBER_ID),
+            Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
+            ContentActor::Member(DEFAULT_MEMBER_ID),
             channel_id,
             VideoCreationParametersRecord {
                 assets: None,
@@ -296,13 +28,13 @@ fn curators_can_censor_videos() {
             }
         ));
 
-        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
+        let group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
 
         // Curator can censor videos
         let is_censored = true;
         assert_ok!(Content::update_video_censorship_status(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+            ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
             video_id,
             is_censored,
             vec![]
@@ -311,7 +43,7 @@ fn curators_can_censor_videos() {
         assert_eq!(
             System::events().last().unwrap().event,
             MetaEvent::content(RawEvent::VideoCensorshipStatusUpdated(
-                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
                 video_id,
                 is_censored,
                 vec![]
@@ -325,8 +57,8 @@ fn curators_can_censor_videos() {
         // Curator can un-censor videos
         let is_censored = false;
         assert_ok!(Content::update_video_censorship_status(
-            Origin::signed(FIRST_CURATOR_ORIGIN),
-            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
+            ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
             video_id,
             is_censored,
             vec![]
@@ -335,7 +67,7 @@ fn curators_can_censor_videos() {
         assert_eq!(
             System::events().last().unwrap().event,
             MetaEvent::content(RawEvent::VideoCensorshipStatusUpdated(
-                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                ContentActor::Curator(group_id, DEFAULT_CURATOR_ID),
                 video_id,
                 is_censored,
                 vec![]
@@ -349,8 +81,8 @@ fn curators_can_censor_videos() {
         // Members cannot censor videos
         assert_err!(
             Content::update_video_censorship_status(
-                Origin::signed(FIRST_MEMBER_ORIGIN),
-                ContentActor::Member(FIRST_MEMBER_ORIGIN),
+                Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
+                ContentActor::Member(DEFAULT_MEMBER_ACCOUNT_ID),
                 channel_id,
                 true,
                 vec![]
@@ -368,7 +100,7 @@ fn featured_videos() {
 
         // Lead can update curator owned channels
         assert_ok!(Content::set_featured_videos(
-            Origin::signed(LEAD_ORIGIN),
+            Origin::signed(LEAD_ACCOUNT_ID),
             ContentActor::Lead,
             vec![1, 2, 3]
         ));
@@ -383,8 +115,8 @@ fn featured_videos() {
 
         assert_err!(
             Content::set_featured_videos(
-                Origin::signed(FIRST_MEMBER_ORIGIN),
-                ContentActor::Member(FIRST_MEMBER_ID),
+                Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
+                ContentActor::Member(DEFAULT_MEMBER_ID),
                 vec![1, 2, 3]
             ),
             Error::<Test>::ActorNotAuthorized
@@ -393,277 +125,1016 @@ fn featured_videos() {
 }
 
 #[test]
-fn non_authorized_collaborators_cannot_add_video() {
+fn successful_video_creation_by_member() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        create_initial_storage_buckets();
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+#[test]
+fn successful_video_creation_by_collaborator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(COLLABORATOR_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
 
-        create_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Err(Error::<Test>::ActorNotAuthorized.into()),
-        );
+#[test]
+fn successful_video_creation_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);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
     })
 }
 
 #[test]
-fn non_authorized_collaborators_cannot_update_video() {
+fn successful_video_creation_by_curator() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        create_initial_storage_buckets();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
 
-        // create video
-        create_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_with_member_auth_failure() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        update_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as Trait>::VideoId::one(),
-            VideoUpdateParametersRecord {
-                assets_to_upload: Some(helper_generate_storage_assets(vec![5])),
-                new_meta: None,
-                assets_to_remove: vec![DataObjectId::<Test>::one()]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Err(Error::<Test>::ActorNotAuthorized.into()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
     })
 }
 
 #[test]
-fn non_authorized_collaborators_cannot_delete_video() {
+fn successful_video_creation_with_collaborator_auth_failure() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
 
-        create_initial_storage_buckets();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: BTreeSet::new(),
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_with_lead_auth_failure() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // create video
-        create_video_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        delete_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as Trait>::VideoId::one(),
-            vec![
-                DataObjectId::<Test>::one(),
-                DataObjectId::<Test>::from(2u64),
-            ]
-            .into_iter()
-            .collect::<BTreeSet<_>>(),
-            Err(Error::<Test>::ActorNotAuthorized.into()),
-        );
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
     })
 }
 
 #[test]
-fn authorized_collaborators_can_add_video() {
+fn unsuccessful_video_creation_with_curator_auth_failure() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
 
-        create_initial_storage_buckets();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: vec![COLLABORATOR_MEMBER_ID]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        CreateVideoFixture::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()));
+    })
+}
 
-        create_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_with_unauth_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();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(UNAUTHORIZED_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
     })
 }
 
 #[test]
-fn authorized_collaborators_can_update_video() {
+fn successful_video_creation_with_unauth_collaborator() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        create_initial_storage_buckets();
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(
+                UNAUTHORIZED_COLLABORATOR_MEMBER_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
 
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: vec![COLLABORATOR_MEMBER_ID]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_with_unauth_curator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        // create video
-        create_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        CreateVideoFixture::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()));
+    })
+}
 
-        update_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as Trait>::VideoId::one(),
-            VideoUpdateParametersRecord {
-                assets_to_upload: Some(helper_generate_storage_assets(vec![5])),
-                new_meta: None,
-                assets_to_remove: vec![DataObjectId::<Test>::one()]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_by_lead_with_member_owned_channel() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
     })
 }
 
 #[test]
-fn authorized_collaborators_can_delete_video() {
+fn unsuccessful_video_creation_with_invalid_channel_id() {
     with_default_mock_builder(|| {
-        // Run to block one to see emitted events
         run_to_block(1);
 
-        helper_init_accounts(vec![FIRST_MEMBER_ORIGIN, COLLABORATOR_MEMBER_ORIGIN]);
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
 
-        create_initial_storage_buckets();
-        // create channel
-        create_channel_mock(
-            FIRST_MEMBER_ORIGIN,
-            ContentActor::Member(FIRST_MEMBER_ID),
-            ChannelCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![2, 3])),
-                meta: None,
-                reward_account: None,
-                collaborators: vec![COLLABORATOR_MEMBER_ID]
-                    .into_iter()
-                    .collect::<BTreeSet<_>>(),
-            },
-            Ok(()),
-        );
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_channel_id(Zero::zero())
+            .call_and_assert(Err(Error::<Test>::ChannelDoesNotExist.into()));
+    })
+}
 
-        // create video
-        create_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as storage::Trait>::ChannelId::one(),
-            VideoCreationParametersRecord {
-                assets: Some(helper_generate_storage_assets(vec![1, 2])),
-                meta: None,
-            },
-            Ok(()),
-        );
+#[test]
+fn unsuccessful_video_creation_with_invalid_expected_data_size_fee() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
 
-        delete_video_mock(
-            COLLABORATOR_MEMBER_ORIGIN,
-            ContentActor::Collaborator(COLLABORATOR_MEMBER_ID),
-            <Test as Trait>::VideoId::one(),
-            vec![
-                DataObjectId::<Test>::one(),
-                DataObjectId::<Test>::from(2u64),
-            ]
-            .into_iter()
-            .collect::<BTreeSet<_>>(),
-            Ok(()),
-        );
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel();
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                // setting a purposely high fee to trigger error
+                expected_data_size_fee: BalanceOf::<Test>::from(1_000_000u64),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::DataSizeFeeChanged.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_creation_with_insufficient_balance() {
+    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();
+        slash_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID);
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::InsufficientBalance.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_creation_due_to_bucket_having_insufficient_objects_size_left() {
+    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();
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: STORAGE_BUCKET_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectSizeLimitReached.into(),
+            ));
+    })
+}
+
+#[test]
+fn unsuccessful_video_creation_due_to_bucket_having_insufficient_objects_number_left() {
+    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();
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: (0..(STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT + 1))
+                    .map(|_| DataObjectCreationParameters {
+                        size: 1,
+                        ipfs_content_id: vec![1u8],
+                    })
+                    .collect(),
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectNumberLimitReached.into(),
+            ));
+    })
+}
+
+#[test]
+fn unsuccessful_video_creation_with_max_object_size_limits_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();
+
+        CreateVideoFixture::default()
+            .with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
+            .with_assets(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: VOUCHER_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(storage::Error::<Test>::MaxDataObjectSizeExceeded.into()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_member_with_assets_upload() {
+    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();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_creation_by_collaborator_with_assets_upload() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(COLLABORATOR_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        UpdateVideoFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_creation_by_lead_with_assets_upload() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        UpdateVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_curator_with_assets_upload() {
+    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 = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateVideoFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_member_with_assets_removal() {
+    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 video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_collaborator_with_assets_removal() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(COLLABORATOR_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+        let video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        UpdateVideoFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_lead_with_assets_removal() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+        let video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        UpdateVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_update_by_curator_with_assets_removal() {
+    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 video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        UpdateVideoFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_member_auth_failure() {
+    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();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn successful_video_update_with_collaborator_auth_failure() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_curator_auth_failure() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        let default_curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
+        CreateVideoFixture::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_video_update_by_lead_with_member_owned_channel() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(LEAD_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_unauth_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();
+
+        CreateVideoFixture::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_video_update_with_unauth_collaborator() {
+    with_default_mock_builder(|| {
+        run_to_block(1);
+
+        create_initial_storage_buckets_helper();
+        increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        increase_account_balance_helper(UNAUTHORIZED_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_member_owned_channel_with_video();
+
+        CreateVideoFixture::default()
+            .with_sender(UNAUTHORIZED_COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(
+                UNAUTHORIZED_COLLABORATOR_MEMBER_ID,
+            ))
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_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);
+        increase_account_balance_helper(UNAUTHORIZED_CURATOR_ACCOUNT_ID, INITIAL_BALANCE);
+        create_default_curator_owned_channel_with_video();
+
+        let unauthorized_curator_group_id =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        CreateVideoFixture::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_video_update_with_invalid_expected_data_size_fee() {
+    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();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                // setting a purposely high fee to trigger error
+                expected_data_size_fee: BalanceOf::<Test>::from(1_000_000u64),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::DataSizeFeeChanged.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_insufficient_balance() {
+    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();
+        slash_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID);
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_objects_helper(),
+            })
+            .call_and_assert(Err(storage::Error::<Test>::InsufficientBalance.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_due_to_bucket_having_insufficient_objects_size_left() {
+    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();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: STORAGE_BUCKET_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectSizeLimitReached.into(),
+            ));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_due_to_bucket_having_insufficient_objects_number_left() {
+    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();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: (0..(STORAGE_BUCKET_OBJECTS_NUMBER_LIMIT + 1))
+                    .map(|_| DataObjectCreationParameters {
+                        size: 1,
+                        ipfs_content_id: vec![1u8],
+                    })
+                    .collect(),
+            })
+            .call_and_assert(Err(
+                storage::Error::<Test>::StorageBucketObjectNumberLimitReached.into(),
+            ));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_max_object_size_limits_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();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_upload(StorageAssets::<Test> {
+                expected_data_size_fee: Storage::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: vec![DataObjectCreationParameters {
+                    size: VOUCHER_OBJECTS_SIZE_LIMIT + 1,
+                    ipfs_content_id: vec![1u8],
+                }],
+            })
+            .call_and_assert(Err(storage::Error::<Test>::MaxDataObjectSizeExceeded.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_invalid_object_ids() {
+    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 invalid_objects_ids = ((2 * DATA_OBJECTS_NUMBER as u64)
+            ..(3 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        UpdateVideoFixture::default()
+            .with_assets_to_remove(invalid_objects_ids)
+            .call_and_assert(Err(storage::Error::<Test>::DataObjectDoesntExist.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_update_with_invalid_video_id() {
+    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();
+
+        UpdateVideoFixture::default()
+            .with_video_id(Zero::zero())
+            .call_and_assert(Err(Error::<Test>::VideoDoesNotExist.into()));
+    })
+}
+
+#[test]
+fn successful_video_deletion_by_member_with_assets_removal() {
+    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 video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        DeleteVideoFixture::default()
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_by_collaborator() {
+    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();
+
+        DeleteVideoFixture::default()
+            .with_sender(COLLABORATOR_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Collaborator(COLLABORATOR_MEMBER_ID))
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_by_lead_with_member_owned_channel() {
+    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();
+
+        DeleteVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::ActorNotAuthorized.into()));
+    })
+}
+
+#[test]
+fn successful_video_deletion_by_lead_with_curator_owned_channel() {
+    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 video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        DeleteVideoFixture::default()
+            .with_sender(LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn successful_video_deletion_by_curator_with_assets_removal() {
+    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 video_assets = ((DATA_OBJECTS_NUMBER as u64)..(2 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        let default_curator_group_id = NextCuratorGroupId::<Test>::get() - 1;
+        DeleteVideoFixture::default()
+            .with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
+            .with_actor(ContentActor::Curator(
+                default_curator_group_id,
+                DEFAULT_CURATOR_ID,
+            ))
+            .with_assets_to_remove(video_assets)
+            .call_and_assert(Ok(()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_by_member_with_auth_failure() {
+    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();
+
+        DeleteVideoFixture::default()
+            .with_sender(UNAUTHORIZED_MEMBER_ACCOUNT_ID)
+            .with_actor(ContentActor::Member(DEFAULT_MEMBER_ACCOUNT_ID))
+            .call_and_assert(Err(Error::<Test>::MemberAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_by_curator_with_auth_failure() {
+    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 = NextCuratorGroupId::<Test>::get() - 1;
+        DeleteVideoFixture::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_video_deletion_with_lead_auth_failure() {
+    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();
+
+        DeleteVideoFixture::default()
+            .with_sender(UNAUTHORIZED_LEAD_ACCOUNT_ID)
+            .with_actor(ContentActor::Lead)
+            .call_and_assert(Err(Error::<Test>::LeadAuthFailed.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_by_unauth_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();
+
+        DeleteVideoFixture::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_video_deletion_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 =
+            curators::add_curator_to_new_group(UNAUTHORIZED_CURATOR_ID);
+        DeleteVideoFixture::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_video_deletion_with_invalid_video_id() {
+    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();
+
+        DeleteVideoFixture::default()
+            .with_video_id(Zero::zero())
+            .call_and_assert(Err(Error::<Test>::VideoDoesNotExist.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_video_deletion_with_invalid_object_ids() {
+    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 invalid_objects_ids = ((2 * DATA_OBJECTS_NUMBER as u64)
+            ..(3 * DATA_OBJECTS_NUMBER as u64 - 1))
+            .collect::<BTreeSet<_>>();
+
+        DeleteVideoFixture::default()
+            .with_assets_to_remove(invalid_objects_ids)
+            .call_and_assert(Err(storage::Error::<Test>::DataObjectDoesntExist.into()));
     })
 }

+ 18 - 9
runtime-modules/storage/src/lib.rs

@@ -1467,6 +1467,9 @@ decl_error! {
         /// Different Accounts for dynamic bag deletion prize and upload fees
         AccountsNotCoherent,
 
+        /// Different Accounts for dynamic bag id and parameters bag id
+        BagsNotCoherent,
+
         /// Invalid transactor account ID for this bucket.
         InvalidTransactorAccount,
     }
@@ -2842,21 +2845,22 @@ impl<T: Trait> Module<T> {
     ) -> Result<Option<BagUpdate<BalanceOf<T>>>, DispatchError> {
         let bag_id: BagId<T> = dynamic_bag_id.clone().into();
         ensure!(
-            !<Bags<T>>::contains_key(bag_id),
+            !<Bags<T>>::contains_key(bag_id.clone()),
             Error::<T>::DynamicBagExists
         );
 
-        // call can upload data explicitly
         let bag_change = upload_params
             .as_ref()
             .map(|params| {
-                // ensure coherent account ids for prize
+                // ensure coherent account ids & bag ids
                 if let Some(deletion_prize) = deletion_prize {
                     ensure!(
                         params.deletion_prize_source_account_id == deletion_prize.account_id,
                         Error::<T>::AccountsNotCoherent,
                     );
                 }
+                ensure!(bag_id == params.bag_id, Error::<T>::BagsNotCoherent);
+
                 Self::validate_bag_change(params)
             })
             .transpose()?;
@@ -2869,12 +2873,17 @@ impl<T: Trait> Module<T> {
                 Self::compute_upload_fees(bag_change)
             }));
 
-        Self::ensure_sufficient_balance_for_upload(
-            deletion_prize
-                .as_ref()
-                .map(|deletion_prize| deletion_prize.account_id.clone()),
-            total_upload_fee,
-        )?;
+        // either bag_prize account or objects_prize account used (provided they are the same)
+        let designated_account = deletion_prize
+            .as_ref()
+            .map(|dp| dp.account_id.clone())
+            .or_else(|| {
+                upload_params
+                    .as_ref()
+                    .map(|p| p.deletion_prize_source_account_id.clone())
+            });
+
+        Self::ensure_sufficient_balance_for_upload(designated_account, total_upload_fee)?;
 
         Ok(bag_change)
     }

+ 128 - 15
runtime-modules/storage/src/tests/fixtures.rs

@@ -2,8 +2,10 @@ use frame_support::dispatch::DispatchResult;
 use frame_support::storage::StorageMap;
 use frame_support::traits::{Currency, OnFinalize, OnInitialize};
 use frame_system::{EventRecord, Phase, RawOrigin};
+use sp_runtime::{traits::Zero, DispatchError};
 use sp_std::collections::btree_map::BTreeMap;
 use sp_std::collections::btree_set::BTreeSet;
+use std::convert::TryInto;
 
 use super::mocks::{
     Balances, CollectiveFlip, Storage, System, Test, TestEvent, DEFAULT_MEMBER_ACCOUNT_ID,
@@ -11,7 +13,9 @@ use super::mocks::{
 };
 
 use crate::tests::mocks::{
-    DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID, DISTRIBUTION_WG_LEADER_ACCOUNT_ID,
+    DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID, DEFAULT_MEMBER_ID,
+    DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT, DEFAULT_STORAGE_BUCKET_SIZE_LIMIT,
+    DISTRIBUTION_WG_LEADER_ACCOUNT_ID,
 };
 use crate::{
     BagId, Cid, DataObjectCreationParameters, DataObjectStorage, DistributionBucket,
@@ -102,6 +106,9 @@ impl EventFixture {
 
 const DEFAULT_ACCOUNT_ID: u64 = 1;
 const DEFAULT_WORKER_ID: u64 = 1;
+pub const DEFAULT_DATA_OBJECTS_NUMBER: u64 = DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT / 2;
+pub const DEFAULT_DATA_OBJECTS_SIZE: u64 =
+    DEFAULT_STORAGE_BUCKET_SIZE_LIMIT / DEFAULT_DATA_OBJECTS_NUMBER - 1;
 
 pub struct CreateStorageBucketFixture {
     origin: RawOrigin<u64>,
@@ -342,7 +349,7 @@ pub fn create_data_object_candidates(
     range
         .into_iter()
         .map(|idx| DataObjectCreationParameters {
-            size: 10 * idx as u64,
+            size: DEFAULT_DATA_OBJECTS_SIZE,
             ipfs_content_id: vec![idx],
         })
         .collect()
@@ -1151,6 +1158,7 @@ impl CreateDynamicBagFixture {
 }
 
 pub struct CreateDynamicBagWithObjectsFixture {
+    sender: u64,
     bag_id: DynamicBagId<Test>,
     deletion_prize: Option<DynamicBagDeletionPrize<Test>>,
     upload_parameters: UploadParameters<Test>,
@@ -1158,10 +1166,68 @@ pub struct CreateDynamicBagWithObjectsFixture {
 
 impl CreateDynamicBagWithObjectsFixture {
     pub fn default() -> Self {
+        let bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        let sender_acc = DEFAULT_MEMBER_ACCOUNT_ID;
+        Self {
+            sender: sender_acc.clone(),
+            bag_id: bag_id.clone(),
+            deletion_prize: None,
+            upload_parameters: UploadParameters::<Test> {
+                bag_id: bag_id.into(),
+                expected_data_size_fee: crate::Module::<Test>::data_object_per_mega_byte_fee(),
+                object_creation_list: create_data_object_candidates(
+                    1,
+                    DEFAULT_DATA_OBJECTS_NUMBER.try_into().unwrap(),
+                ),
+                deletion_prize_source_account_id: sender_acc,
+            },
+        }
+    }
+
+    pub fn with_expected_data_size_fee(self, expected_data_size_fee: u64) -> Self {
+        Self {
+            upload_parameters: UploadParameters::<Test> {
+                expected_data_size_fee,
+                ..self.upload_parameters
+            },
+            ..self
+        }
+    }
+
+    pub fn with_params_bag_id(self, bag_id: BagId<Test>) -> Self {
         Self {
-            bag_id: Default::default(),
-            deletion_prize: Default::default(),
-            upload_parameters: Default::default(),
+            upload_parameters: UploadParameters::<Test> {
+                bag_id,
+                ..self.upload_parameters
+            },
+            ..self
+        }
+    }
+
+    pub fn with_objects(self, object_creation_list: Vec<DataObjectCreationParameters>) -> Self {
+        Self {
+            upload_parameters: UploadParameters::<Test> {
+                object_creation_list,
+                ..self.upload_parameters
+            },
+            ..self
+        }
+    }
+
+    pub fn with_upload_parameters(self, upload_parameters: UploadParameters<Test>) -> Self {
+        Self {
+            upload_parameters,
+            ..self
+        }
+    }
+
+    pub fn with_objects_prize_source_account(self, deletion_prize_source_account_id: u64) -> Self {
+        Self {
+            upload_parameters: UploadParameters::<Test> {
+                deletion_prize_source_account_id,
+                ..self.upload_parameters
+            },
+            ..self
         }
     }
 
@@ -1179,25 +1245,55 @@ impl CreateDynamicBagWithObjectsFixture {
         }
     }
 
-    pub fn with_objects(self, upload_parameters: UploadParameters<Test>) -> Self {
-        Self {
-            upload_parameters,
-            ..self
-        }
-    }
-
     pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let balance_pre = Balances::usable_balance(self.sender);
+        let bag_id: BagId<Test> = self.bag_id.clone().into();
+        let total_size_required = self
+            .upload_parameters
+            .object_creation_list
+            .iter()
+            .fold(0, |acc, it| acc + it.size);
+
         let actual_result = Storage::create_dynamic_bag_with_objects_constraints(
             self.bag_id.clone(),
             self.deletion_prize.clone(),
             self.upload_parameters.clone(),
         );
 
+        let balance_post = Balances::usable_balance(self.sender);
+
         assert_eq!(actual_result, expected_result);
 
-        if actual_result.is_ok() {
-            let bag_id: BagId<Test> = self.bag_id.clone().into();
-            assert!(<crate::Bags<Test>>::contains_key(&bag_id));
+        match actual_result {
+            Ok(()) => {
+                assert!(<crate::Bags<Test>>::contains_key(&bag_id));
+
+                let bag = crate::Bags::<Test>::get(&bag_id);
+                assert_eq!(
+                    balance_pre.saturating_sub(balance_post),
+                    self.deletion_prize
+                        .as_ref()
+                        .map_or_else(|| Zero::zero(), |dprize| dprize.prize)
+                );
+
+                let total_objects_required =
+                    self.upload_parameters.object_creation_list.len() as u64;
+
+                assert!(bag.stored_by.iter().all(|id| {
+                    let bucket = crate::StorageBucketById::<Test>::get(id);
+                    let enough_size =
+                        bucket.voucher.size_limit >= total_size_required + bucket.voucher.size_used;
+                    let enough_objects = bucket.voucher.objects_limit
+                        >= total_objects_required + bucket.voucher.objects_used;
+                    enough_size && enough_objects && bucket.accepting_new_bags
+                }));
+            }
+            Err(err) => {
+                assert_eq!(balance_pre, balance_post);
+                if into_str(err) != "DynamicBagExists" {
+                    assert!(!crate::Bags::<Test>::contains_key(&bag_id))
+                }
+            }
         }
     }
 }
@@ -2044,3 +2140,20 @@ impl SetDistributionBucketFamilyMetadataFixture {
         assert_eq!(actual_result, expected_result);
     }
 }
+
+// helper methods
+impl CreateStorageBucketFixture {
+    pub fn create_several(&self, bucket_number: u64) -> BTreeSet<u64> {
+        let mut bucket_ids = BTreeSet::new();
+        for _ in 0..bucket_number {
+            let bucket_id = self.call_and_assert(Ok(())).unwrap();
+            bucket_ids.insert(bucket_id);
+        }
+        bucket_ids
+    }
+}
+
+// wrapper to silence compiler error
+fn into_str(err: DispatchError) -> &'static str {
+    err.into()
+}

+ 7 - 0
runtime-modules/storage/src/tests/mocks.rs

@@ -74,6 +74,13 @@ pub const DEFAULT_STORAGE_PROVIDER_ID: u64 = 10;
 pub const ANOTHER_STORAGE_PROVIDER_ID: u64 = 11;
 pub const DEFAULT_DISTRIBUTION_PROVIDER_ID: u64 = 12;
 pub const ANOTHER_DISTRIBUTION_PROVIDER_ID: u64 = 13;
+pub const INITIAL_BALANCE: u64 = 10_000;
+pub const BAG_DELETION_PRIZE_VALUE: u64 = 100;
+pub const VOUCHER_SIZE_LIMIT: u64 = 100;
+pub const VOUCHER_OBJECTS_LIMIT: u64 = 20;
+pub const DEFAULT_STORAGE_BUCKET_SIZE_LIMIT: u64 = 100;
+pub const DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT: u64 = 10;
+pub const DEFAULT_STORAGE_BUCKETS_NUMBER: u64 = 10;
 
 impl crate::Trait for Test {
     type Event = TestEvent;

+ 283 - 281
runtime-modules/storage/src/tests/mod.rs

@@ -9,6 +9,7 @@ use frame_support::{StorageDoubleMap, StorageMap, StorageValue};
 use frame_system::RawOrigin;
 use sp_std::collections::btree_map::BTreeMap;
 use sp_std::collections::btree_set::BTreeSet;
+use sp_std::convert::TryInto;
 use sp_std::iter::{repeat, FromIterator};
 
 use common::working_group::WorkingGroup;
@@ -21,18 +22,49 @@ use crate::{
 };
 
 use mocks::{
-    build_test_externalities, Balances, DataObjectDeletionPrize,
+    build_test_externalities, Balances, BlacklistSizeLimit, DataObjectDeletionPrize,
     DefaultChannelDynamicBagNumberOfStorageBuckets, DefaultMemberDynamicBagNumberOfStorageBuckets,
     InitialStorageBucketsNumberForDynamicBag, MaxDataObjectSize, MaxDistributionBucketFamilyNumber,
     MaxRandomIterationNumber, Storage, Test, ANOTHER_DISTRIBUTION_PROVIDER_ID,
-    ANOTHER_STORAGE_PROVIDER_ID, DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID,
-    DEFAULT_DISTRIBUTION_PROVIDER_ID, DEFAULT_MEMBER_ACCOUNT_ID, DEFAULT_MEMBER_ID,
+    ANOTHER_STORAGE_PROVIDER_ID, BAG_DELETION_PRIZE_VALUE,
+    DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID, DEFAULT_DISTRIBUTION_PROVIDER_ID,
+    DEFAULT_MEMBER_ACCOUNT_ID, DEFAULT_MEMBER_ID, DEFAULT_STORAGE_BUCKETS_NUMBER,
+    DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT, DEFAULT_STORAGE_BUCKET_SIZE_LIMIT,
     DEFAULT_STORAGE_PROVIDER_ACCOUNT_ID, DEFAULT_STORAGE_PROVIDER_ID,
-    DISTRIBUTION_WG_LEADER_ACCOUNT_ID, STORAGE_WG_LEADER_ACCOUNT_ID,
+    DISTRIBUTION_WG_LEADER_ACCOUNT_ID, INITIAL_BALANCE, STORAGE_WG_LEADER_ACCOUNT_ID,
+    VOUCHER_OBJECTS_LIMIT, VOUCHER_SIZE_LIMIT,
 };
 
 use fixtures::*;
 
+// helper
+
+fn create_storage_buckets(buckets_number: u64) -> BTreeSet<u64> {
+    set_max_voucher_limits();
+    CreateStorageBucketFixture::default()
+        .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
+        .with_objects_limit(DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT)
+        .with_size_limit(DEFAULT_STORAGE_BUCKET_SIZE_LIMIT)
+        .create_several(buckets_number)
+}
+
+fn default_bag_deletion_prize() -> Option<DynamicBagDeletionPrize<Test>> {
+    Some(DynamicBagDeletionPrize::<Test> {
+        prize: BAG_DELETION_PRIZE_VALUE,
+        account_id: DEFAULT_MEMBER_ACCOUNT_ID,
+    })
+}
+
+fn default_upload_parameters() -> UploadParameters<Test> {
+    let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+    UploadParameters::<Test> {
+        bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
+        object_creation_list: create_single_data_object(),
+        deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
+        expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
+    }
+}
+
 #[test]
 fn create_storage_bucket_succeeded() {
     build_test_externalities().execute_with(|| {
@@ -3049,10 +3081,7 @@ fn set_storage_bucket_voucher_limits_fails_with_invalid_storage_bucket() {
 }
 
 fn set_max_voucher_limits() {
-    let new_size_limit = 100;
-    let new_objects_limit = 1;
-
-    set_max_voucher_limits_with_params(new_size_limit, new_objects_limit);
+    set_max_voucher_limits_with_params(VOUCHER_SIZE_LIMIT, VOUCHER_OBJECTS_LIMIT);
 }
 
 fn set_max_voucher_limits_with_params(size_limit: u64, objects_limit: u64) {
@@ -3103,7 +3132,7 @@ fn create_dynamic_bag_succeeded() {
 
         let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
 
-        create_storage_buckets(10);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
 
         let deletion_prize_value = 100;
         let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
@@ -3400,37 +3429,6 @@ fn test_storage_bucket_iterators() {
     });
 }
 
-fn create_storage_buckets(buckets_number: u64) -> BTreeSet<u64> {
-    set_max_voucher_limits();
-
-    let objects_limit = 1;
-    let size_limit = 100;
-
-    create_storage_buckets_with_limits(buckets_number, size_limit, objects_limit)
-}
-
-fn create_storage_buckets_with_limits(
-    buckets_number: u64,
-    size_limit: u64,
-    objects_limit: u64,
-) -> BTreeSet<u64> {
-    let mut bucket_ids = BTreeSet::new();
-
-    for _ in 0..buckets_number {
-        let bucket_id = CreateStorageBucketFixture::default()
-            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
-            .with_invite_worker(None)
-            .with_objects_limit(objects_limit)
-            .with_size_limit(size_limit)
-            .call_and_assert(Ok(()))
-            .unwrap();
-
-        bucket_ids.insert(bucket_id);
-    }
-
-    bucket_ids
-}
-
 #[test]
 fn update_number_of_storage_buckets_in_dynamic_bag_creation_policy_succeeded() {
     build_test_externalities().execute_with(|| {
@@ -5068,14 +5066,14 @@ fn set_distribution_bucket_family_metadata_fails_with_invalid_distribution_bucke
 }
 
 #[test]
-fn create_dynamic_bag_with_objects_succeeds() {
+fn can_delete_dynamic_bags_with_objects_succeeded() {
     build_test_externalities().execute_with(|| {
         let starting_block = 1;
         run_to_block(starting_block);
 
         let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
 
-        create_storage_buckets(10);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
 
         let deletion_prize_value = 100;
         let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
@@ -5107,332 +5105,336 @@ fn create_dynamic_bag_with_objects_succeeds() {
         CreateDynamicBagWithObjectsFixture::default()
             .with_bag_id(dynamic_bag_id.clone())
             .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters)
+            .with_upload_parameters(upload_parameters)
             .call_and_assert(Ok(()));
 
-        let bag = Storage::dynamic_bag(&dynamic_bag_id);
-
-        // Check that IDs are within possible range.
-        assert!(bag
-            .stored_by
-            .iter()
-            .all(|id| { *id < Storage::next_storage_bucket_id() }));
-
-        let creation_policy =
-            Storage::get_dynamic_bag_creation_policy(dynamic_bag_id.clone().into());
-        assert_eq!(
-            bag.stored_by.len(),
-            creation_policy.number_of_storage_buckets as usize
-        );
+        CanDeleteDynamicBagWithObjectsFixture::default()
+            .with_bag_id(dynamic_bag_id.clone())
+            .call_and_assert(Ok(()));
+    });
+}
 
-        assert_eq!(bag.deletion_prize.unwrap(), deletion_prize_value);
+#[test]
+fn cannot_delete_dynamic_bags_with_objects_with_insufficient_treasury_balance() {
+    build_test_externalities().execute_with(|| {
+        let starting_block = 1;
+        run_to_block(starting_block);
 
-        // post-check balances
+        let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+        // pre-check balances
         assert_eq!(
             Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance - deletion_prize_value
+            INITIAL_BALANCE
         );
         assert_eq!(
             Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            deletion_prize_value
+            0
         );
 
-        EventFixture::assert_last_crate_event(RawEvent::DynamicBagCreated(
-            dynamic_bag_id,
-            deletion_prize,
-            BTreeSet::from_iter(bag.stored_by),
-            BTreeSet::from_iter(bag.distributed_by),
-        ));
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_bag_id(dynamic_bag_id.clone())
+            .with_deletion_prize(default_bag_deletion_prize())
+            .with_upload_parameters(default_upload_parameters())
+            .call_and_assert(Ok(()));
+
+        let _ = Balances::slash(
+            &<StorageTreasury<Test>>::module_account_id(),
+            BAG_DELETION_PRIZE_VALUE,
+        );
+
+        CanDeleteDynamicBagWithObjectsFixture::default()
+            .with_bag_id(dynamic_bag_id.clone())
+            .call_and_assert(Err(Error::<Test>::InsufficientTreasuryBalance.into()));
     });
 }
 
 #[test]
-fn create_dynamic_bag_with_objects_fails_with_no_bucket_availables_with_sufficient_objects_limit() {
+fn unsuccessful_dyn_bag_creation_with_existing_bag_id() {
     build_test_externalities().execute_with(|| {
-        let starting_block = 1;
-        run_to_block(starting_block);
+        run_to_block(1);
 
-        // set limit size 100 and limit obj number 20
-        set_max_voucher_limits_with_params(100, 20);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
         let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        CreateDynamicBagFixture::default()
+            .with_bag_id(dynamic_bag_id)
+            .call_and_assert(Ok(()));
 
-        // create 10 buckets each with size limit 10 and num object limit 1
-        create_storage_buckets_with_limits(10, 10, 1);
+        CreateDynamicBagWithObjectsFixture::default()
+            .call_and_assert(Err(Error::<Test>::DynamicBagExists.into()));
+    })
+}
 
-        let deletion_prize_value = 100;
-        let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
-        let initial_balance = 10000;
-        increase_account_balance(&deletion_prize_account_id, initial_balance);
+#[test]
+fn unsuccessful_dyn_bag_creation_with_insufficient_balance_for_bag_prize_and_upload_fees() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        let deletion_prize = Some(DynamicBagDeletionPrize::<Test> {
-            prize: deletion_prize_value,
-            account_id: deletion_prize_account_id,
-        });
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
 
-        let upload_parameters = UploadParameters::<Test> {
-            bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
-            object_creation_list: create_data_object_candidates(1, 3),
-            deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
-            expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
-        };
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_deletion_prize(default_bag_deletion_prize())
+            .call_and_assert(Err(Error::<Test>::InsufficientBalance.into()));
+    })
+}
 
-        // pre-check balances
-        assert_eq!(
-            Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance
-        );
-        assert_eq!(
-            Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            0
-        );
+#[test]
+fn unsuccessful_dyn_bag_creation_with_different_accounts_for_prize_and_params() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
+
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        // this fails because num objects == 3 & bucket.num_objects_limit == 1
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters.clone())
-            .call_and_assert(Err(Error::<Test>::StorageBucketIdCollectionsAreEmpty.into()));
+            .with_deletion_prize(default_bag_deletion_prize())
+            .with_objects_prize_source_account(DEFAULT_MEMBER_ACCOUNT_ID + 100)
+            .call_and_assert(Err(Error::<Test>::AccountsNotCoherent.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_dyn_bag_creation_with_zero_objects_size() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        // set bucket size limits to be large enought and retry
-        let new_objects_number_limit = 10;
-        let new_objects_size_limit = 100;
-        let bucket_id_to_enlarge = 1;
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        SetStorageBucketVoucherLimitsFixture::default()
-            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
-            .with_storage_bucket_id(bucket_id_to_enlarge)
-            .with_new_objects_number_limit(new_objects_number_limit)
-            .with_new_objects_size_limit(new_objects_size_limit)
-            .call_and_assert(Ok(()));
+        let objects: Vec<DataObjectCreationParameters> = (1..DEFAULT_DATA_OBJECTS_NUMBER)
+            .into_iter()
+            .map(|idx| DataObjectCreationParameters {
+                size: 0,
+                ipfs_content_id: vec![idx.try_into().unwrap()],
+            })
+            .collect();
 
-        // this succeeds now
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters)
-            .call_and_assert(Ok(()));
+            .with_objects(objects)
+            .call_and_assert(Err(Error::<Test>::ZeroObjectSize.into()));
     })
 }
 
 #[test]
-fn create_dynamic_bag_with_objects_fails_with_no_bucket_availables_with_sufficient_size_limit() {
+fn unsuccessful_dyn_bag_creation_with_object_size_exceeding_max_obj_size() {
     build_test_externalities().execute_with(|| {
-        let starting_block = 1;
-        run_to_block(starting_block);
+        run_to_block(1);
 
-        // set limit size 100 and limit obj number 20
-        set_max_voucher_limits_with_params(100, 20);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        let objects: Vec<DataObjectCreationParameters> = (1..DEFAULT_DATA_OBJECTS_NUMBER)
+            .into_iter()
+            .map(|idx| DataObjectCreationParameters {
+                // set size high on purpose to trigger error
+                size: 1_000_000,
+                ipfs_content_id: vec![idx.try_into().unwrap()],
+            })
+            .collect();
 
-        // create 10 buckets each with size limit 1 and num object limit 10
-        create_storage_buckets_with_limits(10, 1, 10);
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_objects(objects)
+            .call_and_assert(Err(Error::<Test>::MaxDataObjectSizeExceeded.into()));
+    })
+}
 
-        let deletion_prize_value = 100;
-        let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
-        let initial_balance = 10000;
-        increase_account_balance(&deletion_prize_account_id, initial_balance);
+#[test]
+fn unsuccessful_dyn_bag_creation_with_buckets_having_insufficient_size_available() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        let deletion_prize = Some(DynamicBagDeletionPrize::<Test> {
-            prize: deletion_prize_value,
-            account_id: deletion_prize_account_id,
-        });
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        // try uploading with 3 objects each exceeding bucket size limit
-        let upload_parameters = UploadParameters::<Test> {
-            bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
-            object_creation_list: create_data_object_candidates(1, 3),
-            deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
-            expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
-        };
+        let objects: Vec<DataObjectCreationParameters> = (1..2)
+            .map(|idx| DataObjectCreationParameters {
+                size: DEFAULT_STORAGE_BUCKET_SIZE_LIMIT + 1,
+                ipfs_content_id: vec![idx],
+            })
+            .collect();
 
-        // pre-check balances
-        assert_eq!(
-            Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance
-        );
-        assert_eq!(
-            Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            0
-        );
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_objects(objects)
+            .call_and_assert(Err(Error::<Test>::StorageBucketIdCollectionsAreEmpty.into()));
+    })
+}
+
+#[test]
+fn unsuccessful_dyn_bag_creation_with_buckets_having_insufficient_objects_available() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
+
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+
+        let objects: Vec<DataObjectCreationParameters> = (1..(DEFAULT_STORAGE_BUCKET_OBJECTS_LIMIT
+            + 1))
+            .map(|idx| DataObjectCreationParameters {
+                size: DEFAULT_DATA_OBJECTS_SIZE,
+                ipfs_content_id: vec![idx.try_into().unwrap()],
+            })
+            .collect();
 
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters.clone())
+            .with_objects(objects)
             .call_and_assert(Err(Error::<Test>::StorageBucketIdCollectionsAreEmpty.into()));
+    })
+}
 
-        // set bucket size limits to be large enought and retry
-        let new_objects_number_limit = 10;
-        let new_objects_size_limit = 100;
-        let bucket_id_to_enlarge = 1;
+#[test]
+fn unsuccessful_dyn_bag_creation_with_empty_ipfs_ids() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        SetStorageBucketVoucherLimitsFixture::default()
-            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
-            .with_storage_bucket_id(bucket_id_to_enlarge)
-            .with_new_objects_number_limit(new_objects_number_limit)
-            .with_new_objects_size_limit(new_objects_size_limit)
-            .call_and_assert(Ok(()));
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
+        let objects: Vec<DataObjectCreationParameters> = (1..DEFAULT_DATA_OBJECTS_NUMBER)
+            .map(|_| DataObjectCreationParameters {
+                size: DEFAULT_DATA_OBJECTS_SIZE,
+                ipfs_content_id: vec![],
+            })
+            .collect();
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters)
-            .call_and_assert(Ok(()));
+            .with_objects(objects)
+            .call_and_assert(Err(Error::<Test>::EmptyContentId.into()));
     })
 }
 
 #[test]
-fn create_dynamic_bag_with_objects_fails_with_unsufficient_balance() {
+fn unsuccessful_dyn_bag_creation_with_empty_objects_list() {
     build_test_externalities().execute_with(|| {
-        let starting_block = 1;
-        run_to_block(starting_block);
+        run_to_block(1);
 
-        // set limit size 100 and limit obj number 20
-        set_max_voucher_limits_with_params(100, 20);
-        // create 3 buckets with size limit 10 and objects limit 3
-        create_storage_buckets_with_limits(3, 10, 3);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_objects(vec![])
+            .call_and_assert(Err(Error::<Test>::NoObjectsOnUpload.into()));
+    })
+}
 
-        let deletion_prize_value = 100;
-        let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
-        let initial_balance = 100; // just enough for the del prize
-        increase_account_balance(&deletion_prize_account_id, initial_balance);
+#[test]
+fn unsuccessful_dyn_bag_creation_with_invalid_expected_data_fee() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        let deletion_prize = Some(DynamicBagDeletionPrize::<Test> {
-            prize: deletion_prize_value,
-            account_id: deletion_prize_account_id,
-        });
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        // try uploading with > 0 objects exceeding balance
-        let data_objects = create_data_object_candidates(1, 3);
-        let upload_parameters = UploadParameters::<Test> {
-            bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
-            object_creation_list: data_objects.clone(),
-            deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
-            expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
-        };
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_expected_data_size_fee(Storage::data_object_per_mega_byte_fee() + 100)
+            .call_and_assert(Err(Error::<Test>::DataSizeFeeChanged.into()));
+    })
+}
 
-        // pre-check balances
-        assert_eq!(
-            Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance
-        );
-        assert_eq!(
-            Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            0
-        );
+#[test]
+fn unsuccessful_dyn_bag_creation_with_dynamic_and_param_bag_differing() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
+
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters.clone())
-            .call_and_assert(Err(Error::<Test>::InsufficientBalance.into()));
+            .with_params_bag_id(DynamicBagId::<Test>::Channel(0u64).into())
+            .call_and_assert(Err(Error::<Test>::BagsNotCoherent.into()));
     })
 }
 
 #[test]
-fn can_delete_dynamic_bags_with_objects_succeeded() {
+fn unsuccessful_dyn_bag_creation_with_upload_blocking() {
     build_test_externalities().execute_with(|| {
-        let starting_block = 1;
-        run_to_block(starting_block);
+        run_to_block(1);
 
-        let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        create_storage_buckets(10);
+        UpdateUploadingBlockedStatusFixture::default()
+            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
+            .with_new_status(true)
+            .call_and_assert(Ok(()));
 
-        let deletion_prize_value = 100;
-        let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
-        let initial_balance = 10000;
-        increase_account_balance(&deletion_prize_account_id, initial_balance);
+        CreateDynamicBagWithObjectsFixture::default()
+            .call_and_assert(Err(Error::<Test>::UploadingBlocked.into()));
+    })
+}
 
-        let deletion_prize = Some(DynamicBagDeletionPrize::<Test> {
-            prize: deletion_prize_value,
-            account_id: deletion_prize_account_id,
-        });
+#[test]
+fn unsuccessful_dyn_bag_creation_with_blacklisted_ipfs_id() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        let upload_parameters = UploadParameters::<Test> {
-            bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
-            object_creation_list: create_single_data_object(),
-            deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
-            expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
-        };
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        // pre-check balances
-        assert_eq!(
-            Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance
-        );
-        assert_eq!(
-            Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            0
-        );
+        let objects: Vec<DataObjectCreationParameters> = (0..BlacklistSizeLimit::get())
+            .map(|idx| DataObjectCreationParameters {
+                size: DEFAULT_DATA_OBJECTS_SIZE,
+                ipfs_content_id: vec![idx.try_into().unwrap()],
+            })
+            .collect();
 
-        CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters)
+        UpdateBlacklistFixture::default()
+            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
+            .with_add_hashes(
+                objects
+                    .iter()
+                    .map(|obj| obj.ipfs_content_id.clone())
+                    .collect(),
+            )
             .call_and_assert(Ok(()));
 
-        CanDeleteDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .call_and_assert(Ok(()));
-    });
+        CreateDynamicBagWithObjectsFixture::default()
+            .with_objects(objects)
+            .call_and_assert(Err(Error::<Test>::DataObjectBlacklisted.into()));
+    })
 }
 
 #[test]
-fn cannot_delete_dynamic_bags_with_objects_with_unsufficient_treasury_balance() {
+fn successful_dyn_bag_creation_with_upload_and_no_deletion_prize() {
     build_test_externalities().execute_with(|| {
-        let starting_block = 1;
-        run_to_block(starting_block);
+        run_to_block(1);
 
-        let dynamic_bag_id = DynamicBagId::<Test>::Member(DEFAULT_MEMBER_ID);
-
-        create_storage_buckets(10);
-
-        let deletion_prize_value = 100;
-        let deletion_prize_account_id = DEFAULT_MEMBER_ACCOUNT_ID;
-        let initial_balance = 10000;
-        increase_account_balance(&deletion_prize_account_id, initial_balance);
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
-        let deletion_prize = Some(DynamicBagDeletionPrize::<Test> {
-            prize: deletion_prize_value,
-            account_id: deletion_prize_account_id,
-        });
+        CreateDynamicBagWithObjectsFixture::default().call_and_assert(Ok(()));
+    })
+}
 
-        let upload_parameters = UploadParameters::<Test> {
-            bag_id: BagId::<Test>::from(dynamic_bag_id.clone()),
-            object_creation_list: create_single_data_object(),
-            deletion_prize_source_account_id: DEFAULT_MEMBER_ACCOUNT_ID,
-            expected_data_size_fee: Storage::data_object_per_mega_byte_fee(),
-        };
+#[test]
+fn successful_dyn_bag_creation_with_all_parameters_specified() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        // pre-check balances
-        assert_eq!(
-            Balances::usable_balance(&DEFAULT_MEMBER_ACCOUNT_ID),
-            initial_balance
-        );
-        assert_eq!(
-            Balances::usable_balance(&<StorageTreasury<Test>>::module_account_id()),
-            0
-        );
+        create_storage_buckets(DEFAULT_STORAGE_BUCKETS_NUMBER);
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
 
         CreateDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .with_deletion_prize(deletion_prize.clone())
-            .with_objects(upload_parameters)
+            .with_deletion_prize(default_bag_deletion_prize())
             .call_and_assert(Ok(()));
+    })
+}
 
-        // Corrupt module balance enough so that it doesn't reach sufficient balance for deletion
-        let _ = Balances::slash(
-            &<StorageTreasury<Test>>::module_account_id(),
-            deletion_prize_value,
-        );
+#[test]
+fn unsuccessful_dyn_bag_creation_with_no_bucket_accepting() {
+    build_test_externalities().execute_with(|| {
+        run_to_block(1);
 
-        CanDeleteDynamicBagWithObjectsFixture::default()
-            .with_bag_id(dynamic_bag_id.clone())
-            .call_and_assert(Err(Error::<Test>::InsufficientTreasuryBalance.into()));
-    });
+        set_max_voucher_limits();
+        CreateStorageBucketFixture::default()
+            .with_origin(RawOrigin::Signed(STORAGE_WG_LEADER_ACCOUNT_ID))
+            .with_accepting_new_bags(false)
+            .create_several(DEFAULT_STORAGE_BUCKETS_NUMBER);
+
+        increase_account_balance(&DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
+
+        CreateDynamicBagWithObjectsFixture::default()
+            .call_and_assert(Err(Error::<Test>::StorageBucketIdCollectionsAreEmpty.into()));
+    })
 }

Some files were not shown because too many files changed in this diff