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