+ await servers[1].config.updateCustomSubConfig({ newConfig: subConfig })
+
+ await commands[0].follow({ hosts: [ servers[1].url ] })
+ await waitJobs(servers)
+
+ await checkServer1And2HasFollowers(servers)
+ })
+
+ it('Should manually approve followers', async function () {
+ this.timeout(20000)
+
+ await commands[0].unfollow({ target: servers[1] })
+ await waitJobs(servers)
+
+ const subConfig = {
+ followers: {
+ instance: {
+ enabled: true,
+ manualApproval: true
+ }
+ }
+ }
+
+ await servers[1].config.updateCustomSubConfig({ newConfig: subConfig })
+ await servers[2].config.updateCustomSubConfig({ newConfig: subConfig })
+
+ await commands[0].follow({ hosts: [ servers[1].url ] })
+ await waitJobs(servers)
+
+ await checkServer1And2HasFollowers(servers, 'pending')
+ })
+
+ it('Should accept a follower', async function () {
+ this.timeout(10000)
+
+ await commands[1].acceptFollower({ follower: 'peertube@' + servers[0].host })
+ await waitJobs(servers)
+
+ await checkServer1And2HasFollowers(servers)
+ })
+
+ it('Should reject another follower', async function () {
+ this.timeout(20000)
+
+ await commands[0].follow({ hosts: [ servers[2].url ] })
+ await waitJobs(servers)
+
+ {
+ const body = await commands[0].getFollowings()
+ expect(body.total).to.equal(2)
+ }
+
+ {
+ const body = await commands[1].getFollowers()
+ expect(body.total).to.equal(1)
+ }
+
+ {
+ const body = await commands[2].getFollowers()
+ expect(body.total).to.equal(1)
+ }
+
+ await commands[2].rejectFollower({ follower: 'peertube@' + servers[0].host })
+ await waitJobs(servers)
+
+ { // server 1
+ {
+ const { data } = await commands[0].getFollowings({ state: 'accepted' })
+ expect(data).to.have.lengthOf(1)
+ }
+
+ {
+ const { data } = await commands[0].getFollowings({ state: 'rejected' })
+ expect(data).to.have.lengthOf(1)
+ expectStartWith(data[0].following.url, servers[2].url)
+ }
+ }
+
+ { // server 3
+ {
+ const { data } = await commands[2].getFollowers({ state: 'accepted' })
+ expect(data).to.have.lengthOf(0)
+ }
+
+ {
+ const { data } = await commands[2].getFollowers({ state: 'rejected' })
+ expect(data).to.have.lengthOf(1)
+ expectStartWith(data[0].follower.url, servers[0].url)
+ }
+ }
+ })
+
+ it('Should not change the follow on refollow with and without auto accept', async function () {
+ const run = async () => {
+ await commands[0].follow({ hosts: [ servers[2].url ] })
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'rejected',
+ following: servers[2],
+ followingState: 'rejected'
+ })
+ }
+
+ await servers[2].config.updateExistingSubConfig({ newConfig: { followers: { instance: { manualApproval: false } } } })
+ await run()
+
+ await servers[2].config.updateExistingSubConfig({ newConfig: { followers: { instance: { manualApproval: true } } } })
+ await run()
+ })
+
+ it('Should not change the rejected status on unfollow', async function () {
+ await commands[0].unfollow({ target: servers[2] })
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'deleted',
+ following: servers[2],
+ followingState: 'rejected'
+ })
+ })
+
+ it('Should delete the follower and add again the follower', async function () {
+ await commands[2].removeFollower({ follower: servers[0] })
+ await waitJobs(servers)
+
+ await commands[0].follow({ hosts: [ servers[2].url ] })
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'pending',
+ following: servers[2],
+ followingState: 'pending'
+ })
+ })
+
+ it('Should be able to reject a previously accepted follower', async function () {
+ await commands[1].rejectFollower({ follower: 'peertube@' + servers[0].host })
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'rejected',
+ following: servers[1],
+ followingState: 'rejected'
+ })
+ })
+
+ it('Should be able to re accept a previously rejected follower', async function () {
+ await commands[1].acceptFollower({ follower: 'peertube@' + servers[0].host })
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'accepted',
+ following: servers[1],
+ followingState: 'accepted'
+ })
+ })
+
+ it('Should ignore follow requests of muted servers', async function () {
+ await servers[1].blocklist.addToServerBlocklist({ server: servers[0].host })
+
+ await commands[0].unfollow({ target: servers[1] })
+
+ await waitJobs(servers)
+
+ await checkFollows({
+ follower: servers[0],
+ followerState: 'deleted',
+ following: servers[1],
+ followingState: 'deleted'
+ })