mod.rs 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616
  1. mod fixtures;
  2. mod hiring_workflow;
  3. mod mock;
  4. pub use mock::{build_test_externalities, Test, DEFAULT_WORKER_ACCOUNT_ID};
  5. use frame_system::RawOrigin;
  6. use crate::tests::fixtures::{
  7. CancelOpeningFixture, DecreaseWorkerStakeFixture, IncreaseWorkerStakeFixture, SetBudgetFixture,
  8. SetStatusTextFixture, SlashWorkerStakeFixture, SpendFromBudgetFixture,
  9. UpdateRewardAccountFixture, UpdateRewardAmountFixture, UpdateWorkerStorageFixture,
  10. WithdrawApplicationFixture,
  11. };
  12. use crate::tests::hiring_workflow::HiringWorkflow;
  13. use crate::tests::mock::{
  14. STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES, STAKING_ACCOUNT_ID_NOT_BOUND_TO_MEMBER,
  15. };
  16. use crate::types::StakeParameters;
  17. use crate::{
  18. default_storage_size_constraint, DefaultInstance, Error, OpeningType, RawEvent,
  19. RewardPaymentType, StakePolicy, Trait, Worker,
  20. };
  21. use common::working_group::WorkingGroupAuthenticator;
  22. use fixtures::{
  23. increase_total_balance_issuance_using_account_id, AddOpeningFixture, ApplyOnOpeningFixture,
  24. EventFixture, FillOpeningFixture, HireLeadFixture, HireRegularWorkerFixture,
  25. LeaveWorkerRoleFixture, TerminateWorkerRoleFixture, UpdateWorkerRoleAccountFixture,
  26. };
  27. use frame_support::dispatch::DispatchError;
  28. use frame_support::StorageMap;
  29. use mock::{run_to_block, Balances, RewardPeriod, TestWorkingGroup, ACTOR_ORIGIN_ERROR};
  30. use sp_runtime::traits::Hash;
  31. use sp_std::collections::btree_map::BTreeMap;
  32. #[test]
  33. fn add_opening_succeeded() {
  34. build_test_externalities().execute_with(|| {
  35. HireLeadFixture::default().hire_lead();
  36. let starting_block = 1;
  37. run_to_block(starting_block);
  38. let add_opening_fixture = AddOpeningFixture::default()
  39. .with_starting_block(starting_block)
  40. .with_stake_policy(StakePolicy {
  41. stake_amount: <Test as Trait>::MinimumApplicationStake::get(),
  42. leaving_unstaking_period: 100,
  43. })
  44. .with_reward_per_block(Some(10));
  45. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  46. EventFixture::assert_last_crate_event(RawEvent::OpeningAdded(
  47. opening_id,
  48. add_opening_fixture.description,
  49. add_opening_fixture.opening_type,
  50. add_opening_fixture.stake_policy,
  51. add_opening_fixture.reward_per_block,
  52. ));
  53. });
  54. }
  55. #[test]
  56. fn add_opening_fails_with_bad_origin() {
  57. build_test_externalities().execute_with(|| {
  58. let add_opening_fixture = AddOpeningFixture::default()
  59. .with_opening_type(OpeningType::Leader)
  60. .with_origin(RawOrigin::None);
  61. add_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  62. });
  63. }
  64. #[test]
  65. fn add_opening_fails_with_less_than_minimum_stake() {
  66. build_test_externalities().execute_with(|| {
  67. HireLeadFixture::default().hire_lead();
  68. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  69. stake_amount: 0,
  70. leaving_unstaking_period: <Test as Trait>::MinUnstakingPeriodLimit::get(),
  71. });
  72. add_opening_fixture.call_and_assert(Err(
  73. Error::<Test, DefaultInstance>::BelowMinimumStakes.into(),
  74. ));
  75. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  76. stake_amount: <Test as Trait>::MinimumApplicationStake::get() - 1,
  77. leaving_unstaking_period: <Test as Trait>::MinUnstakingPeriodLimit::get(),
  78. });
  79. add_opening_fixture.call_and_assert(Err(
  80. Error::<Test, DefaultInstance>::BelowMinimumStakes.into(),
  81. ));
  82. });
  83. }
  84. #[test]
  85. fn add_opening_fails_with_zero_reward() {
  86. build_test_externalities().execute_with(|| {
  87. HireLeadFixture::default().hire_lead();
  88. let add_opening_fixture = AddOpeningFixture::default().with_reward_per_block(Some(0));
  89. add_opening_fixture.call_and_assert(Err(
  90. Error::<Test, DefaultInstance>::CannotRewardWithZero.into(),
  91. ));
  92. });
  93. }
  94. #[test]
  95. fn add_opening_fails_with_insufficient_balance() {
  96. build_test_externalities().execute_with(|| {
  97. HireLeadFixture::default()
  98. .with_initial_balance(<Test as Trait>::MinimumApplicationStake::get())
  99. .hire_lead();
  100. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  101. stake_amount: <Test as Trait>::MinimumApplicationStake::get(),
  102. leaving_unstaking_period: <Test as Trait>::MinUnstakingPeriodLimit::get() + 1,
  103. });
  104. add_opening_fixture.call_and_assert(Err(
  105. Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),
  106. ));
  107. });
  108. }
  109. #[test]
  110. fn add_opening_fails_with_incorrect_unstaking_period() {
  111. build_test_externalities().execute_with(|| {
  112. HireLeadFixture::default().hire_lead();
  113. let account_id = 1;
  114. let total_balance = 300;
  115. let stake = 200;
  116. increase_total_balance_issuance_using_account_id(account_id, total_balance);
  117. let invalid_unstaking_period = 3;
  118. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  119. stake_amount: stake,
  120. leaving_unstaking_period: invalid_unstaking_period,
  121. });
  122. add_opening_fixture.call_and_assert(Err(
  123. Error::<Test, DefaultInstance>::UnstakingPeriodLessThanMinimum.into(),
  124. ));
  125. });
  126. }
  127. #[test]
  128. fn add_leader_opening_fails_with_incorrect_origin_for_opening_type() {
  129. build_test_externalities().execute_with(|| {
  130. let add_opening_fixture =
  131. AddOpeningFixture::default().with_opening_type(OpeningType::Leader);
  132. add_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  133. });
  134. }
  135. #[test]
  136. fn apply_on_opening_succeeded() {
  137. build_test_externalities().execute_with(|| {
  138. HireLeadFixture::default().hire_lead();
  139. let starting_block = 1;
  140. run_to_block(starting_block);
  141. let add_opening_fixture = AddOpeningFixture::default().with_starting_block(starting_block);
  142. let opening_id = add_opening_fixture.call().unwrap();
  143. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  144. .with_initial_balance(<Test as Trait>::MinimumApplicationStake::get());
  145. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  146. EventFixture::assert_last_crate_event(RawEvent::AppliedOnOpening(
  147. apply_on_opening_fixture.get_apply_on_opening_parameters(),
  148. application_id,
  149. ));
  150. });
  151. }
  152. #[test]
  153. fn apply_on_opening_fails_with_invalid_opening_id() {
  154. build_test_externalities().execute_with(|| {
  155. let invalid_opening_id = 22;
  156. let apply_on_opening_fixture =
  157. ApplyOnOpeningFixture::default_for_opening_id(invalid_opening_id);
  158. apply_on_opening_fixture.call_and_assert(Err(
  159. Error::<Test, DefaultInstance>::OpeningDoesNotExist.into(),
  160. ));
  161. });
  162. }
  163. #[test]
  164. fn apply_on_opening_fails_with_bad_origin() {
  165. build_test_externalities().execute_with(|| {
  166. HireLeadFixture::default().hire_lead();
  167. let member_id = 11;
  168. let add_opening_fixture = AddOpeningFixture::default();
  169. let opening_id = add_opening_fixture.call().unwrap();
  170. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  171. .with_origin(RawOrigin::None, member_id);
  172. apply_on_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  173. });
  174. }
  175. #[test]
  176. fn apply_on_opening_fails_with_bad_member_id() {
  177. build_test_externalities().execute_with(|| {
  178. HireLeadFixture::default().hire_lead();
  179. let member_id = 27;
  180. let add_opening_fixture = AddOpeningFixture::default();
  181. let opening_id = add_opening_fixture.call().unwrap();
  182. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  183. .with_origin(RawOrigin::Signed(1), member_id);
  184. apply_on_opening_fixture
  185. .call_and_assert(Err(DispatchError::Other(ACTOR_ORIGIN_ERROR).into()));
  186. });
  187. }
  188. #[test]
  189. fn fill_opening_succeeded() {
  190. build_test_externalities().execute_with(|| {
  191. HireLeadFixture::default().hire_lead();
  192. let starting_block = 1;
  193. run_to_block(starting_block);
  194. let reward_per_block = 10;
  195. let add_opening_fixture = AddOpeningFixture::default()
  196. .with_starting_block(starting_block)
  197. .with_reward_per_block(Some(reward_per_block.clone()));
  198. let opening_id = add_opening_fixture.call().unwrap();
  199. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
  200. let application_id = apply_on_opening_fixture.call().unwrap();
  201. let fill_opening_fixture =
  202. FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
  203. .with_reward_per_block(Some(reward_per_block))
  204. .with_created_at(starting_block);
  205. let initial_balance = Balances::usable_balance(&1);
  206. let worker_id = fill_opening_fixture.call_and_assert(Ok(()));
  207. assert_eq!(
  208. Balances::usable_balance(&1),
  209. initial_balance + <Test as Trait>::LeaderOpeningStake::get()
  210. );
  211. let mut result_map = BTreeMap::new();
  212. result_map.insert(application_id, worker_id);
  213. EventFixture::assert_last_crate_event(RawEvent::OpeningFilled(
  214. opening_id,
  215. result_map,
  216. fill_opening_fixture.successful_application_ids,
  217. ));
  218. });
  219. }
  220. #[test]
  221. fn fill_opening_succeeded_with_stake() {
  222. build_test_externalities().execute_with(|| {
  223. HireLeadFixture::default().hire_lead();
  224. let starting_block = 1;
  225. run_to_block(starting_block);
  226. let account_id = 2;
  227. let total_balance = 300;
  228. let stake = 200;
  229. let stake_parameters = StakeParameters {
  230. stake,
  231. staking_account_id: account_id,
  232. };
  233. let stake_policy = StakePolicy {
  234. stake_amount: stake,
  235. leaving_unstaking_period: 10,
  236. };
  237. let add_opening_fixture = AddOpeningFixture::default()
  238. .with_starting_block(starting_block)
  239. .with_stake_policy(stake_policy.clone());
  240. let opening_id = add_opening_fixture.call().unwrap();
  241. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  242. .with_initial_balance(total_balance)
  243. .with_stake_parameters(stake_parameters);
  244. let application_id = apply_on_opening_fixture.call().unwrap();
  245. let fill_opening_fixture =
  246. FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
  247. .with_stake_policy(stake_policy)
  248. .with_staking_account_id(account_id)
  249. .with_created_at(starting_block);
  250. let worker_id = fill_opening_fixture.call_and_assert(Ok(()));
  251. let mut result_map = BTreeMap::new();
  252. result_map.insert(application_id, worker_id);
  253. EventFixture::assert_last_crate_event(RawEvent::OpeningFilled(
  254. opening_id,
  255. result_map,
  256. fill_opening_fixture.successful_application_ids,
  257. ));
  258. });
  259. }
  260. #[test]
  261. fn fill_opening_fails_with_bad_origin() {
  262. build_test_externalities().execute_with(|| {
  263. HireLeadFixture::default().hire_lead();
  264. let add_opening_fixture = AddOpeningFixture::default();
  265. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  266. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
  267. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  268. let fill_opening_fixture =
  269. FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
  270. .with_origin(RawOrigin::None);
  271. fill_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  272. });
  273. }
  274. #[test]
  275. fn fill_opening_fails_with_application_for_other_opening() {
  276. build_test_externalities().execute_with(|| {
  277. HireLeadFixture::default()
  278. .with_initial_balance(
  279. <Test as Trait>::MinimumApplicationStake::get()
  280. + 3 * <Test as Trait>::LeaderOpeningStake::get()
  281. + 1,
  282. )
  283. .hire_lead();
  284. let add_opening_fixture = AddOpeningFixture::default();
  285. let filling_opening_id = add_opening_fixture.call_and_assert(Ok(()));
  286. let apply_opening_id = add_opening_fixture.call_and_assert(Ok(()));
  287. let apply_on_opening_fixture =
  288. ApplyOnOpeningFixture::default_for_opening_id(apply_opening_id);
  289. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  290. let fill_opening_fixture =
  291. FillOpeningFixture::default_for_ids(filling_opening_id, vec![application_id]);
  292. fill_opening_fixture.call_and_assert(Err(
  293. Error::<Test, DefaultInstance>::ApplicationsNotForOpening.into(),
  294. ));
  295. });
  296. }
  297. #[test]
  298. fn fill_opening_fails_with_invalid_active_worker_number() {
  299. build_test_externalities().execute_with(|| {
  300. HireLeadFixture::default().hire_lead();
  301. let add_opening_fixture = AddOpeningFixture::default();
  302. let opening_id = add_opening_fixture.call().unwrap();
  303. let application_id1 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  304. .with_origin(RawOrigin::Signed(2), 2)
  305. .call()
  306. .unwrap();
  307. let application_id2 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  308. .with_origin(RawOrigin::Signed(3), 3)
  309. .call()
  310. .unwrap();
  311. let application_id3 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  312. .with_origin(RawOrigin::Signed(4), 4)
  313. .call()
  314. .unwrap();
  315. let application_id4 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  316. .with_origin(RawOrigin::Signed(5), 5)
  317. .call()
  318. .unwrap();
  319. let fill_opening_fixture = FillOpeningFixture::default_for_ids(
  320. opening_id,
  321. vec![
  322. application_id1,
  323. application_id2,
  324. application_id3,
  325. application_id4,
  326. ],
  327. );
  328. fill_opening_fixture.call_and_assert(Err(
  329. Error::<Test, DefaultInstance>::MaxActiveWorkerNumberExceeded.into(),
  330. ));
  331. });
  332. }
  333. #[test]
  334. fn fill_opening_fails_with_invalid_application_id() {
  335. build_test_externalities().execute_with(|| {
  336. HireLeadFixture::default().hire_lead();
  337. let add_opening_fixture = AddOpeningFixture::default();
  338. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  339. let invalid_application_id = 1;
  340. let fill_opening_fixture =
  341. FillOpeningFixture::default_for_ids(opening_id, vec![invalid_application_id]);
  342. fill_opening_fixture.call_and_assert(Err(
  343. Error::<Test, DefaultInstance>::SuccessfulWorkerApplicationDoesNotExist.into(),
  344. ));
  345. });
  346. }
  347. #[test]
  348. fn fill_opening_fails_with_zero_application_ids() {
  349. build_test_externalities().execute_with(|| {
  350. HireLeadFixture::default().hire_lead();
  351. let add_opening_fixture = AddOpeningFixture::default();
  352. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  353. let fill_opening_fixture = FillOpeningFixture::default_for_ids(opening_id, Vec::new());
  354. fill_opening_fixture.call_and_assert(Err(
  355. Error::<Test, DefaultInstance>::NoApplicationsProvided.into(),
  356. ));
  357. });
  358. }
  359. #[test]
  360. fn cannot_hire_a_lead_twice() {
  361. build_test_externalities().execute_with(|| {
  362. HireLeadFixture::default().hire_lead();
  363. HireLeadFixture::default()
  364. .with_setup_environment(false)
  365. .expect(Error::<Test, DefaultInstance>::ConflictStakesOnAccount.into());
  366. });
  367. }
  368. #[test]
  369. fn cannot_hire_muptiple_leaders() {
  370. build_test_externalities().execute_with(|| {
  371. HiringWorkflow::default()
  372. .with_setup_environment(true)
  373. .with_opening_type(OpeningType::Leader)
  374. .add_default_application()
  375. .add_application_full(b"leader2".to_vec(), RawOrigin::Signed(3), 3, 3)
  376. .expect(Err(
  377. Error::<Test, DefaultInstance>::CannotHireMultipleLeaders.into(),
  378. ))
  379. .execute();
  380. });
  381. }
  382. #[test]
  383. fn update_worker_role_account_succeeds() {
  384. build_test_externalities().execute_with(|| {
  385. /*
  386. Events are not emitted on block 0.
  387. So any dispatchable calls made during genesis block formation will have no events emitted.
  388. https://substrate.dev/recipes/2-appetizers/4-events.html
  389. */
  390. run_to_block(1);
  391. let new_account_id = 10;
  392. let worker_id = HireRegularWorkerFixture::default().hire();
  393. let update_worker_account_fixture =
  394. UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
  395. update_worker_account_fixture.call_and_assert(Ok(()));
  396. EventFixture::assert_last_crate_event(RawEvent::WorkerRoleAccountUpdated(
  397. worker_id,
  398. new_account_id,
  399. ));
  400. });
  401. }
  402. #[test]
  403. fn update_worker_role_account_by_leader_succeeds() {
  404. build_test_externalities().execute_with(|| {
  405. let new_account_id = 10;
  406. let worker_id = HireLeadFixture::default().hire_lead();
  407. let old_lead = TestWorkingGroup::worker_by_id(worker_id);
  408. let update_worker_account_fixture =
  409. UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
  410. update_worker_account_fixture.call_and_assert(Ok(()));
  411. let new_lead = TestWorkingGroup::worker_by_id(worker_id);
  412. assert_eq!(
  413. new_lead,
  414. Worker::<Test> {
  415. role_account_id: new_account_id,
  416. ..old_lead
  417. }
  418. );
  419. });
  420. }
  421. #[test]
  422. fn update_worker_role_fails_with_leaving_worker() {
  423. build_test_externalities().execute_with(|| {
  424. let total_balance = 300;
  425. let stake = 200;
  426. let leaving_unstaking_period = 10;
  427. let stake_policy = StakePolicy {
  428. stake_amount: stake,
  429. leaving_unstaking_period,
  430. };
  431. let worker_id = HireRegularWorkerFixture::default()
  432. .with_initial_balance(total_balance)
  433. .with_stake_policy(stake_policy.clone())
  434. .hire();
  435. let new_account_id = 10;
  436. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  437. leave_worker_role_fixture.call_and_assert(Ok(()));
  438. let update_worker_account_fixture =
  439. UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
  440. update_worker_account_fixture
  441. .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
  442. });
  443. }
  444. #[test]
  445. fn update_worker_role_account_fails_with_invalid_origin() {
  446. build_test_externalities().execute_with(|| {
  447. let worker_id = HireRegularWorkerFixture::default().hire();
  448. let update_worker_account_fixture =
  449. UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, 1)
  450. .with_origin(RawOrigin::None);
  451. update_worker_account_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  452. });
  453. }
  454. #[test]
  455. fn leave_worker_role_succeeds() {
  456. build_test_externalities().execute_with(|| {
  457. /*
  458. Events are not emitted on block 0.
  459. So any dispatchable calls made during genesis block formation will have no events emitted.
  460. https://substrate.dev/recipes/2-appetizers/4-events.html
  461. */
  462. run_to_block(1);
  463. let worker_id = HireRegularWorkerFixture::default().hire();
  464. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  465. leave_worker_role_fixture.call_and_assert(Ok(()));
  466. EventFixture::assert_last_crate_event(RawEvent::WorkerStartedLeaving(worker_id, None));
  467. let worker = TestWorkingGroup::worker_by_id(worker_id);
  468. run_to_block(1 + worker.job_unstaking_period);
  469. EventFixture::assert_last_crate_event(RawEvent::WorkerExited(worker_id));
  470. });
  471. }
  472. #[test]
  473. fn leave_worker_role_succeeds_with_paying_missed_reward() {
  474. build_test_externalities().execute_with(|| {
  475. let account_id = 2;
  476. let reward_per_block = 10;
  477. let worker_id = HireRegularWorkerFixture::default()
  478. .with_reward_per_block(Some(reward_per_block))
  479. .hire();
  480. let reward_period: u64 = <Test as Trait>::RewardPeriod::get().into();
  481. let missed_reward_block_number = reward_period * 2;
  482. run_to_block(missed_reward_block_number);
  483. assert_eq!(Balances::usable_balance(&account_id), 0);
  484. SetBudgetFixture::default().with_budget(1000000).execute();
  485. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  486. leave_worker_role_fixture.call_and_assert(Ok(()));
  487. let worker = TestWorkingGroup::worker_by_id(worker_id);
  488. let leaving_block = missed_reward_block_number + worker.job_unstaking_period;
  489. run_to_block(leaving_block);
  490. let missed_reward = missed_reward_block_number * reward_per_block;
  491. EventFixture::contains_crate_event(RawEvent::NewMissedRewardLevelReached(
  492. worker_id,
  493. Some(missed_reward),
  494. ));
  495. EventFixture::contains_crate_event(RawEvent::RewardPaid(
  496. worker_id,
  497. account_id,
  498. missed_reward,
  499. RewardPaymentType::MissedReward,
  500. ));
  501. // Didn't get the last reward period: leaving earlier than rewarding.
  502. let reward_block_count = leaving_block - reward_period;
  503. assert_eq!(
  504. Balances::usable_balance(&account_id),
  505. reward_block_count * reward_per_block + <Test as Trait>::MinimumApplicationStake::get()
  506. );
  507. });
  508. }
  509. #[test]
  510. fn leave_worker_role_succeeds_with_correct_unstaking_period() {
  511. build_test_externalities().execute_with(|| {
  512. let starting_block = 10;
  513. run_to_block(starting_block);
  514. let worker_id = HireRegularWorkerFixture::default().hire();
  515. // Assert initial worker existence
  516. assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  517. worker_id
  518. ));
  519. let default_unstaking_period =
  520. TestWorkingGroup::worker_by_id(worker_id).job_unstaking_period;
  521. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  522. leave_worker_role_fixture.call_and_assert(Ok(()));
  523. // Assert worker existence after leave_role
  524. assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  525. worker_id
  526. ));
  527. run_to_block(starting_block + default_unstaking_period - 1);
  528. // Assert worker existence one block before the end of the unstaking period.
  529. assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  530. worker_id
  531. ));
  532. run_to_block(starting_block + default_unstaking_period);
  533. // Assert worker removal after the unstaking period.
  534. assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  535. worker_id
  536. ));
  537. });
  538. }
  539. #[test]
  540. fn leave_worker_role_succeeds_with_partial_payment_of_missed_reward() {
  541. build_test_externalities().execute_with(|| {
  542. let account_id = 2;
  543. let reward_per_block = 10;
  544. let worker_id = HireRegularWorkerFixture::default()
  545. .with_reward_per_block(Some(reward_per_block))
  546. .hire();
  547. let block_number = 4;
  548. run_to_block(block_number);
  549. assert_eq!(Balances::usable_balance(&account_id), 0);
  550. let budget = 30;
  551. SetBudgetFixture::default().with_budget(budget).execute();
  552. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  553. leave_worker_role_fixture.call_and_assert(Ok(()));
  554. let worker = TestWorkingGroup::worker_by_id(worker_id);
  555. run_to_block(block_number + worker.job_unstaking_period);
  556. assert_eq!(
  557. Balances::usable_balance(&account_id),
  558. budget + <Test as Trait>::MinimumApplicationStake::get()
  559. );
  560. });
  561. }
  562. #[test]
  563. fn leave_worker_role_by_leader_succeeds() {
  564. build_test_externalities().execute_with(|| {
  565. // Ensure that lead is default
  566. assert_eq!(TestWorkingGroup::current_lead(), None);
  567. let worker_id = HireLeadFixture::default().hire_lead();
  568. assert!(TestWorkingGroup::current_lead().is_some());
  569. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
  570. .with_origin(RawOrigin::Signed(1));
  571. leave_worker_role_fixture.call_and_assert(Ok(()));
  572. let current_lead = TestWorkingGroup::current_lead().unwrap();
  573. let leader = TestWorkingGroup::worker_by_id(current_lead);
  574. assert!(leader.started_leaving_at.is_some());
  575. run_to_block(frame_system::Module::<Test>::block_number() + leader.job_unstaking_period);
  576. assert_eq!(TestWorkingGroup::current_lead(), None);
  577. });
  578. }
  579. #[test]
  580. fn leave_worker_role_fails_with_invalid_origin() {
  581. build_test_externalities().execute_with(|| {
  582. let leave_worker_role_fixture =
  583. LeaveWorkerRoleFixture::default_for_worker_id(1).with_origin(RawOrigin::None);
  584. leave_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  585. });
  586. }
  587. #[test]
  588. fn leave_worker_role_fails_with_invalid_origin_signed_account() {
  589. build_test_externalities().execute_with(|| {
  590. let worker_id = HireRegularWorkerFixture::default().hire();
  591. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
  592. .with_origin(RawOrigin::Signed(3));
  593. leave_worker_role_fixture.call_and_assert(Err(
  594. Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into(),
  595. ));
  596. });
  597. }
  598. #[test]
  599. fn leave_worker_role_fails_already_leaving_worker() {
  600. build_test_externalities().execute_with(|| {
  601. let total_balance = 300;
  602. let stake = 200;
  603. let stake_policy = StakePolicy {
  604. stake_amount: stake,
  605. leaving_unstaking_period: 10,
  606. };
  607. let worker_id = HireRegularWorkerFixture::default()
  608. .with_initial_balance(total_balance)
  609. .with_stake_policy(stake_policy.clone())
  610. .hire();
  611. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  612. leave_worker_role_fixture.call_and_assert(Ok(()));
  613. leave_worker_role_fixture
  614. .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
  615. });
  616. }
  617. #[test]
  618. fn leave_worker_role_fails_with_invalid_worker_id() {
  619. build_test_externalities().execute_with(|| {
  620. let invalid_worker_id = 10;
  621. HireRegularWorkerFixture::default().hire();
  622. let leave_worker_role_fixture =
  623. LeaveWorkerRoleFixture::default_for_worker_id(invalid_worker_id);
  624. leave_worker_role_fixture.call_and_assert(Err(
  625. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  626. ));
  627. });
  628. }
  629. #[test]
  630. fn terminate_worker_role_succeeds() {
  631. build_test_externalities().execute_with(|| {
  632. /*
  633. Events are not emitted on block 0.
  634. So any dispatchable calls made during genesis block formation will have no events emitted.
  635. https://substrate.dev/recipes/2-appetizers/4-events.html
  636. */
  637. run_to_block(1);
  638. let worker_id = HireRegularWorkerFixture::default().hire();
  639. let terminate_worker_role_fixture =
  640. TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
  641. terminate_worker_role_fixture.call_and_assert(Ok(()));
  642. EventFixture::assert_last_crate_event(RawEvent::TerminatedWorker(
  643. worker_id,
  644. terminate_worker_role_fixture.penalty,
  645. terminate_worker_role_fixture.rationale,
  646. ));
  647. });
  648. }
  649. #[test]
  650. fn terminate_worker_role_succeeds_with_paying_missed_reward() {
  651. build_test_externalities().execute_with(|| {
  652. let account_id = 2;
  653. let reward_per_block = 10;
  654. let worker_id = HireRegularWorkerFixture::default()
  655. .with_reward_per_block(Some(reward_per_block))
  656. .hire();
  657. let block_number = 4;
  658. run_to_block(block_number);
  659. assert_eq!(Balances::usable_balance(&account_id), 0);
  660. SetBudgetFixture::default().with_budget(1000000).execute();
  661. let terminate_worker_role_fixture =
  662. TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
  663. terminate_worker_role_fixture.call_and_assert(Ok(()));
  664. assert_eq!(
  665. Balances::usable_balance(&account_id),
  666. block_number * reward_per_block + <Test as Trait>::MinimumApplicationStake::get()
  667. );
  668. });
  669. }
  670. #[test]
  671. fn terminate_leader_succeeds() {
  672. build_test_externalities().execute_with(|| {
  673. /*
  674. Events are not emitted on block 0.
  675. So any dispatchable calls made during genesis block formation will have no events emitted.
  676. https://substrate.dev/recipes/2-appetizers/4-events.html
  677. */
  678. run_to_block(1);
  679. let worker_id = HireLeadFixture::default().hire_lead();
  680. let terminate_worker_role_fixture =
  681. TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
  682. .with_origin(RawOrigin::Root);
  683. terminate_worker_role_fixture.call_and_assert(Ok(()));
  684. EventFixture::assert_last_crate_event(RawEvent::TerminatedLeader(
  685. worker_id,
  686. terminate_worker_role_fixture.penalty,
  687. terminate_worker_role_fixture.rationale,
  688. ));
  689. assert_eq!(TestWorkingGroup::current_lead(), None);
  690. });
  691. }
  692. #[test]
  693. fn terminate_worker_role_fails_with_unset_lead() {
  694. build_test_externalities().execute_with(|| {
  695. let worker_id = HireRegularWorkerFixture::default().hire();
  696. // Remove the leader from the storage.
  697. TestWorkingGroup::unset_lead();
  698. let terminate_worker_role_fixture =
  699. TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
  700. terminate_worker_role_fixture
  701. .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
  702. });
  703. }
  704. #[test]
  705. fn terminate_worker_role_fails_with_invalid_origin() {
  706. build_test_externalities().execute_with(|| {
  707. HireLeadFixture::default().hire_lead();
  708. let worker_id = HiringWorkflow::default()
  709. .with_setup_environment(false)
  710. .add_application_full(b"worker_handle".to_vec(), RawOrigin::Signed(2), 2, 2)
  711. .execute()
  712. .unwrap();
  713. let terminate_worker_role_fixture =
  714. TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
  715. .with_origin(RawOrigin::None);
  716. terminate_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  717. });
  718. }
  719. #[test]
  720. fn terminate_leader_fails_with_invalid_origin() {
  721. build_test_externalities().execute_with(|| {
  722. let worker_id = HireLeadFixture::default().hire_lead();
  723. let terminate_worker_role_fixture =
  724. TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
  725. .with_origin(RawOrigin::None);
  726. terminate_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  727. });
  728. }
  729. #[test]
  730. fn unset_lead_event_emitted() {
  731. build_test_externalities().execute_with(|| {
  732. /*
  733. Events are not emitted on block 0.
  734. So any dispatchable calls made during genesis block formation will have no events emitted.
  735. https://substrate.dev/recipes/2-appetizers/4-events.html
  736. */
  737. run_to_block(1);
  738. HireRegularWorkerFixture::default().hire();
  739. // Remove the leader from the storage.
  740. TestWorkingGroup::unset_lead();
  741. EventFixture::assert_last_crate_event(RawEvent::LeaderUnset());
  742. });
  743. }
  744. #[test]
  745. fn set_lead_event_emitted() {
  746. build_test_externalities().execute_with(|| {
  747. /*
  748. Events are not emitted on block 0.
  749. So any dispatchable calls made during genesis block formation will have no events emitted.
  750. https://substrate.dev/recipes/2-appetizers/4-events.html
  751. */
  752. run_to_block(1);
  753. let worker_id = 10;
  754. // Add the leader to the storage.
  755. TestWorkingGroup::set_lead(worker_id);
  756. EventFixture::assert_last_crate_event(RawEvent::LeaderSet(worker_id));
  757. });
  758. }
  759. #[test]
  760. fn apply_on_opening_fails_with_stake_inconsistent_with_opening_stake() {
  761. build_test_externalities().execute_with(|| {
  762. HireLeadFixture::default().hire_lead();
  763. let account_id = 1;
  764. let stake_parameters = StakeParameters {
  765. stake: 100,
  766. staking_account_id: account_id,
  767. };
  768. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  769. stake_amount: 200,
  770. leaving_unstaking_period: 10,
  771. });
  772. let opening_id = add_opening_fixture.call().unwrap();
  773. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  774. .with_initial_balance(300)
  775. .with_stake_parameters(stake_parameters);
  776. apply_on_opening_fixture.call_and_assert(Err(
  777. Error::<Test, DefaultInstance>::ApplicationStakeDoesntMatchOpening.into(),
  778. ));
  779. });
  780. }
  781. #[test]
  782. fn apply_on_opening_locks_the_stake() {
  783. build_test_externalities().execute_with(|| {
  784. HireLeadFixture::default().hire_lead();
  785. let account_id = 2;
  786. let total_balance = <Test as Trait>::MinimumApplicationStake::get() + 100;
  787. let stake = <Test as Trait>::MinimumApplicationStake::get();
  788. let stake_parameters = StakeParameters {
  789. stake,
  790. staking_account_id: account_id,
  791. };
  792. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  793. stake_amount: stake,
  794. leaving_unstaking_period: 10,
  795. });
  796. let opening_id = add_opening_fixture.call().unwrap();
  797. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  798. .with_stake_parameters(stake_parameters)
  799. .with_initial_balance(total_balance);
  800. apply_on_opening_fixture.call_and_assert(Ok(()));
  801. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  802. });
  803. }
  804. #[test]
  805. fn apply_on_opening_fails_stake_amount_check() {
  806. build_test_externalities().execute_with(|| {
  807. HireLeadFixture::default().hire_lead();
  808. let account_id = 2;
  809. let total_balance = 100;
  810. let stake = 200;
  811. let stake_parameters = StakeParameters {
  812. stake,
  813. staking_account_id: account_id,
  814. };
  815. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  816. stake_amount: stake,
  817. leaving_unstaking_period: 10,
  818. });
  819. let opening_id = add_opening_fixture.call().unwrap();
  820. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  821. .with_initial_balance(total_balance)
  822. .with_stake_parameters(stake_parameters);
  823. apply_on_opening_fixture.call_and_assert(Err(
  824. Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),
  825. ));
  826. });
  827. }
  828. #[test]
  829. fn apply_on_opening_fails_invalid_staking_check() {
  830. build_test_externalities().execute_with(|| {
  831. HireLeadFixture::default().hire_lead();
  832. let total_balance = 300;
  833. let stake = 200;
  834. increase_total_balance_issuance_using_account_id(
  835. STAKING_ACCOUNT_ID_NOT_BOUND_TO_MEMBER,
  836. total_balance,
  837. );
  838. let stake_parameters = StakeParameters {
  839. stake,
  840. staking_account_id: STAKING_ACCOUNT_ID_NOT_BOUND_TO_MEMBER,
  841. };
  842. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  843. stake_amount: stake,
  844. leaving_unstaking_period: 10,
  845. });
  846. let opening_id = add_opening_fixture.call().unwrap();
  847. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  848. .with_initial_balance(total_balance)
  849. .with_stake_parameters(stake_parameters);
  850. apply_on_opening_fixture.call_and_assert(Err(
  851. Error::<Test, DefaultInstance>::InvalidStakingAccountForMember.into(),
  852. ));
  853. });
  854. }
  855. #[test]
  856. fn apply_on_opening_fails_with_conflicting_stakes() {
  857. build_test_externalities().execute_with(|| {
  858. HireLeadFixture::default().hire_lead();
  859. let account_id = 1;
  860. let total_balance = 300;
  861. let stake = 200;
  862. let stake_parameters = StakeParameters {
  863. stake,
  864. staking_account_id: STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES,
  865. };
  866. increase_total_balance_issuance_using_account_id(account_id, total_balance);
  867. increase_total_balance_issuance_using_account_id(
  868. STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES,
  869. total_balance,
  870. );
  871. let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
  872. stake_amount: stake,
  873. leaving_unstaking_period: 10,
  874. });
  875. let opening_id = add_opening_fixture.call().unwrap();
  876. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  877. .with_stake_parameters(stake_parameters.clone())
  878. .with_initial_balance(stake_parameters.stake);
  879. apply_on_opening_fixture.call_and_assert(Ok(()));
  880. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  881. .with_stake_parameters(stake_parameters);
  882. apply_on_opening_fixture.call_and_assert(Err(
  883. Error::<Test, DefaultInstance>::ConflictStakesOnAccount.into(),
  884. ));
  885. });
  886. }
  887. #[test]
  888. fn terminate_worker_unlocks_the_stake() {
  889. build_test_externalities().execute_with(|| {
  890. let account_id = 2;
  891. let total_balance = 300;
  892. let stake = 200;
  893. let stake_policy = StakePolicy {
  894. stake_amount: stake,
  895. leaving_unstaking_period: 10,
  896. };
  897. let worker_id = HireRegularWorkerFixture::default()
  898. .with_initial_balance(total_balance)
  899. .with_stake_policy(stake_policy)
  900. .hire();
  901. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  902. let terminate_worker_role_fixture =
  903. TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
  904. terminate_worker_role_fixture.call_and_assert(Ok(()));
  905. assert_eq!(Balances::usable_balance(&account_id), total_balance);
  906. });
  907. }
  908. #[test]
  909. fn leave_worker_unlocks_the_stake() {
  910. build_test_externalities().execute_with(|| {
  911. let account_id = 2;
  912. let total_balance = 300;
  913. let stake = 200;
  914. let leaving_unstaking_period = 10;
  915. let stake_policy = StakePolicy {
  916. stake_amount: stake,
  917. leaving_unstaking_period,
  918. };
  919. let worker_id = HireRegularWorkerFixture::default()
  920. .with_initial_balance(total_balance)
  921. .with_stake_policy(stake_policy.clone())
  922. .hire();
  923. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  924. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  925. leave_worker_role_fixture.call_and_assert(Ok(()));
  926. run_to_block(leaving_unstaking_period);
  927. assert_eq!(Balances::usable_balance(&account_id), total_balance);
  928. });
  929. }
  930. #[test]
  931. fn leave_worker_unlocks_the_stake_with_unstaking_period() {
  932. build_test_externalities().execute_with(|| {
  933. let account_id = 2;
  934. let total_balance = 300;
  935. let stake = 200;
  936. let leaving_unstaking_period = 10;
  937. let stake_policy = StakePolicy {
  938. stake_amount: stake,
  939. leaving_unstaking_period,
  940. };
  941. let worker_id = HireRegularWorkerFixture::default()
  942. .with_initial_balance(total_balance)
  943. .with_stake_policy(stake_policy.clone())
  944. .hire();
  945. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  946. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  947. leave_worker_role_fixture.call_and_assert(Ok(()));
  948. run_to_block(leaving_unstaking_period);
  949. assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
  950. worker_id
  951. ));
  952. assert_eq!(Balances::usable_balance(&account_id), total_balance);
  953. EventFixture::assert_last_crate_event(RawEvent::WorkerExited(worker_id));
  954. });
  955. }
  956. #[test]
  957. fn terminate_worker_with_slashing_succeeds() {
  958. build_test_externalities().execute_with(|| {
  959. let account_id = 2;
  960. let total_balance = 300;
  961. let stake = 200;
  962. let stake_policy = StakePolicy {
  963. stake_amount: stake,
  964. leaving_unstaking_period: 10,
  965. };
  966. let worker_id = HireRegularWorkerFixture::default()
  967. .with_initial_balance(total_balance)
  968. .with_stake_policy(stake_policy)
  969. .hire();
  970. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  971. let terminate_worker_role_fixture =
  972. TerminateWorkerRoleFixture::default_for_worker_id(worker_id).with_penalty(Some(stake));
  973. terminate_worker_role_fixture.call_and_assert(Ok(()));
  974. assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
  975. });
  976. }
  977. #[test]
  978. fn slash_worker_stake_succeeds() {
  979. build_test_externalities().execute_with(|| {
  980. /*
  981. Events are not emitted on block 0.
  982. So any dispatchable calls made during genesis block formation will have no events emitted.
  983. https://substrate.dev/recipes/2-appetizers/4-events.html
  984. */
  985. run_to_block(1);
  986. let total_balance = 300;
  987. let stake = 200;
  988. let penalty = 100;
  989. let stake_policy = StakePolicy {
  990. stake_amount: stake,
  991. leaving_unstaking_period: 10,
  992. };
  993. let worker_id = HireRegularWorkerFixture::default()
  994. .with_initial_balance(total_balance)
  995. .with_stake_policy(stake_policy)
  996. .hire();
  997. let slash_stake_fixture =
  998. SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_penalty(penalty);
  999. slash_stake_fixture.call_and_assert(Ok(()));
  1000. EventFixture::assert_last_crate_event(RawEvent::StakeSlashed(
  1001. worker_id, penalty, penalty, None,
  1002. ));
  1003. });
  1004. }
  1005. #[test]
  1006. fn slash_leader_stake_succeeds() {
  1007. build_test_externalities().execute_with(|| {
  1008. /*
  1009. Events are not emitted on block 0.
  1010. So any dispatchable calls made during genesis block formation will have no events emitted.
  1011. https://substrate.dev/recipes/2-appetizers/4-events.html
  1012. */
  1013. run_to_block(1);
  1014. let total_balance = 300;
  1015. let penalty = 200;
  1016. let stake_policy = StakePolicy {
  1017. stake_amount: penalty,
  1018. leaving_unstaking_period: 10,
  1019. };
  1020. let leader_worker_id = HireLeadFixture::default()
  1021. .with_initial_balance(total_balance)
  1022. .with_stake_policy(stake_policy)
  1023. .hire_lead();
  1024. let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(leader_worker_id)
  1025. .with_penalty(penalty)
  1026. .with_account_id(1)
  1027. .with_origin(RawOrigin::Root);
  1028. slash_stake_fixture.call_and_assert(Ok(()));
  1029. EventFixture::assert_last_crate_event(RawEvent::StakeSlashed(
  1030. leader_worker_id,
  1031. penalty,
  1032. penalty,
  1033. None,
  1034. ));
  1035. });
  1036. }
  1037. #[test]
  1038. fn slash_worker_stake_fails_with_invalid_origin() {
  1039. build_test_externalities().execute_with(|| {
  1040. HireLeadFixture::default().hire_lead();
  1041. let invalid_worker_id = 22;
  1042. let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id)
  1043. .with_origin(RawOrigin::None);
  1044. slash_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1045. });
  1046. }
  1047. #[test]
  1048. fn slash_leader_stake_fails_with_invalid_origin() {
  1049. build_test_externalities().execute_with(|| {
  1050. let worker_id = HireLeadFixture::default().hire_lead();
  1051. let slash_stake_fixture =
  1052. SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_origin(RawOrigin::None);
  1053. slash_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1054. });
  1055. }
  1056. #[test]
  1057. fn slash_worker_stake_fails_with_zero_balance() {
  1058. build_test_externalities().execute_with(|| {
  1059. let total_balance = 300;
  1060. let stake = 200;
  1061. let stake_policy = StakePolicy {
  1062. stake_amount: stake,
  1063. leaving_unstaking_period: 10,
  1064. };
  1065. let worker_id = HireRegularWorkerFixture::default()
  1066. .with_initial_balance(total_balance)
  1067. .with_stake_policy(stake_policy)
  1068. .hire();
  1069. let slash_stake_fixture =
  1070. SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_penalty(0);
  1071. slash_stake_fixture.call_and_assert(Err(
  1072. Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
  1073. ));
  1074. });
  1075. }
  1076. #[test]
  1077. fn slash_worker_stake_fails_with_invalid_worker_id() {
  1078. build_test_externalities().execute_with(|| {
  1079. HireLeadFixture::default().hire_lead();
  1080. let invalid_worker_id = 11;
  1081. let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
  1082. slash_stake_fixture.call_and_assert(Err(
  1083. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  1084. ));
  1085. });
  1086. }
  1087. #[test]
  1088. fn slash_worker_stake_fails_with_not_set_lead() {
  1089. build_test_externalities().execute_with(|| {
  1090. let invalid_worker_id = 11;
  1091. let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
  1092. slash_stake_fixture
  1093. .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
  1094. });
  1095. }
  1096. #[test]
  1097. fn decrease_worker_stake_succeeds() {
  1098. build_test_externalities().execute_with(|| {
  1099. /*
  1100. Events are not emitted on block 0.
  1101. So any dispatchable calls made during genesis block formation will have no events emitted.
  1102. https://substrate.dev/recipes/2-appetizers/4-events.html
  1103. */
  1104. run_to_block(1);
  1105. let total_balance = 300;
  1106. let stake = 200;
  1107. let new_stake_balance = 100;
  1108. let stake_policy = StakePolicy {
  1109. stake_amount: stake,
  1110. leaving_unstaking_period: 10,
  1111. };
  1112. let worker_id = HireRegularWorkerFixture::default()
  1113. .with_initial_balance(total_balance)
  1114. .with_stake_policy(stake_policy)
  1115. .hire();
  1116. let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1117. .with_balance(new_stake_balance);
  1118. decrease_stake_fixture.call_and_assert(Ok(()));
  1119. EventFixture::assert_last_crate_event(RawEvent::StakeDecreased(
  1120. worker_id,
  1121. new_stake_balance,
  1122. ));
  1123. });
  1124. }
  1125. #[test]
  1126. fn decrease_worker_stake_succeeds_for_leader() {
  1127. build_test_externalities().execute_with(|| {
  1128. let total_balance = 300;
  1129. let stake = 200;
  1130. let stake_policy = StakePolicy {
  1131. stake_amount: stake,
  1132. leaving_unstaking_period: 10,
  1133. };
  1134. let worker_id = HireLeadFixture::default()
  1135. .with_initial_balance(total_balance)
  1136. .with_stake_policy(stake_policy)
  1137. .hire_lead();
  1138. let new_stake = 100;
  1139. let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1140. .with_account_id(1)
  1141. .with_origin(RawOrigin::Root)
  1142. .with_balance(new_stake);
  1143. decrease_stake_fixture.call_and_assert(Ok(()));
  1144. });
  1145. }
  1146. #[test]
  1147. fn decrease_worker_stake_fails_with_invalid_origin() {
  1148. build_test_externalities().execute_with(|| {
  1149. HireLeadFixture::default().hire_lead();
  1150. let worker_id = 22; // random worker id
  1151. let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1152. .with_origin(RawOrigin::None);
  1153. decrease_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1154. });
  1155. }
  1156. #[test]
  1157. fn decrease_worker_stake_fails_with_invalid_origin_for_leader() {
  1158. build_test_externalities().execute_with(|| {
  1159. let worker_id = HireLeadFixture::default().hire_lead();
  1160. let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1161. .with_origin(RawOrigin::None);
  1162. decrease_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1163. });
  1164. }
  1165. #[test]
  1166. fn decrease_worker_stake_fails_with_zero_balance() {
  1167. build_test_externalities().execute_with(|| {
  1168. let total_balance = 300;
  1169. let stake = 200;
  1170. let stake_policy = StakePolicy {
  1171. stake_amount: stake,
  1172. leaving_unstaking_period: 10,
  1173. };
  1174. let worker_id = HireRegularWorkerFixture::default()
  1175. .with_stake_policy(stake_policy)
  1176. .with_initial_balance(total_balance)
  1177. .hire();
  1178. let decrease_stake_fixture =
  1179. DecreaseWorkerStakeFixture::default_for_worker_id(worker_id).with_balance(0);
  1180. decrease_stake_fixture.call_and_assert(Err(
  1181. Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
  1182. ));
  1183. });
  1184. }
  1185. #[test]
  1186. fn decrease_worker_stake_fails_with_invalid_worker_id() {
  1187. build_test_externalities().execute_with(|| {
  1188. HireLeadFixture::default().hire_lead();
  1189. let invalid_worker_id = 11;
  1190. let decrease_stake_fixture =
  1191. DecreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
  1192. decrease_stake_fixture.call_and_assert(Err(
  1193. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  1194. ));
  1195. });
  1196. }
  1197. #[test]
  1198. fn decrease_worker_stake_fails_with_not_set_lead() {
  1199. build_test_externalities().execute_with(|| {
  1200. let invalid_worker_id = 11;
  1201. let decrease_stake_fixture =
  1202. DecreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
  1203. decrease_stake_fixture
  1204. .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
  1205. });
  1206. }
  1207. #[test]
  1208. fn increase_worker_stake_succeeds() {
  1209. build_test_externalities().execute_with(|| {
  1210. /*
  1211. Events are not emitted on block 0.
  1212. So any dispatchable calls made during genesis block formation will have no events emitted.
  1213. https://substrate.dev/recipes/2-appetizers/4-events.html
  1214. */
  1215. run_to_block(1);
  1216. let total_balance = 300;
  1217. let stake = 200;
  1218. let stake_balance_delta = 100;
  1219. let stake_policy = StakePolicy {
  1220. stake_amount: stake,
  1221. leaving_unstaking_period: 10,
  1222. };
  1223. let worker_id = HireRegularWorkerFixture::default()
  1224. .with_initial_balance(total_balance)
  1225. .with_stake_policy(stake_policy)
  1226. .hire();
  1227. let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1228. .with_balance(stake_balance_delta);
  1229. increase_stake_fixture.call_and_assert(Ok(()));
  1230. EventFixture::assert_last_crate_event(RawEvent::StakeIncreased(
  1231. worker_id,
  1232. stake_balance_delta,
  1233. ));
  1234. });
  1235. }
  1236. #[test]
  1237. fn increase_worker_stake_succeeds_for_leader() {
  1238. build_test_externalities().execute_with(|| {
  1239. let total_balance = 400;
  1240. let stake = 200;
  1241. let stake_policy = StakePolicy {
  1242. stake_amount: stake,
  1243. leaving_unstaking_period: 10,
  1244. };
  1245. let worker_id = HireLeadFixture::default()
  1246. .with_initial_balance(total_balance)
  1247. .with_stake_policy(stake_policy)
  1248. .hire_lead();
  1249. let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1250. .with_balance(stake)
  1251. .with_account_id(1)
  1252. .with_origin(RawOrigin::Signed(1));
  1253. increase_stake_fixture.call_and_assert(Ok(()));
  1254. });
  1255. }
  1256. #[test]
  1257. fn increase_worker_stake_fails_with_invalid_origin() {
  1258. build_test_externalities().execute_with(|| {
  1259. HireLeadFixture::default().hire_lead();
  1260. let worker_id = 0;
  1261. let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1262. .with_origin(RawOrigin::None);
  1263. increase_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1264. });
  1265. }
  1266. #[test]
  1267. fn increase_worker_stake_fails_with_zero_balance() {
  1268. build_test_externalities().execute_with(|| {
  1269. let total_balance = 300;
  1270. let stake = 200;
  1271. let stake_policy = StakePolicy {
  1272. stake_amount: stake,
  1273. leaving_unstaking_period: 10,
  1274. };
  1275. let worker_id = HireRegularWorkerFixture::default()
  1276. .with_stake_policy(stake_policy)
  1277. .with_initial_balance(total_balance)
  1278. .hire();
  1279. let increase_stake_fixture =
  1280. IncreaseWorkerStakeFixture::default_for_worker_id(worker_id).with_balance(0);
  1281. increase_stake_fixture.call_and_assert(Err(
  1282. Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
  1283. ));
  1284. });
  1285. }
  1286. #[test]
  1287. fn increase_worker_stake_fails_with_invalid_worker_id() {
  1288. build_test_externalities().execute_with(|| {
  1289. HireLeadFixture::default().hire_lead();
  1290. let invalid_worker_id = 11;
  1291. let increase_stake_fixture =
  1292. IncreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
  1293. increase_stake_fixture.call_and_assert(Err(
  1294. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  1295. ));
  1296. });
  1297. }
  1298. #[test]
  1299. fn increase_worker_stake_fails_external_check() {
  1300. build_test_externalities().execute_with(|| {
  1301. let total_balance = 300;
  1302. let stake = 200;
  1303. let stake_policy = StakePolicy {
  1304. stake_amount: stake,
  1305. leaving_unstaking_period: 10,
  1306. };
  1307. let worker_id = HireRegularWorkerFixture::default()
  1308. .with_initial_balance(total_balance)
  1309. .with_stake_policy(stake_policy)
  1310. .hire();
  1311. let invalid_new_stake = 2000;
  1312. let decrease_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1313. .with_balance(invalid_new_stake);
  1314. decrease_stake_fixture.call_and_assert(Err(
  1315. Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),
  1316. ));
  1317. });
  1318. }
  1319. #[test]
  1320. fn withdraw_application_succeeds() {
  1321. build_test_externalities().execute_with(|| {
  1322. /*
  1323. Events are not emitted on block 0.
  1324. So any dispatchable calls made during genesis block formation will have no events emitted.
  1325. https://substrate.dev/recipes/2-appetizers/4-events.html
  1326. */
  1327. let starting_block = 1;
  1328. run_to_block(starting_block);
  1329. let account_id = 2;
  1330. let total_balance = 300;
  1331. let stake = 200;
  1332. let stake_parameters = StakeParameters {
  1333. stake,
  1334. staking_account_id: account_id,
  1335. };
  1336. HireLeadFixture::default().hire_lead();
  1337. let add_opening_fixture = AddOpeningFixture::default()
  1338. .with_starting_block(starting_block)
  1339. .with_stake_policy(StakePolicy {
  1340. stake_amount: stake,
  1341. leaving_unstaking_period: 10,
  1342. });
  1343. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  1344. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  1345. .with_initial_balance(total_balance)
  1346. .with_stake_parameters(stake_parameters);
  1347. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  1348. let withdraw_application_fixture =
  1349. WithdrawApplicationFixture::default_for_application_id(application_id).with_stake();
  1350. withdraw_application_fixture.call_and_assert(Ok(()));
  1351. EventFixture::assert_last_crate_event(RawEvent::ApplicationWithdrawn(application_id));
  1352. });
  1353. }
  1354. #[test]
  1355. fn withdraw_application_fails_invalid_application_id() {
  1356. build_test_externalities().execute_with(|| {
  1357. let invalid_application_id = 6;
  1358. let withdraw_application_fixture =
  1359. WithdrawApplicationFixture::default_for_application_id(invalid_application_id);
  1360. withdraw_application_fixture.call_and_assert(Err(
  1361. Error::<Test, DefaultInstance>::WorkerApplicationDoesNotExist.into(),
  1362. ));
  1363. });
  1364. }
  1365. #[test]
  1366. fn withdraw_application_fails_invalid_origin() {
  1367. build_test_externalities().execute_with(|| {
  1368. HireLeadFixture::default().hire_lead();
  1369. let add_opening_fixture = AddOpeningFixture::default();
  1370. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  1371. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
  1372. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  1373. let withdraw_application_fixture =
  1374. WithdrawApplicationFixture::default_for_application_id(application_id)
  1375. .with_origin(RawOrigin::None);
  1376. withdraw_application_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1377. });
  1378. }
  1379. #[test]
  1380. fn withdraw_worker_application_fails_with_invalid_application_author() {
  1381. build_test_externalities().execute_with(|| {
  1382. HireLeadFixture::default().hire_lead();
  1383. let add_opening_fixture = AddOpeningFixture::default();
  1384. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  1385. let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
  1386. .with_initial_balance(<Test as Trait>::MinimumApplicationStake::get() + 1);
  1387. let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
  1388. let invalid_author_account_id = 55;
  1389. let withdraw_application_fixture =
  1390. WithdrawApplicationFixture::default_for_application_id(application_id)
  1391. .with_signer(invalid_author_account_id);
  1392. withdraw_application_fixture.call_and_assert(Err(
  1393. Error::<Test, DefaultInstance>::OriginIsNotApplicant.into(),
  1394. ));
  1395. });
  1396. }
  1397. #[test]
  1398. fn cancel_opening_succeeds() {
  1399. build_test_externalities().execute_with(|| {
  1400. /*
  1401. Events are not emitted on block 0.
  1402. So any dispatchable calls made during genesis block formation will have no events emitted.
  1403. https://substrate.dev/recipes/2-appetizers/4-events.html
  1404. */
  1405. let starting_block = 1;
  1406. run_to_block(starting_block);
  1407. HireLeadFixture::default().hire_lead();
  1408. let add_opening_fixture = AddOpeningFixture::default().with_starting_block(starting_block);
  1409. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  1410. let initial_balance = Balances::usable_balance(&1);
  1411. let cancel_opening_fixture = CancelOpeningFixture::default_for_opening_id(opening_id);
  1412. cancel_opening_fixture.call_and_assert(Ok(()));
  1413. assert_eq!(
  1414. Balances::usable_balance(&1),
  1415. initial_balance + <Test as Trait>::LeaderOpeningStake::get()
  1416. );
  1417. EventFixture::assert_last_crate_event(RawEvent::OpeningCanceled(opening_id));
  1418. });
  1419. }
  1420. #[test]
  1421. fn cancel_opening_fails_invalid_origin() {
  1422. build_test_externalities().execute_with(|| {
  1423. HireLeadFixture::default().hire_lead();
  1424. let add_opening_fixture = AddOpeningFixture::default();
  1425. let opening_id = add_opening_fixture.call_and_assert(Ok(()));
  1426. let cancel_opening_fixture =
  1427. CancelOpeningFixture::default_for_opening_id(opening_id).with_origin(RawOrigin::None);
  1428. cancel_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1429. });
  1430. }
  1431. #[test]
  1432. fn cancel_opening_fails_invalid_opening_id() {
  1433. build_test_externalities().execute_with(|| {
  1434. let invalid_opening_id = 11;
  1435. let cancel_opening_fixture =
  1436. CancelOpeningFixture::default_for_opening_id(invalid_opening_id);
  1437. cancel_opening_fixture.call_and_assert(Err(
  1438. Error::<Test, DefaultInstance>::OpeningDoesNotExist.into(),
  1439. ));
  1440. });
  1441. }
  1442. #[test]
  1443. fn decrease_worker_stake_fails_with_leaving_worker() {
  1444. build_test_externalities().execute_with(|| {
  1445. let total_balance = 300;
  1446. let stake = 200;
  1447. let new_stake_balance = 100;
  1448. let stake_policy = StakePolicy {
  1449. stake_amount: stake,
  1450. leaving_unstaking_period: 10,
  1451. };
  1452. let worker_id = HireRegularWorkerFixture::default()
  1453. .with_initial_balance(total_balance)
  1454. .with_stake_policy(stake_policy.clone())
  1455. .hire();
  1456. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  1457. leave_worker_role_fixture.call_and_assert(Ok(()));
  1458. let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1459. .with_balance(new_stake_balance);
  1460. decrease_stake_fixture
  1461. .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
  1462. });
  1463. }
  1464. #[test]
  1465. fn increase_worker_stake_fails_with_leaving_worker() {
  1466. build_test_externalities().execute_with(|| {
  1467. let total_balance = 300;
  1468. let stake = 200;
  1469. let new_stake_balance = 100;
  1470. let stake_policy = StakePolicy {
  1471. stake_amount: stake,
  1472. leaving_unstaking_period: 10,
  1473. };
  1474. let worker_id = HireRegularWorkerFixture::default()
  1475. .with_stake_policy(stake_policy.clone())
  1476. .with_initial_balance(total_balance)
  1477. .hire();
  1478. let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
  1479. leave_worker_role_fixture.call_and_assert(Ok(()));
  1480. let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
  1481. .with_balance(new_stake_balance);
  1482. increase_stake_fixture
  1483. .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
  1484. });
  1485. }
  1486. #[test]
  1487. fn rewards_payments_are_successful() {
  1488. build_test_externalities().execute_with(|| {
  1489. let reward_per_block = 10;
  1490. let worker_id = HireRegularWorkerFixture::default()
  1491. .with_reward_per_block(Some(reward_per_block))
  1492. .hire();
  1493. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1494. let account_id = worker.role_account_id;
  1495. SetBudgetFixture::default().execute();
  1496. assert_eq!(Balances::usable_balance(&account_id), 0);
  1497. let block_number = 10;
  1498. run_to_block(block_number);
  1499. assert_eq!(
  1500. Balances::usable_balance(&account_id),
  1501. block_number * reward_per_block
  1502. );
  1503. let reward_period: u64 = <Test as Trait>::RewardPeriod::get().into();
  1504. EventFixture::assert_last_crate_event(RawEvent::RewardPaid(
  1505. worker_id,
  1506. account_id,
  1507. reward_per_block * reward_period,
  1508. RewardPaymentType::RegularReward,
  1509. ));
  1510. });
  1511. }
  1512. #[test]
  1513. fn rewards_payments_with_no_budget() {
  1514. build_test_externalities().execute_with(|| {
  1515. let reward_per_block = 10;
  1516. let worker_id = HireRegularWorkerFixture::default()
  1517. .with_reward_per_block(Some(reward_per_block))
  1518. .hire();
  1519. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1520. let account_id = worker.role_account_id;
  1521. assert_eq!(Balances::usable_balance(&account_id), 0);
  1522. let block_number = 10;
  1523. run_to_block(block_number);
  1524. assert_eq!(Balances::usable_balance(&account_id), 0);
  1525. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1526. assert_eq!(
  1527. worker.missed_reward.unwrap(),
  1528. block_number * reward_per_block
  1529. );
  1530. });
  1531. }
  1532. #[test]
  1533. fn rewards_payments_with_insufficient_budget_and_restored_budget() {
  1534. build_test_externalities().execute_with(|| {
  1535. let reward_per_block = 10;
  1536. let worker_id = HireRegularWorkerFixture::default()
  1537. .with_reward_per_block(Some(reward_per_block))
  1538. .hire();
  1539. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1540. let account_id = worker.reward_account_id;
  1541. assert_eq!(Balances::usable_balance(&account_id), 0);
  1542. let paid_blocks = 3;
  1543. let first_budget = paid_blocks * reward_per_block;
  1544. SetBudgetFixture::default()
  1545. .with_budget(first_budget)
  1546. .execute();
  1547. let block_number = 10;
  1548. run_to_block(block_number);
  1549. assert_eq!(Balances::usable_balance(&account_id), first_budget);
  1550. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1551. let effective_missed_reward: u64 = block_number * reward_per_block - first_budget;
  1552. assert_eq!(worker.missed_reward.unwrap(), effective_missed_reward);
  1553. SetBudgetFixture::default().with_budget(1000000).execute();
  1554. // Checkpoint with restored budget.
  1555. let block_number2 = 20;
  1556. run_to_block(block_number2);
  1557. assert_eq!(
  1558. Balances::usable_balance(&account_id),
  1559. block_number2 * reward_per_block
  1560. );
  1561. });
  1562. }
  1563. #[test]
  1564. fn rewards_payments_with_starting_block() {
  1565. build_test_externalities().execute_with(|| {
  1566. let starting_block = 3;
  1567. run_to_block(starting_block);
  1568. let reward_per_block = 10;
  1569. let reward_period: u64 = RewardPeriod::get().into();
  1570. let worker_id = HireRegularWorkerFixture::default()
  1571. .with_reward_per_block(Some(reward_per_block))
  1572. .hire();
  1573. let worker = TestWorkingGroup::worker_by_id(worker_id);
  1574. let account_id = worker.reward_account_id;
  1575. SetBudgetFixture::default().with_budget(100000).execute();
  1576. let block_number = 11;
  1577. run_to_block(block_number);
  1578. let effective_paid_blocks =
  1579. (block_number - starting_block) - (block_number % reward_period);
  1580. assert_eq!(
  1581. Balances::usable_balance(&account_id),
  1582. effective_paid_blocks * reward_per_block
  1583. );
  1584. });
  1585. }
  1586. #[test]
  1587. fn set_budget_succeeded() {
  1588. build_test_externalities().execute_with(|| {
  1589. run_to_block(1);
  1590. let new_budget = 10000;
  1591. SetBudgetFixture::default()
  1592. .with_budget(new_budget)
  1593. .call_and_assert(Ok(()));
  1594. EventFixture::assert_last_crate_event(RawEvent::BudgetSet(new_budget));
  1595. });
  1596. }
  1597. #[test]
  1598. fn set_budget_fails_with_bad_origin() {
  1599. build_test_externalities().execute_with(|| {
  1600. HireLeadFixture::default().hire_lead();
  1601. let leader_account_id = 1;
  1602. SetBudgetFixture::default()
  1603. .with_origin(RawOrigin::Signed(leader_account_id))
  1604. .call_and_assert(Err(DispatchError::BadOrigin));
  1605. });
  1606. }
  1607. #[test]
  1608. fn update_reward_account_succeeds() {
  1609. build_test_externalities().execute_with(|| {
  1610. /*
  1611. Events are not emitted on block 0.
  1612. So any dispatchable calls made during genesis block formation will have no events emitted.
  1613. https://substrate.dev/recipes/2-appetizers/4-events.html
  1614. */
  1615. run_to_block(1);
  1616. let reward_per_block = 10;
  1617. let worker_id = HireRegularWorkerFixture::default()
  1618. .with_reward_per_block(Some(reward_per_block))
  1619. .hire();
  1620. let new_reward_account = 22;
  1621. let update_account_fixture =
  1622. UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account);
  1623. update_account_fixture.call_and_assert(Ok(()));
  1624. EventFixture::assert_last_crate_event(RawEvent::WorkerRewardAccountUpdated(
  1625. worker_id,
  1626. new_reward_account,
  1627. ));
  1628. });
  1629. }
  1630. #[test]
  1631. fn update_reward_account_succeeds_for_leader() {
  1632. build_test_externalities().execute_with(|| {
  1633. let reward_per_block = 10;
  1634. let worker_id = HireLeadFixture::default()
  1635. .with_reward_per_block(Some(reward_per_block))
  1636. .hire_lead();
  1637. let new_reward_account = 22;
  1638. let update_account_fixture =
  1639. UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account)
  1640. .with_origin(RawOrigin::Signed(1));
  1641. update_account_fixture.call_and_assert(Ok(()));
  1642. });
  1643. }
  1644. #[test]
  1645. fn update_reward_account_fails_with_invalid_origin() {
  1646. build_test_externalities().execute_with(|| {
  1647. let update_account_fixture =
  1648. UpdateRewardAccountFixture::default_with_ids(1, 1).with_origin(RawOrigin::None);
  1649. update_account_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1650. });
  1651. }
  1652. #[test]
  1653. fn update_reward_account_fails_with_invalid_origin_signed_account() {
  1654. build_test_externalities().execute_with(|| {
  1655. let reward_per_block = 10;
  1656. let worker_id = HireLeadFixture::default()
  1657. .with_reward_per_block(Some(reward_per_block))
  1658. .hire_lead();
  1659. let invalid_role_account = 23333;
  1660. let new_reward_account = 22;
  1661. let update_account_fixture =
  1662. UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account)
  1663. .with_origin(RawOrigin::Signed(invalid_role_account));
  1664. update_account_fixture.call_and_assert(Err(
  1665. Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into(),
  1666. ));
  1667. });
  1668. }
  1669. #[test]
  1670. fn update_reward_account_fails_with_invalid_worker_id() {
  1671. build_test_externalities().execute_with(|| {
  1672. let reward_per_block = 10;
  1673. HireRegularWorkerFixture::default()
  1674. .with_reward_per_block(Some(reward_per_block))
  1675. .hire();
  1676. let invalid_worker_id = 11;
  1677. let new_reward_account = 2;
  1678. let update_account_fixture =
  1679. UpdateRewardAccountFixture::default_with_ids(invalid_worker_id, new_reward_account);
  1680. update_account_fixture.call_and_assert(Err(
  1681. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  1682. ));
  1683. });
  1684. }
  1685. #[test]
  1686. fn update_reward_account_fails_with_no_recurring_reward() {
  1687. build_test_externalities().execute_with(|| {
  1688. let worker_id = HireRegularWorkerFixture::default().hire();
  1689. let new_reward_account = 343;
  1690. let update_account_fixture =
  1691. UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account);
  1692. update_account_fixture
  1693. .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerHasNoReward.into()));
  1694. });
  1695. }
  1696. #[test]
  1697. fn update_reward_amount_succeeds() {
  1698. build_test_externalities().execute_with(|| {
  1699. /*
  1700. Events are not emitted on block 0.
  1701. So any dispatchable calls made during genesis block formation will have no events emitted.
  1702. https://substrate.dev/recipes/2-appetizers/4-events.html
  1703. */
  1704. run_to_block(1);
  1705. let worker_id = HireRegularWorkerFixture::default().hire();
  1706. let reward_per_block = 120;
  1707. let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
  1708. .with_reward_per_block(Some(reward_per_block));
  1709. update_amount_fixture.call_and_assert(Ok(()));
  1710. EventFixture::assert_last_crate_event(RawEvent::WorkerRewardAmountUpdated(
  1711. worker_id,
  1712. Some(reward_per_block),
  1713. ));
  1714. });
  1715. }
  1716. #[test]
  1717. fn update_reward_amount_succeeds_for_leader() {
  1718. build_test_externalities().execute_with(|| {
  1719. let worker_id = HireLeadFixture::default()
  1720. .with_reward_per_block(Some(1000))
  1721. .hire_lead();
  1722. let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
  1723. .with_origin(RawOrigin::Root);
  1724. update_amount_fixture.call_and_assert(Ok(()));
  1725. });
  1726. }
  1727. #[test]
  1728. fn update_reward_amount_fails_with_invalid_origin() {
  1729. build_test_externalities().execute_with(|| {
  1730. HireLeadFixture::default().hire_lead();
  1731. let worker_id = 22; // random worker id
  1732. let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
  1733. .with_origin(RawOrigin::None);
  1734. update_amount_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1735. });
  1736. }
  1737. #[test]
  1738. fn update_reward_amount_fails_with_invalid_origin_for_leader() {
  1739. build_test_externalities().execute_with(|| {
  1740. let worker_id = HireLeadFixture::default().hire_lead();
  1741. let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
  1742. .with_origin(RawOrigin::None);
  1743. update_amount_fixture.call_and_assert(Err(DispatchError::BadOrigin));
  1744. });
  1745. }
  1746. #[test]
  1747. fn update_reward_amount_fails_with_invalid_origin_signed_account() {
  1748. build_test_externalities().execute_with(|| {
  1749. let worker_id = HireRegularWorkerFixture::default().hire();
  1750. let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
  1751. .with_origin(RawOrigin::Signed(2));
  1752. update_amount_fixture
  1753. .call_and_assert(Err(Error::<Test, DefaultInstance>::IsNotLeadAccount.into()));
  1754. });
  1755. }
  1756. #[test]
  1757. fn update_reward_amount_fails_with_invalid_worker_id() {
  1758. build_test_externalities().execute_with(|| {
  1759. HireRegularWorkerFixture::default().hire();
  1760. let invalid_worker_id = 12;
  1761. let update_amount_fixture =
  1762. UpdateRewardAmountFixture::default_for_worker_id(invalid_worker_id);
  1763. update_amount_fixture.call_and_assert(Err(
  1764. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  1765. ));
  1766. });
  1767. }
  1768. #[test]
  1769. fn set_status_text_succeeded() {
  1770. build_test_externalities().execute_with(|| {
  1771. HireLeadFixture::default().hire_lead();
  1772. run_to_block(1);
  1773. let status_text = b"some".to_vec();
  1774. SetStatusTextFixture::default()
  1775. .with_status_text(Some(status_text.clone()))
  1776. .call_and_assert(Ok(()));
  1777. let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&status_text);
  1778. EventFixture::assert_last_crate_event(RawEvent::StatusTextChanged(
  1779. expected_hash.as_ref().to_vec(),
  1780. Some(status_text),
  1781. ));
  1782. });
  1783. }
  1784. #[test]
  1785. fn set_status_text_fails_with_bad_origin() {
  1786. build_test_externalities().execute_with(|| {
  1787. HireLeadFixture::default().hire_lead();
  1788. let leader_account_id = 10;
  1789. SetStatusTextFixture::default()
  1790. .with_origin(RawOrigin::Signed(leader_account_id))
  1791. .call_and_assert(Err(Error::<Test, DefaultInstance>::IsNotLeadAccount.into()));
  1792. });
  1793. }
  1794. #[test]
  1795. fn spend_from_budget_succeeded() {
  1796. build_test_externalities().execute_with(|| {
  1797. let account_id = 2;
  1798. let amount = 100;
  1799. HireLeadFixture::default().hire_lead();
  1800. run_to_block(1);
  1801. let set_budget_fixture = SetBudgetFixture::default().with_budget(1000);
  1802. assert_eq!(set_budget_fixture.call(), Ok(()));
  1803. SpendFromBudgetFixture::default()
  1804. .with_account_id(account_id)
  1805. .with_amount(amount)
  1806. .call_and_assert(Ok(()));
  1807. EventFixture::assert_last_crate_event(RawEvent::BudgetSpending(account_id, amount, None));
  1808. });
  1809. }
  1810. #[test]
  1811. fn spend_from_budget_failed_with_invalid_origin() {
  1812. build_test_externalities().execute_with(|| {
  1813. SpendFromBudgetFixture::default()
  1814. .with_origin(RawOrigin::None.into())
  1815. .call_and_assert(Err(DispatchError::BadOrigin));
  1816. });
  1817. }
  1818. #[test]
  1819. fn spend_from_budget_fails_with_empty_budget() {
  1820. build_test_externalities().execute_with(|| {
  1821. let account_id = 2;
  1822. let amount = 100;
  1823. HireLeadFixture::default().hire_lead();
  1824. SpendFromBudgetFixture::default()
  1825. .with_account_id(account_id)
  1826. .with_amount(amount)
  1827. .call_and_assert(Err(
  1828. Error::<Test, DefaultInstance>::InsufficientBudgetForSpending.into(),
  1829. ));
  1830. });
  1831. }
  1832. #[test]
  1833. fn spend_from_budget_fails_with_zero_amount() {
  1834. build_test_externalities().execute_with(|| {
  1835. let account_id = 2;
  1836. let amount = 0;
  1837. HireLeadFixture::default().hire_lead();
  1838. SpendFromBudgetFixture::default()
  1839. .with_account_id(account_id)
  1840. .with_amount(amount)
  1841. .call_and_assert(Err(Error::<Test, DefaultInstance>::CannotSpendZero.into()));
  1842. });
  1843. }
  1844. #[test]
  1845. fn ensure_worker_origin_works_correctly() {
  1846. build_test_externalities().execute_with(|| {
  1847. let invalid_worker_id = 2;
  1848. assert_eq!(
  1849. TestWorkingGroup::ensure_worker_origin(RawOrigin::None.into(), &invalid_worker_id),
  1850. Err(DispatchError::BadOrigin)
  1851. );
  1852. let account_id = 2;
  1853. assert_eq!(
  1854. TestWorkingGroup::ensure_worker_origin(
  1855. RawOrigin::Signed(account_id).into(),
  1856. &invalid_worker_id
  1857. ),
  1858. Err(Error::<Test, DefaultInstance>::WorkerDoesNotExist.into())
  1859. );
  1860. let worker_id = HireRegularWorkerFixture::default().hire();
  1861. let invalid_account = 3;
  1862. assert_eq!(
  1863. TestWorkingGroup::ensure_worker_origin(
  1864. RawOrigin::Signed(invalid_account).into(),
  1865. &worker_id
  1866. ),
  1867. Err(Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into())
  1868. );
  1869. assert_eq!(
  1870. TestWorkingGroup::ensure_worker_origin(
  1871. RawOrigin::Signed(account_id).into(),
  1872. &worker_id
  1873. ),
  1874. Ok(())
  1875. );
  1876. });
  1877. }
  1878. #[test]
  1879. fn ensure_leader_origin_works_correctly() {
  1880. build_test_externalities().execute_with(|| {
  1881. assert_eq!(
  1882. TestWorkingGroup::ensure_leader_origin(RawOrigin::None.into()),
  1883. Err(DispatchError::BadOrigin)
  1884. );
  1885. let account_id = 1;
  1886. assert_eq!(
  1887. TestWorkingGroup::ensure_leader_origin(RawOrigin::Signed(account_id).into()),
  1888. Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into())
  1889. );
  1890. HireLeadFixture::default().hire_lead();
  1891. let invalid_account = 2;
  1892. assert_eq!(
  1893. TestWorkingGroup::ensure_leader_origin(RawOrigin::Signed(invalid_account).into()),
  1894. Err(Error::<Test, DefaultInstance>::IsNotLeadAccount.into())
  1895. );
  1896. assert_eq!(
  1897. TestWorkingGroup::ensure_leader_origin(RawOrigin::Signed(account_id).into()),
  1898. Ok(())
  1899. );
  1900. });
  1901. }
  1902. #[test]
  1903. fn get_leader_member_id_works_correctly() {
  1904. build_test_externalities().execute_with(|| {
  1905. assert_eq!(TestWorkingGroup::get_leader_member_id(), None);
  1906. HireLeadFixture::default().hire_lead();
  1907. let leader_member_id = 1;
  1908. assert_eq!(
  1909. TestWorkingGroup::get_leader_member_id(),
  1910. Some(leader_member_id)
  1911. );
  1912. });
  1913. }
  1914. #[test]
  1915. fn is_leader_account_id_works_correctly() {
  1916. build_test_externalities().execute_with(|| {
  1917. let invalid_account_id = 2u64;
  1918. // No leader set
  1919. assert_eq!(
  1920. TestWorkingGroup::is_leader_account_id(&invalid_account_id),
  1921. false
  1922. );
  1923. HireLeadFixture::default().hire_lead();
  1924. assert_eq!(
  1925. TestWorkingGroup::is_leader_account_id(&invalid_account_id),
  1926. false
  1927. );
  1928. let account_id = 1u64;
  1929. assert_eq!(TestWorkingGroup::is_leader_account_id(&account_id), true);
  1930. });
  1931. }
  1932. #[test]
  1933. fn is_worker_account_id_works_correctly() {
  1934. build_test_externalities().execute_with(|| {
  1935. let invalid_account_id = 3u64;
  1936. let invalid_worker_id = 3u64;
  1937. // Not hired
  1938. assert_eq!(
  1939. TestWorkingGroup::is_worker_account_id(&invalid_account_id, &invalid_worker_id),
  1940. false
  1941. );
  1942. let worker_id = HireRegularWorkerFixture::default().hire();
  1943. assert_eq!(
  1944. TestWorkingGroup::is_worker_account_id(&invalid_account_id, &worker_id),
  1945. false
  1946. );
  1947. let account_id = 2u64;
  1948. assert_eq!(
  1949. TestWorkingGroup::is_worker_account_id(&account_id, &invalid_worker_id),
  1950. false
  1951. );
  1952. assert_eq!(
  1953. TestWorkingGroup::is_worker_account_id(&account_id, &worker_id),
  1954. true
  1955. );
  1956. });
  1957. }
  1958. #[test]
  1959. fn update_worker_storage_succeeds() {
  1960. build_test_externalities().execute_with(|| {
  1961. /*
  1962. Events are not emitted on block 0.
  1963. So any dispatchable calls made during genesis block formation will have no events emitted.
  1964. https://substrate.dev/recipes/2-appetizers/4-events.html
  1965. */
  1966. run_to_block(1);
  1967. let storage_field = vec![0u8].repeat(10);
  1968. let worker_id = HireRegularWorkerFixture::default().hire();
  1969. let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
  1970. worker_id,
  1971. storage_field.clone(),
  1972. );
  1973. update_storage_fixture.call_and_assert(Ok(()));
  1974. EventFixture::assert_last_crate_event(RawEvent::WorkerStorageUpdated(
  1975. worker_id,
  1976. storage_field,
  1977. ));
  1978. });
  1979. }
  1980. #[test]
  1981. fn update_worker_storage_by_leader_succeeds() {
  1982. build_test_externalities().execute_with(|| {
  1983. let storage_field = vec![0u8].repeat(10);
  1984. let leader_account_id = 1;
  1985. let worker_id = HireLeadFixture::default().hire_lead();
  1986. let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
  1987. worker_id,
  1988. storage_field.clone(),
  1989. )
  1990. .with_origin(RawOrigin::Signed(leader_account_id));
  1991. update_storage_fixture.call_and_assert(Ok(()));
  1992. let worker_storage = TestWorkingGroup::worker_storage(worker_id);
  1993. assert_eq!(storage_field, worker_storage);
  1994. });
  1995. }
  1996. #[test]
  1997. fn update_worker_storage_fails_with_invalid_origin_signed_account() {
  1998. build_test_externalities().execute_with(|| {
  1999. let worker_id = HireRegularWorkerFixture::default().hire();
  2000. let invalid_account_id = 44;
  2001. let storage_field = vec![0u8].repeat(10);
  2002. let update_storage_fixture =
  2003. UpdateWorkerStorageFixture::default_with_storage_field(worker_id, storage_field)
  2004. .with_origin(RawOrigin::Signed(invalid_account_id));
  2005. update_storage_fixture.call_and_assert(Err(
  2006. Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into(),
  2007. ));
  2008. });
  2009. }
  2010. #[test]
  2011. fn update_worker_storage_fails_with_invalid_worker_id() {
  2012. build_test_externalities().execute_with(|| {
  2013. let storage_field = vec![0u8].repeat(10);
  2014. HireRegularWorkerFixture::default().hire();
  2015. let invalid_worker_id = 111;
  2016. let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
  2017. invalid_worker_id,
  2018. storage_field.clone(),
  2019. );
  2020. update_storage_fixture.call_and_assert(Err(
  2021. Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
  2022. ));
  2023. });
  2024. }
  2025. #[test]
  2026. fn update_worker_storage_fails_with_too_long_text() {
  2027. build_test_externalities().execute_with(|| {
  2028. let storage_field = vec![0u8].repeat(default_storage_size_constraint() as usize + 1);
  2029. let worker_id = HireRegularWorkerFixture::default().hire();
  2030. let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
  2031. worker_id,
  2032. storage_field.clone(),
  2033. );
  2034. update_storage_fixture.call_and_assert(Err(
  2035. Error::<Test, DefaultInstance>::WorkerStorageValueTooLong.into(),
  2036. ));
  2037. });
  2038. }