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