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