2021-02-26 09:26:27 -06:00
|
|
|
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
|
|
|
|
2022-08-17 08:44:32 -05:00
|
|
|
import { expect } from 'chai'
|
2023-04-21 08:00:01 -05:00
|
|
|
import { SQLCommand } from '@server/tests/shared'
|
2021-12-17 04:58:15 -06:00
|
|
|
import { wait } from '@shared/core-utils'
|
2021-02-26 09:26:27 -06:00
|
|
|
import {
|
|
|
|
cleanupTests,
|
2021-07-16 02:47:51 -05:00
|
|
|
createMultipleServers,
|
2021-07-16 07:27:30 -05:00
|
|
|
doubleFollow,
|
2021-07-16 02:47:51 -05:00
|
|
|
PeerTubeServer,
|
2021-07-09 07:15:11 -05:00
|
|
|
setAccessTokensToServers,
|
|
|
|
waitJobs
|
2021-12-17 02:29:23 -06:00
|
|
|
} from '@shared/server-commands'
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
describe('Test AP cleaner', function () {
|
2021-07-16 02:47:51 -05:00
|
|
|
let servers: PeerTubeServer[] = []
|
2023-04-21 08:00:01 -05:00
|
|
|
const sqlCommands: SQLCommand[] = []
|
|
|
|
|
2021-02-26 09:26:27 -06:00
|
|
|
let videoUUID1: string
|
|
|
|
let videoUUID2: string
|
|
|
|
let videoUUID3: string
|
|
|
|
|
|
|
|
let videoUUIDs: string[]
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
this.timeout(120000)
|
|
|
|
|
|
|
|
const config = {
|
|
|
|
federation: {
|
|
|
|
videos: { cleanup_remote_interactions: true }
|
|
|
|
}
|
|
|
|
}
|
2021-07-16 02:47:51 -05:00
|
|
|
servers = await createMultipleServers(3, config)
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
// Get the access tokens
|
|
|
|
await setAccessTokensToServers(servers)
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
doubleFollow(servers[0], servers[1]),
|
|
|
|
doubleFollow(servers[1], servers[2]),
|
|
|
|
doubleFollow(servers[0], servers[2])
|
|
|
|
])
|
|
|
|
|
|
|
|
// Update 1 local share, check 6 shares
|
|
|
|
|
|
|
|
// Create 1 comment per video
|
|
|
|
// Update 1 remote URL and 1 local URL on
|
|
|
|
|
2021-07-16 02:04:35 -05:00
|
|
|
videoUUID1 = (await servers[0].videos.quickUpload({ name: 'server 1' })).uuid
|
|
|
|
videoUUID2 = (await servers[1].videos.quickUpload({ name: 'server 2' })).uuid
|
|
|
|
videoUUID3 = (await servers[2].videos.quickUpload({ name: 'server 3' })).uuid
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
videoUUIDs = [ videoUUID1, videoUUID2, videoUUID3 ]
|
|
|
|
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
for (const uuid of videoUUIDs) {
|
2021-07-16 02:04:35 -05:00
|
|
|
await server.videos.rate({ id: uuid, rating: 'like' })
|
|
|
|
await server.comments.createThread({ videoId: uuid, text: 'comment' })
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
2023-04-21 08:00:01 -05:00
|
|
|
|
|
|
|
sqlCommands.push(new SQLCommand(server))
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
await waitJobs(servers)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should have the correct likes', async function () {
|
|
|
|
for (const server of servers) {
|
|
|
|
for (const uuid of videoUUIDs) {
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await server.videos.get({ id: uuid })
|
2021-07-15 03:02:54 -05:00
|
|
|
|
|
|
|
expect(video.likes).to.equal(3)
|
|
|
|
expect(video.dislikes).to.equal(0)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should destroy server 3 internal likes and correctly clean them', async function () {
|
|
|
|
this.timeout(20000)
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].deleteAll('accountVideoRate')
|
2021-02-26 09:26:27 -06:00
|
|
|
for (const uuid of videoUUIDs) {
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].setVideoField(uuid, 'likes', '0')
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
// Updated rates of my video
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await servers[0].videos.get({ id: videoUUID1 })
|
2021-07-15 03:02:54 -05:00
|
|
|
expect(video.likes).to.equal(2)
|
|
|
|
expect(video.dislikes).to.equal(0)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Did not update rates of a remote video
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await servers[0].videos.get({ id: videoUUID2 })
|
2021-07-15 03:02:54 -05:00
|
|
|
expect(video.likes).to.equal(3)
|
|
|
|
expect(video.dislikes).to.equal(0)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should update rates to dislikes', async function () {
|
|
|
|
this.timeout(20000)
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
for (const uuid of videoUUIDs) {
|
2021-07-16 02:04:35 -05:00
|
|
|
await server.videos.rate({ id: uuid, rating: 'dislike' })
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
for (const uuid of videoUUIDs) {
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await server.videos.get({ id: uuid })
|
2021-07-15 03:02:54 -05:00
|
|
|
expect(video.likes).to.equal(0)
|
|
|
|
expect(video.dislikes).to.equal(3)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should destroy server 3 internal dislikes and correctly clean them', async function () {
|
|
|
|
this.timeout(20000)
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].deleteAll('accountVideoRate')
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
for (const uuid of videoUUIDs) {
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].setVideoField(uuid, 'dislikes', '0')
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
// Updated rates of my video
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await servers[0].videos.get({ id: videoUUID1 })
|
2021-07-15 03:02:54 -05:00
|
|
|
expect(video.likes).to.equal(0)
|
|
|
|
expect(video.dislikes).to.equal(2)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Did not update rates of a remote video
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const video = await servers[0].videos.get({ id: videoUUID2 })
|
2021-07-15 03:02:54 -05:00
|
|
|
expect(video.likes).to.equal(0)
|
|
|
|
expect(video.dislikes).to.equal(3)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should destroy server 3 internal shares and correctly clean them', async function () {
|
|
|
|
this.timeout(20000)
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
const preCount = await sqlCommands[0].getVideoShareCount()
|
2021-02-26 09:26:27 -06:00
|
|
|
expect(preCount).to.equal(6)
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].deleteAll('videoShare')
|
2021-02-26 09:26:27 -06:00
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
// Still 6 because we don't have remote shares on local videos
|
2023-04-21 08:00:01 -05:00
|
|
|
const postCount = await sqlCommands[0].getVideoShareCount()
|
2021-02-26 09:26:27 -06:00
|
|
|
expect(postCount).to.equal(6)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should destroy server 3 internal comments and correctly clean them', async function () {
|
|
|
|
this.timeout(20000)
|
|
|
|
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
|
2021-07-09 07:15:11 -05:00
|
|
|
expect(total).to.equal(3)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[2].deleteAll('videoComment')
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
{
|
2021-07-16 02:04:35 -05:00
|
|
|
const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
|
2021-07-09 07:15:11 -05:00
|
|
|
expect(total).to.equal(2)
|
2021-02-26 09:26:27 -06:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should correctly update rate URLs', async function () {
|
|
|
|
this.timeout(30000)
|
|
|
|
|
|
|
|
async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
|
|
|
|
const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` +
|
|
|
|
`INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${remote} WHERE "accountVideoRate"."url" LIKE '${like}'`
|
2023-04-21 08:00:01 -05:00
|
|
|
const res = await sqlCommands[0].selectQuery<{ url: string }>(query)
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
for (const rate of res) {
|
|
|
|
const matcher = new RegExp(`^${ofServerUrl}/accounts/root/dislikes/\\d+${urlSuffix}$`)
|
|
|
|
expect(rate.url).to.match(matcher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkLocal () {
|
|
|
|
const startsWith = 'http://' + servers[0].host + '%'
|
|
|
|
// On local videos
|
|
|
|
await check(startsWith, servers[0].url, '', 'false')
|
|
|
|
// On remote videos
|
|
|
|
await check(startsWith, servers[0].url, '', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkRemote (suffix: string) {
|
|
|
|
const startsWith = 'http://' + servers[1].host + '%'
|
|
|
|
// On local videos
|
|
|
|
await check(startsWith, servers[1].url, suffix, 'false')
|
|
|
|
// On remote videos, we should not update URLs so no suffix
|
|
|
|
await check(startsWith, servers[1].url, '', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
await checkLocal()
|
|
|
|
await checkRemote('')
|
|
|
|
|
|
|
|
{
|
|
|
|
const query = `UPDATE "accountVideoRate" SET url = url || 'stan'`
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[1].updateQuery(query)
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
}
|
|
|
|
|
|
|
|
await checkLocal()
|
|
|
|
await checkRemote('stan')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should correctly update comment URLs', async function () {
|
|
|
|
this.timeout(30000)
|
|
|
|
|
|
|
|
async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
|
|
|
|
const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` +
|
|
|
|
`INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${remote} WHERE "videoComment"."url" LIKE '${like}'`
|
|
|
|
|
2023-04-21 08:00:01 -05:00
|
|
|
const res = await sqlCommands[0].selectQuery<{ url: string, videoUUID: string }>(query)
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
for (const comment of res) {
|
|
|
|
const matcher = new RegExp(`${ofServerUrl}/videos/watch/${comment.videoUUID}/comments/\\d+${urlSuffix}`)
|
|
|
|
expect(comment.url).to.match(matcher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkLocal () {
|
|
|
|
const startsWith = 'http://' + servers[0].host + '%'
|
|
|
|
// On local videos
|
|
|
|
await check(startsWith, servers[0].url, '', 'false')
|
|
|
|
// On remote videos
|
|
|
|
await check(startsWith, servers[0].url, '', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkRemote (suffix: string) {
|
|
|
|
const startsWith = 'http://' + servers[1].host + '%'
|
|
|
|
// On local videos
|
|
|
|
await check(startsWith, servers[1].url, suffix, 'false')
|
|
|
|
// On remote videos, we should not update URLs so no suffix
|
|
|
|
await check(startsWith, servers[1].url, '', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const query = `UPDATE "videoComment" SET url = url || 'kyle'`
|
2023-04-21 08:00:01 -05:00
|
|
|
await sqlCommands[1].updateQuery(query)
|
2021-02-26 09:26:27 -06:00
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await waitJobs(servers)
|
|
|
|
}
|
|
|
|
|
|
|
|
await checkLocal()
|
|
|
|
await checkRemote('kyle')
|
|
|
|
})
|
|
|
|
|
2021-12-28 04:36:51 -06:00
|
|
|
it('Should remove unavailable remote resources', async function () {
|
|
|
|
this.timeout(240000)
|
|
|
|
|
|
|
|
async function expectNotDeleted () {
|
|
|
|
{
|
|
|
|
const video = await servers[0].videos.get({ id: uuid })
|
|
|
|
|
|
|
|
expect(video.likes).to.equal(3)
|
|
|
|
expect(video.dislikes).to.equal(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const { total } = await servers[0].comments.listThreads({ videoId: uuid })
|
|
|
|
expect(total).to.equal(3)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function expectDeleted () {
|
|
|
|
{
|
|
|
|
const video = await servers[0].videos.get({ id: uuid })
|
|
|
|
|
2021-12-28 04:41:41 -06:00
|
|
|
expect(video.likes).to.equal(2)
|
2021-12-28 04:36:51 -06:00
|
|
|
expect(video.dislikes).to.equal(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2021-12-28 04:41:41 -06:00
|
|
|
const { total } = await servers[0].comments.listThreads({ videoId: uuid })
|
2021-12-28 04:36:51 -06:00
|
|
|
expect(total).to.equal(2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const uuid = (await servers[0].videos.quickUpload({ name: 'server 1 video 2' })).uuid
|
|
|
|
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
await server.videos.rate({ id: uuid, rating: 'like' })
|
|
|
|
await server.comments.createThread({ videoId: uuid, text: 'comment' })
|
|
|
|
}
|
|
|
|
|
|
|
|
await waitJobs(servers)
|
|
|
|
|
|
|
|
await expectNotDeleted()
|
|
|
|
|
|
|
|
await servers[1].kill()
|
|
|
|
|
|
|
|
await wait(5000)
|
|
|
|
await expectNotDeleted()
|
|
|
|
|
2021-12-28 04:41:41 -06:00
|
|
|
let continueWhile = true
|
|
|
|
|
|
|
|
do {
|
|
|
|
try {
|
|
|
|
await expectDeleted()
|
|
|
|
continueWhile = false
|
|
|
|
} catch {
|
|
|
|
}
|
|
|
|
} while (continueWhile)
|
2021-12-28 04:36:51 -06:00
|
|
|
})
|
|
|
|
|
2021-02-26 09:26:27 -06:00
|
|
|
after(async function () {
|
2023-04-21 08:00:01 -05:00
|
|
|
for (const sql of sqlCommands) {
|
|
|
|
await sql.cleanup()
|
|
|
|
}
|
|
|
|
|
2021-02-26 09:26:27 -06:00
|
|
|
await cleanupTests(servers)
|
|
|
|
})
|
|
|
|
})
|