doubleFollow,
findCommentId,
flushAndRunMultipleServers,
- follow,
getAccountBlocklistByAccount,
getAccountBlocklistByServer,
getServerBlocklistByAccount,
removeServerFromServerBlocklist,
ServerInfo,
setAccessTokensToServers,
- unfollow,
uploadVideo,
userLogin,
waitJobs
{
const now = new Date()
- await unfollow(servers[1].url, servers[1].accessToken, servers[0])
+ await servers[1].followsCommand.unfollow({ target: servers[0] })
await waitJobs(servers)
- await follow(servers[1].url, [ servers[0].host ], servers[1].accessToken)
+ await servers[1].followsCommand.follow({ targets: [ servers[0].host ] })
await waitJobs(servers)
{
const now = new Date()
- await unfollow(servers[1].url, servers[1].accessToken, servers[0])
+ await servers[1].followsCommand.unfollow({ target: servers[0] })
await waitJobs(servers)
- await follow(servers[1].url, [ servers[0].host ], servers[1].accessToken)
+ await servers[1].followsCommand.follow({ targets: [ servers[0].host ] })
await waitJobs(servers)
checkVideoIsPublished,
cleanupTests,
createUser,
- follow,
generateUserAccessToken,
getAccount,
getCustomConfig,
removeUserSubscription,
removeVideoFromBlacklist,
ServerInfo,
- unfollow,
updateCustomConfig,
updateCustomSubConfig,
uploadVideo,
it('Should send a notification only to admin when there is a new instance follower', async function () {
this.timeout(20000)
- await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
+ await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
await waitJobs(servers)
it('Should send a notification on auto follow back', async function () {
this.timeout(40000)
- await unfollow(servers[2].url, servers[2].accessToken, servers[0])
+ await servers[2].followsCommand.unfollow({ target: servers[0] })
await waitJobs(servers)
const config = {
}
await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
- await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
+ await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
await waitJobs(servers)
config.followings.instance.autoFollowBack.enabled = false
await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
- await unfollow(servers[0].url, servers[0].accessToken, servers[2])
- await unfollow(servers[2].url, servers[2].accessToken, servers[0])
+ await servers[0].followsCommand.unfollow({ target: servers[2] })
+ await servers[2].followsCommand.unfollow({ target: servers[0] })
})
it('Should send a notification on auto instances index follow', async function () {
this.timeout(30000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[1])
+ await servers[0].followsCommand.unfollow({ target: servers[1] })
await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
config.followings.instance.autoFollowIndex.enabled = false
await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
- await unfollow(servers[0].url, servers[0].accessToken, servers[1])
+ await servers[0].followsCommand.unfollow({ target: servers[1] })
})
})
import {
cleanupTests,
flushAndRunServer,
- follow,
killallServers,
reRunServer,
ServerInfo,
await waitJobs(servers)
// Server 1 and server 2 follow each other
- await follow(remoteServer.url, [ localServer.url ], remoteServer.accessToken)
+ await remoteServer.followsCommand.follow({ targets: [ localServer.url ] })
await waitJobs(servers)
await updateRedundancy(remoteServer.url, remoteServer.accessToken, localServer.host, true)
it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () {
this.timeout(120000)
- await follow(localServer.url, [ remoteServer.url ], localServer.accessToken)
+ await localServer.followsCommand.follow({ targets: [ remoteServer.url ] })
await waitJobs(servers)
await uploadWrapper('video 4 server 2')
cleanupTests,
doubleFollow,
flushAndRunMultipleServers,
- getFollowingListPaginationAndSort,
getVideo,
getVideoWithToken,
immutableAssign,
root,
ServerInfo,
setAccessTokensToServers,
- unfollow,
updateVideo,
uploadVideo,
viewVideo,
updateRedundancy
} from '../../../../shared/extra-utils/server/redundancy'
import { getStats } from '../../../../shared/extra-utils/server/stats'
-import { ActorFollow } from '../../../../shared/models/actors'
import { VideoRedundancy, VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../../shared/models/redundancy'
import { ServerStats } from '../../../../shared/models/server/server-stats.model'
import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
expect(stat.totalVideos).to.equal(0)
}
+async function findServerFollows () {
+ const body = await servers[0].followsCommand.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
+ const follows = body.data
+ const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
+ const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
+
+ return { server2, server3 }
+}
+
async function enableRedundancyOnServer1 () {
await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true)
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' })
- const follows: ActorFollow[] = res.body.data
- const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
- const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
+ const { server2, server3 } = await findServerFollows()
expect(server3).to.not.be.undefined
expect(server3.following.hostRedundancyAllowed).to.be.false
async function disableRedundancyOnServer1 () {
await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, false)
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' })
- const follows: ActorFollow[] = res.body.data
- const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
- const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
+ const { server2, server3 } = await findServerFollows()
expect(server3).to.not.be.undefined
expect(server3.following.hostRedundancyAllowed).to.be.false
it('Should unfollow on server 1 and remove duplicated videos', async function () {
this.timeout(80000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[1])
+ await servers[0].followsCommand.unfollow({ target: servers[1] })
await waitJobs(servers)
await wait(5000)
import 'mocha'
import * as chai from 'chai'
import {
- acceptFollower,
cleanupTests,
flushAndRunMultipleServers,
MockInstancesIndex,
ServerInfo,
setAccessTokensToServers,
- unfollow,
updateCustomSubConfig,
- wait
-} from '../../../../shared/extra-utils/index'
-import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort } from '../../../../shared/extra-utils/server/follows'
-import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
-import { ActorFollow } from '../../../../shared/models/actors'
+ wait,
+ waitJobs
+} from '@shared/extra-utils'
const expect = chai.expect
async function checkFollow (follower: ServerInfo, following: ServerInfo, exists: boolean) {
{
- const res = await getFollowersListPaginationAndSort({ url: following.url, start: 0, count: 5, sort: '-createdAt' })
- const follows = res.body.data as ActorFollow[]
+ const body = await following.followsCommand.getFollowers({ start: 0, count: 5, sort: '-createdAt' })
+ const follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted')
- const follow = follows.find(f => {
- return f.follower.host === follower.host && f.state === 'accepted'
- })
-
- if (exists === true) {
- expect(follow).to.exist
- } else {
- expect(follow).to.be.undefined
- }
+ if (exists === true) expect(follow).to.exist
+ else expect(follow).to.be.undefined
}
{
- const res = await getFollowingListPaginationAndSort({ url: follower.url, start: 0, count: 5, sort: '-createdAt' })
- const follows = res.body.data as ActorFollow[]
-
- const follow = follows.find(f => {
- return f.following.host === following.host && f.state === 'accepted'
- })
+ const body = await follower.followsCommand.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
+ const follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted')
- if (exists === true) {
- expect(follow).to.exist
- } else {
- expect(follow).to.be.undefined
- }
+ if (exists === true) expect(follow).to.exist
+ else expect(follow).to.be.undefined
}
}
async function server1Follows2 (servers: ServerInfo[]) {
- await follow(servers[0].url, [ servers[1].host ], servers[0].accessToken)
+ await servers[0].followsCommand.follow({ targets: [ servers[1].host ] })
await waitJobs(servers)
}
async function resetFollows (servers: ServerInfo[]) {
try {
- await unfollow(servers[0].url, servers[0].accessToken, servers[1])
- await unfollow(servers[1].url, servers[1].accessToken, servers[0])
+ await servers[0].followsCommand.unfollow({ target: servers[1] })
+ await servers[1].followsCommand.unfollow({ target: servers[0] })
} catch { /* empty */
}
await checkFollow(servers[0], servers[1], false)
await checkFollow(servers[1], servers[0], false)
- await acceptFollower(servers[1].url, servers[1].accessToken, 'peertube@' + servers[0].host)
+ await servers[1].followsCommand.acceptFollower({ follower: 'peertube@' + servers[0].host })
await waitJobs(servers)
await checkFollow(servers[0], servers[1], true)
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
+import * as chai from 'chai'
+import { HttpStatusCode } from '@shared/core-utils'
+import { PeerTubeProblemDocument, ServerErrorCode } from '@shared/models'
import {
cleanupTests,
+ createUser,
doubleFollow,
flushAndRunMultipleServers,
getAccountVideos,
getVideoWithToken,
ServerInfo,
setAccessTokensToServers,
- uploadVideo
+ uploadVideo,
+ userLogin
} from '../../../../shared/extra-utils'
-import { unfollow } from '../../../../shared/extra-utils/server/follows'
-import { userLogin } from '../../../../shared/extra-utils/users/login'
-import { createUser } from '../../../../shared/extra-utils/users/users'
-import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
-import { PeerTubeProblemDocument, ServerErrorCode } from '@shared/models'
const expect = chai.expect
before(async function () {
this.timeout(30000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[1])
+ await servers[0].followsCommand.unfollow({ target: servers[1] })
})
describe('With an unlogged user', function () {
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
+import * as chai from 'chai'
import {
- acceptFollower,
cleanupTests,
flushAndRunMultipleServers,
+ FollowsCommand,
ServerInfo,
setAccessTokensToServers,
- updateCustomSubConfig
-} from '../../../../shared/extra-utils/index'
-import {
- follow,
- getFollowersListPaginationAndSort,
- getFollowingListPaginationAndSort,
- rejectFollower,
- removeFollower
-} from '../../../../shared/extra-utils/server/follows'
-import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
-import { ActorFollow } from '../../../../shared/models/actors'
+ updateCustomSubConfig,
+ waitJobs
+} from '@shared/extra-utils'
const expect = chai.expect
async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'accepted') {
- {
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(1)
+ const fns = [
+ servers[0].followsCommand.getFollowings.bind(servers[0].followsCommand),
+ servers[1].followsCommand.getFollowers.bind(servers[1].followsCommand)
+ ]
- const follow = res.body.data[0] as ActorFollow
- expect(follow.state).to.equal(state)
- expect(follow.follower.url).to.equal('http://localhost:' + servers[0].port + '/accounts/peertube')
- expect(follow.following.url).to.equal('http://localhost:' + servers[1].port + '/accounts/peertube')
- }
-
- {
- const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(1)
+ for (const fn of fns) {
+ const body = await fn({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(1)
- const follow = res.body.data[0] as ActorFollow
+ const follow = body.data[0]
expect(follow.state).to.equal(state)
expect(follow.follower.url).to.equal('http://localhost:' + servers[0].port + '/accounts/peertube')
expect(follow.following.url).to.equal('http://localhost:' + servers[1].port + '/accounts/peertube')
}
async function checkNoFollowers (servers: ServerInfo[]) {
- {
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(0)
- }
-
- {
- const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(0)
+ const fns = [
+ servers[0].followsCommand.getFollowings.bind(servers[0].followsCommand),
+ servers[1].followsCommand.getFollowers.bind(servers[1].followsCommand)
+ ]
+
+ for (const fn of fns) {
+ const body = await fn({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
}
}
describe('Test follows moderation', function () {
let servers: ServerInfo[] = []
+ let commands: FollowsCommand[]
before(async function () {
this.timeout(30000)
// Get the access tokens
await setAccessTokensToServers(servers)
+
+ commands = servers.map(s => s.followsCommand)
})
it('Should have server 1 following server 2', async function () {
this.timeout(30000)
- await follow(servers[0].url, [ servers[1].url ], servers[0].accessToken)
+ await commands[0].follow({ targets: [ servers[1].url ] })
await waitJobs(servers)
})
it('Should remove follower on server 2', async function () {
this.timeout(10000)
- await removeFollower(servers[1].url, servers[1].accessToken, servers[0])
+ await commands[1].removeFollower({ follower: servers[0] })
await waitJobs(servers)
})
await updateCustomSubConfig(servers[1].url, servers[1].accessToken, subConfig)
- await follow(servers[0].url, [ servers[1].url ], servers[0].accessToken)
+ await commands[0].follow({ targets: [ servers[1].url ] })
await waitJobs(servers)
await checkNoFollowers(servers)
await updateCustomSubConfig(servers[1].url, servers[1].accessToken, subConfig)
- await follow(servers[0].url, [ servers[1].url ], servers[0].accessToken)
+ await commands[0].follow({ targets: [ servers[1].url ] })
await waitJobs(servers)
await checkServer1And2HasFollowers(servers)
it('Should manually approve followers', async function () {
this.timeout(20000)
- await removeFollower(servers[1].url, servers[1].accessToken, servers[0])
+ await commands[1].removeFollower({ follower: servers[0] })
await waitJobs(servers)
const subConfig = {
await updateCustomSubConfig(servers[1].url, servers[1].accessToken, subConfig)
await updateCustomSubConfig(servers[2].url, servers[2].accessToken, subConfig)
- await follow(servers[0].url, [ servers[1].url ], servers[0].accessToken)
+ await commands[0].follow({ targets: [ servers[1].url ] })
await waitJobs(servers)
await checkServer1And2HasFollowers(servers, 'pending')
it('Should accept a follower', async function () {
this.timeout(10000)
- await acceptFollower(servers[1].url, servers[1].accessToken, 'peertube@localhost:' + servers[0].port)
+ await commands[1].acceptFollower({ follower: 'peertube@localhost:' + servers[0].port })
await waitJobs(servers)
await checkServer1And2HasFollowers(servers)
it('Should reject another follower', async function () {
this.timeout(20000)
- await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken)
+ await commands[0].follow({ targets: [ servers[2].url ] })
await waitJobs(servers)
{
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(2)
+ const body = await commands[0].getFollowings({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(2)
}
{
- const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(1)
+ const body = await commands[1].getFollowers({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(1)
}
{
- const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(1)
+ const body = await commands[2].getFollowers({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(1)
}
- await rejectFollower(servers[2].url, servers[2].accessToken, 'peertube@localhost:' + servers[0].port)
+ await commands[2].rejectFollower({ follower: 'peertube@localhost:' + servers[0].port })
await waitJobs(servers)
await checkServer1And2HasFollowers(servers)
{
- const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 5, sort: 'createdAt' })
- expect(res.body.total).to.equal(0)
+ const body = await commands[2].getFollowers({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
}
})
deleteVideoComment,
expectAccountFollows,
flushAndRunMultipleServers,
- follow,
- getFollowersListPaginationAndSort,
- getFollowingListPaginationAndSort,
+ FollowsCommand,
getVideoCommentThreads,
getVideosList,
getVideoThreadComments,
ServerInfo,
setAccessTokensToServers,
testCaptionFile,
- unfollow,
uploadVideo,
userLogin,
waitJobs
describe('Test follows', function () {
let servers: ServerInfo[] = []
+ let followsCommands: FollowsCommand[]
before(async function () {
this.timeout(30000)
servers = await flushAndRunMultipleServers(3)
+ followsCommands = servers.map(s => s.followsCommand)
// Get the access tokens
await setAccessTokensToServers(servers)
it('Should not have followers', async function () {
for (const server of servers) {
- const res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' })
- const follows = res.body.data
+ const body = await server.followsCommand.getFollowers({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(0)
}
it('Should not have following', async function () {
for (const server of servers) {
- const res = await getFollowingListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' })
- const follows = res.body.data
+ const body = await server.followsCommand.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(0)
}
it('Should have server 1 following server 2 and 3', async function () {
this.timeout(30000)
- await follow(servers[0].url, [ servers[1].url, servers[2].url ], servers[0].accessToken)
+ await followsCommands[0].follow({ targets: [ servers[1].url, servers[2].url ] })
await waitJobs(servers)
})
it('Should have 2 followings on server 1', async function () {
- let res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 1, sort: 'createdAt' })
- let follows = res.body.data
+ const body = await followsCommands[0].getFollowings({ start: 0, count: 1, sort: 'createdAt' })
+ expect(body.total).to.equal(2)
- expect(res.body.total).to.equal(2)
+ let follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(1)
- res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 1, count: 1, sort: 'createdAt' })
- follows = follows.concat(res.body.data)
+ const body2 = await followsCommands[0].getFollowings({ start: 1, count: 1, sort: 'createdAt' })
+ follows = follows.concat(body2.data)
const server2Follow = follows.find(f => f.following.host === 'localhost:' + servers[1].port)
const server3Follow = follows.find(f => f.following.host === 'localhost:' + servers[2].port)
const sort = 'createdAt'
const start = 0
const count = 1
- const url = servers[0].url
{
const search = ':' + servers[1].port
{
- const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search })
- const follows = res.body.data
+ const body = await followsCommands[0].getFollowings({ start, count, sort, search })
+ expect(body.total).to.equal(1)
- expect(res.body.total).to.equal(1)
+ const follows = body.data
expect(follows.length).to.equal(1)
expect(follows[0].following.host).to.equal('localhost:' + servers[1].port)
}
{
- const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'accepted' })
- expect(res.body.total).to.equal(1)
- expect(res.body.data).to.have.lengthOf(1)
+ const body = await followsCommands[0].getFollowings({ start, count, sort, search, state: 'accepted' })
+ expect(body.total).to.equal(1)
+ expect(body.data).to.have.lengthOf(1)
}
{
- const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'accepted', actorType: 'Person' })
- expect(res.body.total).to.equal(0)
- expect(res.body.data).to.have.lengthOf(0)
+ const body = await followsCommands[0].getFollowings({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
+ expect(body.total).to.equal(0)
+ expect(body.data).to.have.lengthOf(0)
}
{
- const res = await getFollowingListPaginationAndSort({
- url,
+ const body = await followsCommands[0].getFollowings({
start,
count,
sort,
state: 'accepted',
actorType: 'Application'
})
- expect(res.body.total).to.equal(1)
- expect(res.body.data).to.have.lengthOf(1)
+ expect(body.total).to.equal(1)
+ expect(body.data).to.have.lengthOf(1)
}
{
- const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search, state: 'pending' })
- expect(res.body.total).to.equal(0)
- expect(res.body.data).to.have.lengthOf(0)
+ const body = await followsCommands[0].getFollowings({ start, count, sort, search, state: 'pending' })
+ expect(body.total).to.equal(0)
+ expect(body.data).to.have.lengthOf(0)
}
}
{
- const res = await getFollowingListPaginationAndSort({ url, start, count, sort, search: 'bla' })
- const follows = res.body.data
+ const body = await followsCommands[0].getFollowings({ start, count, sort, search: 'bla' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
- expect(follows.length).to.equal(0)
+ expect(body.data.length).to.equal(0)
}
})
it('Should have 0 followings on server 2 and 3', async function () {
for (const server of [ servers[1], servers[2] ]) {
- const res = await getFollowingListPaginationAndSort({ url: server.url, start: 0, count: 5, sort: 'createdAt' })
- const follows = res.body.data
+ const body = await server.followsCommand.getFollowings({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(0)
}
it('Should have 1 followers on server 2 and 3', async function () {
for (const server of [ servers[1], servers[2] ]) {
- const res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 1, sort: 'createdAt' })
+ const body = await server.followsCommand.getFollowers({ start: 0, count: 1, sort: 'createdAt' })
+ expect(body.total).to.equal(1)
- const follows = res.body.data
- expect(res.body.total).to.equal(1)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(1)
expect(follows[0].follower.host).to.equal('localhost:' + servers[0].port)
})
it('Should search/filter followers on server 2', async function () {
- const url = servers[2].url
const start = 0
const count = 5
const sort = 'createdAt'
const search = servers[0].port + ''
{
- const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search })
- const follows = res.body.data
+ const body = await followsCommands[2].getFollowers({ start, count, sort, search })
+ expect(body.total).to.equal(1)
- expect(res.body.total).to.equal(1)
+ const follows = body.data
expect(follows.length).to.equal(1)
expect(follows[0].following.host).to.equal('localhost:' + servers[2].port)
}
{
- const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'accepted' })
- expect(res.body.total).to.equal(1)
- expect(res.body.data).to.have.lengthOf(1)
+ const body = await followsCommands[2].getFollowers({ start, count, sort, search, state: 'accepted' })
+ expect(body.total).to.equal(1)
+ expect(body.data).to.have.lengthOf(1)
}
{
- const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'accepted', actorType: 'Person' })
- expect(res.body.total).to.equal(0)
- expect(res.body.data).to.have.lengthOf(0)
+ const body = await followsCommands[2].getFollowers({ start, count, sort, search, state: 'accepted', actorType: 'Person' })
+ expect(body.total).to.equal(0)
+ expect(body.data).to.have.lengthOf(0)
}
{
- const res = await getFollowersListPaginationAndSort({
- url,
+ const body = await followsCommands[2].getFollowers({
start,
count,
sort,
state: 'accepted',
actorType: 'Application'
})
- expect(res.body.total).to.equal(1)
- expect(res.body.data).to.have.lengthOf(1)
+ expect(body.total).to.equal(1)
+ expect(body.data).to.have.lengthOf(1)
}
{
- const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search, state: 'pending' })
- expect(res.body.total).to.equal(0)
- expect(res.body.data).to.have.lengthOf(0)
+ const body = await followsCommands[2].getFollowers({ start, count, sort, search, state: 'pending' })
+ expect(body.total).to.equal(0)
+ expect(body.data).to.have.lengthOf(0)
}
}
{
- const res = await getFollowersListPaginationAndSort({ url, start, count, sort, search: 'bla' })
- const follows = res.body.data
+ const body = await followsCommands[2].getFollowers({ start, count, sort, search: 'bla' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows.length).to.equal(0)
}
})
it('Should have 0 followers on server 1', async function () {
- const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
- const follows = res.body.data
+ const body = await followsCommands[0].getFollowers({ start: 0, count: 5, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(0)
})
it('Should unfollow server 3 on server 1', async function () {
this.timeout(5000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[2])
+ await followsCommands[0].unfollow({ target: servers[2] })
await waitJobs(servers)
})
it('Should not follow server 3 on server 1 anymore', async function () {
- const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
- const follows = res.body.data
+ const body = await followsCommands[0].getFollowings({ start: 0, count: 2, sort: 'createdAt' })
+ expect(body.total).to.equal(1)
- expect(res.body.total).to.equal(1)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(1)
})
it('Should not have server 1 as follower on server 3 anymore', async function () {
- const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 1, sort: 'createdAt' })
+ const body = await followsCommands[2].getFollowers({ start: 0, count: 1, sort: 'createdAt' })
+ expect(body.total).to.equal(0)
- const follows = res.body.data
- expect(res.body.total).to.equal(0)
+ const follows = body.data
expect(follows).to.be.an('array')
expect(follows.length).to.equal(0)
})
await waitJobs(servers)
// Server 1 follows server 3
- await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken)
+ await followsCommands[0].follow({ targets: [ servers[2].url ] })
await waitJobs(servers)
})
it('Should unfollow server 3 on server 1 and does not list server 3 videos', async function () {
this.timeout(5000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[2])
+ await followsCommands[0].unfollow({ target: servers[2] })
await waitJobs(servers)
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
-import { JobState, Video } from '../../../../shared/models'
-import { VideoPrivacy } from '../../../../shared/models/videos'
-import { VideoCommentThreadTree } from '../../../../shared/models/videos/comment/video-comment.model'
-
+import * as chai from 'chai'
+import { HttpStatusCode } from '@shared/core-utils'
import {
+ addVideoCommentReply,
+ addVideoCommentThread,
cleanupTests,
closeAllSequelize,
completeVideoCheck,
flushAndRunMultipleServers,
+ getJobsListPaginationAndSort,
getVideo,
+ getVideoCommentThreads,
getVideosList,
+ getVideoThreadComments,
immutableAssign,
killallServers,
reRunServer,
ServerInfo,
setAccessTokensToServers,
setActorFollowScores,
- unfollow,
updateVideo,
uploadVideo,
uploadVideoAndGetId,
- wait
-} from '../../../../shared/extra-utils'
-import { follow, getFollowersListPaginationAndSort } from '../../../../shared/extra-utils/server/follows'
-import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs'
-import {
- addVideoCommentReply,
- addVideoCommentThread,
- getVideoCommentThreads,
- getVideoThreadComments
-} from '../../../../shared/extra-utils/videos/video-comments'
-import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
+ wait,
+ waitJobs
+} from '@shared/extra-utils'
+import { JobState, Video, VideoCommentThreadTree, VideoPrivacy } from '@shared/models'
const expect = chai.expect
this.timeout(240000)
// Server 2 and 3 follow server 1
- await follow(servers[1].url, [ servers[0].url ], servers[1].accessToken)
- await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
+ await servers[1].followsCommand.follow({ targets: [ servers[0].url ] })
+ await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
await waitJobs(servers)
await wait(11000)
// Only server 3 is still a follower of server 1
- const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
- expect(res.body.data).to.be.an('array')
- expect(res.body.data).to.have.lengthOf(1)
- expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port)
+ const body = await servers[0].followsCommand.getFollowers({ start: 0, count: 2, sort: 'createdAt' })
+ expect(body.data).to.be.an('array')
+ expect(body.data).to.have.lengthOf(1)
+ expect(body.data[0].follower.host).to.equal('localhost:' + servers[2].port)
})
it('Should not have pending/processing jobs anymore', async function () {
await reRunServer(servers[1])
await reRunServer(servers[2])
- await unfollow(servers[1].url, servers[1].accessToken, servers[0])
+ await servers[1].followsCommand.unfollow({ target: servers[0] })
await waitJobs(servers)
- await follow(servers[1].url, [ servers[0].url ], servers[1].accessToken)
+ await servers[1].followsCommand.follow({ targets: [ servers[0].url ] })
await waitJobs(servers)
- const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
- expect(res.body.data).to.be.an('array')
- expect(res.body.data).to.have.lengthOf(2)
+ const body = await servers[0].followsCommand.getFollowers({ start: 0, count: 2, sort: 'createdAt' })
+ expect(body.data).to.be.an('array')
+ expect(body.data).to.have.lengthOf(2)
})
it('Should send an update to server 3, and automatically fetch the video', async function () {
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
+import * as chai from 'chai'
import { cleanupTests, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index'
+import { dateIsValid } from '../../../../shared/extra-utils/miscs/miscs'
import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { flushAndRunMultipleServers } from '../../../../shared/extra-utils/server/servers'
import { uploadVideo } from '../../../../shared/extra-utils/videos/videos'
-import { dateIsValid } from '../../../../shared/extra-utils/miscs/miscs'
import { Job } from '../../../../shared/models/server'
const expect = chai.expect
import * as chai from 'chai'
import {
addVideoChannel,
+ addVideoCommentThread,
cleanupTests,
createUser,
createVideoPlaylist,
doubleFollow,
flushAndRunMultipleServers,
- follow,
ServerInfo,
- unfollow,
+ setAccessTokensToServers,
updateCustomSubConfig,
uploadVideo,
userLogin,
viewVideo,
- wait
-} from '../../../../shared/extra-utils'
-import { setAccessTokensToServers } from '../../../../shared/extra-utils/index'
-import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
-import { getStats } from '../../../../shared/extra-utils/server/stats'
-import { addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
-import { ServerStats } from '../../../../shared/models/server/server-stats.model'
-import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
-import { ActivityType } from '@shared/models'
+ wait,
+ waitJobs
+} from '@shared/extra-utils'
+import { getStats } from '@shared/extra-utils/server/stats'
+import { ActivityType, ServerStats, VideoPlaylistPrivacy } from '@shared/models'
const expect = chai.expect
// Wait the video views repeatable job
await wait(8000)
- await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
+ await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
await waitJobs(servers)
})
it('Should have the correct total videos stats after an unfollow', async function () {
this.timeout(15000)
- await unfollow(servers[2].url, servers[2].accessToken, servers[0])
+ await servers[2].followsCommand.unfollow({ target: servers[0] })
await waitJobs(servers)
const res = await getStats(servers[2].url)
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
+import * as chai from 'chai'
import {
+ addUserSubscription,
+ areSubscriptionsExist,
cleanupTests,
createUser,
doubleFollow,
flushAndRunMultipleServers,
- follow,
- getVideosList,
- unfollow,
- updateVideo,
- userLogin
-} from '../../../../shared/extra-utils'
-import { ServerInfo, uploadVideo } from '../../../../shared/extra-utils/index'
-import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
-import { Video, VideoChannel } from '../../../../shared/models/videos'
-import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
-import {
- addUserSubscription,
- areSubscriptionsExist,
getUserSubscription,
+ getVideosList,
listUserSubscriptions,
listUserSubscriptionVideos,
- removeUserSubscription
-} from '../../../../shared/extra-utils/users/user-subscriptions'
+ removeUserSubscription,
+ ServerInfo,
+ setAccessTokensToServers,
+ updateVideo,
+ uploadVideo,
+ userLogin,
+ waitJobs
+} from '@shared/extra-utils'
+import { Video, VideoChannel } from '@shared/models'
const expect = chai.expect
it('Should have server 1 follow server 3 and display server 3 videos', async function () {
this.timeout(60000)
- await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken)
+ await servers[0].followsCommand.follow({ targets: [ servers[2].url ] })
await waitJobs(servers)
it('Should remove follow server 1 -> server 3 and hide server 3 videos', async function () {
this.timeout(60000)
- await unfollow(servers[0].url, servers[0].accessToken, servers[2])
+ await servers[0].followsCommand.unfollow({ target: servers[2] })
await waitJobs(servers)
createUser,
deleteMe,
flushAndRunServer,
- follow,
getAccountRatings,
getBlacklistedVideosList,
getCustomConfig,
it('Should not be able to follow', async function () {
accessToken = 'my_super_token'
- await follow(server.url, [ 'http://example.com' ], accessToken, HttpStatusCode.UNAUTHORIZED_401)
+
+ await server.followsCommand.follow({
+ targets: [ 'http://example.com' ],
+ token: accessToken,
+ expectedStatus: HttpStatusCode.UNAUTHORIZED_401
+ })
})
it('Should not be able to unfollow')
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
-import * as chai from 'chai'
import 'mocha'
+import * as chai from 'chai'
import {
cleanupTests,
flushAndRunMultipleServers,
import 'mocha'
import * as chai from 'chai'
-import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
+import { HttpStatusCode } from '@shared/core-utils'
import {
+ addAccountToAccountBlocklist,
+ addAccountToServerBlocklist,
+ addServerToAccountBlocklist,
+ addServerToServerBlocklist,
addVideoChannel,
addVideoInPlaylist,
addVideoToBlacklist,
getVideoPlaylistPrivacies,
getVideoPlaylistsList,
getVideoPlaylistWithToken,
+ removeAccountFromAccountBlocklist,
+ removeAccountFromServerBlocklist,
+ removeServerFromAccountBlocklist,
+ removeServerFromServerBlocklist,
removeUser,
removeVideoFromBlacklist,
removeVideoFromPlaylist,
setAccessTokensToServers,
setDefaultVideoChannel,
testImage,
- unfollow,
updateVideo,
updateVideoPlaylist,
updateVideoPlaylistElement,
userLogin,
wait,
waitJobs
-} from '../../../../shared/extra-utils'
+} from '@shared/extra-utils'
import {
- addAccountToAccountBlocklist,
- addAccountToServerBlocklist,
- addServerToAccountBlocklist,
- addServerToServerBlocklist,
- removeAccountFromAccountBlocklist,
- removeAccountFromServerBlocklist,
- removeServerFromAccountBlocklist,
- removeServerFromServerBlocklist
-} from '../../../../shared/extra-utils/users/blocklist'
-import { User } from '../../../../shared/models/users'
-import { VideoPlaylistCreateResult, VideoPrivacy } from '../../../../shared/models/videos'
-import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model'
-import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../../shared/models/videos/playlist/video-playlist-element.model'
-import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
-import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
-import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
+ User,
+ VideoExistInPlaylist,
+ VideoPlaylist,
+ VideoPlaylistCreateResult,
+ VideoPlaylistElement,
+ VideoPlaylistElementType,
+ VideoPlaylistPrivacy,
+ VideoPlaylistType,
+ VideoPrivacy
+} from '@shared/models'
const expect = chai.expect
expect(finder(res.body.data)).to.not.be.undefined
}
- await unfollow(servers[2].url, servers[2].accessToken, servers[0])
+ await servers[2].followsCommand.unfollow({ target: servers[0] })
{
const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
export * from './mock-servers'
export * from './moderation'
export * from './overviews'
+export * from './search'
+export * from './server'
export * from './requests/check-api-params'
export * from './requests/requests'
-export * from './search'
-
export * from './server/clients'
export * from './server/config'
-export * from './server/follows'
export * from './server/jobs'
export * from './server/plugins'
export * from './server/servers'
--- /dev/null
+import { pick } from 'lodash'
+import { ActivityPubActorType, ActorFollow, FollowState, ResultList } from '@shared/models'
+import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
+import { AbstractCommand, OverrideCommandOptions } from '../shared'
+import { ServerInfo } from './servers'
+
+export class FollowsCommand extends AbstractCommand {
+
+ getFollowers (options: OverrideCommandOptions & {
+ start: number
+ count: number
+ sort: string
+ search?: string
+ actorType?: ActivityPubActorType
+ state?: FollowState
+ }) {
+ const path = '/api/v1/server/followers'
+
+ const toPick = [ 'start', 'count', 'sort', 'search', 'state', 'actorType' ]
+ const query = pick(options, toPick)
+
+ return this.getRequestBody<ResultList<ActorFollow>>({
+ ...options,
+
+ token: null,
+
+ path,
+ query,
+ defaultExpectedStatus: HttpStatusCode.OK_200
+ })
+ }
+
+ getFollowings (options: OverrideCommandOptions & {
+ start: number
+ count: number
+ sort: string
+ search?: string
+ actorType?: ActivityPubActorType
+ state?: FollowState
+ }) {
+ const path = '/api/v1/server/following'
+
+ const toPick = [ 'start', 'count', 'sort', 'search', 'state', 'actorType' ]
+ const query = pick(options, toPick)
+
+ return this.getRequestBody<ResultList<ActorFollow>>({
+ ...options,
+
+ token: null,
+
+ path,
+ query,
+ defaultExpectedStatus: HttpStatusCode.OK_200
+ })
+ }
+
+ follow (options: OverrideCommandOptions & {
+ targets: string[]
+ }) {
+ const path = '/api/v1/server/following'
+
+ const hosts = options.targets.map(f => f.replace(/^http:\/\//, ''))
+
+ return this.postBodyRequest({
+ ...options,
+
+ path,
+ fields: { hosts },
+ defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
+ })
+ }
+
+ async unfollow (options: OverrideCommandOptions & {
+ target: ServerInfo
+ }) {
+ const path = '/api/v1/server/following/' + options.target.host
+
+ return this.deleteRequest({
+ ...options,
+
+ path,
+ defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
+ })
+ }
+
+ acceptFollower (options: OverrideCommandOptions & {
+ follower: string
+ }) {
+ const path = '/api/v1/server/followers/' + options.follower + '/accept'
+
+ return this.postBodyRequest({
+ ...options,
+
+ path,
+ defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
+ })
+ }
+
+ rejectFollower (options: OverrideCommandOptions & {
+ follower: string
+ }) {
+ const path = '/api/v1/server/followers/' + options.follower + '/reject'
+
+ return this.postBodyRequest({
+ ...options,
+
+ path,
+ defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
+ })
+ }
+
+ removeFollower (options: OverrideCommandOptions & {
+ follower: ServerInfo
+ }) {
+ const path = '/api/v1/server/followers/peertube@' + options.follower.host
+
+ return this.deleteRequest({
+ ...options,
+
+ path,
+ defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
+ })
+ }
+}
-import * as request from 'supertest'
-import { ServerInfo } from './servers'
import { waitJobs } from './jobs'
-import { makePostBodyRequest } from '../requests/requests'
-import { ActivityPubActorType, FollowState } from '@shared/models'
-import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
-
-function getFollowersListPaginationAndSort (options: {
- url: string
- start: number
- count: number
- sort: string
- search?: string
- actorType?: ActivityPubActorType
- state?: FollowState
-}) {
- const { url, start, count, sort, search, state, actorType } = options
- const path = '/api/v1/server/followers'
-
- const query = {
- start,
- count,
- sort,
- search,
- state,
- actorType
- }
-
- return request(url)
- .get(path)
- .query(query)
- .set('Accept', 'application/json')
- .expect(HttpStatusCode.OK_200)
- .expect('Content-Type', /json/)
-}
-
-function acceptFollower (url: string, token: string, follower: string, statusCodeExpected = HttpStatusCode.NO_CONTENT_204) {
- const path = '/api/v1/server/followers/' + follower + '/accept'
-
- return makePostBodyRequest({
- url,
- token,
- path,
- statusCodeExpected
- })
-}
-
-function rejectFollower (url: string, token: string, follower: string, statusCodeExpected = HttpStatusCode.NO_CONTENT_204) {
- const path = '/api/v1/server/followers/' + follower + '/reject'
-
- return makePostBodyRequest({
- url,
- token,
- path,
- statusCodeExpected
- })
-}
-
-function getFollowingListPaginationAndSort (options: {
- url: string
- start: number
- count: number
- sort: string
- search?: string
- actorType?: ActivityPubActorType
- state?: FollowState
-}) {
- const { url, start, count, sort, search, state, actorType } = options
- const path = '/api/v1/server/following'
-
- const query = {
- start,
- count,
- sort,
- search,
- state,
- actorType
- }
-
- return request(url)
- .get(path)
- .query(query)
- .set('Accept', 'application/json')
- .expect(HttpStatusCode.OK_200)
- .expect('Content-Type', /json/)
-}
-
-function follow (follower: string, following: string[], accessToken: string, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
- const path = '/api/v1/server/following'
-
- const followingHosts = following.map(f => f.replace(/^http:\/\//, ''))
- return request(follower)
- .post(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .send({ hosts: followingHosts })
- .expect(expectedStatus)
-}
-
-async function unfollow (url: string, accessToken: string, target: ServerInfo, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
- const path = '/api/v1/server/following/' + target.host
-
- return request(url)
- .delete(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(expectedStatus)
-}
-
-function removeFollower (url: string, accessToken: string, follower: ServerInfo, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
- const path = '/api/v1/server/followers/peertube@' + follower.host
-
- return request(url)
- .delete(path)
- .set('Accept', 'application/json')
- .set('Authorization', 'Bearer ' + accessToken)
- .expect(expectedStatus)
-}
+import { ServerInfo } from './servers'
async function doubleFollow (server1: ServerInfo, server2: ServerInfo) {
await Promise.all([
- follow(server1.url, [ server2.url ], server1.accessToken),
- follow(server2.url, [ server1.url ], server2.accessToken)
+ server1.followsCommand.follow({ targets: [ server2.url ] }),
+ server2.followsCommand.follow({ targets: [ server1.url ] })
])
// Wait request propagation
// ---------------------------------------------------------------------------
export {
- getFollowersListPaginationAndSort,
- getFollowingListPaginationAndSort,
- unfollow,
- removeFollower,
- follow,
- doubleFollow,
- acceptFollower,
- rejectFollower
+ doubleFollow
}
export * from './contact-form-command'
export * from './debug-command'
+export * from './follows-command'
+export * from './follows'
import { SearchCommand } from '../search'
import { ContactFormCommand } from './contact-form-command'
import { DebugCommand } from './debug-command'
+import { FollowsCommand } from './follows-command'
interface ServerInfo {
app: ChildProcess
searchCommand?: SearchCommand
contactFormCommand?: ContactFormCommand
debugCommand?: DebugCommand
+ followsCommand?: FollowsCommand
}
function parallelTests () {
server.searchCommand = new SearchCommand(server)
server.contactFormCommand = new ContactFormCommand(server)
server.debugCommand = new DebugCommand(server)
+ server.followsCommand = new FollowsCommand(server)
res(server)
})