1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
6 import { HttpStatusCode, VideoCreateResult, VideoPrivacy } from '@shared/models'
14 setAccessTokensToServers
15 } from '@shared/server-commands'
17 const expect = chai.expect
19 describe('Test video comments API validator', function () {
20 let pathThread: string
21 let pathComment: string
23 let server: PeerTubeServer
25 let video: VideoCreateResult
27 let userAccessToken: string
28 let userAccessToken2: string
31 let privateCommentId: number
32 let privateVideo: VideoCreateResult
34 // ---------------------------------------------------------------
36 before(async function () {
39 server = await createSingleServer(1)
41 await setAccessTokensToServers([ server ])
44 video = await server.videos.upload({ attributes: {} })
45 pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
49 privateVideo = await server.videos.upload({ attributes: { privacy: VideoPrivacy.PRIVATE } })
53 const created = await server.comments.createThread({ videoId: video.uuid, text: 'coucou' })
54 commentId = created.id
55 pathComment = '/api/v1/videos/' + video.uuid + '/comments/' + commentId
59 const created = await server.comments.createThread({ videoId: privateVideo.uuid, text: 'coucou' })
60 privateCommentId = created.id
64 const user = { username: 'user1', password: 'my super password' }
65 await server.users.create({ username: user.username, password: user.password })
66 userAccessToken = await server.login.getAccessToken(user)
70 const user = { username: 'user2', password: 'my super password' }
71 await server.users.create({ username: user.username, password: user.password })
72 userAccessToken2 = await server.login.getAccessToken(user)
76 describe('When listing video comment threads', function () {
77 it('Should fail with a bad start pagination', async function () {
78 await checkBadStartPagination(server.url, pathThread, server.accessToken)
81 it('Should fail with a bad count pagination', async function () {
82 await checkBadCountPagination(server.url, pathThread, server.accessToken)
85 it('Should fail with an incorrect sort', async function () {
86 await checkBadSortPagination(server.url, pathThread, server.accessToken)
89 it('Should fail with an incorrect video', async function () {
90 await makeGetRequest({
92 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads',
93 expectedStatus: HttpStatusCode.NOT_FOUND_404
97 it('Should fail with a private video without token', async function () {
98 await makeGetRequest({
100 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
101 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
105 it('Should fail with another user token', async function () {
106 await makeGetRequest({
108 token: userAccessToken,
109 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
110 expectedStatus: HttpStatusCode.FORBIDDEN_403
114 it('Should succeed with the correct params', async function () {
115 await makeGetRequest({
117 token: server.accessToken,
118 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
119 expectedStatus: HttpStatusCode.OK_200
124 describe('When listing comments of a thread', function () {
125 it('Should fail with an incorrect video', async function () {
126 await makeGetRequest({
128 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads/' + commentId,
129 expectedStatus: HttpStatusCode.NOT_FOUND_404
133 it('Should fail with an incorrect thread id', async function () {
134 await makeGetRequest({
136 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/156',
137 expectedStatus: HttpStatusCode.NOT_FOUND_404
141 it('Should fail with a private video without token', async function () {
142 await makeGetRequest({
144 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
145 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
149 it('Should fail with another user token', async function () {
150 await makeGetRequest({
152 token: userAccessToken,
153 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
154 expectedStatus: HttpStatusCode.FORBIDDEN_403
158 it('Should success with the correct params', async function () {
159 await makeGetRequest({
161 token: server.accessToken,
162 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
163 expectedStatus: HttpStatusCode.OK_200
166 await makeGetRequest({
168 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/' + commentId,
169 expectedStatus: HttpStatusCode.OK_200
174 describe('When adding a video thread', function () {
176 it('Should fail with a non authenticated user', async function () {
180 await makePostBodyRequest({
185 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
189 it('Should fail with nothing', async function () {
191 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
194 it('Should fail with a short comment', async function () {
198 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
201 it('Should fail with a long comment', async function () {
203 text: 'h'.repeat(10001)
205 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
208 it('Should fail with an incorrect video', async function () {
209 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads'
210 const fields = { text: 'super comment' }
212 await makePostBodyRequest({
215 token: server.accessToken,
217 expectedStatus: HttpStatusCode.NOT_FOUND_404
221 it('Should fail with a private video of another user', async function () {
222 const fields = { text: 'super comment' }
224 await makePostBodyRequest({
226 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
227 token: userAccessToken,
229 expectedStatus: HttpStatusCode.FORBIDDEN_403
233 it('Should succeed with the correct parameters', async function () {
234 const fields = { text: 'super comment' }
236 await makePostBodyRequest({
239 token: server.accessToken,
241 expectedStatus: HttpStatusCode.OK_200
246 describe('When adding a comment to a thread', function () {
248 it('Should fail with a non authenticated user', async function () {
252 await makePostBodyRequest({
257 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
261 it('Should fail with nothing', async function () {
263 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
266 it('Should fail with a short comment', async function () {
270 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
273 it('Should fail with a long comment', async function () {
275 text: 'h'.repeat(10001)
277 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
280 it('Should fail with an incorrect video', async function () {
281 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comments/' + commentId
283 text: 'super comment'
285 await makePostBodyRequest({
288 token: server.accessToken,
290 expectedStatus: HttpStatusCode.NOT_FOUND_404
294 it('Should fail with a private video of another user', async function () {
295 const fields = { text: 'super comment' }
297 await makePostBodyRequest({
299 path: '/api/v1/videos/' + privateVideo.uuid + '/comments/' + privateCommentId,
300 token: userAccessToken,
302 expectedStatus: HttpStatusCode.FORBIDDEN_403
306 it('Should fail with an incorrect comment', async function () {
307 const path = '/api/v1/videos/' + video.uuid + '/comments/124'
309 text: 'super comment'
311 await makePostBodyRequest({
314 token: server.accessToken,
316 expectedStatus: HttpStatusCode.NOT_FOUND_404
320 it('Should succeed with the correct parameters', async function () {
322 text: 'super comment'
324 await makePostBodyRequest({
327 token: server.accessToken,
329 expectedStatus: HttpStatusCode.OK_200
334 describe('When removing video comments', function () {
335 it('Should fail with a non authenticated user', async function () {
336 await makeDeleteRequest({ url: server.url, path: pathComment, token: 'none', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
339 it('Should fail with another user', async function () {
340 await makeDeleteRequest({
343 token: userAccessToken,
344 expectedStatus: HttpStatusCode.FORBIDDEN_403
348 it('Should fail with an incorrect video', async function () {
349 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comments/' + commentId
350 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
353 it('Should fail with an incorrect comment', async function () {
354 const path = '/api/v1/videos/' + video.uuid + '/comments/124'
355 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
358 it('Should succeed with the same user', async function () {
359 let commentToDelete: number
362 const created = await server.comments.createThread({ videoId: video.uuid, token: userAccessToken, text: 'hello' })
363 commentToDelete = created.id
366 const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete
368 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
369 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
372 it('Should succeed with the owner of the video', async function () {
373 let commentToDelete: number
374 let anotherVideoUUID: string
377 const { uuid } = await server.videos.upload({ token: userAccessToken, attributes: { name: 'video' } })
378 anotherVideoUUID = uuid
382 const created = await server.comments.createThread({ videoId: anotherVideoUUID, text: 'hello' })
383 commentToDelete = created.id
386 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
388 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
389 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
392 it('Should succeed with the correct parameters', async function () {
393 await makeDeleteRequest({
396 token: server.accessToken,
397 expectedStatus: HttpStatusCode.NO_CONTENT_204
402 describe('When a video has comments disabled', function () {
403 before(async function () {
404 video = await server.videos.upload({ attributes: { commentsEnabled: false } })
405 pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
408 it('Should return an empty thread list', async function () {
409 const res = await makeGetRequest({
412 expectedStatus: HttpStatusCode.OK_200
414 expect(res.body.total).to.equal(0)
415 expect(res.body.data).to.have.lengthOf(0)
418 it('Should return an thread comments list')
420 it('Should return conflict on thread add', async function () {
422 text: 'super comment'
424 await makePostBodyRequest({
427 token: server.accessToken,
429 expectedStatus: HttpStatusCode.CONFLICT_409
433 it('Should return conflict on comment thread add')
436 describe('When listing admin comments threads', function () {
437 const path = '/api/v1/videos/comments'
439 it('Should fail with a bad start pagination', async function () {
440 await checkBadStartPagination(server.url, path, server.accessToken)
443 it('Should fail with a bad count pagination', async function () {
444 await checkBadCountPagination(server.url, path, server.accessToken)
447 it('Should fail with an incorrect sort', async function () {
448 await checkBadSortPagination(server.url, path, server.accessToken)
451 it('Should fail with a non authenticated user', async function () {
452 await makeGetRequest({
455 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
459 it('Should fail with a non admin user', async function () {
460 await makeGetRequest({
463 token: userAccessToken,
464 expectedStatus: HttpStatusCode.FORBIDDEN_403
468 it('Should succeed with the correct params', async function () {
469 await makeGetRequest({
472 token: server.accessToken,
476 searchAccount: 'toto',
479 expectedStatus: HttpStatusCode.OK_200
484 after(async function () {
485 await cleanupTests([ server ])