]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/utils.js
Server: allow user to get its informations (/users/me)
[github/Chocobozzz/PeerTube.git] / server / tests / api / utils.js
1 'use strict'
2
3 const childProcess = require('child_process')
4 const exec = childProcess.exec
5 const fork = childProcess.fork
6 const fs = require('fs')
7 const pathUtils = require('path')
8 const request = require('supertest')
9
10 const testUtils = {
11 createUser: createUser,
12 dateIsValid: dateIsValid,
13 flushTests: flushTests,
14 getAllVideosListBy: getAllVideosListBy,
15 getClient: getClient,
16 getFriendsList: getFriendsList,
17 getUserInformation: getUserInformation,
18 getUsersList: getUsersList,
19 getVideo: getVideo,
20 getVideosList: getVideosList,
21 getVideosListPagination: getVideosListPagination,
22 getVideosListSort: getVideosListSort,
23 login: login,
24 loginAndGetAccessToken: loginAndGetAccessToken,
25 makeFriends: makeFriends,
26 quitFriends: quitFriends,
27 removeUser: removeUser,
28 removeVideo: removeVideo,
29 flushAndRunMultipleServers: flushAndRunMultipleServers,
30 runServer: runServer,
31 searchVideo: searchVideo,
32 searchVideoWithPagination: searchVideoWithPagination,
33 searchVideoWithSort: searchVideoWithSort,
34 testImage: testImage,
35 uploadVideo: uploadVideo,
36 updateUser: updateUser
37 }
38
39 // ---------------------- Export functions --------------------
40
41 function 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
58 function 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
68 function flushTests (callback) {
69 exec('npm run clean:server:test', callback)
70 }
71
72 function 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
86 function 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)
95 }
96
97 function 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)
107 }
108
109 function 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
120 function getFriendsList (url, end) {
121 const path = '/api/v1/pods/'
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
131 function 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
142 function getVideosList (url, end) {
143 const path = '/api/v1/videos'
144
145 request(url)
146 .get(path)
147 .query({ sort: 'name' })
148 .set('Accept', 'application/json')
149 .expect(200)
150 .expect('Content-Type', /json/)
151 .end(end)
152 }
153
154 function 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
167 function 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
179 function login (url, client, user, expectedStatus, end) {
180 if (!end) {
181 end = expectedStatus
182 expectedStatus = 200
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)
201 .expect(expectedStatus)
202 .end(end)
203 }
204
205 function 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
213 function makeFriends (url, accessToken, expectedStatus, callback) {
214 if (!callback) {
215 callback = expectedStatus
216 expectedStatus = 204
217 }
218
219 const path = '/api/v1/pods/makefriends'
220
221 // The first pod make friend with the third
222 request(url)
223 .get(path)
224 .set('Accept', 'application/json')
225 .set('Authorization', 'Bearer ' + accessToken)
226 .expect(expectedStatus)
227 .end(function (err, res) {
228 if (err) throw err
229
230 // Wait for the request between pods
231 setTimeout(callback, 1000)
232 })
233 }
234
235 function quitFriends (url, accessToken, expectedStatus, callback) {
236 if (!callback) {
237 callback = expectedStatus
238 expectedStatus = 204
239 }
240
241 const path = '/api/v1/pods/quitfriends'
242
243 // The first pod make friend with the third
244 request(url)
245 .get(path)
246 .set('Accept', 'application/json')
247 .set('Authorization', 'Bearer ' + accessToken)
248 .expect(expectedStatus)
249 .end(function (err, res) {
250 if (err) throw err
251
252 // Wait for the request between pods
253 setTimeout(callback, 1000)
254 })
255 }
256
257 function 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
273 function removeVideo (url, token, id, expectedStatus, end) {
274 if (!end) {
275 end = expectedStatus
276 expectedStatus = 204
277 }
278
279 const path = '/api/v1/videos'
280
281 request(url)
282 .delete(path + '/' + id)
283 .set('Accept', 'application/json')
284 .set('Authorization', 'Bearer ' + token)
285 .expect(expectedStatus)
286 .end(end)
287 }
288
289 function flushAndRunMultipleServers (totalServers, serversRun) {
290 let apps = []
291 let urls = []
292 let i = 0
293
294 function anotherServerDone (number, app, url) {
295 apps[number - 1] = app
296 urls[number - 1] = url
297 i++
298 if (i === totalServers) {
299 serversRun(apps, urls)
300 }
301 }
302
303 flushTests(function () {
304 for (let j = 1; j <= totalServers; j++) {
305 // For the virtual buffer
306 setTimeout(function () {
307 runServer(j, function (app, url) {
308 anotherServerDone(j, app, url)
309 })
310 }, 1000 * j)
311 }
312 })
313 }
314
315 function runServer (number, callback) {
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
330 const serverRunString = {
331 'Connected to mongodb': false,
332 'Server listening on port': false
333 }
334
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
342 // Share the environment
343 const env = Object.create(process.env)
344 env.NODE_ENV = 'test'
345 env.NODE_APP_INSTANCE = number
346 const options = {
347 silent: true,
348 env: env,
349 detached: true
350 }
351
352 server.app = fork(pathUtils.join(__dirname, '../../../server.js'), [], options)
353 server.app.stdout.on('data', function onStdout (data) {
354 let dontContinue = false
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
368 // Check if all required sentences are here
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
372 }
373
374 // If no, there is maybe one thing not already initialized (mongodb...)
375 if (dontContinue === true) return
376
377 server.app.stdout.removeListener('data', onStdout)
378 callback(server)
379 })
380 }
381
382 function searchVideo (url, search, field, end) {
383 if (!end) {
384 end = field
385 field = null
386 }
387
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)
397 }
398
399 function searchVideoWithPagination (url, search, field, start, count, end) {
400 const path = '/api/v1/videos'
401
402 request(url)
403 .get(path + '/search/' + search)
404 .query({ start: start })
405 .query({ count: count })
406 .query({ field: field })
407 .set('Accept', 'application/json')
408 .expect(200)
409 .expect('Content-Type', /json/)
410 .end(end)
411 }
412
413 function 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/)
422 .end(end)
423 }
424
425 function testImage (url, videoName, imagePath, callback) {
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) {
433 if (err) return callback(err)
434
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 })
440 })
441 } else {
442 console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.')
443 callback(null, true)
444 }
445 }
446
447 function uploadVideo (url, accessToken, name, description, tags, fixture, specialStatus, end) {
448 if (!end) {
449 end = specialStatus
450 specialStatus = 204
451 }
452
453 const path = '/api/v1/videos'
454
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
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)
474 .expect(specialStatus)
475 .end(end)
476 }
477
478 function 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 })
486 .expect(200)
487 .end(end)
488 }
489
490 // ---------------------------------------------------------------------------
491
492 module.exports = testUtils