diff options
-rw-r--r-- | client/src/app/+about/about-follows/about-follows.component.html | 8 | ||||
-rw-r--r-- | client/src/app/shared/instance/follow.service.ts | 10 | ||||
-rw-r--r-- | server/controllers/api/server/follows.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/follows.ts | 5 | ||||
-rw-r--r-- | server/models/activitypub/actor-follow.ts | 51 | ||||
-rw-r--r-- | server/tests/api/check-params/follows.ts | 26 | ||||
-rw-r--r-- | server/tests/api/redundancy/redundancy.ts | 4 | ||||
-rw-r--r-- | server/tests/api/server/auto-follows.ts | 4 | ||||
-rw-r--r-- | server/tests/api/server/follows-moderation.ts | 16 | ||||
-rw-r--r-- | server/tests/api/server/follows.ts | 130 | ||||
-rw-r--r-- | server/tests/api/server/handle-down.ts | 4 | ||||
-rw-r--r-- | shared/extra-utils/server/follows.ts | 32 |
12 files changed, 216 insertions, 76 deletions
diff --git a/client/src/app/+about/about-follows/about-follows.component.html b/client/src/app/+about/about-follows/about-follows.component.html index 5d7a50c74..ebe03bd94 100644 --- a/client/src/app/+about/about-follows/about-follows.component.html +++ b/client/src/app/+about/about-follows/about-follows.component.html | |||
@@ -1,8 +1,8 @@ | |||
1 | <div class="row" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()"> | 1 | <div class="row" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()"> |
2 | <div class="col-xl-6 col-md-12"> | 2 | <div class="col-xl-6 col-md-12"> |
3 | <div i18n class="subtitle">Followers</div> | 3 | <div i18n class="subtitle">Followers instances</div> |
4 | 4 | ||
5 | <div i18n class="no-results" *ngIf="followersPagination.totalItems === 0">This instance does not have followers.</div> | 5 | <div i18n class="no-results" *ngIf="followersPagination.totalItems === 0">This instance does not have instances followers.</div> |
6 | 6 | ||
7 | <a *ngFor="let follower of followers" [href]="buildLink(follower)" target="_blank" rel="noopener noreferrer"> | 7 | <a *ngFor="let follower of followers" [href]="buildLink(follower)" target="_blank" rel="noopener noreferrer"> |
8 | {{ follower }} | 8 | {{ follower }} |
@@ -10,9 +10,9 @@ | |||
10 | </div> | 10 | </div> |
11 | 11 | ||
12 | <div class="col-xl-6 col-md-12"> | 12 | <div class="col-xl-6 col-md-12"> |
13 | <div i18n class="subtitle">Followings</div> | 13 | <div i18n class="subtitle">Followings instances</div> |
14 | 14 | ||
15 | <div i18n class="no-results" *ngIf="followingsPagination.totalItems === 0">This instance does not have followings.</div> | 15 | <div i18n class="no-results" *ngIf="followingsPagination.totalItems === 0">This instance does not have instances followings.</div> |
16 | 16 | ||
17 | <a *ngFor="let following of followings" [href]="buildLink(following)" target="_blank" rel="noopener noreferrer"> | 17 | <a *ngFor="let following of followings" [href]="buildLink(following)" target="_blank" rel="noopener noreferrer"> |
18 | {{ following }} | 18 | {{ following }} |
diff --git a/client/src/app/shared/instance/follow.service.ts b/client/src/app/shared/instance/follow.service.ts index 1477a26ae..ef4c09583 100644 --- a/client/src/app/shared/instance/follow.service.ts +++ b/client/src/app/shared/instance/follow.service.ts | |||
@@ -2,7 +2,7 @@ import { catchError, map } from 'rxjs/operators' | |||
2 | import { HttpClient, HttpParams } from '@angular/common/http' | 2 | import { HttpClient, HttpParams } from '@angular/common/http' |
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { Observable } from 'rxjs' | 4 | import { Observable } from 'rxjs' |
5 | import { ActorFollow, FollowState, ResultList } from '@shared/index' | 5 | import { ActivityPubActorType, ActorFollow, FollowState, ResultList } from '@shared/index' |
6 | import { environment } from '../../../environments/environment' | 6 | import { environment } from '../../../environments/environment' |
7 | import { RestExtractor, RestPagination, RestService } from '../rest' | 7 | import { RestExtractor, RestPagination, RestService } from '../rest' |
8 | import { SortMeta } from 'primeng/api' | 8 | import { SortMeta } from 'primeng/api' |
@@ -22,15 +22,17 @@ export class FollowService { | |||
22 | pagination: RestPagination, | 22 | pagination: RestPagination, |
23 | sort: SortMeta, | 23 | sort: SortMeta, |
24 | search?: string, | 24 | search?: string, |
25 | actorType?: ActivityPubActorType, | ||
25 | state?: FollowState | 26 | state?: FollowState |
26 | }): Observable<ResultList<ActorFollow>> { | 27 | }): Observable<ResultList<ActorFollow>> { |
27 | const { pagination, sort, search, state } = options | 28 | const { pagination, sort, search, state, actorType } = options |
28 | 29 | ||
29 | let params = new HttpParams() | 30 | let params = new HttpParams() |
30 | params = this.restService.addRestGetParams(params, pagination, sort) | 31 | params = this.restService.addRestGetParams(params, pagination, sort) |
31 | 32 | ||
32 | if (search) params = params.append('search', search) | 33 | if (search) params = params.append('search', search) |
33 | if (state) params = params.append('state', state) | 34 | if (state) params = params.append('state', state) |
35 | if (actorType) params = params.append('actorType', actorType) | ||
34 | 36 | ||
35 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params }) | 37 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params }) |
36 | .pipe( | 38 | .pipe( |
@@ -43,15 +45,17 @@ export class FollowService { | |||
43 | pagination: RestPagination, | 45 | pagination: RestPagination, |
44 | sort: SortMeta, | 46 | sort: SortMeta, |
45 | search?: string, | 47 | search?: string, |
48 | actorType?: ActivityPubActorType, | ||
46 | state?: FollowState | 49 | state?: FollowState |
47 | }): Observable<ResultList<ActorFollow>> { | 50 | }): Observable<ResultList<ActorFollow>> { |
48 | const { pagination, sort, search, state } = options | 51 | const { pagination, sort, search, state, actorType } = options |
49 | 52 | ||
50 | let params = new HttpParams() | 53 | let params = new HttpParams() |
51 | params = this.restService.addRestGetParams(params, pagination, sort) | 54 | params = this.restService.addRestGetParams(params, pagination, sort) |
52 | 55 | ||
53 | if (search) params = params.append('search', search) | 56 | if (search) params = params.append('search', search) |
54 | if (state) params = params.append('state', state) | 57 | if (state) params = params.append('state', state) |
58 | if (actorType) params = params.append('actorType', actorType) | ||
55 | 59 | ||
56 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) | 60 | return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params }) |
57 | .pipe( | 61 | .pipe( |
diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index e7fd3aabd..29a403a43 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts | |||
@@ -101,6 +101,7 @@ async function listFollowing (req: express.Request, res: express.Response) { | |||
101 | count: req.query.count, | 101 | count: req.query.count, |
102 | sort: req.query.sort, | 102 | sort: req.query.sort, |
103 | search: req.query.search, | 103 | search: req.query.search, |
104 | actorType: req.query.actorType, | ||
104 | state: req.query.state | 105 | state: req.query.state |
105 | }) | 106 | }) |
106 | 107 | ||
@@ -115,6 +116,7 @@ async function listFollowers (req: express.Request, res: express.Response) { | |||
115 | count: req.query.count, | 116 | count: req.query.count, |
116 | sort: req.query.sort, | 117 | sort: req.query.sort, |
117 | search: req.query.search, | 118 | search: req.query.search, |
119 | actorType: req.query.actorType, | ||
118 | state: req.query.state | 120 | state: req.query.state |
119 | }) | 121 | }) |
120 | 122 | ||
diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts index 454f9f2b8..a98d32d86 100644 --- a/server/middlewares/validators/follows.ts +++ b/server/middlewares/validators/follows.ts | |||
@@ -9,7 +9,7 @@ import { ActorFollowModel } from '../../models/activitypub/actor-follow' | |||
9 | import { areValidationErrors } from './utils' | 9 | import { areValidationErrors } from './utils' |
10 | import { ActorModel } from '../../models/activitypub/actor' | 10 | import { ActorModel } from '../../models/activitypub/actor' |
11 | import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' | 11 | import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' |
12 | import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' | 12 | import { isActorTypeValid, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' |
13 | import { MActorFollowActorsDefault } from '@server/typings/models' | 13 | import { MActorFollowActorsDefault } from '@server/typings/models' |
14 | import { isFollowStateValid } from '@server/helpers/custom-validators/follows' | 14 | import { isFollowStateValid } from '@server/helpers/custom-validators/follows' |
15 | 15 | ||
@@ -17,6 +17,9 @@ const listFollowsValidator = [ | |||
17 | query('state') | 17 | query('state') |
18 | .optional() | 18 | .optional() |
19 | .custom(isFollowStateValid).withMessage('Should have a valid follow state'), | 19 | .custom(isFollowStateValid).withMessage('Should have a valid follow state'), |
20 | query('actorType') | ||
21 | .optional() | ||
22 | .custom(isActorTypeValid).withMessage('Should have a valid actor type'), | ||
20 | 23 | ||
21 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 24 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
22 | if (areValidationErrors(req, res)) return | 25 | if (areValidationErrors(req, res)) return |
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 09bc6853d..c3c4d61ab 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts | |||
@@ -27,7 +27,7 @@ import { createSafeIn, getSort } from '../utils' | |||
27 | import { ActorModel, unusedActorAttributesForAPI } from './actor' | 27 | import { ActorModel, unusedActorAttributesForAPI } from './actor' |
28 | import { VideoChannelModel } from '../video/video-channel' | 28 | import { VideoChannelModel } from '../video/video-channel' |
29 | import { AccountModel } from '../account/account' | 29 | import { AccountModel } from '../account/account' |
30 | import { IncludeOptions, Op, QueryTypes, Transaction } from 'sequelize' | 30 | import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize' |
31 | import { | 31 | import { |
32 | MActorFollowActorsDefault, | 32 | MActorFollowActorsDefault, |
33 | MActorFollowActorsDefaultSubscription, | 33 | MActorFollowActorsDefaultSubscription, |
@@ -35,6 +35,7 @@ import { | |||
35 | MActorFollowFormattable, | 35 | MActorFollowFormattable, |
36 | MActorFollowSubscriptions | 36 | MActorFollowSubscriptions |
37 | } from '@server/typings/models' | 37 | } from '@server/typings/models' |
38 | import { ActivityPubActorType } from '@shared/models' | ||
38 | 39 | ||
39 | @Table({ | 40 | @Table({ |
40 | tableName: 'actorFollow', | 41 | tableName: 'actorFollow', |
@@ -298,11 +299,26 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
298 | count: number, | 299 | count: number, |
299 | sort: string, | 300 | sort: string, |
300 | state?: FollowState, | 301 | state?: FollowState, |
302 | actorType?: ActivityPubActorType, | ||
301 | search?: string | 303 | search?: string |
302 | }) { | 304 | }) { |
303 | const { id, start, count, sort, search, state } = options | 305 | const { id, start, count, sort, search, state, actorType } = options |
304 | 306 | ||
305 | const followWhere = state ? { state } : {} | 307 | const followWhere = state ? { state } : {} |
308 | const followingWhere: WhereOptions = {} | ||
309 | const followingServerWhere: WhereOptions = {} | ||
310 | |||
311 | if (search) { | ||
312 | Object.assign(followingServerWhere, { | ||
313 | host: { | ||
314 | [ Op.iLike ]: '%' + search + '%' | ||
315 | } | ||
316 | }) | ||
317 | } | ||
318 | |||
319 | if (actorType) { | ||
320 | Object.assign(followingWhere, { type: actorType }) | ||
321 | } | ||
306 | 322 | ||
307 | const query = { | 323 | const query = { |
308 | distinct: true, | 324 | distinct: true, |
@@ -323,15 +339,12 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
323 | model: ActorModel, | 339 | model: ActorModel, |
324 | as: 'ActorFollowing', | 340 | as: 'ActorFollowing', |
325 | required: true, | 341 | required: true, |
342 | where: followingWhere, | ||
326 | include: [ | 343 | include: [ |
327 | { | 344 | { |
328 | model: ServerModel, | 345 | model: ServerModel, |
329 | required: true, | 346 | required: true, |
330 | where: search ? { | 347 | where: followingServerWhere |
331 | host: { | ||
332 | [Op.iLike]: '%' + search + '%' | ||
333 | } | ||
334 | } : undefined | ||
335 | } | 348 | } |
336 | ] | 349 | ] |
337 | } | 350 | } |
@@ -353,11 +366,26 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
353 | count: number, | 366 | count: number, |
354 | sort: string, | 367 | sort: string, |
355 | state?: FollowState, | 368 | state?: FollowState, |
369 | actorType?: ActivityPubActorType, | ||
356 | search?: string | 370 | search?: string |
357 | }) { | 371 | }) { |
358 | const { actorId, start, count, sort, search, state } = options | 372 | const { actorId, start, count, sort, search, state, actorType } = options |
359 | 373 | ||
360 | const followWhere = state ? { state } : {} | 374 | const followWhere = state ? { state } : {} |
375 | const followerWhere: WhereOptions = {} | ||
376 | const followerServerWhere: WhereOptions = {} | ||
377 | |||
378 | if (search) { | ||
379 | Object.assign(followerServerWhere, { | ||
380 | host: { | ||
381 | [ Op.iLike ]: '%' + search + '%' | ||
382 | } | ||
383 | }) | ||
384 | } | ||
385 | |||
386 | if (actorType) { | ||
387 | Object.assign(followerWhere, { type: actorType }) | ||
388 | } | ||
361 | 389 | ||
362 | const query = { | 390 | const query = { |
363 | distinct: true, | 391 | distinct: true, |
@@ -370,15 +398,12 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
370 | model: ActorModel, | 398 | model: ActorModel, |
371 | required: true, | 399 | required: true, |
372 | as: 'ActorFollower', | 400 | as: 'ActorFollower', |
401 | where: followerWhere, | ||
373 | include: [ | 402 | include: [ |
374 | { | 403 | { |
375 | model: ServerModel, | 404 | model: ServerModel, |
376 | required: true, | 405 | required: true, |
377 | where: search ? { | 406 | where: followerServerWhere |
378 | host: { | ||
379 | [ Op.iLike ]: '%' + search + '%' | ||
380 | } | ||
381 | } : undefined | ||
382 | } | 407 | } |
383 | ] | 408 | ] |
384 | }, | 409 | }, |
diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts index 488666a75..be2a603a3 100644 --- a/server/tests/api/check-params/follows.ts +++ b/server/tests/api/check-params/follows.ts | |||
@@ -142,13 +142,24 @@ describe('Test server follows API validators', function () { | |||
142 | }) | 142 | }) |
143 | }) | 143 | }) |
144 | 144 | ||
145 | it('Should fail with an incorrect actor type', async function () { | ||
146 | await makeGetRequest({ | ||
147 | url: server.url, | ||
148 | path, | ||
149 | query: { | ||
150 | actorType: 'blabla' | ||
151 | } | ||
152 | }) | ||
153 | }) | ||
154 | |||
145 | it('Should fail succeed with the correct params', async function () { | 155 | it('Should fail succeed with the correct params', async function () { |
146 | await makeGetRequest({ | 156 | await makeGetRequest({ |
147 | url: server.url, | 157 | url: server.url, |
148 | path, | 158 | path, |
149 | statusCodeExpected: 200, | 159 | statusCodeExpected: 200, |
150 | query: { | 160 | query: { |
151 | state: 'accepted' | 161 | state: 'accepted', |
162 | actorType: 'Application' | ||
152 | } | 163 | } |
153 | }) | 164 | }) |
154 | }) | 165 | }) |
@@ -169,12 +180,23 @@ describe('Test server follows API validators', function () { | |||
169 | await checkBadSortPagination(server.url, path) | 180 | await checkBadSortPagination(server.url, path) |
170 | }) | 181 | }) |
171 | 182 | ||
183 | it('Should fail with an incorrect actor type', async function () { | ||
184 | await makeGetRequest({ | ||
185 | url: server.url, | ||
186 | path, | ||
187 | query: { | ||
188 | actorType: 'blabla' | ||
189 | } | ||
190 | }) | ||
191 | }) | ||
192 | |||
172 | it('Should fail with an incorrect state', async function () { | 193 | it('Should fail with an incorrect state', async function () { |
173 | await makeGetRequest({ | 194 | await makeGetRequest({ |
174 | url: server.url, | 195 | url: server.url, |
175 | path, | 196 | path, |
176 | query: { | 197 | query: { |
177 | state: 'blabla' | 198 | state: 'blabla', |
199 | actorType: 'Application' | ||
178 | } | 200 | } |
179 | }) | 201 | }) |
180 | }) | 202 | }) |
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts index 9e8733774..be24eb32f 100644 --- a/server/tests/api/redundancy/redundancy.ts +++ b/server/tests/api/redundancy/redundancy.ts | |||
@@ -247,7 +247,7 @@ async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) { | |||
247 | async function enableRedundancyOnServer1 () { | 247 | async function enableRedundancyOnServer1 () { |
248 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) | 248 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) |
249 | 249 | ||
250 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') | 250 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: '-createdAt' }) |
251 | const follows: ActorFollow[] = res.body.data | 251 | const follows: ActorFollow[] = res.body.data |
252 | const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) | 252 | const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) |
253 | const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) | 253 | const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) |
@@ -262,7 +262,7 @@ async function enableRedundancyOnServer1 () { | |||
262 | async function disableRedundancyOnServer1 () { | 262 | async function disableRedundancyOnServer1 () { |
263 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false) | 263 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false) |
264 | 264 | ||
265 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') | 265 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: '-createdAt' }) |
266 | const follows: ActorFollow[] = res.body.data | 266 | const follows: ActorFollow[] = res.body.data |
267 | const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) | 267 | const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) |
268 | const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) | 268 | const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) |
diff --git a/server/tests/api/server/auto-follows.ts b/server/tests/api/server/auto-follows.ts index df468034c..a06f578fc 100644 --- a/server/tests/api/server/auto-follows.ts +++ b/server/tests/api/server/auto-follows.ts | |||
@@ -21,7 +21,7 @@ const expect = chai.expect | |||
21 | 21 | ||
22 | async function checkFollow (follower: ServerInfo, following: ServerInfo, exists: boolean) { | 22 | async function checkFollow (follower: ServerInfo, following: ServerInfo, exists: boolean) { |
23 | { | 23 | { |
24 | const res = await getFollowersListPaginationAndSort(following.url, 0, 5, '-createdAt') | 24 | const res = await getFollowersListPaginationAndSort({ url: following.url, start: 0, count: 5, sort: '-createdAt' }) |
25 | const follows = res.body.data as ActorFollow[] | 25 | const follows = res.body.data as ActorFollow[] |
26 | 26 | ||
27 | const follow = follows.find(f => { | 27 | const follow = follows.find(f => { |
@@ -36,7 +36,7 @@ async function checkFollow (follower: ServerInfo, following: ServerInfo, exists: | |||
36 | } | 36 | } |
37 | 37 | ||
38 | { | 38 | { |
39 | const res = await getFollowingListPaginationAndSort(follower.url, 0, 5, '-createdAt') | 39 | const res = await getFollowingListPaginationAndSort({ url: follower.url, start: 0, count: 5, sort: '-createdAt' }) |
40 | const follows = res.body.data as ActorFollow[] | 40 | const follows = res.body.data as ActorFollow[] |
41 | 41 | ||
42 | const follow = follows.find(f => { | 42 | const follow = follows.find(f => { |
diff --git a/server/tests/api/server/follows-moderation.ts b/server/tests/api/server/follows-moderation.ts index a82acdb34..1984c9eb1 100644 --- a/server/tests/api/server/follows-moderation.ts +++ b/server/tests/api/server/follows-moderation.ts | |||
@@ -24,7 +24,7 @@ const expect = chai.expect | |||
24 | 24 | ||
25 | async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'accepted') { | 25 | async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'accepted') { |
26 | { | 26 | { |
27 | const res = await getFollowingListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') | 27 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) |
28 | expect(res.body.total).to.equal(1) | 28 | expect(res.body.total).to.equal(1) |
29 | 29 | ||
30 | const follow = res.body.data[0] as ActorFollow | 30 | const follow = res.body.data[0] as ActorFollow |
@@ -34,7 +34,7 @@ async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'acc | |||
34 | } | 34 | } |
35 | 35 | ||
36 | { | 36 | { |
37 | const res = await getFollowersListPaginationAndSort(servers[1].url, 0, 5, 'createdAt') | 37 | const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) |
38 | expect(res.body.total).to.equal(1) | 38 | expect(res.body.total).to.equal(1) |
39 | 39 | ||
40 | const follow = res.body.data[0] as ActorFollow | 40 | const follow = res.body.data[0] as ActorFollow |
@@ -46,12 +46,12 @@ async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'acc | |||
46 | 46 | ||
47 | async function checkNoFollowers (servers: ServerInfo[]) { | 47 | async function checkNoFollowers (servers: ServerInfo[]) { |
48 | { | 48 | { |
49 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, 'createdAt') | 49 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) |
50 | expect(res.body.total).to.equal(0) | 50 | expect(res.body.total).to.equal(0) |
51 | } | 51 | } |
52 | 52 | ||
53 | { | 53 | { |
54 | const res = await getFollowersListPaginationAndSort(servers[ 1 ].url, 0, 5, 'createdAt') | 54 | const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) |
55 | expect(res.body.total).to.equal(0) | 55 | expect(res.body.total).to.equal(0) |
56 | } | 56 | } |
57 | } | 57 | } |
@@ -164,17 +164,17 @@ describe('Test follows moderation', function () { | |||
164 | await waitJobs(servers) | 164 | await waitJobs(servers) |
165 | 165 | ||
166 | { | 166 | { |
167 | const res = await getFollowingListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') | 167 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) |
168 | expect(res.body.total).to.equal(2) | 168 | expect(res.body.total).to.equal(2) |
169 | } | 169 | } |
170 | 170 | ||
171 | { | 171 | { |
172 | const res = await getFollowersListPaginationAndSort(servers[1].url, 0, 5, 'createdAt') | 172 | const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) |
173 | expect(res.body.total).to.equal(1) | 173 | expect(res.body.total).to.equal(1) |
174 | } | 174 | } |
175 | 175 | ||
176 | { | 176 | { |
177 | const res = await getFollowersListPaginationAndSort(servers[2].url, 0, 5, 'createdAt') | 177 | const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 5, sort: 'createdAt' }) |
178 | expect(res.body.total).to.equal(1) | 178 | expect(res.body.total).to.equal(1) |
179 | } | 179 | } |
180 | 180 | ||
@@ -184,7 +184,7 @@ describe('Test follows moderation', function () { | |||
184 | await checkServer1And2HasFollowers(servers) | 184 | await checkServer1And2HasFollowers(servers) |
185 | 185 | ||
186 | { | 186 | { |
187 | const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt') | 187 | const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 5, sort: 'createdAt' }) |
188 | expect(res.body.total).to.equal(0) | 188 | expect(res.body.total).to.equal(0) |
189 | } | 189 | } |
190 | }) | 190 | }) |
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index 36a061926..dd85722a0 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts | |||
@@ -49,7 +49,7 @@ describe('Test follows', function () { | |||
49 | 49 | ||
50 | it('Should not have followers', async function () { | 50 | it('Should not have followers', async function () { |
51 | for (const server of servers) { | 51 | for (const server of servers) { |
52 | const res = await getFollowersListPaginationAndSort(server.url, 0, 5, 'createdAt') | 52 | const res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' }) |
53 | const follows = res.body.data | 53 | const follows = res.body.data |
54 | 54 | ||
55 | expect(res.body.total).to.equal(0) | 55 | expect(res.body.total).to.equal(0) |
@@ -60,7 +60,7 @@ describe('Test follows', function () { | |||
60 | 60 | ||
61 | it('Should not have following', async function () { | 61 | it('Should not have following', async function () { |
62 | for (const server of servers) { | 62 | for (const server of servers) { |
63 | const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') | 63 | const res = await getFollowingListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' }) |
64 | const follows = res.body.data | 64 | const follows = res.body.data |
65 | 65 | ||
66 | expect(res.body.total).to.equal(0) | 66 | expect(res.body.total).to.equal(0) |
@@ -78,14 +78,14 @@ describe('Test follows', function () { | |||
78 | }) | 78 | }) |
79 | 79 | ||
80 | it('Should have 2 followings on server 1', async function () { | 80 | it('Should have 2 followings on server 1', async function () { |
81 | let res = await getFollowingListPaginationAndSort(servers[0].url, 0, 1, 'createdAt') | 81 | let res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 1, sort: 'createdAt' }) |
82 | let follows = res.body.data | 82 | let follows = res.body.data |
83 | 83 | ||
84 | expect(res.body.total).to.equal(2) | 84 | expect(res.body.total).to.equal(2) |
85 | expect(follows).to.be.an('array') | 85 | expect(follows).to.be.an('array') |
86 | expect(follows.length).to.equal(1) | 86 | expect(follows.length).to.equal(1) |
87 | 87 | ||
88 | res = await getFollowingListPaginationAndSort(servers[0].url, 1, 1, 'createdAt') | 88 | res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 1, count: 1, sort: 'createdAt' }) |
89 | follows = follows.concat(res.body.data) | 89 | follows = follows.concat(res.body.data) |
90 | 90 | ||
91 | const server2Follow = follows.find(f => f.following.host === 'localhost:' + servers[1].port) | 91 | const server2Follow = follows.find(f => f.following.host === 'localhost:' + servers[1].port) |
@@ -98,26 +98,58 @@ describe('Test follows', function () { | |||
98 | }) | 98 | }) |
99 | 99 | ||
100 | it('Should search/filter followings on server 1', async function () { | 100 | it('Should search/filter followings on server 1', async function () { |
101 | const sort = 'createdAt' | ||
102 | const start = 0 | ||
103 | const count = 1 | ||
104 | const url = servers[ 0 ].url | ||
105 | |||
101 | { | 106 | { |
102 | const search = ':' + servers[1].port | 107 | const search = ':' + servers[1].port |
103 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search) | ||
104 | const follows = res.body.data | ||
105 | 108 | ||
106 | expect(res.body.total).to.equal(1) | 109 | { |
107 | expect(follows.length).to.equal(1) | 110 | const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search }) |
108 | expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[1].port) | 111 | const follows = res.body.data |
109 | 112 | ||
110 | const res2 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'accepted') | 113 | expect(res.body.total).to.equal(1) |
111 | expect(res2.body.total).to.equal(1) | 114 | expect(follows.length).to.equal(1) |
112 | expect(res2.body.data).to.have.lengthOf(1) | 115 | expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[ 1 ].port) |
116 | } | ||
117 | |||
118 | { | ||
119 | const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'accepted' }) | ||
120 | expect(res.body.total).to.equal(1) | ||
121 | expect(res.body.data).to.have.lengthOf(1) | ||
122 | } | ||
113 | 123 | ||
114 | const res3 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'pending') | 124 | { |
115 | expect(res3.body.total).to.equal(0) | 125 | const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'accepted', actorType: 'Person' }) |
116 | expect(res3.body.data).to.have.lengthOf(0) | 126 | expect(res.body.total).to.equal(0) |
127 | expect(res.body.data).to.have.lengthOf(0) | ||
128 | } | ||
129 | |||
130 | { | ||
131 | const res = await getFollowingListPaginationAndSort({ | ||
132 | url, | ||
133 | start, | ||
134 | count, | ||
135 | sort, | ||
136 | search, | ||
137 | state: 'accepted', | ||
138 | actorType: 'Application' | ||
139 | }) | ||
140 | expect(res.body.total).to.equal(1) | ||
141 | expect(res.body.data).to.have.lengthOf(1) | ||
142 | } | ||
143 | |||
144 | { | ||
145 | const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'pending' }) | ||
146 | expect(res.body.total).to.equal(0) | ||
147 | expect(res.body.data).to.have.lengthOf(0) | ||
148 | } | ||
117 | } | 149 | } |
118 | 150 | ||
119 | { | 151 | { |
120 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', 'bla') | 152 | const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search: 'bla' }) |
121 | const follows = res.body.data | 153 | const follows = res.body.data |
122 | 154 | ||
123 | expect(res.body.total).to.equal(0) | 155 | expect(res.body.total).to.equal(0) |
@@ -127,7 +159,7 @@ describe('Test follows', function () { | |||
127 | 159 | ||
128 | it('Should have 0 followings on server 2 and 3', async function () { | 160 | it('Should have 0 followings on server 2 and 3', async function () { |
129 | for (const server of [ servers[1], servers[2] ]) { | 161 | for (const server of [ servers[1], servers[2] ]) { |
130 | const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') | 162 | const res = await getFollowingListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' }) |
131 | const follows = res.body.data | 163 | const follows = res.body.data |
132 | 164 | ||
133 | expect(res.body.total).to.equal(0) | 165 | expect(res.body.total).to.equal(0) |
@@ -138,7 +170,7 @@ describe('Test follows', function () { | |||
138 | 170 | ||
139 | it('Should have 1 followers on server 2 and 3', async function () { | 171 | it('Should have 1 followers on server 2 and 3', async function () { |
140 | for (const server of [ servers[1], servers[2] ]) { | 172 | for (const server of [ servers[1], servers[2] ]) { |
141 | let res = await getFollowersListPaginationAndSort(server.url, 0, 1, 'createdAt') | 173 | let res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 1, sort: 'createdAt' }) |
142 | 174 | ||
143 | let follows = res.body.data | 175 | let follows = res.body.data |
144 | expect(res.body.total).to.equal(1) | 176 | expect(res.body.total).to.equal(1) |
@@ -149,26 +181,58 @@ describe('Test follows', function () { | |||
149 | }) | 181 | }) |
150 | 182 | ||
151 | it('Should search/filter followers on server 2', async function () { | 183 | it('Should search/filter followers on server 2', async function () { |
184 | const url = servers[ 2 ].url | ||
185 | const start = 0 | ||
186 | const count = 5 | ||
187 | const sort = 'createdAt' | ||
188 | |||
152 | { | 189 | { |
153 | const search = servers[0].port + '' | 190 | const search = servers[0].port + '' |
154 | const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search) | ||
155 | const follows = res.body.data | ||
156 | 191 | ||
157 | expect(res.body.total).to.equal(1) | 192 | { |
158 | expect(follows.length).to.equal(1) | 193 | const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search }) |
159 | expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[2].port) | 194 | const follows = res.body.data |
160 | 195 | ||
161 | const res2 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'accepted') | 196 | expect(res.body.total).to.equal(1) |
162 | expect(res2.body.total).to.equal(1) | 197 | expect(follows.length).to.equal(1) |
163 | expect(res2.body.data).to.have.lengthOf(1) | 198 | expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[ 2 ].port) |
199 | } | ||
200 | |||
201 | { | ||
202 | const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'accepted' }) | ||
203 | expect(res.body.total).to.equal(1) | ||
204 | expect(res.body.data).to.have.lengthOf(1) | ||
205 | } | ||
164 | 206 | ||
165 | const res3 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'pending') | 207 | { |
166 | expect(res3.body.total).to.equal(0) | 208 | const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'accepted', actorType: 'Person' }) |
167 | expect(res3.body.data).to.have.lengthOf(0) | 209 | expect(res.body.total).to.equal(0) |
210 | expect(res.body.data).to.have.lengthOf(0) | ||
211 | } | ||
212 | |||
213 | { | ||
214 | const res = await getFollowersListPaginationAndSort({ | ||
215 | url, | ||
216 | start, | ||
217 | count, | ||
218 | sort, | ||
219 | search, | ||
220 | state: 'accepted', | ||
221 | actorType: 'Application' | ||
222 | }) | ||
223 | expect(res.body.total).to.equal(1) | ||
224 | expect(res.body.data).to.have.lengthOf(1) | ||
225 | } | ||
226 | |||
227 | { | ||
228 | const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'pending' }) | ||
229 | expect(res.body.total).to.equal(0) | ||
230 | expect(res.body.data).to.have.lengthOf(0) | ||
231 | } | ||
168 | } | 232 | } |
169 | 233 | ||
170 | { | 234 | { |
171 | const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', 'bla') | 235 | const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search: 'bla' }) |
172 | const follows = res.body.data | 236 | const follows = res.body.data |
173 | 237 | ||
174 | expect(res.body.total).to.equal(0) | 238 | expect(res.body.total).to.equal(0) |
@@ -177,7 +241,7 @@ describe('Test follows', function () { | |||
177 | }) | 241 | }) |
178 | 242 | ||
179 | it('Should have 0 followers on server 1', async function () { | 243 | it('Should have 0 followers on server 1', async function () { |
180 | const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') | 244 | const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) |
181 | const follows = res.body.data | 245 | const follows = res.body.data |
182 | 246 | ||
183 | expect(res.body.total).to.equal(0) | 247 | expect(res.body.total).to.equal(0) |
@@ -207,7 +271,7 @@ describe('Test follows', function () { | |||
207 | }) | 271 | }) |
208 | 272 | ||
209 | it('Should not follow server 3 on server 1 anymore', async function () { | 273 | it('Should not follow server 3 on server 1 anymore', async function () { |
210 | const res = await getFollowingListPaginationAndSort(servers[0].url, 0, 2, 'createdAt') | 274 | const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) |
211 | let follows = res.body.data | 275 | let follows = res.body.data |
212 | 276 | ||
213 | expect(res.body.total).to.equal(1) | 277 | expect(res.body.total).to.equal(1) |
@@ -218,7 +282,7 @@ describe('Test follows', function () { | |||
218 | }) | 282 | }) |
219 | 283 | ||
220 | it('Should not have server 1 as follower on server 3 anymore', async function () { | 284 | it('Should not have server 1 as follower on server 3 anymore', async function () { |
221 | const res = await getFollowersListPaginationAndSort(servers[2].url, 0, 1, 'createdAt') | 285 | const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 1, sort: 'createdAt' }) |
222 | 286 | ||
223 | let follows = res.body.data | 287 | let follows = res.body.data |
224 | expect(res.body.total).to.equal(0) | 288 | expect(res.body.total).to.equal(0) |
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index 420289bf4..a0f505474 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts | |||
@@ -174,7 +174,7 @@ describe('Test handle downs', function () { | |||
174 | await wait(11000) | 174 | await wait(11000) |
175 | 175 | ||
176 | // Only server 3 is still a follower of server 1 | 176 | // Only server 3 is still a follower of server 1 |
177 | const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 2, 'createdAt') | 177 | const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) |
178 | expect(res.body.data).to.be.an('array') | 178 | expect(res.body.data).to.be.an('array') |
179 | expect(res.body.data).to.have.lengthOf(1) | 179 | expect(res.body.data).to.have.lengthOf(1) |
180 | expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port) | 180 | expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port) |
@@ -202,7 +202,7 @@ describe('Test handle downs', function () { | |||
202 | 202 | ||
203 | await waitJobs(servers) | 203 | await waitJobs(servers) |
204 | 204 | ||
205 | const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 2, 'createdAt') | 205 | const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) |
206 | expect(res.body.data).to.be.an('array') | 206 | expect(res.body.data).to.be.an('array') |
207 | expect(res.body.data).to.have.lengthOf(2) | 207 | expect(res.body.data).to.have.lengthOf(2) |
208 | }) | 208 | }) |
diff --git a/shared/extra-utils/server/follows.ts b/shared/extra-utils/server/follows.ts index 365263a22..3f7729c20 100644 --- a/shared/extra-utils/server/follows.ts +++ b/shared/extra-utils/server/follows.ts | |||
@@ -2,9 +2,18 @@ import * as request from 'supertest' | |||
2 | import { ServerInfo } from './servers' | 2 | import { ServerInfo } from './servers' |
3 | import { waitJobs } from './jobs' | 3 | import { waitJobs } from './jobs' |
4 | import { makePostBodyRequest } from '../requests/requests' | 4 | import { makePostBodyRequest } from '../requests/requests' |
5 | import { FollowState } from '@shared/models' | 5 | import { ActivityPubActorType, FollowState } from '@shared/models' |
6 | 6 | ||
7 | function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string, state?: FollowState) { | 7 | function getFollowersListPaginationAndSort (options: { |
8 | url: string, | ||
9 | start: number, | ||
10 | count: number, | ||
11 | sort: string, | ||
12 | search?: string, | ||
13 | actorType?: ActivityPubActorType, | ||
14 | state?: FollowState | ||
15 | }) { | ||
16 | const { url, start, count, sort, search, state, actorType } = options | ||
8 | const path = '/api/v1/server/followers' | 17 | const path = '/api/v1/server/followers' |
9 | 18 | ||
10 | const query = { | 19 | const query = { |
@@ -12,7 +21,8 @@ function getFollowersListPaginationAndSort (url: string, start: number, count: n | |||
12 | count, | 21 | count, |
13 | sort, | 22 | sort, |
14 | search, | 23 | search, |
15 | state | 24 | state, |
25 | actorType | ||
16 | } | 26 | } |
17 | 27 | ||
18 | return request(url) | 28 | return request(url) |
@@ -45,7 +55,16 @@ function rejectFollower (url: string, token: string, follower: string, statusCod | |||
45 | }) | 55 | }) |
46 | } | 56 | } |
47 | 57 | ||
48 | function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string, state?: FollowState) { | 58 | function getFollowingListPaginationAndSort (options: { |
59 | url: string, | ||
60 | start: number, | ||
61 | count: number, | ||
62 | sort: string, | ||
63 | search?: string, | ||
64 | actorType?: ActivityPubActorType, | ||
65 | state?: FollowState | ||
66 | }) { | ||
67 | const { url, start, count, sort, search, state, actorType } = options | ||
49 | const path = '/api/v1/server/following' | 68 | const path = '/api/v1/server/following' |
50 | 69 | ||
51 | const query = { | 70 | const query = { |
@@ -53,7 +72,8 @@ function getFollowingListPaginationAndSort (url: string, start: number, count: n | |||
53 | count, | 72 | count, |
54 | sort, | 73 | sort, |
55 | search, | 74 | search, |
56 | state | 75 | state, |
76 | actorType | ||
57 | } | 77 | } |
58 | 78 | ||
59 | return request(url) | 79 | return request(url) |