aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/utils/users
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-02-11 11:52:34 +0100
committerChocobozzz <me@florianbigard.com>2019-02-11 11:52:34 +0100
commit88108880bbdba473cfe36ecbebc1c3c4f972e102 (patch)
treeb242efb3b4f0d7e49d88f2d1f2063b5b3b0489c0 /shared/utils/users
parent53a94c7cfa8368da4cd248d65df8346905938f0c (diff)
parent9b712a2017e4ab3cf12cd6bd58278905520159d0 (diff)
downloadPeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.gz
PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.zst
PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.zip
Merge branch 'develop' into pr/1217
Diffstat (limited to 'shared/utils/users')
-rw-r--r--shared/utils/users/accounts.ts63
-rw-r--r--shared/utils/users/blocklist.ts197
-rw-r--r--shared/utils/users/login.ts62
-rw-r--r--shared/utils/users/user-notifications.ts437
-rw-r--r--shared/utils/users/user-subscriptions.ts82
-rw-r--r--shared/utils/users/users.ts304
6 files changed, 1145 insertions, 0 deletions
diff --git a/shared/utils/users/accounts.ts b/shared/utils/users/accounts.ts
new file mode 100644
index 000000000..388eb6973
--- /dev/null
+++ b/shared/utils/users/accounts.ts
@@ -0,0 +1,63 @@
1/* tslint:disable:no-unused-expression */
2
3import { expect } from 'chai'
4import { existsSync, readdir } from 'fs-extra'
5import { join } from 'path'
6import { Account } from '../../models/actors'
7import { root } from '../miscs/miscs'
8import { makeGetRequest } from '../requests/requests'
9
10function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
11 const path = '/api/v1/accounts'
12
13 return makeGetRequest({
14 url,
15 query: { sort },
16 path,
17 statusCodeExpected
18 })
19}
20
21function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
22 const path = '/api/v1/accounts/' + accountName
23
24 return makeGetRequest({
25 url,
26 path,
27 statusCodeExpected
28 })
29}
30
31async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
32 const res = await getAccountsList(url)
33 const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
34
35 const message = `${nameWithDomain} on ${url}`
36 expect(account.followersCount).to.equal(followersCount, message)
37 expect(account.followingCount).to.equal(followingCount, message)
38}
39
40async function checkActorFilesWereRemoved (actorUUID: string, serverNumber: number) {
41 const testDirectory = 'test' + serverNumber
42
43 for (const directory of [ 'avatars' ]) {
44 const directoryPath = join(root(), testDirectory, directory)
45
46 const directoryExists = existsSync(directoryPath)
47 expect(directoryExists).to.be.true
48
49 const files = await readdir(directoryPath)
50 for (const file of files) {
51 expect(file).to.not.contain(actorUUID)
52 }
53 }
54}
55
56// ---------------------------------------------------------------------------
57
58export {
59 getAccount,
60 expectAccountFollows,
61 getAccountsList,
62 checkActorFilesWereRemoved
63}
diff --git a/shared/utils/users/blocklist.ts b/shared/utils/users/blocklist.ts
new file mode 100644
index 000000000..5feb84179
--- /dev/null
+++ b/shared/utils/users/blocklist.ts
@@ -0,0 +1,197 @@
1/* tslint:disable:no-unused-expression */
2
3import { makeGetRequest, makeDeleteRequest, makePostBodyRequest } from '../requests/requests'
4
5function getAccountBlocklistByAccount (
6 url: string,
7 token: string,
8 start: number,
9 count: number,
10 sort = '-createdAt',
11 statusCodeExpected = 200
12) {
13 const path = '/api/v1/users/me/blocklist/accounts'
14
15 return makeGetRequest({
16 url,
17 token,
18 query: { start, count, sort },
19 path,
20 statusCodeExpected
21 })
22}
23
24function addAccountToAccountBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
25 const path = '/api/v1/users/me/blocklist/accounts'
26
27 return makePostBodyRequest({
28 url,
29 path,
30 token,
31 fields: {
32 accountName: accountToBlock
33 },
34 statusCodeExpected
35 })
36}
37
38function removeAccountFromAccountBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
39 const path = '/api/v1/users/me/blocklist/accounts/' + accountToUnblock
40
41 return makeDeleteRequest({
42 url,
43 path,
44 token,
45 statusCodeExpected
46 })
47}
48
49function getServerBlocklistByAccount (
50 url: string,
51 token: string,
52 start: number,
53 count: number,
54 sort = '-createdAt',
55 statusCodeExpected = 200
56) {
57 const path = '/api/v1/users/me/blocklist/servers'
58
59 return makeGetRequest({
60 url,
61 token,
62 query: { start, count, sort },
63 path,
64 statusCodeExpected
65 })
66}
67
68function addServerToAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
69 const path = '/api/v1/users/me/blocklist/servers'
70
71 return makePostBodyRequest({
72 url,
73 path,
74 token,
75 fields: {
76 host: serverToBlock
77 },
78 statusCodeExpected
79 })
80}
81
82function removeServerFromAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
83 const path = '/api/v1/users/me/blocklist/servers/' + serverToBlock
84
85 return makeDeleteRequest({
86 url,
87 path,
88 token,
89 statusCodeExpected
90 })
91}
92
93function getAccountBlocklistByServer (
94 url: string,
95 token: string,
96 start: number,
97 count: number,
98 sort = '-createdAt',
99 statusCodeExpected = 200
100) {
101 const path = '/api/v1/server/blocklist/accounts'
102
103 return makeGetRequest({
104 url,
105 token,
106 query: { start, count, sort },
107 path,
108 statusCodeExpected
109 })
110}
111
112function addAccountToServerBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
113 const path = '/api/v1/server/blocklist/accounts'
114
115 return makePostBodyRequest({
116 url,
117 path,
118 token,
119 fields: {
120 accountName: accountToBlock
121 },
122 statusCodeExpected
123 })
124}
125
126function removeAccountFromServerBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
127 const path = '/api/v1/server/blocklist/accounts/' + accountToUnblock
128
129 return makeDeleteRequest({
130 url,
131 path,
132 token,
133 statusCodeExpected
134 })
135}
136
137function getServerBlocklistByServer (
138 url: string,
139 token: string,
140 start: number,
141 count: number,
142 sort = '-createdAt',
143 statusCodeExpected = 200
144) {
145 const path = '/api/v1/server/blocklist/servers'
146
147 return makeGetRequest({
148 url,
149 token,
150 query: { start, count, sort },
151 path,
152 statusCodeExpected
153 })
154}
155
156function addServerToServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
157 const path = '/api/v1/server/blocklist/servers'
158
159 return makePostBodyRequest({
160 url,
161 path,
162 token,
163 fields: {
164 host: serverToBlock
165 },
166 statusCodeExpected
167 })
168}
169
170function removeServerFromServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
171 const path = '/api/v1/server/blocklist/servers/' + serverToBlock
172
173 return makeDeleteRequest({
174 url,
175 path,
176 token,
177 statusCodeExpected
178 })
179}
180
181// ---------------------------------------------------------------------------
182
183export {
184 getAccountBlocklistByAccount,
185 addAccountToAccountBlocklist,
186 removeAccountFromAccountBlocklist,
187 getServerBlocklistByAccount,
188 addServerToAccountBlocklist,
189 removeServerFromAccountBlocklist,
190
191 getAccountBlocklistByServer,
192 addAccountToServerBlocklist,
193 removeAccountFromServerBlocklist,
194 getServerBlocklistByServer,
195 addServerToServerBlocklist,
196 removeServerFromServerBlocklist
197}
diff --git a/shared/utils/users/login.ts b/shared/utils/users/login.ts
new file mode 100644
index 000000000..ddeb9df2a
--- /dev/null
+++ b/shared/utils/users/login.ts
@@ -0,0 +1,62 @@
1import * as request from 'supertest'
2
3import { ServerInfo } from '../server/servers'
4
5type Client = { id: string, secret: string }
6type User = { username: string, password: string }
7type Server = { url: string, client: Client, user: User }
8
9function login (url: string, client: Client, user: User, expectedStatus = 200) {
10 const path = '/api/v1/users/token'
11
12 const body = {
13 client_id: client.id,
14 client_secret: client.secret,
15 username: user.username,
16 password: user.password,
17 response_type: 'code',
18 grant_type: 'password',
19 scope: 'upload'
20 }
21
22 return request(url)
23 .post(path)
24 .type('form')
25 .send(body)
26 .expect(expectedStatus)
27}
28
29async function serverLogin (server: Server) {
30 const res = await login(server.url, server.client, server.user, 200)
31
32 return res.body.access_token as string
33}
34
35async function userLogin (server: Server, user: User, expectedStatus = 200) {
36 const res = await login(server.url, server.client, user, expectedStatus)
37
38 return res.body.access_token as string
39}
40
41function setAccessTokensToServers (servers: ServerInfo[]) {
42 const tasks: Promise<any>[] = []
43
44 for (const server of servers) {
45 const p = serverLogin(server).then(t => server.accessToken = t)
46 tasks.push(p)
47 }
48
49 return Promise.all(tasks)
50}
51
52// ---------------------------------------------------------------------------
53
54export {
55 login,
56 serverLogin,
57 userLogin,
58 setAccessTokensToServers,
59 Server,
60 Client,
61 User
62}
diff --git a/shared/utils/users/user-notifications.ts b/shared/utils/users/user-notifications.ts
new file mode 100644
index 000000000..c8ed7df30
--- /dev/null
+++ b/shared/utils/users/user-notifications.ts
@@ -0,0 +1,437 @@
1/* tslint:disable:no-unused-expression */
2
3import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
4import { UserNotification, UserNotificationSetting, UserNotificationType } from '../../models/users'
5import { ServerInfo } from '..'
6import { expect } from 'chai'
7import { inspect } from 'util'
8
9function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) {
10 const path = '/api/v1/users/me/notification-settings'
11
12 return makePutBodyRequest({
13 url,
14 path,
15 token,
16 fields: settings,
17 statusCodeExpected
18 })
19}
20
21function getUserNotifications (
22 url: string,
23 token: string,
24 start: number,
25 count: number,
26 unread?: boolean,
27 sort = '-createdAt',
28 statusCodeExpected = 200
29) {
30 const path = '/api/v1/users/me/notifications'
31
32 return makeGetRequest({
33 url,
34 path,
35 token,
36 query: {
37 start,
38 count,
39 sort,
40 unread
41 },
42 statusCodeExpected
43 })
44}
45
46function markAsReadNotifications (url: string, token: string, ids: number[], statusCodeExpected = 204) {
47 const path = '/api/v1/users/me/notifications/read'
48
49 return makePostBodyRequest({
50 url,
51 path,
52 token,
53 fields: { ids },
54 statusCodeExpected
55 })
56}
57function markAsReadAllNotifications (url: string, token: string, statusCodeExpected = 204) {
58 const path = '/api/v1/users/me/notifications/read-all'
59
60 return makePostBodyRequest({
61 url,
62 path,
63 token,
64 statusCodeExpected
65 })
66}
67
68async function getLastNotification (serverUrl: string, accessToken: string) {
69 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, undefined, '-createdAt')
70
71 if (res.body.total === 0) return undefined
72
73 return res.body.data[0] as UserNotification
74}
75
76type CheckerBaseParams = {
77 server: ServerInfo
78 emails: object[]
79 socketNotifications: UserNotification[]
80 token: string,
81 check?: { web: boolean, mail: boolean }
82}
83
84type CheckerType = 'presence' | 'absence'
85
86async function checkNotification (
87 base: CheckerBaseParams,
88 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
89 emailNotificationFinder: (email: object) => boolean,
90 checkType: CheckerType
91) {
92 const check = base.check || { web: true, mail: true }
93
94 if (check.web) {
95 const notification = await getLastNotification(base.server.url, base.token)
96
97 if (notification || checkType !== 'absence') {
98 notificationChecker(notification, checkType)
99 }
100
101 const socketNotification = base.socketNotifications.find(n => {
102 try {
103 notificationChecker(n, 'presence')
104 return true
105 } catch {
106 return false
107 }
108 })
109
110 if (checkType === 'presence') {
111 const obj = inspect(base.socketNotifications, { depth: 5 })
112 expect(socketNotification, 'The socket notification is absent. ' + obj).to.not.be.undefined
113 } else {
114 const obj = inspect(socketNotification, { depth: 5 })
115 expect(socketNotification, 'The socket notification is present. ' + obj).to.be.undefined
116 }
117 }
118
119 if (check.mail) {
120 // Last email
121 const email = base.emails
122 .slice()
123 .reverse()
124 .find(e => emailNotificationFinder(e))
125
126 if (checkType === 'presence') {
127 expect(email, 'The email is absent. ' + inspect(base.emails)).to.not.be.undefined
128 } else {
129 expect(email, 'The email is present. ' + inspect(email)).to.be.undefined
130 }
131 }
132}
133
134function checkVideo (video: any, videoName?: string, videoUUID?: string) {
135 expect(video.name).to.be.a('string')
136 expect(video.name).to.not.be.empty
137 if (videoName) expect(video.name).to.equal(videoName)
138
139 expect(video.uuid).to.be.a('string')
140 expect(video.uuid).to.not.be.empty
141 if (videoUUID) expect(video.uuid).to.equal(videoUUID)
142
143 expect(video.id).to.be.a('number')
144}
145
146function checkActor (actor: any) {
147 expect(actor.displayName).to.be.a('string')
148 expect(actor.displayName).to.not.be.empty
149 expect(actor.host).to.not.be.undefined
150}
151
152function checkComment (comment: any, commentId: number, threadId: number) {
153 expect(comment.id).to.equal(commentId)
154 expect(comment.threadId).to.equal(threadId)
155}
156
157async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
158 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
159
160 function notificationChecker (notification: UserNotification, type: CheckerType) {
161 if (type === 'presence') {
162 expect(notification).to.not.be.undefined
163 expect(notification.type).to.equal(notificationType)
164
165 checkVideo(notification.video, videoName, videoUUID)
166 checkActor(notification.video.channel)
167 } else {
168 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
169 }
170 }
171
172 function emailFinder (email: object) {
173 return email[ 'text' ].indexOf(videoUUID) !== -1
174 }
175
176 await checkNotification(base, notificationChecker, emailFinder, type)
177}
178
179async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
180 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
181
182 function notificationChecker (notification: UserNotification, type: CheckerType) {
183 if (type === 'presence') {
184 expect(notification).to.not.be.undefined
185 expect(notification.type).to.equal(notificationType)
186
187 checkVideo(notification.video, videoName, videoUUID)
188 checkActor(notification.video.channel)
189 } else {
190 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
191 }
192 }
193
194 function emailFinder (email: object) {
195 const text: string = email[ 'text' ]
196 return text.includes(videoUUID) && text.includes('Your video')
197 }
198
199 await checkNotification(base, notificationChecker, emailFinder, type)
200}
201
202async function checkMyVideoImportIsFinished (
203 base: CheckerBaseParams,
204 videoName: string,
205 videoUUID: string,
206 url: string,
207 success: boolean,
208 type: CheckerType
209) {
210 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
211
212 function notificationChecker (notification: UserNotification, type: CheckerType) {
213 if (type === 'presence') {
214 expect(notification).to.not.be.undefined
215 expect(notification.type).to.equal(notificationType)
216
217 expect(notification.videoImport.targetUrl).to.equal(url)
218
219 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID)
220 } else {
221 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
222 }
223 }
224
225 function emailFinder (email: object) {
226 const text: string = email[ 'text' ]
227 const toFind = success ? ' finished' : ' error'
228
229 return text.includes(url) && text.includes(toFind)
230 }
231
232 await checkNotification(base, notificationChecker, emailFinder, type)
233}
234
235async function checkUserRegistered (base: CheckerBaseParams, username: string, type: CheckerType) {
236 const notificationType = UserNotificationType.NEW_USER_REGISTRATION
237
238 function notificationChecker (notification: UserNotification, type: CheckerType) {
239 if (type === 'presence') {
240 expect(notification).to.not.be.undefined
241 expect(notification.type).to.equal(notificationType)
242
243 checkActor(notification.account)
244 expect(notification.account.name).to.equal(username)
245 } else {
246 expect(notification).to.satisfy(n => n.type !== notificationType || n.account.name !== username)
247 }
248 }
249
250 function emailFinder (email: object) {
251 const text: string = email[ 'text' ]
252
253 return text.includes(' registered ') && text.includes(username)
254 }
255
256 await checkNotification(base, notificationChecker, emailFinder, type)
257}
258
259async function checkNewActorFollow (
260 base: CheckerBaseParams,
261 followType: 'channel' | 'account',
262 followerName: string,
263 followerDisplayName: string,
264 followingDisplayName: string,
265 type: CheckerType
266) {
267 const notificationType = UserNotificationType.NEW_FOLLOW
268
269 function notificationChecker (notification: UserNotification, type: CheckerType) {
270 if (type === 'presence') {
271 expect(notification).to.not.be.undefined
272 expect(notification.type).to.equal(notificationType)
273
274 checkActor(notification.actorFollow.follower)
275 expect(notification.actorFollow.follower.displayName).to.equal(followerDisplayName)
276 expect(notification.actorFollow.follower.name).to.equal(followerName)
277 expect(notification.actorFollow.follower.host).to.not.be.undefined
278
279 expect(notification.actorFollow.following.displayName).to.equal(followingDisplayName)
280 expect(notification.actorFollow.following.type).to.equal(followType)
281 } else {
282 expect(notification).to.satisfy(n => {
283 return n.type !== notificationType ||
284 (n.actorFollow.follower.name !== followerName && n.actorFollow.following !== followingDisplayName)
285 })
286 }
287 }
288
289 function emailFinder (email: object) {
290 const text: string = email[ 'text' ]
291
292 return text.includes('Your ' + followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
293 }
294
295 await checkNotification(base, notificationChecker, emailFinder, type)
296}
297
298async function checkCommentMention (
299 base: CheckerBaseParams,
300 uuid: string,
301 commentId: number,
302 threadId: number,
303 byAccountDisplayName: string,
304 type: CheckerType
305) {
306 const notificationType = UserNotificationType.COMMENT_MENTION
307
308 function notificationChecker (notification: UserNotification, type: CheckerType) {
309 if (type === 'presence') {
310 expect(notification).to.not.be.undefined
311 expect(notification.type).to.equal(notificationType)
312
313 checkComment(notification.comment, commentId, threadId)
314 checkActor(notification.comment.account)
315 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName)
316
317 checkVideo(notification.comment.video, undefined, uuid)
318 } else {
319 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId)
320 }
321 }
322
323 function emailFinder (email: object) {
324 const text: string = email[ 'text' ]
325
326 return text.includes(' mentioned ') && text.includes(uuid) && text.includes(byAccountDisplayName)
327 }
328
329 await checkNotification(base, notificationChecker, emailFinder, type)
330}
331
332let lastEmailCount = 0
333async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) {
334 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
335
336 function notificationChecker (notification: UserNotification, type: CheckerType) {
337 if (type === 'presence') {
338 expect(notification).to.not.be.undefined
339 expect(notification.type).to.equal(notificationType)
340
341 checkComment(notification.comment, commentId, threadId)
342 checkActor(notification.comment.account)
343 checkVideo(notification.comment.video, undefined, uuid)
344 } else {
345 expect(notification).to.satisfy((n: UserNotification) => {
346 return n === undefined || n.comment === undefined || n.comment.id !== commentId
347 })
348 }
349 }
350
351 const commentUrl = `http://localhost:9001/videos/watch/${uuid};threadId=${threadId}`
352 function emailFinder (email: object) {
353 return email[ 'text' ].indexOf(commentUrl) !== -1
354 }
355
356 await checkNotification(base, notificationChecker, emailFinder, type)
357
358 if (type === 'presence') {
359 // We cannot detect email duplicates, so check we received another email
360 expect(base.emails).to.have.length.above(lastEmailCount)
361 lastEmailCount = base.emails.length
362 }
363}
364
365async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
366 const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS
367
368 function notificationChecker (notification: UserNotification, type: CheckerType) {
369 if (type === 'presence') {
370 expect(notification).to.not.be.undefined
371 expect(notification.type).to.equal(notificationType)
372
373 expect(notification.videoAbuse.id).to.be.a('number')
374 checkVideo(notification.videoAbuse.video, videoName, videoUUID)
375 } else {
376 expect(notification).to.satisfy((n: UserNotification) => {
377 return n === undefined || n.videoAbuse === undefined || n.videoAbuse.video.uuid !== videoUUID
378 })
379 }
380 }
381
382 function emailFinder (email: object) {
383 const text = email[ 'text' ]
384 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
385 }
386
387 await checkNotification(base, notificationChecker, emailFinder, type)
388}
389
390async function checkNewBlacklistOnMyVideo (
391 base: CheckerBaseParams,
392 videoUUID: string,
393 videoName: string,
394 blacklistType: 'blacklist' | 'unblacklist'
395) {
396 const notificationType = blacklistType === 'blacklist'
397 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
398 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
399
400 function notificationChecker (notification: UserNotification) {
401 expect(notification).to.not.be.undefined
402 expect(notification.type).to.equal(notificationType)
403
404 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
405
406 checkVideo(video, videoName, videoUUID)
407 }
408
409 function emailFinder (email: object) {
410 const text = email[ 'text' ]
411 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
412 }
413
414 await checkNotification(base, notificationChecker, emailFinder, 'presence')
415}
416
417// ---------------------------------------------------------------------------
418
419export {
420 CheckerBaseParams,
421 CheckerType,
422 checkNotification,
423 markAsReadAllNotifications,
424 checkMyVideoImportIsFinished,
425 checkUserRegistered,
426 checkVideoIsPublished,
427 checkNewVideoFromSubscription,
428 checkNewActorFollow,
429 checkNewCommentOnMyVideo,
430 checkNewBlacklistOnMyVideo,
431 checkCommentMention,
432 updateMyNotificationSettings,
433 checkNewVideoAbuseForModerators,
434 getUserNotifications,
435 markAsReadNotifications,
436 getLastNotification
437}
diff --git a/shared/utils/users/user-subscriptions.ts b/shared/utils/users/user-subscriptions.ts
new file mode 100644
index 000000000..7148fbfca
--- /dev/null
+++ b/shared/utils/users/user-subscriptions.ts
@@ -0,0 +1,82 @@
1import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../requests/requests'
2
3function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
4 const path = '/api/v1/users/me/subscriptions'
5
6 return makePostBodyRequest({
7 url,
8 path,
9 token,
10 statusCodeExpected,
11 fields: { uri: targetUri }
12 })
13}
14
15function listUserSubscriptions (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
16 const path = '/api/v1/users/me/subscriptions'
17
18 return makeGetRequest({
19 url,
20 path,
21 token,
22 statusCodeExpected,
23 query: { sort }
24 })
25}
26
27function listUserSubscriptionVideos (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
28 const path = '/api/v1/users/me/subscriptions/videos'
29
30 return makeGetRequest({
31 url,
32 path,
33 token,
34 statusCodeExpected,
35 query: { sort }
36 })
37}
38
39function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
40 const path = '/api/v1/users/me/subscriptions/' + uri
41
42 return makeGetRequest({
43 url,
44 path,
45 token,
46 statusCodeExpected
47 })
48}
49
50function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
51 const path = '/api/v1/users/me/subscriptions/' + uri
52
53 return makeDeleteRequest({
54 url,
55 path,
56 token,
57 statusCodeExpected
58 })
59}
60
61function areSubscriptionsExist (url: string, token: string, uris: string[], statusCodeExpected = 200) {
62 const path = '/api/v1/users/me/subscriptions/exist'
63
64 return makeGetRequest({
65 url,
66 path,
67 query: { 'uris[]': uris },
68 token,
69 statusCodeExpected
70 })
71}
72
73// ---------------------------------------------------------------------------
74
75export {
76 areSubscriptionsExist,
77 addUserSubscription,
78 listUserSubscriptions,
79 getUserSubscription,
80 listUserSubscriptionVideos,
81 removeUserSubscription
82}
diff --git a/shared/utils/users/users.ts b/shared/utils/users/users.ts
new file mode 100644
index 000000000..7191b263e
--- /dev/null
+++ b/shared/utils/users/users.ts
@@ -0,0 +1,304 @@
1import * as request from 'supertest'
2import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests'
3
4import { UserRole } from '../../index'
5import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type'
6
7function createUser (
8 url: string,
9 accessToken: string,
10 username: string,
11 password: string,
12 videoQuota = 1000000,
13 videoQuotaDaily = -1,
14 role: UserRole = UserRole.USER,
15 specialStatus = 200
16) {
17 const path = '/api/v1/users'
18 const body = {
19 username,
20 password,
21 role,
22 email: username + '@example.com',
23 videoQuota,
24 videoQuotaDaily
25 }
26
27 return request(url)
28 .post(path)
29 .set('Accept', 'application/json')
30 .set('Authorization', 'Bearer ' + accessToken)
31 .send(body)
32 .expect(specialStatus)
33}
34
35function registerUser (url: string, username: string, password: string, specialStatus = 204) {
36 const path = '/api/v1/users/register'
37 const body = {
38 username,
39 password,
40 email: username + '@example.com'
41 }
42
43 return request(url)
44 .post(path)
45 .set('Accept', 'application/json')
46 .send(body)
47 .expect(specialStatus)
48}
49
50function getMyUserInformation (url: string, accessToken: string, specialStatus = 200) {
51 const path = '/api/v1/users/me'
52
53 return request(url)
54 .get(path)
55 .set('Accept', 'application/json')
56 .set('Authorization', 'Bearer ' + accessToken)
57 .expect(specialStatus)
58 .expect('Content-Type', /json/)
59}
60
61function deleteMe (url: string, accessToken: string, specialStatus = 204) {
62 const path = '/api/v1/users/me'
63
64 return request(url)
65 .delete(path)
66 .set('Accept', 'application/json')
67 .set('Authorization', 'Bearer ' + accessToken)
68 .expect(specialStatus)
69}
70
71function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = 200) {
72 const path = '/api/v1/users/me/video-quota-used'
73
74 return request(url)
75 .get(path)
76 .set('Accept', 'application/json')
77 .set('Authorization', 'Bearer ' + accessToken)
78 .expect(specialStatus)
79 .expect('Content-Type', /json/)
80}
81
82function getUserInformation (url: string, accessToken: string, userId: number) {
83 const path = '/api/v1/users/' + userId
84
85 return request(url)
86 .get(path)
87 .set('Accept', 'application/json')
88 .set('Authorization', 'Bearer ' + accessToken)
89 .expect(200)
90 .expect('Content-Type', /json/)
91}
92
93function getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = 200) {
94 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
95
96 return request(url)
97 .get(path)
98 .set('Accept', 'application/json')
99 .set('Authorization', 'Bearer ' + accessToken)
100 .expect(specialStatus)
101 .expect('Content-Type', /json/)
102}
103
104function getUsersList (url: string, accessToken: string) {
105 const path = '/api/v1/users'
106
107 return request(url)
108 .get(path)
109 .set('Accept', 'application/json')
110 .set('Authorization', 'Bearer ' + accessToken)
111 .expect(200)
112 .expect('Content-Type', /json/)
113}
114
115function getUsersListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string, search?: string) {
116 const path = '/api/v1/users'
117
118 return request(url)
119 .get(path)
120 .query({ start })
121 .query({ count })
122 .query({ sort })
123 .query({ search })
124 .set('Accept', 'application/json')
125 .set('Authorization', 'Bearer ' + accessToken)
126 .expect(200)
127 .expect('Content-Type', /json/)
128}
129
130function removeUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
131 const path = '/api/v1/users'
132
133 return request(url)
134 .delete(path + '/' + userId)
135 .set('Accept', 'application/json')
136 .set('Authorization', 'Bearer ' + accessToken)
137 .expect(expectedStatus)
138}
139
140function blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204, reason?: string) {
141 const path = '/api/v1/users'
142 let body: any
143 if (reason) body = { reason }
144
145 return request(url)
146 .post(path + '/' + userId + '/block')
147 .send(body)
148 .set('Accept', 'application/json')
149 .set('Authorization', 'Bearer ' + accessToken)
150 .expect(expectedStatus)
151}
152
153function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
154 const path = '/api/v1/users'
155
156 return request(url)
157 .post(path + '/' + userId + '/unblock')
158 .set('Accept', 'application/json')
159 .set('Authorization', 'Bearer ' + accessToken)
160 .expect(expectedStatus)
161}
162
163function updateMyUser (options: {
164 url: string
165 accessToken: string
166 currentPassword?: string
167 newPassword?: string
168 nsfwPolicy?: NSFWPolicyType
169 email?: string
170 autoPlayVideo?: boolean
171 displayName?: string
172 description?: string
173 videosHistoryEnabled?: boolean
174}) {
175 const path = '/api/v1/users/me'
176
177 const toSend = {}
178 if (options.currentPassword !== undefined && options.currentPassword !== null) toSend['currentPassword'] = options.currentPassword
179 if (options.newPassword !== undefined && options.newPassword !== null) toSend['password'] = options.newPassword
180 if (options.nsfwPolicy !== undefined && options.nsfwPolicy !== null) toSend['nsfwPolicy'] = options.nsfwPolicy
181 if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
182 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
183 if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
184 if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
185 if (options.videosHistoryEnabled !== undefined && options.videosHistoryEnabled !== null) {
186 toSend['videosHistoryEnabled'] = options.videosHistoryEnabled
187 }
188
189 return makePutBodyRequest({
190 url: options.url,
191 path,
192 token: options.accessToken,
193 fields: toSend,
194 statusCodeExpected: 204
195 })
196}
197
198function updateMyAvatar (options: {
199 url: string,
200 accessToken: string,
201 fixture: string
202}) {
203 const path = '/api/v1/users/me/avatar/pick'
204
205 return updateAvatarRequest(Object.assign(options, { path }))
206}
207
208function updateUser (options: {
209 url: string
210 userId: number,
211 accessToken: string,
212 email?: string,
213 emailVerified?: boolean,
214 videoQuota?: number,
215 videoQuotaDaily?: number,
216 password?: string,
217 role?: UserRole
218}) {
219 const path = '/api/v1/users/' + options.userId
220
221 const toSend = {}
222 if (options.password !== undefined && options.password !== null) toSend['password'] = options.password
223 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
224 if (options.emailVerified !== undefined && options.emailVerified !== null) toSend['emailVerified'] = options.emailVerified
225 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
226 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
227 if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
228
229 return makePutBodyRequest({
230 url: options.url,
231 path,
232 token: options.accessToken,
233 fields: toSend,
234 statusCodeExpected: 204
235 })
236}
237
238function askResetPassword (url: string, email: string) {
239 const path = '/api/v1/users/ask-reset-password'
240
241 return makePostBodyRequest({
242 url,
243 path,
244 fields: { email },
245 statusCodeExpected: 204
246 })
247}
248
249function resetPassword (url: string, userId: number, verificationString: string, password: string, statusCodeExpected = 204) {
250 const path = '/api/v1/users/' + userId + '/reset-password'
251
252 return makePostBodyRequest({
253 url,
254 path,
255 fields: { password, verificationString },
256 statusCodeExpected
257 })
258}
259
260function askSendVerifyEmail (url: string, email: string) {
261 const path = '/api/v1/users/ask-send-verify-email'
262
263 return makePostBodyRequest({
264 url,
265 path,
266 fields: { email },
267 statusCodeExpected: 204
268 })
269}
270
271function verifyEmail (url: string, userId: number, verificationString: string, statusCodeExpected = 204) {
272 const path = '/api/v1/users/' + userId + '/verify-email'
273
274 return makePostBodyRequest({
275 url,
276 path,
277 fields: { verificationString },
278 statusCodeExpected
279 })
280}
281
282// ---------------------------------------------------------------------------
283
284export {
285 createUser,
286 registerUser,
287 getMyUserInformation,
288 getMyUserVideoRating,
289 deleteMe,
290 getMyUserVideoQuotaUsed,
291 getUsersList,
292 getUsersListPaginationAndSort,
293 removeUser,
294 updateUser,
295 updateMyUser,
296 getUserInformation,
297 blockUser,
298 unblockUser,
299 askResetPassword,
300 resetPassword,
301 updateMyAvatar,
302 askSendVerifyEmail,
303 verifyEmail
304}