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