Add video channel tests
[oweals/peertube.git] / server / tests / utils / videos.ts
1 import { readFile } from 'fs'
2 import * as request from 'supertest'
3 import { join, isAbsolute } from 'path'
4 import * as parseTorrent from 'parse-torrent'
5
6 import { makeGetRequest } from './requests'
7 import { readFilePromise } from './miscs'
8 import { ServerInfo } from './servers'
9 import { getMyUserInformation } from './users'
10
11 type VideoAttributes = {
12   name?: string
13   category?: number
14   licence?: number
15   language?: number
16   nsfw?: boolean
17   description?: string
18   tags?: string[]
19   channelId?: number
20   fixture?: string
21 }
22
23 function getVideoCategories (url: string) {
24   const path = '/api/v1/videos/categories'
25
26   return makeGetRequest(url, path)
27 }
28
29 function getVideoLicences (url: string) {
30   const path = '/api/v1/videos/licences'
31
32   return makeGetRequest(url, path)
33 }
34
35 function getVideoLanguages (url: string) {
36   const path = '/api/v1/videos/languages'
37
38   return makeGetRequest(url, path)
39 }
40
41 function getAllVideosListBy (url: string) {
42   const path = '/api/v1/videos'
43
44   return request(url)
45           .get(path)
46           .query({ sort: 'createdAt' })
47           .query({ start: 0 })
48           .query({ count: 10000 })
49           .set('Accept', 'application/json')
50           .expect(200)
51           .expect('Content-Type', /json/)
52 }
53
54 function getVideo (url: string, id: number | string) {
55   const path = '/api/v1/videos/' + id
56
57   return request(url)
58           .get(path)
59           .set('Accept', 'application/json')
60           .expect(200)
61           .expect('Content-Type', /json/)
62 }
63
64 function getVideosList (url: string) {
65   const path = '/api/v1/videos'
66
67   return request(url)
68           .get(path)
69           .query({ sort: 'name' })
70           .set('Accept', 'application/json')
71           .expect(200)
72           .expect('Content-Type', /json/)
73 }
74
75 function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
76   const path = '/api/v1/videos'
77
78   const req = request(url)
79               .get(path)
80               .query({ start: start })
81               .query({ count: count })
82
83   if (sort) req.query({ sort })
84
85   return req.set('Accept', 'application/json')
86            .expect(200)
87            .expect('Content-Type', /json/)
88 }
89
90 function getVideosListSort (url: string, sort: string) {
91   const path = '/api/v1/videos'
92
93   return request(url)
94           .get(path)
95           .query({ sort: sort })
96           .set('Accept', 'application/json')
97           .expect(200)
98           .expect('Content-Type', /json/)
99 }
100
101 function removeVideo (url: string, token: string, id: number, expectedStatus = 204) {
102   const path = '/api/v1/videos'
103
104   return request(url)
105           .delete(path + '/' + id)
106           .set('Accept', 'application/json')
107           .set('Authorization', 'Bearer ' + token)
108           .expect(expectedStatus)
109 }
110
111 function searchVideo (url: string, search: string, field?: string) {
112   const path = '/api/v1/videos'
113   const req = request(url)
114                 .get(path + '/search/' + search)
115                 .set('Accept', 'application/json')
116
117   if (field) req.query({ field })
118
119   return req.expect(200)
120             .expect('Content-Type', /json/)
121 }
122
123 function searchVideoWithPagination (url: string, search: string, field: string, start: number, count: number, sort?: string) {
124   const path = '/api/v1/videos'
125
126   const req = request(url)
127                 .get(path + '/search/' + search)
128                 .query({ start })
129                 .query({ count })
130                 .query({ field })
131
132   if (sort) req.query({ sort })
133
134   return req.set('Accept', 'application/json')
135             .expect(200)
136             .expect('Content-Type', /json/)
137 }
138
139 function searchVideoWithSort (url: string, search: string, sort: string) {
140   const path = '/api/v1/videos'
141
142   return request(url)
143           .get(path + '/search/' + search)
144           .query({ sort })
145           .set('Accept', 'application/json')
146           .expect(200)
147           .expect('Content-Type', /json/)
148 }
149
150 async function testVideoImage (url: string, imageName: string, imagePath: string) {
151   // Don't test images if the node env is not set
152   // Because we need a special ffmpeg version for this test
153   if (process.env['NODE_TEST_IMAGE']) {
154     const res = await request(url)
155                         .get(imagePath)
156                         .expect(200)
157
158     const data = await readFilePromise(join(__dirname, '..', 'api', 'fixtures', imageName + '.jpg'))
159
160     return data.equals(res.body)
161   } else {
162     console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.')
163     return true
164   }
165 }
166
167 async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 204) {
168   const path = '/api/v1/videos/upload'
169   let defaultChannelId = '1'
170
171   try {
172     const res = await getMyUserInformation(url, accessToken)
173     defaultChannelId = res.body.videoChannels[0].id
174   } catch (e) { /* empty */ }
175
176   // Default attributes
177   let attributes = {
178     name: 'my super video',
179     category: 5,
180     licence: 4,
181     language: 3,
182     channelId: defaultChannelId,
183     nsfw: true,
184     description: 'my super description',
185     tags: [ 'tag' ],
186     fixture: 'video_short.webm'
187   }
188   attributes = Object.assign(attributes, videoAttributesArg)
189
190   const req = request(url)
191               .post(path)
192               .set('Accept', 'application/json')
193               .set('Authorization', 'Bearer ' + accessToken)
194               .field('name', attributes.name)
195               .field('category', attributes.category.toString())
196               .field('licence', attributes.licence.toString())
197               .field('nsfw', JSON.stringify(attributes.nsfw))
198               .field('description', attributes.description)
199               .field('channelId', attributes.channelId)
200
201   if (attributes.language !== undefined) {
202     req.field('language', attributes.language.toString())
203   }
204
205   for (let i = 0; i < attributes.tags.length; i++) {
206     req.field('tags[' + i + ']', attributes.tags[i])
207   }
208
209   let filePath = ''
210   if (isAbsolute(attributes.fixture)) {
211     filePath = attributes.fixture
212   } else {
213     filePath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture)
214   }
215
216   return req.attach('videofile', filePath)
217             .expect(specialStatus)
218 }
219
220 function updateVideo (url: string, accessToken: string, id: number, attributes: VideoAttributes, specialStatus = 204) {
221   const path = '/api/v1/videos/' + id
222   const body = {}
223
224   if (attributes.name) body['name'] = attributes.name
225   if (attributes.category) body['category'] = attributes.category
226   if (attributes.licence) body['licence'] = attributes.licence
227   if (attributes.language) body['language'] = attributes.language
228   if (attributes.nsfw) body['nsfw'] = attributes.nsfw
229   if (attributes.description) body['description'] = attributes.description
230   if (attributes.tags) body['tags'] = attributes.tags
231
232   return request(url)
233           .put(path)
234           .send(body)
235           .set('Accept', 'application/json')
236           .set('Authorization', 'Bearer ' + accessToken)
237           .expect(specialStatus)
238 }
239
240 function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) {
241   const path = '/api/v1/videos/' + id + '/rate'
242
243   return request(url)
244           .put(path)
245           .set('Accept', 'application/json')
246           .set('Authorization', 'Bearer ' + accessToken)
247           .send({ rating })
248           .expect(specialStatus)
249 }
250
251 function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
252   return new Promise<any>((res, rej) => {
253     const torrentName = videoUUID + '-' + resolution + '.torrent'
254     const torrentPath = join(__dirname, '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName)
255     readFile(torrentPath, (err, data) => {
256       if (err) return rej(err)
257
258       return res(parseTorrent(data))
259     })
260   })
261 }
262
263 // ---------------------------------------------------------------------------
264
265 export {
266   getVideoCategories,
267   getVideoLicences,
268   getVideoLanguages,
269   getAllVideosListBy,
270   getVideo,
271   getVideosList,
272   getVideosListPagination,
273   getVideosListSort,
274   removeVideo,
275   searchVideo,
276   searchVideoWithPagination,
277   searchVideoWithSort,
278   testVideoImage,
279   uploadVideo,
280   updateVideo,
281   rateVideo,
282   parseTorrentVideo
283 }