multiple-servers.ts 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. /* tslint:disable:no-unused-expression */
  2. import * as chai from 'chai'
  3. import 'mocha'
  4. import { join } from 'path'
  5. import * as request from 'supertest'
  6. import { VideoPrivacy } from '../../../../shared/models/videos'
  7. import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
  8. import {
  9. addVideoChannel,
  10. checkTmpIsEmpty,
  11. checkVideoFilesWereRemoved,
  12. completeVideoCheck,
  13. createUser,
  14. dateIsValid,
  15. doubleFollow,
  16. flushAndRunMultipleServers,
  17. flushTests,
  18. getLocalVideos,
  19. getVideo,
  20. getVideoChannelsList,
  21. getVideosList,
  22. killallServers,
  23. rateVideo,
  24. removeVideo,
  25. ServerInfo,
  26. setAccessTokensToServers,
  27. testImage,
  28. updateVideo,
  29. uploadVideo,
  30. userLogin,
  31. viewVideo,
  32. wait,
  33. webtorrentAdd
  34. } from '../../../../shared/extra-utils'
  35. import {
  36. addVideoCommentReply,
  37. addVideoCommentThread,
  38. deleteVideoComment,
  39. getVideoCommentThreads,
  40. getVideoThreadComments
  41. } from '../../../../shared/extra-utils/videos/video-comments'
  42. import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
  43. const expect = chai.expect
  44. describe('Test multiple servers', function () {
  45. let servers: ServerInfo[] = []
  46. const toRemove = []
  47. let videoUUID = ''
  48. let videoChannelId: number
  49. before(async function () {
  50. this.timeout(120000)
  51. servers = await flushAndRunMultipleServers(3)
  52. // Get the access tokens
  53. await setAccessTokensToServers(servers)
  54. {
  55. const videoChannel = {
  56. name: 'super_channel_name',
  57. displayName: 'my channel',
  58. description: 'super channel'
  59. }
  60. await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel)
  61. const channelRes = await getVideoChannelsList(servers[ 0 ].url, 0, 1)
  62. videoChannelId = channelRes.body.data[ 0 ].id
  63. }
  64. // Server 1 and server 2 follow each other
  65. await doubleFollow(servers[0], servers[1])
  66. // Server 1 and server 3 follow each other
  67. await doubleFollow(servers[0], servers[2])
  68. // Server 2 and server 3 follow each other
  69. await doubleFollow(servers[1], servers[2])
  70. })
  71. it('Should not have videos for all servers', async function () {
  72. for (const server of servers) {
  73. const res = await getVideosList(server.url)
  74. const videos = res.body.data
  75. expect(videos).to.be.an('array')
  76. expect(videos.length).to.equal(0)
  77. }
  78. })
  79. describe('Should upload the video and propagate on each server', function () {
  80. it('Should upload the video on server 1 and propagate on each server', async function () {
  81. this.timeout(25000)
  82. const videoAttributes = {
  83. name: 'my super name for server 1',
  84. category: 5,
  85. licence: 4,
  86. language: 'ja',
  87. nsfw: true,
  88. description: 'my super description for server 1',
  89. support: 'my super support text for server 1',
  90. originallyPublishedAt: '2019-02-10T13:38:14.449Z',
  91. tags: [ 'tag1p1', 'tag2p1' ],
  92. channelId: videoChannelId,
  93. fixture: 'video_short1.webm'
  94. }
  95. await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
  96. await waitJobs(servers)
  97. // All servers should have this video
  98. let publishedAt: string = null
  99. for (const server of servers) {
  100. const isLocal = server.url === 'http://localhost:9001'
  101. const checkAttributes = {
  102. name: 'my super name for server 1',
  103. category: 5,
  104. licence: 4,
  105. language: 'ja',
  106. nsfw: true,
  107. description: 'my super description for server 1',
  108. support: 'my super support text for server 1',
  109. originallyPublishedAt: '2019-02-10T13:38:14.449Z',
  110. account: {
  111. name: 'root',
  112. host: 'localhost:9001'
  113. },
  114. isLocal,
  115. publishedAt,
  116. duration: 10,
  117. tags: [ 'tag1p1', 'tag2p1' ],
  118. privacy: VideoPrivacy.PUBLIC,
  119. commentsEnabled: true,
  120. downloadEnabled: true,
  121. channel: {
  122. displayName: 'my channel',
  123. name: 'super_channel_name',
  124. description: 'super channel',
  125. isLocal
  126. },
  127. fixture: 'video_short1.webm',
  128. files: [
  129. {
  130. resolution: 720,
  131. size: 572456
  132. }
  133. ]
  134. }
  135. const res = await getVideosList(server.url)
  136. const videos = res.body.data
  137. expect(videos).to.be.an('array')
  138. expect(videos.length).to.equal(1)
  139. const video = videos[0]
  140. await completeVideoCheck(server.url, video, checkAttributes)
  141. publishedAt = video.publishedAt
  142. }
  143. })
  144. it('Should upload the video on server 2 and propagate on each server', async function () {
  145. this.timeout(50000)
  146. const user = {
  147. username: 'user1',
  148. password: 'super_password'
  149. }
  150. await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password })
  151. const userAccessToken = await userLogin(servers[1], user)
  152. const videoAttributes = {
  153. name: 'my super name for server 2',
  154. category: 4,
  155. licence: 3,
  156. language: 'de',
  157. nsfw: true,
  158. description: 'my super description for server 2',
  159. support: 'my super support text for server 2',
  160. tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
  161. fixture: 'video_short2.webm',
  162. thumbnailfile: 'thumbnail.jpg',
  163. previewfile: 'preview.jpg'
  164. }
  165. await uploadVideo(servers[1].url, userAccessToken, videoAttributes)
  166. // Transcoding
  167. await waitJobs(servers)
  168. // All servers should have this video
  169. for (const server of servers) {
  170. const isLocal = server.url === 'http://localhost:9002'
  171. const checkAttributes = {
  172. name: 'my super name for server 2',
  173. category: 4,
  174. licence: 3,
  175. language: 'de',
  176. nsfw: true,
  177. description: 'my super description for server 2',
  178. support: 'my super support text for server 2',
  179. account: {
  180. name: 'user1',
  181. host: 'localhost:9002'
  182. },
  183. isLocal,
  184. commentsEnabled: true,
  185. downloadEnabled: true,
  186. duration: 5,
  187. tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
  188. privacy: VideoPrivacy.PUBLIC,
  189. channel: {
  190. displayName: 'Main user1 channel',
  191. name: 'user1_channel',
  192. description: 'super channel',
  193. isLocal
  194. },
  195. fixture: 'video_short2.webm',
  196. files: [
  197. {
  198. resolution: 240,
  199. size: 187000
  200. },
  201. {
  202. resolution: 360,
  203. size: 278000
  204. },
  205. {
  206. resolution: 480,
  207. size: 383000
  208. },
  209. {
  210. resolution: 720,
  211. size: 706000
  212. }
  213. ],
  214. thumbnailfile: 'thumbnail',
  215. previewfile: 'preview'
  216. }
  217. const res = await getVideosList(server.url)
  218. const videos = res.body.data
  219. expect(videos).to.be.an('array')
  220. expect(videos.length).to.equal(2)
  221. const video = videos[1]
  222. await completeVideoCheck(server.url, video, checkAttributes)
  223. }
  224. })
  225. it('Should upload two videos on server 3 and propagate on each server', async function () {
  226. this.timeout(45000)
  227. const videoAttributes1 = {
  228. name: 'my super name for server 3',
  229. category: 6,
  230. licence: 5,
  231. language: 'de',
  232. nsfw: true,
  233. description: 'my super description for server 3',
  234. support: 'my super support text for server 3',
  235. tags: [ 'tag1p3' ],
  236. fixture: 'video_short3.webm'
  237. }
  238. await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1)
  239. const videoAttributes2 = {
  240. name: 'my super name for server 3-2',
  241. category: 7,
  242. licence: 6,
  243. language: 'ko',
  244. nsfw: false,
  245. description: 'my super description for server 3-2',
  246. support: 'my super support text for server 3-2',
  247. tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
  248. fixture: 'video_short.webm'
  249. }
  250. await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2)
  251. await waitJobs(servers)
  252. // All servers should have this video
  253. for (const server of servers) {
  254. const isLocal = server.url === 'http://localhost:9003'
  255. const res = await getVideosList(server.url)
  256. const videos = res.body.data
  257. expect(videos).to.be.an('array')
  258. expect(videos.length).to.equal(4)
  259. // We not sure about the order of the two last uploads
  260. let video1 = null
  261. let video2 = null
  262. if (videos[2].name === 'my super name for server 3') {
  263. video1 = videos[2]
  264. video2 = videos[3]
  265. } else {
  266. video1 = videos[3]
  267. video2 = videos[2]
  268. }
  269. const checkAttributesVideo1 = {
  270. name: 'my super name for server 3',
  271. category: 6,
  272. licence: 5,
  273. language: 'de',
  274. nsfw: true,
  275. description: 'my super description for server 3',
  276. support: 'my super support text for server 3',
  277. account: {
  278. name: 'root',
  279. host: 'localhost:9003'
  280. },
  281. isLocal,
  282. duration: 5,
  283. commentsEnabled: true,
  284. downloadEnabled: true,
  285. tags: [ 'tag1p3' ],
  286. privacy: VideoPrivacy.PUBLIC,
  287. channel: {
  288. displayName: 'Main root channel',
  289. name: 'root_channel',
  290. description: '',
  291. isLocal
  292. },
  293. fixture: 'video_short3.webm',
  294. files: [
  295. {
  296. resolution: 720,
  297. size: 292677
  298. }
  299. ]
  300. }
  301. await completeVideoCheck(server.url, video1, checkAttributesVideo1)
  302. const checkAttributesVideo2 = {
  303. name: 'my super name for server 3-2',
  304. category: 7,
  305. licence: 6,
  306. language: 'ko',
  307. nsfw: false,
  308. description: 'my super description for server 3-2',
  309. support: 'my super support text for server 3-2',
  310. account: {
  311. name: 'root',
  312. host: 'localhost:9003'
  313. },
  314. commentsEnabled: true,
  315. downloadEnabled: true,
  316. isLocal,
  317. duration: 5,
  318. tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
  319. privacy: VideoPrivacy.PUBLIC,
  320. channel: {
  321. displayName: 'Main root channel',
  322. name: 'root_channel',
  323. description: '',
  324. isLocal
  325. },
  326. fixture: 'video_short.webm',
  327. files: [
  328. {
  329. resolution: 720,
  330. size: 218910
  331. }
  332. ]
  333. }
  334. await completeVideoCheck(server.url, video2, checkAttributesVideo2)
  335. }
  336. })
  337. })
  338. describe('It should list local videos', function () {
  339. it('Should list only local videos on server 1', async function () {
  340. const { body } = await getLocalVideos(servers[0].url)
  341. expect(body.total).to.equal(1)
  342. expect(body.data).to.be.an('array')
  343. expect(body.data.length).to.equal(1)
  344. expect(body.data[0].name).to.equal('my super name for server 1')
  345. })
  346. it('Should list only local videos on server 2', async function () {
  347. const { body } = await getLocalVideos(servers[1].url)
  348. expect(body.total).to.equal(1)
  349. expect(body.data).to.be.an('array')
  350. expect(body.data.length).to.equal(1)
  351. expect(body.data[0].name).to.equal('my super name for server 2')
  352. })
  353. it('Should list only local videos on server 3', async function () {
  354. const { body } = await getLocalVideos(servers[2].url)
  355. expect(body.total).to.equal(2)
  356. expect(body.data).to.be.an('array')
  357. expect(body.data.length).to.equal(2)
  358. expect(body.data[0].name).to.equal('my super name for server 3')
  359. expect(body.data[1].name).to.equal('my super name for server 3-2')
  360. })
  361. })
  362. describe('Should seed the uploaded video', function () {
  363. it('Should add the file 1 by asking server 3', async function () {
  364. this.timeout(10000)
  365. const res = await getVideosList(servers[2].url)
  366. const video = res.body.data[0]
  367. toRemove.push(res.body.data[2])
  368. toRemove.push(res.body.data[3])
  369. const res2 = await getVideo(servers[2].url, video.id)
  370. const videoDetails = res2.body
  371. const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
  372. expect(torrent.files).to.be.an('array')
  373. expect(torrent.files.length).to.equal(1)
  374. expect(torrent.files[0].path).to.exist.and.to.not.equal('')
  375. })
  376. it('Should add the file 2 by asking server 1', async function () {
  377. this.timeout(10000)
  378. const res = await getVideosList(servers[0].url)
  379. const video = res.body.data[1]
  380. const res2 = await getVideo(servers[0].url, video.id)
  381. const videoDetails = res2.body
  382. const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
  383. expect(torrent.files).to.be.an('array')
  384. expect(torrent.files.length).to.equal(1)
  385. expect(torrent.files[0].path).to.exist.and.to.not.equal('')
  386. })
  387. it('Should add the file 3 by asking server 2', async function () {
  388. this.timeout(10000)
  389. const res = await getVideosList(servers[1].url)
  390. const video = res.body.data[2]
  391. const res2 = await getVideo(servers[1].url, video.id)
  392. const videoDetails = res2.body
  393. const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
  394. expect(torrent.files).to.be.an('array')
  395. expect(torrent.files.length).to.equal(1)
  396. expect(torrent.files[0].path).to.exist.and.to.not.equal('')
  397. })
  398. it('Should add the file 3-2 by asking server 1', async function () {
  399. this.timeout(10000)
  400. const res = await getVideosList(servers[0].url)
  401. const video = res.body.data[3]
  402. const res2 = await getVideo(servers[0].url, video.id)
  403. const videoDetails = res2.body
  404. const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
  405. expect(torrent.files).to.be.an('array')
  406. expect(torrent.files.length).to.equal(1)
  407. expect(torrent.files[0].path).to.exist.and.to.not.equal('')
  408. })
  409. it('Should add the file 2 in 360p by asking server 1', async function () {
  410. this.timeout(10000)
  411. const res = await getVideosList(servers[0].url)
  412. const video = res.body.data.find(v => v.name === 'my super name for server 2')
  413. const res2 = await getVideo(servers[0].url, video.id)
  414. const videoDetails = res2.body
  415. const file = videoDetails.files.find(f => f.resolution.id === 360)
  416. expect(file).not.to.be.undefined
  417. const torrent = await webtorrentAdd(file.magnetUri)
  418. expect(torrent.files).to.be.an('array')
  419. expect(torrent.files.length).to.equal(1)
  420. expect(torrent.files[0].path).to.exist.and.to.not.equal('')
  421. })
  422. })
  423. describe('Should update video views, likes and dislikes', function () {
  424. let localVideosServer3 = []
  425. let remoteVideosServer1 = []
  426. let remoteVideosServer2 = []
  427. let remoteVideosServer3 = []
  428. before(async function () {
  429. const res1 = await getVideosList(servers[0].url)
  430. remoteVideosServer1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
  431. const res2 = await getVideosList(servers[1].url)
  432. remoteVideosServer2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
  433. const res3 = await getVideosList(servers[2].url)
  434. localVideosServer3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.uuid)
  435. remoteVideosServer3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
  436. })
  437. it('Should view multiple videos on owned servers', async function () {
  438. this.timeout(30000)
  439. const tasks: Promise<any>[] = []
  440. await viewVideo(servers[2].url, localVideosServer3[0])
  441. await viewVideo(servers[2].url, localVideosServer3[0])
  442. await viewVideo(servers[2].url, localVideosServer3[0])
  443. await viewVideo(servers[2].url, localVideosServer3[1])
  444. await Promise.all(tasks)
  445. await waitJobs(servers)
  446. await viewVideo(servers[2].url, localVideosServer3[0])
  447. await waitJobs(servers)
  448. await viewVideo(servers[2].url, localVideosServer3[0])
  449. await waitJobs(servers)
  450. // Wait the repeatable job
  451. await wait(6000)
  452. for (const server of servers) {
  453. const res = await getVideosList(server.url)
  454. const videos = res.body.data
  455. const video0 = videos.find(v => v.uuid === localVideosServer3[0])
  456. const video1 = videos.find(v => v.uuid === localVideosServer3[1])
  457. expect(video0.views).to.equal(3)
  458. expect(video1.views).to.equal(1)
  459. }
  460. })
  461. it('Should view multiple videos on each servers', async function () {
  462. this.timeout(30000)
  463. const tasks: Promise<any>[] = []
  464. tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0]))
  465. tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
  466. tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
  467. tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0]))
  468. tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
  469. tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
  470. tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
  471. tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
  472. tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
  473. tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
  474. await Promise.all(tasks)
  475. await waitJobs(servers)
  476. // Wait the repeatable job
  477. await wait(8000)
  478. let baseVideos = null
  479. for (const server of servers) {
  480. const res = await getVideosList(server.url)
  481. const videos = res.body.data
  482. // Initialize base videos for future comparisons
  483. if (baseVideos === null) {
  484. baseVideos = videos
  485. continue
  486. }
  487. for (const baseVideo of baseVideos) {
  488. const sameVideo = videos.find(video => video.name === baseVideo.name)
  489. expect(baseVideo.views).to.equal(sameVideo.views)
  490. }
  491. }
  492. })
  493. it('Should like and dislikes videos on different services', async function () {
  494. this.timeout(20000)
  495. await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')
  496. await wait(500)
  497. await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'dislike')
  498. await wait(500)
  499. await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')
  500. await rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'like')
  501. await wait(500)
  502. await rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'dislike')
  503. await rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[1], 'dislike')
  504. await wait(500)
  505. await rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[0], 'like')
  506. await waitJobs(servers)
  507. let baseVideos = null
  508. for (const server of servers) {
  509. const res = await getVideosList(server.url)
  510. const videos = res.body.data
  511. // Initialize base videos for future comparisons
  512. if (baseVideos === null) {
  513. baseVideos = videos
  514. continue
  515. }
  516. for (const baseVideo of baseVideos) {
  517. const sameVideo = videos.find(video => video.name === baseVideo.name)
  518. expect(baseVideo.likes).to.equal(sameVideo.likes)
  519. expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
  520. }
  521. }
  522. })
  523. })
  524. describe('Should manipulate these videos', function () {
  525. it('Should update the video 3 by asking server 3', async function () {
  526. this.timeout(10000)
  527. const attributes = {
  528. name: 'my super video updated',
  529. category: 10,
  530. licence: 7,
  531. language: 'fr',
  532. nsfw: true,
  533. description: 'my super description updated',
  534. support: 'my super support text updated',
  535. tags: [ 'tag_up_1', 'tag_up_2' ],
  536. thumbnailfile: 'thumbnail.jpg',
  537. originallyPublishedAt: '2019-02-11T13:38:14.449Z',
  538. previewfile: 'preview.jpg'
  539. }
  540. await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes)
  541. await waitJobs(servers)
  542. })
  543. it('Should have the video 3 updated on each server', async function () {
  544. this.timeout(10000)
  545. for (const server of servers) {
  546. const res = await getVideosList(server.url)
  547. const videos = res.body.data
  548. const videoUpdated = videos.find(video => video.name === 'my super video updated')
  549. expect(!!videoUpdated).to.be.true
  550. const isLocal = server.url === 'http://localhost:9003'
  551. const checkAttributes = {
  552. name: 'my super video updated',
  553. category: 10,
  554. licence: 7,
  555. language: 'fr',
  556. nsfw: true,
  557. description: 'my super description updated',
  558. support: 'my super support text updated',
  559. originallyPublishedAt: '2019-02-11T13:38:14.449Z',
  560. account: {
  561. name: 'root',
  562. host: 'localhost:9003'
  563. },
  564. isLocal,
  565. duration: 5,
  566. commentsEnabled: true,
  567. downloadEnabled: true,
  568. tags: [ 'tag_up_1', 'tag_up_2' ],
  569. privacy: VideoPrivacy.PUBLIC,
  570. channel: {
  571. displayName: 'Main root channel',
  572. name: 'root_channel',
  573. description: '',
  574. isLocal
  575. },
  576. fixture: 'video_short3.webm',
  577. files: [
  578. {
  579. resolution: 720,
  580. size: 292677
  581. }
  582. ],
  583. thumbnailfile: 'thumbnail',
  584. previewfile: 'preview'
  585. }
  586. await completeVideoCheck(server.url, videoUpdated, checkAttributes)
  587. }
  588. })
  589. it('Should remove the videos 3 and 3-2 by asking server 3', async function () {
  590. this.timeout(10000)
  591. await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id)
  592. await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id)
  593. await waitJobs(servers)
  594. })
  595. it('Should not have files of videos 3 and 3-2 on each server', async function () {
  596. for (const server of servers) {
  597. await checkVideoFilesWereRemoved(toRemove[0].uuid, server.serverNumber)
  598. await checkVideoFilesWereRemoved(toRemove[1].uuid, server.serverNumber)
  599. }
  600. })
  601. it('Should have videos 1 and 3 on each server', async function () {
  602. for (const server of servers) {
  603. const res = await getVideosList(server.url)
  604. const videos = res.body.data
  605. expect(videos).to.be.an('array')
  606. expect(videos.length).to.equal(2)
  607. expect(videos[0].name).not.to.equal(videos[1].name)
  608. expect(videos[0].name).not.to.equal(toRemove[0].name)
  609. expect(videos[1].name).not.to.equal(toRemove[0].name)
  610. expect(videos[0].name).not.to.equal(toRemove[1].name)
  611. expect(videos[1].name).not.to.equal(toRemove[1].name)
  612. videoUUID = videos.find(video => video.name === 'my super name for server 1').uuid
  613. }
  614. })
  615. it('Should get the same video by UUID on each server', async function () {
  616. let baseVideo = null
  617. for (const server of servers) {
  618. const res = await getVideo(server.url, videoUUID)
  619. const video = res.body
  620. if (baseVideo === null) {
  621. baseVideo = video
  622. continue
  623. }
  624. expect(baseVideo.name).to.equal(video.name)
  625. expect(baseVideo.uuid).to.equal(video.uuid)
  626. expect(baseVideo.category.id).to.equal(video.category.id)
  627. expect(baseVideo.language.id).to.equal(video.language.id)
  628. expect(baseVideo.licence.id).to.equal(video.licence.id)
  629. expect(baseVideo.nsfw).to.equal(video.nsfw)
  630. expect(baseVideo.account.name).to.equal(video.account.name)
  631. expect(baseVideo.account.displayName).to.equal(video.account.displayName)
  632. expect(baseVideo.account.url).to.equal(video.account.url)
  633. expect(baseVideo.account.host).to.equal(video.account.host)
  634. expect(baseVideo.tags).to.deep.equal(video.tags)
  635. }
  636. })
  637. it('Should get the preview from each server', async function () {
  638. for (const server of servers) {
  639. const res = await getVideo(server.url, videoUUID)
  640. const video = res.body
  641. await testImage(server.url, 'video_short1-preview.webm', video.previewPath)
  642. }
  643. })
  644. })
  645. describe('Should comment these videos', function () {
  646. let childOfFirstChild: VideoCommentThreadTree
  647. it('Should add comment (threads and replies)', async function () {
  648. this.timeout(25000)
  649. {
  650. const text = 'my super first comment'
  651. await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text)
  652. }
  653. {
  654. const text = 'my super second comment'
  655. await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text)
  656. }
  657. await waitJobs(servers)
  658. {
  659. const res = await getVideoCommentThreads(servers[1].url, videoUUID, 0, 5)
  660. const threadId = res.body.data.find(c => c.text === 'my super first comment').id
  661. const text = 'my super answer to thread 1'
  662. await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text)
  663. }
  664. await waitJobs(servers)
  665. {
  666. const res1 = await getVideoCommentThreads(servers[2].url, videoUUID, 0, 5)
  667. const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
  668. const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId)
  669. const childCommentId = res2.body.children[0].comment.id
  670. const text3 = 'my second answer to thread 1'
  671. await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3)
  672. const text2 = 'my super answer to answer of thread 1'
  673. await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2)
  674. }
  675. await waitJobs(servers)
  676. })
  677. it('Should have these threads', async function () {
  678. for (const server of servers) {
  679. const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
  680. expect(res.body.total).to.equal(2)
  681. expect(res.body.data).to.be.an('array')
  682. expect(res.body.data).to.have.lengthOf(2)
  683. {
  684. const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment')
  685. expect(comment).to.not.be.undefined
  686. expect(comment.inReplyToCommentId).to.be.null
  687. expect(comment.account.name).to.equal('root')
  688. expect(comment.account.host).to.equal('localhost:9001')
  689. expect(comment.totalReplies).to.equal(3)
  690. expect(dateIsValid(comment.createdAt as string)).to.be.true
  691. expect(dateIsValid(comment.updatedAt as string)).to.be.true
  692. }
  693. {
  694. const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment')
  695. expect(comment).to.not.be.undefined
  696. expect(comment.inReplyToCommentId).to.be.null
  697. expect(comment.account.name).to.equal('root')
  698. expect(comment.account.host).to.equal('localhost:9003')
  699. expect(comment.totalReplies).to.equal(0)
  700. expect(dateIsValid(comment.createdAt as string)).to.be.true
  701. expect(dateIsValid(comment.updatedAt as string)).to.be.true
  702. }
  703. }
  704. })
  705. it('Should have these comments', async function () {
  706. for (const server of servers) {
  707. const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
  708. const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
  709. const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
  710. const tree: VideoCommentThreadTree = res2.body
  711. expect(tree.comment.text).equal('my super first comment')
  712. expect(tree.comment.account.name).equal('root')
  713. expect(tree.comment.account.host).equal('localhost:9001')
  714. expect(tree.children).to.have.lengthOf(2)
  715. const firstChild = tree.children[0]
  716. expect(firstChild.comment.text).to.equal('my super answer to thread 1')
  717. expect(firstChild.comment.account.name).equal('root')
  718. expect(firstChild.comment.account.host).equal('localhost:9002')
  719. expect(firstChild.children).to.have.lengthOf(1)
  720. childOfFirstChild = firstChild.children[0]
  721. expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
  722. expect(childOfFirstChild.comment.account.name).equal('root')
  723. expect(childOfFirstChild.comment.account.host).equal('localhost:9003')
  724. expect(childOfFirstChild.children).to.have.lengthOf(0)
  725. const secondChild = tree.children[1]
  726. expect(secondChild.comment.text).to.equal('my second answer to thread 1')
  727. expect(secondChild.comment.account.name).equal('root')
  728. expect(secondChild.comment.account.host).equal('localhost:9003')
  729. expect(secondChild.children).to.have.lengthOf(0)
  730. }
  731. })
  732. it('Should delete a reply', async function () {
  733. this.timeout(10000)
  734. await deleteVideoComment(servers[2].url, servers[2].accessToken, videoUUID, childOfFirstChild.comment.id)
  735. await waitJobs(servers)
  736. })
  737. it('Should not have this comment anymore', async function () {
  738. for (const server of servers) {
  739. const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
  740. const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
  741. const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
  742. const tree: VideoCommentThreadTree = res2.body
  743. expect(tree.comment.text).equal('my super first comment')
  744. const firstChild = tree.children[0]
  745. expect(firstChild.comment.text).to.equal('my super answer to thread 1')
  746. expect(firstChild.children).to.have.lengthOf(0)
  747. const secondChild = tree.children[1]
  748. expect(secondChild.comment.text).to.equal('my second answer to thread 1')
  749. }
  750. })
  751. it('Should delete the thread comments', async function () {
  752. this.timeout(10000)
  753. const res1 = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5)
  754. const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
  755. await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId)
  756. await waitJobs(servers)
  757. })
  758. it('Should have the thread comments deleted on other servers too', async function () {
  759. for (const server of servers) {
  760. const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
  761. expect(res.body.total).to.equal(1)
  762. expect(res.body.data).to.be.an('array')
  763. expect(res.body.data).to.have.lengthOf(1)
  764. {
  765. const comment: VideoComment = res.body.data[0]
  766. expect(comment).to.not.be.undefined
  767. expect(comment.inReplyToCommentId).to.be.null
  768. expect(comment.account.name).to.equal('root')
  769. expect(comment.account.host).to.equal('localhost:9003')
  770. expect(comment.totalReplies).to.equal(0)
  771. expect(dateIsValid(comment.createdAt as string)).to.be.true
  772. expect(dateIsValid(comment.updatedAt as string)).to.be.true
  773. }
  774. }
  775. })
  776. it('Should disable comments and download', async function () {
  777. this.timeout(20000)
  778. const attributes = {
  779. commentsEnabled: false,
  780. downloadEnabled: false
  781. }
  782. await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, attributes)
  783. await waitJobs(servers)
  784. for (const server of servers) {
  785. const res = await getVideo(server.url, videoUUID)
  786. expect(res.body.commentsEnabled).to.be.false
  787. expect(res.body.downloadEnabled).to.be.false
  788. const text = 'my super forbidden comment'
  789. await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409)
  790. }
  791. })
  792. })
  793. describe('With minimum parameters', function () {
  794. it('Should upload and propagate the video', async function () {
  795. this.timeout(60000)
  796. const path = '/api/v1/videos/upload'
  797. const req = request(servers[1].url)
  798. .post(path)
  799. .set('Accept', 'application/json')
  800. .set('Authorization', 'Bearer ' + servers[1].accessToken)
  801. .field('name', 'minimum parameters')
  802. .field('privacy', '1')
  803. .field('channelId', '1')
  804. const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm')
  805. await req.attach('videofile', filePath)
  806. .expect(200)
  807. await waitJobs(servers)
  808. for (const server of servers) {
  809. const res = await getVideosList(server.url)
  810. const video = res.body.data.find(v => v.name === 'minimum parameters')
  811. const isLocal = server.url === 'http://localhost:9002'
  812. const checkAttributes = {
  813. name: 'minimum parameters',
  814. category: null,
  815. licence: null,
  816. language: null,
  817. nsfw: false,
  818. description: null,
  819. support: null,
  820. account: {
  821. name: 'root',
  822. host: 'localhost:9002'
  823. },
  824. isLocal,
  825. duration: 5,
  826. commentsEnabled: false,
  827. downloadEnabled: true,
  828. tags: [ ],
  829. privacy: VideoPrivacy.PUBLIC,
  830. channel: {
  831. displayName: 'Main root channel',
  832. name: 'root_channel',
  833. description: '',
  834. isLocal
  835. },
  836. fixture: 'video_short.webm',
  837. files: [
  838. {
  839. resolution: 720,
  840. size: 72000
  841. },
  842. {
  843. resolution: 480,
  844. size: 45000
  845. },
  846. {
  847. resolution: 360,
  848. size: 34600
  849. },
  850. {
  851. resolution: 240,
  852. size: 24770
  853. }
  854. ]
  855. }
  856. await completeVideoCheck(server.url, video, checkAttributes)
  857. }
  858. })
  859. })
  860. describe('TMP directory', function () {
  861. it('Should have an empty tmp directory', async function () {
  862. for (const server of servers) {
  863. await checkTmpIsEmpty(server)
  864. }
  865. })
  866. })
  867. after(function () {
  868. killallServers(servers)
  869. })
  870. })