|
17 | 17 |
|
18 | 18 | //! The crate's tests. |
19 | 19 |
|
20 | | -use std::collections::BTreeMap; |
| 20 | +use std::{cell::RefCell, collections::BTreeMap}; |
21 | 21 |
|
22 | 22 | use frame_support::{ |
23 | 23 | assert_noop, assert_ok, derive_impl, parameter_types, |
@@ -155,6 +155,7 @@ impl Config for Test { |
155 | 155 | type MaxTurnout = frame_support::traits::TotalIssuanceOf<Balances, Self::AccountId>; |
156 | 156 | type Polls = TestPolls; |
157 | 157 | type BlockNumberProvider = System; |
| 158 | + type VotingHooks = HooksHandler; |
158 | 159 | } |
159 | 160 |
|
160 | 161 | pub fn new_test_ext() -> sp_io::TestExternalities { |
@@ -913,3 +914,140 @@ fn errors_with_remove_vote_work() { |
913 | 914 | ); |
914 | 915 | }); |
915 | 916 | } |
| 917 | + |
| 918 | +thread_local! { |
| 919 | + static LAST_ON_VOTE_DATA: RefCell<Option<(u64, u8, AccountVote<u64>)>> = RefCell::new(None); |
| 920 | + static LAST_ON_REMOVE_VOTE_DATA: RefCell<Option<(u64, u8, Status)>> = RefCell::new(None); |
| 921 | + static LAST_LOCKED_IF_UNSUCCESSFUL_VOTE_DATA: RefCell<Option<(u64, u8)>> = RefCell::new(None); |
| 922 | + static REMOVE_VOTE_LOCKED_AMOUNT: RefCell<Option<u64>> = RefCell::new(None); |
| 923 | +} |
| 924 | + |
| 925 | +pub struct HooksHandler; |
| 926 | + |
| 927 | +impl HooksHandler { |
| 928 | + fn last_on_vote_data() -> Option<(u64, u8, AccountVote<u64>)> { |
| 929 | + LAST_ON_VOTE_DATA.with(|data| *data.borrow()) |
| 930 | + } |
| 931 | + |
| 932 | + fn last_on_remove_vote_data() -> Option<(u64, u8, Status)> { |
| 933 | + LAST_ON_REMOVE_VOTE_DATA.with(|data| *data.borrow()) |
| 934 | + } |
| 935 | + |
| 936 | + fn last_locked_if_unsuccessful_vote_data() -> Option<(u64, u8)> { |
| 937 | + LAST_LOCKED_IF_UNSUCCESSFUL_VOTE_DATA.with(|data| *data.borrow()) |
| 938 | + } |
| 939 | + |
| 940 | + fn reset() { |
| 941 | + LAST_ON_VOTE_DATA.with(|data| *data.borrow_mut() = None); |
| 942 | + LAST_ON_REMOVE_VOTE_DATA.with(|data| *data.borrow_mut() = None); |
| 943 | + LAST_LOCKED_IF_UNSUCCESSFUL_VOTE_DATA.with(|data| *data.borrow_mut() = None); |
| 944 | + REMOVE_VOTE_LOCKED_AMOUNT.with(|data| *data.borrow_mut() = None); |
| 945 | + } |
| 946 | + |
| 947 | + fn with_remove_locked_amount(v: u64) { |
| 948 | + REMOVE_VOTE_LOCKED_AMOUNT.with(|data| *data.borrow_mut() = Some(v)); |
| 949 | + } |
| 950 | +} |
| 951 | + |
| 952 | +impl VotingHooks<u64, u8, u64> for HooksHandler { |
| 953 | + fn on_before_vote(who: &u64, ref_index: u8, vote: AccountVote<u64>) -> DispatchResult { |
| 954 | + LAST_ON_VOTE_DATA.with(|data| { |
| 955 | + *data.borrow_mut() = Some((*who, ref_index, vote)); |
| 956 | + }); |
| 957 | + Ok(()) |
| 958 | + } |
| 959 | + |
| 960 | + fn on_remove_vote(who: &u64, ref_index: u8, ongoing: Status) { |
| 961 | + LAST_ON_REMOVE_VOTE_DATA.with(|data| { |
| 962 | + *data.borrow_mut() = Some((*who, ref_index, ongoing)); |
| 963 | + }); |
| 964 | + } |
| 965 | + |
| 966 | + fn lock_balance_on_unsuccessful_vote(who: &u64, ref_index: u8) -> Option<u64> { |
| 967 | + LAST_LOCKED_IF_UNSUCCESSFUL_VOTE_DATA.with(|data| { |
| 968 | + *data.borrow_mut() = Some((*who, ref_index)); |
| 969 | + |
| 970 | + REMOVE_VOTE_LOCKED_AMOUNT.with(|data| *data.borrow()) |
| 971 | + }) |
| 972 | + } |
| 973 | + |
| 974 | + #[cfg(feature = "runtime-benchmarks")] |
| 975 | + fn on_vote_worst_case(_who: &u64) {} |
| 976 | + |
| 977 | + #[cfg(feature = "runtime-benchmarks")] |
| 978 | + fn on_remove_vote_worst_case(_who: &u64) {} |
| 979 | +} |
| 980 | + |
| 981 | +#[test] |
| 982 | +fn voting_hooks_are_called_correctly() { |
| 983 | + new_test_ext().execute_with(|| { |
| 984 | + let c = class(3); |
| 985 | + |
| 986 | + let usable_balance_1 = Balances::usable_balance(1); |
| 987 | + dbg!(usable_balance_1); |
| 988 | + |
| 989 | + // Voting |
| 990 | + assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, aye(1, 1))); |
| 991 | + assert_eq!( |
| 992 | + HooksHandler::last_on_vote_data(), |
| 993 | + Some(( |
| 994 | + 1, |
| 995 | + 3, |
| 996 | + AccountVote::Standard { |
| 997 | + vote: Vote { aye: true, conviction: Conviction::Locked1x }, |
| 998 | + balance: 1 |
| 999 | + } |
| 1000 | + )) |
| 1001 | + ); |
| 1002 | + assert_ok!(Voting::vote(RuntimeOrigin::signed(2), 3, nay(20, 2))); |
| 1003 | + assert_eq!( |
| 1004 | + HooksHandler::last_on_vote_data(), |
| 1005 | + Some(( |
| 1006 | + 2, |
| 1007 | + 3, |
| 1008 | + AccountVote::Standard { |
| 1009 | + vote: Vote { aye: false, conviction: Conviction::Locked2x }, |
| 1010 | + balance: 20 |
| 1011 | + } |
| 1012 | + )) |
| 1013 | + ); |
| 1014 | + HooksHandler::reset(); |
| 1015 | + |
| 1016 | + // removing vote while ongoing |
| 1017 | + assert_ok!(Voting::vote(RuntimeOrigin::signed(3), 3, nay(20, 0))); |
| 1018 | + assert_eq!( |
| 1019 | + HooksHandler::last_on_vote_data(), |
| 1020 | + Some(( |
| 1021 | + 3, |
| 1022 | + 3, |
| 1023 | + AccountVote::Standard { |
| 1024 | + vote: Vote { aye: false, conviction: Conviction::None }, |
| 1025 | + balance: 20 |
| 1026 | + } |
| 1027 | + )) |
| 1028 | + ); |
| 1029 | + assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(3), Some(c), 3)); |
| 1030 | + assert_eq!(HooksHandler::last_on_remove_vote_data(), Some((3, 3, Status::Ongoing))); |
| 1031 | + HooksHandler::reset(); |
| 1032 | + |
| 1033 | + Polls::set(vec![(3, Completed(3, false))].into_iter().collect()); |
| 1034 | + |
| 1035 | + // removing successful vote while completed |
| 1036 | + assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(2), Some(c), 3)); |
| 1037 | + assert_eq!(HooksHandler::last_on_remove_vote_data(), Some((2, 3, Status::Completed))); |
| 1038 | + assert_eq!(HooksHandler::last_locked_if_unsuccessful_vote_data(), None); |
| 1039 | + |
| 1040 | + HooksHandler::reset(); |
| 1041 | + |
| 1042 | + HooksHandler::with_remove_locked_amount(5); |
| 1043 | + |
| 1044 | + // removing unsuccessful vote when completed |
| 1045 | + assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(1), Some(c), 3)); |
| 1046 | + assert_eq!(HooksHandler::last_on_remove_vote_data(), Some((1, 3, Status::Completed))); |
| 1047 | + assert_eq!(HooksHandler::last_locked_if_unsuccessful_vote_data(), Some((1, 3))); |
| 1048 | + |
| 1049 | + // Removing unsuccessful vote when completed should lock if given amount from the hook |
| 1050 | + assert_ok!(Voting::unlock(RuntimeOrigin::signed(1), c, 1)); |
| 1051 | + assert_eq!(Balances::usable_balance(1), 5); |
| 1052 | + }); |
| 1053 | +} |
0 commit comments