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