Files
pezkuwi-subxt/substrate/frame/nft-fractionalization/src/tests.rs
T
Przemek Rzad bfb241d7f3 Add missing licenses and tune the scanning workflow (#1288)
* Add missing Cumulus licenses

* Typo

* Add missing Substrate licenses

* Single job checking the sub-repos in steps

* Remove dates

* Remove dates

* Add missing (C)

* Update FRAME UI tests

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update more UI tests

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
2023-08-30 15:45:49 +03:00

306 lines
7.2 KiB
Rust

// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Tests for Nft fractionalization pallet.
use crate::{mock::*, *};
use frame_support::{
assert_noop, assert_ok,
traits::{
fungible::{hold::Inspect as InspectHold, Mutate as MutateFungible},
fungibles::{metadata::Inspect, InspectEnumerable},
},
};
use pallet_nfts::CollectionConfig;
use sp_runtime::{DispatchError, ModuleError, TokenError::FundsUnavailable};
fn assets() -> Vec<u32> {
let mut s: Vec<_> = <<Test as Config>::Assets>::asset_ids().collect();
s.sort();
s
}
fn events() -> Vec<Event<Test>> {
let result = System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| {
if let mock::RuntimeEvent::NftFractionalization(inner) = e {
Some(inner)
} else {
None
}
})
.collect();
System::reset_events();
result
}
type AccountIdOf<Test> = <Test as frame_system::Config>::AccountId;
fn account(id: u8) -> AccountIdOf<Test> {
[id; 32].into()
}
#[test]
fn fractionalize_should_work() {
new_test_ext().execute_with(|| {
let nft_collection_id = 0;
let nft_id = 0;
let asset_id = 0;
let fractions = 1000;
Balances::set_balance(&account(1), 100);
Balances::set_balance(&account(2), 100);
assert_ok!(Nfts::force_create(
RuntimeOrigin::root(),
account(1),
CollectionConfig::default(),
));
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(1),
None,
));
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
));
assert_eq!(assets(), vec![asset_id]);
assert_eq!(Assets::balance(asset_id, account(2)), fractions);
assert_eq!(Balances::total_balance_on_hold(&account(1)), 2);
assert_eq!(String::from_utf8(Assets::name(0)).unwrap(), "Frac 0-0");
assert_eq!(String::from_utf8(Assets::symbol(0)).unwrap(), "FRAC");
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(1)));
assert_noop!(
Nfts::transfer(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(2),
),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
let details = NftToAsset::<Test>::get((&nft_collection_id, &nft_id)).unwrap();
assert_eq!(details.asset, asset_id);
assert_eq!(details.fractions, fractions);
assert!(events().contains(&Event::<Test>::NftFractionalized {
nft_collection: nft_collection_id,
nft: nft_id,
fractions,
asset: asset_id,
beneficiary: account(2),
}));
// owner can't burn an already fractionalized NFT
assert_noop!(
Nfts::burn(RuntimeOrigin::signed(account(1)), nft_collection_id, nft_id),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
// can't fractionalize twice
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id + 1,
account(2),
fractions,
),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
let nft_id = nft_id + 1;
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
),
Error::<Test>::NftNotFound
);
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(2),
None
));
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
),
Error::<Test>::NoPermission
);
});
}
#[test]
fn unify_should_work() {
new_test_ext().execute_with(|| {
let nft_collection_id = 0;
let nft_id = 0;
let asset_id = 0;
let fractions = 1000;
Balances::set_balance(&account(1), 100);
Balances::set_balance(&account(2), 100);
assert_ok!(Nfts::force_create(
RuntimeOrigin::root(),
account(1),
CollectionConfig::default(),
));
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(1),
None,
));
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
));
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id + 1,
nft_id,
asset_id,
account(1),
),
Error::<Test>::NftNotFractionalized
);
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id,
nft_id,
asset_id + 1,
account(1),
),
Error::<Test>::IncorrectAssetId
);
// can't unify the asset a user doesn't hold
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
),
DispatchError::Token(FundsUnavailable)
);
assert_ok!(NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id,
nft_id,
asset_id,
account(1),
));
assert_eq!(Assets::balance(asset_id, account(2)), 0);
assert_eq!(Balances::reserved_balance(&account(1)), 1);
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(1)));
assert!(!NftToAsset::<Test>::contains_key((&nft_collection_id, &nft_id)));
assert!(events().contains(&Event::<Test>::NftUnified {
nft_collection: nft_collection_id,
nft: nft_id,
asset: asset_id,
beneficiary: account(1),
}));
// validate we need to hold the full balance to un-fractionalize the NFT
let asset_id = asset_id + 1;
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
fractions,
));
assert_ok!(Assets::transfer(RuntimeOrigin::signed(account(1)), asset_id, account(2), 1));
assert_eq!(Assets::balance(asset_id, account(1)), fractions - 1);
assert_eq!(Assets::balance(asset_id, account(2)), 1);
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
),
DispatchError::Token(FundsUnavailable)
);
assert_ok!(Assets::transfer(RuntimeOrigin::signed(account(2)), asset_id, account(1), 1));
assert_ok!(NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
));
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(2)));
});
}