transport.mock.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. import { Observable } from 'rxjs';
  2. import { Balance } from '@polkadot/types/interfaces';
  3. import { Option, u32, u128, GenericAccountId } from '@polkadot/types';
  4. import { Subscribable, Transport as TransportBase } from '@polkadot/joy-utils/index';
  5. import { ITransport } from './transport';
  6. import { Role, MemberId } from '@joystream/types/members';
  7. import {
  8. Opening,
  9. ApplicationRationingPolicy,
  10. StakingPolicy
  11. } from '@joystream/types/hiring';
  12. import { WorkingGroupMembership, GroupLeadStatus } from './tabs/WorkingGroup';
  13. import { CuratorId } from '@joystream/types/content-working-group';
  14. import { WorkingGroupOpening } from './tabs/Opportunities';
  15. import { ActiveRole, OpeningApplication } from './tabs/MyRoles';
  16. import { ApplicationStakeRequirement, RoleStakeRequirement, StakeType } from './StakeRequirement';
  17. import { keyPairDetails } from './flows/apply';
  18. import { tomorrow, yesterday, newMockHumanReadableText } from './tabs/Opportunities.stories';
  19. import { OpeningState } from './classifiers';
  20. import * as faker from 'faker';
  21. import { mockProfile, mockStage } from './mocks';
  22. import { WorkingGroups, workerRoleNameByGroup } from './working_groups';
  23. export class Transport extends TransportBase implements ITransport {
  24. protected simulateApiResponse<T> (value: T): Promise<T> {
  25. return this.promise<T>(value, this.randomTimeout());
  26. }
  27. protected randomTimeout (min = 1, max = 20): number {
  28. return Math.random() * (max - min) + min;
  29. }
  30. roles (): Promise<Array<Role>> {
  31. return this.promise<Array<Role>>(
  32. [
  33. new Role('StorageProvider')
  34. ]
  35. );
  36. }
  37. groupLeadStatus (group: WorkingGroups = WorkingGroups.ContentCurators): Promise<GroupLeadStatus> {
  38. return this.simulateApiResponse<GroupLeadStatus>({
  39. loaded: true
  40. });
  41. }
  42. async curationGroup (): Promise<WorkingGroupMembership> {
  43. return this.simulateApiResponse<WorkingGroupMembership>({
  44. leadStatus: await this.groupLeadStatus(),
  45. workerRolesAvailable: true,
  46. leadRolesAvailable: false,
  47. workers: [
  48. {
  49. memberId: new MemberId(1),
  50. roleAccount: new GenericAccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp'),
  51. profile: mockProfile(
  52. 'benholdencrowther',
  53. 'https://www.benholdencrowther.com/wp-content/uploads/2019/03/Hanging_Gardens_of_Babylon.jpg'
  54. ),
  55. title: 'Content curator',
  56. stake: new u128(10101),
  57. workerId: 1,
  58. group: WorkingGroups.ContentCurators
  59. },
  60. {
  61. memberId: new MemberId(2),
  62. roleAccount: new GenericAccountId('5DfJWGbBAH8hLAg8rcRYZW5BEZbE4BJeCQKoxUeqoyewLSew'),
  63. profile: mockProfile('bwhm0'),
  64. title: 'Content curator',
  65. stake: new u128(10101),
  66. workerId: 2,
  67. group: WorkingGroups.ContentCurators
  68. },
  69. {
  70. memberId: new MemberId(3),
  71. roleAccount: new GenericAccountId('5DQqNWRFPruFs9YKheVMqxUbqoXeMzAWfVfcJgzuia7NA3D3'),
  72. profile: mockProfile(
  73. 'yourheropaul',
  74. 'https://yhp.io/img/paul.svg'
  75. ),
  76. title: 'Content curator',
  77. stake: new u128(10101),
  78. workerId: 3,
  79. group: WorkingGroups.ContentCurators
  80. },
  81. {
  82. memberId: new MemberId(4),
  83. roleAccount: new GenericAccountId('5GSMNn8Sy8k64mGUWPDafjMZu9bQNX26GujbBQ1LeJpNbrfg'),
  84. profile: mockProfile(
  85. 'alex_joystream',
  86. 'https://avatars2.githubusercontent.com/u/153928?s=200&v=4'
  87. ),
  88. title: 'Content curator',
  89. stake: new u128(10101),
  90. workerId: 4,
  91. group: WorkingGroups.ContentCurators
  92. },
  93. {
  94. memberId: new MemberId(3),
  95. roleAccount: new GenericAccountId('5Gn9n7SDJ7VgHqHQWYzkSA4vX6DCmS5TFWdHxikTXp9b4L32'),
  96. profile: mockProfile(
  97. 'mokhtar',
  98. 'https://avatars2.githubusercontent.com/u/1621012?s=460&v=4'
  99. ),
  100. title: 'Content curator',
  101. stake: new u128(10101),
  102. workerId: 5,
  103. group: WorkingGroups.ContentCurators
  104. }
  105. ]
  106. });
  107. }
  108. async storageGroup (): Promise<WorkingGroupMembership> {
  109. return this.simulateApiResponse<WorkingGroupMembership>({
  110. leadStatus: await this.groupLeadStatus(),
  111. workerRolesAvailable: true,
  112. leadRolesAvailable: true,
  113. workers: [
  114. {
  115. memberId: new MemberId(1),
  116. roleAccount: new GenericAccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp'),
  117. profile: mockProfile(
  118. 'benholdencrowther',
  119. 'https://www.benholdencrowther.com/wp-content/uploads/2019/03/Hanging_Gardens_of_Babylon.jpg'
  120. ),
  121. title: 'Storage provider',
  122. stake: new u128(10101),
  123. workerId: 1,
  124. group: WorkingGroups.StorageProviders
  125. }
  126. ]
  127. });
  128. }
  129. currentOpportunities (): Promise<Array<WorkingGroupOpening>> {
  130. return this.simulateApiResponse<Array<WorkingGroupOpening>>(
  131. [
  132. {
  133. opening: new Opening({
  134. created: new u32(50000),
  135. stage: mockStage,
  136. max_review_period_length: new u32(100),
  137. application_rationing_policy: new Option(ApplicationRationingPolicy),
  138. application_staking_policy: new Option(StakingPolicy),
  139. role_staking_policy: new Option(StakingPolicy),
  140. human_readable_text: newMockHumanReadableText({
  141. version: 1,
  142. headline: 'Help us curate awesome content',
  143. job: {
  144. title: 'Content curator',
  145. description: faker.lorem.paragraphs(4)
  146. },
  147. application: {
  148. sections: [
  149. {
  150. title: 'About you',
  151. questions: [
  152. {
  153. title: 'your name',
  154. type: 'text'
  155. }
  156. ]
  157. },
  158. {
  159. title: 'About you',
  160. questions: [
  161. {
  162. title: 'your name',
  163. type: 'text area'
  164. }
  165. ]
  166. }
  167. ]
  168. },
  169. reward: '10 JOY per block',
  170. process: {
  171. details: [
  172. 'Some custom detail'
  173. ]
  174. }
  175. })
  176. }),
  177. meta: {
  178. id: '1',
  179. group: WorkingGroups.ContentCurators
  180. },
  181. stage: {
  182. state: OpeningState.AcceptingApplications,
  183. starting_block: 2956498,
  184. starting_block_hash: 'somehash',
  185. starting_time: yesterday(),
  186. review_end_block: 3956498,
  187. review_end_time: tomorrow()
  188. },
  189. applications: {
  190. numberOfApplications: 0,
  191. maxNumberOfApplications: 0,
  192. requiredApplicationStake: new ApplicationStakeRequirement(
  193. new u128(500)
  194. ),
  195. requiredRoleStake: new RoleStakeRequirement(
  196. new u128(0)
  197. ),
  198. defactoMinimumStake: new u128(0)
  199. },
  200. defactoMinimumStake: new u128(0)
  201. }
  202. ]
  203. );
  204. }
  205. // eslint-disable-next-line @typescript-eslint/require-await
  206. async groupOpening (group: WorkingGroups, id: number): Promise<WorkingGroupOpening> {
  207. return this.simulateApiResponse<WorkingGroupOpening>(
  208. {
  209. opening: new Opening({
  210. created: new u32(50000),
  211. stage: mockStage,
  212. max_review_period_length: new u32(100),
  213. application_rationing_policy: new Option(ApplicationRationingPolicy),
  214. application_staking_policy: new Option(StakingPolicy),
  215. role_staking_policy: new Option(StakingPolicy),
  216. human_readable_text: newMockHumanReadableText({
  217. version: 1,
  218. headline: 'Help us curate awesome content',
  219. job: {
  220. title: 'Content curator',
  221. description: faker.lorem.paragraphs(4)
  222. },
  223. application: {
  224. sections: [
  225. {
  226. title: 'About you',
  227. questions: [
  228. {
  229. title: 'Your name',
  230. type: 'text'
  231. },
  232. {
  233. title: 'Your e-mail address',
  234. type: 'text'
  235. }
  236. ]
  237. },
  238. {
  239. title: 'Your experience',
  240. questions: [
  241. {
  242. title: 'Why would you be good for this role?',
  243. type: 'text area'
  244. }
  245. ]
  246. }
  247. ]
  248. },
  249. reward: '10 JOY per block',
  250. process: {
  251. details: [
  252. 'Some custom detail'
  253. ]
  254. }
  255. })
  256. }),
  257. meta: {
  258. id: '1',
  259. group: WorkingGroups.ContentCurators
  260. },
  261. stage: {
  262. state: OpeningState.AcceptingApplications,
  263. starting_block: 2956498,
  264. starting_block_hash: 'somehash',
  265. starting_time: yesterday(),
  266. review_end_block: 3956498,
  267. review_end_time: tomorrow()
  268. },
  269. applications: {
  270. numberOfApplications: 0,
  271. maxNumberOfApplications: 0,
  272. requiredApplicationStake: new ApplicationStakeRequirement(
  273. new u128(501),
  274. StakeType.AtLeast
  275. ),
  276. requiredRoleStake: new RoleStakeRequirement(
  277. new u128(502)
  278. ),
  279. defactoMinimumStake: new u128(0)
  280. },
  281. defactoMinimumStake: new u128(0)
  282. }
  283. );
  284. }
  285. openingApplicationRanks (group: WorkingGroups, openingId: number): Promise<Balance[]> {
  286. const slots: Balance[] = [];
  287. for (let i = 0; i < 20; i++) {
  288. slots.push(new u128((i * 100) + 10 + i + 1));
  289. }
  290. return this.simulateApiResponse<Balance[]>(slots);
  291. }
  292. expectedBlockTime (): Promise<number> {
  293. return this.promise<number>(6);
  294. }
  295. blockHash (height: number): Promise<string> {
  296. return this.promise<string>('somehash');
  297. }
  298. blockTimestamp (height: number): Promise<Date> {
  299. return this.promise<Date>(new Date());
  300. }
  301. transactionFee (): Promise<Balance> {
  302. return this.simulateApiResponse<Balance>(new u128(5));
  303. }
  304. accounts (): Subscribable<keyPairDetails[]> {
  305. return new Observable<keyPairDetails[]>(observer => {
  306. observer.next(
  307. [
  308. {
  309. shortName: 'KP1',
  310. accountId: new GenericAccountId('5HZ6GtaeyxagLynPryM7ZnmLzoWFePKuDrkb4AT8rT4pU1fp'),
  311. balance: new u128(23342)
  312. },
  313. {
  314. shortName: 'KP2',
  315. accountId: new GenericAccountId('5DQqNWRFPruFs9YKheVMqxUbqoXeMzAWfVfcJgzuia7NA3D3'),
  316. balance: new u128(993342)
  317. },
  318. {
  319. shortName: 'KP3',
  320. accountId: new GenericAccountId('5DBaczGTDhcHgwsZzNE5qW15GrQxxdyros4pYkcKrSUovFQ9'),
  321. balance: new u128(242)
  322. }
  323. ]
  324. );
  325. });
  326. }
  327. // eslint-disable-next-line @typescript-eslint/require-await
  328. async openingApplicationsByAddress (address: string): Promise<OpeningApplication[]> {
  329. return [{
  330. id: 1,
  331. meta: {
  332. id: '1',
  333. group: WorkingGroups.ContentCurators
  334. },
  335. stage: {
  336. state: OpeningState.AcceptingApplications,
  337. starting_block: 2956498,
  338. starting_block_hash: 'somehash',
  339. starting_time: yesterday()
  340. },
  341. opening: new Opening({
  342. created: new u32(50000),
  343. stage: mockStage,
  344. max_review_period_length: new u32(100),
  345. application_rationing_policy: new Option(ApplicationRationingPolicy),
  346. application_staking_policy: new Option(StakingPolicy),
  347. role_staking_policy: new Option(StakingPolicy),
  348. human_readable_text: newMockHumanReadableText({
  349. version: 1,
  350. headline: 'Help us curate awesome content',
  351. job: {
  352. title: 'Content curator',
  353. description: faker.lorem.paragraphs(4)
  354. },
  355. application: {
  356. sections: [
  357. {
  358. title: 'About you',
  359. questions: [
  360. {
  361. title: 'Your name',
  362. type: 'text'
  363. },
  364. {
  365. title: 'Your e-mail address',
  366. type: 'text'
  367. }
  368. ]
  369. },
  370. {
  371. title: 'Your experience',
  372. questions: [
  373. {
  374. title: 'Why would you be good for this role?',
  375. type: 'text area'
  376. }
  377. ]
  378. }
  379. ]
  380. },
  381. reward: '10 JOY per block',
  382. process: {
  383. details: [
  384. 'Some custom detail'
  385. ]
  386. }
  387. })
  388. }),
  389. applicationStake: new u128(5),
  390. roleStake: new u128(15),
  391. rank: 21,
  392. capacity: 20
  393. }];
  394. }
  395. // eslint-disable-next-line @typescript-eslint/require-await
  396. async myRoles (address: string): Promise<ActiveRole[]> {
  397. return [
  398. {
  399. workerId: new CuratorId(1),
  400. name: workerRoleNameByGroup[WorkingGroups.ContentCurators],
  401. group: WorkingGroups.ContentCurators,
  402. url: 'some URL',
  403. reward: new u128(321),
  404. stake: new u128(12343200)
  405. }
  406. ];
  407. }
  408. // eslint-disable-next-line @typescript-eslint/require-await
  409. async applyToOpening (
  410. group: WorkingGroups,
  411. id: number,
  412. roleAccountName: string,
  413. sourceAccount: string,
  414. appStake: Balance,
  415. roleStake: Balance,
  416. applicationText: string): Promise<number> {
  417. return 0;
  418. }
  419. leaveRole (group: WorkingGroups, sourceAccount: string, id: number, rationale: string) {
  420. /* do nothing */
  421. }
  422. withdrawApplication (group: WorkingGroups, sourceAccount: string, id: number) {
  423. /* do nothing */
  424. }
  425. }