single-server.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
  2. import { expect } from 'chai'
  3. import { wait } from '@peertube/peertube-core-utils'
  4. import { Video, VideoPrivacy } from '@peertube/peertube-models'
  5. import { checkVideoFilesWereRemoved, completeVideoCheck } from '@tests/shared/videos.js'
  6. import { testImageGeneratedByFFmpeg } from '@tests/shared/checks.js'
  7. import {
  8. cleanupTests,
  9. createSingleServer,
  10. PeerTubeServer,
  11. setAccessTokensToServers,
  12. setDefaultAccountAvatar,
  13. setDefaultChannelAvatar,
  14. waitJobs
  15. } from '@peertube/peertube-server-commands'
  16. describe('Test a single server', function () {
  17. function runSuite (mode: 'legacy' | 'resumable') {
  18. let server: PeerTubeServer = null
  19. let videoId: number | string
  20. let videoId2: string
  21. let videoUUID = ''
  22. let videosListBase: any[] = null
  23. const getCheckAttributes = () => ({
  24. name: 'my super name',
  25. category: 2,
  26. licence: 6,
  27. language: 'zh',
  28. nsfw: true,
  29. description: 'my super description',
  30. support: 'my super support text',
  31. account: {
  32. name: 'root',
  33. host: server.host
  34. },
  35. duration: 5,
  36. tags: [ 'tag1', 'tag2', 'tag3' ],
  37. privacy: VideoPrivacy.PUBLIC,
  38. commentsEnabled: true,
  39. downloadEnabled: true,
  40. channel: {
  41. displayName: 'Main root channel',
  42. name: 'root_channel',
  43. description: ''
  44. },
  45. fixture: 'video_short.webm',
  46. files: [
  47. {
  48. resolution: 720,
  49. height: 720,
  50. width: 1280,
  51. size: 218910
  52. }
  53. ]
  54. })
  55. const updateCheckAttributes = () => ({
  56. name: 'my super video updated',
  57. category: 4,
  58. licence: 2,
  59. language: 'ar',
  60. nsfw: false,
  61. description: 'my super description updated',
  62. support: 'my super support text updated',
  63. account: {
  64. name: 'root',
  65. host: server.host
  66. },
  67. tags: [ 'tagup1', 'tagup2' ],
  68. privacy: VideoPrivacy.PUBLIC,
  69. duration: 5,
  70. commentsEnabled: false,
  71. downloadEnabled: false,
  72. channel: {
  73. name: 'root_channel',
  74. displayName: 'Main root channel',
  75. description: ''
  76. },
  77. fixture: 'video_short3.webm',
  78. files: [
  79. {
  80. resolution: 720,
  81. height: 720,
  82. width: 1280,
  83. size: 292677
  84. }
  85. ]
  86. })
  87. before(async function () {
  88. this.timeout(30000)
  89. server = await createSingleServer(1, {})
  90. await setAccessTokensToServers([ server ])
  91. await setDefaultChannelAvatar(server)
  92. await setDefaultAccountAvatar(server)
  93. })
  94. it('Should list video categories', async function () {
  95. const categories = await server.videos.getCategories()
  96. expect(Object.keys(categories)).to.have.length.above(10)
  97. expect(categories[11]).to.equal('News & Politics')
  98. })
  99. it('Should list video licences', async function () {
  100. const licences = await server.videos.getLicences()
  101. expect(Object.keys(licences)).to.have.length.above(5)
  102. expect(licences[3]).to.equal('Attribution - No Derivatives')
  103. })
  104. it('Should list video languages', async function () {
  105. const languages = await server.videos.getLanguages()
  106. expect(Object.keys(languages)).to.have.length.above(5)
  107. expect(languages['ru']).to.equal('Russian')
  108. })
  109. it('Should list video privacies', async function () {
  110. const privacies = await server.videos.getPrivacies()
  111. expect(Object.keys(privacies)).to.have.length.at.least(3)
  112. expect(privacies[3]).to.equal('Private')
  113. })
  114. it('Should not have videos', async function () {
  115. const { data, total } = await server.videos.list()
  116. expect(total).to.equal(0)
  117. expect(data).to.be.an('array')
  118. expect(data.length).to.equal(0)
  119. })
  120. it('Should upload the video', async function () {
  121. const attributes = {
  122. name: 'my super name',
  123. category: 2,
  124. nsfw: true,
  125. licence: 6,
  126. tags: [ 'tag1', 'tag2', 'tag3' ]
  127. }
  128. const video = await server.videos.upload({ attributes, mode })
  129. expect(video).to.not.be.undefined
  130. expect(video.id).to.equal(1)
  131. expect(video.uuid).to.have.length.above(5)
  132. videoId = video.id
  133. videoUUID = video.uuid
  134. })
  135. it('Should get and seed the uploaded video', async function () {
  136. this.timeout(5000)
  137. const { data, total } = await server.videos.list()
  138. expect(total).to.equal(1)
  139. expect(data).to.be.an('array')
  140. expect(data.length).to.equal(1)
  141. const video = data[0]
  142. await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: getCheckAttributes() })
  143. })
  144. it('Should get the video by UUID', async function () {
  145. this.timeout(5000)
  146. const video = await server.videos.get({ id: videoUUID })
  147. await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: getCheckAttributes() })
  148. })
  149. it('Should have the views updated', async function () {
  150. this.timeout(20000)
  151. await server.views.simulateView({ id: videoId })
  152. await server.views.simulateView({ id: videoId })
  153. await server.views.simulateView({ id: videoId })
  154. await wait(1500)
  155. await server.views.simulateView({ id: videoId })
  156. await server.views.simulateView({ id: videoId })
  157. await wait(1500)
  158. await server.views.simulateView({ id: videoId })
  159. await server.views.simulateView({ id: videoId })
  160. await server.debug.sendCommand({ body: { command: 'process-video-views-buffer' } })
  161. const video = await server.videos.get({ id: videoId })
  162. expect(video.views).to.equal(3)
  163. })
  164. it('Should remove the video', async function () {
  165. const video = await server.videos.get({ id: videoId })
  166. await server.videos.remove({ id: videoId })
  167. await checkVideoFilesWereRemoved({ video, server })
  168. })
  169. it('Should not have videos', async function () {
  170. const { total, data } = await server.videos.list()
  171. expect(total).to.equal(0)
  172. expect(data).to.be.an('array')
  173. expect(data).to.have.lengthOf(0)
  174. })
  175. it('Should upload 6 videos', async function () {
  176. this.timeout(120000)
  177. const videos = new Set([
  178. 'video_short.mp4', 'video_short.ogv', 'video_short.webm',
  179. 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
  180. ])
  181. for (const video of videos) {
  182. const attributes = {
  183. name: video + ' name',
  184. description: video + ' description',
  185. category: 2,
  186. licence: 1,
  187. language: 'en',
  188. nsfw: true,
  189. tags: [ 'tag1', 'tag2', 'tag3' ],
  190. fixture: video
  191. }
  192. await server.videos.upload({ attributes, mode })
  193. }
  194. })
  195. it('Should have the correct durations', async function () {
  196. const { total, data } = await server.videos.list()
  197. expect(total).to.equal(6)
  198. expect(data).to.be.an('array')
  199. expect(data).to.have.lengthOf(6)
  200. const videosByName: { [ name: string ]: Video } = {}
  201. data.forEach(v => { videosByName[v.name] = v })
  202. expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
  203. expect(videosByName['video_short.ogv name'].duration).to.equal(5)
  204. expect(videosByName['video_short.webm name'].duration).to.equal(5)
  205. expect(videosByName['video_short1.webm name'].duration).to.equal(10)
  206. expect(videosByName['video_short2.webm name'].duration).to.equal(5)
  207. expect(videosByName['video_short3.webm name'].duration).to.equal(5)
  208. })
  209. it('Should have the correct thumbnails', async function () {
  210. const { data } = await server.videos.list()
  211. // For the next test
  212. videosListBase = data
  213. for (const video of data) {
  214. const videoName = video.name.replace(' name', '')
  215. await testImageGeneratedByFFmpeg(server.url, videoName, video.thumbnailPath)
  216. }
  217. })
  218. it('Should list only the two first videos', async function () {
  219. const { total, data } = await server.videos.list({ start: 0, count: 2, sort: 'name' })
  220. expect(total).to.equal(6)
  221. expect(data.length).to.equal(2)
  222. expect(data[0].name).to.equal(videosListBase[0].name)
  223. expect(data[1].name).to.equal(videosListBase[1].name)
  224. })
  225. it('Should list only the next three videos', async function () {
  226. const { total, data } = await server.videos.list({ start: 2, count: 3, sort: 'name' })
  227. expect(total).to.equal(6)
  228. expect(data.length).to.equal(3)
  229. expect(data[0].name).to.equal(videosListBase[2].name)
  230. expect(data[1].name).to.equal(videosListBase[3].name)
  231. expect(data[2].name).to.equal(videosListBase[4].name)
  232. })
  233. it('Should list the last video', async function () {
  234. const { total, data } = await server.videos.list({ start: 5, count: 6, sort: 'name' })
  235. expect(total).to.equal(6)
  236. expect(data.length).to.equal(1)
  237. expect(data[0].name).to.equal(videosListBase[5].name)
  238. })
  239. it('Should not have the total field', async function () {
  240. const { total, data } = await server.videos.list({ start: 5, count: 6, sort: 'name', skipCount: true })
  241. expect(total).to.not.exist
  242. expect(data.length).to.equal(1)
  243. expect(data[0].name).to.equal(videosListBase[5].name)
  244. })
  245. it('Should list and sort by name in descending order', async function () {
  246. const { total, data } = await server.videos.list({ sort: '-name' })
  247. expect(total).to.equal(6)
  248. expect(data.length).to.equal(6)
  249. expect(data[0].name).to.equal('video_short.webm name')
  250. expect(data[1].name).to.equal('video_short.ogv name')
  251. expect(data[2].name).to.equal('video_short.mp4 name')
  252. expect(data[3].name).to.equal('video_short3.webm name')
  253. expect(data[4].name).to.equal('video_short2.webm name')
  254. expect(data[5].name).to.equal('video_short1.webm name')
  255. videoId = data[3].uuid
  256. videoId2 = data[5].uuid
  257. })
  258. it('Should list and sort by trending in descending order', async function () {
  259. const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-trending' })
  260. expect(total).to.equal(6)
  261. expect(data.length).to.equal(2)
  262. })
  263. it('Should list and sort by hotness in descending order', async function () {
  264. const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-hot' })
  265. expect(total).to.equal(6)
  266. expect(data.length).to.equal(2)
  267. })
  268. it('Should list and sort by best in descending order', async function () {
  269. const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-best' })
  270. expect(total).to.equal(6)
  271. expect(data.length).to.equal(2)
  272. })
  273. it('Should update a video', async function () {
  274. const attributes = {
  275. name: 'my super video updated',
  276. category: 4,
  277. licence: 2,
  278. language: 'ar',
  279. nsfw: false,
  280. description: 'my super description updated',
  281. commentsEnabled: false,
  282. downloadEnabled: false,
  283. tags: [ 'tagup1', 'tagup2' ]
  284. }
  285. await server.videos.update({ id: videoId, attributes })
  286. })
  287. it('Should have the video updated', async function () {
  288. this.timeout(60000)
  289. await waitJobs([ server ])
  290. const video = await server.videos.get({ id: videoId })
  291. await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: updateCheckAttributes() })
  292. })
  293. it('Should update only the tags of a video', async function () {
  294. const attributes = {
  295. tags: [ 'supertag', 'tag1', 'tag2' ]
  296. }
  297. await server.videos.update({ id: videoId, attributes })
  298. const video = await server.videos.get({ id: videoId })
  299. await completeVideoCheck({
  300. server,
  301. originServer: server,
  302. videoUUID: video.uuid,
  303. attributes: Object.assign(updateCheckAttributes(), attributes)
  304. })
  305. })
  306. it('Should update only the description of a video', async function () {
  307. const attributes = {
  308. description: 'hello everybody'
  309. }
  310. await server.videos.update({ id: videoId, attributes })
  311. const video = await server.videos.get({ id: videoId })
  312. await completeVideoCheck({
  313. server,
  314. originServer: server,
  315. videoUUID: video.uuid,
  316. attributes: Object.assign(updateCheckAttributes(), { tags: [ 'supertag', 'tag1', 'tag2' ] }, attributes)
  317. })
  318. })
  319. it('Should like a video', async function () {
  320. await server.videos.rate({ id: videoId, rating: 'like' })
  321. const video = await server.videos.get({ id: videoId })
  322. expect(video.likes).to.equal(1)
  323. expect(video.dislikes).to.equal(0)
  324. })
  325. it('Should dislike the same video', async function () {
  326. await server.videos.rate({ id: videoId, rating: 'dislike' })
  327. const video = await server.videos.get({ id: videoId })
  328. expect(video.likes).to.equal(0)
  329. expect(video.dislikes).to.equal(1)
  330. })
  331. it('Should sort by originallyPublishedAt', async function () {
  332. {
  333. const now = new Date()
  334. const attributes = { originallyPublishedAt: now.toISOString() }
  335. await server.videos.update({ id: videoId, attributes })
  336. const { data } = await server.videos.list({ sort: '-originallyPublishedAt' })
  337. const names = data.map(v => v.name)
  338. expect(names[0]).to.equal('my super video updated')
  339. expect(names[1]).to.equal('video_short2.webm name')
  340. expect(names[2]).to.equal('video_short1.webm name')
  341. expect(names[3]).to.equal('video_short.webm name')
  342. expect(names[4]).to.equal('video_short.ogv name')
  343. expect(names[5]).to.equal('video_short.mp4 name')
  344. }
  345. {
  346. const now = new Date()
  347. const attributes = { originallyPublishedAt: now.toISOString() }
  348. await server.videos.update({ id: videoId2, attributes })
  349. const { data } = await server.videos.list({ sort: '-originallyPublishedAt' })
  350. const names = data.map(v => v.name)
  351. expect(names[0]).to.equal('video_short1.webm name')
  352. expect(names[1]).to.equal('my super video updated')
  353. expect(names[2]).to.equal('video_short2.webm name')
  354. expect(names[3]).to.equal('video_short.webm name')
  355. expect(names[4]).to.equal('video_short.ogv name')
  356. expect(names[5]).to.equal('video_short.mp4 name')
  357. }
  358. })
  359. after(async function () {
  360. await cleanupTests([ server ])
  361. })
  362. }
  363. describe('Legacy upload', function () {
  364. runSuite('legacy')
  365. })
  366. describe('Resumable upload', function () {
  367. runSuite('resumable')
  368. })
  369. })