Add ability to search a video with an URL
[oweals/peertube.git] / server / tests / api / videos / single-server.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import { keyBy } from 'lodash'
5 import 'mocha'
6 import { VideoPrivacy } from '../../../../shared/models/videos'
7 import {
8   checkVideoFilesWereRemoved,
9   completeVideoCheck,
10   flushTests,
11   getVideo,
12   getVideoCategories,
13   getVideoLanguages,
14   getVideoLicences,
15   getVideoPrivacies,
16   getVideosList,
17   getVideosListPagination,
18   getVideosListSort,
19   getVideosWithFilters,
20   killallServers,
21   rateVideo,
22   removeVideo,
23   runServer,
24   ServerInfo,
25   setAccessTokensToServers,
26   testImage,
27   updateVideo,
28   uploadVideo,
29   viewVideo,
30   wait
31 } from '../../utils'
32
33 const expect = chai.expect
34
35 describe('Test a single server', function () {
36   let server: ServerInfo = null
37   let videoId = -1
38   let videoUUID = ''
39   let videosListBase: any[] = null
40
41   const getCheckAttributes = {
42     name: 'my super name',
43     category: 2,
44     licence: 6,
45     language: 'zh',
46     nsfw: true,
47     description: 'my super description',
48     support: 'my super support text',
49     account: {
50       name: 'root',
51       host: 'localhost:9001'
52     },
53     isLocal: true,
54     duration: 5,
55     tags: [ 'tag1', 'tag2', 'tag3' ],
56     privacy: VideoPrivacy.PUBLIC,
57     commentsEnabled: true,
58     channel: {
59       displayName: 'Main root channel',
60       name: 'root_channel',
61       description: '',
62       isLocal: true
63     },
64     fixture: 'video_short.webm',
65     files: [
66       {
67         resolution: 720,
68         size: 218910
69       }
70     ]
71   }
72
73   const updateCheckAttributes = {
74     name: 'my super video updated',
75     category: 4,
76     licence: 2,
77     language: 'ar',
78     nsfw: false,
79     description: 'my super description updated',
80     support: 'my super support text updated',
81     account: {
82       name: 'root',
83       host: 'localhost:9001'
84     },
85     isLocal: true,
86     tags: [ 'tagup1', 'tagup2' ],
87     privacy: VideoPrivacy.PUBLIC,
88     duration: 5,
89     commentsEnabled: false,
90     channel: {
91       name: 'root_channel',
92       displayName: 'Main root channel',
93       description: '',
94       isLocal: true
95     },
96     fixture: 'video_short3.webm',
97     files: [
98       {
99         resolution: 720,
100         size: 292677
101       }
102     ]
103   }
104
105   before(async function () {
106     this.timeout(30000)
107
108     await flushTests()
109
110     server = await runServer(1)
111
112     await setAccessTokensToServers([ server ])
113   })
114
115   it('Should list video categories', async function () {
116     const res = await getVideoCategories(server.url)
117
118     const categories = res.body
119     expect(Object.keys(categories)).to.have.length.above(10)
120
121     expect(categories[11]).to.equal('News')
122   })
123
124   it('Should list video licences', async function () {
125     const res = await getVideoLicences(server.url)
126
127     const licences = res.body
128     expect(Object.keys(licences)).to.have.length.above(5)
129
130     expect(licences[3]).to.equal('Attribution - No Derivatives')
131   })
132
133   it('Should list video languages', async function () {
134     const res = await getVideoLanguages(server.url)
135
136     const languages = res.body
137     expect(Object.keys(languages)).to.have.length.above(5)
138
139     expect(languages['ru']).to.equal('Russian')
140   })
141
142   it('Should list video privacies', async function () {
143     const res = await getVideoPrivacies(server.url)
144
145     const privacies = res.body
146     expect(Object.keys(privacies)).to.have.length.at.least(3)
147
148     expect(privacies[3]).to.equal('Private')
149   })
150
151   it('Should not have videos', async function () {
152     const res = await getVideosList(server.url)
153
154     expect(res.body.total).to.equal(0)
155     expect(res.body.data).to.be.an('array')
156     expect(res.body.data.length).to.equal(0)
157   })
158
159   it('Should upload the video', async function () {
160     const videoAttributes = {
161       name: 'my super name',
162       category: 2,
163       nsfw: true,
164       licence: 6,
165       tags: [ 'tag1', 'tag2', 'tag3' ]
166     }
167     const res = await uploadVideo(server.url, server.accessToken, videoAttributes)
168     expect(res.body.video).to.not.be.undefined
169     expect(res.body.video.id).to.equal(1)
170     expect(res.body.video.uuid).to.have.length.above(5)
171
172     videoId = res.body.video.id
173     videoUUID = res.body.video.uuid
174   })
175
176   it('Should get and seed the uploaded video', async function () {
177     this.timeout(5000)
178
179     const res = await getVideosList(server.url)
180
181     expect(res.body.total).to.equal(1)
182     expect(res.body.data).to.be.an('array')
183     expect(res.body.data.length).to.equal(1)
184
185     const video = res.body.data[0]
186     await completeVideoCheck(server.url, video, getCheckAttributes)
187   })
188
189   it('Should get the video by UUID', async function () {
190     this.timeout(5000)
191
192     const res = await getVideo(server.url, videoUUID)
193
194     const video = res.body
195     await completeVideoCheck(server.url, video, getCheckAttributes)
196   })
197
198   it('Should have the views updated', async function () {
199     this.timeout(10000)
200
201     await viewVideo(server.url, videoId)
202     await viewVideo(server.url, videoId)
203     await viewVideo(server.url, videoId)
204
205     await wait(1500)
206
207     await viewVideo(server.url, videoId)
208     await viewVideo(server.url, videoId)
209
210     await wait(1500)
211
212     await viewVideo(server.url, videoId)
213     await viewVideo(server.url, videoId)
214
215     const res = await getVideo(server.url, videoId)
216
217     const video = res.body
218     expect(video.views).to.equal(3)
219   })
220
221   it('Should remove the video', async function () {
222     await removeVideo(server.url, server.accessToken, videoId)
223
224     await checkVideoFilesWereRemoved(videoUUID, 1)
225   })
226
227   it('Should not have videos', async function () {
228     const res = await getVideosList(server.url)
229
230     expect(res.body.total).to.equal(0)
231     expect(res.body.data).to.be.an('array')
232     expect(res.body.data).to.have.lengthOf(0)
233   })
234
235   it('Should upload 6 videos', async function () {
236     this.timeout(25000)
237
238     const videos = [
239       'video_short.mp4', 'video_short.ogv', 'video_short.webm',
240       'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
241     ]
242
243     const tasks: Promise<any>[] = []
244     for (const video of videos) {
245       const videoAttributes = {
246         name: video + ' name',
247         description: video + ' description',
248         category: 2,
249         licence: 1,
250         language: 'en',
251         nsfw: true,
252         tags: [ 'tag1', 'tag2', 'tag3' ],
253         fixture: video
254       }
255
256       const p = uploadVideo(server.url, server.accessToken, videoAttributes)
257       tasks.push(p)
258     }
259
260     await Promise.all(tasks)
261   })
262
263   it('Should have the correct durations', async function () {
264     const res = await getVideosList(server.url)
265
266     expect(res.body.total).to.equal(6)
267     const videos = res.body.data
268     expect(videos).to.be.an('array')
269     expect(videos).to.have.lengthOf(6)
270
271     const videosByName = keyBy<{ duration: number }>(videos, 'name')
272     expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
273     expect(videosByName['video_short.ogv name'].duration).to.equal(5)
274     expect(videosByName['video_short.webm name'].duration).to.equal(5)
275     expect(videosByName['video_short1.webm name'].duration).to.equal(10)
276     expect(videosByName['video_short2.webm name'].duration).to.equal(5)
277     expect(videosByName['video_short3.webm name'].duration).to.equal(5)
278   })
279
280   it('Should have the correct thumbnails', async function () {
281     const res = await getVideosList(server.url)
282
283     const videos = res.body.data
284     // For the next test
285     videosListBase = videos
286
287     for (const video of videos) {
288       const videoName = video.name.replace(' name', '')
289       await testImage(server.url, videoName, video.thumbnailPath)
290     }
291   })
292
293   it('Should list only the two first videos', async function () {
294     const res = await getVideosListPagination(server.url, 0, 2, 'name')
295
296     const videos = res.body.data
297     expect(res.body.total).to.equal(6)
298     expect(videos.length).to.equal(2)
299     expect(videos[0].name).to.equal(videosListBase[0].name)
300     expect(videos[1].name).to.equal(videosListBase[1].name)
301   })
302
303   it('Should list only the next three videos', async function () {
304     const res = await getVideosListPagination(server.url, 2, 3, 'name')
305
306     const videos = res.body.data
307     expect(res.body.total).to.equal(6)
308     expect(videos.length).to.equal(3)
309     expect(videos[0].name).to.equal(videosListBase[2].name)
310     expect(videos[1].name).to.equal(videosListBase[3].name)
311     expect(videos[2].name).to.equal(videosListBase[4].name)
312   })
313
314   it('Should list the last video', async function () {
315     const res = await getVideosListPagination(server.url, 5, 6, 'name')
316
317     const videos = res.body.data
318     expect(res.body.total).to.equal(6)
319     expect(videos.length).to.equal(1)
320     expect(videos[0].name).to.equal(videosListBase[5].name)
321   })
322
323   it('Should list and sort by name in descending order', async function () {
324     const res = await getVideosListSort(server.url, '-name')
325
326     const videos = res.body.data
327     expect(res.body.total).to.equal(6)
328     expect(videos.length).to.equal(6)
329     expect(videos[0].name).to.equal('video_short.webm name')
330     expect(videos[1].name).to.equal('video_short.ogv name')
331     expect(videos[2].name).to.equal('video_short.mp4 name')
332     expect(videos[3].name).to.equal('video_short3.webm name')
333     expect(videos[4].name).to.equal('video_short2.webm name')
334     expect(videos[5].name).to.equal('video_short1.webm name')
335
336     videoId = videos[3].uuid
337   })
338
339   it('Should update a video', async function () {
340     const attributes = {
341       name: 'my super video updated',
342       category: 4,
343       licence: 2,
344       language: 'ar',
345       nsfw: false,
346       description: 'my super description updated',
347       commentsEnabled: false,
348       tags: [ 'tagup1', 'tagup2' ]
349     }
350     await updateVideo(server.url, server.accessToken, videoId, attributes)
351   })
352
353   it('Should filter by tags and category', async function () {
354     const res1 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: 4 })
355     expect(res1.body.total).to.equal(1)
356     expect(res1.body.data[0].name).to.equal('my super video updated')
357
358     const res2 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: 3 })
359     expect(res2.body.total).to.equal(0)
360   })
361
362   it('Should have the video updated', async function () {
363     this.timeout(60000)
364
365     const res = await getVideo(server.url, videoId)
366     const video = res.body
367
368     await completeVideoCheck(server.url, video, updateCheckAttributes)
369   })
370
371   it('Should update only the tags of a video', async function () {
372     const attributes = {
373       tags: [ 'supertag', 'tag1', 'tag2' ]
374     }
375     await updateVideo(server.url, server.accessToken, videoId, attributes)
376
377     const res = await getVideo(server.url, videoId)
378     const video = res.body
379
380     await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes, attributes))
381   })
382
383   it('Should update only the description of a video', async function () {
384     const attributes = {
385       description: 'hello everybody'
386     }
387     await updateVideo(server.url, server.accessToken, videoId, attributes)
388
389     const res = await getVideo(server.url, videoId)
390     const video = res.body
391
392     await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes, attributes))
393   })
394
395   it('Should like a video', async function () {
396     await rateVideo(server.url, server.accessToken, videoId, 'like')
397
398     const res = await getVideo(server.url, videoId)
399     const video = res.body
400
401     expect(video.likes).to.equal(1)
402     expect(video.dislikes).to.equal(0)
403   })
404
405   it('Should dislike the same video', async function () {
406     await rateVideo(server.url, server.accessToken, videoId, 'dislike')
407
408     const res = await getVideo(server.url, videoId)
409     const video = res.body
410
411     expect(video.likes).to.equal(0)
412     expect(video.dislikes).to.equal(1)
413   })
414
415   after(async function () {
416     killallServers([ server ])
417
418     // Keep the logs if the test failed
419     if (this['ok']) {
420       await flushTests()
421     }
422   })
423 })