Update follower/following counts
This commit is contained in:
parent
6502c3d43e
commit
32b2b43c06
|
@ -9,7 +9,7 @@ import { isTestInstance, root, sanitizeHost, sanitizeUrl } from '../helpers/core
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const LAST_MIGRATION_VERSION = 170
|
||||
const LAST_MIGRATION_VERSION = 175
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import { ACTOR_FOLLOW_SCORE } from '../index'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
queryInterface: Sequelize.QueryInterface,
|
||||
sequelize: Sequelize.Sequelize
|
||||
}): Promise<void> {
|
||||
const query = 'UPDATE "actor" SET ' +
|
||||
'"followersCount" = (SELECT COUNT(*) FROM "actorFollow" WHERE "actor"."id" = "actorFollow"."targetActorId"), ' +
|
||||
'"followingCount" = (SELECT COUNT(*) FROM "actorFollow" WHERE "actor"."id" = "actorFollow"."actorId") ' +
|
||||
'WHERE "actor"."serverId" IS NULL'
|
||||
|
||||
await utils.sequelize.query(query)
|
||||
}
|
||||
|
||||
function down (options) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -314,6 +314,7 @@ async function refreshActorIfNeeded (actor: ActorModel) {
|
|||
if (result === undefined) throw new Error('Cannot fetch remote actor in refresh actor.')
|
||||
|
||||
return sequelizeTypescript.transaction(async t => {
|
||||
logger.info('coucou', result.actor.toJSON())
|
||||
updateInstanceWithAnother(actor, result.actor)
|
||||
|
||||
if (result.avatarName !== undefined) {
|
||||
|
|
|
@ -51,6 +51,9 @@ async function follow (actor: ActorModel, targetActorURL: string) {
|
|||
transaction: t
|
||||
})
|
||||
|
||||
actorFollow.ActorFollower = actor
|
||||
actorFollow.ActorFollowing = targetActor
|
||||
|
||||
if (actorFollow.state !== 'accepted') {
|
||||
actorFollow.state = 'accepted'
|
||||
await actorFollow.save({ transaction: t })
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as Bluebird from 'bluebird'
|
|||
import { values } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import {
|
||||
AfterCreate, AfterDestroy, AfterUpdate,
|
||||
AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, IsInt, Max, Model, Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
|
@ -79,6 +80,25 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
|||
})
|
||||
ActorFollowing: ActorModel
|
||||
|
||||
@AfterCreate
|
||||
@AfterUpdate
|
||||
static incrementFollowerAndFollowingCount (instance: ActorFollowModel) {
|
||||
if (instance.state !== 'accepted') return
|
||||
|
||||
return Promise.all([
|
||||
ActorModel.incrementFollows(instance.actorId, 'followingCount', 1),
|
||||
ActorModel.incrementFollows(instance.targetActorId, 'followersCount', 1)
|
||||
])
|
||||
}
|
||||
|
||||
@AfterDestroy
|
||||
static decrementFollowerAndFollowingCount (instance: ActorFollowModel) {
|
||||
return Promise.all([
|
||||
ActorModel.incrementFollows(instance.actorId, 'followingCount',-1),
|
||||
ActorModel.incrementFollows(instance.targetActorId, 'followersCount', -1)
|
||||
])
|
||||
}
|
||||
|
||||
// Remove actor follows with a score of 0 (too many requests where they were unreachable)
|
||||
static async removeBadActorFollows () {
|
||||
const actorFollows = await ActorFollowModel.listBadActorFollows()
|
||||
|
|
|
@ -264,6 +264,16 @@ export class ActorModel extends Model<ActorModel> {
|
|||
return ActorModel.scope(ScopeNames.FULL).findOne(query)
|
||||
}
|
||||
|
||||
static incrementFollows (id: number, column: 'followersCount' | 'followingCount', by: number) {
|
||||
// FIXME: typings
|
||||
return (ActorModel as any).increment(column, {
|
||||
by,
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
toFormattedJSON () {
|
||||
let avatar: Avatar = null
|
||||
if (this.Avatar) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
} from '../../utils/index'
|
||||
import { dateIsValid } from '../../utils/miscs/miscs'
|
||||
import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows'
|
||||
import { expectAccountFollows } from '../../utils/users/accounts'
|
||||
import { userLogin } from '../../utils/users/login'
|
||||
import { createUser } from '../../utils/users/users'
|
||||
import {
|
||||
|
@ -116,6 +117,19 @@ describe('Test follows', function () {
|
|||
expect(follows.length).to.equal(0)
|
||||
})
|
||||
|
||||
it('Should have the correct following counts', async function () {
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9001', 0, 2)
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9002', 1, 0)
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9003', 1, 0)
|
||||
|
||||
// Server 2 and 3 does not know server 1 follow another server (there was not a refresh)
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9002', 1, 0)
|
||||
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9003', 1, 0)
|
||||
})
|
||||
|
||||
it('Should unfollow server 3 on server 1', async function () {
|
||||
this.timeout(5000)
|
||||
|
||||
|
@ -144,6 +158,17 @@ describe('Test follows', function () {
|
|||
expect(follows.length).to.equal(0)
|
||||
})
|
||||
|
||||
it('Should have the correct following counts 2', async function () {
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9002', 1, 0)
|
||||
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9002', 1, 0)
|
||||
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9001', 0, 0)
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9003', 0, 0)
|
||||
})
|
||||
|
||||
it('Should upload a video on server 2 ans 3 and propagate only the video of server 2', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
|
@ -223,6 +248,18 @@ describe('Test follows', function () {
|
|||
await wait(7000)
|
||||
})
|
||||
|
||||
it('Should have the correct following counts 2', async function () {
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9001', 0, 2)
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9002', 1, 0)
|
||||
await expectAccountFollows(servers[0].url, 'peertube@localhost:9003', 1, 0)
|
||||
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[1].url, 'peertube@localhost:9002', 1, 0)
|
||||
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9001', 0, 1)
|
||||
await expectAccountFollows(servers[2].url, 'peertube@localhost:9003', 1, 0)
|
||||
})
|
||||
|
||||
it('Should propagate videos', async function () {
|
||||
const res = await getVideosList(servers[ 0 ].url)
|
||||
expect(res.body.total).to.equal(7)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { expect } from 'chai'
|
||||
import { Account } from '../../../../shared/models/actors'
|
||||
import { makeGetRequest } from '../requests/requests'
|
||||
|
||||
function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
|
||||
|
@ -21,9 +23,19 @@ function getAccount (url: string, accountId: number | string, statusCodeExpected
|
|||
})
|
||||
}
|
||||
|
||||
async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
|
||||
const res = await getAccountsList(url)
|
||||
const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
|
||||
|
||||
const message = `${nameWithDomain} on ${url}`
|
||||
expect(account.followersCount).to.equal(followersCount, message)
|
||||
expect(account.followingCount).to.equal(followingCount, message)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
getAccount,
|
||||
expectAccountFollows,
|
||||
getAccountsList
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue