use super::*;
use crate as pallet_derivatives;
use frame_support::{assert_err, assert_ok, traits::tokens::asset_ops::common_strategies::*};
use mock::*;
use xcm::prelude::*;
use xcm_executor::XcmExecutor;
#[test]
fn predefined_id_collection() {
new_test_ext().execute_with(|| {
let id = AssetId(Location::new(1, [Parachain(1111), PalletInstance(42), GeneralIndex(1)]));
assert_err!(
PredefinedIdDerivativeCollections::create_derivative(RuntimeOrigin::none(), id.clone()),
DispatchError::BadOrigin,
);
assert_ok!(PredefinedIdDerivativeCollections::create_derivative(
RuntimeOrigin::signed(1),
id.clone()
));
let owner =
unique_items::ItemOwner::<Test, PredefinedIdCollectionsInstance>::get(&id).unwrap();
assert_eq!(owner, 1111);
assert_err!(
PredefinedIdDerivativeCollections::create_derivative(
RuntimeOrigin::signed(2),
id.clone()
),
unique_items::Error::<Test, PredefinedIdCollectionsInstance>::AlreadyExists,
);
assert_err!(
PredefinedIdDerivativeCollections::destroy_derivative(
RuntimeOrigin::signed(1),
id.clone()
),
DispatchError::BadOrigin,
);
assert_ok!(PredefinedIdDerivativeCollections::destroy_derivative(
RuntimeOrigin::root(),
id.clone()
));
assert!(
unique_items::ItemOwner::<Test, PredefinedIdCollectionsInstance>::get(&id).is_none()
);
let invalid_id = AssetId(Location::new(0, [PalletInstance(42), GeneralIndex(1)]));
assert_err!(
PredefinedIdDerivativeCollections::create_derivative(RuntimeOrigin::signed(3), invalid_id),
pallet_derivatives::Error::<Test, PredefinedIdDerivativeCollectionsInstance>::InvalidAsset,
);
});
}
#[test]
fn auto_id_collection() {
new_test_ext().execute_with(|| {
let id_a =
AssetId(Location::new(1, [Parachain(2222), PalletInstance(42), GeneralIndex(1)]));
let id_b =
AssetId(Location::new(1, [Parachain(3333), PalletInstance(42), GeneralIndex(2)]));
assert_err!(
AutoIdDerivativeCollections::create_derivative(RuntimeOrigin::none(), id_a.clone()),
DispatchError::BadOrigin,
);
assert_ok!(AutoIdDerivativeCollections::create_derivative(
RuntimeOrigin::signed(3),
id_a.clone()
));
let derivative_id_a = AutoIdDerivativeCollections::get_derivative(&id_a).unwrap();
let owner_a =
unique_items::ItemOwner::<Test, AutoIdCollectionsInstance>::get(&derivative_id_a)
.unwrap();
assert_eq!(owner_a, 2222);
assert_err!(
AutoIdDerivativeCollections::create_derivative(RuntimeOrigin::signed(4), id_a.clone()),
pallet_derivatives::Error::<Test, AutoIdCollectionsInstance>::DerivativeAlreadyExists,
);
assert_ok!(AutoIdDerivativeCollections::create_derivative(
RuntimeOrigin::signed(5),
id_b.clone()
));
let derivative_id_b = AutoIdDerivativeCollections::get_derivative(&id_b).unwrap();
assert_ne!(derivative_id_a, derivative_id_b);
let owner_b =
unique_items::ItemOwner::<Test, AutoIdCollectionsInstance>::get(&derivative_id_b)
.unwrap();
assert_eq!(owner_b, 3333);
assert_err!(
AutoIdDerivativeCollections::create_derivative(RuntimeOrigin::signed(6), id_b.clone()),
pallet_derivatives::Error::<Test, AutoIdCollectionsInstance>::DerivativeAlreadyExists,
);
assert_err!(
AutoIdDerivativeCollections::destroy_derivative(RuntimeOrigin::signed(7), id_a.clone()),
DispatchError::BadOrigin,
);
assert_ok!(AutoIdDerivativeCollections::destroy_derivative(
RuntimeOrigin::root(),
id_a.clone()
));
assert!(unique_items::ItemOwner::<Test, AutoIdCollectionsInstance>::get(&derivative_id_a)
.is_none());
assert_ok!(AutoIdDerivativeCollections::destroy_derivative(
RuntimeOrigin::root(),
id_b.clone()
));
assert!(unique_items::ItemOwner::<Test, AutoIdCollectionsInstance>::get(&derivative_id_b)
.is_none());
let invalid_id = AssetId(Location::new(0, [PalletInstance(42), GeneralIndex(1)]));
assert_err!(
AutoIdDerivativeCollections::create_derivative(RuntimeOrigin::signed(8), invalid_id),
pallet_derivatives::Error::<Test, AutoIdDerivativeCollectionsInstance>::InvalidAsset,
);
});
}
#[test]
fn local_nfts() {
new_test_ext().execute_with(|| {
let collection_owner = 1;
let nft_initial_owner = 2;
let nft_beneficiary = 3;
let collection_id = AutoIdCollections::create(WithConfig::new(
ConfigValue(collection_owner),
AutoId::auto(),
))
.unwrap();
let nft_local_id = 112;
assert_ok!(PredefinedIdNfts::create(WithConfig::new(
ConfigValue(nft_initial_owner),
PredefinedId::from((collection_id, nft_local_id)),
)));
assert_eq!(
unique_items::ItemOwner::<Test, PredefinedIdNftsInstance>::get(&(
collection_id,
nft_local_id
)),
Some(nft_initial_owner),
);
let local_nfts_pallet_index = <PredefinedIdNfts as PalletInfoAccess>::index() as u8;
let nft_asset: Asset = (
(PalletInstance(local_nfts_pallet_index), GeneralIndex(collection_id.into())),
Index(nft_local_id.into()),
)
.into();
let nft_beneficiary_location = AccountIndex64 { index: nft_beneficiary, network: None };
let message = Xcm::builder_unpaid()
.unpaid_execution(Unlimited, None)
.withdraw_asset(nft_asset)
.deposit_asset(AllCounted(1), nft_beneficiary_location)
.build();
let origin: Location = AccountIndex64 { index: nft_initial_owner, network: None }.into();
let mut hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome = XcmExecutor::<XcmConfig>::prepare_and_execute(
origin,
message,
&mut hash,
Weight::MAX,
Weight::zero(),
);
assert_ok!(outcome.ensure_complete());
assert_eq!(
unique_items::ItemOwner::<Test, PredefinedIdNftsInstance>::get(&(
collection_id,
nft_local_id
)),
Some(nft_beneficiary),
);
});
}
#[test]
fn derivative_nfts() {
sp_tracing::try_init_simple();
new_test_ext().execute_with(|| {
let foreign_para_id = 2222;
let foreign_collection_id = AssetId(Location::new(
1,
[Parachain(foreign_para_id), PalletInstance(42), GeneralIndex(1)],
));
let foreign_nft_id = Index(112);
assert_ok!(AutoIdDerivativeCollections::create_derivative(
RuntimeOrigin::signed(1),
foreign_collection_id.clone(),
));
let derivative_collection_id =
AutoIdDerivativeCollections::get_derivative(&foreign_collection_id).unwrap();
assert!(DerivativeNfts::get_derivative(&(foreign_collection_id.clone(), foreign_nft_id))
.is_err());
let nft_beneficiary = 1;
let nft_asset: Asset = (foreign_collection_id.clone(), foreign_nft_id).into();
let nft_beneficiary_location = AccountIndex64 { index: nft_beneficiary, network: None };
let deposited_assets: Assets = nft_asset.clone().into();
let message = Xcm::builder_unpaid()
.unpaid_execution(Unlimited, None)
.reserve_asset_deposited(deposited_assets)
.deposit_asset(AllCounted(1), nft_beneficiary_location)
.build();
let origin = Location::new(1, [Parachain(foreign_para_id)]);
let mut hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome = XcmExecutor::<XcmConfig>::prepare_and_execute(
origin,
message,
&mut hash,
Weight::MAX,
Weight::zero(),
);
assert_ok!(outcome.ensure_complete());
let derivative_full_nft_id =
DerivativeNfts::get_derivative(&(foreign_collection_id.clone(), foreign_nft_id))
.unwrap();
assert_eq!(
unique_items::ItemOwner::<Test, PredefinedIdNftsInstance>::get(&derivative_full_nft_id),
Some(nft_beneficiary),
);
assert_eq!(derivative_collection_id, derivative_full_nft_id.0);
let derivative_local_nft_id = derivative_full_nft_id.1;
let nft_owner = nft_beneficiary;
let another_nft_beneficiary = nft_beneficiary + 1;
let local_nfts_pallet_index = <PredefinedIdNfts as PalletInfoAccess>::index() as u8;
let nft_asset_as_local: Asset = (
(
PalletInstance(local_nfts_pallet_index),
GeneralIndex(derivative_collection_id.into()),
),
Index(derivative_local_nft_id.into()),
)
.into();
let another_nft_beneficiary_location =
AccountIndex64 { index: another_nft_beneficiary, network: None };
let message = Xcm::builder_unpaid()
.unpaid_execution(Unlimited, None)
.withdraw_asset(nft_asset_as_local)
.deposit_asset(AllCounted(1), another_nft_beneficiary_location)
.build();
let origin: Location = AccountIndex64 { index: nft_owner, network: None }.into();
let mut hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome = XcmExecutor::<XcmConfig>::prepare_and_execute(
origin,
message,
&mut hash,
Weight::MAX,
Weight::zero(),
);
assert_err!(
outcome.ensure_complete(),
InstructionError { index: 1, error: XcmError::AssetNotFound }
);
let message = Xcm::builder_unpaid()
.unpaid_execution(Unlimited, None)
.withdraw_asset(nft_asset)
.deposit_asset(AllCounted(1), another_nft_beneficiary_location)
.build();
let origin: Location = AccountIndex64 { index: nft_owner, network: None }.into();
let mut hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome = XcmExecutor::<XcmConfig>::prepare_and_execute(
origin,
message,
&mut hash,
Weight::MAX,
Weight::zero(),
);
assert_ok!(outcome.ensure_complete());
assert_eq!(
unique_items::ItemOwner::<Test, PredefinedIdNftsInstance>::get(&derivative_full_nft_id),
Some(another_nft_beneficiary),
);
});
}