index.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { FlowProps } from '../../Flow'
  2. import Debugger from 'debug'
  3. import { FixtureRunner } from '../../Fixture'
  4. import { BuyMembershipHappyCaseFixture } from '../../fixtures/membership'
  5. import { CreateProposalsFixture, ExpireProposalsFixture } from '../../fixtures/proposals'
  6. import {
  7. ChangeThreadsModeFixture,
  8. CreatePostsFixture,
  9. DeletePostParams,
  10. DeletePostsFixture,
  11. PostParams,
  12. PostUpdateParams,
  13. ThreadModeChangeParams,
  14. UpdatePostsFixture,
  15. } from '../../fixtures/proposalsDiscussion'
  16. import { Resource } from '../../Resources'
  17. import { ThreadId } from '../../../../../types/common'
  18. import { ALL_BYTES } from '../../consts'
  19. export default async function proposalsDiscussion({ api, query, lock }: FlowProps): Promise<void> {
  20. const debug = Debugger('flow:proposals-discussion')
  21. debug('Started')
  22. api.enableDebugTxLogs()
  23. const threadsN = 3
  24. const accounts = (await api.createKeyPairs(threadsN)).map((kp) => kp.address)
  25. const buyMembershipsFixture = new BuyMembershipHappyCaseFixture(api, query, accounts)
  26. await new FixtureRunner(buyMembershipsFixture).run()
  27. const memberIds = buyMembershipsFixture.getCreatedMembers()
  28. const unlocks = await Promise.all(Array.from({ length: threadsN }, () => lock(Resource.Proposals)))
  29. const createProposalFixture = new CreateProposalsFixture(
  30. api,
  31. query,
  32. Array.from({ length: threadsN }, (v, i) => ({
  33. type: 'Signal',
  34. details: `Discussion test ${i}`,
  35. asMember: memberIds[i],
  36. title: `Discussion test proposal ${i}`,
  37. description: `Proposals discussion test proposal ${i}`,
  38. }))
  39. )
  40. await new FixtureRunner(createProposalFixture).run()
  41. const proposalsIds = createProposalFixture.getCreatedProposalsIds()
  42. const threadIds = await api.query.proposalsCodex.threadIdByProposalId.multi<ThreadId>(proposalsIds)
  43. const createPostsParams: PostParams[] = threadIds.reduce(
  44. (posts, threadId) =>
  45. posts.concat([
  46. // Standard case:
  47. {
  48. threadId,
  49. asMember: memberIds[0],
  50. metadata: { value: { text: 'Test' } },
  51. editable: true,
  52. },
  53. // Invalid repliesTo case:
  54. {
  55. threadId,
  56. asMember: memberIds[1],
  57. metadata: { value: { text: 'Test', repliesTo: 9999 }, expectReplyFailure: true },
  58. editable: true,
  59. },
  60. // ALL_BYTES metadata + non-editable case:
  61. {
  62. threadId,
  63. asMember: memberIds[2],
  64. metadata: { value: ALL_BYTES, expectFailure: true }, // expectFailure just means serialization failure, but the value will still be checked
  65. editable: false,
  66. },
  67. ]),
  68. [] as PostParams[]
  69. )
  70. const createPostsFixture = new CreatePostsFixture(api, query, createPostsParams)
  71. await new FixtureRunner(createPostsFixture).runWithQueryNodeChecks()
  72. const postIds = createPostsFixture.getCreatedPostsIds()
  73. const threadModeChangesParams: ThreadModeChangeParams[] = [
  74. { threadId: threadIds[0], asMember: memberIds[0], newMode: { Closed: memberIds } },
  75. { threadId: threadIds[1], asMember: memberIds[1], newMode: { Closed: [memberIds[0]] } },
  76. { threadId: threadIds[1], asMember: memberIds[1], newMode: 'Open' },
  77. ]
  78. const threadModeChanges = new ChangeThreadsModeFixture(api, query, threadModeChangesParams)
  79. const threadModeChangesRunner = new FixtureRunner(threadModeChanges)
  80. await threadModeChangesRunner.run()
  81. const createPostRepliesParams: PostParams[] = createPostsParams.map((params, i) => ({
  82. threadId: params.threadId,
  83. asMember: memberIds[i % memberIds.length],
  84. metadata: { value: { text: `Reply to post ${postIds[i].toString()}`, repliesTo: postIds[i].toNumber() } },
  85. }))
  86. const createRepliesFixture = new CreatePostsFixture(api, query, createPostRepliesParams)
  87. const createRepliesRunner = new FixtureRunner(createRepliesFixture)
  88. await createRepliesRunner.run()
  89. const updatePostsParams: PostUpdateParams[] = [
  90. { threadId: threadIds[0], postId: postIds[0], asMember: memberIds[0], newText: 'New text' },
  91. { threadId: threadIds[0], postId: postIds[1], asMember: memberIds[1], newText: ALL_BYTES },
  92. ]
  93. const updatePostsFixture = new UpdatePostsFixture(api, query, updatePostsParams)
  94. const updatePostsRunner = new FixtureRunner(updatePostsFixture)
  95. await updatePostsRunner.run()
  96. // TODO: Test anyone_can_delete_post (would require waiting PostLifetime)
  97. const deletePostsParams: DeletePostParams[] = postIds
  98. .map((postId, i) => ({ postId, ...createPostsParams[i] }))
  99. .filter((p) => p.editable !== false)
  100. const deletePostsFixture = new DeletePostsFixture(api, query, deletePostsParams)
  101. const deletePostsRunner = new FixtureRunner(deletePostsFixture)
  102. await deletePostsRunner.run()
  103. // Run compound query-node checks
  104. await Promise.all([
  105. createRepliesRunner.runQueryNodeChecks(),
  106. threadModeChangesRunner.runQueryNodeChecks(),
  107. updatePostsRunner.runQueryNodeChecks(),
  108. deletePostsRunner.runQueryNodeChecks(),
  109. ])
  110. // Wait until proposal expires and release locks
  111. await new FixtureRunner(new ExpireProposalsFixture(api, query, proposalsIds)).run()
  112. unlocks.forEach((unlock) => unlock())
  113. debug('Done')
  114. }