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