2
1

user-notifications.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
  2. import 'mocha'
  3. import * as chai from 'chai'
  4. import { v4 as uuidv4 } from 'uuid'
  5. import {
  6. cleanupTests,
  7. updateMyUser,
  8. updateVideo,
  9. updateVideoChannel,
  10. uploadRandomVideoOnServers,
  11. wait
  12. } from '../../../../shared/extra-utils'
  13. import { ServerInfo } from '../../../../shared/extra-utils/index'
  14. import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
  15. import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
  16. import {
  17. CheckerBaseParams,
  18. checkMyVideoImportIsFinished,
  19. checkNewActorFollow,
  20. checkNewVideoFromSubscription,
  21. checkVideoIsPublished,
  22. getLastNotification,
  23. prepareNotificationsTest
  24. } from '../../../../shared/extra-utils/users/user-notifications'
  25. import { addUserSubscription, removeUserSubscription } from '../../../../shared/extra-utils/users/user-subscriptions'
  26. import { getBadVideoUrl, getGoodVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
  27. import { UserNotification, UserNotificationType } from '../../../../shared/models/users'
  28. import { VideoPrivacy } from '../../../../shared/models/videos'
  29. const expect = chai.expect
  30. describe('Test user notifications', function () {
  31. let servers: ServerInfo[] = []
  32. let userAccessToken: string
  33. let userNotifications: UserNotification[] = []
  34. let adminNotifications: UserNotification[] = []
  35. let adminNotificationsServer2: UserNotification[] = []
  36. let emails: object[] = []
  37. let channelId: number
  38. before(async function () {
  39. this.timeout(120000)
  40. const res = await prepareNotificationsTest(3)
  41. emails = res.emails
  42. userAccessToken = res.userAccessToken
  43. servers = res.servers
  44. userNotifications = res.userNotifications
  45. adminNotifications = res.adminNotifications
  46. adminNotificationsServer2 = res.adminNotificationsServer2
  47. channelId = res.channelId
  48. })
  49. describe('New video from my subscription notification', function () {
  50. let baseParams: CheckerBaseParams
  51. before(() => {
  52. baseParams = {
  53. server: servers[0],
  54. emails,
  55. socketNotifications: userNotifications,
  56. token: userAccessToken
  57. }
  58. })
  59. it('Should not send notifications if the user does not follow the video publisher', async function () {
  60. this.timeout(50000)
  61. await uploadRandomVideoOnServers(servers, 1)
  62. const notification = await getLastNotification(servers[0].url, userAccessToken)
  63. expect(notification).to.be.undefined
  64. expect(emails).to.have.lengthOf(0)
  65. expect(userNotifications).to.have.lengthOf(0)
  66. })
  67. it('Should send a new video notification if the user follows the local video publisher', async function () {
  68. this.timeout(15000)
  69. await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:' + servers[0].port)
  70. await waitJobs(servers)
  71. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1)
  72. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  73. })
  74. it('Should send a new video notification from a remote account', async function () {
  75. this.timeout(50000) // Server 2 has transcoding enabled
  76. await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:' + servers[1].port)
  77. await waitJobs(servers)
  78. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2)
  79. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  80. })
  81. it('Should send a new video notification on a scheduled publication', async function () {
  82. this.timeout(50000)
  83. // In 2 seconds
  84. const updateAt = new Date(new Date().getTime() + 2000)
  85. const data = {
  86. privacy: VideoPrivacy.PRIVATE,
  87. scheduleUpdate: {
  88. updateAt: updateAt.toISOString(),
  89. privacy: VideoPrivacy.PUBLIC
  90. }
  91. }
  92. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1, data)
  93. await wait(6000)
  94. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  95. })
  96. it('Should send a new video notification on a remote scheduled publication', async function () {
  97. this.timeout(100000)
  98. // In 2 seconds
  99. const updateAt = new Date(new Date().getTime() + 2000)
  100. const data = {
  101. privacy: VideoPrivacy.PRIVATE,
  102. scheduleUpdate: {
  103. updateAt: updateAt.toISOString(),
  104. privacy: VideoPrivacy.PUBLIC
  105. }
  106. }
  107. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, data)
  108. await waitJobs(servers)
  109. await wait(6000)
  110. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  111. })
  112. it('Should not send a notification before the video is published', async function () {
  113. this.timeout(50000)
  114. const updateAt = new Date(new Date().getTime() + 1000000)
  115. const data = {
  116. privacy: VideoPrivacy.PRIVATE,
  117. scheduleUpdate: {
  118. updateAt: updateAt.toISOString(),
  119. privacy: VideoPrivacy.PUBLIC
  120. }
  121. }
  122. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1, data)
  123. await wait(6000)
  124. await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
  125. })
  126. it('Should send a new video notification when a video becomes public', async function () {
  127. this.timeout(50000)
  128. const data = { privacy: VideoPrivacy.PRIVATE }
  129. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1, data)
  130. await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
  131. await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
  132. await wait(500)
  133. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  134. })
  135. it('Should send a new video notification when a remote video becomes public', async function () {
  136. this.timeout(50000)
  137. const data = { privacy: VideoPrivacy.PRIVATE }
  138. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, data)
  139. await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
  140. await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
  141. await waitJobs(servers)
  142. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  143. })
  144. it('Should not send a new video notification when a video becomes unlisted', async function () {
  145. this.timeout(50000)
  146. const data = { privacy: VideoPrivacy.PRIVATE }
  147. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1, data)
  148. await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
  149. await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
  150. })
  151. it('Should not send a new video notification when a remote video becomes unlisted', async function () {
  152. this.timeout(50000)
  153. const data = { privacy: VideoPrivacy.PRIVATE }
  154. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, data)
  155. await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
  156. await waitJobs(servers)
  157. await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
  158. })
  159. it('Should send a new video notification after a video import', async function () {
  160. this.timeout(100000)
  161. const name = 'video import ' + uuidv4()
  162. const attributes = {
  163. name,
  164. channelId,
  165. privacy: VideoPrivacy.PUBLIC,
  166. targetUrl: getGoodVideoUrl()
  167. }
  168. const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
  169. const uuid = res.body.video.uuid
  170. await waitJobs(servers)
  171. await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
  172. })
  173. })
  174. describe('My video is published', function () {
  175. let baseParams: CheckerBaseParams
  176. before(() => {
  177. baseParams = {
  178. server: servers[1],
  179. emails,
  180. socketNotifications: adminNotificationsServer2,
  181. token: servers[1].accessToken
  182. }
  183. })
  184. it('Should not send a notification if transcoding is not enabled', async function () {
  185. this.timeout(50000)
  186. const { name, uuid } = await uploadRandomVideoOnServers(servers, 1)
  187. await waitJobs(servers)
  188. await checkVideoIsPublished(baseParams, name, uuid, 'absence')
  189. })
  190. it('Should not send a notification if the wait transcoding is false', async function () {
  191. this.timeout(50000)
  192. await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: false })
  193. await waitJobs(servers)
  194. const notification = await getLastNotification(servers[0].url, userAccessToken)
  195. if (notification) {
  196. expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
  197. }
  198. })
  199. it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
  200. this.timeout(50000)
  201. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
  202. await waitJobs(servers)
  203. await checkVideoIsPublished(baseParams, name, uuid, 'presence')
  204. })
  205. it('Should send a notification with a transcoded video', async function () {
  206. this.timeout(50000)
  207. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true })
  208. await waitJobs(servers)
  209. await checkVideoIsPublished(baseParams, name, uuid, 'presence')
  210. })
  211. it('Should send a notification when an imported video is transcoded', async function () {
  212. this.timeout(50000)
  213. const name = 'video import ' + uuidv4()
  214. const attributes = {
  215. name,
  216. channelId,
  217. privacy: VideoPrivacy.PUBLIC,
  218. targetUrl: getGoodVideoUrl(),
  219. waitTranscoding: true
  220. }
  221. const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
  222. const uuid = res.body.video.uuid
  223. await waitJobs(servers)
  224. await checkVideoIsPublished(baseParams, name, uuid, 'presence')
  225. })
  226. it('Should send a notification when the scheduled update has been proceeded', async function () {
  227. this.timeout(70000)
  228. // In 2 seconds
  229. const updateAt = new Date(new Date().getTime() + 2000)
  230. const data = {
  231. privacy: VideoPrivacy.PRIVATE,
  232. scheduleUpdate: {
  233. updateAt: updateAt.toISOString(),
  234. privacy: VideoPrivacy.PUBLIC
  235. }
  236. }
  237. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, data)
  238. await wait(6000)
  239. await checkVideoIsPublished(baseParams, name, uuid, 'presence')
  240. })
  241. it('Should not send a notification before the video is published', async function () {
  242. this.timeout(40000)
  243. const updateAt = new Date(new Date().getTime() + 1000000)
  244. const data = {
  245. privacy: VideoPrivacy.PRIVATE,
  246. scheduleUpdate: {
  247. updateAt: updateAt.toISOString(),
  248. privacy: VideoPrivacy.PUBLIC
  249. }
  250. }
  251. const { name, uuid } = await uploadRandomVideoOnServers(servers, 2, data)
  252. await wait(6000)
  253. await checkVideoIsPublished(baseParams, name, uuid, 'absence')
  254. })
  255. })
  256. describe('My video is imported', function () {
  257. let baseParams: CheckerBaseParams
  258. before(() => {
  259. baseParams = {
  260. server: servers[0],
  261. emails,
  262. socketNotifications: adminNotifications,
  263. token: servers[0].accessToken
  264. }
  265. })
  266. it('Should send a notification when the video import failed', async function () {
  267. this.timeout(70000)
  268. const name = 'video import ' + uuidv4()
  269. const attributes = {
  270. name,
  271. channelId,
  272. privacy: VideoPrivacy.PRIVATE,
  273. targetUrl: getBadVideoUrl()
  274. }
  275. const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
  276. const uuid = res.body.video.uuid
  277. await waitJobs(servers)
  278. await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence')
  279. })
  280. it('Should send a notification when the video import succeeded', async function () {
  281. this.timeout(70000)
  282. const name = 'video import ' + uuidv4()
  283. const attributes = {
  284. name,
  285. channelId,
  286. privacy: VideoPrivacy.PRIVATE,
  287. targetUrl: getGoodVideoUrl()
  288. }
  289. const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
  290. const uuid = res.body.video.uuid
  291. await waitJobs(servers)
  292. await checkMyVideoImportIsFinished(baseParams, name, uuid, getGoodVideoUrl(), true, 'presence')
  293. })
  294. })
  295. describe('New actor follow', function () {
  296. let baseParams: CheckerBaseParams
  297. const myChannelName = 'super channel name'
  298. const myUserName = 'super user name'
  299. before(async () => {
  300. baseParams = {
  301. server: servers[0],
  302. emails,
  303. socketNotifications: userNotifications,
  304. token: userAccessToken
  305. }
  306. await updateMyUser({
  307. url: servers[0].url,
  308. accessToken: servers[0].accessToken,
  309. displayName: 'super root name'
  310. })
  311. await updateMyUser({
  312. url: servers[0].url,
  313. accessToken: userAccessToken,
  314. displayName: myUserName
  315. })
  316. await updateMyUser({
  317. url: servers[1].url,
  318. accessToken: servers[1].accessToken,
  319. displayName: 'super root 2 name'
  320. })
  321. await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName })
  322. })
  323. it('Should notify when a local channel is following one of our channel', async function () {
  324. this.timeout(50000)
  325. await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
  326. await waitJobs(servers)
  327. await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence')
  328. await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
  329. })
  330. it('Should notify when a remote channel is following one of our channel', async function () {
  331. this.timeout(50000)
  332. await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
  333. await waitJobs(servers)
  334. await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence')
  335. await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
  336. })
  337. // PeerTube does not support accout -> account follows
  338. // it('Should notify when a local account is following one of our channel', async function () {
  339. // this.timeout(50000)
  340. //
  341. // await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:' + servers[0].port)
  342. //
  343. // await waitJobs(servers)
  344. //
  345. // await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
  346. // })
  347. // it('Should notify when a remote account is following one of our channel', async function () {
  348. // this.timeout(50000)
  349. //
  350. // await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:' + servers[0].port)
  351. //
  352. // await waitJobs(servers)
  353. //
  354. // await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
  355. // })
  356. })
  357. after(async function () {
  358. MockSmtpServer.Instance.kill()
  359. await cleanupTests(servers)
  360. })
  361. })