123#![cfg(test)]45use super::*;6use frame_support::{assert_noop, assert_ok, error::BadOrigin};7use mock::{Event, *};8use pallet_balances::{BalanceLock, Reasons};910#[test]11fn vesting_from_chain_spec_works() {12 ExtBuilder::build().execute_with(|| {13 assert_ok!(PalletBalances::ensure_can_withdraw(14 &CHARLIE,15 10,16 WithdrawReasons::TRANSFER,17 2018 ));19 assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 11, WithdrawReasons::TRANSFER, 19).is_err());2021 assert_eq!(22 Vesting::vesting_schedules(&CHARLIE),23 vec![24 VestingSchedule {25 start: 2u64,26 period: 3u64,27 period_count: 1u32,28 per_period: 5u64,29 },30 VestingSchedule {31 start: 2u64 + 3u64,32 period: 3u64,33 period_count: 3u32,34 per_period: 5u64,35 }36 ]37 );3839 MockBlockNumberProvider::set(13);4041 assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));4243 assert_ok!(PalletBalances::ensure_can_withdraw(44 &CHARLIE,45 25,46 WithdrawReasons::TRANSFER,47 548 ));49 assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 26, WithdrawReasons::TRANSFER, 4).is_err());5051 MockBlockNumberProvider::set(14);5253 assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));5455 assert_ok!(PalletBalances::ensure_can_withdraw(56 &CHARLIE,57 30,58 WithdrawReasons::TRANSFER,59 060 ));61 });62}6364#[test]65fn vested_transfer_works() {66 ExtBuilder::build().execute_with(|| {67 System::set_block_number(1);6869 let schedule = VestingSchedule {70 start: 0u64,71 period: 10u64,72 period_count: 1u32,73 per_period: 100u64,74 };75 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));76 assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule.clone()]);77 System::assert_last_event(Event::Vesting(crate::Event::VestingScheduleAdded(ALICE, BOB, schedule)));78 });79}8081#[test]82fn add_new_vesting_schedule_merges_with_current_locked_balance_and_until() {83 ExtBuilder::build().execute_with(|| {84 let schedule = VestingSchedule {85 start: 0u64,86 period: 10u64,87 period_count: 2u32,88 per_period: 10u64,89 };90 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));9192 MockBlockNumberProvider::set(12);9394 let another_schedule = VestingSchedule {95 start: 10u64,96 period: 13u64,97 period_count: 1u32,98 per_period: 7u64,99 };100 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule));101102 assert_eq!(103 PalletBalances::locks(&BOB).get(0),104 Some(&BalanceLock {105 id: VESTING_LOCK_ID,106 amount: 17u64,107 reasons: Reasons::All,108 })109 );110 });111}112113#[test]114fn cannot_use_fund_if_not_claimed() {115 ExtBuilder::build().execute_with(|| {116 let schedule = VestingSchedule {117 start: 10u64,118 period: 10u64,119 period_count: 1u32,120 per_period: 50u64,121 };122 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));123 assert!(PalletBalances::ensure_can_withdraw(&BOB, 1, WithdrawReasons::TRANSFER, 49).is_err());124 });125}126127#[test]128fn vested_transfer_fails_if_zero_period_or_count() {129 ExtBuilder::build().execute_with(|| {130 let schedule = VestingSchedule {131 start: 1u64,132 period: 0u64,133 period_count: 1u32,134 per_period: 100u64,135 };136 assert_noop!(137 Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule),138 Error::<Runtime>::ZeroVestingPeriod139 );140141 let schedule = VestingSchedule {142 start: 1u64,143 period: 1u64,144 period_count: 0u32,145 per_period: 100u64,146 };147 assert_noop!(148 Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule),149 Error::<Runtime>::ZeroVestingPeriodCount150 );151 });152}153154#[test]155fn vested_transfer_fails_if_transfer_err() {156 ExtBuilder::build().execute_with(|| {157 let schedule = VestingSchedule {158 start: 1u64,159 period: 1u64,160 period_count: 1u32,161 per_period: 100u64,162 };163 assert_noop!(164 Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule),165 pallet_balances::Error::<Runtime, _>::InsufficientBalance,166 );167 });168}169170#[test]171fn vested_transfer_fails_if_overflow() {172 ExtBuilder::build().execute_with(|| {173 let schedule = VestingSchedule {174 start: 1u64,175 period: 1u64,176 period_count: 2u32,177 per_period: u64::MAX,178 };179 assert_noop!(180 Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule),181 ArithmeticError::Overflow,182 );183184 let another_schedule = VestingSchedule {185 start: u64::MAX,186 period: 1u64,187 period_count: 2u32,188 per_period: 1u64,189 };190 assert_noop!(191 Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule),192 ArithmeticError::Overflow,193 );194 });195}196197#[test]198fn vested_transfer_fails_if_bad_origin() {199 ExtBuilder::build().execute_with(|| {200 let schedule = VestingSchedule {201 start: 0u64,202 period: 10u64,203 period_count: 1u32,204 per_period: 100u64,205 };206 assert_noop!(207 Vesting::vested_transfer(Origin::signed(CHARLIE), BOB, schedule),208 BadOrigin209 );210 });211}212213#[test]214fn claim_works() {215 ExtBuilder::build().execute_with(|| {216 let schedule = VestingSchedule {217 start: 0u64,218 period: 10u64,219 period_count: 2u32,220 per_period: 10u64,221 };222 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));223224 MockBlockNumberProvider::set(11);225 226 assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10).is_err());227 228 assert_ok!(Vesting::claim(Origin::signed(BOB)));229 assert!(VestingSchedules::<Runtime>::contains_key(BOB));230 assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));231 232 assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());233234 MockBlockNumberProvider::set(21);235 236 assert_ok!(Vesting::claim(Origin::signed(BOB)));237 assert!(!VestingSchedules::<Runtime>::contains_key(BOB));238 assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));239 240 assert_eq!(PalletBalances::free_balance(BOB), 0);241242 243 assert_eq!(PalletBalances::locks(&BOB), vec![]);244 });245}246247#[test]248fn claim_for_works() {249 ExtBuilder::build().execute_with(|| {250 let schedule = VestingSchedule {251 start: 0u64,252 period: 10u64,253 period_count: 2u32,254 per_period: 10u64,255 };256 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));257258 assert_ok!(Vesting::claim_for(Origin::signed(ALICE), BOB));259260 assert_eq!(261 PalletBalances::locks(&BOB).get(0),262 Some(&BalanceLock {263 id: VESTING_LOCK_ID,264 amount: 20u64,265 reasons: Reasons::All,266 })267 );268 assert!(VestingSchedules::<Runtime>::contains_key(&BOB));269270 MockBlockNumberProvider::set(21);271272 assert_ok!(Vesting::claim_for(Origin::signed(ALICE), BOB));273274 275 assert_eq!(PalletBalances::locks(&BOB), vec![]);276 assert!(!VestingSchedules::<Runtime>::contains_key(&BOB));277 });278}279280#[test]281fn update_vesting_schedules_works() {282 ExtBuilder::build().execute_with(|| {283 let schedule = VestingSchedule {284 start: 0u64,285 period: 10u64,286 period_count: 2u32,287 per_period: 10u64,288 };289 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));290291 let updated_schedule = VestingSchedule {292 start: 0u64,293 period: 20u64,294 period_count: 2u32,295 per_period: 10u64,296 };297 assert_ok!(Vesting::update_vesting_schedules(298 Origin::root(),299 BOB,300 vec![updated_schedule]301 ));302303 MockBlockNumberProvider::set(11);304 assert_ok!(Vesting::claim(Origin::signed(BOB)));305 assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());306307 MockBlockNumberProvider::set(21);308 assert_ok!(Vesting::claim(Origin::signed(BOB)));309 assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));310311 312 assert!(VestingSchedules::<Runtime>::contains_key(BOB));313 assert_eq!(314 PalletBalances::locks(&BOB).get(0),315 Some(&BalanceLock {316 id: VESTING_LOCK_ID,317 amount: 10u64,318 reasons: Reasons::All,319 })320 );321 assert_ok!(Vesting::update_vesting_schedules(Origin::root(), BOB, vec![]));322 assert!(!VestingSchedules::<Runtime>::contains_key(BOB));323 assert_eq!(PalletBalances::locks(&BOB), vec![]);324 });325}326327#[test]328fn update_vesting_schedules_fails_if_unexpected_existing_locks() {329 ExtBuilder::build().execute_with(|| {330 assert_ok!(PalletBalances::transfer(Origin::signed(ALICE), BOB, 1));331 PalletBalances::set_lock(*b"prelocks", &BOB, 0u64, WithdrawReasons::all());332 });333}334335#[test]336fn vested_transfer_check_for_min() {337 ExtBuilder::build().execute_with(|| {338 let schedule = VestingSchedule {339 start: 1u64,340 period: 1u64,341 period_count: 1u32,342 per_period: 3u64,343 };344 assert_noop!(345 Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule),346 Error::<Runtime>::AmountLow347 );348 });349}350351#[test]352fn multiple_vesting_schedule_claim_works() {353 ExtBuilder::build().execute_with(|| {354 let schedule = VestingSchedule {355 start: 0u64,356 period: 10u64,357 period_count: 2u32,358 per_period: 10u64,359 };360 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));361362 let schedule2 = VestingSchedule {363 start: 0u64,364 period: 10u64,365 period_count: 3u32,366 per_period: 10u64,367 };368 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule2.clone()));369370 assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule, schedule2.clone()]);371372 MockBlockNumberProvider::set(21);373374 assert_ok!(Vesting::claim(Origin::signed(BOB)));375376 assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule2]);377378 MockBlockNumberProvider::set(31);379380 assert_ok!(Vesting::claim(Origin::signed(BOB)));381382 assert!(!VestingSchedules::<Runtime>::contains_key(&BOB));383384 assert_eq!(PalletBalances::locks(&BOB), vec![]);385 });386}387388#[test]389fn exceeding_maximum_schedules_should_fail() {390 ExtBuilder::build().execute_with(|| {391 let schedule = VestingSchedule {392 start: 0u64,393 period: 10u64,394 period_count: 2u32,395 per_period: 10u64,396 };397 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));398 assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));399 assert_noop!(400 Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()),401 Error::<Runtime>::MaxVestingSchedulesExceeded402 );403404 let schedules = vec![schedule.clone(), schedule.clone(), schedule];405406 assert_noop!(407 Vesting::update_vesting_schedules(Origin::root(), BOB, schedules),408 Error::<Runtime>::MaxVestingSchedulesExceeded409 );410 });411}