aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/api/activitypub/cleaner.ts8
-rw-r--r--server/tests/api/check-params/config.ts2
-rw-r--r--server/tests/api/check-params/contact-form.ts13
-rw-r--r--server/tests/api/check-params/index.ts3
-rw-r--r--server/tests/api/check-params/redundancy.ts2
-rw-r--r--server/tests/api/check-params/registrations.ts433
-rw-r--r--server/tests/api/check-params/upload-quota.ts4
-rw-r--r--server/tests/api/check-params/users-admin.ts9
-rw-r--r--server/tests/api/check-params/users-emails.ts119
-rw-r--r--server/tests/api/check-params/users.ts255
-rw-r--r--server/tests/api/live/live-fast-restream.ts17
-rw-r--r--server/tests/api/notifications/index.ts1
-rw-r--r--server/tests/api/notifications/moderation-notifications.ts55
-rw-r--r--server/tests/api/notifications/registrations-notifications.ts88
-rw-r--r--server/tests/api/object-storage/video-static-file-privacy.ts4
-rw-r--r--server/tests/api/server/config-defaults.ts4
-rw-r--r--server/tests/api/server/config.ts9
-rw-r--r--server/tests/api/server/contact-form.ts9
-rw-r--r--server/tests/api/server/email.ts77
-rw-r--r--server/tests/api/server/reverse-proxy.ts8
-rw-r--r--server/tests/api/users/index.ts4
-rw-r--r--server/tests/api/users/oauth.ts192
-rw-r--r--server/tests/api/users/registrations.ts415
-rw-r--r--server/tests/api/users/users-email-verification.ts (renamed from server/tests/api/users/users-verification.ts)39
-rw-r--r--server/tests/api/users/users.ts234
-rw-r--r--server/tests/api/videos/video-channel-syncs.ts3
-rw-r--r--server/tests/api/videos/video-comments.ts33
-rw-r--r--server/tests/api/videos/video-imports.ts2
-rw-r--r--server/tests/api/videos/video-playlists.ts15
-rw-r--r--server/tests/external-plugins/akismet.ts4
-rw-r--r--server/tests/external-plugins/auto-block-videos.ts2
-rw-r--r--server/tests/external-plugins/auto-mute.ts2
-rw-r--r--server/tests/feeds/feeds.ts8
-rw-r--r--server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js12
-rw-r--r--server/tests/fixtures/peertube-plugin-test-four/main.js6
-rw-r--r--server/tests/fixtures/peertube-plugin-test-id-pass-auth-two/main.js13
-rw-r--r--server/tests/fixtures/peertube-plugin-test/main.js34
-rw-r--r--server/tests/helpers/index.ts1
-rw-r--r--server/tests/helpers/version.ts36
-rw-r--r--server/tests/plugins/action-hooks.ts2
-rw-r--r--server/tests/plugins/external-auth.ts42
-rw-r--r--server/tests/plugins/filter-hooks.ts96
-rw-r--r--server/tests/plugins/id-and-pass-auth.ts34
-rw-r--r--server/tests/plugins/plugin-helpers.ts12
-rw-r--r--server/tests/shared/notifications.ts45
-rw-r--r--server/tests/shared/videos.ts2
46 files changed, 1744 insertions, 664 deletions
diff --git a/server/tests/api/activitypub/cleaner.ts b/server/tests/api/activitypub/cleaner.ts
index eb6779123..1c1495022 100644
--- a/server/tests/api/activitypub/cleaner.ts
+++ b/server/tests/api/activitypub/cleaner.ts
@@ -148,7 +148,7 @@ describe('Test AP cleaner', function () {
148 it('Should destroy server 3 internal shares and correctly clean them', async function () { 148 it('Should destroy server 3 internal shares and correctly clean them', async function () {
149 this.timeout(20000) 149 this.timeout(20000)
150 150
151 const preCount = await servers[0].sql.getCount('videoShare') 151 const preCount = await servers[0].sql.getVideoShareCount()
152 expect(preCount).to.equal(6) 152 expect(preCount).to.equal(6)
153 153
154 await servers[2].sql.deleteAll('videoShare') 154 await servers[2].sql.deleteAll('videoShare')
@@ -156,7 +156,7 @@ describe('Test AP cleaner', function () {
156 await waitJobs(servers) 156 await waitJobs(servers)
157 157
158 // Still 6 because we don't have remote shares on local videos 158 // Still 6 because we don't have remote shares on local videos
159 const postCount = await servers[0].sql.getCount('videoShare') 159 const postCount = await servers[0].sql.getVideoShareCount()
160 expect(postCount).to.equal(6) 160 expect(postCount).to.equal(6)
161 }) 161 })
162 162
@@ -185,7 +185,7 @@ describe('Test AP cleaner', function () {
185 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') { 185 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
186 const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` + 186 const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` +
187 `INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${remote} WHERE "accountVideoRate"."url" LIKE '${like}'` 187 `INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${remote} WHERE "accountVideoRate"."url" LIKE '${like}'`
188 const res = await servers[0].sql.selectQuery(query) 188 const res = await servers[0].sql.selectQuery<{ url: string }>(query)
189 189
190 for (const rate of res) { 190 for (const rate of res) {
191 const matcher = new RegExp(`^${ofServerUrl}/accounts/root/dislikes/\\d+${urlSuffix}$`) 191 const matcher = new RegExp(`^${ofServerUrl}/accounts/root/dislikes/\\d+${urlSuffix}$`)
@@ -231,7 +231,7 @@ describe('Test AP cleaner', function () {
231 const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` + 231 const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` +
232 `INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${remote} WHERE "videoComment"."url" LIKE '${like}'` 232 `INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${remote} WHERE "videoComment"."url" LIKE '${like}'`
233 233
234 const res = await servers[0].sql.selectQuery(query) 234 const res = await servers[0].sql.selectQuery<{ url: string, videoUUID: string }>(query)
235 235
236 for (const comment of res) { 236 for (const comment of res) {
237 const matcher = new RegExp(`${ofServerUrl}/videos/watch/${comment.videoUUID}/comments/\\d+${urlSuffix}`) 237 const matcher = new RegExp(`${ofServerUrl}/videos/watch/${comment.videoUUID}/comments/\\d+${urlSuffix}`)
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index 3415625ca..93a3f3eb9 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -79,6 +79,7 @@ describe('Test config API validators', function () {
79 signup: { 79 signup: {
80 enabled: false, 80 enabled: false,
81 limit: 5, 81 limit: 5,
82 requiresApproval: false,
82 requiresEmailVerification: false, 83 requiresEmailVerification: false,
83 minimumAge: 16 84 minimumAge: 16
84 }, 85 },
@@ -313,6 +314,7 @@ describe('Test config API validators', function () {
313 signup: { 314 signup: {
314 enabled: true, 315 enabled: true,
315 limit: 5, 316 limit: 5,
317 requiresApproval: true,
316 requiresEmailVerification: true 318 requiresEmailVerification: true
317 } 319 }
318 } 320 }
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts
index 7968ef802..f0f8819b9 100644
--- a/server/tests/api/check-params/contact-form.ts
+++ b/server/tests/api/check-params/contact-form.ts
@@ -2,7 +2,14 @@
2 2
3import { MockSmtpServer } from '@server/tests/shared' 3import { MockSmtpServer } from '@server/tests/shared'
4import { HttpStatusCode } from '@shared/models' 4import { HttpStatusCode } from '@shared/models'
5import { cleanupTests, ContactFormCommand, createSingleServer, killallServers, PeerTubeServer } from '@shared/server-commands' 5import {
6 cleanupTests,
7 ConfigCommand,
8 ContactFormCommand,
9 createSingleServer,
10 killallServers,
11 PeerTubeServer
12} from '@shared/server-commands'
6 13
7describe('Test contact form API validators', function () { 14describe('Test contact form API validators', function () {
8 let server: PeerTubeServer 15 let server: PeerTubeServer
@@ -38,7 +45,7 @@ describe('Test contact form API validators', function () {
38 await killallServers([ server ]) 45 await killallServers([ server ])
39 46
40 // Contact form is disabled 47 // Contact form is disabled
41 await server.run({ smtp: { hostname: '127.0.0.1', port: emailPort }, contact_form: { enabled: false } }) 48 await server.run({ ...ConfigCommand.getEmailOverrideConfig(emailPort), contact_form: { enabled: false } })
42 await command.send({ ...defaultBody, expectedStatus: HttpStatusCode.CONFLICT_409 }) 49 await command.send({ ...defaultBody, expectedStatus: HttpStatusCode.CONFLICT_409 })
43 }) 50 })
44 51
@@ -48,7 +55,7 @@ describe('Test contact form API validators', function () {
48 await killallServers([ server ]) 55 await killallServers([ server ])
49 56
50 // Email & contact form enabled 57 // Email & contact form enabled
51 await server.run({ smtp: { hostname: '127.0.0.1', port: emailPort } }) 58 await server.run(ConfigCommand.getEmailOverrideConfig(emailPort))
52 59
53 await command.send({ ...defaultBody, fromEmail: 'badEmail', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) 60 await command.send({ ...defaultBody, fromEmail: 'badEmail', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
54 await command.send({ ...defaultBody, fromEmail: 'badEmail@', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) 61 await command.send({ ...defaultBody, fromEmail: 'badEmail@', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
index 961093bb5..ddbcb42f8 100644
--- a/server/tests/api/check-params/index.ts
+++ b/server/tests/api/check-params/index.ts
@@ -15,6 +15,7 @@ import './metrics'
15import './my-user' 15import './my-user'
16import './plugins' 16import './plugins'
17import './redundancy' 17import './redundancy'
18import './registrations'
18import './search' 19import './search'
19import './services' 20import './services'
20import './transcoding' 21import './transcoding'
@@ -23,7 +24,7 @@ import './upload-quota'
23import './user-notifications' 24import './user-notifications'
24import './user-subscriptions' 25import './user-subscriptions'
25import './users-admin' 26import './users-admin'
26import './users' 27import './users-emails'
27import './video-blacklist' 28import './video-blacklist'
28import './video-captions' 29import './video-captions'
29import './video-channel-syncs' 30import './video-channel-syncs'
diff --git a/server/tests/api/check-params/redundancy.ts b/server/tests/api/check-params/redundancy.ts
index 908407b9a..73dfd489d 100644
--- a/server/tests/api/check-params/redundancy.ts
+++ b/server/tests/api/check-params/redundancy.ts
@@ -24,7 +24,7 @@ describe('Test server redundancy API validators', function () {
24 // --------------------------------------------------------------- 24 // ---------------------------------------------------------------
25 25
26 before(async function () { 26 before(async function () {
27 this.timeout(80000) 27 this.timeout(160000)
28 28
29 servers = await createMultipleServers(2) 29 servers = await createMultipleServers(2)
30 30
diff --git a/server/tests/api/check-params/registrations.ts b/server/tests/api/check-params/registrations.ts
new file mode 100644
index 000000000..fe16ebd93
--- /dev/null
+++ b/server/tests/api/check-params/registrations.ts
@@ -0,0 +1,433 @@
1import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
2import { omit } from '@shared/core-utils'
3import { HttpStatusCode, UserRole } from '@shared/models'
4import {
5 cleanupTests,
6 createSingleServer,
7 makePostBodyRequest,
8 PeerTubeServer,
9 setAccessTokensToServers,
10 setDefaultAccountAvatar,
11 setDefaultChannelAvatar
12} from '@shared/server-commands'
13
14describe('Test registrations API validators', function () {
15 let server: PeerTubeServer
16 let userToken: string
17 let moderatorToken: string
18
19 // ---------------------------------------------------------------
20
21 before(async function () {
22 this.timeout(30000)
23
24 server = await createSingleServer(1)
25
26 await setAccessTokensToServers([ server ])
27 await setDefaultAccountAvatar([ server ])
28 await setDefaultChannelAvatar([ server ])
29
30 await server.config.enableSignup(false);
31
32 ({ token: moderatorToken } = await server.users.generate('moderator', UserRole.MODERATOR));
33 ({ token: userToken } = await server.users.generate('user', UserRole.USER))
34 })
35
36 describe('Register', function () {
37 const registrationPath = '/api/v1/users/register'
38 const registrationRequestPath = '/api/v1/users/registrations/request'
39
40 const baseCorrectParams = {
41 username: 'user3',
42 displayName: 'super user',
43 email: 'test3@example.com',
44 password: 'my super password',
45 registrationReason: 'my super registration reason'
46 }
47
48 describe('When registering a new user or requesting user registration', function () {
49
50 async function check (fields: any, expectedStatus = HttpStatusCode.BAD_REQUEST_400) {
51 await server.config.enableSignup(false)
52 await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus })
53
54 await server.config.enableSignup(true)
55 await makePostBodyRequest({ url: server.url, path: registrationRequestPath, fields, expectedStatus })
56 }
57
58 it('Should fail with a too small username', async function () {
59 const fields = { ...baseCorrectParams, username: '' }
60
61 await check(fields)
62 })
63
64 it('Should fail with a too long username', async function () {
65 const fields = { ...baseCorrectParams, username: 'super'.repeat(50) }
66
67 await check(fields)
68 })
69
70 it('Should fail with an incorrect username', async function () {
71 const fields = { ...baseCorrectParams, username: 'my username' }
72
73 await check(fields)
74 })
75
76 it('Should fail with a missing email', async function () {
77 const fields = omit(baseCorrectParams, [ 'email' ])
78
79 await check(fields)
80 })
81
82 it('Should fail with an invalid email', async function () {
83 const fields = { ...baseCorrectParams, email: 'test_example.com' }
84
85 await check(fields)
86 })
87
88 it('Should fail with a too small password', async function () {
89 const fields = { ...baseCorrectParams, password: 'bla' }
90
91 await check(fields)
92 })
93
94 it('Should fail with a too long password', async function () {
95 const fields = { ...baseCorrectParams, password: 'super'.repeat(61) }
96
97 await check(fields)
98 })
99
100 it('Should fail if we register a user with the same username', async function () {
101 const fields = { ...baseCorrectParams, username: 'root' }
102
103 await check(fields, HttpStatusCode.CONFLICT_409)
104 })
105
106 it('Should fail with a "peertube" username', async function () {
107 const fields = { ...baseCorrectParams, username: 'peertube' }
108
109 await check(fields, HttpStatusCode.CONFLICT_409)
110 })
111
112 it('Should fail if we register a user with the same email', async function () {
113 const fields = { ...baseCorrectParams, email: 'admin' + server.internalServerNumber + '@example.com' }
114
115 await check(fields, HttpStatusCode.CONFLICT_409)
116 })
117
118 it('Should fail with a bad display name', async function () {
119 const fields = { ...baseCorrectParams, displayName: 'a'.repeat(150) }
120
121 await check(fields)
122 })
123
124 it('Should fail with a bad channel name', async function () {
125 const fields = { ...baseCorrectParams, channel: { name: '[]azf', displayName: 'toto' } }
126
127 await check(fields)
128 })
129
130 it('Should fail with a bad channel display name', async function () {
131 const fields = { ...baseCorrectParams, channel: { name: 'toto', displayName: '' } }
132
133 await check(fields)
134 })
135
136 it('Should fail with a channel name that is the same as username', async function () {
137 const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
138 const fields = { ...baseCorrectParams, ...source }
139
140 await check(fields)
141 })
142
143 it('Should fail with an existing channel', async function () {
144 const attributes = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
145 await server.channels.create({ attributes })
146
147 const fields = { ...baseCorrectParams, channel: { name: 'existing_channel', displayName: 'toto' } }
148
149 await check(fields, HttpStatusCode.CONFLICT_409)
150 })
151
152 it('Should fail on a server with registration disabled', async function () {
153 this.timeout(60000)
154
155 await server.config.updateExistingSubConfig({
156 newConfig: {
157 signup: {
158 enabled: false
159 }
160 }
161 })
162
163 await server.registrations.register({ username: 'user4', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
164 await server.registrations.requestRegistration({
165 username: 'user4',
166 registrationReason: 'reason',
167 expectedStatus: HttpStatusCode.FORBIDDEN_403
168 })
169 })
170
171 it('Should fail if the user limit is reached', async function () {
172 this.timeout(60000)
173
174 const { total } = await server.users.list()
175
176 await server.config.enableSignup(false, total)
177 await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
178
179 await server.config.enableSignup(true, total)
180 await server.registrations.requestRegistration({
181 username: 'user42',
182 registrationReason: 'reason',
183 expectedStatus: HttpStatusCode.FORBIDDEN_403
184 })
185 })
186
187 it('Should succeed if the user limit is not reached', async function () {
188 this.timeout(60000)
189
190 const { total } = await server.users.list()
191
192 await server.config.enableSignup(false, total + 1)
193 await server.registrations.register({ username: 'user43', expectedStatus: HttpStatusCode.NO_CONTENT_204 })
194
195 await server.config.enableSignup(true, total + 2)
196 await server.registrations.requestRegistration({
197 username: 'user44',
198 registrationReason: 'reason',
199 expectedStatus: HttpStatusCode.OK_200
200 })
201 })
202 })
203
204 describe('On direct registration', function () {
205
206 it('Should succeed with the correct params', async function () {
207 await server.config.enableSignup(false)
208
209 const fields = {
210 username: 'user_direct_1',
211 displayName: 'super user direct 1',
212 email: 'user_direct_1@example.com',
213 password: 'my super password',
214 channel: { name: 'super_user_direct_1_channel', displayName: 'super user direct 1 channel' }
215 }
216
217 await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
218 })
219
220 it('Should fail if the instance requires approval', async function () {
221 this.timeout(60000)
222
223 await server.config.enableSignup(true)
224 await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
225 })
226 })
227
228 describe('On registration request', function () {
229
230 before(async function () {
231 this.timeout(60000)
232
233 await server.config.enableSignup(true)
234 })
235
236 it('Should fail with an invalid registration reason', async function () {
237 for (const registrationReason of [ '', 't', 't'.repeat(5000) ]) {
238 await server.registrations.requestRegistration({
239 username: 'user_request_1',
240 registrationReason,
241 expectedStatus: HttpStatusCode.BAD_REQUEST_400
242 })
243 }
244 })
245
246 it('Should succeed with the correct params', async function () {
247 await server.registrations.requestRegistration({
248 username: 'user_request_2',
249 registrationReason: 'tt',
250 channel: {
251 displayName: 'my user request 2 channel',
252 name: 'user_request_2_channel'
253 }
254 })
255 })
256
257 it('Should fail if the user is already awaiting registration approval', async function () {
258 await server.registrations.requestRegistration({
259 username: 'user_request_2',
260 registrationReason: 'tt',
261 channel: {
262 displayName: 'my user request 42 channel',
263 name: 'user_request_42_channel'
264 },
265 expectedStatus: HttpStatusCode.CONFLICT_409
266 })
267 })
268
269 it('Should fail if the channel is already awaiting registration approval', async function () {
270 await server.registrations.requestRegistration({
271 username: 'user42',
272 registrationReason: 'tt',
273 channel: {
274 displayName: 'my user request 2 channel',
275 name: 'user_request_2_channel'
276 },
277 expectedStatus: HttpStatusCode.CONFLICT_409
278 })
279 })
280
281 it('Should fail if the instance does not require approval', async function () {
282 this.timeout(60000)
283
284 await server.config.enableSignup(false)
285
286 await server.registrations.requestRegistration({
287 username: 'user42',
288 registrationReason: 'toto',
289 expectedStatus: HttpStatusCode.BAD_REQUEST_400
290 })
291 })
292 })
293 })
294
295 describe('Registrations accept/reject', function () {
296 let id1: number
297 let id2: number
298
299 before(async function () {
300 this.timeout(60000)
301
302 await server.config.enableSignup(true);
303
304 ({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_2', registrationReason: 'toto' }));
305 ({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_3', registrationReason: 'toto' }))
306 })
307
308 it('Should fail to accept/reject registration without token', async function () {
309 const options = { id: id1, moderationResponse: 'tt', token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }
310 await server.registrations.accept(options)
311 await server.registrations.reject(options)
312 })
313
314 it('Should fail to accept/reject registration with a non moderator user', async function () {
315 const options = { id: id1, moderationResponse: 'tt', token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }
316 await server.registrations.accept(options)
317 await server.registrations.reject(options)
318 })
319
320 it('Should fail to accept/reject registration with a bad registration id', async function () {
321 {
322 const options = { id: 't' as any, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
323 await server.registrations.accept(options)
324 await server.registrations.reject(options)
325 }
326
327 {
328 const options = { id: 42, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }
329 await server.registrations.accept(options)
330 await server.registrations.reject(options)
331 }
332 })
333
334 it('Should fail to accept/reject registration with a bad moderation resposne', async function () {
335 for (const moderationResponse of [ '', 't', 't'.repeat(5000) ]) {
336 const options = { id: id1, moderationResponse, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
337 await server.registrations.accept(options)
338 await server.registrations.reject(options)
339 }
340 })
341
342 it('Should succeed to accept a registration', async function () {
343 await server.registrations.accept({ id: id1, moderationResponse: 'tt', token: moderatorToken })
344 })
345
346 it('Should succeed to reject a registration', async function () {
347 await server.registrations.reject({ id: id2, moderationResponse: 'tt', token: moderatorToken })
348 })
349
350 it('Should fail to accept/reject a registration that was already accepted/rejected', async function () {
351 for (const id of [ id1, id2 ]) {
352 const options = { id, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.CONFLICT_409 }
353 await server.registrations.accept(options)
354 await server.registrations.reject(options)
355 }
356 })
357 })
358
359 describe('Registrations deletion', function () {
360 let id1: number
361 let id2: number
362 let id3: number
363
364 before(async function () {
365 ({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_4', registrationReason: 'toto' }));
366 ({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_5', registrationReason: 'toto' }));
367 ({ id: id3 } = await server.registrations.requestRegistration({ username: 'request_6', registrationReason: 'toto' }))
368
369 await server.registrations.accept({ id: id2, moderationResponse: 'tt' })
370 await server.registrations.reject({ id: id3, moderationResponse: 'tt' })
371 })
372
373 it('Should fail to delete registration without token', async function () {
374 await server.registrations.delete({ id: id1, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
375 })
376
377 it('Should fail to delete registration with a non moderator user', async function () {
378 await server.registrations.delete({ id: id1, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
379 })
380
381 it('Should fail to delete registration with a bad registration id', async function () {
382 await server.registrations.delete({ id: 't' as any, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
383 await server.registrations.delete({ id: 42, token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
384 })
385
386 it('Should succeed with the correct params', async function () {
387 await server.registrations.delete({ id: id1, token: moderatorToken })
388 await server.registrations.delete({ id: id2, token: moderatorToken })
389 await server.registrations.delete({ id: id3, token: moderatorToken })
390 })
391 })
392
393 describe('Listing registrations', function () {
394 const path = '/api/v1/users/registrations'
395
396 it('Should fail with a bad start pagination', async function () {
397 await checkBadStartPagination(server.url, path, server.accessToken)
398 })
399
400 it('Should fail with a bad count pagination', async function () {
401 await checkBadCountPagination(server.url, path, server.accessToken)
402 })
403
404 it('Should fail with an incorrect sort', async function () {
405 await checkBadSortPagination(server.url, path, server.accessToken)
406 })
407
408 it('Should fail with a non authenticated user', async function () {
409 await server.registrations.list({
410 token: null,
411 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
412 })
413 })
414
415 it('Should fail with a non admin user', async function () {
416 await server.registrations.list({
417 token: userToken,
418 expectedStatus: HttpStatusCode.FORBIDDEN_403
419 })
420 })
421
422 it('Should succeed with the correct params', async function () {
423 await server.registrations.list({
424 token: moderatorToken,
425 search: 'toto'
426 })
427 })
428 })
429
430 after(async function () {
431 await cleanupTests([ server ])
432 })
433})
diff --git a/server/tests/api/check-params/upload-quota.ts b/server/tests/api/check-params/upload-quota.ts
index 70e6f4af9..fdc711bd5 100644
--- a/server/tests/api/check-params/upload-quota.ts
+++ b/server/tests/api/check-params/upload-quota.ts
@@ -42,7 +42,7 @@ describe('Test upload quota', function () {
42 this.timeout(30000) 42 this.timeout(30000)
43 43
44 const user = { username: 'registered' + randomInt(1, 1500), password: 'password' } 44 const user = { username: 'registered' + randomInt(1, 1500), password: 'password' }
45 await server.users.register(user) 45 await server.registrations.register(user)
46 const userToken = await server.login.getAccessToken(user) 46 const userToken = await server.login.getAccessToken(user)
47 47
48 const attributes = { fixture: 'video_short2.webm' } 48 const attributes = { fixture: 'video_short2.webm' }
@@ -57,7 +57,7 @@ describe('Test upload quota', function () {
57 this.timeout(30000) 57 this.timeout(30000)
58 58
59 const user = { username: 'registered' + randomInt(1, 1500), password: 'password' } 59 const user = { username: 'registered' + randomInt(1, 1500), password: 'password' }
60 await server.users.register(user) 60 await server.registrations.register(user)
61 const userToken = await server.login.getAccessToken(user) 61 const userToken = await server.login.getAccessToken(user)
62 62
63 const attributes = { fixture: 'video_short2.webm' } 63 const attributes = { fixture: 'video_short2.webm' }
diff --git a/server/tests/api/check-params/users-admin.ts b/server/tests/api/check-params/users-admin.ts
index 7ba709c4a..be2496bb4 100644
--- a/server/tests/api/check-params/users-admin.ts
+++ b/server/tests/api/check-params/users-admin.ts
@@ -5,6 +5,7 @@ import { omit } from '@shared/core-utils'
5import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models' 5import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models'
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 ConfigCommand,
8 createSingleServer, 9 createSingleServer,
9 killallServers, 10 killallServers,
10 makeGetRequest, 11 makeGetRequest,
@@ -156,13 +157,7 @@ describe('Test users admin API validators', function () {
156 157
157 await killallServers([ server ]) 158 await killallServers([ server ])
158 159
159 const config = { 160 await server.run(ConfigCommand.getEmailOverrideConfig(emailPort))
160 smtp: {
161 hostname: '127.0.0.1',
162 port: emailPort
163 }
164 }
165 await server.run(config)
166 161
167 const fields = { 162 const fields = {
168 ...baseCorrectParams, 163 ...baseCorrectParams,
diff --git a/server/tests/api/check-params/users-emails.ts b/server/tests/api/check-params/users-emails.ts
new file mode 100644
index 000000000..8cfb1d15f
--- /dev/null
+++ b/server/tests/api/check-params/users-emails.ts
@@ -0,0 +1,119 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2import { MockSmtpServer } from '@server/tests/shared'
3import { HttpStatusCode, UserRole } from '@shared/models'
4import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
5
6describe('Test users API validators', function () {
7 let server: PeerTubeServer
8
9 // ---------------------------------------------------------------
10
11 before(async function () {
12 this.timeout(30000)
13
14 server = await createSingleServer(1, {
15 rates_limit: {
16 ask_send_email: {
17 max: 10
18 }
19 }
20 })
21
22 await setAccessTokensToServers([ server ])
23 await server.config.enableSignup(true)
24
25 await server.users.generate('moderator2', UserRole.MODERATOR)
26
27 await server.registrations.requestRegistration({
28 username: 'request1',
29 registrationReason: 'tt'
30 })
31 })
32
33 describe('When asking a password reset', function () {
34 const path = '/api/v1/users/ask-reset-password'
35
36 it('Should fail with a missing email', async function () {
37 const fields = {}
38
39 await makePostBodyRequest({ url: server.url, path, fields })
40 })
41
42 it('Should fail with an invalid email', async function () {
43 const fields = { email: 'hello' }
44
45 await makePostBodyRequest({ url: server.url, path, fields })
46 })
47
48 it('Should success with the correct params', async function () {
49 const fields = { email: 'admin@example.com' }
50
51 await makePostBodyRequest({
52 url: server.url,
53 path,
54 fields,
55 expectedStatus: HttpStatusCode.NO_CONTENT_204
56 })
57 })
58 })
59
60 describe('When asking for an account verification email', function () {
61 const path = '/api/v1/users/ask-send-verify-email'
62
63 it('Should fail with a missing email', async function () {
64 const fields = {}
65
66 await makePostBodyRequest({ url: server.url, path, fields })
67 })
68
69 it('Should fail with an invalid email', async function () {
70 const fields = { email: 'hello' }
71
72 await makePostBodyRequest({ url: server.url, path, fields })
73 })
74
75 it('Should succeed with the correct params', async function () {
76 const fields = { email: 'admin@example.com' }
77
78 await makePostBodyRequest({
79 url: server.url,
80 path,
81 fields,
82 expectedStatus: HttpStatusCode.NO_CONTENT_204
83 })
84 })
85 })
86
87 describe('When asking for a registration verification email', function () {
88 const path = '/api/v1/users/registrations/ask-send-verify-email'
89
90 it('Should fail with a missing email', async function () {
91 const fields = {}
92
93 await makePostBodyRequest({ url: server.url, path, fields })
94 })
95
96 it('Should fail with an invalid email', async function () {
97 const fields = { email: 'hello' }
98
99 await makePostBodyRequest({ url: server.url, path, fields })
100 })
101
102 it('Should succeed with the correct params', async function () {
103 const fields = { email: 'request1@example.com' }
104
105 await makePostBodyRequest({
106 url: server.url,
107 path,
108 fields,
109 expectedStatus: HttpStatusCode.NO_CONTENT_204
110 })
111 })
112 })
113
114 after(async function () {
115 MockSmtpServer.Instance.kill()
116
117 await cleanupTests([ server ])
118 })
119})
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
deleted file mode 100644
index 7acfd8c2c..000000000
--- a/server/tests/api/check-params/users.ts
+++ /dev/null
@@ -1,255 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2import { MockSmtpServer } from '@server/tests/shared'
3import { omit } from '@shared/core-utils'
4import { HttpStatusCode, UserRole } from '@shared/models'
5import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
6
7describe('Test users API validators', function () {
8 const path = '/api/v1/users/'
9 let server: PeerTubeServer
10 let serverWithRegistrationDisabled: PeerTubeServer
11
12 // ---------------------------------------------------------------
13
14 before(async function () {
15 this.timeout(30000)
16
17 const res = await Promise.all([
18 createSingleServer(1, { signup: { limit: 3 } }),
19 createSingleServer(2)
20 ])
21
22 server = res[0]
23 serverWithRegistrationDisabled = res[1]
24
25 await setAccessTokensToServers([ server ])
26
27 await server.users.generate('moderator2', UserRole.MODERATOR)
28 })
29
30 describe('When registering a new user', function () {
31 const registrationPath = path + '/register'
32 const baseCorrectParams = {
33 username: 'user3',
34 displayName: 'super user',
35 email: 'test3@example.com',
36 password: 'my super password'
37 }
38
39 it('Should fail with a too small username', async function () {
40 const fields = { ...baseCorrectParams, username: '' }
41
42 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
43 })
44
45 it('Should fail with a too long username', async function () {
46 const fields = { ...baseCorrectParams, username: 'super'.repeat(50) }
47
48 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
49 })
50
51 it('Should fail with an incorrect username', async function () {
52 const fields = { ...baseCorrectParams, username: 'my username' }
53
54 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
55 })
56
57 it('Should fail with a missing email', async function () {
58 const fields = omit(baseCorrectParams, [ 'email' ])
59
60 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
61 })
62
63 it('Should fail with an invalid email', async function () {
64 const fields = { ...baseCorrectParams, email: 'test_example.com' }
65
66 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
67 })
68
69 it('Should fail with a too small password', async function () {
70 const fields = { ...baseCorrectParams, password: 'bla' }
71
72 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
73 })
74
75 it('Should fail with a too long password', async function () {
76 const fields = { ...baseCorrectParams, password: 'super'.repeat(61) }
77
78 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
79 })
80
81 it('Should fail if we register a user with the same username', async function () {
82 const fields = { ...baseCorrectParams, username: 'root' }
83
84 await makePostBodyRequest({
85 url: server.url,
86 path: registrationPath,
87 token: server.accessToken,
88 fields,
89 expectedStatus: HttpStatusCode.CONFLICT_409
90 })
91 })
92
93 it('Should fail with a "peertube" username', async function () {
94 const fields = { ...baseCorrectParams, username: 'peertube' }
95
96 await makePostBodyRequest({
97 url: server.url,
98 path: registrationPath,
99 token: server.accessToken,
100 fields,
101 expectedStatus: HttpStatusCode.CONFLICT_409
102 })
103 })
104
105 it('Should fail if we register a user with the same email', async function () {
106 const fields = { ...baseCorrectParams, email: 'admin' + server.internalServerNumber + '@example.com' }
107
108 await makePostBodyRequest({
109 url: server.url,
110 path: registrationPath,
111 token: server.accessToken,
112 fields,
113 expectedStatus: HttpStatusCode.CONFLICT_409
114 })
115 })
116
117 it('Should fail with a bad display name', async function () {
118 const fields = { ...baseCorrectParams, displayName: 'a'.repeat(150) }
119
120 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
121 })
122
123 it('Should fail with a bad channel name', async function () {
124 const fields = { ...baseCorrectParams, channel: { name: '[]azf', displayName: 'toto' } }
125
126 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
127 })
128
129 it('Should fail with a bad channel display name', async function () {
130 const fields = { ...baseCorrectParams, channel: { name: 'toto', displayName: '' } }
131
132 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
133 })
134
135 it('Should fail with a channel name that is the same as username', async function () {
136 const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
137 const fields = { ...baseCorrectParams, ...source }
138
139 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
140 })
141
142 it('Should fail with an existing channel', async function () {
143 const attributes = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
144 await server.channels.create({ attributes })
145
146 const fields = { ...baseCorrectParams, channel: { name: 'existing_channel', displayName: 'toto' } }
147
148 await makePostBodyRequest({
149 url: server.url,
150 path: registrationPath,
151 token: server.accessToken,
152 fields,
153 expectedStatus: HttpStatusCode.CONFLICT_409
154 })
155 })
156
157 it('Should succeed with the correct params', async function () {
158 const fields = { ...baseCorrectParams, channel: { name: 'super_channel', displayName: 'toto' } }
159
160 await makePostBodyRequest({
161 url: server.url,
162 path: registrationPath,
163 token: server.accessToken,
164 fields,
165 expectedStatus: HttpStatusCode.NO_CONTENT_204
166 })
167 })
168
169 it('Should fail on a server with registration disabled', async function () {
170 const fields = {
171 username: 'user4',
172 email: 'test4@example.com',
173 password: 'my super password 4'
174 }
175
176 await makePostBodyRequest({
177 url: serverWithRegistrationDisabled.url,
178 path: registrationPath,
179 token: serverWithRegistrationDisabled.accessToken,
180 fields,
181 expectedStatus: HttpStatusCode.FORBIDDEN_403
182 })
183 })
184 })
185
186 describe('When registering multiple users on a server with users limit', function () {
187
188 it('Should fail when after 3 registrations', async function () {
189 await server.users.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
190 })
191
192 })
193
194 describe('When asking a password reset', function () {
195 const path = '/api/v1/users/ask-reset-password'
196
197 it('Should fail with a missing email', async function () {
198 const fields = {}
199
200 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
201 })
202
203 it('Should fail with an invalid email', async function () {
204 const fields = { email: 'hello' }
205
206 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
207 })
208
209 it('Should success with the correct params', async function () {
210 const fields = { email: 'admin@example.com' }
211
212 await makePostBodyRequest({
213 url: server.url,
214 path,
215 token: server.accessToken,
216 fields,
217 expectedStatus: HttpStatusCode.NO_CONTENT_204
218 })
219 })
220 })
221
222 describe('When asking for an account verification email', function () {
223 const path = '/api/v1/users/ask-send-verify-email'
224
225 it('Should fail with a missing email', async function () {
226 const fields = {}
227
228 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
229 })
230
231 it('Should fail with an invalid email', async function () {
232 const fields = { email: 'hello' }
233
234 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
235 })
236
237 it('Should succeed with the correct params', async function () {
238 const fields = { email: 'admin@example.com' }
239
240 await makePostBodyRequest({
241 url: server.url,
242 path,
243 token: server.accessToken,
244 fields,
245 expectedStatus: HttpStatusCode.NO_CONTENT_204
246 })
247 })
248 })
249
250 after(async function () {
251 MockSmtpServer.Instance.kill()
252
253 await cleanupTests([ server, serverWithRegistrationDisabled ])
254 })
255})
diff --git a/server/tests/api/live/live-fast-restream.ts b/server/tests/api/live/live-fast-restream.ts
index c0bb8d529..9e6d10dbd 100644
--- a/server/tests/api/live/live-fast-restream.ts
+++ b/server/tests/api/live/live-fast-restream.ts
@@ -78,9 +78,15 @@ describe('Fast restream in live', function () {
78 const video = await server.videos.get({ id: liveId }) 78 const video = await server.videos.get({ id: liveId })
79 expect(video.streamingPlaylists).to.have.lengthOf(1) 79 expect(video.streamingPlaylists).to.have.lengthOf(1)
80 80
81 await server.live.getSegmentFile({ videoUUID: liveId, segment: 0, playlistNumber: 0 }) 81 try {
82 await makeRawRequest({ url: video.streamingPlaylists[0].playlistUrl, expectedStatus: HttpStatusCode.OK_200 }) 82 await server.live.getSegmentFile({ videoUUID: liveId, segment: 0, playlistNumber: 0 })
83 await makeRawRequest({ url: video.streamingPlaylists[0].segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 }) 83 await makeRawRequest({ url: video.streamingPlaylists[0].playlistUrl, expectedStatus: HttpStatusCode.OK_200 })
84 await makeRawRequest({ url: video.streamingPlaylists[0].segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 })
85 } catch (err) {
86 // FIXME: try to debug error in CI "Unexpected end of JSON input"
87 console.error(err)
88 throw err
89 }
84 90
85 await wait(100) 91 await wait(100)
86 } 92 }
@@ -89,6 +95,9 @@ describe('Fast restream in live', function () {
89 async function runTest (replay: boolean) { 95 async function runTest (replay: boolean) {
90 const { ffmpegCommand, liveVideoUUID } = await fastRestreamWrapper({ replay }) 96 const { ffmpegCommand, liveVideoUUID } = await fastRestreamWrapper({ replay })
91 97
98 // TODO: remove, we try to debug a test timeout failure here
99 console.log('Ensuring last live works')
100
92 await ensureLastLiveWorks(liveVideoUUID) 101 await ensureLastLiveWorks(liveVideoUUID)
93 102
94 await stopFfmpeg(ffmpegCommand) 103 await stopFfmpeg(ffmpegCommand)
@@ -129,7 +138,7 @@ describe('Fast restream in live', function () {
129 await server.config.enableLive({ allowReplay: true, transcoding: true, resolutions: 'min' }) 138 await server.config.enableLive({ allowReplay: true, transcoding: true, resolutions: 'min' })
130 }) 139 })
131 140
132 it('Should correctly fast reastream in a permanent live with and without save replay', async function () { 141 it('Should correctly fast restream in a permanent live with and without save replay', async function () {
133 this.timeout(480000) 142 this.timeout(480000)
134 143
135 // A test can take a long time, so prefer to run them in parallel 144 // A test can take a long time, so prefer to run them in parallel
diff --git a/server/tests/api/notifications/index.ts b/server/tests/api/notifications/index.ts
index 8caa30a3d..c0216b74f 100644
--- a/server/tests/api/notifications/index.ts
+++ b/server/tests/api/notifications/index.ts
@@ -2,4 +2,5 @@ import './admin-notifications'
2import './comments-notifications' 2import './comments-notifications'
3import './moderation-notifications' 3import './moderation-notifications'
4import './notifications-api' 4import './notifications-api'
5import './registrations-notifications'
5import './user-notifications' 6import './user-notifications'
diff --git a/server/tests/api/notifications/moderation-notifications.ts b/server/tests/api/notifications/moderation-notifications.ts
index b127a7a31..bb11a08aa 100644
--- a/server/tests/api/notifications/moderation-notifications.ts
+++ b/server/tests/api/notifications/moderation-notifications.ts
@@ -11,7 +11,6 @@ import {
11 checkNewInstanceFollower, 11 checkNewInstanceFollower,
12 checkNewVideoAbuseForModerators, 12 checkNewVideoAbuseForModerators,
13 checkNewVideoFromSubscription, 13 checkNewVideoFromSubscription,
14 checkUserRegistered,
15 checkVideoAutoBlacklistForModerators, 14 checkVideoAutoBlacklistForModerators,
16 checkVideoIsPublished, 15 checkVideoIsPublished,
17 MockInstancesIndex, 16 MockInstancesIndex,
@@ -34,7 +33,7 @@ describe('Test moderation notifications', function () {
34 let emails: object[] = [] 33 let emails: object[] = []
35 34
36 before(async function () { 35 before(async function () {
37 this.timeout(120000) 36 this.timeout(50000)
38 37
39 const res = await prepareNotificationsTest(3) 38 const res = await prepareNotificationsTest(3)
40 emails = res.emails 39 emails = res.emails
@@ -60,7 +59,7 @@ describe('Test moderation notifications', function () {
60 }) 59 })
61 60
62 it('Should not send a notification to moderators on local abuse reported by an admin', async function () { 61 it('Should not send a notification to moderators on local abuse reported by an admin', async function () {
63 this.timeout(20000) 62 this.timeout(50000)
64 63
65 const name = 'video for abuse ' + buildUUID() 64 const name = 'video for abuse ' + buildUUID()
66 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } }) 65 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
@@ -72,7 +71,7 @@ describe('Test moderation notifications', function () {
72 }) 71 })
73 72
74 it('Should send a notification to moderators on local video abuse', async function () { 73 it('Should send a notification to moderators on local video abuse', async function () {
75 this.timeout(20000) 74 this.timeout(50000)
76 75
77 const name = 'video for abuse ' + buildUUID() 76 const name = 'video for abuse ' + buildUUID()
78 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } }) 77 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
@@ -84,7 +83,7 @@ describe('Test moderation notifications', function () {
84 }) 83 })
85 84
86 it('Should send a notification to moderators on remote video abuse', async function () { 85 it('Should send a notification to moderators on remote video abuse', async function () {
87 this.timeout(20000) 86 this.timeout(50000)
88 87
89 const name = 'video for abuse ' + buildUUID() 88 const name = 'video for abuse ' + buildUUID()
90 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } }) 89 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
@@ -99,7 +98,7 @@ describe('Test moderation notifications', function () {
99 }) 98 })
100 99
101 it('Should send a notification to moderators on local comment abuse', async function () { 100 it('Should send a notification to moderators on local comment abuse', async function () {
102 this.timeout(20000) 101 this.timeout(50000)
103 102
104 const name = 'video for abuse ' + buildUUID() 103 const name = 'video for abuse ' + buildUUID()
105 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } }) 104 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
@@ -118,7 +117,7 @@ describe('Test moderation notifications', function () {
118 }) 117 })
119 118
120 it('Should send a notification to moderators on remote comment abuse', async function () { 119 it('Should send a notification to moderators on remote comment abuse', async function () {
121 this.timeout(20000) 120 this.timeout(50000)
122 121
123 const name = 'video for abuse ' + buildUUID() 122 const name = 'video for abuse ' + buildUUID()
124 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } }) 123 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
@@ -140,7 +139,7 @@ describe('Test moderation notifications', function () {
140 }) 139 })
141 140
142 it('Should send a notification to moderators on local account abuse', async function () { 141 it('Should send a notification to moderators on local account abuse', async function () {
143 this.timeout(20000) 142 this.timeout(50000)
144 143
145 const username = 'user' + new Date().getTime() 144 const username = 'user' + new Date().getTime()
146 const { account } = await servers[0].users.create({ username, password: 'donald' }) 145 const { account } = await servers[0].users.create({ username, password: 'donald' })
@@ -153,7 +152,7 @@ describe('Test moderation notifications', function () {
153 }) 152 })
154 153
155 it('Should send a notification to moderators on remote account abuse', async function () { 154 it('Should send a notification to moderators on remote account abuse', async function () {
156 this.timeout(20000) 155 this.timeout(50000)
157 156
158 const username = 'user' + new Date().getTime() 157 const username = 'user' + new Date().getTime()
159 const tmpToken = await servers[0].users.generateUserAndToken(username) 158 const tmpToken = await servers[0].users.generateUserAndToken(username)
@@ -327,32 +326,6 @@ describe('Test moderation notifications', function () {
327 }) 326 })
328 }) 327 })
329 328
330 describe('New registration', function () {
331 let baseParams: CheckerBaseParams
332
333 before(() => {
334 baseParams = {
335 server: servers[0],
336 emails,
337 socketNotifications: adminNotifications,
338 token: servers[0].accessToken
339 }
340 })
341
342 it('Should send a notification only to moderators when a user registers on the instance', async function () {
343 this.timeout(10000)
344
345 await servers[0].users.register({ username: 'user_45' })
346
347 await waitJobs(servers)
348
349 await checkUserRegistered({ ...baseParams, username: 'user_45', checkType: 'presence' })
350
351 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
352 await checkUserRegistered({ ...baseParams, ...userOverride, username: 'user_45', checkType: 'absence' })
353 })
354 })
355
356 describe('New instance follows', function () { 329 describe('New instance follows', function () {
357 const instanceIndexServer = new MockInstancesIndex() 330 const instanceIndexServer = new MockInstancesIndex()
358 let config: any 331 let config: any
@@ -512,10 +485,14 @@ describe('Test moderation notifications', function () {
512 }) 485 })
513 486
514 it('Should not send video publish notification if auto-blacklisted', async function () { 487 it('Should not send video publish notification if auto-blacklisted', async function () {
488 this.timeout(120000)
489
515 await checkVideoIsPublished({ ...userBaseParams, videoName, shortUUID, checkType: 'absence' }) 490 await checkVideoIsPublished({ ...userBaseParams, videoName, shortUUID, checkType: 'absence' })
516 }) 491 })
517 492
518 it('Should not send a local user subscription notification if auto-blacklisted', async function () { 493 it('Should not send a local user subscription notification if auto-blacklisted', async function () {
494 this.timeout(120000)
495
519 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'absence' }) 496 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'absence' })
520 }) 497 })
521 498
@@ -524,7 +501,7 @@ describe('Test moderation notifications', function () {
524 }) 501 })
525 502
526 it('Should send video published and unblacklist after video unblacklisted', async function () { 503 it('Should send video published and unblacklist after video unblacklisted', async function () {
527 this.timeout(40000) 504 this.timeout(120000)
528 505
529 await servers[0].blacklist.remove({ videoId: uuid }) 506 await servers[0].blacklist.remove({ videoId: uuid })
530 507
@@ -537,10 +514,14 @@ describe('Test moderation notifications', function () {
537 }) 514 })
538 515
539 it('Should send a local user subscription notification after removed from blacklist', async function () { 516 it('Should send a local user subscription notification after removed from blacklist', async function () {
517 this.timeout(120000)
518
540 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'presence' }) 519 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'presence' })
541 }) 520 })
542 521
543 it('Should send a remote user subscription notification after removed from blacklist', async function () { 522 it('Should send a remote user subscription notification after removed from blacklist', async function () {
523 this.timeout(120000)
524
544 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName, shortUUID, checkType: 'presence' }) 525 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName, shortUUID, checkType: 'presence' })
545 }) 526 })
546 527
@@ -576,7 +557,7 @@ describe('Test moderation notifications', function () {
576 }) 557 })
577 558
578 it('Should not send publish/subscription notifications after scheduled update if video still auto-blacklisted', async function () { 559 it('Should not send publish/subscription notifications after scheduled update if video still auto-blacklisted', async function () {
579 this.timeout(40000) 560 this.timeout(120000)
580 561
581 // In 2 seconds 562 // In 2 seconds
582 const updateAt = new Date(new Date().getTime() + 2000) 563 const updateAt = new Date(new Date().getTime() + 2000)
diff --git a/server/tests/api/notifications/registrations-notifications.ts b/server/tests/api/notifications/registrations-notifications.ts
new file mode 100644
index 000000000..b5a7c2bb5
--- /dev/null
+++ b/server/tests/api/notifications/registrations-notifications.ts
@@ -0,0 +1,88 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import {
4 CheckerBaseParams,
5 checkRegistrationRequest,
6 checkUserRegistered,
7 MockSmtpServer,
8 prepareNotificationsTest
9} from '@server/tests/shared'
10import { UserNotification } from '@shared/models'
11import { cleanupTests, PeerTubeServer, waitJobs } from '@shared/server-commands'
12
13describe('Test registrations notifications', function () {
14 let server: PeerTubeServer
15 let userToken1: string
16
17 let userNotifications: UserNotification[] = []
18 let adminNotifications: UserNotification[] = []
19 let emails: object[] = []
20
21 let baseParams: CheckerBaseParams
22
23 before(async function () {
24 this.timeout(50000)
25
26 const res = await prepareNotificationsTest(1)
27
28 server = res.servers[0]
29 emails = res.emails
30 userToken1 = res.userAccessToken
31 adminNotifications = res.adminNotifications
32 userNotifications = res.userNotifications
33
34 baseParams = {
35 server,
36 emails,
37 socketNotifications: adminNotifications,
38 token: server.accessToken
39 }
40 })
41
42 describe('New direct registration for moderators', function () {
43
44 before(async function () {
45 await server.config.enableSignup(false)
46 })
47
48 it('Should send a notification only to moderators when a user registers on the instance', async function () {
49 this.timeout(50000)
50
51 await server.registrations.register({ username: 'user_10' })
52
53 await waitJobs([ server ])
54
55 await checkUserRegistered({ ...baseParams, username: 'user_10', checkType: 'presence' })
56
57 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
58 await checkUserRegistered({ ...baseParams, ...userOverride, username: 'user_10', checkType: 'absence' })
59 })
60 })
61
62 describe('New registration request for moderators', function () {
63
64 before(async function () {
65 await server.config.enableSignup(true)
66 })
67
68 it('Should send a notification on new registration request', async function () {
69 this.timeout(50000)
70
71 const registrationReason = 'my reason'
72 await server.registrations.requestRegistration({ username: 'user_11', registrationReason })
73
74 await waitJobs([ server ])
75
76 await checkRegistrationRequest({ ...baseParams, username: 'user_11', registrationReason, checkType: 'presence' })
77
78 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
79 await checkRegistrationRequest({ ...baseParams, ...userOverride, username: 'user_11', registrationReason, checkType: 'absence' })
80 })
81 })
82
83 after(async function () {
84 MockSmtpServer.Instance.kill()
85
86 await cleanupTests([ server ])
87 })
88})
diff --git a/server/tests/api/object-storage/video-static-file-privacy.ts b/server/tests/api/object-storage/video-static-file-privacy.ts
index 71ad35a43..869d437d5 100644
--- a/server/tests/api/object-storage/video-static-file-privacy.ts
+++ b/server/tests/api/object-storage/video-static-file-privacy.ts
@@ -120,7 +120,7 @@ describe('Object storage for video static file privacy', function () {
120 // --------------------------------------------------------------------------- 120 // ---------------------------------------------------------------------------
121 121
122 it('Should upload a private video and have appropriate object storage ACL', async function () { 122 it('Should upload a private video and have appropriate object storage ACL', async function () {
123 this.timeout(60000) 123 this.timeout(120000)
124 124
125 { 125 {
126 const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.PRIVATE }) 126 const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.PRIVATE })
@@ -138,7 +138,7 @@ describe('Object storage for video static file privacy', function () {
138 }) 138 })
139 139
140 it('Should upload a public video and have appropriate object storage ACL', async function () { 140 it('Should upload a public video and have appropriate object storage ACL', async function () {
141 this.timeout(60000) 141 this.timeout(120000)
142 142
143 const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.UNLISTED }) 143 const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.UNLISTED })
144 await waitJobs([ server ]) 144 await waitJobs([ server ])
diff --git a/server/tests/api/server/config-defaults.ts b/server/tests/api/server/config-defaults.ts
index 4fa37d0e2..d3b3a2447 100644
--- a/server/tests/api/server/config-defaults.ts
+++ b/server/tests/api/server/config-defaults.ts
@@ -149,7 +149,7 @@ describe('Test config defaults', function () {
149 }) 149 })
150 150
151 it('Should register a user with this default setting', async function () { 151 it('Should register a user with this default setting', async function () {
152 await server.users.register({ username: 'user_p2p_2' }) 152 await server.registrations.register({ username: 'user_p2p_2' })
153 153
154 const userToken = await server.login.getAccessToken('user_p2p_2') 154 const userToken = await server.login.getAccessToken('user_p2p_2')
155 155
@@ -194,7 +194,7 @@ describe('Test config defaults', function () {
194 }) 194 })
195 195
196 it('Should register a user with this default setting', async function () { 196 it('Should register a user with this default setting', async function () {
197 await server.users.register({ username: 'user_p2p_4' }) 197 await server.registrations.register({ username: 'user_p2p_4' })
198 198
199 const userToken = await server.login.getAccessToken('user_p2p_4') 199 const userToken = await server.login.getAccessToken('user_p2p_4')
200 200
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index 22446fe0c..b91519660 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -50,6 +50,7 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
50 expect(data.signup.enabled).to.be.true 50 expect(data.signup.enabled).to.be.true
51 expect(data.signup.limit).to.equal(4) 51 expect(data.signup.limit).to.equal(4)
52 expect(data.signup.minimumAge).to.equal(16) 52 expect(data.signup.minimumAge).to.equal(16)
53 expect(data.signup.requiresApproval).to.be.false
53 expect(data.signup.requiresEmailVerification).to.be.false 54 expect(data.signup.requiresEmailVerification).to.be.false
54 55
55 expect(data.admin.email).to.equal('admin' + server.internalServerNumber + '@example.com') 56 expect(data.admin.email).to.equal('admin' + server.internalServerNumber + '@example.com')
@@ -152,6 +153,7 @@ function checkUpdatedConfig (data: CustomConfig) {
152 153
153 expect(data.signup.enabled).to.be.false 154 expect(data.signup.enabled).to.be.false
154 expect(data.signup.limit).to.equal(5) 155 expect(data.signup.limit).to.equal(5)
156 expect(data.signup.requiresApproval).to.be.false
155 expect(data.signup.requiresEmailVerification).to.be.false 157 expect(data.signup.requiresEmailVerification).to.be.false
156 expect(data.signup.minimumAge).to.equal(10) 158 expect(data.signup.minimumAge).to.equal(10)
157 159
@@ -285,6 +287,7 @@ const newCustomConfig: CustomConfig = {
285 signup: { 287 signup: {
286 enabled: false, 288 enabled: false,
287 limit: 5, 289 limit: 5,
290 requiresApproval: false,
288 requiresEmailVerification: false, 291 requiresEmailVerification: false,
289 minimumAge: 10 292 minimumAge: 10
290 }, 293 },
@@ -468,9 +471,9 @@ describe('Test config', function () {
468 this.timeout(5000) 471 this.timeout(5000)
469 472
470 await Promise.all([ 473 await Promise.all([
471 server.users.register({ username: 'user1' }), 474 server.registrations.register({ username: 'user1' }),
472 server.users.register({ username: 'user2' }), 475 server.registrations.register({ username: 'user2' }),
473 server.users.register({ username: 'user3' }) 476 server.registrations.register({ username: 'user3' })
474 ]) 477 ])
475 478
476 const data = await server.config.getConfig() 479 const data = await server.config.getConfig()
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
index 325218008..dd971203a 100644
--- a/server/tests/api/server/contact-form.ts
+++ b/server/tests/api/server/contact-form.ts
@@ -6,6 +6,7 @@ import { wait } from '@shared/core-utils'
6import { HttpStatusCode } from '@shared/models' 6import { HttpStatusCode } from '@shared/models'
7import { 7import {
8 cleanupTests, 8 cleanupTests,
9 ConfigCommand,
9 ContactFormCommand, 10 ContactFormCommand,
10 createSingleServer, 11 createSingleServer,
11 PeerTubeServer, 12 PeerTubeServer,
@@ -23,13 +24,7 @@ describe('Test contact form', function () {
23 24
24 const port = await MockSmtpServer.Instance.collectEmails(emails) 25 const port = await MockSmtpServer.Instance.collectEmails(emails)
25 26
26 const overrideConfig = { 27 server = await createSingleServer(1, ConfigCommand.getEmailOverrideConfig(port))
27 smtp: {
28 hostname: '127.0.0.1',
29 port
30 }
31 }
32 server = await createSingleServer(1, overrideConfig)
33 await setAccessTokensToServers([ server ]) 28 await setAccessTokensToServers([ server ])
34 29
35 command = server.contactForm 30 command = server.contactForm
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index 4ab5463fe..db7aa65bd 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -3,7 +3,14 @@
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { MockSmtpServer } from '@server/tests/shared' 4import { MockSmtpServer } from '@server/tests/shared'
5import { HttpStatusCode } from '@shared/models' 5import { HttpStatusCode } from '@shared/models'
6import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/server-commands' 6import {
7 cleanupTests,
8 ConfigCommand,
9 createSingleServer,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 waitJobs
13} from '@shared/server-commands'
7 14
8describe('Test emails', function () { 15describe('Test emails', function () {
9 let server: PeerTubeServer 16 let server: PeerTubeServer
@@ -24,21 +31,15 @@ describe('Test emails', function () {
24 username: 'user_1', 31 username: 'user_1',
25 password: 'super_password' 32 password: 'super_password'
26 } 33 }
27 let emailPort: number
28 34
29 before(async function () { 35 before(async function () {
30 this.timeout(50000) 36 this.timeout(50000)
31 37
32 emailPort = await MockSmtpServer.Instance.collectEmails(emails) 38 const emailPort = await MockSmtpServer.Instance.collectEmails(emails)
39 server = await createSingleServer(1, ConfigCommand.getEmailOverrideConfig(emailPort))
33 40
34 const overrideConfig = {
35 smtp: {
36 hostname: '127.0.0.1',
37 port: emailPort
38 }
39 }
40 server = await createSingleServer(1, overrideConfig)
41 await setAccessTokensToServers([ server ]) 41 await setAccessTokensToServers([ server ])
42 await server.config.enableSignup(true)
42 43
43 { 44 {
44 const created = await server.users.create({ username: user.username, password: user.password }) 45 const created = await server.users.create({ username: user.username, password: user.password })
@@ -322,6 +323,62 @@ describe('Test emails', function () {
322 }) 323 })
323 }) 324 })
324 325
326 describe('When verifying a registration email', function () {
327 let registrationId: number
328 let registrationIdEmail: number
329
330 before(async function () {
331 const { id } = await server.registrations.requestRegistration({
332 username: 'request_1',
333 email: 'request_1@example.com',
334 registrationReason: 'tt'
335 })
336 registrationId = id
337 })
338
339 it('Should ask to send the verification email', async function () {
340 this.timeout(10000)
341
342 await server.registrations.askSendVerifyEmail({ email: 'request_1@example.com' })
343
344 await waitJobs(server)
345 expect(emails).to.have.lengthOf(9)
346
347 const email = emails[8]
348
349 expect(email['from'][0]['name']).equal('PeerTube')
350 expect(email['from'][0]['address']).equal('test-admin@127.0.0.1')
351 expect(email['to'][0]['address']).equal('request_1@example.com')
352 expect(email['subject']).contains('Verify')
353
354 const verificationStringMatches = /verificationString=([a-z0-9]+)/.exec(email['text'])
355 expect(verificationStringMatches).not.to.be.null
356
357 verificationString = verificationStringMatches[1]
358 expect(verificationString).to.not.be.undefined
359 expect(verificationString).to.have.length.above(2)
360
361 const registrationIdMatches = /registrationId=([0-9]+)/.exec(email['text'])
362 expect(registrationIdMatches).not.to.be.null
363
364 registrationIdEmail = parseInt(registrationIdMatches[1], 10)
365
366 expect(registrationId).to.equal(registrationIdEmail)
367 })
368
369 it('Should not verify the email with an invalid verification string', async function () {
370 await server.registrations.verifyEmail({
371 registrationId: registrationIdEmail,
372 verificationString: verificationString + 'b',
373 expectedStatus: HttpStatusCode.FORBIDDEN_403
374 })
375 })
376
377 it('Should verify the email', async function () {
378 await server.registrations.verifyEmail({ registrationId: registrationIdEmail, verificationString })
379 })
380 })
381
325 after(async function () { 382 after(async function () {
326 MockSmtpServer.Instance.kill() 383 MockSmtpServer.Instance.kill()
327 384
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts
index d882f0bde..11c96c4b5 100644
--- a/server/tests/api/server/reverse-proxy.ts
+++ b/server/tests/api/server/reverse-proxy.ts
@@ -106,13 +106,13 @@ describe('Test application behind a reverse proxy', function () {
106 it('Should rate limit signup', async function () { 106 it('Should rate limit signup', async function () {
107 for (let i = 0; i < 10; i++) { 107 for (let i = 0; i < 10; i++) {
108 try { 108 try {
109 await server.users.register({ username: 'test' + i }) 109 await server.registrations.register({ username: 'test' + i })
110 } catch { 110 } catch {
111 // empty 111 // empty
112 } 112 }
113 } 113 }
114 114
115 await server.users.register({ username: 'test42', expectedStatus: HttpStatusCode.TOO_MANY_REQUESTS_429 }) 115 await server.registrations.register({ username: 'test42', expectedStatus: HttpStatusCode.TOO_MANY_REQUESTS_429 })
116 }) 116 })
117 117
118 it('Should not rate limit failed signup', async function () { 118 it('Should not rate limit failed signup', async function () {
@@ -121,10 +121,10 @@ describe('Test application behind a reverse proxy', function () {
121 await wait(7000) 121 await wait(7000)
122 122
123 for (let i = 0; i < 3; i++) { 123 for (let i = 0; i < 3; i++) {
124 await server.users.register({ username: 'test' + i, expectedStatus: HttpStatusCode.CONFLICT_409 }) 124 await server.registrations.register({ username: 'test' + i, expectedStatus: HttpStatusCode.CONFLICT_409 })
125 } 125 }
126 126
127 await server.users.register({ username: 'test43', expectedStatus: HttpStatusCode.NO_CONTENT_204 }) 127 await server.registrations.register({ username: 'test43', expectedStatus: HttpStatusCode.NO_CONTENT_204 })
128 128
129 }) 129 })
130 130
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts
index 643f1a531..a4443a8ec 100644
--- a/server/tests/api/users/index.ts
+++ b/server/tests/api/users/index.ts
@@ -1,6 +1,8 @@
1import './oauth'
2import './registrations`'
1import './two-factor' 3import './two-factor'
2import './user-subscriptions' 4import './user-subscriptions'
3import './user-videos' 5import './user-videos'
4import './users' 6import './users'
5import './users-multiple-servers' 7import './users-multiple-servers'
6import './users-verification' 8import './users-email-verification'
diff --git a/server/tests/api/users/oauth.ts b/server/tests/api/users/oauth.ts
new file mode 100644
index 000000000..6a3da5ea2
--- /dev/null
+++ b/server/tests/api/users/oauth.ts
@@ -0,0 +1,192 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { wait } from '@shared/core-utils'
5import { HttpStatusCode, OAuth2ErrorCode, PeerTubeProblemDocument } from '@shared/models'
6import { cleanupTests, createSingleServer, killallServers, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
7
8describe('Test oauth', function () {
9 let server: PeerTubeServer
10
11 before(async function () {
12 this.timeout(30000)
13
14 server = await createSingleServer(1, {
15 rates_limit: {
16 login: {
17 max: 30
18 }
19 }
20 })
21
22 await setAccessTokensToServers([ server ])
23 })
24
25 describe('OAuth client', function () {
26
27 function expectInvalidClient (body: PeerTubeProblemDocument) {
28 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_CLIENT)
29 expect(body.error).to.contain('client is invalid')
30 expect(body.type.startsWith('https://')).to.be.true
31 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_CLIENT)
32 }
33
34 it('Should create a new client')
35
36 it('Should return the first client')
37
38 it('Should remove the last client')
39
40 it('Should not login with an invalid client id', async function () {
41 const client = { id: 'client', secret: server.store.client.secret }
42 const body = await server.login.login({ client, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
43
44 expectInvalidClient(body)
45 })
46
47 it('Should not login with an invalid client secret', async function () {
48 const client = { id: server.store.client.id, secret: 'coucou' }
49 const body = await server.login.login({ client, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
50
51 expectInvalidClient(body)
52 })
53 })
54
55 describe('Login', function () {
56
57 function expectInvalidCredentials (body: PeerTubeProblemDocument) {
58 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_GRANT)
59 expect(body.error).to.contain('credentials are invalid')
60 expect(body.type.startsWith('https://')).to.be.true
61 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_GRANT)
62 }
63
64 it('Should not login with an invalid username', async function () {
65 const user = { username: 'captain crochet', password: server.store.user.password }
66 const body = await server.login.login({ user, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
67
68 expectInvalidCredentials(body)
69 })
70
71 it('Should not login with an invalid password', async function () {
72 const user = { username: server.store.user.username, password: 'mew_three' }
73 const body = await server.login.login({ user, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
74
75 expectInvalidCredentials(body)
76 })
77
78 it('Should be able to login', async function () {
79 await server.login.login({ expectedStatus: HttpStatusCode.OK_200 })
80 })
81
82 it('Should be able to login with an insensitive username', async function () {
83 const user = { username: 'RoOt', password: server.store.user.password }
84 await server.login.login({ user, expectedStatus: HttpStatusCode.OK_200 })
85
86 const user2 = { username: 'rOoT', password: server.store.user.password }
87 await server.login.login({ user: user2, expectedStatus: HttpStatusCode.OK_200 })
88
89 const user3 = { username: 'ROOt', password: server.store.user.password }
90 await server.login.login({ user: user3, expectedStatus: HttpStatusCode.OK_200 })
91 })
92 })
93
94 describe('Logout', function () {
95
96 it('Should logout (revoke token)', async function () {
97 await server.login.logout({ token: server.accessToken })
98 })
99
100 it('Should not be able to get the user information', async function () {
101 await server.users.getMyInfo({ expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
102 })
103
104 it('Should not be able to upload a video', async function () {
105 await server.videos.upload({ attributes: { name: 'video' }, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
106 })
107
108 it('Should be able to login again', async function () {
109 const body = await server.login.login()
110 server.accessToken = body.access_token
111 server.refreshToken = body.refresh_token
112 })
113
114 it('Should be able to get my user information again', async function () {
115 await server.users.getMyInfo()
116 })
117
118 it('Should have an expired access token', async function () {
119 this.timeout(60000)
120
121 await server.sql.setTokenField(server.accessToken, 'accessTokenExpiresAt', new Date().toISOString())
122 await server.sql.setTokenField(server.accessToken, 'refreshTokenExpiresAt', new Date().toISOString())
123
124 await killallServers([ server ])
125 await server.run()
126
127 await server.users.getMyInfo({ expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
128 })
129
130 it('Should not be able to refresh an access token with an expired refresh token', async function () {
131 await server.login.refreshToken({ refreshToken: server.refreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
132 })
133
134 it('Should refresh the token', async function () {
135 this.timeout(50000)
136
137 const futureDate = new Date(new Date().getTime() + 1000 * 60).toISOString()
138 await server.sql.setTokenField(server.accessToken, 'refreshTokenExpiresAt', futureDate)
139
140 await killallServers([ server ])
141 await server.run()
142
143 const res = await server.login.refreshToken({ refreshToken: server.refreshToken })
144 server.accessToken = res.body.access_token
145 server.refreshToken = res.body.refresh_token
146 })
147
148 it('Should be able to get my user information again', async function () {
149 await server.users.getMyInfo()
150 })
151 })
152
153 describe('Custom token lifetime', function () {
154 before(async function () {
155 this.timeout(120_000)
156
157 await server.kill()
158 await server.run({
159 oauth2: {
160 token_lifetime: {
161 access_token: '2 seconds',
162 refresh_token: '2 seconds'
163 }
164 }
165 })
166 })
167
168 it('Should have a very short access token lifetime', async function () {
169 this.timeout(50000)
170
171 const { access_token: accessToken } = await server.login.login()
172 await server.users.getMyInfo({ token: accessToken })
173
174 await wait(3000)
175 await server.users.getMyInfo({ token: accessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
176 })
177
178 it('Should have a very short refresh token lifetime', async function () {
179 this.timeout(50000)
180
181 const { refresh_token: refreshToken } = await server.login.login()
182 await server.login.refreshToken({ refreshToken })
183
184 await wait(3000)
185 await server.login.refreshToken({ refreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
186 })
187 })
188
189 after(async function () {
190 await cleanupTests([ server ])
191 })
192})
diff --git a/server/tests/api/users/registrations.ts b/server/tests/api/users/registrations.ts
new file mode 100644
index 000000000..e6524f07d
--- /dev/null
+++ b/server/tests/api/users/registrations.ts
@@ -0,0 +1,415 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { MockSmtpServer } from '@server/tests/shared'
5import { UserRegistrationState, UserRole } from '@shared/models'
6import {
7 cleanupTests,
8 ConfigCommand,
9 createSingleServer,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 waitJobs
13} from '@shared/server-commands'
14
15describe('Test registrations', function () {
16 let server: PeerTubeServer
17
18 const emails: object[] = []
19 let emailPort: number
20
21 before(async function () {
22 this.timeout(30000)
23
24 emailPort = await MockSmtpServer.Instance.collectEmails(emails)
25
26 server = await createSingleServer(1, ConfigCommand.getEmailOverrideConfig(emailPort))
27
28 await setAccessTokensToServers([ server ])
29 await server.config.enableSignup(false)
30 })
31
32 describe('Direct registrations of a new user', function () {
33 let user1Token: string
34
35 it('Should register a new user', async function () {
36 const user = { displayName: 'super user 1', username: 'user_1', password: 'my super password' }
37 const channel = { name: 'my_user_1_channel', displayName: 'my channel rocks' }
38
39 await server.registrations.register({ ...user, channel })
40 })
41
42 it('Should be able to login with this registered user', async function () {
43 const user1 = { username: 'user_1', password: 'my super password' }
44
45 user1Token = await server.login.getAccessToken(user1)
46 })
47
48 it('Should have the correct display name', async function () {
49 const user = await server.users.getMyInfo({ token: user1Token })
50 expect(user.account.displayName).to.equal('super user 1')
51 })
52
53 it('Should have the correct video quota', async function () {
54 const user = await server.users.getMyInfo({ token: user1Token })
55 expect(user.videoQuota).to.equal(5 * 1024 * 1024)
56 })
57
58 it('Should have created the channel', async function () {
59 const { displayName } = await server.channels.get({ channelName: 'my_user_1_channel' })
60
61 expect(displayName).to.equal('my channel rocks')
62 })
63
64 it('Should remove me', async function () {
65 {
66 const { data } = await server.users.list()
67 expect(data.find(u => u.username === 'user_1')).to.not.be.undefined
68 }
69
70 await server.users.deleteMe({ token: user1Token })
71
72 {
73 const { data } = await server.users.list()
74 expect(data.find(u => u.username === 'user_1')).to.be.undefined
75 }
76 })
77 })
78
79 describe('Registration requests', function () {
80 let id2: number
81 let id3: number
82 let id4: number
83
84 let user2Token: string
85 let user3Token: string
86
87 before(async function () {
88 this.timeout(60000)
89
90 await server.config.enableSignup(true)
91
92 {
93 const { id } = await server.registrations.requestRegistration({
94 username: 'user4',
95 registrationReason: 'registration reason 4'
96 })
97
98 id4 = id
99 }
100 })
101
102 it('Should request a registration without a channel', async function () {
103 {
104 const { id } = await server.registrations.requestRegistration({
105 username: 'user2',
106 displayName: 'my super user 2',
107 email: 'user2@example.com',
108 password: 'user2password',
109 registrationReason: 'registration reason 2'
110 })
111
112 id2 = id
113 }
114 })
115
116 it('Should request a registration with a channel', async function () {
117 const { id } = await server.registrations.requestRegistration({
118 username: 'user3',
119 displayName: 'my super user 3',
120 channel: {
121 displayName: 'my user 3 channel',
122 name: 'super_user3_channel'
123 },
124 email: 'user3@example.com',
125 password: 'user3password',
126 registrationReason: 'registration reason 3'
127 })
128
129 id3 = id
130 })
131
132 it('Should list these registration requests', async function () {
133 {
134 const { total, data } = await server.registrations.list({ sort: '-createdAt' })
135 expect(total).to.equal(3)
136 expect(data).to.have.lengthOf(3)
137
138 {
139 expect(data[0].id).to.equal(id3)
140 expect(data[0].username).to.equal('user3')
141 expect(data[0].accountDisplayName).to.equal('my super user 3')
142
143 expect(data[0].channelDisplayName).to.equal('my user 3 channel')
144 expect(data[0].channelHandle).to.equal('super_user3_channel')
145
146 expect(data[0].createdAt).to.exist
147 expect(data[0].updatedAt).to.exist
148
149 expect(data[0].email).to.equal('user3@example.com')
150 expect(data[0].emailVerified).to.be.null
151
152 expect(data[0].moderationResponse).to.be.null
153 expect(data[0].registrationReason).to.equal('registration reason 3')
154 expect(data[0].state.id).to.equal(UserRegistrationState.PENDING)
155 expect(data[0].state.label).to.equal('Pending')
156 expect(data[0].user).to.be.null
157 }
158
159 {
160 expect(data[1].id).to.equal(id2)
161 expect(data[1].username).to.equal('user2')
162 expect(data[1].accountDisplayName).to.equal('my super user 2')
163
164 expect(data[1].channelDisplayName).to.be.null
165 expect(data[1].channelHandle).to.be.null
166
167 expect(data[1].createdAt).to.exist
168 expect(data[1].updatedAt).to.exist
169
170 expect(data[1].email).to.equal('user2@example.com')
171 expect(data[1].emailVerified).to.be.null
172
173 expect(data[1].moderationResponse).to.be.null
174 expect(data[1].registrationReason).to.equal('registration reason 2')
175 expect(data[1].state.id).to.equal(UserRegistrationState.PENDING)
176 expect(data[1].state.label).to.equal('Pending')
177 expect(data[1].user).to.be.null
178 }
179
180 {
181 expect(data[2].username).to.equal('user4')
182 }
183 }
184
185 {
186 const { total, data } = await server.registrations.list({ count: 1, start: 1, sort: 'createdAt' })
187
188 expect(total).to.equal(3)
189 expect(data).to.have.lengthOf(1)
190 expect(data[0].id).to.equal(id2)
191 }
192
193 {
194 const { total, data } = await server.registrations.list({ search: 'user3' })
195 expect(total).to.equal(1)
196 expect(data).to.have.lengthOf(1)
197 expect(data[0].id).to.equal(id3)
198 }
199 })
200
201 it('Should reject a registration request', async function () {
202 await server.registrations.reject({ id: id4, moderationResponse: 'I do not want id 4 on this instance' })
203 })
204
205 it('Should have sent an email to the user explanining the registration has been rejected', async function () {
206 this.timeout(50000)
207
208 await waitJobs([ server ])
209
210 const email = emails.find(e => e['to'][0]['address'] === 'user4@example.com')
211 expect(email).to.exist
212
213 expect(email['subject']).to.contain('been rejected')
214 expect(email['text']).to.contain('been rejected')
215 expect(email['text']).to.contain('I do not want id 4 on this instance')
216 })
217
218 it('Should accept registration requests', async function () {
219 await server.registrations.accept({ id: id2, moderationResponse: 'Welcome id 2' })
220 await server.registrations.accept({ id: id3, moderationResponse: 'Welcome id 3' })
221 })
222
223 it('Should have sent an email to the user explanining the registration has been accepted', async function () {
224 this.timeout(50000)
225
226 await waitJobs([ server ])
227
228 {
229 const email = emails.find(e => e['to'][0]['address'] === 'user2@example.com')
230 expect(email).to.exist
231
232 expect(email['subject']).to.contain('been accepted')
233 expect(email['text']).to.contain('been accepted')
234 expect(email['text']).to.contain('Welcome id 2')
235 }
236
237 {
238 const email = emails.find(e => e['to'][0]['address'] === 'user3@example.com')
239 expect(email).to.exist
240
241 expect(email['subject']).to.contain('been accepted')
242 expect(email['text']).to.contain('been accepted')
243 expect(email['text']).to.contain('Welcome id 3')
244 }
245 })
246
247 it('Should login with these users', async function () {
248 user2Token = await server.login.getAccessToken({ username: 'user2', password: 'user2password' })
249 user3Token = await server.login.getAccessToken({ username: 'user3', password: 'user3password' })
250 })
251
252 it('Should have created the appropriate attributes for user 2', async function () {
253 const me = await server.users.getMyInfo({ token: user2Token })
254
255 expect(me.username).to.equal('user2')
256 expect(me.account.displayName).to.equal('my super user 2')
257 expect(me.videoQuota).to.equal(5 * 1024 * 1024)
258 expect(me.videoChannels[0].name).to.equal('user2_channel')
259 expect(me.videoChannels[0].displayName).to.equal('Main user2 channel')
260 expect(me.role.id).to.equal(UserRole.USER)
261 expect(me.email).to.equal('user2@example.com')
262 })
263
264 it('Should have created the appropriate attributes for user 3', async function () {
265 const me = await server.users.getMyInfo({ token: user3Token })
266
267 expect(me.username).to.equal('user3')
268 expect(me.account.displayName).to.equal('my super user 3')
269 expect(me.videoQuota).to.equal(5 * 1024 * 1024)
270 expect(me.videoChannels[0].name).to.equal('super_user3_channel')
271 expect(me.videoChannels[0].displayName).to.equal('my user 3 channel')
272 expect(me.role.id).to.equal(UserRole.USER)
273 expect(me.email).to.equal('user3@example.com')
274 })
275
276 it('Should list these accepted/rejected registration requests', async function () {
277 const { data } = await server.registrations.list({ sort: 'createdAt' })
278 const { data: users } = await server.users.list()
279
280 {
281 expect(data[0].id).to.equal(id4)
282 expect(data[0].state.id).to.equal(UserRegistrationState.REJECTED)
283 expect(data[0].state.label).to.equal('Rejected')
284
285 expect(data[0].moderationResponse).to.equal('I do not want id 4 on this instance')
286 expect(data[0].user).to.be.null
287
288 expect(users.find(u => u.username === 'user4')).to.not.exist
289 }
290
291 {
292 expect(data[1].id).to.equal(id2)
293 expect(data[1].state.id).to.equal(UserRegistrationState.ACCEPTED)
294 expect(data[1].state.label).to.equal('Accepted')
295
296 expect(data[1].moderationResponse).to.equal('Welcome id 2')
297 expect(data[1].user).to.exist
298
299 const user2 = users.find(u => u.username === 'user2')
300 expect(data[1].user.id).to.equal(user2.id)
301 }
302
303 {
304 expect(data[2].id).to.equal(id3)
305 expect(data[2].state.id).to.equal(UserRegistrationState.ACCEPTED)
306 expect(data[2].state.label).to.equal('Accepted')
307
308 expect(data[2].moderationResponse).to.equal('Welcome id 3')
309 expect(data[2].user).to.exist
310
311 const user3 = users.find(u => u.username === 'user3')
312 expect(data[2].user.id).to.equal(user3.id)
313 }
314 })
315
316 it('Shoulde delete a registration', async function () {
317 await server.registrations.delete({ id: id2 })
318 await server.registrations.delete({ id: id3 })
319
320 const { total, data } = await server.registrations.list()
321 expect(total).to.equal(1)
322 expect(data).to.have.lengthOf(1)
323 expect(data[0].id).to.equal(id4)
324
325 const { data: users } = await server.users.list()
326
327 for (const username of [ 'user2', 'user3' ]) {
328 expect(users.find(u => u.username === username)).to.exist
329 }
330 })
331
332 it('Should be able to prevent email delivery on accept/reject', async function () {
333 this.timeout(50000)
334
335 let id1: number
336 let id2: number
337
338 {
339 const { id } = await server.registrations.requestRegistration({
340 username: 'user7',
341 email: 'user7@example.com',
342 registrationReason: 'tt'
343 })
344 id1 = id
345 }
346 {
347 const { id } = await server.registrations.requestRegistration({
348 username: 'user8',
349 email: 'user8@example.com',
350 registrationReason: 'tt'
351 })
352 id2 = id
353 }
354
355 await server.registrations.accept({ id: id1, moderationResponse: 'tt', preventEmailDelivery: true })
356 await server.registrations.reject({ id: id2, moderationResponse: 'tt', preventEmailDelivery: true })
357
358 await waitJobs([ server ])
359
360 const filtered = emails.filter(e => {
361 const address = e['to'][0]['address']
362 return address === 'user7@example.com' || address === 'user8@example.com'
363 })
364
365 expect(filtered).to.have.lengthOf(0)
366 })
367
368 it('Should request a registration without a channel, that will conflict with an already existing channel', async function () {
369 let id1: number
370 let id2: number
371
372 {
373 const { id } = await server.registrations.requestRegistration({
374 registrationReason: 'tt',
375 username: 'user5',
376 password: 'user5password',
377 channel: {
378 displayName: 'channel 6',
379 name: 'user6_channel'
380 }
381 })
382
383 id1 = id
384 }
385
386 {
387 const { id } = await server.registrations.requestRegistration({
388 registrationReason: 'tt',
389 username: 'user6',
390 password: 'user6password'
391 })
392
393 id2 = id
394 }
395
396 await server.registrations.accept({ id: id1, moderationResponse: 'tt' })
397 await server.registrations.accept({ id: id2, moderationResponse: 'tt' })
398
399 const user5Token = await server.login.getAccessToken('user5', 'user5password')
400 const user6Token = await server.login.getAccessToken('user6', 'user6password')
401
402 const user5 = await server.users.getMyInfo({ token: user5Token })
403 const user6 = await server.users.getMyInfo({ token: user6Token })
404
405 expect(user5.videoChannels[0].name).to.equal('user6_channel')
406 expect(user6.videoChannels[0].name).to.equal('user6_channel-1')
407 })
408 })
409
410 after(async function () {
411 MockSmtpServer.Instance.kill()
412
413 await cleanupTests([ server ])
414 })
415})
diff --git a/server/tests/api/users/users-verification.ts b/server/tests/api/users/users-email-verification.ts
index 19a8df9e1..cb84dc758 100644
--- a/server/tests/api/users/users-verification.ts
+++ b/server/tests/api/users/users-email-verification.ts
@@ -3,9 +3,16 @@
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { MockSmtpServer } from '@server/tests/shared' 4import { MockSmtpServer } from '@server/tests/shared'
5import { HttpStatusCode } from '@shared/models' 5import { HttpStatusCode } from '@shared/models'
6import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/server-commands' 6import {
7 7 cleanupTests,
8describe('Test users account verification', function () { 8 ConfigCommand,
9 createSingleServer,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 waitJobs
13} from '@shared/server-commands'
14
15describe('Test users email verification', function () {
9 let server: PeerTubeServer 16 let server: PeerTubeServer
10 let userId: number 17 let userId: number
11 let userAccessToken: string 18 let userAccessToken: string
@@ -25,14 +32,7 @@ describe('Test users account verification', function () {
25 this.timeout(30000) 32 this.timeout(30000)
26 33
27 const port = await MockSmtpServer.Instance.collectEmails(emails) 34 const port = await MockSmtpServer.Instance.collectEmails(emails)
28 35 server = await createSingleServer(1, ConfigCommand.getEmailOverrideConfig(port))
29 const overrideConfig = {
30 smtp: {
31 hostname: '127.0.0.1',
32 port
33 }
34 }
35 server = await createSingleServer(1, overrideConfig)
36 36
37 await setAccessTokensToServers([ server ]) 37 await setAccessTokensToServers([ server ])
38 }) 38 })
@@ -40,17 +40,18 @@ describe('Test users account verification', function () {
40 it('Should register user and send verification email if verification required', async function () { 40 it('Should register user and send verification email if verification required', async function () {
41 this.timeout(30000) 41 this.timeout(30000)
42 42
43 await server.config.updateCustomSubConfig({ 43 await server.config.updateExistingSubConfig({
44 newConfig: { 44 newConfig: {
45 signup: { 45 signup: {
46 enabled: true, 46 enabled: true,
47 requiresApproval: false,
47 requiresEmailVerification: true, 48 requiresEmailVerification: true,
48 limit: 10 49 limit: 10
49 } 50 }
50 } 51 }
51 }) 52 })
52 53
53 await server.users.register(user1) 54 await server.registrations.register(user1)
54 55
55 await waitJobs(server) 56 await waitJobs(server)
56 expectedEmailsLength++ 57 expectedEmailsLength++
@@ -127,17 +128,15 @@ describe('Test users account verification', function () {
127 128
128 it('Should register user not requiring email verification if setting not enabled', async function () { 129 it('Should register user not requiring email verification if setting not enabled', async function () {
129 this.timeout(5000) 130 this.timeout(5000)
130 await server.config.updateCustomSubConfig({ 131 await server.config.updateExistingSubConfig({
131 newConfig: { 132 newConfig: {
132 signup: { 133 signup: {
133 enabled: true, 134 requiresEmailVerification: false
134 requiresEmailVerification: false,
135 limit: 10
136 } 135 }
137 } 136 }
138 }) 137 })
139 138
140 await server.users.register(user2) 139 await server.registrations.register(user2)
141 140
142 await waitJobs(server) 141 await waitJobs(server)
143 expect(emails).to.have.lengthOf(expectedEmailsLength) 142 expect(emails).to.have.lengthOf(expectedEmailsLength)
@@ -152,9 +151,7 @@ describe('Test users account verification', function () {
152 await server.config.updateCustomSubConfig({ 151 await server.config.updateCustomSubConfig({
153 newConfig: { 152 newConfig: {
154 signup: { 153 signup: {
155 enabled: true, 154 requiresEmailVerification: true
156 requiresEmailVerification: true,
157 limit: 10
158 } 155 }
159 } 156 }
160 }) 157 })
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 421b3ce16..f1e170971 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -2,15 +2,8 @@
2 2
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { testImage } from '@server/tests/shared' 4import { testImage } from '@server/tests/shared'
5import { AbuseState, HttpStatusCode, OAuth2ErrorCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@shared/models' 5import { AbuseState, HttpStatusCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@shared/models'
6import { 6import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
7 cleanupTests,
8 createSingleServer,
9 killallServers,
10 makePutBodyRequest,
11 PeerTubeServer,
12 setAccessTokensToServers
13} from '@shared/server-commands'
14 7
15describe('Test users', function () { 8describe('Test users', function () {
16 let server: PeerTubeServer 9 let server: PeerTubeServer
@@ -39,166 +32,6 @@ describe('Test users', function () {
39 await server.plugins.install({ npmName: 'peertube-theme-background-red' }) 32 await server.plugins.install({ npmName: 'peertube-theme-background-red' })
40 }) 33 })
41 34
42 describe('OAuth client', function () {
43 it('Should create a new client')
44
45 it('Should return the first client')
46
47 it('Should remove the last client')
48
49 it('Should not login with an invalid client id', async function () {
50 const client = { id: 'client', secret: server.store.client.secret }
51 const body = await server.login.login({ client, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
52
53 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_CLIENT)
54 expect(body.error).to.contain('client is invalid')
55 expect(body.type.startsWith('https://')).to.be.true
56 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_CLIENT)
57 })
58
59 it('Should not login with an invalid client secret', async function () {
60 const client = { id: server.store.client.id, secret: 'coucou' }
61 const body = await server.login.login({ client, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
62
63 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_CLIENT)
64 expect(body.error).to.contain('client is invalid')
65 expect(body.type.startsWith('https://')).to.be.true
66 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_CLIENT)
67 })
68 })
69
70 describe('Login', function () {
71
72 it('Should not login with an invalid username', async function () {
73 const user = { username: 'captain crochet', password: server.store.user.password }
74 const body = await server.login.login({ user, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
75
76 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_GRANT)
77 expect(body.error).to.contain('credentials are invalid')
78 expect(body.type.startsWith('https://')).to.be.true
79 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_GRANT)
80 })
81
82 it('Should not login with an invalid password', async function () {
83 const user = { username: server.store.user.username, password: 'mew_three' }
84 const body = await server.login.login({ user, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
85
86 expect(body.code).to.equal(OAuth2ErrorCode.INVALID_GRANT)
87 expect(body.error).to.contain('credentials are invalid')
88 expect(body.type.startsWith('https://')).to.be.true
89 expect(body.type).to.contain(OAuth2ErrorCode.INVALID_GRANT)
90 })
91
92 it('Should not be able to upload a video', async function () {
93 token = 'my_super_token'
94
95 await server.videos.upload({ token, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
96 })
97
98 it('Should not be able to follow', async function () {
99 token = 'my_super_token'
100
101 await server.follows.follow({
102 hosts: [ 'http://example.com' ],
103 token,
104 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
105 })
106 })
107
108 it('Should not be able to unfollow')
109
110 it('Should be able to login', async function () {
111 const body = await server.login.login({ expectedStatus: HttpStatusCode.OK_200 })
112
113 token = body.access_token
114 })
115
116 it('Should be able to login with an insensitive username', async function () {
117 const user = { username: 'RoOt', password: server.store.user.password }
118 await server.login.login({ user, expectedStatus: HttpStatusCode.OK_200 })
119
120 const user2 = { username: 'rOoT', password: server.store.user.password }
121 await server.login.login({ user: user2, expectedStatus: HttpStatusCode.OK_200 })
122
123 const user3 = { username: 'ROOt', password: server.store.user.password }
124 await server.login.login({ user: user3, expectedStatus: HttpStatusCode.OK_200 })
125 })
126 })
127
128 describe('Logout', function () {
129 it('Should logout (revoke token)', async function () {
130 await server.login.logout({ token: server.accessToken })
131 })
132
133 it('Should not be able to get the user information', async function () {
134 await server.users.getMyInfo({ expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
135 })
136
137 it('Should not be able to upload a video', async function () {
138 await server.videos.upload({ attributes: { name: 'video' }, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
139 })
140
141 it('Should not be able to rate a video', async function () {
142 const path = '/api/v1/videos/'
143 const data = {
144 rating: 'likes'
145 }
146
147 const options = {
148 url: server.url,
149 path: path + videoId,
150 token: 'wrong token',
151 fields: data,
152 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
153 }
154 await makePutBodyRequest(options)
155 })
156
157 it('Should be able to login again', async function () {
158 const body = await server.login.login()
159 server.accessToken = body.access_token
160 server.refreshToken = body.refresh_token
161 })
162
163 it('Should be able to get my user information again', async function () {
164 await server.users.getMyInfo()
165 })
166
167 it('Should have an expired access token', async function () {
168 this.timeout(60000)
169
170 await server.sql.setTokenField(server.accessToken, 'accessTokenExpiresAt', new Date().toISOString())
171 await server.sql.setTokenField(server.accessToken, 'refreshTokenExpiresAt', new Date().toISOString())
172
173 await killallServers([ server ])
174 await server.run()
175
176 await server.users.getMyInfo({ expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
177 })
178
179 it('Should not be able to refresh an access token with an expired refresh token', async function () {
180 await server.login.refreshToken({ refreshToken: server.refreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
181 })
182
183 it('Should refresh the token', async function () {
184 this.timeout(50000)
185
186 const futureDate = new Date(new Date().getTime() + 1000 * 60).toISOString()
187 await server.sql.setTokenField(server.accessToken, 'refreshTokenExpiresAt', futureDate)
188
189 await killallServers([ server ])
190 await server.run()
191
192 const res = await server.login.refreshToken({ refreshToken: server.refreshToken })
193 server.accessToken = res.body.access_token
194 server.refreshToken = res.body.refresh_token
195 })
196
197 it('Should be able to get my user information again', async function () {
198 await server.users.getMyInfo()
199 })
200 })
201
202 describe('Creating a user', function () { 35 describe('Creating a user', function () {
203 36
204 it('Should be able to create a new user', async function () { 37 it('Should be able to create a new user', async function () {
@@ -512,6 +345,7 @@ describe('Test users', function () {
512 }) 345 })
513 346
514 describe('Updating another user', function () { 347 describe('Updating another user', function () {
348
515 it('Should be able to update another user', async function () { 349 it('Should be able to update another user', async function () {
516 await server.users.update({ 350 await server.users.update({
517 userId, 351 userId,
@@ -562,13 +396,6 @@ describe('Test users', function () {
562 }) 396 })
563 }) 397 })
564 398
565 describe('Video blacklists', function () {
566
567 it('Should be able to list my video blacklist', async function () {
568 await server.blacklist.list({ token: userToken })
569 })
570 })
571
572 describe('Remove a user', function () { 399 describe('Remove a user', function () {
573 400
574 before(async function () { 401 before(async function () {
@@ -602,59 +429,10 @@ describe('Test users', function () {
602 }) 429 })
603 }) 430 })
604 431
605 describe('Registering a new user', function () {
606 let user15AccessToken: string
607
608 it('Should register a new user', async function () {
609 const user = { displayName: 'super user 15', username: 'user_15', password: 'my super password' }
610 const channel = { name: 'my_user_15_channel', displayName: 'my channel rocks' }
611
612 await server.users.register({ ...user, channel })
613 })
614
615 it('Should be able to login with this registered user', async function () {
616 const user15 = {
617 username: 'user_15',
618 password: 'my super password'
619 }
620
621 user15AccessToken = await server.login.getAccessToken(user15)
622 })
623
624 it('Should have the correct display name', async function () {
625 const user = await server.users.getMyInfo({ token: user15AccessToken })
626 expect(user.account.displayName).to.equal('super user 15')
627 })
628
629 it('Should have the correct video quota', async function () {
630 const user = await server.users.getMyInfo({ token: user15AccessToken })
631 expect(user.videoQuota).to.equal(5 * 1024 * 1024)
632 })
633
634 it('Should have created the channel', async function () {
635 const { displayName } = await server.channels.get({ channelName: 'my_user_15_channel' })
636
637 expect(displayName).to.equal('my channel rocks')
638 })
639
640 it('Should remove me', async function () {
641 {
642 const { data } = await server.users.list()
643 expect(data.find(u => u.username === 'user_15')).to.not.be.undefined
644 }
645
646 await server.users.deleteMe({ token: user15AccessToken })
647
648 {
649 const { data } = await server.users.list()
650 expect(data.find(u => u.username === 'user_15')).to.be.undefined
651 }
652 })
653 })
654
655 describe('User blocking', function () { 432 describe('User blocking', function () {
656 let user16Id 433 let user16Id: number
657 let user16AccessToken 434 let user16AccessToken: string
435
658 const user16 = { 436 const user16 = {
659 username: 'user_16', 437 username: 'user_16',
660 password: 'my super password' 438 password: 'my super password'
diff --git a/server/tests/api/videos/video-channel-syncs.ts b/server/tests/api/videos/video-channel-syncs.ts
index 91291524d..dd483f95e 100644
--- a/server/tests/api/videos/video-channel-syncs.ts
+++ b/server/tests/api/videos/video-channel-syncs.ts
@@ -307,6 +307,7 @@ describe('Test channel synchronizations', function () {
307 }) 307 })
308 } 308 }
309 309
310 runSuite('youtube-dl') 310 // FIXME: suite is broken with youtube-dl
311 // runSuite('youtube-dl')
311 runSuite('yt-dlp') 312 runSuite('yt-dlp')
312}) 313})
diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts
index dc47f8a4a..e35500b0b 100644
--- a/server/tests/api/videos/video-comments.ts
+++ b/server/tests/api/videos/video-comments.ts
@@ -38,6 +38,8 @@ describe('Test video comments', function () {
38 await setDefaultAccountAvatar(server) 38 await setDefaultAccountAvatar(server)
39 39
40 userAccessTokenServer1 = await server.users.generateUserAndToken('user1') 40 userAccessTokenServer1 = await server.users.generateUserAndToken('user1')
41 await setDefaultChannelAvatar(server, 'user1_channel')
42 await setDefaultAccountAvatar(server, userAccessTokenServer1)
41 43
42 command = server.comments 44 command = server.comments
43 }) 45 })
@@ -167,6 +169,13 @@ describe('Test video comments', function () {
167 expect(body.data[2].totalReplies).to.equal(0) 169 expect(body.data[2].totalReplies).to.equal(0)
168 }) 170 })
169 171
172 it('Should list the and sort them by total replies', async function () {
173 const body = await command.listThreads({ videoId: videoUUID, sort: 'totalReplies' })
174
175 expect(body.data[2].text).to.equal('my super first comment')
176 expect(body.data[2].totalReplies).to.equal(3)
177 })
178
170 it('Should delete a reply', async function () { 179 it('Should delete a reply', async function () {
171 await command.delete({ videoId, commentId: replyToDeleteId }) 180 await command.delete({ videoId, commentId: replyToDeleteId })
172 181
@@ -232,16 +241,34 @@ describe('Test video comments', function () {
232 await command.addReply({ videoId, toCommentId: threadId2, text: text3 }) 241 await command.addReply({ videoId, toCommentId: threadId2, text: text3 })
233 242
234 const tree = await command.getThread({ videoId: videoUUID, threadId: threadId2 }) 243 const tree = await command.getThread({ videoId: videoUUID, threadId: threadId2 })
235 expect(tree.comment.totalReplies).to.equal(tree.comment.totalRepliesFromVideoAuthor + 1) 244 expect(tree.comment.totalRepliesFromVideoAuthor).to.equal(1)
245 expect(tree.comment.totalReplies).to.equal(2)
236 }) 246 })
237 }) 247 })
238 248
239 describe('All instance comments', function () { 249 describe('All instance comments', function () {
240 250
241 it('Should list instance comments as admin', async function () { 251 it('Should list instance comments as admin', async function () {
242 const { data } = await command.listForAdmin({ start: 0, count: 1 }) 252 {
253 const { data, total } = await command.listForAdmin({ start: 0, count: 1 })
254
255 expect(total).to.equal(7)
256 expect(data).to.have.lengthOf(1)
257 expect(data[0].text).to.equal('my second answer to thread 4')
258 expect(data[0].account.name).to.equal('root')
259 expect(data[0].account.displayName).to.equal('root')
260 expect(data[0].account.avatars).to.have.lengthOf(2)
261 }
262
263 {
264 const { data, total } = await command.listForAdmin({ start: 1, count: 2 })
243 265
244 expect(data[0].text).to.equal('my second answer to thread 4') 266 expect(total).to.equal(7)
267 expect(data).to.have.lengthOf(2)
268
269 expect(data[0].account.avatars).to.have.lengthOf(2)
270 expect(data[1].account.avatars).to.have.lengthOf(2)
271 }
245 }) 272 })
246 273
247 it('Should filter instance comments by isLocal', async function () { 274 it('Should filter instance comments by isLocal', async function () {
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index 0583134b2..5636de45f 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -41,7 +41,7 @@ async function checkVideosServer1 (server: PeerTubeServer, idHttp: string, idMag
41 const videoTorrent = await server.videos.get({ id: idTorrent }) 41 const videoTorrent = await server.videos.get({ id: idTorrent })
42 42
43 for (const video of [ videoMagnet, videoTorrent ]) { 43 for (const video of [ videoMagnet, videoTorrent ]) {
44 expect(video.category.label).to.equal('Misc') 44 expect(video.category.label).to.equal('Unknown')
45 expect(video.licence.label).to.equal('Unknown') 45 expect(video.licence.label).to.equal('Unknown')
46 expect(video.language.label).to.equal('Unknown') 46 expect(video.language.label).to.equal('Unknown')
47 expect(video.nsfw).to.be.false 47 expect(video.nsfw).to.be.false
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts
index 6a18cf26a..e8e653382 100644
--- a/server/tests/api/videos/video-playlists.ts
+++ b/server/tests/api/videos/video-playlists.ts
@@ -3,6 +3,7 @@
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { checkPlaylistFilesWereRemoved, testImage } from '@server/tests/shared' 4import { checkPlaylistFilesWereRemoved, testImage } from '@server/tests/shared'
5import { wait } from '@shared/core-utils' 5import { wait } from '@shared/core-utils'
6import { uuidToShort } from '@shared/extra-utils'
6import { 7import {
7 HttpStatusCode, 8 HttpStatusCode,
8 VideoPlaylist, 9 VideoPlaylist,
@@ -23,7 +24,6 @@ import {
23 setDefaultVideoChannel, 24 setDefaultVideoChannel,
24 waitJobs 25 waitJobs
25} from '@shared/server-commands' 26} from '@shared/server-commands'
26import { uuidToShort } from '@shared/extra-utils'
27 27
28async function checkPlaylistElementType ( 28async function checkPlaylistElementType (
29 servers: PeerTubeServer[], 29 servers: PeerTubeServer[],
@@ -752,19 +752,6 @@ describe('Test video playlists', function () {
752 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 752 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
753 } 753 }
754 }) 754 })
755
756 it('Should hide the video if it is NSFW', async function () {
757 const body = await commands[0].listVideos({ token: userTokenServer1, playlistId: playlistServer1UUID2, query: { nsfw: 'false' } })
758 expect(body.total).to.equal(3)
759
760 const elements = body.data
761 const element = elements.find(e => e.position === 3)
762
763 expect(element).to.exist
764 expect(element.video).to.be.null
765 expect(element.type).to.equal(VideoPlaylistElementType.UNAVAILABLE)
766 })
767
768 }) 755 })
769 756
770 describe('Managing playlist elements', function () { 757 describe('Managing playlist elements', function () {
diff --git a/server/tests/external-plugins/akismet.ts b/server/tests/external-plugins/akismet.ts
index 974bf0011..e964bf0c2 100644
--- a/server/tests/external-plugins/akismet.ts
+++ b/server/tests/external-plugins/akismet.ts
@@ -138,14 +138,14 @@ describe('Official plugin Akismet', function () {
138 }) 138 })
139 139
140 it('Should allow signup', async function () { 140 it('Should allow signup', async function () {
141 await servers[0].users.register({ 141 await servers[0].registrations.register({
142 username: 'user1', 142 username: 'user1',
143 displayName: 'user 1' 143 displayName: 'user 1'
144 }) 144 })
145 }) 145 })
146 146
147 it('Should detect a signup as SPAM', async function () { 147 it('Should detect a signup as SPAM', async function () {
148 await servers[0].users.register({ 148 await servers[0].registrations.register({
149 username: 'user2', 149 username: 'user2',
150 displayName: 'user 2', 150 displayName: 'user 2',
151 email: 'akismet-guaranteed-spam@example.com', 151 email: 'akismet-guaranteed-spam@example.com',
diff --git a/server/tests/external-plugins/auto-block-videos.ts b/server/tests/external-plugins/auto-block-videos.ts
index d14587c38..cadd02e8d 100644
--- a/server/tests/external-plugins/auto-block-videos.ts
+++ b/server/tests/external-plugins/auto-block-videos.ts
@@ -30,7 +30,7 @@ describe('Official plugin auto-block videos', function () {
30 let port: number 30 let port: number
31 31
32 before(async function () { 32 before(async function () {
33 this.timeout(60000) 33 this.timeout(120000)
34 34
35 servers = await createMultipleServers(2) 35 servers = await createMultipleServers(2)
36 await setAccessTokensToServers(servers) 36 await setAccessTokensToServers(servers)
diff --git a/server/tests/external-plugins/auto-mute.ts b/server/tests/external-plugins/auto-mute.ts
index 440b58bfd..cfed76e88 100644
--- a/server/tests/external-plugins/auto-mute.ts
+++ b/server/tests/external-plugins/auto-mute.ts
@@ -21,7 +21,7 @@ describe('Official plugin auto-mute', function () {
21 let port: number 21 let port: number
22 22
23 before(async function () { 23 before(async function () {
24 this.timeout(30000) 24 this.timeout(120000)
25 25
26 servers = await createMultipleServers(2) 26 servers = await createMultipleServers(2)
27 await setAccessTokensToServers(servers) 27 await setAccessTokensToServers(servers)
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 906dab1a3..7345f728a 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -189,7 +189,7 @@ describe('Test syndication feeds', () => {
189 const jsonObj = JSON.parse(json) 189 const jsonObj = JSON.parse(json)
190 expect(jsonObj.items.length).to.be.equal(1) 190 expect(jsonObj.items.length).to.be.equal(1)
191 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 191 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
192 expect(jsonObj.items[0].author.name).to.equal('root') 192 expect(jsonObj.items[0].author.name).to.equal('Main root channel')
193 } 193 }
194 194
195 { 195 {
@@ -197,7 +197,7 @@ describe('Test syndication feeds', () => {
197 const jsonObj = JSON.parse(json) 197 const jsonObj = JSON.parse(json)
198 expect(jsonObj.items.length).to.be.equal(1) 198 expect(jsonObj.items.length).to.be.equal(1)
199 expect(jsonObj.items[0].title).to.equal('user video') 199 expect(jsonObj.items[0].title).to.equal('user video')
200 expect(jsonObj.items[0].author.name).to.equal('john') 200 expect(jsonObj.items[0].author.name).to.equal('Main john channel')
201 } 201 }
202 202
203 for (const server of servers) { 203 for (const server of servers) {
@@ -223,7 +223,7 @@ describe('Test syndication feeds', () => {
223 const jsonObj = JSON.parse(json) 223 const jsonObj = JSON.parse(json)
224 expect(jsonObj.items.length).to.be.equal(1) 224 expect(jsonObj.items.length).to.be.equal(1)
225 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 225 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
226 expect(jsonObj.items[0].author.name).to.equal('root') 226 expect(jsonObj.items[0].author.name).to.equal('Main root channel')
227 } 227 }
228 228
229 { 229 {
@@ -231,7 +231,7 @@ describe('Test syndication feeds', () => {
231 const jsonObj = JSON.parse(json) 231 const jsonObj = JSON.parse(json)
232 expect(jsonObj.items.length).to.be.equal(1) 232 expect(jsonObj.items.length).to.be.equal(1)
233 expect(jsonObj.items[0].title).to.equal('user video') 233 expect(jsonObj.items[0].title).to.equal('user video')
234 expect(jsonObj.items[0].author.name).to.equal('john') 234 expect(jsonObj.items[0].author.name).to.equal('Main john channel')
235 } 235 }
236 236
237 for (const server of servers) { 237 for (const server of servers) {
diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
index c65b8d3a8..58bc27661 100644
--- a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
@@ -33,7 +33,17 @@ async function register ({
33 username: 'kefka', 33 username: 'kefka',
34 email: 'kefka@example.com', 34 email: 'kefka@example.com',
35 role: 0, 35 role: 0,
36 displayName: 'Kefka Palazzo' 36 displayName: 'Kefka Palazzo',
37 adminFlags: 1,
38 videoQuota: 42000,
39 videoQuotaDaily: 42100,
40
41 // Always use new value except for videoQuotaDaily field
42 userUpdater: ({ fieldName, currentValue, newValue }) => {
43 if (fieldName === 'videoQuotaDaily') return currentValue
44
45 return newValue
46 }
37 }) 47 })
38 }, 48 },
39 hookTokenValidity: (options) => { 49 hookTokenValidity: (options) => {
diff --git a/server/tests/fixtures/peertube-plugin-test-four/main.js b/server/tests/fixtures/peertube-plugin-test-four/main.js
index 3e848c49e..b10177b45 100644
--- a/server/tests/fixtures/peertube-plugin-test-four/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-four/main.js
@@ -76,6 +76,12 @@ async function register ({
76 return res.json({ serverConfig }) 76 return res.json({ serverConfig })
77 }) 77 })
78 78
79 router.get('/server-listening-config', async (req, res) => {
80 const config = await peertubeHelpers.config.getServerListeningConfig()
81
82 return res.json({ config })
83 })
84
79 router.get('/static-route', async (req, res) => { 85 router.get('/static-route', async (req, res) => {
80 const staticRoute = peertubeHelpers.plugin.getBaseStaticRoute() 86 const staticRoute = peertubeHelpers.plugin.getBaseStaticRoute()
81 87
diff --git a/server/tests/fixtures/peertube-plugin-test-id-pass-auth-two/main.js b/server/tests/fixtures/peertube-plugin-test-id-pass-auth-two/main.js
index ceab7b60d..fad5abf60 100644
--- a/server/tests/fixtures/peertube-plugin-test-id-pass-auth-two/main.js
+++ b/server/tests/fixtures/peertube-plugin-test-id-pass-auth-two/main.js
@@ -33,7 +33,18 @@ async function register ({
33 if (body.id === 'laguna' && body.password === 'laguna password') { 33 if (body.id === 'laguna' && body.password === 'laguna password') {
34 return Promise.resolve({ 34 return Promise.resolve({
35 username: 'laguna', 35 username: 'laguna',
36 email: 'laguna@example.com' 36 email: 'laguna@example.com',
37 displayName: 'Laguna Loire',
38 adminFlags: 1,
39 videoQuota: 42000,
40 videoQuotaDaily: 42100,
41
42 // Always use new value except for videoQuotaDaily field
43 userUpdater: ({ fieldName, currentValue, newValue }) => {
44 if (fieldName === 'videoQuotaDaily') return currentValue
45
46 return newValue
47 }
37 }) 48 })
38 } 49 }
39 50
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js
index 19dccf26e..5b4d34f15 100644
--- a/server/tests/fixtures/peertube-plugin-test/main.js
+++ b/server/tests/fixtures/peertube-plugin-test/main.js
@@ -226,16 +226,29 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
226 } 226 }
227 }) 227 })
228 228
229 registerHook({ 229 {
230 target: 'filter:api.user.signup.allowed.result', 230 registerHook({
231 handler: (result, params) => { 231 target: 'filter:api.user.signup.allowed.result',
232 if (params && params.body && params.body.email && params.body.email.includes('jma')) { 232 handler: (result, params) => {
233 return { allowed: false, errorMessage: 'No jma' } 233 if (params && params.body && params.body.email && params.body.email.includes('jma 1')) {
234 return { allowed: false, errorMessage: 'No jma 1' }
235 }
236
237 return result
234 } 238 }
239 })
235 240
236 return result 241 registerHook({
237 } 242 target: 'filter:api.user.request-signup.allowed.result',
238 }) 243 handler: (result, params) => {
244 if (params && params.body && params.body.email && params.body.email.includes('jma 2')) {
245 return { allowed: false, errorMessage: 'No jma 2' }
246 }
247
248 return result
249 }
250 })
251 }
239 252
240 registerHook({ 253 registerHook({
241 target: 'filter:api.download.torrent.allowed.result', 254 target: 'filter:api.download.torrent.allowed.result',
@@ -250,7 +263,10 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
250 263
251 registerHook({ 264 registerHook({
252 target: 'filter:api.download.video.allowed.result', 265 target: 'filter:api.download.video.allowed.result',
253 handler: (result, params) => { 266 handler: async (result, params) => {
267 const loggedInUser = await peertubeHelpers.user.getAuthUser(params.res)
268 if (loggedInUser) return { allowed: true }
269
254 if (params && !params.streamingPlaylist && params.video.name.includes('bad file')) { 270 if (params && !params.streamingPlaylist && params.video.name.includes('bad file')) {
255 return { allowed: false, errorMessage: 'Cao Cao' } 271 return { allowed: false, errorMessage: 'Cao Cao' }
256 } 272 }
diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts
index 1b5c6d15b..073ae6455 100644
--- a/server/tests/helpers/index.ts
+++ b/server/tests/helpers/index.ts
@@ -6,3 +6,4 @@ import './image'
6import './markdown' 6import './markdown'
7import './request' 7import './request'
8import './validator' 8import './validator'
9import './version'
diff --git a/server/tests/helpers/version.ts b/server/tests/helpers/version.ts
new file mode 100644
index 000000000..2a90efba3
--- /dev/null
+++ b/server/tests/helpers/version.ts
@@ -0,0 +1,36 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { compareSemVer } from '@shared/core-utils'
5
6describe('Version', function () {
7
8 it('Should correctly compare two stable versions', async function () {
9 expect(compareSemVer('3.4.0', '3.5.0')).to.be.below(0)
10 expect(compareSemVer('3.5.0', '3.4.0')).to.be.above(0)
11
12 expect(compareSemVer('3.4.0', '4.1.0')).to.be.below(0)
13 expect(compareSemVer('4.1.0', '3.4.0')).to.be.above(0)
14
15 expect(compareSemVer('3.4.0', '3.4.1')).to.be.below(0)
16 expect(compareSemVer('3.4.1', '3.4.0')).to.be.above(0)
17 })
18
19 it('Should correctly compare two unstable version', async function () {
20 expect(compareSemVer('3.4.0-alpha', '3.4.0-beta.1')).to.be.below(0)
21 expect(compareSemVer('3.4.0-alpha.1', '3.4.0-beta.1')).to.be.below(0)
22 expect(compareSemVer('3.4.0-beta.1', '3.4.0-beta.2')).to.be.below(0)
23 expect(compareSemVer('3.4.0-beta.1', '3.5.0-alpha.1')).to.be.below(0)
24
25 expect(compareSemVer('3.4.0-alpha.1', '3.4.0-nightly.4')).to.be.below(0)
26 expect(compareSemVer('3.4.0-nightly.3', '3.4.0-nightly.4')).to.be.below(0)
27 expect(compareSemVer('3.3.0-nightly.5', '3.4.0-nightly.4')).to.be.below(0)
28 })
29
30 it('Should correctly compare a stable and unstable versions', async function () {
31 expect(compareSemVer('3.4.0', '3.4.1-beta.1')).to.be.below(0)
32 expect(compareSemVer('3.4.0-beta.1', '3.4.0-beta.2')).to.be.below(0)
33 expect(compareSemVer('3.4.0-beta.1', '3.4.0')).to.be.below(0)
34 expect(compareSemVer('3.4.0-nightly.4', '3.4.0')).to.be.below(0)
35 })
36})
diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts
index 36f8052c0..a266ae7f1 100644
--- a/server/tests/plugins/action-hooks.ts
+++ b/server/tests/plugins/action-hooks.ts
@@ -153,7 +153,7 @@ describe('Test plugin action hooks', function () {
153 let userId: number 153 let userId: number
154 154
155 it('Should run action:api.user.registered', async function () { 155 it('Should run action:api.user.registered', async function () {
156 await servers[0].users.register({ username: 'registered_user' }) 156 await servers[0].registrations.register({ username: 'registered_user' })
157 157
158 await checkHook('action:api.user.registered') 158 await checkHook('action:api.user.registered')
159 }) 159 })
diff --git a/server/tests/plugins/external-auth.ts b/server/tests/plugins/external-auth.ts
index 437777e90..e600f958f 100644
--- a/server/tests/plugins/external-auth.ts
+++ b/server/tests/plugins/external-auth.ts
@@ -2,7 +2,7 @@
2 2
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { wait } from '@shared/core-utils' 4import { wait } from '@shared/core-utils'
5import { HttpStatusCode, UserRole } from '@shared/models' 5import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models'
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 createSingleServer, 8 createSingleServer,
@@ -51,6 +51,7 @@ describe('Test external auth plugins', function () {
51 51
52 let kefkaAccessToken: string 52 let kefkaAccessToken: string
53 let kefkaRefreshToken: string 53 let kefkaRefreshToken: string
54 let kefkaId: number
54 55
55 let externalAuthToken: string 56 let externalAuthToken: string
56 57
@@ -156,6 +157,9 @@ describe('Test external auth plugins', function () {
156 expect(body.account.displayName).to.equal('cyan') 157 expect(body.account.displayName).to.equal('cyan')
157 expect(body.email).to.equal('cyan@example.com') 158 expect(body.email).to.equal('cyan@example.com')
158 expect(body.role.id).to.equal(UserRole.USER) 159 expect(body.role.id).to.equal(UserRole.USER)
160 expect(body.adminFlags).to.equal(UserAdminFlag.NONE)
161 expect(body.videoQuota).to.equal(5242880)
162 expect(body.videoQuotaDaily).to.equal(-1)
159 } 163 }
160 }) 164 })
161 165
@@ -178,6 +182,11 @@ describe('Test external auth plugins', function () {
178 expect(body.account.displayName).to.equal('Kefka Palazzo') 182 expect(body.account.displayName).to.equal('Kefka Palazzo')
179 expect(body.email).to.equal('kefka@example.com') 183 expect(body.email).to.equal('kefka@example.com')
180 expect(body.role.id).to.equal(UserRole.ADMINISTRATOR) 184 expect(body.role.id).to.equal(UserRole.ADMINISTRATOR)
185 expect(body.adminFlags).to.equal(UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST)
186 expect(body.videoQuota).to.equal(42000)
187 expect(body.videoQuotaDaily).to.equal(42100)
188
189 kefkaId = body.id
181 } 190 }
182 }) 191 })
183 192
@@ -240,6 +249,37 @@ describe('Test external auth plugins', function () {
240 expect(body.role.id).to.equal(UserRole.USER) 249 expect(body.role.id).to.equal(UserRole.USER)
241 }) 250 })
242 251
252 it('Should login Kefka and update the profile', async function () {
253 {
254 await server.users.update({ userId: kefkaId, videoQuota: 43000, videoQuotaDaily: 43100 })
255 await server.users.updateMe({ token: kefkaAccessToken, displayName: 'kefka updated' })
256
257 const body = await server.users.getMyInfo({ token: kefkaAccessToken })
258 expect(body.username).to.equal('kefka')
259 expect(body.account.displayName).to.equal('kefka updated')
260 expect(body.videoQuota).to.equal(43000)
261 expect(body.videoQuotaDaily).to.equal(43100)
262 }
263
264 {
265 const res = await loginExternal({
266 server,
267 npmName: 'test-external-auth-one',
268 authName: 'external-auth-2',
269 username: 'kefka'
270 })
271
272 kefkaAccessToken = res.access_token
273 kefkaRefreshToken = res.refresh_token
274
275 const body = await server.users.getMyInfo({ token: kefkaAccessToken })
276 expect(body.username).to.equal('kefka')
277 expect(body.account.displayName).to.equal('Kefka Palazzo')
278 expect(body.videoQuota).to.equal(42000)
279 expect(body.videoQuotaDaily).to.equal(43100)
280 }
281 })
282
243 it('Should not update an external auth email', async function () { 283 it('Should not update an external auth email', async function () {
244 await server.users.updateMe({ 284 await server.users.updateMe({
245 token: cyanAccessToken, 285 token: cyanAccessToken,
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts
index 083fd43ca..37eef6cf3 100644
--- a/server/tests/plugins/filter-hooks.ts
+++ b/server/tests/plugins/filter-hooks.ts
@@ -1,7 +1,15 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { HttpStatusCode, VideoDetails, VideoImportState, VideoPlaylist, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' 4import {
5 HttpStatusCode,
6 PeerTubeProblemDocument,
7 VideoDetails,
8 VideoImportState,
9 VideoPlaylist,
10 VideoPlaylistPrivacy,
11 VideoPrivacy
12} from '@shared/models'
5import { 13import {
6 cleanupTests, 14 cleanupTests,
7 createMultipleServers, 15 createMultipleServers,
@@ -408,28 +416,58 @@ describe('Test plugin filter hooks', function () {
408 416
409 describe('Should run filter:api.user.signup.allowed.result', function () { 417 describe('Should run filter:api.user.signup.allowed.result', function () {
410 418
419 before(async function () {
420 await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: false } } })
421 })
422
411 it('Should run on config endpoint', async function () { 423 it('Should run on config endpoint', async function () {
412 const body = await servers[0].config.getConfig() 424 const body = await servers[0].config.getConfig()
413 expect(body.signup.allowed).to.be.true 425 expect(body.signup.allowed).to.be.true
414 }) 426 })
415 427
416 it('Should allow a signup', async function () { 428 it('Should allow a signup', async function () {
417 await servers[0].users.register({ username: 'john', password: 'password' }) 429 await servers[0].registrations.register({ username: 'john1' })
418 }) 430 })
419 431
420 it('Should not allow a signup', async function () { 432 it('Should not allow a signup', async function () {
421 const res = await servers[0].users.register({ 433 const res = await servers[0].registrations.register({
422 username: 'jma', 434 username: 'jma 1',
423 password: 'password',
424 expectedStatus: HttpStatusCode.FORBIDDEN_403 435 expectedStatus: HttpStatusCode.FORBIDDEN_403
425 }) 436 })
426 437
427 expect(res.body.error).to.equal('No jma') 438 expect(res.body.error).to.equal('No jma 1')
439 })
440 })
441
442 describe('Should run filter:api.user.request-signup.allowed.result', function () {
443
444 before(async function () {
445 await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: true } } })
446 })
447
448 it('Should run on config endpoint', async function () {
449 const body = await servers[0].config.getConfig()
450 expect(body.signup.allowed).to.be.true
451 })
452
453 it('Should allow a signup request', async function () {
454 await servers[0].registrations.requestRegistration({ username: 'john2', registrationReason: 'tt' })
455 })
456
457 it('Should not allow a signup request', async function () {
458 const body = await servers[0].registrations.requestRegistration({
459 username: 'jma 2',
460 registrationReason: 'tt',
461 expectedStatus: HttpStatusCode.FORBIDDEN_403
462 })
463
464 expect((body as unknown as PeerTubeProblemDocument).error).to.equal('No jma 2')
428 }) 465 })
429 }) 466 })
430 467
431 describe('Download hooks', function () { 468 describe('Download hooks', function () {
432 const downloadVideos: VideoDetails[] = [] 469 const downloadVideos: VideoDetails[] = []
470 let downloadVideo2Token: string
433 471
434 before(async function () { 472 before(async function () {
435 this.timeout(120000) 473 this.timeout(120000)
@@ -459,6 +497,8 @@ describe('Test plugin filter hooks', function () {
459 for (const uuid of uuids) { 497 for (const uuid of uuids) {
460 downloadVideos.push(await servers[0].videos.get({ id: uuid })) 498 downloadVideos.push(await servers[0].videos.get({ id: uuid }))
461 } 499 }
500
501 downloadVideo2Token = await servers[0].videoToken.getVideoFileToken({ videoId: downloadVideos[2].uuid })
462 }) 502 })
463 503
464 it('Should run filter:api.download.torrent.allowed.result', async function () { 504 it('Should run filter:api.download.torrent.allowed.result', async function () {
@@ -471,32 +511,42 @@ describe('Test plugin filter hooks', function () {
471 511
472 it('Should run filter:api.download.video.allowed.result', async function () { 512 it('Should run filter:api.download.video.allowed.result', async function () {
473 { 513 {
474 const res = await makeRawRequest({ url: downloadVideos[1].files[0].fileDownloadUrl, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) 514 const refused = downloadVideos[1].files[0].fileDownloadUrl
515 const allowed = [
516 downloadVideos[0].files[0].fileDownloadUrl,
517 downloadVideos[2].files[0].fileDownloadUrl
518 ]
519
520 const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
475 expect(res.body.error).to.equal('Cao Cao') 521 expect(res.body.error).to.equal('Cao Cao')
476 522
477 await makeRawRequest({ url: downloadVideos[0].files[0].fileDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }) 523 for (const url of allowed) {
478 await makeRawRequest({ url: downloadVideos[2].files[0].fileDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }) 524 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
525 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
526 }
479 } 527 }
480 528
481 { 529 {
482 const res = await makeRawRequest({ 530 const refused = downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl
483 url: downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl,
484 expectedStatus: HttpStatusCode.FORBIDDEN_403
485 })
486 531
487 expect(res.body.error).to.equal('Sun Jian') 532 const allowed = [
533 downloadVideos[2].files[0].fileDownloadUrl,
534 downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl,
535 downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl
536 ]
488 537
489 await makeRawRequest({ url: downloadVideos[2].files[0].fileDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }) 538 // Only streaming playlist is refuse
539 const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
540 expect(res.body.error).to.equal('Sun Jian')
490 541
491 await makeRawRequest({ 542 // But not we there is a user in res
492 url: downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl, 543 await makeRawRequest({ url: refused, token: servers[0].accessToken, expectedStatus: HttpStatusCode.OK_200 })
493 expectedStatus: HttpStatusCode.OK_200 544 await makeRawRequest({ url: refused, query: { videoFileToken: downloadVideo2Token }, expectedStatus: HttpStatusCode.OK_200 })
494 })
495 545
496 await makeRawRequest({ 546 // Other files work
497 url: downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl, 547 for (const url of allowed) {
498 expectedStatus: HttpStatusCode.OK_200 548 await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 })
499 }) 549 }
500 } 550 }
501 }) 551 })
502 }) 552 })
diff --git a/server/tests/plugins/id-and-pass-auth.ts b/server/tests/plugins/id-and-pass-auth.ts
index fc24a5656..10155c28b 100644
--- a/server/tests/plugins/id-and-pass-auth.ts
+++ b/server/tests/plugins/id-and-pass-auth.ts
@@ -13,6 +13,7 @@ describe('Test id and pass auth plugins', function () {
13 13
14 let lagunaAccessToken: string 14 let lagunaAccessToken: string
15 let lagunaRefreshToken: string 15 let lagunaRefreshToken: string
16 let lagunaId: number
16 17
17 before(async function () { 18 before(async function () {
18 this.timeout(30000) 19 this.timeout(30000)
@@ -78,8 +79,10 @@ describe('Test id and pass auth plugins', function () {
78 const body = await server.users.getMyInfo({ token: lagunaAccessToken }) 79 const body = await server.users.getMyInfo({ token: lagunaAccessToken })
79 80
80 expect(body.username).to.equal('laguna') 81 expect(body.username).to.equal('laguna')
81 expect(body.account.displayName).to.equal('laguna') 82 expect(body.account.displayName).to.equal('Laguna Loire')
82 expect(body.role.id).to.equal(UserRole.USER) 83 expect(body.role.id).to.equal(UserRole.USER)
84
85 lagunaId = body.id
83 } 86 }
84 }) 87 })
85 88
@@ -132,6 +135,33 @@ describe('Test id and pass auth plugins', function () {
132 expect(body.role.id).to.equal(UserRole.MODERATOR) 135 expect(body.role.id).to.equal(UserRole.MODERATOR)
133 }) 136 })
134 137
138 it('Should login Laguna and update the profile', async function () {
139 {
140 await server.users.update({ userId: lagunaId, videoQuota: 43000, videoQuotaDaily: 43100 })
141 await server.users.updateMe({ token: lagunaAccessToken, displayName: 'laguna updated' })
142
143 const body = await server.users.getMyInfo({ token: lagunaAccessToken })
144 expect(body.username).to.equal('laguna')
145 expect(body.account.displayName).to.equal('laguna updated')
146 expect(body.videoQuota).to.equal(43000)
147 expect(body.videoQuotaDaily).to.equal(43100)
148 }
149
150 {
151 const body = await server.login.login({ user: { username: 'laguna', password: 'laguna password' } })
152 lagunaAccessToken = body.access_token
153 lagunaRefreshToken = body.refresh_token
154 }
155
156 {
157 const body = await server.users.getMyInfo({ token: lagunaAccessToken })
158 expect(body.username).to.equal('laguna')
159 expect(body.account.displayName).to.equal('Laguna Loire')
160 expect(body.videoQuota).to.equal(42000)
161 expect(body.videoQuotaDaily).to.equal(43100)
162 }
163 })
164
135 it('Should reject token of laguna by the plugin hook', async function () { 165 it('Should reject token of laguna by the plugin hook', async function () {
136 this.timeout(10000) 166 this.timeout(10000)
137 167
@@ -147,7 +177,7 @@ describe('Test id and pass auth plugins', function () {
147 await server.servers.waitUntilLog('valid username') 177 await server.servers.waitUntilLog('valid username')
148 178
149 await command.login({ user: { username: 'kiros', password: 'kiros password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) 179 await command.login({ user: { username: 'kiros', password: 'kiros password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
150 await server.servers.waitUntilLog('valid display name') 180 await server.servers.waitUntilLog('valid displayName')
151 181
152 await command.login({ user: { username: 'raine', password: 'raine password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) 182 await command.login({ user: { username: 'raine', password: 'raine password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
153 await server.servers.waitUntilLog('valid role') 183 await server.servers.waitUntilLog('valid role')
diff --git a/server/tests/plugins/plugin-helpers.ts b/server/tests/plugins/plugin-helpers.ts
index 038e3f0d6..e25992723 100644
--- a/server/tests/plugins/plugin-helpers.ts
+++ b/server/tests/plugins/plugin-helpers.ts
@@ -64,6 +64,18 @@ describe('Test plugin helpers', function () {
64 await servers[0].servers.waitUntilLog(`server url is ${servers[0].url}`) 64 await servers[0].servers.waitUntilLog(`server url is ${servers[0].url}`)
65 }) 65 })
66 66
67 it('Should have the correct listening config', async function () {
68 const res = await makeGetRequest({
69 url: servers[0].url,
70 path: '/plugins/test-four/router/server-listening-config',
71 expectedStatus: HttpStatusCode.OK_200
72 })
73
74 expect(res.body.config).to.exist
75 expect(res.body.config.hostname).to.equal('::')
76 expect(res.body.config.port).to.equal(servers[0].port)
77 })
78
67 it('Should have the correct config', async function () { 79 it('Should have the correct config', async function () {
68 const res = await makeGetRequest({ 80 const res = await makeGetRequest({
69 url: servers[0].url, 81 url: servers[0].url,
diff --git a/server/tests/shared/notifications.ts b/server/tests/shared/notifications.ts
index e600bd6b2..6c0688d5a 100644
--- a/server/tests/shared/notifications.ts
+++ b/server/tests/shared/notifications.ts
@@ -11,6 +11,7 @@ import {
11 UserNotificationType 11 UserNotificationType
12} from '@shared/models' 12} from '@shared/models'
13import { 13import {
14 ConfigCommand,
14 createMultipleServers, 15 createMultipleServers,
15 doubleFollow, 16 doubleFollow,
16 PeerTubeServer, 17 PeerTubeServer,
@@ -173,6 +174,8 @@ async function checkMyVideoImportIsFinished (options: CheckerBaseParams & {
173 await checkNotification({ ...options, notificationChecker, emailNotificationFinder }) 174 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
174} 175}
175 176
177// ---------------------------------------------------------------------------
178
176async function checkUserRegistered (options: CheckerBaseParams & { 179async function checkUserRegistered (options: CheckerBaseParams & {
177 username: string 180 username: string
178 checkType: CheckerType 181 checkType: CheckerType
@@ -201,6 +204,36 @@ async function checkUserRegistered (options: CheckerBaseParams & {
201 await checkNotification({ ...options, notificationChecker, emailNotificationFinder }) 204 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
202} 205}
203 206
207async function checkRegistrationRequest (options: CheckerBaseParams & {
208 username: string
209 registrationReason: string
210 checkType: CheckerType
211}) {
212 const { username, registrationReason } = options
213 const notificationType = UserNotificationType.NEW_USER_REGISTRATION_REQUEST
214
215 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
216 if (checkType === 'presence') {
217 expect(notification).to.not.be.undefined
218 expect(notification.type).to.equal(notificationType)
219
220 expect(notification.registration.username).to.equal(username)
221 } else {
222 expect(notification).to.satisfy(n => n.type !== notificationType || n.registration.username !== username)
223 }
224 }
225
226 function emailNotificationFinder (email: object) {
227 const text: string = email['text']
228
229 return text.includes(' wants to register ') && text.includes(username) && text.includes(registrationReason)
230 }
231
232 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
233}
234
235// ---------------------------------------------------------------------------
236
204async function checkNewActorFollow (options: CheckerBaseParams & { 237async function checkNewActorFollow (options: CheckerBaseParams & {
205 followType: 'channel' | 'account' 238 followType: 'channel' | 'account'
206 followerName: string 239 followerName: string
@@ -673,10 +706,8 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
673 const port = await MockSmtpServer.Instance.collectEmails(emails) 706 const port = await MockSmtpServer.Instance.collectEmails(emails)
674 707
675 const overrideConfig = { 708 const overrideConfig = {
676 smtp: { 709 ...ConfigCommand.getEmailOverrideConfig(port),
677 hostname: '127.0.0.1', 710
678 port
679 },
680 signup: { 711 signup: {
681 limit: 20 712 limit: 20
682 } 713 }
@@ -735,7 +766,8 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
735 userAccessToken, 766 userAccessToken,
736 emails, 767 emails,
737 servers, 768 servers,
738 channelId 769 channelId,
770 baseOverrideConfig: overrideConfig
739 } 771 }
740} 772}
741 773
@@ -765,7 +797,8 @@ export {
765 checkNewAccountAbuseForModerators, 797 checkNewAccountAbuseForModerators,
766 checkNewPeerTubeVersion, 798 checkNewPeerTubeVersion,
767 checkNewPluginVersion, 799 checkNewPluginVersion,
768 checkVideoStudioEditionIsFinished 800 checkVideoStudioEditionIsFinished,
801 checkRegistrationRequest
769} 802}
770 803
771// --------------------------------------------------------------------------- 804// ---------------------------------------------------------------------------
diff --git a/server/tests/shared/videos.ts b/server/tests/shared/videos.ts
index c8339584b..f8ec65752 100644
--- a/server/tests/shared/videos.ts
+++ b/server/tests/shared/videos.ts
@@ -59,7 +59,7 @@ async function completeVideoCheck (
59 59
60 expect(video.name).to.equal(attributes.name) 60 expect(video.name).to.equal(attributes.name)
61 expect(video.category.id).to.equal(attributes.category) 61 expect(video.category.id).to.equal(attributes.category)
62 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc') 62 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Unknown')
63 expect(video.licence.id).to.equal(attributes.licence) 63 expect(video.licence.id).to.equal(attributes.licence)
64 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown') 64 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
65 expect(video.language.id).to.equal(attributes.language) 65 expect(video.language.id).to.equal(attributes.language)