1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { expect } from 'chai'
4 import { wait } from '@shared/core-utils'
10 setAccessTokensToServers,
12 } from '@shared/server-commands'
14 describe('Test AP cleaner', function () {
15 let servers: PeerTubeServer[] = []
16 let videoUUID1: string
17 let videoUUID2: string
18 let videoUUID3: string
20 let videoUUIDs: string[]
22 before(async function () {
27 videos: { cleanup_remote_interactions: true }
30 servers = await createMultipleServers(3, config)
32 // Get the access tokens
33 await setAccessTokensToServers(servers)
36 doubleFollow(servers[0], servers[1]),
37 doubleFollow(servers[1], servers[2]),
38 doubleFollow(servers[0], servers[2])
41 // Update 1 local share, check 6 shares
43 // Create 1 comment per video
44 // Update 1 remote URL and 1 local URL on
46 videoUUID1 = (await servers[0].videos.quickUpload({ name: 'server 1' })).uuid
47 videoUUID2 = (await servers[1].videos.quickUpload({ name: 'server 2' })).uuid
48 videoUUID3 = (await servers[2].videos.quickUpload({ name: 'server 3' })).uuid
50 videoUUIDs = [ videoUUID1, videoUUID2, videoUUID3 ]
52 await waitJobs(servers)
54 for (const server of servers) {
55 for (const uuid of videoUUIDs) {
56 await server.videos.rate({ id: uuid, rating: 'like' })
57 await server.comments.createThread({ videoId: uuid, text: 'comment' })
61 await waitJobs(servers)
64 it('Should have the correct likes', async function () {
65 for (const server of servers) {
66 for (const uuid of videoUUIDs) {
67 const video = await server.videos.get({ id: uuid })
69 expect(video.likes).to.equal(3)
70 expect(video.dislikes).to.equal(0)
75 it('Should destroy server 3 internal likes and correctly clean them', async function () {
78 await servers[2].sql.deleteAll('accountVideoRate')
79 for (const uuid of videoUUIDs) {
80 await servers[2].sql.setVideoField(uuid, 'likes', '0')
84 await waitJobs(servers)
86 // Updated rates of my video
88 const video = await servers[0].videos.get({ id: videoUUID1 })
89 expect(video.likes).to.equal(2)
90 expect(video.dislikes).to.equal(0)
93 // Did not update rates of a remote video
95 const video = await servers[0].videos.get({ id: videoUUID2 })
96 expect(video.likes).to.equal(3)
97 expect(video.dislikes).to.equal(0)
101 it('Should update rates to dislikes', async function () {
104 for (const server of servers) {
105 for (const uuid of videoUUIDs) {
106 await server.videos.rate({ id: uuid, rating: 'dislike' })
110 await waitJobs(servers)
112 for (const server of servers) {
113 for (const uuid of videoUUIDs) {
114 const video = await server.videos.get({ id: uuid })
115 expect(video.likes).to.equal(0)
116 expect(video.dislikes).to.equal(3)
121 it('Should destroy server 3 internal dislikes and correctly clean them', async function () {
124 await servers[2].sql.deleteAll('accountVideoRate')
126 for (const uuid of videoUUIDs) {
127 await servers[2].sql.setVideoField(uuid, 'dislikes', '0')
131 await waitJobs(servers)
133 // Updated rates of my video
135 const video = await servers[0].videos.get({ id: videoUUID1 })
136 expect(video.likes).to.equal(0)
137 expect(video.dislikes).to.equal(2)
140 // Did not update rates of a remote video
142 const video = await servers[0].videos.get({ id: videoUUID2 })
143 expect(video.likes).to.equal(0)
144 expect(video.dislikes).to.equal(3)
148 it('Should destroy server 3 internal shares and correctly clean them', async function () {
151 const preCount = await servers[0].sql.getVideoShareCount()
152 expect(preCount).to.equal(6)
154 await servers[2].sql.deleteAll('videoShare')
156 await waitJobs(servers)
158 // Still 6 because we don't have remote shares on local videos
159 const postCount = await servers[0].sql.getVideoShareCount()
160 expect(postCount).to.equal(6)
163 it('Should destroy server 3 internal comments and correctly clean them', async function () {
167 const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
168 expect(total).to.equal(3)
171 await servers[2].sql.deleteAll('videoComment')
174 await waitJobs(servers)
177 const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
178 expect(total).to.equal(2)
182 it('Should correctly update rate URLs', async function () {
185 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
186 const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` +
187 `INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${remote} WHERE "accountVideoRate"."url" LIKE '${like}'`
188 const res = await servers[0].sql.selectQuery<{ url: string }>(query)
190 for (const rate of res) {
191 const matcher = new RegExp(`^${ofServerUrl}/accounts/root/dislikes/\\d+${urlSuffix}$`)
192 expect(rate.url).to.match(matcher)
196 async function checkLocal () {
197 const startsWith = 'http://' + servers[0].host + '%'
199 await check(startsWith, servers[0].url, '', 'false')
201 await check(startsWith, servers[0].url, '', 'true')
204 async function checkRemote (suffix: string) {
205 const startsWith = 'http://' + servers[1].host + '%'
207 await check(startsWith, servers[1].url, suffix, 'false')
208 // On remote videos, we should not update URLs so no suffix
209 await check(startsWith, servers[1].url, '', 'true')
213 await checkRemote('')
216 const query = `UPDATE "accountVideoRate" SET url = url || 'stan'`
217 await servers[1].sql.updateQuery(query)
220 await waitJobs(servers)
224 await checkRemote('stan')
227 it('Should correctly update comment URLs', async function () {
230 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
231 const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` +
232 `INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${remote} WHERE "videoComment"."url" LIKE '${like}'`
234 const res = await servers[0].sql.selectQuery<{ url: string, videoUUID: string }>(query)
236 for (const comment of res) {
237 const matcher = new RegExp(`${ofServerUrl}/videos/watch/${comment.videoUUID}/comments/\\d+${urlSuffix}`)
238 expect(comment.url).to.match(matcher)
242 async function checkLocal () {
243 const startsWith = 'http://' + servers[0].host + '%'
245 await check(startsWith, servers[0].url, '', 'false')
247 await check(startsWith, servers[0].url, '', 'true')
250 async function checkRemote (suffix: string) {
251 const startsWith = 'http://' + servers[1].host + '%'
253 await check(startsWith, servers[1].url, suffix, 'false')
254 // On remote videos, we should not update URLs so no suffix
255 await check(startsWith, servers[1].url, '', 'true')
259 const query = `UPDATE "videoComment" SET url = url || 'kyle'`
260 await servers[1].sql.updateQuery(query)
263 await waitJobs(servers)
267 await checkRemote('kyle')
270 it('Should remove unavailable remote resources', async function () {
273 async function expectNotDeleted () {
275 const video = await servers[0].videos.get({ id: uuid })
277 expect(video.likes).to.equal(3)
278 expect(video.dislikes).to.equal(0)
282 const { total } = await servers[0].comments.listThreads({ videoId: uuid })
283 expect(total).to.equal(3)
287 async function expectDeleted () {
289 const video = await servers[0].videos.get({ id: uuid })
291 expect(video.likes).to.equal(2)
292 expect(video.dislikes).to.equal(0)
296 const { total } = await servers[0].comments.listThreads({ videoId: uuid })
297 expect(total).to.equal(2)
301 const uuid = (await servers[0].videos.quickUpload({ name: 'server 1 video 2' })).uuid
303 await waitJobs(servers)
305 for (const server of servers) {
306 await server.videos.rate({ id: uuid, rating: 'like' })
307 await server.comments.createThread({ videoId: uuid, text: 'comment' })
310 await waitJobs(servers)
312 await expectNotDeleted()
314 await servers[1].kill()
317 await expectNotDeleted()
319 let continueWhile = true
323 await expectDeleted()
324 continueWhile = false
327 } while (continueWhile)
330 after(async function () {
331 await cleanupTests(servers)