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