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