1
0
Fork 0

Only display accepted followers/followings in about page

This commit is contained in:
Chocobozzz 2019-11-28 11:37:32 +01:00
parent d275e75453
commit b8f4167fb6
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
11 changed files with 171 additions and 35 deletions

View File

@ -74,7 +74,7 @@ export class AboutFollowsComponent implements OnInit {
private loadMoreFollowers () {
const pagination = this.restService.componentPaginationToRestPagination(this.followersPagination)
this.followService.getFollowers(pagination, this.sort)
this.followService.getFollowers({ pagination: pagination, sort: this.sort, state: 'accepted' })
.subscribe(
resultList => {
const newFollowers = resultList.data.map(r => r.follower.host)
@ -92,7 +92,7 @@ export class AboutFollowsComponent implements OnInit {
private loadMoreFollowings () {
const pagination = this.restService.componentPaginationToRestPagination(this.followingsPagination)
this.followService.getFollowing(pagination, this.sort)
this.followService.getFollowing({ pagination, sort: this.sort, state: 'accepted' })
.subscribe(
resultList => {
const newFollowings = resultList.data.map(r => r.following.host)

View File

@ -88,7 +88,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
}
protected loadData () {
this.followService.getFollowers(this.pagination, this.sort, this.search)
this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search })
.subscribe(
resultList => {
this.followers = resultList.data

View File

@ -50,7 +50,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
}
protected loadData () {
this.followService.getFollowing(this.pagination, this.sort, this.search)
this.followService.getFollowing({ pagination: this.pagination, sort: this.sort, search: this.search })
.subscribe(
resultList => {
this.following = resultList.data

View File

@ -2,7 +2,7 @@ import { catchError, map } from 'rxjs/operators'
import { HttpClient, HttpParams } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { ActorFollow, ResultList } from '@shared/index'
import { ActorFollow, FollowState, ResultList } from '@shared/index'
import { environment } from '../../../environments/environment'
import { RestExtractor, RestPagination, RestService } from '../rest'
import { SortMeta } from 'primeng/api'
@ -18,11 +18,19 @@ export class FollowService {
) {
}
getFollowing (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<ActorFollow>> {
getFollowing (options: {
pagination: RestPagination,
sort: SortMeta,
search?: string,
state?: FollowState
}): Observable<ResultList<ActorFollow>> {
const { pagination, sort, search, state } = options
let params = new HttpParams()
params = this.restService.addRestGetParams(params, pagination, sort)
if (search) params = params.append('search', search)
if (state) params = params.append('state', state)
return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params })
.pipe(
@ -31,11 +39,19 @@ export class FollowService {
)
}
getFollowers (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<ActorFollow>> {
getFollowers (options: {
pagination: RestPagination,
sort: SortMeta,
search?: string,
state?: FollowState
}): Observable<ResultList<ActorFollow>> {
const { pagination, sort, search, state } = options
let params = new HttpParams()
params = this.restService.addRestGetParams(params, pagination, sort)
if (search) params = params.append('search', search)
if (state) params = params.append('state', state)
return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params })
.pipe(

View File

@ -19,7 +19,8 @@ import {
followingSortValidator,
followValidator,
getFollowerValidator,
removeFollowingValidator
removeFollowingValidator,
listFollowsValidator
} from '../../../middlewares/validators'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { JobQueue } from '../../../lib/job-queue'
@ -29,6 +30,7 @@ import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow'
const serverFollowsRouter = express.Router()
serverFollowsRouter.get('/following',
listFollowsValidator,
paginationValidator,
followingSortValidator,
setDefaultSort,
@ -52,6 +54,7 @@ serverFollowsRouter.delete('/following/:host',
)
serverFollowsRouter.get('/followers',
listFollowsValidator,
paginationValidator,
followersSortValidator,
setDefaultSort,
@ -92,26 +95,28 @@ export {
async function listFollowing (req: express.Request, res: express.Response) {
const serverActor = await getServerActor()
const resultList = await ActorFollowModel.listFollowingForApi(
serverActor.id,
req.query.start,
req.query.count,
req.query.sort,
req.query.search
)
const resultList = await ActorFollowModel.listFollowingForApi({
id: serverActor.id,
start: req.query.start,
count: req.query.count,
sort: req.query.sort,
search: req.query.search,
state: req.query.state
})
return res.json(getFormattedObjects(resultList.data, resultList.total))
}
async function listFollowers (req: express.Request, res: express.Response) {
const serverActor = await getServerActor()
const resultList = await ActorFollowModel.listFollowersForApi(
serverActor.id,
req.query.start,
req.query.count,
req.query.sort,
req.query.search
)
const resultList = await ActorFollowModel.listFollowersForApi({
actorId: serverActor.id,
start: req.query.start,
count: req.query.count,
sort: req.query.sort,
search: req.query.search,
state: req.query.state
})
return res.json(getFormattedObjects(resultList.data, resultList.total))
}

View File

@ -0,0 +1,14 @@
import { exists } from './misc'
import { FollowState } from '@shared/models'
function isFollowStateValid (value: FollowState) {
if (!exists(value)) return false
return value === 'pending' || value === 'accepted'
}
// ---------------------------------------------------------------------------
export {
isFollowStateValid
}

View File

@ -1,5 +1,5 @@
import * as express from 'express'
import { body, param } from 'express-validator'
import { body, param, query } from 'express-validator'
import { isTestInstance } from '../../helpers/core-utils'
import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers'
import { logger } from '../../helpers/logger'
@ -11,6 +11,19 @@ import { ActorModel } from '../../models/activitypub/actor'
import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor'
import { MActorFollowActorsDefault } from '@server/typings/models'
import { isFollowStateValid } from '@server/helpers/custom-validators/follows'
const listFollowsValidator = [
query('state')
.optional()
.custom(isFollowStateValid).withMessage('Should have a valid follow state'),
(req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return
return next()
}
]
const followValidator = [
body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
@ -110,5 +123,6 @@ export {
followValidator,
removeFollowingValidator,
getFollowerValidator,
acceptOrRejectFollowerValidator
acceptOrRejectFollowerValidator,
listFollowsValidator
}

View File

@ -292,12 +292,24 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
return ActorFollowModel.findAll(query)
}
static listFollowingForApi (id: number, start: number, count: number, sort: string, search?: string) {
static listFollowingForApi (options: {
id: number,
start: number,
count: number,
sort: string,
state?: FollowState,
search?: string
}) {
const { id, start, count, sort, search, state } = options
const followWhere = state ? { state } : {}
const query = {
distinct: true,
offset: start,
limit: count,
order: getSort(sort),
where: followWhere,
include: [
{
model: ActorModel,
@ -335,12 +347,24 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
})
}
static listFollowersForApi (actorId: number, start: number, count: number, sort: string, search?: string) {
static listFollowersForApi (options: {
actorId: number,
start: number,
count: number,
sort: string,
state?: FollowState,
search?: string
}) {
const { actorId, start, count, sort, search, state } = options
const followWhere = state ? { state } : {}
const query = {
distinct: true,
offset: start,
limit: count,
order: getSort(sort),
where: followWhere,
include: [
{
model: ActorModel,

View File

@ -6,7 +6,7 @@ import {
cleanupTests,
createUser,
flushAndRunServer,
makeDeleteRequest,
makeDeleteRequest, makeGetRequest,
makePostBodyRequest,
ServerInfo,
setAccessTokensToServers,
@ -131,6 +131,27 @@ describe('Test server follows API validators', function () {
it('Should fail with an incorrect sort', async function () {
await checkBadSortPagination(server.url, path)
})
it('Should fail with an incorrect state', async function () {
await makeGetRequest({
url: server.url,
path,
query: {
state: 'blabla'
}
})
})
it('Should fail succeed with the correct params', async function () {
await makeGetRequest({
url: server.url,
path,
statusCodeExpected: 200,
query: {
state: 'accepted'
}
})
})
})
describe('When listing followers', function () {
@ -147,6 +168,27 @@ describe('Test server follows API validators', function () {
it('Should fail with an incorrect sort', async function () {
await checkBadSortPagination(server.url, path)
})
it('Should fail with an incorrect state', async function () {
await makeGetRequest({
url: server.url,
path,
query: {
state: 'blabla'
}
})
})
it('Should fail succeed with the correct params', async function () {
await makeGetRequest({
url: server.url,
path,
statusCodeExpected: 200,
query: {
state: 'accepted'
}
})
})
})
describe('When removing a follower', function () {

View File

@ -97,14 +97,23 @@ describe('Test follows', function () {
expect(server3Follow.state).to.equal('accepted')
})
it('Should search followings on server 1', async function () {
it('Should search/filter followings on server 1', async function () {
{
const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', ':' + servers[1].port)
const search = ':' + servers[1].port
const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search)
const follows = res.body.data
expect(res.body.total).to.equal(1)
expect(follows.length).to.equal(1)
expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[1].port)
const res2 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'accepted')
expect(res2.body.total).to.equal(1)
expect(res2.body.data).to.have.lengthOf(1)
const res3 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'pending')
expect(res3.body.total).to.equal(0)
expect(res3.body.data).to.have.lengthOf(0)
}
{
@ -139,14 +148,23 @@ describe('Test follows', function () {
}
})
it('Should search followers on server 2', async function () {
it('Should search/filter followers on server 2', async function () {
{
const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', servers[0].port + '')
const search = servers[0].port + ''
const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search)
const follows = res.body.data
expect(res.body.total).to.equal(1)
expect(follows.length).to.equal(1)
expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[2].port)
const res2 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'accepted')
expect(res2.body.total).to.equal(1)
expect(res2.body.data).to.have.lengthOf(1)
const res3 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'pending')
expect(res3.body.total).to.equal(0)
expect(res3.body.data).to.have.lengthOf(0)
}
{

View File

@ -2,15 +2,17 @@ import * as request from 'supertest'
import { ServerInfo } from './servers'
import { waitJobs } from './jobs'
import { makePostBodyRequest } from '../requests/requests'
import { FollowState } from '@shared/models'
function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string, state?: FollowState) {
const path = '/api/v1/server/followers'
const query = {
start,
count,
sort,
search
search,
state
}
return request(url)
@ -43,14 +45,15 @@ function rejectFollower (url: string, token: string, follower: string, statusCod
})
}
function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string, state?: FollowState) {
const path = '/api/v1/server/following'
const query = {
start,
count,
sort,
search
search,
state
}
return request(url)