]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/activitypub/cleaner.ts
Add runner server tests
[github/Chocobozzz/PeerTube.git] / server / tests / api / activitypub / cleaner.ts
CommitLineData
74d249bc
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
86347717 3import { expect } from 'chai'
d102de1b 4import { SQLCommand } from '@server/tests/shared'
c55e3d72 5import { wait } from '@shared/core-utils'
74d249bc
C
6import {
7 cleanupTests,
254d3579 8 createMultipleServers,
4c7e60bc 9 doubleFollow,
254d3579 10 PeerTubeServer,
12edc149 11 setAccessTokensToServers,
12edc149 12 waitJobs
bf54587a 13} from '@shared/server-commands'
74d249bc 14
74d249bc 15describe('Test AP cleaner', function () {
254d3579 16 let servers: PeerTubeServer[] = []
d102de1b
C
17 const sqlCommands: SQLCommand[] = []
18
74d249bc
C
19 let videoUUID1: string
20 let videoUUID2: string
21 let videoUUID3: string
22
23 let videoUUIDs: string[]
24
25 before(async function () {
26 this.timeout(120000)
27
28 const config = {
29 federation: {
30 videos: { cleanup_remote_interactions: true }
31 }
32 }
254d3579 33 servers = await createMultipleServers(3, config)
74d249bc
C
34
35 // Get the access tokens
36 await setAccessTokensToServers(servers)
37
38 await Promise.all([
39 doubleFollow(servers[0], servers[1]),
40 doubleFollow(servers[1], servers[2]),
41 doubleFollow(servers[0], servers[2])
42 ])
43
44 // Update 1 local share, check 6 shares
45
46 // Create 1 comment per video
47 // Update 1 remote URL and 1 local URL on
48
89d241a7
C
49 videoUUID1 = (await servers[0].videos.quickUpload({ name: 'server 1' })).uuid
50 videoUUID2 = (await servers[1].videos.quickUpload({ name: 'server 2' })).uuid
51 videoUUID3 = (await servers[2].videos.quickUpload({ name: 'server 3' })).uuid
74d249bc
C
52
53 videoUUIDs = [ videoUUID1, videoUUID2, videoUUID3 ]
54
55 await waitJobs(servers)
56
57 for (const server of servers) {
58 for (const uuid of videoUUIDs) {
89d241a7
C
59 await server.videos.rate({ id: uuid, rating: 'like' })
60 await server.comments.createThread({ videoId: uuid, text: 'comment' })
74d249bc 61 }
d102de1b
C
62
63 sqlCommands.push(new SQLCommand(server))
74d249bc
C
64 }
65
66 await waitJobs(servers)
67 })
68
69 it('Should have the correct likes', async function () {
70 for (const server of servers) {
71 for (const uuid of videoUUIDs) {
89d241a7 72 const video = await server.videos.get({ id: uuid })
d23dd9fb
C
73
74 expect(video.likes).to.equal(3)
75 expect(video.dislikes).to.equal(0)
74d249bc
C
76 }
77 }
78 })
79
80 it('Should destroy server 3 internal likes and correctly clean them', async function () {
81 this.timeout(20000)
82
d102de1b 83 await sqlCommands[2].deleteAll('accountVideoRate')
74d249bc 84 for (const uuid of videoUUIDs) {
d102de1b 85 await sqlCommands[2].setVideoField(uuid, 'likes', '0')
74d249bc
C
86 }
87
88 await wait(5000)
89 await waitJobs(servers)
90
91 // Updated rates of my video
92 {
89d241a7 93 const video = await servers[0].videos.get({ id: videoUUID1 })
d23dd9fb
C
94 expect(video.likes).to.equal(2)
95 expect(video.dislikes).to.equal(0)
74d249bc
C
96 }
97
98 // Did not update rates of a remote video
99 {
89d241a7 100 const video = await servers[0].videos.get({ id: videoUUID2 })
d23dd9fb
C
101 expect(video.likes).to.equal(3)
102 expect(video.dislikes).to.equal(0)
74d249bc
C
103 }
104 })
105
106 it('Should update rates to dislikes', async function () {
107 this.timeout(20000)
108
109 for (const server of servers) {
110 for (const uuid of videoUUIDs) {
89d241a7 111 await server.videos.rate({ id: uuid, rating: 'dislike' })
74d249bc
C
112 }
113 }
114
115 await waitJobs(servers)
116
117 for (const server of servers) {
118 for (const uuid of videoUUIDs) {
89d241a7 119 const video = await server.videos.get({ id: uuid })
d23dd9fb
C
120 expect(video.likes).to.equal(0)
121 expect(video.dislikes).to.equal(3)
74d249bc
C
122 }
123 }
124 })
125
126 it('Should destroy server 3 internal dislikes and correctly clean them', async function () {
127 this.timeout(20000)
128
d102de1b 129 await sqlCommands[2].deleteAll('accountVideoRate')
74d249bc
C
130
131 for (const uuid of videoUUIDs) {
d102de1b 132 await sqlCommands[2].setVideoField(uuid, 'dislikes', '0')
74d249bc
C
133 }
134
135 await wait(5000)
136 await waitJobs(servers)
137
138 // Updated rates of my video
139 {
89d241a7 140 const video = await servers[0].videos.get({ id: videoUUID1 })
d23dd9fb
C
141 expect(video.likes).to.equal(0)
142 expect(video.dislikes).to.equal(2)
74d249bc
C
143 }
144
145 // Did not update rates of a remote video
146 {
89d241a7 147 const video = await servers[0].videos.get({ id: videoUUID2 })
d23dd9fb
C
148 expect(video.likes).to.equal(0)
149 expect(video.dislikes).to.equal(3)
74d249bc
C
150 }
151 })
152
153 it('Should destroy server 3 internal shares and correctly clean them', async function () {
154 this.timeout(20000)
155
d102de1b 156 const preCount = await sqlCommands[0].getVideoShareCount()
74d249bc
C
157 expect(preCount).to.equal(6)
158
d102de1b 159 await sqlCommands[2].deleteAll('videoShare')
74d249bc
C
160 await wait(5000)
161 await waitJobs(servers)
162
163 // Still 6 because we don't have remote shares on local videos
d102de1b 164 const postCount = await sqlCommands[0].getVideoShareCount()
74d249bc
C
165 expect(postCount).to.equal(6)
166 })
167
168 it('Should destroy server 3 internal comments and correctly clean them', async function () {
169 this.timeout(20000)
170
171 {
89d241a7 172 const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
12edc149 173 expect(total).to.equal(3)
74d249bc
C
174 }
175
d102de1b 176 await sqlCommands[2].deleteAll('videoComment')
74d249bc
C
177
178 await wait(5000)
179 await waitJobs(servers)
180
181 {
89d241a7 182 const { total } = await servers[0].comments.listThreads({ videoId: videoUUID1 })
12edc149 183 expect(total).to.equal(2)
74d249bc
C
184 }
185 })
186
187 it('Should correctly update rate URLs', async function () {
188 this.timeout(30000)
189
190 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
191 const query = `SELECT "videoId", "accountVideoRate".url FROM "accountVideoRate" ` +
192 `INNER JOIN video ON "accountVideoRate"."videoId" = video.id AND remote IS ${remote} WHERE "accountVideoRate"."url" LIKE '${like}'`
d102de1b 193 const res = await sqlCommands[0].selectQuery<{ url: string }>(query)
74d249bc
C
194
195 for (const rate of res) {
196 const matcher = new RegExp(`^${ofServerUrl}/accounts/root/dislikes/\\d+${urlSuffix}$`)
197 expect(rate.url).to.match(matcher)
198 }
199 }
200
201 async function checkLocal () {
202 const startsWith = 'http://' + servers[0].host + '%'
203 // On local videos
204 await check(startsWith, servers[0].url, '', 'false')
205 // On remote videos
206 await check(startsWith, servers[0].url, '', 'true')
207 }
208
209 async function checkRemote (suffix: string) {
210 const startsWith = 'http://' + servers[1].host + '%'
211 // On local videos
212 await check(startsWith, servers[1].url, suffix, 'false')
213 // On remote videos, we should not update URLs so no suffix
214 await check(startsWith, servers[1].url, '', 'true')
215 }
216
217 await checkLocal()
218 await checkRemote('')
219
220 {
221 const query = `UPDATE "accountVideoRate" SET url = url || 'stan'`
d102de1b 222 await sqlCommands[1].updateQuery(query)
74d249bc
C
223
224 await wait(5000)
225 await waitJobs(servers)
226 }
227
228 await checkLocal()
229 await checkRemote('stan')
230 })
231
232 it('Should correctly update comment URLs', async function () {
233 this.timeout(30000)
234
235 async function check (like: string, ofServerUrl: string, urlSuffix: string, remote: 'true' | 'false') {
236 const query = `SELECT "videoId", "videoComment".url, uuid as "videoUUID" FROM "videoComment" ` +
237 `INNER JOIN video ON "videoComment"."videoId" = video.id AND remote IS ${remote} WHERE "videoComment"."url" LIKE '${like}'`
238
d102de1b 239 const res = await sqlCommands[0].selectQuery<{ url: string, videoUUID: string }>(query)
74d249bc
C
240
241 for (const comment of res) {
242 const matcher = new RegExp(`${ofServerUrl}/videos/watch/${comment.videoUUID}/comments/\\d+${urlSuffix}`)
243 expect(comment.url).to.match(matcher)
244 }
245 }
246
247 async function checkLocal () {
248 const startsWith = 'http://' + servers[0].host + '%'
249 // On local videos
250 await check(startsWith, servers[0].url, '', 'false')
251 // On remote videos
252 await check(startsWith, servers[0].url, '', 'true')
253 }
254
255 async function checkRemote (suffix: string) {
256 const startsWith = 'http://' + servers[1].host + '%'
257 // On local videos
258 await check(startsWith, servers[1].url, suffix, 'false')
259 // On remote videos, we should not update URLs so no suffix
260 await check(startsWith, servers[1].url, '', 'true')
261 }
262
263 {
264 const query = `UPDATE "videoComment" SET url = url || 'kyle'`
d102de1b 265 await sqlCommands[1].updateQuery(query)
74d249bc
C
266
267 await wait(5000)
268 await waitJobs(servers)
269 }
270
271 await checkLocal()
272 await checkRemote('kyle')
273 })
274
f1569117
C
275 it('Should remove unavailable remote resources', async function () {
276 this.timeout(240000)
277
278 async function expectNotDeleted () {
279 {
280 const video = await servers[0].videos.get({ id: uuid })
281
282 expect(video.likes).to.equal(3)
283 expect(video.dislikes).to.equal(0)
284 }
285
286 {
287 const { total } = await servers[0].comments.listThreads({ videoId: uuid })
288 expect(total).to.equal(3)
289 }
290 }
291
292 async function expectDeleted () {
293 {
294 const video = await servers[0].videos.get({ id: uuid })
295
10a72a7e 296 expect(video.likes).to.equal(2)
f1569117
C
297 expect(video.dislikes).to.equal(0)
298 }
299
300 {
10a72a7e 301 const { total } = await servers[0].comments.listThreads({ videoId: uuid })
f1569117
C
302 expect(total).to.equal(2)
303 }
304 }
305
306 const uuid = (await servers[0].videos.quickUpload({ name: 'server 1 video 2' })).uuid
307
308 await waitJobs(servers)
309
310 for (const server of servers) {
311 await server.videos.rate({ id: uuid, rating: 'like' })
312 await server.comments.createThread({ videoId: uuid, text: 'comment' })
313 }
314
315 await waitJobs(servers)
316
317 await expectNotDeleted()
318
319 await servers[1].kill()
320
321 await wait(5000)
322 await expectNotDeleted()
323
10a72a7e
C
324 let continueWhile = true
325
326 do {
327 try {
328 await expectDeleted()
329 continueWhile = false
330 } catch {
331 }
332 } while (continueWhile)
f1569117
C
333 })
334
74d249bc 335 after(async function () {
d102de1b
C
336 for (const sql of sqlCommands) {
337 await sql.cleanup()
338 }
339
74d249bc 340 await cleanupTests(servers)
74d249bc
C
341 })
342})