fixtures.rs 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. #![cfg(test)]
  2. use frame_support::dispatch::{DispatchError, DispatchResult};
  3. use frame_support::StorageMap;
  4. use frame_system::{EventRecord, Phase, RawOrigin};
  5. use sp_runtime::traits::Hash;
  6. use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
  7. use super::hiring_workflow::HiringWorkflow;
  8. use super::mock::{Balances, LockId, System, Test, TestEvent, TestWorkingGroup};
  9. use crate::types::StakeParameters;
  10. use crate::{
  11. Application, ApplyOnOpeningParameters, DefaultInstance, Opening, OpeningType, Penalty,
  12. RawEvent, StakePolicy, Worker,
  13. };
  14. pub struct EventFixture;
  15. impl EventFixture {
  16. pub fn assert_last_crate_event(
  17. expected_raw_event: RawEvent<u64, u64, BTreeMap<u64, u64>, u64, u64, u64, DefaultInstance>,
  18. ) {
  19. let converted_event = TestEvent::crate_DefaultInstance(expected_raw_event);
  20. Self::assert_last_global_event(converted_event)
  21. }
  22. pub fn assert_last_global_event(expected_event: TestEvent) {
  23. let expected_event = EventRecord {
  24. phase: Phase::Initialization,
  25. event: expected_event,
  26. topics: vec![],
  27. };
  28. assert_eq!(System::events().pop().unwrap(), expected_event);
  29. }
  30. }
  31. pub struct AddOpeningFixture {
  32. origin: RawOrigin<u64>,
  33. description: Vec<u8>,
  34. opening_type: OpeningType,
  35. starting_block: u64,
  36. stake_policy: Option<StakePolicy<u64, u64>>,
  37. reward_per_block: Option<u64>,
  38. }
  39. impl Default for AddOpeningFixture {
  40. fn default() -> Self {
  41. Self {
  42. origin: RawOrigin::Signed(1),
  43. description: b"human_text".to_vec(),
  44. opening_type: OpeningType::Regular,
  45. starting_block: 0,
  46. stake_policy: None,
  47. reward_per_block: None,
  48. }
  49. }
  50. }
  51. impl AddOpeningFixture {
  52. pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
  53. let saved_opening_next_id = TestWorkingGroup::next_opening_id();
  54. let actual_result = self.call().map(|_| ());
  55. assert_eq!(actual_result.clone(), expected_result);
  56. if actual_result.is_ok() {
  57. assert_eq!(
  58. TestWorkingGroup::next_opening_id(),
  59. saved_opening_next_id + 1
  60. );
  61. let opening_id = saved_opening_next_id;
  62. let actual_opening = TestWorkingGroup::opening_by_id(opening_id);
  63. let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&self.description);
  64. let expected_opening = Opening {
  65. created: self.starting_block,
  66. description_hash: expected_hash.as_ref().to_vec(),
  67. opening_type: self.opening_type,
  68. stake_policy: self.stake_policy.clone(),
  69. reward_per_block: self.reward_per_block.clone(),
  70. };
  71. assert_eq!(actual_opening, expected_opening);
  72. }
  73. saved_opening_next_id
  74. }
  75. pub fn call(&self) -> Result<u64, DispatchError> {
  76. let saved_opening_next_id = TestWorkingGroup::next_opening_id();
  77. TestWorkingGroup::add_opening(
  78. self.origin.clone().into(),
  79. self.description.clone(),
  80. self.opening_type,
  81. self.stake_policy.clone(),
  82. self.reward_per_block.clone(),
  83. )?;
  84. Ok(saved_opening_next_id)
  85. }
  86. pub fn with_opening_type(self, opening_type: OpeningType) -> Self {
  87. Self {
  88. opening_type,
  89. ..self
  90. }
  91. }
  92. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  93. Self { origin, ..self }
  94. }
  95. pub fn with_starting_block(self, starting_block: u64) -> Self {
  96. Self {
  97. starting_block,
  98. ..self
  99. }
  100. }
  101. pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
  102. Self {
  103. stake_policy,
  104. ..self
  105. }
  106. }
  107. pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
  108. Self {
  109. reward_per_block,
  110. ..self
  111. }
  112. }
  113. }
  114. pub struct ApplyOnOpeningFixture {
  115. origin: RawOrigin<u64>,
  116. member_id: u64,
  117. opening_id: u64,
  118. role_account_id: u64,
  119. reward_account_id: u64,
  120. description: Vec<u8>,
  121. stake_parameters: Option<StakeParameters<u64, u64>>,
  122. }
  123. impl ApplyOnOpeningFixture {
  124. pub fn with_text(self, text: Vec<u8>) -> Self {
  125. Self {
  126. description: text,
  127. ..self
  128. }
  129. }
  130. pub fn with_origin(self, origin: RawOrigin<u64>, member_id: u64) -> Self {
  131. Self {
  132. origin,
  133. member_id,
  134. ..self
  135. }
  136. }
  137. pub fn with_stake_parameters(
  138. self,
  139. stake_parameters: Option<StakeParameters<u64, u64>>,
  140. ) -> Self {
  141. Self {
  142. stake_parameters,
  143. ..self
  144. }
  145. }
  146. pub fn default_for_opening_id(opening_id: u64) -> Self {
  147. Self {
  148. origin: RawOrigin::Signed(1),
  149. member_id: 1,
  150. opening_id,
  151. role_account_id: 1,
  152. reward_account_id: 1,
  153. description: b"human_text".to_vec(),
  154. stake_parameters: None,
  155. }
  156. }
  157. pub fn call(&self) -> Result<u64, DispatchError> {
  158. let saved_application_next_id = TestWorkingGroup::next_application_id();
  159. TestWorkingGroup::apply_on_opening(
  160. self.origin.clone().into(),
  161. ApplyOnOpeningParameters::<Test> {
  162. member_id: self.member_id,
  163. opening_id: self.opening_id,
  164. role_account_id: self.role_account_id,
  165. reward_account_id: self.reward_account_id,
  166. description: self.description.clone(),
  167. stake_parameters: self.stake_parameters.clone(),
  168. },
  169. )?;
  170. Ok(saved_application_next_id)
  171. }
  172. pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
  173. let saved_application_next_id = TestWorkingGroup::next_application_id();
  174. let actual_result = self.call().map(|_| ());
  175. assert_eq!(actual_result.clone(), expected_result);
  176. if actual_result.is_ok() {
  177. assert_eq!(
  178. TestWorkingGroup::next_application_id(),
  179. saved_application_next_id + 1
  180. );
  181. let application_id = saved_application_next_id;
  182. let actual_application = TestWorkingGroup::application_by_id(application_id);
  183. let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&self.description);
  184. let expected_application = Application::<Test> {
  185. role_account_id: self.role_account_id,
  186. reward_account_id: self.reward_account_id,
  187. staking_account_id: self
  188. .stake_parameters
  189. .clone()
  190. .map(|sp| sp.staking_account_id),
  191. member_id: self.member_id,
  192. description_hash: expected_hash.as_ref().to_vec(),
  193. };
  194. assert_eq!(actual_application, expected_application);
  195. }
  196. saved_application_next_id
  197. }
  198. }
  199. pub struct FillOpeningFixture {
  200. origin: RawOrigin<u64>,
  201. opening_id: u64,
  202. successful_application_ids: BTreeSet<u64>,
  203. role_account_id: u64,
  204. reward_account_id: u64,
  205. staking_account_id: Option<u64>,
  206. stake_policy: Option<StakePolicy<u64, u64>>,
  207. reward_per_block: Option<u64>,
  208. created_at: u64,
  209. }
  210. impl FillOpeningFixture {
  211. pub fn default_for_ids(opening_id: u64, application_ids: Vec<u64>) -> Self {
  212. let application_ids: BTreeSet<u64> = application_ids.iter().map(|x| *x).collect();
  213. Self {
  214. origin: RawOrigin::Signed(1),
  215. opening_id,
  216. successful_application_ids: application_ids,
  217. role_account_id: 1,
  218. reward_account_id: 1,
  219. staking_account_id: None,
  220. stake_policy: None,
  221. reward_per_block: None,
  222. created_at: 0,
  223. }
  224. }
  225. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  226. Self { origin, ..self }
  227. }
  228. pub fn with_created_at(self, created_at: u64) -> Self {
  229. Self { created_at, ..self }
  230. }
  231. pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
  232. Self {
  233. stake_policy,
  234. ..self
  235. }
  236. }
  237. pub fn with_staking_account_id(self, staking_account_id: Option<u64>) -> Self {
  238. Self {
  239. staking_account_id,
  240. ..self
  241. }
  242. }
  243. pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
  244. Self {
  245. reward_per_block,
  246. ..self
  247. }
  248. }
  249. pub fn call(&self) -> Result<u64, DispatchError> {
  250. let saved_worker_next_id = TestWorkingGroup::next_worker_id();
  251. TestWorkingGroup::fill_opening(
  252. self.origin.clone().into(),
  253. self.opening_id,
  254. self.successful_application_ids.clone(),
  255. )?;
  256. Ok(saved_worker_next_id)
  257. }
  258. pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
  259. let saved_worker_count = TestWorkingGroup::active_worker_count();
  260. let saved_worker_next_id = TestWorkingGroup::next_worker_id();
  261. let actual_result = self.call().map(|_| ());
  262. assert_eq!(actual_result.clone(), expected_result);
  263. if actual_result.is_ok() {
  264. assert_eq!(TestWorkingGroup::next_worker_id(), saved_worker_next_id + 1);
  265. let worker_id = saved_worker_next_id;
  266. assert!(!<crate::OpeningById<Test, DefaultInstance>>::contains_key(
  267. self.opening_id
  268. ));
  269. for application_id in self.successful_application_ids.iter() {
  270. assert!(
  271. !<crate::ApplicationById<Test, DefaultInstance>>::contains_key(application_id)
  272. );
  273. }
  274. let expected_worker = Worker::<Test> {
  275. member_id: 1,
  276. role_account_id: self.role_account_id,
  277. reward_account_id: self.reward_account_id,
  278. staking_account_id: self.staking_account_id,
  279. started_leaving_at: None,
  280. job_unstaking_period: self
  281. .stake_policy
  282. .as_ref()
  283. .map_or(0, |sp| sp.leaving_unstaking_period),
  284. reward_per_block: self.reward_per_block,
  285. missed_reward: None,
  286. created_at: self.created_at,
  287. };
  288. let actual_worker = TestWorkingGroup::worker_by_id(worker_id);
  289. assert_eq!(actual_worker, expected_worker);
  290. let expected_worker_count =
  291. saved_worker_count + (self.successful_application_ids.len() as u32);
  292. assert_eq!(
  293. TestWorkingGroup::active_worker_count(),
  294. expected_worker_count
  295. );
  296. }
  297. saved_worker_next_id
  298. }
  299. }
  300. pub struct HireLeadFixture {
  301. setup_environment: bool,
  302. stake_policy: Option<StakePolicy<u64, u64>>,
  303. reward_per_block: Option<u64>,
  304. }
  305. impl Default for HireLeadFixture {
  306. fn default() -> Self {
  307. Self {
  308. setup_environment: true,
  309. stake_policy: None,
  310. reward_per_block: None,
  311. }
  312. }
  313. }
  314. impl HireLeadFixture {
  315. pub fn with_setup_environment(self, setup_environment: bool) -> Self {
  316. Self {
  317. setup_environment,
  318. ..self
  319. }
  320. }
  321. pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
  322. Self {
  323. stake_policy,
  324. ..self
  325. }
  326. }
  327. pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
  328. Self {
  329. reward_per_block,
  330. ..self
  331. }
  332. }
  333. pub fn hire_lead(self) -> u64 {
  334. HiringWorkflow::default()
  335. .with_setup_environment(self.setup_environment)
  336. .with_opening_type(OpeningType::Leader)
  337. .with_stake_policy(self.stake_policy)
  338. .with_reward_per_block(self.reward_per_block)
  339. .add_application(b"leader".to_vec())
  340. .execute()
  341. .unwrap()
  342. }
  343. pub fn expect(self, error: DispatchError) {
  344. HiringWorkflow::default()
  345. .with_setup_environment(self.setup_environment)
  346. .with_opening_type(OpeningType::Leader)
  347. .with_stake_policy(self.stake_policy)
  348. .with_reward_per_block(self.reward_per_block)
  349. .add_application(b"leader".to_vec())
  350. .expect(Err(error))
  351. .execute();
  352. }
  353. }
  354. pub struct HireRegularWorkerFixture {
  355. setup_environment: bool,
  356. stake_policy: Option<StakePolicy<u64, u64>>,
  357. reward_per_block: Option<u64>,
  358. }
  359. impl Default for HireRegularWorkerFixture {
  360. fn default() -> Self {
  361. Self {
  362. setup_environment: true,
  363. stake_policy: None,
  364. reward_per_block: None,
  365. }
  366. }
  367. }
  368. impl HireRegularWorkerFixture {
  369. pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
  370. Self {
  371. stake_policy,
  372. ..self
  373. }
  374. }
  375. pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
  376. Self {
  377. reward_per_block,
  378. ..self
  379. }
  380. }
  381. pub fn hire(self) -> u64 {
  382. HiringWorkflow::default()
  383. .with_setup_environment(self.setup_environment)
  384. .with_opening_type(OpeningType::Regular)
  385. .with_stake_policy(self.stake_policy)
  386. .with_reward_per_block(self.reward_per_block)
  387. .add_application(b"worker".to_vec())
  388. .execute()
  389. .unwrap()
  390. }
  391. }
  392. pub struct UpdateWorkerRoleAccountFixture {
  393. worker_id: u64,
  394. new_role_account_id: u64,
  395. origin: RawOrigin<u64>,
  396. }
  397. impl UpdateWorkerRoleAccountFixture {
  398. pub fn default_with_ids(worker_id: u64, new_role_account_id: u64) -> Self {
  399. Self {
  400. worker_id,
  401. new_role_account_id,
  402. origin: RawOrigin::Signed(1),
  403. }
  404. }
  405. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  406. Self { origin, ..self }
  407. }
  408. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  409. let actual_result = TestWorkingGroup::update_role_account(
  410. self.origin.clone().into(),
  411. self.worker_id,
  412. self.new_role_account_id,
  413. );
  414. assert_eq!(actual_result, expected_result);
  415. if actual_result.is_ok() {
  416. let worker = TestWorkingGroup::worker_by_id(self.worker_id);
  417. assert_eq!(worker.role_account_id, self.new_role_account_id);
  418. }
  419. }
  420. }
  421. pub(crate) struct LeaveWorkerRoleFixture {
  422. worker_id: u64,
  423. origin: RawOrigin<u64>,
  424. stake_policy: Option<StakePolicy<u64, u64>>,
  425. }
  426. impl LeaveWorkerRoleFixture {
  427. pub fn default_for_worker_id(worker_id: u64) -> Self {
  428. Self {
  429. worker_id,
  430. origin: RawOrigin::Signed(1),
  431. stake_policy: None,
  432. }
  433. }
  434. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  435. Self { origin, ..self }
  436. }
  437. pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
  438. Self {
  439. stake_policy,
  440. ..self
  441. }
  442. }
  443. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  444. let actual_result =
  445. TestWorkingGroup::leave_role(self.origin.clone().into(), self.worker_id);
  446. assert_eq!(actual_result, expected_result);
  447. if actual_result.is_ok() {
  448. if self.stake_policy.is_some() {
  449. let worker = TestWorkingGroup::worker_by_id(self.worker_id);
  450. if worker.job_unstaking_period > 0 {
  451. assert_eq!(
  452. worker.started_leaving_at,
  453. Some(<frame_system::Module<Test>>::block_number())
  454. );
  455. return;
  456. }
  457. }
  458. assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  459. self.worker_id
  460. ));
  461. }
  462. }
  463. }
  464. pub struct TerminateWorkerRoleFixture {
  465. worker_id: u64,
  466. origin: RawOrigin<u64>,
  467. penalty: Option<Penalty<u64>>,
  468. }
  469. impl TerminateWorkerRoleFixture {
  470. pub fn default_for_worker_id(worker_id: u64) -> Self {
  471. Self {
  472. worker_id,
  473. origin: RawOrigin::Signed(1),
  474. penalty: None,
  475. }
  476. }
  477. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  478. Self { origin, ..self }
  479. }
  480. pub fn with_penalty(self, penalty: Option<Penalty<u64>>) -> Self {
  481. Self { penalty, ..self }
  482. }
  483. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  484. let actual_result = TestWorkingGroup::terminate_role(
  485. self.origin.clone().into(),
  486. self.worker_id,
  487. self.penalty.clone(),
  488. );
  489. assert_eq!(actual_result, expected_result);
  490. if actual_result.is_ok() {
  491. if actual_result.is_ok() {
  492. assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  493. self.worker_id
  494. ));
  495. }
  496. }
  497. }
  498. }
  499. pub fn increase_total_balance_issuance_using_account_id(account_id: u64, balance: u64) {
  500. let _ =
  501. <Balances as frame_support::traits::Currency<u64>>::deposit_creating(&account_id, balance);
  502. }
  503. pub struct SlashWorkerStakeFixture {
  504. origin: RawOrigin<u64>,
  505. worker_id: u64,
  506. account_id: u64,
  507. penalty: Penalty<u64>,
  508. }
  509. impl SlashWorkerStakeFixture {
  510. pub fn default_for_worker_id(worker_id: u64) -> Self {
  511. let account_id = 1;
  512. let lead_account_id = get_current_lead_account_id();
  513. Self {
  514. origin: RawOrigin::Signed(lead_account_id),
  515. worker_id,
  516. penalty: Penalty {
  517. slashing_text: Vec::new(),
  518. slashing_amount: 10,
  519. },
  520. account_id,
  521. }
  522. }
  523. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  524. Self { origin, ..self }
  525. }
  526. pub fn with_penalty(self, penalty: Penalty<u64>) -> Self {
  527. Self { penalty, ..self }
  528. }
  529. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  530. let old_balance = Balances::usable_balance(&self.account_id);
  531. let old_stake = get_stake_balance(&self.account_id);
  532. let actual_result = TestWorkingGroup::slash_stake(
  533. self.origin.clone().into(),
  534. self.worker_id,
  535. self.penalty.clone(),
  536. );
  537. assert_eq!(actual_result, expected_result);
  538. if actual_result.is_ok() {
  539. // stake decreased
  540. assert_eq!(
  541. old_stake,
  542. get_stake_balance(&self.account_id) + self.penalty.slashing_amount
  543. );
  544. let new_balance = Balances::usable_balance(&self.account_id);
  545. // worker balance unchanged
  546. assert_eq!(new_balance, old_balance,);
  547. }
  548. }
  549. }
  550. pub(crate) fn get_stake_balance(account_id: &u64) -> u64 {
  551. let locks = Balances::locks(account_id);
  552. let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
  553. existing_lock.map_or(0, |lock| lock.amount)
  554. }
  555. fn get_current_lead_account_id() -> u64 {
  556. let leader_worker_id = TestWorkingGroup::current_lead();
  557. if let Some(leader_worker_id) = leader_worker_id {
  558. let leader = TestWorkingGroup::worker_by_id(leader_worker_id);
  559. leader.role_account_id
  560. } else {
  561. 0 // return invalid lead_account_id for testing
  562. }
  563. }
  564. pub struct DecreaseWorkerStakeFixture {
  565. origin: RawOrigin<u64>,
  566. worker_id: u64,
  567. balance: u64,
  568. account_id: u64,
  569. }
  570. impl DecreaseWorkerStakeFixture {
  571. pub fn default_for_worker_id(worker_id: u64) -> Self {
  572. let account_id = 1;
  573. let lead_account_id = get_current_lead_account_id();
  574. Self {
  575. origin: RawOrigin::Signed(lead_account_id),
  576. worker_id,
  577. balance: 10,
  578. account_id,
  579. }
  580. }
  581. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  582. Self { origin, ..self }
  583. }
  584. pub fn with_balance(self, balance: u64) -> Self {
  585. Self { balance, ..self }
  586. }
  587. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  588. let old_balance = Balances::usable_balance(&self.account_id);
  589. let old_stake = get_stake_balance(&self.account_id);
  590. let actual_result = TestWorkingGroup::decrease_stake(
  591. self.origin.clone().into(),
  592. self.worker_id,
  593. self.balance,
  594. );
  595. assert_eq!(actual_result, expected_result);
  596. if actual_result.is_ok() {
  597. // new stake was set
  598. assert_eq!(self.balance, get_stake_balance(&self.account_id));
  599. let new_balance = Balances::usable_balance(&self.account_id);
  600. // worker balance equilibrium
  601. assert_eq!(old_balance + old_stake, new_balance + self.balance);
  602. }
  603. }
  604. }
  605. pub struct IncreaseWorkerStakeFixture {
  606. origin: RawOrigin<u64>,
  607. worker_id: u64,
  608. balance: u64,
  609. account_id: u64,
  610. }
  611. impl IncreaseWorkerStakeFixture {
  612. pub fn default_for_worker_id(worker_id: u64) -> Self {
  613. let account_id = 1;
  614. Self {
  615. origin: RawOrigin::Signed(1),
  616. worker_id,
  617. balance: 10,
  618. account_id,
  619. }
  620. }
  621. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  622. Self { origin, ..self }
  623. }
  624. pub fn with_balance(self, balance: u64) -> Self {
  625. Self { balance, ..self }
  626. }
  627. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  628. let old_balance = Balances::usable_balance(&self.account_id);
  629. let old_stake = get_stake_balance(&self.account_id);
  630. let actual_result = TestWorkingGroup::increase_stake(
  631. self.origin.clone().into(),
  632. self.worker_id,
  633. self.balance,
  634. );
  635. assert_eq!(actual_result, expected_result);
  636. if actual_result.is_ok() {
  637. // new stake was set
  638. assert_eq!(
  639. self.balance + old_stake,
  640. get_stake_balance(&self.account_id)
  641. );
  642. let new_balance = Balances::usable_balance(&self.account_id);
  643. // worker balance equilibrium
  644. assert_eq!(
  645. old_balance + old_stake,
  646. new_balance + self.balance + old_stake
  647. );
  648. }
  649. }
  650. }
  651. pub struct WithdrawApplicationFixture {
  652. origin: RawOrigin<u64>,
  653. application_id: u64,
  654. stake: bool,
  655. account_id: u64,
  656. }
  657. impl WithdrawApplicationFixture {
  658. pub fn with_signer(self, account_id: u64) -> Self {
  659. Self {
  660. origin: RawOrigin::Signed(account_id),
  661. ..self
  662. }
  663. }
  664. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  665. Self { origin, ..self }
  666. }
  667. pub fn with_stake(self) -> Self {
  668. Self {
  669. stake: true,
  670. ..self
  671. }
  672. }
  673. pub fn default_for_application_id(application_id: u64) -> Self {
  674. Self {
  675. origin: RawOrigin::Signed(1),
  676. application_id,
  677. stake: false,
  678. account_id: 1,
  679. }
  680. }
  681. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  682. let old_balance = Balances::usable_balance(&self.account_id);
  683. let old_stake = get_stake_balance(&self.account_id);
  684. let actual_result =
  685. TestWorkingGroup::withdraw_application(self.origin.clone().into(), self.application_id);
  686. assert_eq!(actual_result.clone(), expected_result);
  687. if actual_result.is_ok() {
  688. if self.stake {
  689. // the stake was removed
  690. assert_eq!(0, get_stake_balance(&self.account_id));
  691. let new_balance = Balances::usable_balance(&self.account_id);
  692. // worker balance equilibrium
  693. assert_eq!(old_balance + old_stake, new_balance);
  694. }
  695. }
  696. }
  697. }
  698. pub struct CancelOpeningFixture {
  699. origin: RawOrigin<u64>,
  700. opening_id: u64,
  701. }
  702. impl CancelOpeningFixture {
  703. pub fn default_for_opening_id(opening_id: u64) -> Self {
  704. Self {
  705. origin: RawOrigin::Signed(1),
  706. opening_id,
  707. }
  708. }
  709. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  710. Self { origin, ..self }
  711. }
  712. pub fn call(&self) -> DispatchResult {
  713. TestWorkingGroup::cancel_opening(self.origin.clone().into(), self.opening_id)
  714. }
  715. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  716. if expected_result.is_ok() {
  717. assert!(<crate::OpeningById<Test, DefaultInstance>>::contains_key(
  718. self.opening_id
  719. ));
  720. }
  721. let actual_result = self.call().map(|_| ());
  722. assert_eq!(actual_result.clone(), expected_result);
  723. if actual_result.is_ok() {
  724. assert!(!<crate::OpeningById<Test, DefaultInstance>>::contains_key(
  725. self.opening_id
  726. ));
  727. }
  728. }
  729. }
  730. pub struct SetBudgetFixture {
  731. origin: RawOrigin<u64>,
  732. new_budget: u64,
  733. }
  734. impl Default for SetBudgetFixture {
  735. fn default() -> Self {
  736. Self {
  737. origin: RawOrigin::Root,
  738. new_budget: 1000000,
  739. }
  740. }
  741. }
  742. impl SetBudgetFixture {
  743. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  744. Self { origin, ..self }
  745. }
  746. pub fn with_budget(self, new_budget: u64) -> Self {
  747. Self { new_budget, ..self }
  748. }
  749. pub fn execute(self) {
  750. self.call().unwrap();
  751. }
  752. pub fn call(&self) -> DispatchResult {
  753. TestWorkingGroup::set_budget(self.origin.clone().into(), self.new_budget)
  754. }
  755. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  756. let old_budget = TestWorkingGroup::budget();
  757. let actual_result = self.call().map(|_| ());
  758. assert_eq!(actual_result.clone(), expected_result);
  759. let new_budget = TestWorkingGroup::budget();
  760. if actual_result.is_ok() {
  761. assert_eq!(new_budget, self.new_budget);
  762. } else {
  763. assert_eq!(new_budget, old_budget);
  764. }
  765. }
  766. }
  767. pub struct UpdateRewardAccountFixture {
  768. worker_id: u64,
  769. new_reward_account_id: u64,
  770. origin: RawOrigin<u64>,
  771. }
  772. impl UpdateRewardAccountFixture {
  773. pub fn default_with_ids(worker_id: u64, new_reward_account_id: u64) -> Self {
  774. Self {
  775. worker_id,
  776. new_reward_account_id,
  777. origin: RawOrigin::Signed(1),
  778. }
  779. }
  780. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  781. Self { origin, ..self }
  782. }
  783. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  784. let actual_result = TestWorkingGroup::update_reward_account(
  785. self.origin.clone().into(),
  786. self.worker_id,
  787. self.new_reward_account_id,
  788. );
  789. assert_eq!(actual_result.clone(), expected_result);
  790. if actual_result.is_ok() {
  791. let worker = TestWorkingGroup::worker_by_id(self.worker_id);
  792. assert_eq!(worker.reward_account_id, self.new_reward_account_id);
  793. }
  794. }
  795. }
  796. pub struct UpdateRewardAmountFixture {
  797. worker_id: u64,
  798. reward_per_block: Option<u64>,
  799. origin: RawOrigin<u64>,
  800. }
  801. impl UpdateRewardAmountFixture {
  802. pub fn default_for_worker_id(worker_id: u64) -> Self {
  803. let lead_account_id = get_current_lead_account_id();
  804. Self {
  805. worker_id,
  806. reward_per_block: None,
  807. origin: RawOrigin::Signed(lead_account_id),
  808. }
  809. }
  810. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  811. Self { origin, ..self }
  812. }
  813. pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
  814. Self {
  815. reward_per_block,
  816. ..self
  817. }
  818. }
  819. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  820. let actual_result = TestWorkingGroup::update_reward_amount(
  821. self.origin.clone().into(),
  822. self.worker_id,
  823. self.reward_per_block,
  824. );
  825. assert_eq!(actual_result.clone(), expected_result);
  826. if actual_result.is_ok() {
  827. let worker = TestWorkingGroup::worker_by_id(self.worker_id);
  828. assert_eq!(worker.reward_per_block, self.reward_per_block);
  829. }
  830. }
  831. }
  832. pub struct SetStatusTextFixture {
  833. origin: RawOrigin<u64>,
  834. new_status_text: Option<Vec<u8>>,
  835. }
  836. impl Default for SetStatusTextFixture {
  837. fn default() -> Self {
  838. Self {
  839. origin: RawOrigin::Signed(1),
  840. new_status_text: None,
  841. }
  842. }
  843. }
  844. impl SetStatusTextFixture {
  845. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  846. Self { origin, ..self }
  847. }
  848. pub fn with_status_text(self, new_status_text: Option<Vec<u8>>) -> Self {
  849. Self {
  850. new_status_text,
  851. ..self
  852. }
  853. }
  854. pub fn call(&self) -> DispatchResult {
  855. TestWorkingGroup::set_status_text(self.origin.clone().into(), self.new_status_text.clone())
  856. }
  857. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  858. let old_text_hash = TestWorkingGroup::status_text_hash();
  859. let actual_result = self.call().map(|_| ());
  860. assert_eq!(actual_result.clone(), expected_result);
  861. let new_text_hash = TestWorkingGroup::status_text_hash();
  862. if actual_result.is_ok() {
  863. let expected_hash = <Test as frame_system::Trait>::Hashing::hash(
  864. &self.new_status_text.clone().unwrap(),
  865. );
  866. assert_eq!(new_text_hash, expected_hash.as_ref().to_vec());
  867. } else {
  868. assert_eq!(new_text_hash, old_text_hash);
  869. }
  870. }
  871. }
  872. pub struct SpendFromBudgetFixture {
  873. origin: RawOrigin<u64>,
  874. account_id: u64,
  875. amount: u64,
  876. rationale: Option<Vec<u8>>,
  877. }
  878. impl Default for SpendFromBudgetFixture {
  879. fn default() -> Self {
  880. Self {
  881. origin: RawOrigin::Signed(1),
  882. account_id: 1,
  883. amount: 100,
  884. rationale: None,
  885. }
  886. }
  887. }
  888. impl SpendFromBudgetFixture {
  889. pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
  890. Self { origin, ..self }
  891. }
  892. pub fn with_account_id(self, account_id: u64) -> Self {
  893. Self { account_id, ..self }
  894. }
  895. pub fn with_amount(self, amount: u64) -> Self {
  896. Self { amount, ..self }
  897. }
  898. pub fn call(&self) -> DispatchResult {
  899. TestWorkingGroup::spend_from_budget(
  900. self.origin.clone().into(),
  901. self.account_id,
  902. self.amount,
  903. self.rationale.clone(),
  904. )
  905. }
  906. pub fn call_and_assert(&self, expected_result: DispatchResult) {
  907. let old_budget = TestWorkingGroup::budget();
  908. let old_balance = Balances::usable_balance(&self.account_id);
  909. let actual_result = self.call().map(|_| ());
  910. assert_eq!(actual_result.clone(), expected_result);
  911. let new_budget = TestWorkingGroup::budget();
  912. let new_balance = Balances::usable_balance(&self.account_id);
  913. if actual_result.is_ok() {
  914. assert_eq!(new_budget, old_budget - self.amount);
  915. assert_eq!(new_balance, old_balance + self.amount);
  916. } else {
  917. assert_eq!(old_budget, new_budget);
  918. assert_eq!(old_balance, new_balance);
  919. }
  920. }
  921. }