Skip to content
Snippets Groups Projects
tests.rs 7.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • Shaopeng Wang's avatar
    Shaopeng Wang committed
    //! Unit tests for the vesting module.
    
    #![cfg(test)]
    
    use super::*;
    
    use frame_support::{assert_err, assert_ok, traits::WithdrawReason};
    
    use mock::{ExtBuilder, Origin, PalletBalances, Runtime, System, TestEvent, Vesting, ALICE, BOB, CHARLIE};
    
    use pallet_balances::{BalanceLock, Reasons};
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    
    
    #[test]
    fn vesting_from_chain_spec_works() {
    	ExtBuilder::build().execute_with(|| {
    		assert_ok!(PalletBalances::ensure_can_withdraw(
    			&CHARLIE,
    			10,
    			WithdrawReason::Transfer.into(),
    			20
    		));
    		assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 11, WithdrawReason::Transfer.into(), 19).is_err());
    
    		assert_eq!(
    			Vesting::vesting_schedules(&CHARLIE),
    			vec![VestingSchedule {
    				start: 2u64,
    				period: 3u64,
    				period_count: 4u32,
    				per_period: 5u64,
    			}]
    		);
    
    		System::set_block_number(13);
    
    		assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));
    
    		assert_ok!(PalletBalances::ensure_can_withdraw(
    			&CHARLIE,
    			25,
    			WithdrawReason::Transfer.into(),
    			5
    		));
    		assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 26, WithdrawReason::Transfer.into(), 4).is_err());
    
    		System::set_block_number(14);
    
    		assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));
    
    		assert_ok!(PalletBalances::ensure_can_withdraw(
    			&CHARLIE,
    			30,
    			WithdrawReason::Transfer.into(),
    			0
    		));
    	});
    }
    
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    #[test]
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    fn vested_transfer_works() {
    
    	ExtBuilder::build().execute_with(|| {
    
    wangjj9219's avatar
    wangjj9219 committed
    		System::set_block_number(1);
    
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 1u32,
    			per_period: 100u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule.clone()]);
    
    		let vested_event = TestEvent::vesting(RawEvent::VestingScheduleAdded(ALICE, BOB, schedule));
    		assert!(System::events().iter().any(|record| record.event == vested_event));
    	});
    }
    
    #[test]
    fn add_new_vesting_schedule_merges_with_current_locked_balance_and_until() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 2u32,
    			per_period: 10u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    
    		System::set_block_number(12);
    
    		let another_schedule = VestingSchedule {
    			start: 10u64,
    			period: 13u64,
    			period_count: 1u32,
    			per_period: 7u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    
    		assert_eq!(
    			PalletBalances::locks(&BOB).pop(),
    			Some(BalanceLock {
    				id: VESTING_LOCK_ID,
    				amount: 17u64,
    
    				reasons: Reasons::All,
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			})
    		);
    	});
    }
    
    #[test]
    fn cannot_use_fund_if_not_claimed() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 10u64,
    			period: 10u64,
    			period_count: 1u32,
    			per_period: 50u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		assert!(PalletBalances::ensure_can_withdraw(&BOB, 1, WithdrawReason::Transfer.into(), 49).is_err());
    	});
    }
    
    #[test]
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    fn vested_transfer_fails_if_zero_period_or_count() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 1u64,
    			period: 0u64,
    			period_count: 1u32,
    			per_period: 100u64,
    		};
    		assert_err!(
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    			Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			Error::<Runtime>::ZeroVestingPeriod
    		);
    
    		let schedule = VestingSchedule {
    			start: 1u64,
    			period: 1u64,
    			period_count: 0u32,
    			per_period: 100u64,
    		};
    		assert_err!(
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    			Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			Error::<Runtime>::ZeroVestingPeriodCount
    		);
    	});
    }
    
    #[test]
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    fn vested_transfer_fails_if_transfer_err() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 1u64,
    			period: 1u64,
    			period_count: 1u32,
    			per_period: 100u64,
    		};
    		assert_err!(
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    			Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule.clone()),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			pallet_balances::Error::<Runtime, _>::InsufficientBalance,
    		);
    	});
    }
    
    #[test]
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    fn vested_transfer_fails_if_overflow() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 1u64,
    			period: 1u64,
    			period_count: 2u32,
    			per_period: u64::max_value(),
    		};
    		assert_err!(
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    			Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			Error::<Runtime>::NumOverflow
    		);
    
    		let another_schedule = VestingSchedule {
    			start: u64::max_value(),
    			period: 1u64,
    			period_count: 2u32,
    			per_period: 1u64,
    		};
    		assert_err!(
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    			Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			Error::<Runtime>::NumOverflow
    		);
    	});
    }
    
    #[test]
    fn claim_works() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 2u32,
    			per_period: 10u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    
    		System::set_block_number(11);
    		// remain locked if not claimed
    		assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10).is_err());
    		// unlocked after claiming
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    		assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
    		// more are still locked
    		assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());
    
    		System::set_block_number(21);
    		// claim more
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    		assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
    		// all used up
    		assert_eq!(PalletBalances::free_balance(BOB), 0);
    
    		// no locks anymore
    		assert_eq!(PalletBalances::locks(&BOB), vec![]);
    	});
    }
    
    #[test]
    fn update_vesting_schedules_works() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		let schedule = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 2u32,
    			per_period: 10u64,
    		};
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    
    		let updated_schedule = VestingSchedule {
    			start: 0u64,
    			period: 20u64,
    			period_count: 2u32,
    			per_period: 10u64,
    		};
    		assert_ok!(Vesting::update_vesting_schedules(
    
    			Origin::root(),
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    			BOB,
    			vec![updated_schedule]
    		));
    
    		System::set_block_number(11);
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    		assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());
    
    		System::set_block_number(21);
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    		assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
    	});
    }
    
    #[test]
    fn update_vesting_schedules_fails_if_unexpected_existing_locks() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    		assert_ok!(PalletBalances::transfer(Origin::signed(ALICE), BOB, 1));
    
    		PalletBalances::set_lock(*b"prelocks", &BOB, 0u64, WithdrawReasons::all());
    
    Shaopeng Wang's avatar
    Shaopeng Wang committed
    	});
    }
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    
    #[test]
    fn vested_transfer_check_for_min() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		let schedule = VestingSchedule {
    			start: 1u64,
    			period: 1u64,
    			period_count: 1u32,
    			per_period: 3u64,
    		};
    		assert_err!(
    			Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule.clone()),
    			Error::<Runtime>::AmountLow
    		);
    	});
    }
    
    #[test]
    fn multiple_vesting_schedule_claim_works() {
    
    	ExtBuilder::build().execute_with(|| {
    
    Xiliang Chen's avatar
    Xiliang Chen committed
    		let schedule = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 2u32,
    			per_period: 10u64,
    		};
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
    
    		let schedule2 = VestingSchedule {
    			start: 0u64,
    			period: 10u64,
    			period_count: 3u32,
    			per_period: 10u64,
    		};
    		assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule2.clone()));
    
    		assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule, schedule2.clone()]);
    
    		System::set_block_number(21);
    
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    
    		assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule2]);
    
    		System::set_block_number(31);
    
    		assert_ok!(Vesting::claim(Origin::signed(BOB)));
    
    		assert_eq!(VestingSchedules::<Runtime>::contains_key(&BOB), false);
    
    		assert_eq!(PalletBalances::locks(&BOB), vec![]);
    	});
    }