diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-11-17 11:35:10 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-11-27 19:40:52 +0100 |
commit | afffe98839db7ccbfa9fb8b7d1413b97900fdc73 (patch) | |
tree | f0b3cbe58f73e81a5ba4bb31dabd9691994cf2ca /server | |
parent | 1b3989b0961d22a5a45ad16239e3c3f58f66180c (diff) | |
download | PeerTube-afffe98839db7ccbfa9fb8b7d1413b97900fdc73.tar.gz PeerTube-afffe98839db7ccbfa9fb8b7d1413b97900fdc73.tar.zst PeerTube-afffe98839db7ccbfa9fb8b7d1413b97900fdc73.zip |
Speed up activity pub http requests
Diffstat (limited to 'server')
21 files changed, 501 insertions, 431 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index c710117cd..338698652 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts | |||
@@ -3,6 +3,7 @@ import * as request from 'request' | |||
3 | import * as Sequelize from 'sequelize' | 3 | import * as Sequelize from 'sequelize' |
4 | import * as url from 'url' | 4 | import * as url from 'url' |
5 | import { ActivityIconObject } from '../../shared/index' | 5 | import { ActivityIconObject } from '../../shared/index' |
6 | import { Activity } from '../../shared/models/activitypub/activity' | ||
6 | import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor' | 7 | import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor' |
7 | import { VideoChannelObject } from '../../shared/models/activitypub/objects/video-channel-object' | 8 | import { VideoChannelObject } from '../../shared/models/activitypub/objects/video-channel-object' |
8 | import { ResultList } from '../../shared/models/result-list.model' | 9 | import { ResultList } from '../../shared/models/result-list.model' |
@@ -17,6 +18,7 @@ import { VideoInstance } from '../models/video/video-interface' | |||
17 | import { isRemoteAccountValid } from './custom-validators' | 18 | import { isRemoteAccountValid } from './custom-validators' |
18 | import { isVideoChannelObjectValid } from './custom-validators/activitypub/videos' | 19 | import { isVideoChannelObjectValid } from './custom-validators/activitypub/videos' |
19 | import { logger } from './logger' | 20 | import { logger } from './logger' |
21 | import { signObject } from './peertube-crypto' | ||
20 | import { doRequest, doRequestAndSaveToFile } from './requests' | 22 | import { doRequest, doRequestAndSaveToFile } from './requests' |
21 | import { getServerAccount } from './utils' | 23 | import { getServerAccount } from './utils' |
22 | 24 | ||
@@ -239,6 +241,12 @@ function activityPubCollectionPagination (url: string, page: number, result: Res | |||
239 | return activityPubContextify(obj) | 241 | return activityPubContextify(obj) |
240 | } | 242 | } |
241 | 243 | ||
244 | function buildSignedActivity (byAccount: AccountInstance, data: Object) { | ||
245 | const activity = activityPubContextify(data) | ||
246 | |||
247 | return signObject(byAccount, activity) as Promise<Activity> | ||
248 | } | ||
249 | |||
242 | // --------------------------------------------------------------------------- | 250 | // --------------------------------------------------------------------------- |
243 | 251 | ||
244 | export { | 252 | export { |
@@ -252,7 +260,8 @@ export { | |||
252 | fetchRemoteVideoDescription, | 260 | fetchRemoteVideoDescription, |
253 | shareVideoChannelByServer, | 261 | shareVideoChannelByServer, |
254 | shareVideoByServer, | 262 | shareVideoByServer, |
255 | getOrCreateVideoChannel | 263 | getOrCreateVideoChannel, |
264 | buildSignedActivity | ||
256 | } | 265 | } |
257 | 266 | ||
258 | // --------------------------------------------------------------------------- | 267 | // --------------------------------------------------------------------------- |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index f0a569410..48d7b5b98 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -260,7 +260,7 @@ const JOB_STATES: { [ id: string ]: JobState } = { | |||
260 | } | 260 | } |
261 | const JOB_CATEGORIES: { [ id: string ]: JobCategory } = { | 261 | const JOB_CATEGORIES: { [ id: string ]: JobCategory } = { |
262 | TRANSCODING: 'transcoding', | 262 | TRANSCODING: 'transcoding', |
263 | HTTP_REQUEST: 'http-request' | 263 | ACTIVITYPUB_HTTP: 'activitypub-http' |
264 | } | 264 | } |
265 | // How many maximum jobs we fetch from the database per cycle | 265 | // How many maximum jobs we fetch from the database per cycle |
266 | const JOBS_FETCH_LIMIT_PER_CYCLE = { | 266 | const JOBS_FETCH_LIMIT_PER_CYCLE = { |
diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts index abc1b598d..8d013fa87 100644 --- a/server/lib/activitypub/send-request.ts +++ b/server/lib/activitypub/send-request.ts | |||
@@ -1,116 +1,124 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | |||
3 | import { database as db } from '../../initializers' | ||
4 | import { | 2 | import { |
5 | AccountInstance, | 3 | ActivityAccept, |
6 | VideoInstance, | 4 | ActivityAdd, |
7 | VideoChannelInstance | 5 | ActivityCreate, |
8 | } from '../../models' | 6 | ActivityDelete, |
9 | import { httpRequestJobScheduler } from '../jobs' | 7 | ActivityFollow, |
10 | import { signObject, activityPubContextify } from '../../helpers' | 8 | ActivityUpdate |
11 | import { Activity, VideoAbuseObject } from '../../../shared' | 9 | } from '../../../shared/models/activitypub/activity' |
12 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' | ||
13 | import { getActivityPubUrl } from '../../helpers/activitypub' | 10 | import { getActivityPubUrl } from '../../helpers/activitypub' |
14 | import { logger } from '../../helpers/logger' | 11 | import { logger } from '../../helpers/logger' |
12 | import { database as db } from '../../initializers' | ||
13 | import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../models' | ||
14 | import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' | ||
15 | import { activitypubHttpJobScheduler } from '../jobs' | ||
16 | |||
17 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { | ||
18 | const byAccount = videoChannel.Account | ||
15 | 19 | ||
16 | async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { | ||
17 | const videoChannelObject = videoChannel.toActivityPubObject() | 20 | const videoChannelObject = videoChannel.toActivityPubObject() |
18 | const data = await createActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) | 21 | const data = await createActivityData(videoChannel.url, byAccount, videoChannelObject) |
19 | 22 | ||
20 | return broadcastToFollowers(data, [ videoChannel.Account ], t) | 23 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
21 | } | 24 | } |
22 | 25 | ||
23 | async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { | 26 | async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { |
27 | const byAccount = videoChannel.Account | ||
28 | |||
24 | const videoChannelObject = videoChannel.toActivityPubObject() | 29 | const videoChannelObject = videoChannel.toActivityPubObject() |
25 | const data = await updateActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) | 30 | const data = await updateActivityData(videoChannel.url, byAccount, videoChannelObject) |
26 | 31 | ||
27 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) | 32 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) |
28 | accountsInvolved.push(videoChannel.Account) | 33 | accountsInvolved.push(byAccount) |
29 | 34 | ||
30 | return broadcastToFollowers(data, accountsInvolved, t) | 35 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) |
31 | } | 36 | } |
32 | 37 | ||
33 | async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { | 38 | async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { |
34 | const data = await deleteActivityData(videoChannel.url, videoChannel.Account) | 39 | const byAccount = videoChannel.Account |
40 | |||
41 | const data = await deleteActivityData(videoChannel.url, byAccount) | ||
35 | 42 | ||
36 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) | 43 | const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) |
37 | accountsInvolved.push(videoChannel.Account) | 44 | accountsInvolved.push(byAccount) |
38 | 45 | ||
39 | return broadcastToFollowers(data, accountsInvolved, t) | 46 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) |
40 | } | 47 | } |
41 | 48 | ||
42 | async function sendAddVideo (video: VideoInstance, t: Sequelize.Transaction) { | 49 | async function sendAddVideo (video: VideoInstance, t: Transaction) { |
50 | const byAccount = video.VideoChannel.Account | ||
51 | |||
43 | const videoObject = video.toActivityPubObject() | 52 | const videoObject = video.toActivityPubObject() |
44 | const data = await addActivityData(video.url, video.VideoChannel.Account, video.VideoChannel.url, videoObject) | 53 | const data = await addActivityData(video.url, byAccount, video.VideoChannel.url, videoObject) |
45 | 54 | ||
46 | return broadcastToFollowers(data, [ video.VideoChannel.Account ], t) | 55 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
47 | } | 56 | } |
48 | 57 | ||
49 | async function sendUpdateVideo (video: VideoInstance, t: Sequelize.Transaction) { | 58 | async function sendUpdateVideo (video: VideoInstance, t: Transaction) { |
59 | const byAccount = video.VideoChannel.Account | ||
60 | |||
50 | const videoObject = video.toActivityPubObject() | 61 | const videoObject = video.toActivityPubObject() |
51 | const data = await updateActivityData(video.url, video.VideoChannel.Account, videoObject) | 62 | const data = await updateActivityData(video.url, byAccount, videoObject) |
52 | 63 | ||
53 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) | 64 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) |
54 | accountsInvolved.push(video.VideoChannel.Account) | 65 | accountsInvolved.push(byAccount) |
55 | 66 | ||
56 | return broadcastToFollowers(data, accountsInvolved, t) | 67 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) |
57 | } | 68 | } |
58 | 69 | ||
59 | async function sendDeleteVideo (video: VideoInstance, t: Sequelize.Transaction) { | 70 | async function sendDeleteVideo (video: VideoInstance, t: Transaction) { |
60 | const data = await deleteActivityData(video.url, video.VideoChannel.Account) | 71 | const byAccount = video.VideoChannel.Account |
72 | |||
73 | const data = await deleteActivityData(video.url, byAccount) | ||
61 | 74 | ||
62 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) | 75 | const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) |
63 | accountsInvolved.push(video.VideoChannel.Account) | 76 | accountsInvolved.push(byAccount) |
64 | 77 | ||
65 | return broadcastToFollowers(data, accountsInvolved, t) | 78 | return broadcastToFollowers(data, byAccount, accountsInvolved, t) |
66 | } | 79 | } |
67 | 80 | ||
68 | async function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction) { | 81 | async function sendDeleteAccount (account: AccountInstance, t: Transaction) { |
69 | const data = await deleteActivityData(account.url, account) | 82 | const data = await deleteActivityData(account.url, account) |
70 | 83 | ||
71 | return broadcastToFollowers(data, [ account ], t) | 84 | return broadcastToFollowers(data, account, [ account ], t) |
72 | } | 85 | } |
73 | 86 | ||
74 | async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { | 87 | async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { |
75 | const url = getActivityPubUrl('videoChannel', videoChannel.uuid) + '#announce' | 88 | const url = getActivityPubUrl('videoChannel', videoChannel.uuid) + '#announce' |
76 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), true) | 89 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject()) |
77 | 90 | ||
78 | const data = await announceActivityData(url, byAccount, announcedActivity) | 91 | const data = await announceActivityData(url, byAccount, announcedActivity) |
79 | return broadcastToFollowers(data, [ byAccount ], t) | 92 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
80 | } | 93 | } |
81 | 94 | ||
82 | async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Sequelize.Transaction) { | 95 | async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { |
83 | const url = getActivityPubUrl('video', video.uuid) + '#announce' | 96 | const url = getActivityPubUrl('video', video.uuid) + '#announce' |
84 | 97 | ||
85 | const videoChannel = video.VideoChannel | 98 | const videoChannel = video.VideoChannel |
86 | const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject(), true) | 99 | const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject()) |
87 | 100 | ||
88 | const data = await announceActivityData(url, byAccount, announcedActivity) | 101 | const data = await announceActivityData(url, byAccount, announcedActivity) |
89 | return broadcastToFollowers(data, [ byAccount ], t) | 102 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
90 | } | 103 | } |
91 | 104 | ||
92 | async function sendVideoAbuse ( | 105 | async function sendVideoAbuse (byAccount: AccountInstance, videoAbuse: VideoAbuseInstance, video: VideoInstance, t: Transaction) { |
93 | fromAccount: AccountInstance, | ||
94 | videoAbuse: VideoAbuseInstance, | ||
95 | video: VideoInstance, | ||
96 | t: Sequelize.Transaction | ||
97 | ) { | ||
98 | const url = getActivityPubUrl('videoAbuse', videoAbuse.id.toString()) | 106 | const url = getActivityPubUrl('videoAbuse', videoAbuse.id.toString()) |
99 | const data = await createActivityData(url, fromAccount, videoAbuse.toActivityPubObject()) | 107 | const data = await createActivityData(url, byAccount, videoAbuse.toActivityPubObject()) |
100 | 108 | ||
101 | return unicastTo(data, video.VideoChannel.Account.sharedInboxUrl, t) | 109 | return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) |
102 | } | 110 | } |
103 | 111 | ||
104 | async function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { | 112 | async function sendAccept (byAccount: AccountInstance, toAccount: AccountInstance, t: Transaction) { |
105 | const data = await acceptActivityData(fromAccount) | 113 | const data = await acceptActivityData(byAccount) |
106 | 114 | ||
107 | return unicastTo(data, toAccount.inboxUrl, t) | 115 | return unicastTo(data, byAccount, toAccount.inboxUrl, t) |
108 | } | 116 | } |
109 | 117 | ||
110 | async function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { | 118 | async function sendFollow (byAccount: AccountInstance, toAccount: AccountInstance, t: Transaction) { |
111 | const data = await followActivityData(toAccount.url, fromAccount) | 119 | const data = await followActivityData(toAccount.url, byAccount) |
112 | 120 | ||
113 | return unicastTo(data, toAccount.inboxUrl, t) | 121 | return unicastTo(data, byAccount, toAccount.inboxUrl, t) |
114 | } | 122 | } |
115 | 123 | ||
116 | // --------------------------------------------------------------------------- | 124 | // --------------------------------------------------------------------------- |
@@ -132,7 +140,7 @@ export { | |||
132 | 140 | ||
133 | // --------------------------------------------------------------------------- | 141 | // --------------------------------------------------------------------------- |
134 | 142 | ||
135 | async function broadcastToFollowers (data: any, toAccountFollowers: AccountInstance[], t: Sequelize.Transaction) { | 143 | async function broadcastToFollowers (data: any, byAccount: AccountInstance, toAccountFollowers: AccountInstance[], t: Transaction) { |
136 | const toAccountFollowerIds = toAccountFollowers.map(a => a.id) | 144 | const toAccountFollowerIds = toAccountFollowers.map(a => a.id) |
137 | const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds) | 145 | const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds) |
138 | if (result.data.length === 0) { | 146 | if (result.data.length === 0) { |
@@ -142,25 +150,21 @@ async function broadcastToFollowers (data: any, toAccountFollowers: AccountInsta | |||
142 | 150 | ||
143 | const jobPayload = { | 151 | const jobPayload = { |
144 | uris: result.data, | 152 | uris: result.data, |
153 | signatureAccountId: byAccount.id, | ||
145 | body: data | 154 | body: data |
146 | } | 155 | } |
147 | 156 | ||
148 | return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload) | 157 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpBroadcastHandler', jobPayload) |
149 | } | 158 | } |
150 | 159 | ||
151 | async function unicastTo (data: any, toAccountUrl: string, t: Sequelize.Transaction) { | 160 | async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: string, t: Transaction) { |
152 | const jobPayload = { | 161 | const jobPayload = { |
153 | uris: [ toAccountUrl ], | 162 | uris: [ toAccountUrl ], |
163 | signatureAccountId: byAccount.id, | ||
154 | body: data | 164 | body: data |
155 | } | 165 | } |
156 | 166 | ||
157 | return httpRequestJobScheduler.createJob(t, 'httpRequestUnicastHandler', jobPayload) | 167 | return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) |
158 | } | ||
159 | |||
160 | function buildSignedActivity (byAccount: AccountInstance, data: Object) { | ||
161 | const activity = activityPubContextify(data) | ||
162 | |||
163 | return signObject(byAccount, activity) as Promise<Activity> | ||
164 | } | 168 | } |
165 | 169 | ||
166 | async function getPublicActivityTo (account: AccountInstance) { | 170 | async function getPublicActivityTo (account: AccountInstance) { |
@@ -169,9 +173,9 @@ async function getPublicActivityTo (account: AccountInstance) { | |||
169 | return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') | 173 | return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') |
170 | } | 174 | } |
171 | 175 | ||
172 | async function createActivityData (url: string, byAccount: AccountInstance, object: any, raw = false) { | 176 | async function createActivityData (url: string, byAccount: AccountInstance, object: any) { |
173 | const to = await getPublicActivityTo(byAccount) | 177 | const to = await getPublicActivityTo(byAccount) |
174 | const base = { | 178 | const activity: ActivityCreate = { |
175 | type: 'Create', | 179 | type: 'Create', |
176 | id: url, | 180 | id: url, |
177 | actor: byAccount.url, | 181 | actor: byAccount.url, |
@@ -179,14 +183,12 @@ async function createActivityData (url: string, byAccount: AccountInstance, obje | |||
179 | object | 183 | object |
180 | } | 184 | } |
181 | 185 | ||
182 | if (raw === true) return base | 186 | return activity |
183 | |||
184 | return buildSignedActivity(byAccount, base) | ||
185 | } | 187 | } |
186 | 188 | ||
187 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { | 189 | async function updateActivityData (url: string, byAccount: AccountInstance, object: any) { |
188 | const to = await getPublicActivityTo(byAccount) | 190 | const to = await getPublicActivityTo(byAccount) |
189 | const base = { | 191 | const activity: ActivityUpdate = { |
190 | type: 'Update', | 192 | type: 'Update', |
191 | id: url, | 193 | id: url, |
192 | actor: byAccount.url, | 194 | actor: byAccount.url, |
@@ -194,22 +196,22 @@ async function updateActivityData (url: string, byAccount: AccountInstance, obje | |||
194 | object | 196 | object |
195 | } | 197 | } |
196 | 198 | ||
197 | return buildSignedActivity(byAccount, base) | 199 | return activity |
198 | } | 200 | } |
199 | 201 | ||
200 | async function deleteActivityData (url: string, byAccount: AccountInstance) { | 202 | async function deleteActivityData (url: string, byAccount: AccountInstance) { |
201 | const base = { | 203 | const activity: ActivityDelete = { |
202 | type: 'Delete', | 204 | type: 'Delete', |
203 | id: url, | 205 | id: url, |
204 | actor: byAccount.url | 206 | actor: byAccount.url |
205 | } | 207 | } |
206 | 208 | ||
207 | return buildSignedActivity(byAccount, base) | 209 | return activity |
208 | } | 210 | } |
209 | 211 | ||
210 | async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any, raw = false) { | 212 | async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any) { |
211 | const to = await getPublicActivityTo(byAccount) | 213 | const to = await getPublicActivityTo(byAccount) |
212 | const base = { | 214 | const activity: ActivityAdd = { |
213 | type: 'Add', | 215 | type: 'Add', |
214 | id: url, | 216 | id: url, |
215 | actor: byAccount.url, | 217 | actor: byAccount.url, |
@@ -218,39 +220,37 @@ async function addActivityData (url: string, byAccount: AccountInstance, target: | |||
218 | target | 220 | target |
219 | } | 221 | } |
220 | 222 | ||
221 | if (raw === true) return base | 223 | return activity |
222 | |||
223 | return buildSignedActivity(byAccount, base) | ||
224 | } | 224 | } |
225 | 225 | ||
226 | async function announceActivityData (url: string, byAccount: AccountInstance, object: any) { | 226 | async function announceActivityData (url: string, byAccount: AccountInstance, object: any) { |
227 | const base = { | 227 | const activity = { |
228 | type: 'Announce', | 228 | type: 'Announce', |
229 | id: url, | 229 | id: url, |
230 | actor: byAccount.url, | 230 | actor: byAccount.url, |
231 | object | 231 | object |
232 | } | 232 | } |
233 | 233 | ||
234 | return buildSignedActivity(byAccount, base) | 234 | return activity |
235 | } | 235 | } |
236 | 236 | ||
237 | async function followActivityData (url: string, byAccount: AccountInstance) { | 237 | async function followActivityData (url: string, byAccount: AccountInstance) { |
238 | const base = { | 238 | const activity: ActivityFollow = { |
239 | type: 'Follow', | 239 | type: 'Follow', |
240 | id: byAccount.url, | 240 | id: byAccount.url, |
241 | actor: byAccount.url, | 241 | actor: byAccount.url, |
242 | object: url | 242 | object: url |
243 | } | 243 | } |
244 | 244 | ||
245 | return buildSignedActivity(byAccount, base) | 245 | return activity |
246 | } | 246 | } |
247 | 247 | ||
248 | async function acceptActivityData (byAccount: AccountInstance) { | 248 | async function acceptActivityData (byAccount: AccountInstance) { |
249 | const base = { | 249 | const activity: ActivityAccept = { |
250 | type: 'Accept', | 250 | type: 'Accept', |
251 | id: byAccount.url, | 251 | id: byAccount.url, |
252 | actor: byAccount.url | 252 | actor: byAccount.url |
253 | } | 253 | } |
254 | 254 | ||
255 | return buildSignedActivity(byAccount, base) | 255 | return activity |
256 | } | 256 | } |
diff --git a/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-broadcast-handler.ts b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-broadcast-handler.ts new file mode 100644 index 000000000..111fc88a4 --- /dev/null +++ b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-broadcast-handler.ts | |||
@@ -0,0 +1,43 @@ | |||
1 | import { logger } from '../../../helpers' | ||
2 | import { buildSignedActivity } from '../../../helpers/activitypub' | ||
3 | import { doRequest } from '../../../helpers/requests' | ||
4 | import { database as db } from '../../../initializers' | ||
5 | import { ActivityPubHttpPayload } from './activitypub-http-job-scheduler' | ||
6 | |||
7 | async function process (payload: ActivityPubHttpPayload, jobId: number) { | ||
8 | logger.info('Processing ActivityPub broadcast in job %d.', jobId) | ||
9 | |||
10 | const accountSignature = await db.Account.load(payload.signatureAccountId) | ||
11 | if (!accountSignature) throw new Error('Unknown signature account id.') | ||
12 | |||
13 | const signedBody = await buildSignedActivity(accountSignature, payload.body) | ||
14 | |||
15 | const options = { | ||
16 | method: 'POST', | ||
17 | uri: '', | ||
18 | json: signedBody | ||
19 | } | ||
20 | |||
21 | for (const uri of payload.uris) { | ||
22 | options.uri = uri | ||
23 | await doRequest(options) | ||
24 | } | ||
25 | } | ||
26 | |||
27 | function onError (err: Error, jobId: number) { | ||
28 | logger.error('Error when broadcasting ActivityPub request in job %d.', jobId, err) | ||
29 | return Promise.resolve() | ||
30 | } | ||
31 | |||
32 | function onSuccess (jobId: number) { | ||
33 | logger.info('Job %d is a success.', jobId) | ||
34 | return Promise.resolve() | ||
35 | } | ||
36 | |||
37 | // --------------------------------------------------------------------------- | ||
38 | |||
39 | export { | ||
40 | process, | ||
41 | onError, | ||
42 | onSuccess | ||
43 | } | ||
diff --git a/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler.ts b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler.ts new file mode 100644 index 000000000..e4f6c94a5 --- /dev/null +++ b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler.ts | |||
@@ -0,0 +1,23 @@ | |||
1 | import { JobScheduler, JobHandler } from '../job-scheduler' | ||
2 | |||
3 | import * as activitypubHttpBroadcastHandler from './activitypub-http-broadcast-handler' | ||
4 | import * as activitypubHttpUnicastHandler from './activitypub-http-unicast-handler' | ||
5 | import { JobCategory } from '../../../../shared' | ||
6 | |||
7 | type ActivityPubHttpPayload = { | ||
8 | uris: string[] | ||
9 | signatureAccountId: number | ||
10 | body: any | ||
11 | } | ||
12 | const jobHandlers: { [ handlerName: string ]: JobHandler<ActivityPubHttpPayload, void> } = { | ||
13 | activitypubHttpBroadcastHandler, | ||
14 | activitypubHttpUnicastHandler | ||
15 | } | ||
16 | const jobCategory: JobCategory = 'activitypub-http' | ||
17 | |||
18 | const activitypubHttpJobScheduler = new JobScheduler(jobCategory, jobHandlers) | ||
19 | |||
20 | export { | ||
21 | ActivityPubHttpPayload, | ||
22 | activitypubHttpJobScheduler | ||
23 | } | ||
diff --git a/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-unicast-handler.ts b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-unicast-handler.ts new file mode 100644 index 000000000..8d3b755ad --- /dev/null +++ b/server/lib/jobs/activitypub-http-job-scheduler/activitypub-http-unicast-handler.ts | |||
@@ -0,0 +1,40 @@ | |||
1 | import { logger } from '../../../helpers' | ||
2 | import { doRequest } from '../../../helpers/requests' | ||
3 | import { ActivityPubHttpPayload } from './activitypub-http-job-scheduler' | ||
4 | import { database as db } from '../../../initializers/database' | ||
5 | import { buildSignedActivity } from '../../../helpers/activitypub' | ||
6 | |||
7 | async function process (payload: ActivityPubHttpPayload, jobId: number) { | ||
8 | logger.info('Processing ActivityPub unicast in job %d.', jobId) | ||
9 | |||
10 | const accountSignature = await db.Account.load(payload.signatureAccountId) | ||
11 | if (!accountSignature) throw new Error('Unknown signature account id.') | ||
12 | |||
13 | const signedBody = await buildSignedActivity(accountSignature, payload.body) | ||
14 | const uri = payload.uris[0] | ||
15 | const options = { | ||
16 | method: 'POST', | ||
17 | uri, | ||
18 | json: signedBody | ||
19 | } | ||
20 | |||
21 | await doRequest(options) | ||
22 | } | ||
23 | |||
24 | function onError (err: Error, jobId: number) { | ||
25 | logger.error('Error when sending ActivityPub request in job %d.', jobId, err) | ||
26 | return Promise.resolve() | ||
27 | } | ||
28 | |||
29 | function onSuccess (jobId: number) { | ||
30 | logger.info('Job %d is a success.', jobId) | ||
31 | return Promise.resolve() | ||
32 | } | ||
33 | |||
34 | // --------------------------------------------------------------------------- | ||
35 | |||
36 | export { | ||
37 | process, | ||
38 | onError, | ||
39 | onSuccess | ||
40 | } | ||
diff --git a/server/lib/jobs/activitypub-http-job-scheduler/index.ts b/server/lib/jobs/activitypub-http-job-scheduler/index.ts new file mode 100644 index 000000000..ad8f527b4 --- /dev/null +++ b/server/lib/jobs/activitypub-http-job-scheduler/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './activitypub-http-job-scheduler' | |||
diff --git a/server/lib/jobs/http-request-job-scheduler/http-request-broadcast-handler.ts b/server/lib/jobs/http-request-job-scheduler/http-request-broadcast-handler.ts deleted file mode 100644 index ccb008e4d..000000000 --- a/server/lib/jobs/http-request-job-scheduler/http-request-broadcast-handler.ts +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | import { logger } from '../../../helpers' | ||
2 | import { doRequest } from '../../../helpers/requests' | ||
3 | import { HTTPRequestPayload } from './http-request-job-scheduler' | ||
4 | |||
5 | async function process (payload: HTTPRequestPayload, jobId: number) { | ||
6 | logger.info('Processing broadcast in job %d.', jobId) | ||
7 | |||
8 | const options = { | ||
9 | method: 'POST', | ||
10 | uri: '', | ||
11 | json: payload.body | ||
12 | } | ||
13 | |||
14 | for (const uri of payload.uris) { | ||
15 | options.uri = uri | ||
16 | await doRequest(options) | ||
17 | } | ||
18 | } | ||
19 | |||
20 | function onError (err: Error, jobId: number) { | ||
21 | logger.error('Error when broadcasting request in job %d.', jobId, err) | ||
22 | return Promise.resolve() | ||
23 | } | ||
24 | |||
25 | function onSuccess (jobId: number) { | ||
26 | logger.info('Job %d is a success.', jobId) | ||
27 | return Promise.resolve() | ||
28 | } | ||
29 | |||
30 | // --------------------------------------------------------------------------- | ||
31 | |||
32 | export { | ||
33 | process, | ||
34 | onError, | ||
35 | onSuccess | ||
36 | } | ||
diff --git a/server/lib/jobs/http-request-job-scheduler/http-request-job-scheduler.ts b/server/lib/jobs/http-request-job-scheduler/http-request-job-scheduler.ts deleted file mode 100644 index ad3349866..000000000 --- a/server/lib/jobs/http-request-job-scheduler/http-request-job-scheduler.ts +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | import { JobScheduler, JobHandler } from '../job-scheduler' | ||
2 | |||
3 | import * as httpRequestBroadcastHandler from './http-request-broadcast-handler' | ||
4 | import * as httpRequestUnicastHandler from './http-request-unicast-handler' | ||
5 | import { JobCategory } from '../../../../shared' | ||
6 | |||
7 | type HTTPRequestPayload = { | ||
8 | uris: string[] | ||
9 | body: any | ||
10 | } | ||
11 | const jobHandlers: { [ handlerName: string ]: JobHandler<HTTPRequestPayload, void> } = { | ||
12 | httpRequestBroadcastHandler, | ||
13 | httpRequestUnicastHandler | ||
14 | } | ||
15 | const jobCategory: JobCategory = 'http-request' | ||
16 | |||
17 | const httpRequestJobScheduler = new JobScheduler(jobCategory, jobHandlers) | ||
18 | |||
19 | export { | ||
20 | HTTPRequestPayload, | ||
21 | httpRequestJobScheduler | ||
22 | } | ||
diff --git a/server/lib/jobs/http-request-job-scheduler/http-request-unicast-handler.ts b/server/lib/jobs/http-request-job-scheduler/http-request-unicast-handler.ts deleted file mode 100644 index 9e4e73891..000000000 --- a/server/lib/jobs/http-request-job-scheduler/http-request-unicast-handler.ts +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | import { logger } from '../../../helpers' | ||
2 | import { doRequest } from '../../../helpers/requests' | ||
3 | import { HTTPRequestPayload } from './http-request-job-scheduler' | ||
4 | |||
5 | async function process (payload: HTTPRequestPayload, jobId: number) { | ||
6 | logger.info('Processing unicast in job %d.', jobId) | ||
7 | |||
8 | const uri = payload.uris[0] | ||
9 | const options = { | ||
10 | method: 'POST', | ||
11 | uri, | ||
12 | json: payload.body | ||
13 | } | ||
14 | |||
15 | await doRequest(options) | ||
16 | } | ||
17 | |||
18 | function onError (err: Error, jobId: number) { | ||
19 | logger.error('Error when sending request in job %d.', jobId, err) | ||
20 | return Promise.resolve() | ||
21 | } | ||
22 | |||
23 | function onSuccess (jobId: number) { | ||
24 | logger.info('Job %d is a success.', jobId) | ||
25 | return Promise.resolve() | ||
26 | } | ||
27 | |||
28 | // --------------------------------------------------------------------------- | ||
29 | |||
30 | export { | ||
31 | process, | ||
32 | onError, | ||
33 | onSuccess | ||
34 | } | ||
diff --git a/server/lib/jobs/http-request-job-scheduler/index.ts b/server/lib/jobs/http-request-job-scheduler/index.ts deleted file mode 100644 index 4d2573296..000000000 --- a/server/lib/jobs/http-request-job-scheduler/index.ts +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | export * from './http-request-job-scheduler' | ||
diff --git a/server/lib/jobs/index.ts b/server/lib/jobs/index.ts index a92743707..394264ec1 100644 --- a/server/lib/jobs/index.ts +++ b/server/lib/jobs/index.ts | |||
@@ -1,2 +1,2 @@ | |||
1 | export * from './http-request-job-scheduler' | 1 | export * from './activitypub-http-job-scheduler' |
2 | export * from './transcoding-job-scheduler' | 2 | export * from './transcoding-job-scheduler' |
diff --git a/server/tests/api/index-fast.ts b/server/tests/api/index-fast.ts index f13d8155d..ced973bc2 100644 --- a/server/tests/api/index-fast.ts +++ b/server/tests/api/index-fast.ts | |||
@@ -10,4 +10,3 @@ import './video-blacklist-management' | |||
10 | import './video-description' | 10 | import './video-description' |
11 | import './video-privacy' | 11 | import './video-privacy' |
12 | import './services' | 12 | import './services' |
13 | import './request-schedulers' | ||
diff --git a/server/tests/api/multiple-pods.ts b/server/tests/api/multiple-pods.ts index 8e89da97a..3c6b3f650 100644 --- a/server/tests/api/multiple-pods.ts +++ b/server/tests/api/multiple-pods.ts | |||
@@ -113,7 +113,7 @@ describe('Test multiple pods', function () { | |||
113 | expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) | 113 | expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) |
114 | expect(dateIsValid(video.createdAt)).to.be.true | 114 | expect(dateIsValid(video.createdAt)).to.be.true |
115 | expect(dateIsValid(video.updatedAt)).to.be.true | 115 | expect(dateIsValid(video.updatedAt)).to.be.true |
116 | expect(video.author).to.equal('root') | 116 | expect(video.account).to.equal('root') |
117 | 117 | ||
118 | const res2 = await getVideo(server.url, video.uuid) | 118 | const res2 = await getVideo(server.url, video.uuid) |
119 | const videoDetails = res2.body | 119 | const videoDetails = res2.body |
@@ -202,7 +202,7 @@ describe('Test multiple pods', function () { | |||
202 | expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) | 202 | expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) |
203 | expect(dateIsValid(video.createdAt)).to.be.true | 203 | expect(dateIsValid(video.createdAt)).to.be.true |
204 | expect(dateIsValid(video.updatedAt)).to.be.true | 204 | expect(dateIsValid(video.updatedAt)).to.be.true |
205 | expect(video.author).to.equal('user1') | 205 | expect(video.account).to.equal('user1') |
206 | 206 | ||
207 | if (server.url !== 'http://localhost:9002') { | 207 | if (server.url !== 'http://localhost:9002') { |
208 | expect(video.isLocal).to.be.false | 208 | expect(video.isLocal).to.be.false |
@@ -696,7 +696,7 @@ describe('Test multiple pods', function () { | |||
696 | expect(baseVideo.licence).to.equal(video.licence) | 696 | expect(baseVideo.licence).to.equal(video.licence) |
697 | expect(baseVideo.category).to.equal(video.category) | 697 | expect(baseVideo.category).to.equal(video.category) |
698 | expect(baseVideo.nsfw).to.equal(video.nsfw) | 698 | expect(baseVideo.nsfw).to.equal(video.nsfw) |
699 | expect(baseVideo.author).to.equal(video.author) | 699 | expect(baseVideo.author).to.equal(video.account) |
700 | expect(baseVideo.tags).to.deep.equal(video.tags) | 700 | expect(baseVideo.tags).to.deep.equal(video.tags) |
701 | } | 701 | } |
702 | }) | 702 | }) |
diff --git a/server/tests/api/request-schedulers.ts b/server/tests/api/request-schedulers.ts deleted file mode 100644 index c136d1cea..000000000 --- a/server/tests/api/request-schedulers.ts +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | ||
5 | const expect = chai.expect | ||
6 | |||
7 | import { | ||
8 | ServerInfo, | ||
9 | flushTests, | ||
10 | uploadVideo, | ||
11 | makeFriends, | ||
12 | wait, | ||
13 | setAccessTokensToServers, | ||
14 | flushAndRunMultipleServers, | ||
15 | getRequestsStats, | ||
16 | killallServers | ||
17 | } from '../utils' | ||
18 | |||
19 | describe('Test requests schedulers stats', function () { | ||
20 | const requestSchedulerNames = [ 'requestScheduler', 'requestVideoQaduScheduler', 'requestVideoEventScheduler' ] | ||
21 | let servers: ServerInfo[] = [] | ||
22 | |||
23 | function uploadVideoWrapper (server: ServerInfo) { | ||
24 | const videoAttributes = { | ||
25 | tags: [ 'tag1', 'tag2' ] | ||
26 | } | ||
27 | |||
28 | return uploadVideo(server.url, server.accessToken, videoAttributes) | ||
29 | } | ||
30 | |||
31 | // --------------------------------------------------------------- | ||
32 | |||
33 | before(async function () { | ||
34 | this.timeout(120000) | ||
35 | |||
36 | servers = await flushAndRunMultipleServers(2) | ||
37 | |||
38 | await setAccessTokensToServers(servers) | ||
39 | |||
40 | await makeFriends(servers[0].url, servers[0].accessToken) | ||
41 | }) | ||
42 | |||
43 | it('Should have a correct timer', async function () { | ||
44 | const server = servers[0] | ||
45 | |||
46 | const res = await getRequestsStats(server) | ||
47 | |||
48 | const requestSchedulers = res.body | ||
49 | for (const requestSchedulerName of requestSchedulerNames) { | ||
50 | const requestScheduler = requestSchedulers[requestSchedulerName] | ||
51 | |||
52 | expect(requestScheduler.remainingMilliSeconds).to.be.at.least(0) | ||
53 | expect(requestScheduler.remainingMilliSeconds).to.be.at.most(10000) | ||
54 | } | ||
55 | }) | ||
56 | |||
57 | it('Should have the correct total request', async function () { | ||
58 | this.timeout(15000) | ||
59 | |||
60 | const server = servers[0] | ||
61 | // Ensure the requests of pod 1 won't be made | ||
62 | servers[1].app.kill() | ||
63 | |||
64 | await uploadVideoWrapper(server) | ||
65 | |||
66 | await wait(1000) | ||
67 | |||
68 | const res = await getRequestsStats(server) | ||
69 | const requestSchedulers = res.body | ||
70 | const requestScheduler = requestSchedulers.requestScheduler | ||
71 | expect(requestScheduler.totalRequests).to.equal(3) | ||
72 | }) | ||
73 | |||
74 | after(async function () { | ||
75 | // Server 1 has already been killed | ||
76 | killallServers([ servers[0] ]) | ||
77 | |||
78 | if (this['ok']) { | ||
79 | await flushTests() | ||
80 | } | ||
81 | }) | ||
82 | }) | ||
diff --git a/server/tests/api/services.ts b/server/tests/api/services.ts index 76911fdc5..c34c51f66 100644 --- a/server/tests/api/services.ts +++ b/server/tests/api/services.ts | |||
@@ -14,6 +14,7 @@ import { | |||
14 | getOEmbed | 14 | getOEmbed |
15 | } from '../utils' | 15 | } from '../utils' |
16 | import { runServer } from '../utils/servers' | 16 | import { runServer } from '../utils/servers' |
17 | import { Video } from '../../../client/src/app/videos/shared/video.model' | ||
17 | 18 | ||
18 | describe('Test services', function () { | 19 | describe('Test services', function () { |
19 | let server: ServerInfo = null | 20 | let server: ServerInfo = null |
@@ -46,7 +47,7 @@ describe('Test services', function () { | |||
46 | 47 | ||
47 | expect(res.body.html).to.equal(expectedHtml) | 48 | expect(res.body.html).to.equal(expectedHtml) |
48 | expect(res.body.title).to.equal(server.video.name) | 49 | expect(res.body.title).to.equal(server.video.name) |
49 | expect(res.body.author_name).to.equal(server.video.author) | 50 | expect(res.body.author_name).to.equal(server.video.account) |
50 | expect(res.body.width).to.equal(560) | 51 | expect(res.body.width).to.equal(560) |
51 | expect(res.body.height).to.equal(315) | 52 | expect(res.body.height).to.equal(315) |
52 | expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) | 53 | expect(res.body.thumbnail_url).to.equal(expectedThumbnailUrl) |
@@ -66,7 +67,7 @@ describe('Test services', function () { | |||
66 | 67 | ||
67 | expect(res.body.html).to.equal(expectedHtml) | 68 | expect(res.body.html).to.equal(expectedHtml) |
68 | expect(res.body.title).to.equal(server.video.name) | 69 | expect(res.body.title).to.equal(server.video.name) |
69 | expect(res.body.author_name).to.equal(server.video.author) | 70 | expect(res.body.author_name).to.equal(server.video.account) |
70 | expect(res.body.height).to.equal(50) | 71 | expect(res.body.height).to.equal(50) |
71 | expect(res.body.width).to.equal(50) | 72 | expect(res.body.width).to.equal(50) |
72 | expect(res.body).to.not.have.property('thumbnail_url') | 73 | expect(res.body).to.not.have.property('thumbnail_url') |
diff --git a/server/tests/api/single-pod.ts b/server/tests/api/single-pod.ts index 3a05d0727..0a917f2ae 100644 --- a/server/tests/api/single-pod.ts +++ b/server/tests/api/single-pod.ts | |||
@@ -125,8 +125,8 @@ describe('Test a single pod', function () { | |||
125 | expect(video.languageLabel).to.equal('Mandarin') | 125 | expect(video.languageLabel).to.equal('Mandarin') |
126 | expect(video.nsfw).to.be.ok | 126 | expect(video.nsfw).to.be.ok |
127 | expect(video.description).to.equal('my super description') | 127 | expect(video.description).to.equal('my super description') |
128 | expect(video.podHost).to.equal('localhost:9001') | 128 | expect(video.serverHost).to.equal('localhost:9001') |
129 | expect(video.author).to.equal('root') | 129 | expect(video.account).to.equal('root') |
130 | expect(video.isLocal).to.be.true | 130 | expect(video.isLocal).to.be.true |
131 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 131 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
132 | expect(dateIsValid(video.createdAt)).to.be.true | 132 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -174,8 +174,8 @@ describe('Test a single pod', function () { | |||
174 | expect(video.languageLabel).to.equal('Mandarin') | 174 | expect(video.languageLabel).to.equal('Mandarin') |
175 | expect(video.nsfw).to.be.ok | 175 | expect(video.nsfw).to.be.ok |
176 | expect(video.description).to.equal('my super description') | 176 | expect(video.description).to.equal('my super description') |
177 | expect(video.podHost).to.equal('localhost:9001') | 177 | expect(video.serverHost).to.equal('localhost:9001') |
178 | expect(video.author).to.equal('root') | 178 | expect(video.account).to.equal('root') |
179 | expect(video.isLocal).to.be.true | 179 | expect(video.isLocal).to.be.true |
180 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 180 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
181 | expect(dateIsValid(video.createdAt)).to.be.true | 181 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -237,8 +237,8 @@ describe('Test a single pod', function () { | |||
237 | expect(video.languageLabel).to.equal('Mandarin') | 237 | expect(video.languageLabel).to.equal('Mandarin') |
238 | expect(video.nsfw).to.be.ok | 238 | expect(video.nsfw).to.be.ok |
239 | expect(video.description).to.equal('my super description') | 239 | expect(video.description).to.equal('my super description') |
240 | expect(video.podHost).to.equal('localhost:9001') | 240 | expect(video.serverHost).to.equal('localhost:9001') |
241 | expect(video.author).to.equal('root') | 241 | expect(video.account).to.equal('root') |
242 | expect(video.isLocal).to.be.true | 242 | expect(video.isLocal).to.be.true |
243 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 243 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
244 | expect(dateIsValid(video.createdAt)).to.be.true | 244 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -249,7 +249,7 @@ describe('Test a single pod', function () { | |||
249 | }) | 249 | }) |
250 | 250 | ||
251 | // Not implemented yet | 251 | // Not implemented yet |
252 | // it('Should search the video by podHost', async function () { | 252 | // it('Should search the video by serverHost', async function () { |
253 | // const res = await videosUtils.searchVideo(server.url, '9001', 'host') | 253 | // const res = await videosUtils.searchVideo(server.url, '9001', 'host') |
254 | 254 | ||
255 | // expect(res.body.total).to.equal(1) | 255 | // expect(res.body.total).to.equal(1) |
@@ -259,7 +259,7 @@ describe('Test a single pod', function () { | |||
259 | // const video = res.body.data[0] | 259 | // const video = res.body.data[0] |
260 | // expect(video.name).to.equal('my super name') | 260 | // expect(video.name).to.equal('my super name') |
261 | // expect(video.description).to.equal('my super description') | 261 | // expect(video.description).to.equal('my super description') |
262 | // expect(video.podHost).to.equal('localhost:9001') | 262 | // expect(video.serverHost).to.equal('localhost:9001') |
263 | // expect(video.author).to.equal('root') | 263 | // expect(video.author).to.equal('root') |
264 | // expect(video.isLocal).to.be.true | 264 | // expect(video.isLocal).to.be.true |
265 | // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 265 | // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
@@ -291,8 +291,8 @@ describe('Test a single pod', function () { | |||
291 | expect(video.languageLabel).to.equal('Mandarin') | 291 | expect(video.languageLabel).to.equal('Mandarin') |
292 | expect(video.nsfw).to.be.ok | 292 | expect(video.nsfw).to.be.ok |
293 | expect(video.description).to.equal('my super description') | 293 | expect(video.description).to.equal('my super description') |
294 | expect(video.podHost).to.equal('localhost:9001') | 294 | expect(video.serverHost).to.equal('localhost:9001') |
295 | expect(video.author).to.equal('root') | 295 | expect(video.account).to.equal('root') |
296 | expect(video.isLocal).to.be.true | 296 | expect(video.isLocal).to.be.true |
297 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 297 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
298 | expect(dateIsValid(video.createdAt)).to.be.true | 298 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -311,7 +311,7 @@ describe('Test a single pod', function () { | |||
311 | }) | 311 | }) |
312 | 312 | ||
313 | it('Should not find a search by author', async function () { | 313 | it('Should not find a search by author', async function () { |
314 | const res = await searchVideo(server.url, 'hello', 'author') | 314 | const res = await searchVideo(server.url, 'hello', 'account') |
315 | 315 | ||
316 | expect(res.body.total).to.equal(0) | 316 | expect(res.body.total).to.equal(0) |
317 | expect(res.body.data).to.be.an('array') | 317 | expect(res.body.data).to.be.an('array') |
@@ -352,7 +352,7 @@ describe('Test a single pod', function () { | |||
352 | 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' | 352 | 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' |
353 | ] | 353 | ] |
354 | 354 | ||
355 | const tasks: Promise<any>[] = [] | 355 | // const tasks: Promise<any>[] = [] |
356 | for (const video of videos) { | 356 | for (const video of videos) { |
357 | const videoAttributes = { | 357 | const videoAttributes = { |
358 | name: video + ' name', | 358 | name: video + ' name', |
@@ -366,10 +366,13 @@ describe('Test a single pod', function () { | |||
366 | } | 366 | } |
367 | 367 | ||
368 | const p = uploadVideo(server.url, server.accessToken, videoAttributes) | 368 | const p = uploadVideo(server.url, server.accessToken, videoAttributes) |
369 | tasks.push(p) | 369 | await p |
370 | } | 370 | } |
371 | 371 | // FIXME: concurrent uploads does not work :( | |
372 | await Promise.all(tasks) | 372 | // tasks.push(p) |
373 | // } | ||
374 | // | ||
375 | // await Promise.all(tasks) | ||
373 | }) | 376 | }) |
374 | 377 | ||
375 | it('Should have the correct durations', async function () { | 378 | it('Should have the correct durations', async function () { |
@@ -462,7 +465,7 @@ describe('Test a single pod', function () { | |||
462 | }) | 465 | }) |
463 | 466 | ||
464 | it('Should search all the root author videos', async function () { | 467 | it('Should search all the root author videos', async function () { |
465 | const res = await searchVideoWithPagination(server.url, 'root', 'author', 0, 15) | 468 | const res = await searchVideoWithPagination(server.url, 'root', 'account', 0, 15) |
466 | 469 | ||
467 | const videos = res.body.data | 470 | const videos = res.body.data |
468 | expect(res.body.total).to.equal(6) | 471 | expect(res.body.total).to.equal(6) |
@@ -550,8 +553,8 @@ describe('Test a single pod', function () { | |||
550 | expect(video.languageLabel).to.equal('Arabic') | 553 | expect(video.languageLabel).to.equal('Arabic') |
551 | expect(video.nsfw).to.be.ok | 554 | expect(video.nsfw).to.be.ok |
552 | expect(video.description).to.equal('my super description updated') | 555 | expect(video.description).to.equal('my super description updated') |
553 | expect(video.podHost).to.equal('localhost:9001') | 556 | expect(video.serverHost).to.equal('localhost:9001') |
554 | expect(video.author).to.equal('root') | 557 | expect(video.account).to.equal('root') |
555 | expect(video.isLocal).to.be.true | 558 | expect(video.isLocal).to.be.true |
556 | expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ]) | 559 | expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ]) |
557 | expect(dateIsValid(video.createdAt)).to.be.true | 560 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -599,8 +602,8 @@ describe('Test a single pod', function () { | |||
599 | expect(video.languageLabel).to.equal('Arabic') | 602 | expect(video.languageLabel).to.equal('Arabic') |
600 | expect(video.nsfw).to.be.ok | 603 | expect(video.nsfw).to.be.ok |
601 | expect(video.description).to.equal('my super description updated') | 604 | expect(video.description).to.equal('my super description updated') |
602 | expect(video.podHost).to.equal('localhost:9001') | 605 | expect(video.serverHost).to.equal('localhost:9001') |
603 | expect(video.author).to.equal('root') | 606 | expect(video.account).to.equal('root') |
604 | expect(video.isLocal).to.be.true | 607 | expect(video.isLocal).to.be.true |
605 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ]) | 608 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ]) |
606 | expect(dateIsValid(video.createdAt)).to.be.true | 609 | expect(dateIsValid(video.createdAt)).to.be.true |
@@ -639,8 +642,8 @@ describe('Test a single pod', function () { | |||
639 | expect(video.languageLabel).to.equal('Arabic') | 642 | expect(video.languageLabel).to.equal('Arabic') |
640 | expect(video.nsfw).to.be.ok | 643 | expect(video.nsfw).to.be.ok |
641 | expect(video.description).to.equal('hello everybody') | 644 | expect(video.description).to.equal('hello everybody') |
642 | expect(video.podHost).to.equal('localhost:9001') | 645 | expect(video.serverHost).to.equal('localhost:9001') |
643 | expect(video.author).to.equal('root') | 646 | expect(video.account).to.equal('root') |
644 | expect(video.isLocal).to.be.true | 647 | expect(video.isLocal).to.be.true |
645 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ]) | 648 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ]) |
646 | expect(dateIsValid(video.createdAt)).to.be.true | 649 | expect(dateIsValid(video.createdAt)).to.be.true |
diff --git a/server/tests/api/users.ts b/server/tests/api/users.ts index 6f40ca3c9..055dade04 100644 --- a/server/tests/api/users.ts +++ b/server/tests/api/users.ts | |||
@@ -1,38 +1,36 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | 1 | /* tslint:disable:no-unused-expression */ |
2 | |||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | 2 | import * as chai from 'chai' |
5 | const expect = chai.expect | 3 | import 'mocha' |
6 | 4 | import { UserRole } from '../../../shared' | |
7 | import { | 5 | import { |
8 | ServerInfo, | ||
9 | flushTests, | ||
10 | runServer, | ||
11 | login, | ||
12 | uploadVideo, | ||
13 | makeFriends, | ||
14 | quitFriends, | ||
15 | getVideosList, | ||
16 | rateVideo, | ||
17 | getUserVideoRating, | ||
18 | removeVideo, | ||
19 | makePutBodyRequest, | ||
20 | createUser, | 6 | createUser, |
21 | loginAndGetAccessToken, | 7 | flushTests, |
8 | getBlacklistedVideosList, | ||
22 | getMyUserInformation, | 9 | getMyUserInformation, |
10 | getUserInformation, | ||
23 | getUsersList, | 11 | getUsersList, |
24 | getUsersListPaginationAndSort, | 12 | getUsersListPaginationAndSort, |
25 | updateUser, | 13 | getUserVideoRating, |
26 | updateMyUser, | 14 | getVideosList, |
15 | killallServers, | ||
16 | login, | ||
17 | loginAndGetAccessToken, | ||
18 | makePutBodyRequest, | ||
19 | rateVideo, | ||
27 | registerUser, | 20 | registerUser, |
28 | removeUser, | 21 | removeUser, |
29 | killallServers, | 22 | removeVideo, |
30 | getUserInformation, | 23 | runServer, |
31 | getBlacklistedVideosList | 24 | ServerInfo, |
25 | updateMyUser, | ||
26 | updateUser, | ||
27 | uploadVideo | ||
32 | } from '../utils' | 28 | } from '../utils' |
33 | import { UserRole } from '../../../shared' | 29 | import { follow } from '../utils/follows' |
34 | import { getMyVideos } from '../utils/videos' | 30 | import { getMyVideos } from '../utils/videos' |
35 | 31 | ||
32 | const expect = chai.expect | ||
33 | |||
36 | describe('Test users', function () { | 34 | describe('Test users', function () { |
37 | let server: ServerInfo | 35 | let server: ServerInfo |
38 | let accessToken: string | 36 | let accessToken: string |
@@ -57,28 +55,36 @@ describe('Test users', function () { | |||
57 | const client = { id: 'client', secret: server.client.secret } | 55 | const client = { id: 'client', secret: server.client.secret } |
58 | const res = await login(server.url, client, server.user, 400) | 56 | const res = await login(server.url, client, server.user, 400) |
59 | 57 | ||
60 | expect(res.body.error).to.equal('invalid_client') | 58 | expect(res.body.error) |
59 | .to | ||
60 | .equal('invalid_client') | ||
61 | }) | 61 | }) |
62 | 62 | ||
63 | it('Should not login with an invalid client secret', async function () { | 63 | it('Should not login with an invalid client secret', async function () { |
64 | const client = { id: server.client.id, secret: 'coucou' } | 64 | const client = { id: server.client.id, secret: 'coucou' } |
65 | const res = await login(server.url, client, server.user, 400) | 65 | const res = await login(server.url, client, server.user, 400) |
66 | 66 | ||
67 | expect(res.body.error).to.equal('invalid_client') | 67 | expect(res.body.error) |
68 | .to | ||
69 | .equal('invalid_client') | ||
68 | }) | 70 | }) |
69 | 71 | ||
70 | it('Should not login with an invalid username', async function () { | 72 | it('Should not login with an invalid username', async function () { |
71 | const user = { username: 'captain crochet', password: server.user.password } | 73 | const user = { username: 'captain crochet', password: server.user.password } |
72 | const res = await login(server.url, server.client, user, 400) | 74 | const res = await login(server.url, server.client, user, 400) |
73 | 75 | ||
74 | expect(res.body.error).to.equal('invalid_grant') | 76 | expect(res.body.error) |
77 | .to | ||
78 | .equal('invalid_grant') | ||
75 | }) | 79 | }) |
76 | 80 | ||
77 | it('Should not login with an invalid password', async function () { | 81 | it('Should not login with an invalid password', async function () { |
78 | const user = { username: server.user.username, password: 'mew_three' } | 82 | const user = { username: server.user.username, password: 'mew_three' } |
79 | const res = await login(server.url, server.client, user, 400) | 83 | const res = await login(server.url, server.client, user, 400) |
80 | 84 | ||
81 | expect(res.body.error).to.equal('invalid_grant') | 85 | expect(res.body.error) |
86 | .to | ||
87 | .equal('invalid_grant') | ||
82 | }) | 88 | }) |
83 | 89 | ||
84 | it('Should not be able to upload a video', async function () { | 90 | it('Should not be able to upload a video', async function () { |
@@ -88,15 +94,12 @@ describe('Test users', function () { | |||
88 | await uploadVideo(server.url, accessToken, videoAttributes, 401) | 94 | await uploadVideo(server.url, accessToken, videoAttributes, 401) |
89 | }) | 95 | }) |
90 | 96 | ||
91 | it('Should not be able to make friends', async function () { | 97 | it('Should not be able to follow', async function () { |
92 | accessToken = 'my_super_token' | 98 | accessToken = 'my_super_token' |
93 | await makeFriends(server.url, accessToken, 401) | 99 | await follow(server.url, [ 'http://example.com' ], accessToken, 401) |
94 | }) | 100 | }) |
95 | 101 | ||
96 | it('Should not be able to quit friends', async function () { | 102 | it('Should not be able to unfollow') |
97 | accessToken = 'my_super_token' | ||
98 | await quitFriends(server.url, accessToken, 401) | ||
99 | }) | ||
100 | 103 | ||
101 | it('Should be able to login', async function () { | 104 | it('Should be able to login', async function () { |
102 | const res = await login(server.url, server.client, server.user, 200) | 105 | const res = await login(server.url, server.client, server.user, 200) |
@@ -108,9 +111,11 @@ describe('Test users', function () { | |||
108 | const videoAttributes = {} | 111 | const videoAttributes = {} |
109 | await uploadVideo(server.url, accessToken, videoAttributes, 204) | 112 | await uploadVideo(server.url, accessToken, videoAttributes, 204) |
110 | const res = await getVideosList(server.url) | 113 | const res = await getVideosList(server.url) |
111 | const video = res.body.data[0] | 114 | const video = res.body.data[ 0 ] |
112 | 115 | ||
113 | expect(video.author).to.equal('root') | 116 | expect(video.account) |
117 | .to | ||
118 | .equal('root') | ||
114 | videoId = video.id | 119 | videoId = video.id |
115 | }) | 120 | }) |
116 | 121 | ||
@@ -124,8 +129,12 @@ describe('Test users', function () { | |||
124 | const res = await getUserVideoRating(server.url, accessToken, videoId) | 129 | const res = await getUserVideoRating(server.url, accessToken, videoId) |
125 | const rating = res.body | 130 | const rating = res.body |
126 | 131 | ||
127 | expect(rating.videoId).to.equal(videoId) | 132 | expect(rating.videoId) |
128 | expect(rating.rating).to.equal('like') | 133 | .to |
134 | .equal(videoId) | ||
135 | expect(rating.rating) | ||
136 | .to | ||
137 | .equal('like') | ||
129 | }) | 138 | }) |
130 | 139 | ||
131 | it('Should not be able to remove the video with an incorrect token', async function () { | 140 | it('Should not be able to remove the video with an incorrect token', async function () { |
@@ -187,12 +196,23 @@ describe('Test users', function () { | |||
187 | const res = await getMyUserInformation(server.url, accessTokenUser) | 196 | const res = await getMyUserInformation(server.url, accessTokenUser) |
188 | const user = res.body | 197 | const user = res.body |
189 | 198 | ||
190 | expect(user.username).to.equal('user_1') | 199 | expect(user.username) |
191 | expect(user.email).to.equal('user_1@example.com') | 200 | .to |
201 | .equal('user_1') | ||
202 | expect(user.email) | ||
203 | .to | ||
204 | .equal('user_1@example.com') | ||
192 | expect(user.displayNSFW).to.be.false | 205 | expect(user.displayNSFW).to.be.false |
193 | expect(user.videoQuota).to.equal(2 * 1024 * 1024) | 206 | expect(user.videoQuota) |
194 | expect(user.roleLabel).to.equal('User') | 207 | .to |
195 | expect(user.id).to.be.a('number') | 208 | .equal(2 * 1024 * 1024) |
209 | expect(user.roleLabel) | ||
210 | .to | ||
211 | .equal('User') | ||
212 | expect(user.id) | ||
213 | .to | ||
214 | .be | ||
215 | .a('number') | ||
196 | }) | 216 | }) |
197 | 217 | ||
198 | it('Should be able to upload a video with this user', async function () { | 218 | it('Should be able to upload a video with this user', async function () { |
@@ -206,12 +226,19 @@ describe('Test users', function () { | |||
206 | 226 | ||
207 | it('Should be able to list my videos', async function () { | 227 | it('Should be able to list my videos', async function () { |
208 | const res = await getMyVideos(server.url, accessTokenUser, 0, 5) | 228 | const res = await getMyVideos(server.url, accessTokenUser, 0, 5) |
209 | expect(res.body.total).to.equal(1) | 229 | expect(res.body.total) |
230 | .to | ||
231 | .equal(1) | ||
210 | 232 | ||
211 | const videos = res.body.data | 233 | const videos = res.body.data |
212 | expect(videos).to.have.lengthOf(1) | 234 | expect(videos) |
235 | .to | ||
236 | .have | ||
237 | .lengthOf(1) | ||
213 | 238 | ||
214 | expect(videos[0].name).to.equal('super user video') | 239 | expect(videos[ 0 ].name) |
240 | .to | ||
241 | .equal('super user video') | ||
215 | }) | 242 | }) |
216 | 243 | ||
217 | it('Should list all the users', async function () { | 244 | it('Should list all the users', async function () { |
@@ -220,18 +247,33 @@ describe('Test users', function () { | |||
220 | const total = result.total | 247 | const total = result.total |
221 | const users = result.data | 248 | const users = result.data |
222 | 249 | ||
223 | expect(total).to.equal(2) | 250 | expect(total) |
224 | expect(users).to.be.an('array') | 251 | .to |
225 | expect(users.length).to.equal(2) | 252 | .equal(2) |
226 | 253 | expect(users) | |
227 | const user = users[0] | 254 | .to |
228 | expect(user.username).to.equal('user_1') | 255 | .be |
229 | expect(user.email).to.equal('user_1@example.com') | 256 | .an('array') |
257 | expect(users.length) | ||
258 | .to | ||
259 | .equal(2) | ||
260 | |||
261 | const user = users[ 0 ] | ||
262 | expect(user.username) | ||
263 | .to | ||
264 | .equal('user_1') | ||
265 | expect(user.email) | ||
266 | .to | ||
267 | .equal('user_1@example.com') | ||
230 | expect(user.displayNSFW).to.be.false | 268 | expect(user.displayNSFW).to.be.false |
231 | 269 | ||
232 | const rootUser = users[1] | 270 | const rootUser = users[ 1 ] |
233 | expect(rootUser.username).to.equal('root') | 271 | expect(rootUser.username) |
234 | expect(rootUser.email).to.equal('admin1@example.com') | 272 | .to |
273 | .equal('root') | ||
274 | expect(rootUser.email) | ||
275 | .to | ||
276 | .equal('admin1@example.com') | ||
235 | expect(rootUser.displayNSFW).to.be.false | 277 | expect(rootUser.displayNSFW).to.be.false |
236 | 278 | ||
237 | userId = user.id | 279 | userId = user.id |
@@ -244,13 +286,23 @@ describe('Test users', function () { | |||
244 | const total = result.total | 286 | const total = result.total |
245 | const users = result.data | 287 | const users = result.data |
246 | 288 | ||
247 | expect(total).to.equal(2) | 289 | expect(total) |
248 | expect(users.length).to.equal(1) | 290 | .to |
249 | 291 | .equal(2) | |
250 | const user = users[0] | 292 | expect(users.length) |
251 | expect(user.username).to.equal('root') | 293 | .to |
252 | expect(user.email).to.equal('admin1@example.com') | 294 | .equal(1) |
253 | expect(user.roleLabel).to.equal('Administrator') | 295 | |
296 | const user = users[ 0 ] | ||
297 | expect(user.username) | ||
298 | .to | ||
299 | .equal('root') | ||
300 | expect(user.email) | ||
301 | .to | ||
302 | .equal('admin1@example.com') | ||
303 | expect(user.roleLabel) | ||
304 | .to | ||
305 | .equal('Administrator') | ||
254 | expect(user.displayNSFW).to.be.false | 306 | expect(user.displayNSFW).to.be.false |
255 | }) | 307 | }) |
256 | 308 | ||
@@ -260,12 +312,20 @@ describe('Test users', function () { | |||
260 | const total = result.total | 312 | const total = result.total |
261 | const users = result.data | 313 | const users = result.data |
262 | 314 | ||
263 | expect(total).to.equal(2) | 315 | expect(total) |
264 | expect(users.length).to.equal(1) | 316 | .to |
265 | 317 | .equal(2) | |
266 | const user = users[0] | 318 | expect(users.length) |
267 | expect(user.username).to.equal('user_1') | 319 | .to |
268 | expect(user.email).to.equal('user_1@example.com') | 320 | .equal(1) |
321 | |||
322 | const user = users[ 0 ] | ||
323 | expect(user.username) | ||
324 | .to | ||
325 | .equal('user_1') | ||
326 | expect(user.email) | ||
327 | .to | ||
328 | .equal('user_1@example.com') | ||
269 | expect(user.displayNSFW).to.be.false | 329 | expect(user.displayNSFW).to.be.false |
270 | }) | 330 | }) |
271 | 331 | ||
@@ -275,12 +335,20 @@ describe('Test users', function () { | |||
275 | const total = result.total | 335 | const total = result.total |
276 | const users = result.data | 336 | const users = result.data |
277 | 337 | ||
278 | expect(total).to.equal(2) | 338 | expect(total) |
279 | expect(users.length).to.equal(1) | 339 | .to |
280 | 340 | .equal(2) | |
281 | const user = users[0] | 341 | expect(users.length) |
282 | expect(user.username).to.equal('user_1') | 342 | .to |
283 | expect(user.email).to.equal('user_1@example.com') | 343 | .equal(1) |
344 | |||
345 | const user = users[ 0 ] | ||
346 | expect(user.username) | ||
347 | .to | ||
348 | .equal('user_1') | ||
349 | expect(user.email) | ||
350 | .to | ||
351 | .equal('user_1@example.com') | ||
284 | expect(user.displayNSFW).to.be.false | 352 | expect(user.displayNSFW).to.be.false |
285 | }) | 353 | }) |
286 | 354 | ||
@@ -290,16 +358,28 @@ describe('Test users', function () { | |||
290 | const total = result.total | 358 | const total = result.total |
291 | const users = result.data | 359 | const users = result.data |
292 | 360 | ||
293 | expect(total).to.equal(2) | 361 | expect(total) |
294 | expect(users.length).to.equal(2) | 362 | .to |
295 | 363 | .equal(2) | |
296 | expect(users[0].username).to.equal('root') | 364 | expect(users.length) |
297 | expect(users[0].email).to.equal('admin1@example.com') | 365 | .to |
298 | expect(users[0].displayNSFW).to.be.false | 366 | .equal(2) |
299 | 367 | ||
300 | expect(users[1].username).to.equal('user_1') | 368 | expect(users[ 0 ].username) |
301 | expect(users[1].email).to.equal('user_1@example.com') | 369 | .to |
302 | expect(users[1].displayNSFW).to.be.false | 370 | .equal('root') |
371 | expect(users[ 0 ].email) | ||
372 | .to | ||
373 | .equal('admin1@example.com') | ||
374 | expect(users[ 0 ].displayNSFW).to.be.false | ||
375 | |||
376 | expect(users[ 1 ].username) | ||
377 | .to | ||
378 | .equal('user_1') | ||
379 | expect(users[ 1 ].email) | ||
380 | .to | ||
381 | .equal('user_1@example.com') | ||
382 | expect(users[ 1 ].displayNSFW).to.be.false | ||
303 | }) | 383 | }) |
304 | 384 | ||
305 | it('Should update my password', async function () { | 385 | it('Should update my password', async function () { |
@@ -315,11 +395,20 @@ describe('Test users', function () { | |||
315 | const res = await getMyUserInformation(server.url, accessTokenUser) | 395 | const res = await getMyUserInformation(server.url, accessTokenUser) |
316 | const user = res.body | 396 | const user = res.body |
317 | 397 | ||
318 | expect(user.username).to.equal('user_1') | 398 | expect(user.username) |
319 | expect(user.email).to.equal('user_1@example.com') | 399 | .to |
400 | .equal('user_1') | ||
401 | expect(user.email) | ||
402 | .to | ||
403 | .equal('user_1@example.com') | ||
320 | expect(user.displayNSFW).to.be.ok | 404 | expect(user.displayNSFW).to.be.ok |
321 | expect(user.videoQuota).to.equal(2 * 1024 * 1024) | 405 | expect(user.videoQuota) |
322 | expect(user.id).to.be.a('number') | 406 | .to |
407 | .equal(2 * 1024 * 1024) | ||
408 | expect(user.id) | ||
409 | .to | ||
410 | .be | ||
411 | .a('number') | ||
323 | }) | 412 | }) |
324 | 413 | ||
325 | it('Should be able to change the email display attribute', async function () { | 414 | it('Should be able to change the email display attribute', async function () { |
@@ -328,11 +417,20 @@ describe('Test users', function () { | |||
328 | const res = await getMyUserInformation(server.url, accessTokenUser) | 417 | const res = await getMyUserInformation(server.url, accessTokenUser) |
329 | const user = res.body | 418 | const user = res.body |
330 | 419 | ||
331 | expect(user.username).to.equal('user_1') | 420 | expect(user.username) |
332 | expect(user.email).to.equal('updated@example.com') | 421 | .to |
422 | .equal('user_1') | ||
423 | expect(user.email) | ||
424 | .to | ||
425 | .equal('updated@example.com') | ||
333 | expect(user.displayNSFW).to.be.ok | 426 | expect(user.displayNSFW).to.be.ok |
334 | expect(user.videoQuota).to.equal(2 * 1024 * 1024) | 427 | expect(user.videoQuota) |
335 | expect(user.id).to.be.a('number') | 428 | .to |
429 | .equal(2 * 1024 * 1024) | ||
430 | expect(user.id) | ||
431 | .to | ||
432 | .be | ||
433 | .a('number') | ||
336 | }) | 434 | }) |
337 | 435 | ||
338 | it('Should be able to update another user', async function () { | 436 | it('Should be able to update another user', async function () { |
@@ -341,12 +439,23 @@ describe('Test users', function () { | |||
341 | const res = await getUserInformation(server.url, accessToken, userId) | 439 | const res = await getUserInformation(server.url, accessToken, userId) |
342 | const user = res.body | 440 | const user = res.body |
343 | 441 | ||
344 | expect(user.username).to.equal('user_1') | 442 | expect(user.username) |
345 | expect(user.email).to.equal('updated2@example.com') | 443 | .to |
444 | .equal('user_1') | ||
445 | expect(user.email) | ||
446 | .to | ||
447 | .equal('updated2@example.com') | ||
346 | expect(user.displayNSFW).to.be.ok | 448 | expect(user.displayNSFW).to.be.ok |
347 | expect(user.videoQuota).to.equal(42) | 449 | expect(user.videoQuota) |
348 | expect(user.roleLabel).to.equal('Moderator') | 450 | .to |
349 | expect(user.id).to.be.a('number') | 451 | .equal(42) |
452 | expect(user.roleLabel) | ||
453 | .to | ||
454 | .equal('Moderator') | ||
455 | expect(user.id) | ||
456 | .to | ||
457 | .be | ||
458 | .a('number') | ||
350 | }) | 459 | }) |
351 | 460 | ||
352 | it('Should not be able to delete a user by a moderator', async function () { | 461 | it('Should not be able to delete a user by a moderator', async function () { |
@@ -369,10 +478,14 @@ describe('Test users', function () { | |||
369 | it('Should not have videos of this user', async function () { | 478 | it('Should not have videos of this user', async function () { |
370 | const res = await getVideosList(server.url) | 479 | const res = await getVideosList(server.url) |
371 | 480 | ||
372 | expect(res.body.total).to.equal(1) | 481 | expect(res.body.total) |
482 | .to | ||
483 | .equal(1) | ||
373 | 484 | ||
374 | const video = res.body.data[0] | 485 | const video = res.body.data[ 0 ] |
375 | expect(video.author).to.equal('root') | 486 | expect(video.account) |
487 | .to | ||
488 | .equal('root') | ||
376 | }) | 489 | }) |
377 | 490 | ||
378 | it('Should register a new user', async function () { | 491 | it('Should register a new user', async function () { |
@@ -392,14 +505,16 @@ describe('Test users', function () { | |||
392 | const res = await getMyUserInformation(server.url, accessToken) | 505 | const res = await getMyUserInformation(server.url, accessToken) |
393 | const user = res.body | 506 | const user = res.body |
394 | 507 | ||
395 | expect(user.videoQuota).to.equal(5 * 1024 * 1024) | 508 | expect(user.videoQuota) |
509 | .to | ||
510 | .equal(5 * 1024 * 1024) | ||
396 | }) | 511 | }) |
397 | 512 | ||
398 | after(async function () { | 513 | after(async function () { |
399 | killallServers([ server ]) | 514 | killallServers([ server ]) |
400 | 515 | ||
401 | // Keep the logs if the test failed | 516 | // Keep the logs if the test failed |
402 | if (this['ok']) { | 517 | if (this[ 'ok' ]) { |
403 | await flushTests() | 518 | await flushTests() |
404 | } | 519 | } |
405 | }) | 520 | }) |
diff --git a/server/tests/api/video-abuse.ts b/server/tests/api/video-abuse.ts index f2a2c322a..bc21ee59b 100644 --- a/server/tests/api/video-abuse.ts +++ b/server/tests/api/video-abuse.ts | |||
@@ -1,22 +1,22 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | 1 | /* tslint:disable:no-unused-expression */ |
2 | 2 | ||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
5 | const expect = chai.expect | 4 | import 'mocha' |
6 | |||
7 | import { | 5 | import { |
8 | ServerInfo, | ||
9 | flushAndRunMultipleServers, | 6 | flushAndRunMultipleServers, |
10 | uploadVideo, | 7 | flushTests, |
11 | makeFriends, | ||
12 | getVideosList, | ||
13 | wait, | ||
14 | setAccessTokensToServers, | ||
15 | getVideoAbusesList, | 8 | getVideoAbusesList, |
16 | reportVideoAbuse, | 9 | getVideosList, |
17 | killallServers, | 10 | killallServers, |
18 | flushTests | 11 | reportVideoAbuse, |
12 | ServerInfo, | ||
13 | setAccessTokensToServers, | ||
14 | uploadVideo, | ||
15 | wait | ||
19 | } from '../utils' | 16 | } from '../utils' |
17 | import { doubleFollow } from '../utils/follows' | ||
18 | |||
19 | const expect = chai.expect | ||
20 | 20 | ||
21 | describe('Test video abuses', function () { | 21 | describe('Test video abuses', function () { |
22 | let servers: ServerInfo[] = [] | 22 | let servers: ServerInfo[] = [] |
@@ -30,32 +30,32 @@ describe('Test video abuses', function () { | |||
30 | // Get the access tokens | 30 | // Get the access tokens |
31 | await setAccessTokensToServers(servers) | 31 | await setAccessTokensToServers(servers) |
32 | 32 | ||
33 | // Pod 1 makes friend with pod 2 | 33 | // Server 1 and server 2 follow each other |
34 | await makeFriends(servers[0].url, servers[0].accessToken) | 34 | await doubleFollow(servers[0], servers[1]) |
35 | 35 | ||
36 | // Upload some videos on each pods | 36 | // Upload some videos on each servers |
37 | const video1Attributes = { | 37 | const video1Attributes = { |
38 | name: 'my super name for pod 1', | 38 | name: 'my super name for server 1', |
39 | description: 'my super description for pod 1' | 39 | description: 'my super description for server 1' |
40 | } | 40 | } |
41 | await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes) | 41 | await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes) |
42 | 42 | ||
43 | const video2Attributes = { | 43 | const video2Attributes = { |
44 | name: 'my super name for pod 2', | 44 | name: 'my super name for server 2', |
45 | description: 'my super description for pod 2' | 45 | description: 'my super description for server 2' |
46 | } | 46 | } |
47 | await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes) | 47 | await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes) |
48 | 48 | ||
49 | // Wait videos propagation | 49 | // Wait videos propagation |
50 | await wait(22000) | 50 | await wait(25000) |
51 | 51 | ||
52 | const res = await getVideosList(servers[0].url) | 52 | const res = await getVideosList(servers[0].url) |
53 | const videos = res.body.data | 53 | const videos = res.body.data |
54 | 54 | ||
55 | expect(videos.length).to.equal(2) | 55 | expect(videos.length).to.equal(2) |
56 | 56 | ||
57 | servers[0].video = videos.find(video => video.name === 'my super name for pod 1') | 57 | servers[0].video = videos.find(video => video.name === 'my super name for server 1') |
58 | servers[1].video = videos.find(video => video.name === 'my super name for pod 2') | 58 | servers[1].video = videos.find(video => video.name === 'my super name for server 2') |
59 | }) | 59 | }) |
60 | 60 | ||
61 | it('Should not have video abuses', async function () { | 61 | it('Should not have video abuses', async function () { |
@@ -72,11 +72,11 @@ describe('Test video abuses', function () { | |||
72 | const reason = 'my super bad reason' | 72 | const reason = 'my super bad reason' |
73 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason) | 73 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason) |
74 | 74 | ||
75 | // We wait requests propagation, even if the pod 1 is not supposed to make a request to pod 2 | 75 | // We wait requests propagation, even if the server 1 is not supposed to make a request to server 2 |
76 | await wait(11000) | 76 | await wait(11000) |
77 | }) | 77 | }) |
78 | 78 | ||
79 | it('Should have 1 video abuses on pod 1 and 0 on pod 2', async function () { | 79 | it('Should have 1 video abuses on server 1 and 0 on server 2', async function () { |
80 | const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) | 80 | const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) |
81 | 81 | ||
82 | expect(res1.body.total).to.equal(1) | 82 | expect(res1.body.total).to.equal(1) |
@@ -86,7 +86,7 @@ describe('Test video abuses', function () { | |||
86 | const abuse = res1.body.data[0] | 86 | const abuse = res1.body.data[0] |
87 | expect(abuse.reason).to.equal('my super bad reason') | 87 | expect(abuse.reason).to.equal('my super bad reason') |
88 | expect(abuse.reporterUsername).to.equal('root') | 88 | expect(abuse.reporterUsername).to.equal('root') |
89 | expect(abuse.reporterPodHost).to.equal('localhost:9001') | 89 | expect(abuse.reporterServerHost).to.equal('localhost:9001') |
90 | expect(abuse.videoId).to.equal(servers[0].video.id) | 90 | expect(abuse.videoId).to.equal(servers[0].video.id) |
91 | 91 | ||
92 | const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) | 92 | const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) |
@@ -96,16 +96,16 @@ describe('Test video abuses', function () { | |||
96 | }) | 96 | }) |
97 | 97 | ||
98 | it('Should report abuse on a remote video', async function () { | 98 | it('Should report abuse on a remote video', async function () { |
99 | this.timeout(15000) | 99 | this.timeout(25000) |
100 | 100 | ||
101 | const reason = 'my super bad reason 2' | 101 | const reason = 'my super bad reason 2' |
102 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason) | 102 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason) |
103 | 103 | ||
104 | // We wait requests propagation | 104 | // We wait requests propagation |
105 | await wait(11000) | 105 | await wait(15000) |
106 | }) | 106 | }) |
107 | 107 | ||
108 | it('Should have 2 video abuse on pod 1 and 1 on pod 2', async function () { | 108 | it('Should have 2 video abuse on server 1 and 1 on server 2', async function () { |
109 | const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) | 109 | const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) |
110 | expect(res1.body.total).to.equal(2) | 110 | expect(res1.body.total).to.equal(2) |
111 | expect(res1.body.data).to.be.an('array') | 111 | expect(res1.body.data).to.be.an('array') |
@@ -114,13 +114,13 @@ describe('Test video abuses', function () { | |||
114 | const abuse1 = res1.body.data[0] | 114 | const abuse1 = res1.body.data[0] |
115 | expect(abuse1.reason).to.equal('my super bad reason') | 115 | expect(abuse1.reason).to.equal('my super bad reason') |
116 | expect(abuse1.reporterUsername).to.equal('root') | 116 | expect(abuse1.reporterUsername).to.equal('root') |
117 | expect(abuse1.reporterPodHost).to.equal('localhost:9001') | 117 | expect(abuse1.reporterServerHost).to.equal('localhost:9001') |
118 | expect(abuse1.videoId).to.equal(servers[0].video.id) | 118 | expect(abuse1.videoId).to.equal(servers[0].video.id) |
119 | 119 | ||
120 | const abuse2 = res1.body.data[1] | 120 | const abuse2 = res1.body.data[1] |
121 | expect(abuse2.reason).to.equal('my super bad reason 2') | 121 | expect(abuse2.reason).to.equal('my super bad reason 2') |
122 | expect(abuse2.reporterUsername).to.equal('root') | 122 | expect(abuse2.reporterUsername).to.equal('root') |
123 | expect(abuse2.reporterPodHost).to.equal('localhost:9001') | 123 | expect(abuse2.reporterServerHost).to.equal('localhost:9001') |
124 | expect(abuse2.videoId).to.equal(servers[1].video.id) | 124 | expect(abuse2.videoId).to.equal(servers[1].video.id) |
125 | 125 | ||
126 | const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) | 126 | const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) |
@@ -131,7 +131,7 @@ describe('Test video abuses', function () { | |||
131 | const abuse3 = res2.body.data[0] | 131 | const abuse3 = res2.body.data[0] |
132 | expect(abuse3.reason).to.equal('my super bad reason 2') | 132 | expect(abuse3.reason).to.equal('my super bad reason 2') |
133 | expect(abuse3.reporterUsername).to.equal('root') | 133 | expect(abuse3.reporterUsername).to.equal('root') |
134 | expect(abuse3.reporterPodHost).to.equal('localhost:9001') | 134 | expect(abuse3.reporterServerHost).to.equal('localhost:9001') |
135 | }) | 135 | }) |
136 | 136 | ||
137 | after(async function () { | 137 | after(async function () { |
diff --git a/server/tests/utils/follows.ts b/server/tests/utils/follows.ts index 9ad1ca7f4..b454fe2f8 100644 --- a/server/tests/utils/follows.ts +++ b/server/tests/utils/follows.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | |||
3 | import { wait } from './miscs' | 2 | import { wait } from './miscs' |
3 | import { ServerInfo } from './servers' | ||
4 | 4 | ||
5 | function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) { | 5 | function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) { |
6 | const path = '/api/v1/servers/followers' | 6 | const path = '/api/v1/server/followers' |
7 | 7 | ||
8 | return request(url) | 8 | return request(url) |
9 | .get(path) | 9 | .get(path) |
@@ -16,7 +16,7 @@ function getFollowersListPaginationAndSort (url: string, start: number, count: n | |||
16 | } | 16 | } |
17 | 17 | ||
18 | function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) { | 18 | function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) { |
19 | const path = '/api/v1/servers/following' | 19 | const path = '/api/v1/server/following' |
20 | 20 | ||
21 | return request(url) | 21 | return request(url) |
22 | .get(path) | 22 | .get(path) |
@@ -29,25 +29,36 @@ function getFollowingListPaginationAndSort (url: string, start: number, count: n | |||
29 | } | 29 | } |
30 | 30 | ||
31 | async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) { | 31 | async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) { |
32 | const path = '/api/v1/servers/follow' | 32 | const path = '/api/v1/server/follow' |
33 | 33 | ||
34 | const followingHosts = following.map(f => f.replace(/^http:\/\//, '')) | ||
34 | const res = await request(follower) | 35 | const res = await request(follower) |
35 | .post(path) | 36 | .post(path) |
36 | .set('Accept', 'application/json') | 37 | .set('Accept', 'application/json') |
37 | .set('Authorization', 'Bearer ' + accessToken) | 38 | .set('Authorization', 'Bearer ' + accessToken) |
38 | .send({ 'hosts': following }) | 39 | .send({ 'hosts': followingHosts }) |
39 | .expect(expectedStatus) | 40 | .expect(expectedStatus) |
40 | 41 | ||
41 | // Wait request propagation | 42 | // Wait request propagation |
42 | await wait(1000) | 43 | await wait(20000) |
43 | 44 | ||
44 | return res | 45 | return res |
45 | } | 46 | } |
46 | 47 | ||
48 | async function doubleFollow (server1: ServerInfo, server2: ServerInfo) { | ||
49 | await Promise.all([ | ||
50 | follow(server1.url, [ server2.url ], server1.accessToken), | ||
51 | follow(server2.url, [ server1.url ], server2.accessToken) | ||
52 | ]) | ||
53 | |||
54 | return true | ||
55 | } | ||
56 | |||
47 | // --------------------------------------------------------------------------- | 57 | // --------------------------------------------------------------------------- |
48 | 58 | ||
49 | export { | 59 | export { |
50 | getFollowersListPaginationAndSort, | 60 | getFollowersListPaginationAndSort, |
51 | getFollowingListPaginationAndSort, | 61 | getFollowingListPaginationAndSort, |
52 | follow | 62 | follow, |
63 | doubleFollow | ||
53 | } | 64 | } |
diff --git a/server/tests/utils/servers.ts b/server/tests/utils/servers.ts index f042a9e53..faa2f19ff 100644 --- a/server/tests/utils/servers.ts +++ b/server/tests/utils/servers.ts | |||
@@ -24,7 +24,7 @@ interface ServerInfo { | |||
24 | id: number | 24 | id: number |
25 | uuid: string | 25 | uuid: string |
26 | name: string | 26 | name: string |
27 | author: string | 27 | account: string |
28 | } | 28 | } |
29 | 29 | ||
30 | remoteVideo?: { | 30 | remoteVideo?: { |