1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import * as chai from 'chai'
4 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
5 import { HttpStatusCode, VideoCreateResult, VideoPrivacy } from '@shared/models'
13 setAccessTokensToServers
14 } from '@shared/server-commands'
16 const expect = chai.expect
18 describe('Test video comments API validator', function () {
19 let pathThread: string
20 let pathComment: string
22 let server: PeerTubeServer
24 let video: VideoCreateResult
26 let userAccessToken: string
27 let userAccessToken2: string
30 let privateCommentId: number
31 let privateVideo: VideoCreateResult
33 // ---------------------------------------------------------------
35 before(async function () {
38 server = await createSingleServer(1)
40 await setAccessTokensToServers([ server ])
43 video = await server.videos.upload({ attributes: {} })
44 pathThread = '/api/v1/videos/' + video.uuid + '/comment-threads'
48 privateVideo = await server.videos.upload({ attributes: { privacy: VideoPrivacy.PRIVATE } })
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
58 const created = await server.comments.createThread({ videoId: privateVideo.uuid, text: 'coucou' })
59 privateCommentId = created.id
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)
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)
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)
80 it('Should fail with a bad count pagination', async function () {
81 await checkBadCountPagination(server.url, pathThread, server.accessToken)
84 it('Should fail with an incorrect sort', async function () {
85 await checkBadSortPagination(server.url, pathThread, server.accessToken)
88 it('Should fail with an incorrect video', async function () {
89 await makeGetRequest({
91 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads',
92 expectedStatus: HttpStatusCode.NOT_FOUND_404
96 it('Should fail with a private video without token', async function () {
97 await makeGetRequest({
99 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
100 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
104 it('Should fail with another user token', async function () {
105 await makeGetRequest({
107 token: userAccessToken,
108 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
109 expectedStatus: HttpStatusCode.FORBIDDEN_403
113 it('Should succeed with the correct params', async function () {
114 await makeGetRequest({
116 token: server.accessToken,
117 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
118 expectedStatus: HttpStatusCode.OK_200
123 describe('When listing comments of a thread', function () {
124 it('Should fail with an incorrect video', async function () {
125 await makeGetRequest({
127 path: '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comment-threads/' + commentId,
128 expectedStatus: HttpStatusCode.NOT_FOUND_404
132 it('Should fail with an incorrect thread id', async function () {
133 await makeGetRequest({
135 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/156',
136 expectedStatus: HttpStatusCode.NOT_FOUND_404
140 it('Should fail with a private video without token', async function () {
141 await makeGetRequest({
143 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
144 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
148 it('Should fail with another user token', async function () {
149 await makeGetRequest({
151 token: userAccessToken,
152 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
153 expectedStatus: HttpStatusCode.FORBIDDEN_403
157 it('Should success with the correct params', async function () {
158 await makeGetRequest({
160 token: server.accessToken,
161 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads/' + privateCommentId,
162 expectedStatus: HttpStatusCode.OK_200
165 await makeGetRequest({
167 path: '/api/v1/videos/' + video.shortUUID + '/comment-threads/' + commentId,
168 expectedStatus: HttpStatusCode.OK_200
173 describe('When adding a video thread', function () {
175 it('Should fail with a non authenticated user', async function () {
179 await makePostBodyRequest({
184 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
188 it('Should fail with nothing', async function () {
190 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
193 it('Should fail with a short comment', async function () {
197 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
200 it('Should fail with a long comment', async function () {
202 text: 'h'.repeat(10001)
204 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
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' }
211 await makePostBodyRequest({
214 token: server.accessToken,
216 expectedStatus: HttpStatusCode.NOT_FOUND_404
220 it('Should fail with a private video of another user', async function () {
221 const fields = { text: 'super comment' }
223 await makePostBodyRequest({
225 path: '/api/v1/videos/' + privateVideo.shortUUID + '/comment-threads',
226 token: userAccessToken,
228 expectedStatus: HttpStatusCode.FORBIDDEN_403
232 it('Should succeed with the correct parameters', async function () {
233 const fields = { text: 'super comment' }
235 await makePostBodyRequest({
238 token: server.accessToken,
240 expectedStatus: HttpStatusCode.OK_200
245 describe('When adding a comment to a thread', function () {
247 it('Should fail with a non authenticated user', async function () {
251 await makePostBodyRequest({
256 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
260 it('Should fail with nothing', async function () {
262 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
265 it('Should fail with a short comment', async function () {
269 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
272 it('Should fail with a long comment', async function () {
274 text: 'h'.repeat(10001)
276 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
279 it('Should fail with an incorrect video', async function () {
280 const path = '/api/v1/videos/ba708d62-e3d7-45d9-9d73-41b9097cc02d/comments/' + commentId
282 text: 'super comment'
284 await makePostBodyRequest({
287 token: server.accessToken,
289 expectedStatus: HttpStatusCode.NOT_FOUND_404
293 it('Should fail with a private video of another user', async function () {
294 const fields = { text: 'super comment' }
296 await makePostBodyRequest({
298 path: '/api/v1/videos/' + privateVideo.uuid + '/comments/' + privateCommentId,
299 token: userAccessToken,
301 expectedStatus: HttpStatusCode.FORBIDDEN_403
305 it('Should fail with an incorrect comment', async function () {
306 const path = '/api/v1/videos/' + video.uuid + '/comments/124'
308 text: 'super comment'
310 await makePostBodyRequest({
313 token: server.accessToken,
315 expectedStatus: HttpStatusCode.NOT_FOUND_404
319 it('Should succeed with the correct parameters', async function () {
321 text: 'super comment'
323 await makePostBodyRequest({
326 token: server.accessToken,
328 expectedStatus: HttpStatusCode.OK_200
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 })
338 it('Should fail with another user', async function () {
339 await makeDeleteRequest({
342 token: userAccessToken,
343 expectedStatus: HttpStatusCode.FORBIDDEN_403
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 })
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 })
357 it('Should succeed with the same user', async function () {
358 let commentToDelete: number
361 const created = await server.comments.createThread({ videoId: video.uuid, token: userAccessToken, text: 'hello' })
362 commentToDelete = created.id
365 const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete
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 })
371 it('Should succeed with the owner of the video', async function () {
372 let commentToDelete: number
373 let anotherVideoUUID: string
376 const { uuid } = await server.videos.upload({ token: userAccessToken, attributes: { name: 'video' } })
377 anotherVideoUUID = uuid
381 const created = await server.comments.createThread({ videoId: anotherVideoUUID, text: 'hello' })
382 commentToDelete = created.id
385 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
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 })
391 it('Should succeed with the correct parameters', async function () {
392 await makeDeleteRequest({
395 token: server.accessToken,
396 expectedStatus: HttpStatusCode.NO_CONTENT_204
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'
407 it('Should return an empty thread list', async function () {
408 const res = await makeGetRequest({
411 expectedStatus: HttpStatusCode.OK_200
413 expect(res.body.total).to.equal(0)
414 expect(res.body.data).to.have.lengthOf(0)
417 it('Should return an thread comments list')
419 it('Should return conflict on thread add', async function () {
421 text: 'super comment'
423 await makePostBodyRequest({
426 token: server.accessToken,
428 expectedStatus: HttpStatusCode.CONFLICT_409
432 it('Should return conflict on comment thread add')
435 describe('When listing admin comments threads', function () {
436 const path = '/api/v1/videos/comments'
438 it('Should fail with a bad start pagination', async function () {
439 await checkBadStartPagination(server.url, path, server.accessToken)
442 it('Should fail with a bad count pagination', async function () {
443 await checkBadCountPagination(server.url, path, server.accessToken)
446 it('Should fail with an incorrect sort', async function () {
447 await checkBadSortPagination(server.url, path, server.accessToken)
450 it('Should fail with a non authenticated user', async function () {
451 await makeGetRequest({
454 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
458 it('Should fail with a non admin user', async function () {
459 await makeGetRequest({
462 token: userAccessToken,
463 expectedStatus: HttpStatusCode.FORBIDDEN_403
467 it('Should succeed with the correct params', async function () {
468 await makeGetRequest({
471 token: server.accessToken,
475 searchAccount: 'toto',
478 expectedStatus: HttpStatusCode.OK_200
483 after(async function () {
484 await cleanupTests([ server ])