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