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