]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/utils.js
Server: fix tests
[github/Chocobozzz/PeerTube.git] / server / tests / api / utils.js
CommitLineData
9f10b292
C
1'use strict'
2
bc503c2a
C
3const childProcess = require('child_process')
4const exec = childProcess.exec
5const fork = childProcess.fork
9e5f3740 6const fs = require('fs')
f0f5567b
C
7const pathUtils = require('path')
8const request = require('supertest')
9f10b292 9
f0f5567b 10const testUtils = {
9bd26629 11 createUser: createUser,
bb10240e 12 dateIsValid: dateIsValid,
9f10b292 13 flushTests: flushTests,
6666aad4 14 getAllVideosListBy: getAllVideosListBy,
677618d4 15 getClient: getClient,
9f10b292 16 getFriendsList: getFriendsList,
99a64bfe 17 getUserInformation: getUserInformation,
9bd26629 18 getUsersList: getUsersList,
2df82d42 19 getVideo: getVideo,
9f10b292 20 getVideosList: getVideosList,
fbf1134e 21 getVideosListPagination: getVideosListPagination,
a877d5ac 22 getVideosListSort: getVideosListSort,
0c1cbbfe
C
23 login: login,
24 loginAndGetAccessToken: loginAndGetAccessToken,
9f10b292
C
25 makeFriends: makeFriends,
26 quitFriends: quitFriends,
9bd26629 27 removeUser: removeUser,
9f10b292
C
28 removeVideo: removeVideo,
29 flushAndRunMultipleServers: flushAndRunMultipleServers,
30 runServer: runServer,
31 searchVideo: searchVideo,
fbf1134e 32 searchVideoWithPagination: searchVideoWithPagination,
a877d5ac 33 searchVideoWithSort: searchVideoWithSort,
9e5f3740 34 testImage: testImage,
9bd26629
C
35 uploadVideo: uploadVideo,
36 updateUser: updateUser
9f10b292
C
37}
38
39// ---------------------- Export functions --------------------
40
9bd26629
C
41function createUser (url, accessToken, username, password, specialStatus, end) {
42 if (!end) {
43 end = specialStatus
44 specialStatus = 204
45 }
46
47 const path = '/api/v1/users'
48
49 request(url)
50 .post(path)
51 .set('Accept', 'application/json')
52 .set('Authorization', 'Bearer ' + accessToken)
53 .send({ username: username, password: password })
54 .expect(specialStatus)
55 .end(end)
56}
57
bb10240e
C
58function dateIsValid (dateString) {
59 const dateToCheck = new Date(dateString)
60 const now = new Date()
61
62 // Check if the interval is more than 2 minutes
63 if (now - dateToCheck > 120000) return false
64
65 return true
66}
67
9f10b292 68function flushTests (callback) {
93534495 69 exec('npm run clean:server:test', callback)
9f10b292
C
70}
71
6666aad4
C
72function getAllVideosListBy (url, end) {
73 const path = '/api/v1/videos'
74
75 request(url)
76 .get(path)
77 .query({ sort: 'createdDate' })
78 .query({ start: 0 })
79 .query({ count: 10000 })
80 .set('Accept', 'application/json')
81 .expect(200)
82 .expect('Content-Type', /json/)
83 .end(end)
84}
85
677618d4
C
86function getClient (url, end) {
87 const path = '/api/v1/users/client'
88
89 request(url)
90 .get(path)
91 .set('Accept', 'application/json')
92 .expect(200)
93 .expect('Content-Type', /json/)
94 .end(end)
99a64bfe
C
95}
96
97function getUserInformation (url, accessToken, end) {
98 const path = '/api/v1/users/me'
99
100 request(url)
101 .get(path)
102 .set('Accept', 'application/json')
103 .set('Authorization', 'Bearer ' + accessToken)
104 .expect(200)
105 .expect('Content-Type', /json/)
106 .end(end)
677618d4
C
107}
108
9bd26629
C
109function getUsersList (url, end) {
110 const path = '/api/v1/users'
111
112 request(url)
113 .get(path)
114 .set('Accept', 'application/json')
115 .expect(200)
116 .expect('Content-Type', /json/)
117 .end(end)
118}
119
9f10b292 120function getFriendsList (url, end) {
f0f5567b 121 const path = '/api/v1/pods/'
9f10b292
C
122
123 request(url)
124 .get(path)
125 .set('Accept', 'application/json')
126 .expect(200)
127 .expect('Content-Type', /json/)
128 .end(end)
129}
130
2df82d42
C
131function getVideo (url, id, end) {
132 const path = '/api/v1/videos/' + id
133
134 request(url)
135 .get(path)
136 .set('Accept', 'application/json')
137 .expect(200)
138 .expect('Content-Type', /json/)
139 .end(end)
140}
141
9f10b292 142function getVideosList (url, end) {
f0f5567b 143 const path = '/api/v1/videos'
9f10b292
C
144
145 request(url)
146 .get(path)
1af470c7 147 .query({ sort: 'name' })
9f10b292
C
148 .set('Accept', 'application/json')
149 .expect(200)
150 .expect('Content-Type', /json/)
151 .end(end)
152}
153
fbf1134e
C
154function getVideosListPagination (url, start, count, end) {
155 const path = '/api/v1/videos'
156
157 request(url)
158 .get(path)
159 .query({ start: start })
160 .query({ count: count })
161 .set('Accept', 'application/json')
162 .expect(200)
163 .expect('Content-Type', /json/)
164 .end(end)
165}
166
a877d5ac
C
167function getVideosListSort (url, sort, end) {
168 const path = '/api/v1/videos'
169
170 request(url)
171 .get(path)
172 .query({ sort: sort })
173 .set('Accept', 'application/json')
174 .expect(200)
175 .expect('Content-Type', /json/)
176 .end(end)
177}
178
bc503c2a 179function login (url, client, user, expectedStatus, end) {
0c1cbbfe 180 if (!end) {
bc503c2a
C
181 end = expectedStatus
182 expectedStatus = 200
0c1cbbfe
C
183 }
184
185 const path = '/api/v1/users/token'
186
187 const body = {
188 client_id: client.id,
189 client_secret: client.secret,
190 username: user.username,
191 password: user.password,
192 response_type: 'code',
193 grant_type: 'password',
194 scope: 'upload'
195 }
196
197 request(url)
198 .post(path)
199 .type('form')
200 .send(body)
bc503c2a 201 .expect(expectedStatus)
0c1cbbfe
C
202 .end(end)
203}
204
205function loginAndGetAccessToken (server, callback) {
206 login(server.url, server.client, server.user, 200, function (err, res) {
207 if (err) return callback(err)
208
209 return callback(null, res.body.access_token)
210 })
211}
212
b3b92647 213function makeFriends (url, accessToken, expectedStatus, callback) {
9f10b292 214 if (!callback) {
bc503c2a
C
215 callback = expectedStatus
216 expectedStatus = 204
ee66c593
C
217 }
218
f0f5567b 219 const path = '/api/v1/pods/makefriends'
ee66c593 220
9f10b292
C
221 // The first pod make friend with the third
222 request(url)
223 .get(path)
224 .set('Accept', 'application/json')
b3b92647 225 .set('Authorization', 'Bearer ' + accessToken)
bc503c2a 226 .expect(expectedStatus)
9f10b292
C
227 .end(function (err, res) {
228 if (err) throw err
45239549 229
9f10b292
C
230 // Wait for the request between pods
231 setTimeout(callback, 1000)
876d1bcf 232 })
9f10b292 233}
876d1bcf 234
b3b92647
C
235function quitFriends (url, accessToken, expectedStatus, callback) {
236 if (!callback) {
237 callback = expectedStatus
238 expectedStatus = 204
239 }
240
f0f5567b 241 const path = '/api/v1/pods/quitfriends'
876d1bcf 242
9f10b292
C
243 // The first pod make friend with the third
244 request(url)
245 .get(path)
246 .set('Accept', 'application/json')
b3b92647
C
247 .set('Authorization', 'Bearer ' + accessToken)
248 .expect(expectedStatus)
9f10b292
C
249 .end(function (err, res) {
250 if (err) throw err
876d1bcf 251
9f10b292
C
252 // Wait for the request between pods
253 setTimeout(callback, 1000)
876d1bcf 254 })
9f10b292
C
255}
256
9bd26629
C
257function removeUser (url, token, username, expectedStatus, end) {
258 if (!end) {
259 end = expectedStatus
260 expectedStatus = 204
261 }
262
263 const path = '/api/v1/users'
264
265 request(url)
266 .delete(path + '/' + username)
267 .set('Accept', 'application/json')
268 .set('Authorization', 'Bearer ' + token)
269 .expect(expectedStatus)
270 .end(end)
271}
272
bc503c2a 273function removeVideo (url, token, id, expectedStatus, end) {
0c1cbbfe 274 if (!end) {
bc503c2a
C
275 end = expectedStatus
276 expectedStatus = 204
0c1cbbfe
C
277 }
278
f0f5567b 279 const path = '/api/v1/videos'
9f10b292
C
280
281 request(url)
282 .delete(path + '/' + id)
283 .set('Accept', 'application/json')
0c1cbbfe 284 .set('Authorization', 'Bearer ' + token)
bc503c2a 285 .expect(expectedStatus)
9f10b292
C
286 .end(end)
287}
288
bc503c2a 289function flushAndRunMultipleServers (totalServers, serversRun) {
f0f5567b
C
290 let apps = []
291 let urls = []
292 let i = 0
9f10b292
C
293
294 function anotherServerDone (number, app, url) {
295 apps[number - 1] = app
296 urls[number - 1] = url
297 i++
bc503c2a 298 if (i === totalServers) {
9f10b292
C
299 serversRun(apps, urls)
300 }
876d1bcf
C
301 }
302
9f10b292 303 flushTests(function () {
bc503c2a 304 for (let j = 1; j <= totalServers; j++) {
f0f5567b
C
305 // For the virtual buffer
306 setTimeout(function () {
307 runServer(j, function (app, url) {
308 anotherServerDone(j, app, url)
309 })
310 }, 1000 * j)
9f10b292
C
311 }
312 })
313}
314
315function runServer (number, callback) {
0c1cbbfe
C
316 const server = {
317 app: null,
318 url: `http://localhost:${9000 + number}`,
319 client: {
320 id: null,
321 secret: null
322 },
323 user: {
324 username: null,
325 password: null
326 }
327 }
328
329 // These actions are async so we need to be sure that they have both been done
bc503c2a 330 const serverRunString = {
9f10b292
C
331 'Connected to mongodb': false,
332 'Server listening on port': false
876d1bcf
C
333 }
334
0c1cbbfe
C
335 const regexps = {
336 client_id: 'Client id: ([a-f0-9]+)',
337 client_secret: 'Client secret: (.+)',
338 user_username: 'Username: (.+)',
339 user_password: 'User password: (.+)'
340 }
341
9f10b292 342 // Share the environment
f0f5567b 343 const env = Object.create(process.env)
9f10b292
C
344 env.NODE_ENV = 'test'
345 env.NODE_APP_INSTANCE = number
f0f5567b 346 const options = {
9f10b292
C
347 silent: true,
348 env: env,
349 detached: true
876d1bcf 350 }
c45f7f84 351
0c1cbbfe
C
352 server.app = fork(pathUtils.join(__dirname, '../../../server.js'), [], options)
353 server.app.stdout.on('data', function onStdout (data) {
bc503c2a 354 let dontContinue = false
0c1cbbfe
C
355
356 // Capture things if we want to
357 for (const key of Object.keys(regexps)) {
358 const regexp = regexps[key]
359 const matches = data.toString().match(regexp)
360 if (matches !== null) {
361 if (key === 'client_id') server.client.id = matches[1]
362 else if (key === 'client_secret') server.client.secret = matches[1]
363 else if (key === 'user_username') server.user.username = matches[1]
364 else if (key === 'user_password') server.user.password = matches[1]
365 }
366 }
367
9f10b292 368 // Check if all required sentences are here
bc503c2a
C
369 for (const key of Object.keys(serverRunString)) {
370 if (data.toString().indexOf(key) !== -1) serverRunString[key] = true
371 if (serverRunString[key] === false) dontContinue = true
9f10b292 372 }
c45f7f84 373
9f10b292 374 // If no, there is maybe one thing not already initialized (mongodb...)
bc503c2a 375 if (dontContinue === true) return
9f10b292 376
0c1cbbfe
C
377 server.app.stdout.removeListener('data', onStdout)
378 callback(server)
9f10b292
C
379 })
380}
381
46246b5f
C
382function searchVideo (url, search, field, end) {
383 if (!end) {
384 end = field
385 field = null
386 }
9f10b292 387
46246b5f
C
388 const path = '/api/v1/videos'
389 const req = request(url)
390 .get(path + '/search/' + search)
391 .set('Accept', 'application/json')
392
393 if (field) req.query({ field: field })
394 req.expect(200)
395 .expect('Content-Type', /json/)
396 .end(end)
fbf1134e
C
397}
398
46246b5f 399function searchVideoWithPagination (url, search, field, start, count, end) {
fbf1134e
C
400 const path = '/api/v1/videos'
401
402 request(url)
403 .get(path + '/search/' + search)
404 .query({ start: start })
405 .query({ count: count })
46246b5f 406 .query({ field: field })
fbf1134e
C
407 .set('Accept', 'application/json')
408 .expect(200)
409 .expect('Content-Type', /json/)
a877d5ac
C
410 .end(end)
411}
412
413function searchVideoWithSort (url, search, sort, end) {
414 const path = '/api/v1/videos'
415
416 request(url)
417 .get(path + '/search/' + search)
418 .query({ sort: sort })
419 .set('Accept', 'application/json')
420 .expect(200)
421 .expect('Content-Type', /json/)
9f10b292
C
422 .end(end)
423}
424
bc503c2a 425function testImage (url, videoName, imagePath, callback) {
2bd3f171
C
426 // Don't test images if the node env is not set
427 // Because we need a special ffmpeg version for this test
428 if (process.env.NODE_TEST_IMAGE) {
429 request(url)
430 .get(imagePath)
431 .expect(200)
432 .end(function (err, res) {
9e5f3740
C
433 if (err) return callback(err)
434
2bd3f171
C
435 fs.readFile(pathUtils.join(__dirname, 'fixtures', videoName + '.jpg'), function (err, data) {
436 if (err) return callback(err)
437
438 callback(null, data.equals(res.body))
439 })
9e5f3740 440 })
2bd3f171
C
441 } else {
442 console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.')
443 callback(null, true)
444 }
9e5f3740
C
445}
446
be587647 447function uploadVideo (url, accessToken, name, description, tags, fixture, specialStatus, end) {
0c1cbbfe 448 if (!end) {
bc503c2a
C
449 end = specialStatus
450 specialStatus = 204
0c1cbbfe
C
451 }
452
f0f5567b 453 const path = '/api/v1/videos'
9f10b292 454
be587647
C
455 const req = request(url)
456 .post(path)
457 .set('Accept', 'application/json')
458 .set('Authorization', 'Bearer ' + accessToken)
459 .field('name', name)
460 .field('description', description)
461
462 for (let i = 0; i < tags.length; i++) {
463 req.field('tags[' + i + ']', tags[i])
464 }
465
677618d4
C
466 let filepath = ''
467 if (pathUtils.isAbsolute(fixture)) {
468 filepath = fixture
469 } else {
470 filepath = pathUtils.join(__dirname, 'fixtures', fixture)
471 }
472
473 req.attach('videofile', filepath)
be587647
C
474 .expect(specialStatus)
475 .end(end)
9f10b292
C
476}
477
9bd26629
C
478function updateUser (url, userId, accessToken, newPassword, end) {
479 const path = '/api/v1/users/' + userId
480
481 request(url)
482 .put(path)
483 .set('Accept', 'application/json')
484 .set('Authorization', 'Bearer ' + accessToken)
485 .send({ password: newPassword })
f3391f92 486 .expect(204)
9bd26629
C
487 .end(end)
488}
489
9f10b292
C
490// ---------------------------------------------------------------------------
491
492module.exports = testUtils