]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/check-params/video-comments.ts
55019884487824479dfccc4327131e1a0ae7fbc9
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / video-comments.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import { expect } from 'chai'
4 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
5 import { HttpStatusCode, VideoCreateResult, VideoPrivacy } from '@shared/models'
6 import {
7 cleanupTests,
8 createSingleServer,
9 makeDeleteRequest,
10 makeGetRequest,
11 makePostBodyRequest,
12 PeerTubeServer,
13 setAccessTokensToServers
14 } from '@shared/server-commands'
15
16 describe('Test video comments API validator', function () {
17 let pathThread: string
18 let pathComment: string
19
20 let server: PeerTubeServer
21
22 let video: VideoCreateResult
23
24 let userAccessToken: string
25 let userAccessToken2: string
26
27 let commentId: number
28 let privateCommentId: number
29 let privateVideo: VideoCreateResult
30
31 // ---------------------------------------------------------------
32
33 before(async function () {
34 this.timeout(30000)
35
36 server = await createSingleServer(1)
37
38 await setAccessTokensToServers([ server ])
39
40 {
41 video = await server.videos.upload({ attributes: {} })
42 pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
43 }
44
45 {
46 privateVideo = await server.videos.upload({ attributes: { privacy: VideoPrivacy.PRIVATE } })
47 }
48
49 {
50 const created = await server.comments.createThread({ videoId: video.uuid, text: 'coucou' })
51 commentId = created.id
52 pathComment = '/api/v1/videos/' + video.uuid + '/comments/' + commentId
53 }
54
55 {
56 const created = await server.comments.createThread({ videoId: privateVideo.uuid, text: 'coucou' })
57 privateCommentId = created.id
58 }
59
60 {
61 const user = { username: 'user1', password: 'my super password' }
62 await server.users.create({ username: user.username, password: user.password })
63 userAccessToken = await server.login.getAccessToken(user)
64 }
65
66 {
67 const user = { username: 'user2', password: 'my super password' }
68 await server.users.create({ username: user.username, password: user.password })
69 userAccessToken2 = await server.login.getAccessToken(user)
70 }
71 })
72
73 describe('When listing video comment threads', function () {
74 it('Should fail with a bad start pagination', async function () {
75 await checkBadStartPagination(server.url, pathThread, server.accessToken)
76 })
77
78 it('Should fail with a bad count pagination', async function () {
79 await checkBadCountPagination(server.url, pathThread, server.accessToken)
80 })
81
82 it('Should fail with an incorrect sort', async function () {
83 await checkBadSortPagination(server.url, pathThread, server.accessToken)
84 })
85
86 it('Should fail with an incorrect video', async function () {
87 await makeGetRequest({
88 url: server.url,
89 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads',
90 expectedStatus: HttpStatusCode.NOT_FOUND_404
91 })
92 })
93
94 it('Should fail with a private video without token', async function () {
95 await makeGetRequest({
96 url: server.url,
97 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
98 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
99 })
100 })
101
102 it('Should fail with another user token', async function () {
103 await makeGetRequest({
104 url: server.url,
105 token: userAccessToken,
106 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
107 expectedStatus: HttpStatusCode.FORBIDDEN_403
108 })
109 })
110
111 it('Should succeed with the correct params', async function () {
112 await makeGetRequest({
113 url: server.url,
114 token: server.accessToken,
115 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
116 expectedStatus: HttpStatusCode.OK_200
117 })
118 })
119 })
120
121 describe('When listing comments of a thread', function () {
122 it('Should fail with an incorrect video', async function () {
123 await makeGetRequest({
124 url: server.url,
125 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads/' + commentId,
126 expectedStatus: HttpStatusCode.NOT_FOUND_404
127 })
128 })
129
130 it('Should fail with an incorrect thread id', async function () {
131 await makeGetRequest({
132 url: server.url,
133 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/156',
134 expectedStatus: HttpStatusCode.NOT_FOUND_404
135 })
136 })
137
138 it('Should fail with a private video without token', async function () {
139 await makeGetRequest({
140 url: server.url,
141 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
142 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
143 })
144 })
145
146 it('Should fail with another user token', async function () {
147 await makeGetRequest({
148 url: server.url,
149 token: userAccessToken,
150 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
151 expectedStatus: HttpStatusCode.FORBIDDEN_403
152 })
153 })
154
155 it('Should success with the correct params', async function () {
156 await makeGetRequest({
157 url: server.url,
158 token: server.accessToken,
159 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
160 expectedStatus: HttpStatusCode.OK_200
161 })
162
163 await makeGetRequest({
164 url: server.url,
165 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/' + commentId,
166 expectedStatus: HttpStatusCode.OK_200
167 })
168 })
169 })
170
171 describe('When adding a video thread', function () {
172
173 it('Should fail with a non authenticated user', async function () {
174 const fields = {
175 text: 'text'
176 }
177 await makePostBodyRequest({
178 url: server.url,
179 path: pathThread,
180 token: 'none',
181 fields,
182 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
183 })
184 })
185
186 it('Should fail with nothing', async function () {
187 const fields = {}
188 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
189 })
190
191 it('Should fail with a short comment', async function () {
192 const fields = {
193 text: ''
194 }
195 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
196 })
197
198 it('Should fail with a long comment', async function () {
199 const fields = {
200 text: 'h'.repeat(10001)
201 }
202 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
203 })
204
205 it('Should fail with an incorrect video', async function () {
206 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads'
207 const fields = { text: 'super comment' }
208
209 await makePostBodyRequest({
210 url: server.url,
211 path,
212 token: server.accessToken,
213 fields,
214 expectedStatus: HttpStatusCode.NOT_FOUND_404
215 })
216 })
217
218 it('Should fail with a private video of another user', async function () {
219 const fields = { text: 'super comment' }
220
221 await makePostBodyRequest({
222 url: server.url,
223 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
224 token: userAccessToken,
225 fields,
226 expectedStatus: HttpStatusCode.FORBIDDEN_403
227 })
228 })
229
230 it('Should succeed with the correct parameters', async function () {
231 const fields = { text: 'super comment' }
232
233 await makePostBodyRequest({
234 url: server.url,
235 path: pathThread,
236 token: server.accessToken,
237 fields,
238 expectedStatus: HttpStatusCode.OK_200
239 })
240 })
241 })
242
243 describe('When adding a comment to a thread', function () {
244
245 it('Should fail with a non authenticated user', async function () {
246 const fields = {
247 text: 'text'
248 }
249 await makePostBodyRequest({
250 url: server.url,
251 path: pathComment,
252 token: 'none',
253 fields,
254 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
255 })
256 })
257
258 it('Should fail with nothing', async function () {
259 const fields = {}
260 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
261 })
262
263 it('Should fail with a short comment', async function () {
264 const fields = {
265 text: ''
266 }
267 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
268 })
269
270 it('Should fail with a long comment', async function () {
271 const fields = {
272 text: 'h'.repeat(10001)
273 }
274 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
275 })
276
277 it('Should fail with an incorrect video', async function () {
278 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comments/' + commentId
279 const fields = {
280 text: 'super comment'
281 }
282 await makePostBodyRequest({
283 url: server.url,
284 path,
285 token: server.accessToken,
286 fields,
287 expectedStatus: HttpStatusCode.NOT_FOUND_404
288 })
289 })
290
291 it('Should fail with a private video of another user', async function () {
292 const fields = { text: 'super comment' }
293
294 await makePostBodyRequest({
295 url: server.url,
296 path: '/api/v1/videos/' + privateVideo.uuid + '/comments/' + privateCommentId,
297 token: userAccessToken,
298 fields,
299 expectedStatus: HttpStatusCode.FORBIDDEN_403
300 })
301 })
302
303 it('Should fail with an incorrect comment', async function () {
304 const path = '/api/v1/videos/' + video.uuid + '/comments/124'
305 const fields = {
306 text: 'super comment'
307 }
308 await makePostBodyRequest({
309 url: server.url,
310 path,
311 token: server.accessToken,
312 fields,
313 expectedStatus: HttpStatusCode.NOT_FOUND_404
314 })
315 })
316
317 it('Should succeed with the correct parameters', async function () {
318 const fields = {
319 text: 'super comment'
320 }
321 await makePostBodyRequest({
322 url: server.url,
323 path: pathComment,
324 token: server.accessToken,
325 fields,
326 expectedStatus: HttpStatusCode.OK_200
327 })
328 })
329 })
330
331 describe('When removing video comments', function () {
332 it('Should fail with a non authenticated user', async function () {
333 await makeDeleteRequest({ url: server.url, path: pathComment, token: 'none', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
334 })
335
336 it('Should fail with another user', async function () {
337 await makeDeleteRequest({
338 url: server.url,
339 path: pathComment,
340 token: userAccessToken,
341 expectedStatus: HttpStatusCode.FORBIDDEN_403
342 })
343 })
344
345 it('Should fail with an incorrect video', async function () {
346 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comments/' + commentId
347 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
348 })
349
350 it('Should fail with an incorrect comment', async function () {
351 const path = '/api/v1/videos/' + video.uuid + '/comments/124'
352 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
353 })
354
355 it('Should succeed with the same user', async function () {
356 let commentToDelete: number
357
358 {
359 const created = await server.comments.createThread({ videoId: video.uuid, token: userAccessToken, text: 'hello' })
360 commentToDelete = created.id
361 }
362
363 const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete
364
365 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
366 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
367 })
368
369 it('Should succeed with the owner of the video', async function () {
370 let commentToDelete: number
371 let anotherVideoUUID: string
372
373 {
374 const { uuid } = await server.videos.upload({ token: userAccessToken, attributes: { name: 'video' } })
375 anotherVideoUUID = uuid
376 }
377
378 {
379 const created = await server.comments.createThread({ videoId: anotherVideoUUID, text: 'hello' })
380 commentToDelete = created.id
381 }
382
383 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
384
385 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
386 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
387 })
388
389 it('Should succeed with the correct parameters', async function () {
390 await makeDeleteRequest({
391 url: server.url,
392 path: pathComment,
393 token: server.accessToken,
394 expectedStatus: HttpStatusCode.NO_CONTENT_204
395 })
396 })
397 })
398
399 describe('When a video has comments disabled', function () {
400 before(async function () {
401 video = await server.videos.upload({ attributes: { commentsEnabled: false } })
402 pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
403 })
404
405 it('Should return an empty thread list', async function () {
406 const res = await makeGetRequest({
407 url: server.url,
408 path: pathThread,
409 expectedStatus: HttpStatusCode.OK_200
410 })
411 expect(res.body.total).to.equal(0)
412 expect(res.body.data).to.have.lengthOf(0)
413 })
414
415 it('Should return an thread comments list')
416
417 it('Should return conflict on thread add', async function () {
418 const fields = {
419 text: 'super comment'
420 }
421 await makePostBodyRequest({
422 url: server.url,
423 path: pathThread,
424 token: server.accessToken,
425 fields,
426 expectedStatus: HttpStatusCode.CONFLICT_409
427 })
428 })
429
430 it('Should return conflict on comment thread add')
431 })
432
433 describe('When listing admin comments threads', function () {
434 const path = '/api/v1/videos/comments'
435
436 it('Should fail with a bad start pagination', async function () {
437 await checkBadStartPagination(server.url, path, server.accessToken)
438 })
439
440 it('Should fail with a bad count pagination', async function () {
441 await checkBadCountPagination(server.url, path, server.accessToken)
442 })
443
444 it('Should fail with an incorrect sort', async function () {
445 await checkBadSortPagination(server.url, path, server.accessToken)
446 })
447
448 it('Should fail with a non authenticated user', async function () {
449 await makeGetRequest({
450 url: server.url,
451 path,
452 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
453 })
454 })
455
456 it('Should fail with a non admin user', async function () {
457 await makeGetRequest({
458 url: server.url,
459 path,
460 token: userAccessToken,
461 expectedStatus: HttpStatusCode.FORBIDDEN_403
462 })
463 })
464
465 it('Should succeed with the correct params', async function () {
466 await makeGetRequest({
467 url: server.url,
468 path,
469 token: server.accessToken,
470 query: {
471 isLocal: false,
472 search: 'toto',
473 searchAccount: 'toto',
474 searchVideo: 'toto'
475 },
476 expectedStatus: HttpStatusCode.OK_200
477 })
478 })
479 })
480
481 after(async function () {
482 await cleanupTests([ server ])
483 })
484 })