comments-notifications.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
  2. import { expect } from 'chai'
  3. import {
  4. checkCommentMention,
  5. CheckerBaseParams,
  6. checkNewCommentOnMyVideo,
  7. MockSmtpServer,
  8. prepareNotificationsTest
  9. } from '@server/tests/shared'
  10. import { UserNotification } from '@shared/models'
  11. import { cleanupTests, PeerTubeServer, waitJobs } from '@shared/server-commands'
  12. describe('Test comments notifications', function () {
  13. let servers: PeerTubeServer[] = []
  14. let userToken: string
  15. let userNotifications: UserNotification[] = []
  16. let emails: object[] = []
  17. const commentText = '**hello** <a href="https://joinpeertube.org">world</a>, <h1>what do you think about peertube?</h1>'
  18. const expectedHtml = '<strong style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">hello</strong> ' +
  19. '<a href="https://joinpeertube.org" target="_blank" rel="noopener noreferrer" style="-ms-text-size-adjust: 100%; ' +
  20. '-webkit-text-size-adjust: 100%; text-decoration: none; color: #f2690d;">world</a>, </p>what do you think about peertube?'
  21. before(async function () {
  22. this.timeout(120000)
  23. const res = await prepareNotificationsTest(2)
  24. emails = res.emails
  25. userToken = res.userAccessToken
  26. servers = res.servers
  27. userNotifications = res.userNotifications
  28. })
  29. describe('Comment on my video notifications', function () {
  30. let baseParams: CheckerBaseParams
  31. before(() => {
  32. baseParams = {
  33. server: servers[0],
  34. emails,
  35. socketNotifications: userNotifications,
  36. token: userToken
  37. }
  38. })
  39. it('Should not send a new comment notification after a comment on another video', async function () {
  40. this.timeout(30000)
  41. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  42. const created = await servers[0].comments.createThread({ videoId: uuid, text: 'comment' })
  43. const commentId = created.id
  44. await waitJobs(servers)
  45. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId: commentId, commentId, checkType: 'absence' })
  46. })
  47. it('Should not send a new comment notification if I comment my own video', async function () {
  48. this.timeout(30000)
  49. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  50. const created = await servers[0].comments.createThread({ token: userToken, videoId: uuid, text: 'comment' })
  51. const commentId = created.id
  52. await waitJobs(servers)
  53. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId: commentId, commentId, checkType: 'absence' })
  54. })
  55. it('Should not send a new comment notification if the account is muted', async function () {
  56. this.timeout(30000)
  57. await servers[0].blocklist.addToMyBlocklist({ token: userToken, account: 'root' })
  58. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  59. const created = await servers[0].comments.createThread({ videoId: uuid, text: 'comment' })
  60. const commentId = created.id
  61. await waitJobs(servers)
  62. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId: commentId, commentId, checkType: 'absence' })
  63. await servers[0].blocklist.removeFromMyBlocklist({ token: userToken, account: 'root' })
  64. })
  65. it('Should send a new comment notification after a local comment on my video', async function () {
  66. this.timeout(30000)
  67. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  68. const created = await servers[0].comments.createThread({ videoId: uuid, text: 'comment' })
  69. const commentId = created.id
  70. await waitJobs(servers)
  71. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId: commentId, commentId, checkType: 'presence' })
  72. })
  73. it('Should send a new comment notification after a remote comment on my video', async function () {
  74. this.timeout(30000)
  75. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  76. await waitJobs(servers)
  77. await servers[1].comments.createThread({ videoId: uuid, text: 'comment' })
  78. await waitJobs(servers)
  79. const { data } = await servers[0].comments.listThreads({ videoId: uuid })
  80. expect(data).to.have.lengthOf(1)
  81. const commentId = data[0].id
  82. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId: commentId, commentId, checkType: 'presence' })
  83. })
  84. it('Should send a new comment notification after a local reply on my video', async function () {
  85. this.timeout(30000)
  86. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  87. const { id: threadId } = await servers[0].comments.createThread({ videoId: uuid, text: 'comment' })
  88. const { id: commentId } = await servers[0].comments.addReply({ videoId: uuid, toCommentId: threadId, text: 'reply' })
  89. await waitJobs(servers)
  90. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId, commentId, checkType: 'presence' })
  91. })
  92. it('Should send a new comment notification after a remote reply on my video', async function () {
  93. this.timeout(30000)
  94. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  95. await waitJobs(servers)
  96. {
  97. const created = await servers[1].comments.createThread({ videoId: uuid, text: 'comment' })
  98. const threadId = created.id
  99. await servers[1].comments.addReply({ videoId: uuid, toCommentId: threadId, text: 'reply' })
  100. }
  101. await waitJobs(servers)
  102. const { data } = await servers[0].comments.listThreads({ videoId: uuid })
  103. expect(data).to.have.lengthOf(1)
  104. const threadId = data[0].id
  105. const tree = await servers[0].comments.getThread({ videoId: uuid, threadId })
  106. expect(tree.children).to.have.lengthOf(1)
  107. const commentId = tree.children[0].comment.id
  108. await checkNewCommentOnMyVideo({ ...baseParams, shortUUID, threadId, commentId, checkType: 'presence' })
  109. })
  110. it('Should convert markdown in comment to html', async function () {
  111. this.timeout(30000)
  112. const { uuid } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'cool video' } })
  113. await servers[0].comments.createThread({ videoId: uuid, text: commentText })
  114. await waitJobs(servers)
  115. const latestEmail = emails[emails.length - 1]
  116. expect(latestEmail['html']).to.contain(expectedHtml)
  117. })
  118. })
  119. describe('Mention notifications', function () {
  120. let baseParams: CheckerBaseParams
  121. const byAccountDisplayName = 'super root name'
  122. before(async () => {
  123. baseParams = {
  124. server: servers[0],
  125. emails,
  126. socketNotifications: userNotifications,
  127. token: userToken
  128. }
  129. await servers[0].users.updateMe({ displayName: 'super root name' })
  130. await servers[1].users.updateMe({ displayName: 'super root 2 name' })
  131. })
  132. it('Should not send a new mention comment notification if I mention the video owner', async function () {
  133. this.timeout(30000)
  134. const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken, attributes: { name: 'super video' } })
  135. const { id: commentId } = await servers[0].comments.createThread({ videoId: uuid, text: '@user_1 hello' })
  136. await waitJobs(servers)
  137. await checkCommentMention({ ...baseParams, shortUUID, threadId: commentId, commentId, byAccountDisplayName, checkType: 'absence' })
  138. })
  139. it('Should not send a new mention comment notification if I mention myself', async function () {
  140. this.timeout(30000)
  141. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  142. const { id: commentId } = await servers[0].comments.createThread({ token: userToken, videoId: uuid, text: '@user_1 hello' })
  143. await waitJobs(servers)
  144. await checkCommentMention({ ...baseParams, shortUUID, threadId: commentId, commentId, byAccountDisplayName, checkType: 'absence' })
  145. })
  146. it('Should not send a new mention notification if the account is muted', async function () {
  147. this.timeout(30000)
  148. await servers[0].blocklist.addToMyBlocklist({ token: userToken, account: 'root' })
  149. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  150. const { id: commentId } = await servers[0].comments.createThread({ videoId: uuid, text: '@user_1 hello' })
  151. await waitJobs(servers)
  152. await checkCommentMention({ ...baseParams, shortUUID, threadId: commentId, commentId, byAccountDisplayName, checkType: 'absence' })
  153. await servers[0].blocklist.removeFromMyBlocklist({ token: userToken, account: 'root' })
  154. })
  155. it('Should not send a new mention notification if the remote account mention a local account', async function () {
  156. this.timeout(30000)
  157. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  158. await waitJobs(servers)
  159. const { id: threadId } = await servers[1].comments.createThread({ videoId: uuid, text: '@user_1 hello' })
  160. await waitJobs(servers)
  161. const byAccountDisplayName = 'super root 2 name'
  162. await checkCommentMention({ ...baseParams, shortUUID, threadId, commentId: threadId, byAccountDisplayName, checkType: 'absence' })
  163. })
  164. it('Should send a new mention notification after local comments', async function () {
  165. this.timeout(30000)
  166. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  167. const { id: threadId } = await servers[0].comments.createThread({ videoId: uuid, text: '@user_1 hellotext: 1' })
  168. await waitJobs(servers)
  169. await checkCommentMention({ ...baseParams, shortUUID, threadId, commentId: threadId, byAccountDisplayName, checkType: 'presence' })
  170. const { id: commentId } = await servers[0].comments.addReply({ videoId: uuid, toCommentId: threadId, text: 'hello 2 @user_1' })
  171. await waitJobs(servers)
  172. await checkCommentMention({ ...baseParams, shortUUID, commentId, threadId, byAccountDisplayName, checkType: 'presence' })
  173. })
  174. it('Should send a new mention notification after remote comments', async function () {
  175. this.timeout(30000)
  176. const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  177. await waitJobs(servers)
  178. const text1 = `hello @user_1@${servers[0].host} 1`
  179. const { id: server2ThreadId } = await servers[1].comments.createThread({ videoId: uuid, text: text1 })
  180. await waitJobs(servers)
  181. const { data } = await servers[0].comments.listThreads({ videoId: uuid })
  182. expect(data).to.have.lengthOf(1)
  183. const byAccountDisplayName = 'super root 2 name'
  184. const threadId = data[0].id
  185. await checkCommentMention({ ...baseParams, shortUUID, commentId: threadId, threadId, byAccountDisplayName, checkType: 'presence' })
  186. const text2 = `@user_1@${servers[0].host} hello 2 @root@${servers[0].host}`
  187. await servers[1].comments.addReply({ videoId: uuid, toCommentId: server2ThreadId, text: text2 })
  188. await waitJobs(servers)
  189. const tree = await servers[0].comments.getThread({ videoId: uuid, threadId })
  190. expect(tree.children).to.have.lengthOf(1)
  191. const commentId = tree.children[0].comment.id
  192. await checkCommentMention({ ...baseParams, shortUUID, commentId, threadId, byAccountDisplayName, checkType: 'presence' })
  193. })
  194. it('Should convert markdown in comment to html', async function () {
  195. this.timeout(30000)
  196. const { uuid } = await servers[0].videos.upload({ attributes: { name: 'super video' } })
  197. const { id: threadId } = await servers[0].comments.createThread({ videoId: uuid, text: '@user_1 hello 1' })
  198. await servers[0].comments.addReply({ videoId: uuid, toCommentId: threadId, text: '@user_1 ' + commentText })
  199. await waitJobs(servers)
  200. const latestEmail = emails[emails.length - 1]
  201. expect(latestEmail['html']).to.contain(expectedHtml)
  202. })
  203. })
  204. after(async function () {
  205. MockSmtpServer.Instance.kill()
  206. await cleanupTests(servers)
  207. })
  208. })