use super::{mock::*, *};
use pezframe_support::{
assert_ok,
traits::{tokens::GetSalary, RankedMembers},
};
use pezsp_runtime::{traits::ConvertToValue, DispatchResult};
parameter_types! {
pub Interior: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into();
pub Timeout: BlockNumber = 5;
pub AssetHub: Location = (Parent, Teyrchain(1)).into();
pub AssetIdGeneralIndex: u128 = 100;
pub AssetHubAssetId: AssetId = (PalletInstance(1), GeneralIndex(AssetIdGeneralIndex::get())).into();
pub LocatableAsset: LocatableAssetId = LocatableAssetId { asset_id: AssetHubAssetId::get(), location: AssetHub::get() };
}
type SalaryPayOverXcm = PayOverXcm<
Interior,
TestMessageSender,
TestQueryHandler<TestConfig, BlockNumber>,
Timeout,
AccountId,
(),
ConvertToValue<LocatableAsset>,
AliasesIntoAccountId32<AnyNetwork, AccountId>,
>;
type Rank = u128;
thread_local! {
pub static CLUB: RefCell<BTreeMap<AccountId, Rank>> = RefCell::new(BTreeMap::new());
}
pub struct TestClub;
impl RankedMembers for TestClub {
type AccountId = AccountId;
type Rank = Rank;
fn min_rank() -> Self::Rank {
0
}
fn rank_of(who: &Self::AccountId) -> Option<Self::Rank> {
CLUB.with(|club| club.borrow().get(who).cloned())
}
fn induct(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| club.borrow_mut().insert(who.clone(), 0));
Ok(())
}
fn promote(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| {
club.borrow_mut().entry(who.clone()).and_modify(|rank| *rank += 1);
});
Ok(())
}
fn demote(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| match club.borrow().get(who) {
None => Err(pezsp_runtime::DispatchError::Unavailable),
Some(&0) => {
club.borrow_mut().remove(&who);
Ok(())
},
Some(_) => {
club.borrow_mut().entry(who.clone()).and_modify(|rank| *rank += 1);
Ok(())
},
})
}
}
fn set_rank(who: AccountId, rank: u128) {
CLUB.with(|club| club.borrow_mut().insert(who, rank));
}
parameter_types! {
pub const RegistrationPeriod: BlockNumber = 2;
pub const PayoutPeriod: BlockNumber = 2;
pub const FixedSalaryAmount: Balance = 10 * UNITS;
pub static Budget: Balance = FixedSalaryAmount::get();
}
pub struct FixedSalary;
impl GetSalary<Rank, AccountId, Balance> for FixedSalary {
fn get_salary(_rank: Rank, _who: &AccountId) -> Balance {
FixedSalaryAmount::get()
}
}
impl pezpallet_salary::Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Paymaster = SalaryPayOverXcm;
type Members = TestClub;
type Salary = FixedSalary;
type RegistrationPeriod = RegistrationPeriod;
type PayoutPeriod = PayoutPeriod;
type Budget = Budget;
}
#[test]
fn salary_pay_over_xcm_works() {
let recipient = AccountId::new([1u8; 32]);
new_test_ext().execute_with(|| {
set_rank(recipient.clone(), 1);
assert_eq!(mock::Assets::balance(AssetIdGeneralIndex::get(), &recipient.clone()), 0);
assert_ok!(Salary::init(RuntimeOrigin::signed(recipient.clone())));
run_to(5);
assert_ok!(Salary::induct(RuntimeOrigin::signed(recipient.clone())));
assert_ok!(Salary::bump(RuntimeOrigin::signed(recipient.clone())));
assert_ok!(Salary::register(RuntimeOrigin::signed(recipient.clone())));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(recipient.clone())));
let (_, message, mut hash) = sent_xcm()[0].clone();
let message =
Xcm::<<XcmConfig as xcm_executor::Config>::RuntimeCall>::from(message.clone());
let expected_message: Xcm<RuntimeCall> = Xcm::<RuntimeCall>(vec![
DescendOrigin(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into()),
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
SetAppendix(Xcm(vec![
SetFeesMode { jit_withdraw: true },
ReportError(QueryResponseInfo {
destination: (Parent, Teyrchain(42)).into(),
query_id: 1,
max_weight: Weight::zero(),
}),
])),
TransferAsset {
assets: (AssetHubAssetId::get(), FixedSalaryAmount::get()).into(),
beneficiary: AccountId32 { id: recipient.clone().into(), network: None }.into(),
},
]);
assert_eq!(message, expected_message);
XcmExecutor::<XcmConfig>::prepare_and_execute(
(Parent, Teyrchain(42)),
message,
&mut hash,
Weight::MAX,
Weight::zero(),
);
assert_eq!(
mock::Assets::balance(AssetIdGeneralIndex::get(), &recipient),
FixedSalaryAmount::get()
);
});
}