aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-01-02 16:37:43 +0100
committerChocobozzz <chocobozzz@cpy.re>2019-01-09 11:15:15 +0100
commitdc13348070d808d0ba3feb56a435b835c2e7e791 (patch)
tree887202a33f1aa680fd8ece6ee465381f3931c64e /shared
parent6e7e63b83f08ba68edc2bb9f72ff03d1802e45df (diff)
downloadPeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.tar.gz
PeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.tar.zst
PeerTube-dc13348070d808d0ba3feb56a435b835c2e7e791.zip
Add import finished and video published notifs
Diffstat (limited to 'shared')
-rw-r--r--shared/models/users/user-notification-setting.model.ts2
-rw-r--r--shared/models/users/user-notification.model.ts17
-rw-r--r--shared/utils/users/user-notifications.ts180
-rw-r--r--shared/utils/videos/video-imports.ts5
4 files changed, 158 insertions, 46 deletions
diff --git a/shared/models/users/user-notification-setting.model.ts b/shared/models/users/user-notification-setting.model.ts
index 7cecd70a2..55d351abf 100644
--- a/shared/models/users/user-notification-setting.model.ts
+++ b/shared/models/users/user-notification-setting.model.ts
@@ -10,4 +10,6 @@ export interface UserNotificationSetting {
10 newCommentOnMyVideo: UserNotificationSettingValue 10 newCommentOnMyVideo: UserNotificationSettingValue
11 videoAbuseAsModerator: UserNotificationSettingValue 11 videoAbuseAsModerator: UserNotificationSettingValue
12 blacklistOnMyVideo: UserNotificationSettingValue 12 blacklistOnMyVideo: UserNotificationSettingValue
13 myVideoPublished: UserNotificationSettingValue
14 myVideoImportFinished: UserNotificationSettingValue
13} 15}
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts
index 39beb2350..ee9ac275a 100644
--- a/shared/models/users/user-notification.model.ts
+++ b/shared/models/users/user-notification.model.ts
@@ -3,10 +3,13 @@ export enum UserNotificationType {
3 NEW_COMMENT_ON_MY_VIDEO = 2, 3 NEW_COMMENT_ON_MY_VIDEO = 2,
4 NEW_VIDEO_ABUSE_FOR_MODERATORS = 3, 4 NEW_VIDEO_ABUSE_FOR_MODERATORS = 3,
5 BLACKLIST_ON_MY_VIDEO = 4, 5 BLACKLIST_ON_MY_VIDEO = 4,
6 UNBLACKLIST_ON_MY_VIDEO = 5 6 UNBLACKLIST_ON_MY_VIDEO = 5,
7 MY_VIDEO_PUBLISHED = 6,
8 MY_VIDEO_IMPORT_SUCCESS = 7,
9 MY_VIDEO_IMPORT_ERROR = 8
7} 10}
8 11
9interface VideoInfo { 12export interface VideoInfo {
10 id: number 13 id: number
11 uuid: string 14 uuid: string
12 name: string 15 name: string
@@ -24,12 +27,22 @@ export interface UserNotification {
24 } 27 }
25 } 28 }
26 29
30 videoImport?: {
31 id: number
32 video?: VideoInfo
33 torrentName?: string
34 magnetUri?: string
35 targetUrl?: string
36 }
37
27 comment?: { 38 comment?: {
28 id: number 39 id: number
40 threadId: number
29 account: { 41 account: {
30 id: number 42 id: number
31 displayName: string 43 displayName: string
32 } 44 }
45 video: VideoInfo
33 } 46 }
34 47
35 videoAbuse?: { 48 videoAbuse?: {
diff --git a/shared/utils/users/user-notifications.ts b/shared/utils/users/user-notifications.ts
index dbe87559e..75d52023a 100644
--- a/shared/utils/users/user-notifications.ts
+++ b/shared/utils/users/user-notifications.ts
@@ -4,6 +4,7 @@ import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requ
4import { UserNotification, UserNotificationSetting, UserNotificationType } from '../../models/users' 4import { UserNotification, UserNotificationSetting, UserNotificationType } from '../../models/users'
5import { ServerInfo } from '..' 5import { ServerInfo } from '..'
6import { expect } from 'chai' 6import { expect } from 'chai'
7import { inspect } from 'util'
7 8
8function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) { 9function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) {
9 const path = '/api/v1/users/me/notification-settings' 10 const path = '/api/v1/users/me/notification-settings'
@@ -17,7 +18,15 @@ function updateMyNotificationSettings (url: string, token: string, settings: Use
17 }) 18 })
18} 19}
19 20
20function getUserNotifications (url: string, token: string, start: number, count: number, sort = '-createdAt', statusCodeExpected = 200) { 21function getUserNotifications (
22 url: string,
23 token: string,
24 start: number,
25 count: number,
26 unread?: boolean,
27 sort = '-createdAt',
28 statusCodeExpected = 200
29) {
21 const path = '/api/v1/users/me/notifications' 30 const path = '/api/v1/users/me/notifications'
22 31
23 return makeGetRequest({ 32 return makeGetRequest({
@@ -27,7 +36,8 @@ function getUserNotifications (url: string, token: string, start: number, count:
27 query: { 36 query: {
28 start, 37 start,
29 count, 38 count,
30 sort 39 sort,
40 unread
31 }, 41 },
32 statusCodeExpected 42 statusCodeExpected
33 }) 43 })
@@ -46,7 +56,7 @@ function markAsReadNotifications (url: string, token: string, ids: number[], sta
46} 56}
47 57
48async function getLastNotification (serverUrl: string, accessToken: string) { 58async function getLastNotification (serverUrl: string, accessToken: string) {
49 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, '-createdAt') 59 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, undefined, '-createdAt')
50 60
51 if (res.body.total === 0) return undefined 61 if (res.body.total === 0) return undefined
52 62
@@ -65,21 +75,33 @@ type CheckerType = 'presence' | 'absence'
65 75
66async function checkNotification ( 76async function checkNotification (
67 base: CheckerBaseParams, 77 base: CheckerBaseParams,
68 lastNotificationChecker: (notification: UserNotification) => void, 78 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
69 socketNotificationFinder: (notification: UserNotification) => boolean,
70 emailNotificationFinder: (email: object) => boolean, 79 emailNotificationFinder: (email: object) => boolean,
71 checkType: 'presence' | 'absence' 80 checkType: CheckerType
72) { 81) {
73 const check = base.check || { web: true, mail: true } 82 const check = base.check || { web: true, mail: true }
74 83
75 if (check.web) { 84 if (check.web) {
76 const notification = await getLastNotification(base.server.url, base.token) 85 const notification = await getLastNotification(base.server.url, base.token)
77 lastNotificationChecker(notification)
78 86
79 const socketNotification = base.socketNotifications.find(n => socketNotificationFinder(n)) 87 if (notification || checkType !== 'absence') {
88 notificationChecker(notification, checkType)
89 }
80 90
81 if (checkType === 'presence') expect(socketNotification, 'The socket notification is absent.').to.not.be.undefined 91 const socketNotification = base.socketNotifications.find(n => {
82 else expect(socketNotification, 'The socket notification is present.').to.be.undefined 92 try {
93 notificationChecker(n, 'presence')
94 return true
95 } catch {
96 return false
97 }
98 })
99
100 if (checkType === 'presence') {
101 expect(socketNotification, 'The socket notification is absent. ' + inspect(base.socketNotifications)).to.not.be.undefined
102 } else {
103 expect(socketNotification, 'The socket notification is present. ' + inspect(socketNotification)).to.be.undefined
104 }
83 } 105 }
84 106
85 if (check.mail) { 107 if (check.mail) {
@@ -89,45 +111,127 @@ async function checkNotification (
89 .reverse() 111 .reverse()
90 .find(e => emailNotificationFinder(e)) 112 .find(e => emailNotificationFinder(e))
91 113
92 if (checkType === 'presence') expect(email, 'The email is present.').to.not.be.undefined 114 if (checkType === 'presence') {
93 else expect(email, 'The email is absent.').to.be.undefined 115 expect(email, 'The email is absent. ' + inspect(base.emails)).to.not.be.undefined
116 } else {
117 expect(email, 'The email is present. ' + inspect(email)).to.be.undefined
118 }
94 } 119 }
95} 120}
96 121
122function checkVideo (video: any, videoName?: string, videoUUID?: string) {
123 expect(video.name).to.be.a('string')
124 expect(video.name).to.not.be.empty
125 if (videoName) expect(video.name).to.equal(videoName)
126
127 expect(video.uuid).to.be.a('string')
128 expect(video.uuid).to.not.be.empty
129 if (videoUUID) expect(video.uuid).to.equal(videoUUID)
130
131 expect(video.id).to.be.a('number')
132}
133
134function checkActor (channel: any) {
135 expect(channel.id).to.be.a('number')
136 expect(channel.displayName).to.be.a('string')
137 expect(channel.displayName).to.not.be.empty
138}
139
140function checkComment (comment: any, commentId: number, threadId: number) {
141 expect(comment.id).to.equal(commentId)
142 expect(comment.threadId).to.equal(threadId)
143}
144
97async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) { 145async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
98 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION 146 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
99 147
100 function lastNotificationChecker (notification: UserNotification) { 148 function notificationChecker (notification: UserNotification, type: CheckerType) {
101 if (type === 'presence') { 149 if (type === 'presence') {
102 expect(notification).to.not.be.undefined 150 expect(notification).to.not.be.undefined
103 expect(notification.type).to.equal(notificationType) 151 expect(notification.type).to.equal(notificationType)
104 expect(notification.video.name).to.equal(videoName) 152
153 checkVideo(notification.video, videoName, videoUUID)
154 checkActor(notification.video.channel)
105 } else { 155 } else {
106 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName) 156 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
107 } 157 }
108 } 158 }
109 159
110 function socketFinder (notification: UserNotification) { 160 function emailFinder (email: object) {
111 return notification.type === notificationType && notification.video.name === videoName 161 return email[ 'text' ].indexOf(videoUUID) !== -1
162 }
163
164 await checkNotification(base, notificationChecker, emailFinder, type)
165}
166
167async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
168 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
169
170 function notificationChecker (notification: UserNotification, type: CheckerType) {
171 if (type === 'presence') {
172 expect(notification).to.not.be.undefined
173 expect(notification.type).to.equal(notificationType)
174
175 checkVideo(notification.video, videoName, videoUUID)
176 checkActor(notification.video.channel)
177 } else {
178 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
179 }
112 } 180 }
113 181
114 function emailFinder (email: object) { 182 function emailFinder (email: object) {
115 return email[ 'text' ].indexOf(videoUUID) !== -1 183 const text: string = email[ 'text' ]
184 return text.includes(videoUUID) && text.includes('Your video')
116 } 185 }
117 186
118 await checkNotification(base, lastNotificationChecker, socketFinder, emailFinder, type) 187 await checkNotification(base, notificationChecker, emailFinder, type)
188}
189
190async function checkMyVideoImportIsFinished (
191 base: CheckerBaseParams,
192 videoName: string,
193 videoUUID: string,
194 url: string,
195 success: boolean,
196 type: CheckerType
197) {
198 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
199
200 function notificationChecker (notification: UserNotification, type: CheckerType) {
201 if (type === 'presence') {
202 expect(notification).to.not.be.undefined
203 expect(notification.type).to.equal(notificationType)
204
205 expect(notification.videoImport.targetUrl).to.equal(url)
206
207 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID)
208 } else {
209 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
210 }
211 }
212
213 function emailFinder (email: object) {
214 const text: string = email[ 'text' ]
215 const toFind = success ? ' finished' : ' error'
216
217 return text.includes(url) && text.includes(toFind)
218 }
219
220 await checkNotification(base, notificationChecker, emailFinder, type)
119} 221}
120 222
121let lastEmailCount = 0 223let lastEmailCount = 0
122async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) { 224async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) {
123 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO 225 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
124 226
125 function lastNotificationChecker (notification: UserNotification) { 227 function notificationChecker (notification: UserNotification, type: CheckerType) {
126 if (type === 'presence') { 228 if (type === 'presence') {
127 expect(notification).to.not.be.undefined 229 expect(notification).to.not.be.undefined
128 expect(notification.type).to.equal(notificationType) 230 expect(notification.type).to.equal(notificationType)
129 expect(notification.comment.id).to.equal(commentId) 231
130 expect(notification.comment.account.displayName).to.equal('root') 232 checkComment(notification.comment, commentId, threadId)
233 checkActor(notification.comment.account)
234 checkVideo(notification.comment.video, undefined, uuid)
131 } else { 235 } else {
132 expect(notification).to.satisfy((n: UserNotification) => { 236 expect(notification).to.satisfy((n: UserNotification) => {
133 return n === undefined || n.comment === undefined || n.comment.id !== commentId 237 return n === undefined || n.comment === undefined || n.comment.id !== commentId
@@ -135,18 +239,12 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
135 } 239 }
136 } 240 }
137 241
138 function socketFinder (notification: UserNotification) {
139 return notification.type === notificationType &&
140 notification.comment.id === commentId &&
141 notification.comment.account.displayName === 'root'
142 }
143
144 const commentUrl = `http://localhost:9001/videos/watch/${uuid};threadId=${threadId}` 242 const commentUrl = `http://localhost:9001/videos/watch/${uuid};threadId=${threadId}`
145 function emailFinder (email: object) { 243 function emailFinder (email: object) {
146 return email[ 'text' ].indexOf(commentUrl) !== -1 244 return email[ 'text' ].indexOf(commentUrl) !== -1
147 } 245 }
148 246
149 await checkNotification(base, lastNotificationChecker, socketFinder, emailFinder, type) 247 await checkNotification(base, notificationChecker, emailFinder, type)
150 248
151 if (type === 'presence') { 249 if (type === 'presence') {
152 // We cannot detect email duplicates, so check we received another email 250 // We cannot detect email duplicates, so check we received another email
@@ -158,12 +256,13 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
158async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) { 256async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
159 const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS 257 const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS
160 258
161 function lastNotificationChecker (notification: UserNotification) { 259 function notificationChecker (notification: UserNotification, type: CheckerType) {
162 if (type === 'presence') { 260 if (type === 'presence') {
163 expect(notification).to.not.be.undefined 261 expect(notification).to.not.be.undefined
164 expect(notification.type).to.equal(notificationType) 262 expect(notification.type).to.equal(notificationType)
165 expect(notification.videoAbuse.video.uuid).to.equal(videoUUID) 263
166 expect(notification.videoAbuse.video.name).to.equal(videoName) 264 expect(notification.videoAbuse.id).to.be.a('number')
265 checkVideo(notification.videoAbuse.video, videoName, videoUUID)
167 } else { 266 } else {
168 expect(notification).to.satisfy((n: UserNotification) => { 267 expect(notification).to.satisfy((n: UserNotification) => {
169 return n === undefined || n.videoAbuse === undefined || n.videoAbuse.video.uuid !== videoUUID 268 return n === undefined || n.videoAbuse === undefined || n.videoAbuse.video.uuid !== videoUUID
@@ -171,16 +270,12 @@ async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUU
171 } 270 }
172 } 271 }
173 272
174 function socketFinder (notification: UserNotification) {
175 return notification.type === notificationType && notification.videoAbuse.video.uuid === videoUUID
176 }
177
178 function emailFinder (email: object) { 273 function emailFinder (email: object) {
179 const text = email[ 'text' ] 274 const text = email[ 'text' ]
180 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1 275 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
181 } 276 }
182 277
183 await checkNotification(base, lastNotificationChecker, socketFinder, emailFinder, type) 278 await checkNotification(base, notificationChecker, emailFinder, type)
184} 279}
185 280
186async function checkNewBlacklistOnMyVideo ( 281async function checkNewBlacklistOnMyVideo (
@@ -193,18 +288,13 @@ async function checkNewBlacklistOnMyVideo (
193 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO 288 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
194 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO 289 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
195 290
196 function lastNotificationChecker (notification: UserNotification) { 291 function notificationChecker (notification: UserNotification) {
197 expect(notification).to.not.be.undefined 292 expect(notification).to.not.be.undefined
198 expect(notification.type).to.equal(notificationType) 293 expect(notification.type).to.equal(notificationType)
199 294
200 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video 295 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
201 296
202 expect(video.uuid).to.equal(videoUUID) 297 checkVideo(video, videoName, videoUUID)
203 expect(video.name).to.equal(videoName)
204 }
205
206 function socketFinder (notification: UserNotification) {
207 return notification.type === notificationType && (notification.video || notification.videoBlacklist.video).uuid === videoUUID
208 } 298 }
209 299
210 function emailFinder (email: object) { 300 function emailFinder (email: object) {
@@ -212,7 +302,7 @@ async function checkNewBlacklistOnMyVideo (
212 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1 302 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
213 } 303 }
214 304
215 await checkNotification(base, lastNotificationChecker, socketFinder, emailFinder, 'presence') 305 await checkNotification(base, notificationChecker, emailFinder, 'presence')
216} 306}
217 307
218// --------------------------------------------------------------------------- 308// ---------------------------------------------------------------------------
@@ -221,6 +311,8 @@ export {
221 CheckerBaseParams, 311 CheckerBaseParams,
222 CheckerType, 312 CheckerType,
223 checkNotification, 313 checkNotification,
314 checkMyVideoImportIsFinished,
315 checkVideoIsPublished,
224 checkNewVideoFromSubscription, 316 checkNewVideoFromSubscription,
225 checkNewCommentOnMyVideo, 317 checkNewCommentOnMyVideo,
226 checkNewBlacklistOnMyVideo, 318 checkNewBlacklistOnMyVideo,
diff --git a/shared/utils/videos/video-imports.ts b/shared/utils/videos/video-imports.ts
index 3fa49b432..ec77cdcda 100644
--- a/shared/utils/videos/video-imports.ts
+++ b/shared/utils/videos/video-imports.ts
@@ -11,6 +11,10 @@ function getMagnetURI () {
11 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4' 11 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
12} 12}
13 13
14function getBadVideoUrl () {
15 return 'https://download.cpy.re/peertube/bad_video.mp4'
16}
17
14function importVideo (url: string, token: string, attributes: VideoImportCreate) { 18function importVideo (url: string, token: string, attributes: VideoImportCreate) {
15 const path = '/api/v1/videos/imports' 19 const path = '/api/v1/videos/imports'
16 20
@@ -45,6 +49,7 @@ function getMyVideoImports (url: string, token: string, sort?: string) {
45// --------------------------------------------------------------------------- 49// ---------------------------------------------------------------------------
46 50
47export { 51export {
52 getBadVideoUrl,
48 getYoutubeVideoUrl, 53 getYoutubeVideoUrl,
49 importVideo, 54 importVideo,
50 getMagnetURI, 55 getMagnetURI,