]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/utils.js
Add ability to sort videos list
[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
C
12 flushTests: flushTests,
13 getFriendsList: getFriendsList,
2df82d42 14 getVideo: getVideo,
9f10b292 15 getVideosList: getVideosList,
fbf1134e 16 getVideosListPagination: getVideosListPagination,
a877d5ac 17 getVideosListSort: getVideosListSort,
0c1cbbfe
C
18 login: login,
19 loginAndGetAccessToken: loginAndGetAccessToken,
9f10b292
C
20 makeFriends: makeFriends,
21 quitFriends: quitFriends,
22 removeVideo: removeVideo,
23 flushAndRunMultipleServers: flushAndRunMultipleServers,
24 runServer: runServer,
25 searchVideo: searchVideo,
fbf1134e 26 searchVideoWithPagination: searchVideoWithPagination,
a877d5ac 27 searchVideoWithSort: searchVideoWithSort,
9e5f3740 28 testImage: testImage,
9f10b292
C
29 uploadVideo: uploadVideo
30}
31
32// ---------------------- Export functions --------------------
33
bb10240e
C
34function 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
9f10b292 44function flushTests (callback) {
93534495 45 exec('npm run clean:server:test', callback)
9f10b292
C
46}
47
48function getFriendsList (url, end) {
f0f5567b 49 const path = '/api/v1/pods/'
9f10b292
C
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
2df82d42
C
59function 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
9f10b292 70function getVideosList (url, end) {
f0f5567b 71 const path = '/api/v1/videos'
9f10b292
C
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
fbf1134e
C
81function 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
a877d5ac
C
94function 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
bc503c2a 106function login (url, client, user, expectedStatus, end) {
0c1cbbfe 107 if (!end) {
bc503c2a
C
108 end = expectedStatus
109 expectedStatus = 200
0c1cbbfe
C
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)
bc503c2a 128 .expect(expectedStatus)
0c1cbbfe
C
129 .end(end)
130}
131
132function 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
b3b92647 140function makeFriends (url, accessToken, expectedStatus, callback) {
9f10b292 141 if (!callback) {
bc503c2a
C
142 callback = expectedStatus
143 expectedStatus = 204
ee66c593
C
144 }
145
f0f5567b 146 const path = '/api/v1/pods/makefriends'
ee66c593 147
9f10b292
C
148 // The first pod make friend with the third
149 request(url)
150 .get(path)
151 .set('Accept', 'application/json')
b3b92647 152 .set('Authorization', 'Bearer ' + accessToken)
bc503c2a 153 .expect(expectedStatus)
9f10b292
C
154 .end(function (err, res) {
155 if (err) throw err
45239549 156
9f10b292
C
157 // Wait for the request between pods
158 setTimeout(callback, 1000)
876d1bcf 159 })
9f10b292 160}
876d1bcf 161
b3b92647
C
162function quitFriends (url, accessToken, expectedStatus, callback) {
163 if (!callback) {
164 callback = expectedStatus
165 expectedStatus = 204
166 }
167
f0f5567b 168 const path = '/api/v1/pods/quitfriends'
876d1bcf 169
9f10b292
C
170 // The first pod make friend with the third
171 request(url)
172 .get(path)
173 .set('Accept', 'application/json')
b3b92647
C
174 .set('Authorization', 'Bearer ' + accessToken)
175 .expect(expectedStatus)
9f10b292
C
176 .end(function (err, res) {
177 if (err) throw err
876d1bcf 178
9f10b292
C
179 // Wait for the request between pods
180 setTimeout(callback, 1000)
876d1bcf 181 })
9f10b292
C
182}
183
bc503c2a 184function removeVideo (url, token, id, expectedStatus, end) {
0c1cbbfe 185 if (!end) {
bc503c2a
C
186 end = expectedStatus
187 expectedStatus = 204
0c1cbbfe
C
188 }
189
f0f5567b 190 const path = '/api/v1/videos'
9f10b292
C
191
192 request(url)
193 .delete(path + '/' + id)
194 .set('Accept', 'application/json')
0c1cbbfe 195 .set('Authorization', 'Bearer ' + token)
bc503c2a 196 .expect(expectedStatus)
9f10b292
C
197 .end(end)
198}
199
bc503c2a 200function flushAndRunMultipleServers (totalServers, serversRun) {
f0f5567b
C
201 let apps = []
202 let urls = []
203 let i = 0
9f10b292
C
204
205 function anotherServerDone (number, app, url) {
206 apps[number - 1] = app
207 urls[number - 1] = url
208 i++
bc503c2a 209 if (i === totalServers) {
9f10b292
C
210 serversRun(apps, urls)
211 }
876d1bcf
C
212 }
213
9f10b292 214 flushTests(function () {
bc503c2a 215 for (let j = 1; j <= totalServers; j++) {
f0f5567b
C
216 // For the virtual buffer
217 setTimeout(function () {
218 runServer(j, function (app, url) {
219 anotherServerDone(j, app, url)
220 })
221 }, 1000 * j)
9f10b292
C
222 }
223 })
224}
225
226function runServer (number, callback) {
0c1cbbfe
C
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
bc503c2a 241 const serverRunString = {
9f10b292
C
242 'Connected to mongodb': false,
243 'Server listening on port': false
876d1bcf
C
244 }
245
0c1cbbfe
C
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
9f10b292 253 // Share the environment
f0f5567b 254 const env = Object.create(process.env)
9f10b292
C
255 env.NODE_ENV = 'test'
256 env.NODE_APP_INSTANCE = number
f0f5567b 257 const options = {
9f10b292
C
258 silent: true,
259 env: env,
260 detached: true
876d1bcf 261 }
c45f7f84 262
0c1cbbfe
C
263 server.app = fork(pathUtils.join(__dirname, '../../../server.js'), [], options)
264 server.app.stdout.on('data', function onStdout (data) {
bc503c2a 265 let dontContinue = false
0c1cbbfe
C
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
9f10b292 279 // Check if all required sentences are here
bc503c2a
C
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
9f10b292 283 }
c45f7f84 284
9f10b292 285 // If no, there is maybe one thing not already initialized (mongodb...)
bc503c2a 286 if (dontContinue === true) return
9f10b292 287
0c1cbbfe
C
288 server.app.stdout.removeListener('data', onStdout)
289 callback(server)
9f10b292
C
290 })
291}
292
293function searchVideo (url, search, end) {
f0f5567b 294 const path = '/api/v1/videos'
9f10b292
C
295
296 request(url)
297 .get(path + '/search/' + search)
298 .set('Accept', 'application/json')
299 .expect(200)
300 .expect('Content-Type', /json/)
fbf1134e
C
301 .end(end)
302}
303
304function 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/)
a877d5ac
C
314 .end(end)
315}
316
317function 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/)
9f10b292
C
326 .end(end)
327}
328
bc503c2a 329function testImage (url, videoName, imagePath, callback) {
9e5f3740 330 request(url)
bc503c2a 331 .get(imagePath)
9e5f3740
C
332 .expect(200)
333 .end(function (err, res) {
334 if (err) return callback(err)
335
bc503c2a 336 fs.readFile(pathUtils.join(__dirname, 'fixtures', videoName + '.jpg'), function (err, data) {
9e5f3740
C
337 if (err) return callback(err)
338
339 callback(null, data.equals(res.body))
340 })
341 })
342}
343
bc503c2a 344function uploadVideo (url, accessToken, name, description, fixture, specialStatus, end) {
0c1cbbfe 345 if (!end) {
bc503c2a
C
346 end = specialStatus
347 specialStatus = 204
0c1cbbfe
C
348 }
349
f0f5567b 350 const path = '/api/v1/videos'
9f10b292
C
351
352 request(url)
353 .post(path)
354 .set('Accept', 'application/json')
bc503c2a 355 .set('Authorization', 'Bearer ' + accessToken)
9f10b292
C
356 .field('name', name)
357 .field('description', description)
8c9c1942 358 .attach('videofile', pathUtils.join(__dirname, 'fixtures', fixture))
bc503c2a 359 .expect(specialStatus)
9f10b292
C
360 .end(end)
361}
362
363// ---------------------------------------------------------------------------
364
365module.exports = testUtils