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