abuses.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
  2. import 'mocha'
  3. import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
  4. import { AbuseCreate, AbuseState, HttpStatusCode } from '@shared/models'
  5. import {
  6. AbusesCommand,
  7. cleanupTests,
  8. createSingleServer,
  9. doubleFollow,
  10. makeGetRequest,
  11. makePostBodyRequest,
  12. PeerTubeServer,
  13. setAccessTokensToServers,
  14. waitJobs
  15. } from '@shared/server-commands'
  16. describe('Test abuses API validators', function () {
  17. const basePath = '/api/v1/abuses/'
  18. let server: PeerTubeServer
  19. let userToken = ''
  20. let userToken2 = ''
  21. let abuseId: number
  22. let messageId: number
  23. let command: AbusesCommand
  24. // ---------------------------------------------------------------
  25. before(async function () {
  26. this.timeout(30000)
  27. server = await createSingleServer(1)
  28. await setAccessTokensToServers([ server ])
  29. userToken = await server.users.generateUserAndToken('user_1')
  30. userToken2 = await server.users.generateUserAndToken('user_2')
  31. server.store.videoCreated = await server.videos.upload()
  32. command = server.abuses
  33. })
  34. describe('When listing abuses for admins', function () {
  35. const path = basePath
  36. it('Should fail with a bad start pagination', async function () {
  37. await checkBadStartPagination(server.url, path, server.accessToken)
  38. })
  39. it('Should fail with a bad count pagination', async function () {
  40. await checkBadCountPagination(server.url, path, server.accessToken)
  41. })
  42. it('Should fail with an incorrect sort', async function () {
  43. await checkBadSortPagination(server.url, path, server.accessToken)
  44. })
  45. it('Should fail with a non authenticated user', async function () {
  46. await makeGetRequest({
  47. url: server.url,
  48. path,
  49. expectedStatus: HttpStatusCode.UNAUTHORIZED_401
  50. })
  51. })
  52. it('Should fail with a non admin user', async function () {
  53. await makeGetRequest({
  54. url: server.url,
  55. path,
  56. token: userToken,
  57. expectedStatus: HttpStatusCode.FORBIDDEN_403
  58. })
  59. })
  60. it('Should fail with a bad id filter', async function () {
  61. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { id: 'toto' } })
  62. })
  63. it('Should fail with a bad filter', async function () {
  64. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { filter: 'toto' } })
  65. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { filter: 'videos' } })
  66. })
  67. it('Should fail with bad predefined reason', async function () {
  68. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { predefinedReason: 'violentOrRepulsives' } })
  69. })
  70. it('Should fail with a bad state filter', async function () {
  71. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { state: 'toto' } })
  72. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { state: 0 } })
  73. })
  74. it('Should fail with a bad videoIs filter', async function () {
  75. await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { videoIs: 'toto' } })
  76. })
  77. it('Should succeed with the correct params', async function () {
  78. const query = {
  79. id: 13,
  80. predefinedReason: 'violentOrRepulsive',
  81. filter: 'comment',
  82. state: 2,
  83. videoIs: 'deleted'
  84. }
  85. await makeGetRequest({ url: server.url, path, token: server.accessToken, query, expectedStatus: HttpStatusCode.OK_200 })
  86. })
  87. })
  88. describe('When listing abuses for users', function () {
  89. const path = '/api/v1/users/me/abuses'
  90. it('Should fail with a bad start pagination', async function () {
  91. await checkBadStartPagination(server.url, path, userToken)
  92. })
  93. it('Should fail with a bad count pagination', async function () {
  94. await checkBadCountPagination(server.url, path, userToken)
  95. })
  96. it('Should fail with an incorrect sort', async function () {
  97. await checkBadSortPagination(server.url, path, userToken)
  98. })
  99. it('Should fail with a non authenticated user', async function () {
  100. await makeGetRequest({
  101. url: server.url,
  102. path,
  103. expectedStatus: HttpStatusCode.UNAUTHORIZED_401
  104. })
  105. })
  106. it('Should fail with a bad id filter', async function () {
  107. await makeGetRequest({ url: server.url, path, token: userToken, query: { id: 'toto' } })
  108. })
  109. it('Should fail with a bad state filter', async function () {
  110. await makeGetRequest({ url: server.url, path, token: userToken, query: { state: 'toto' } })
  111. await makeGetRequest({ url: server.url, path, token: userToken, query: { state: 0 } })
  112. })
  113. it('Should succeed with the correct params', async function () {
  114. const query = {
  115. id: 13,
  116. state: 2
  117. }
  118. await makeGetRequest({ url: server.url, path, token: userToken, query, expectedStatus: HttpStatusCode.OK_200 })
  119. })
  120. })
  121. describe('When reporting an abuse', function () {
  122. const path = basePath
  123. it('Should fail with nothing', async function () {
  124. const fields = {}
  125. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  126. })
  127. it('Should fail with a wrong video', async function () {
  128. const fields = { video: { id: 'blabla' }, reason: 'my super reason' }
  129. await makePostBodyRequest({ url: server.url, path: path, token: userToken, fields })
  130. })
  131. it('Should fail with an unknown video', async function () {
  132. const fields = { video: { id: 42 }, reason: 'my super reason' }
  133. await makePostBodyRequest({
  134. url: server.url,
  135. path,
  136. token: userToken,
  137. fields,
  138. expectedStatus: HttpStatusCode.NOT_FOUND_404
  139. })
  140. })
  141. it('Should fail with a wrong comment', async function () {
  142. const fields = { comment: { id: 'blabla' }, reason: 'my super reason' }
  143. await makePostBodyRequest({ url: server.url, path: path, token: userToken, fields })
  144. })
  145. it('Should fail with an unknown comment', async function () {
  146. const fields = { comment: { id: 42 }, reason: 'my super reason' }
  147. await makePostBodyRequest({
  148. url: server.url,
  149. path,
  150. token: userToken,
  151. fields,
  152. expectedStatus: HttpStatusCode.NOT_FOUND_404
  153. })
  154. })
  155. it('Should fail with a wrong account', async function () {
  156. const fields = { account: { id: 'blabla' }, reason: 'my super reason' }
  157. await makePostBodyRequest({ url: server.url, path: path, token: userToken, fields })
  158. })
  159. it('Should fail with an unknown account', async function () {
  160. const fields = { account: { id: 42 }, reason: 'my super reason' }
  161. await makePostBodyRequest({
  162. url: server.url,
  163. path,
  164. token: userToken,
  165. fields,
  166. expectedStatus: HttpStatusCode.NOT_FOUND_404
  167. })
  168. })
  169. it('Should fail with not account, comment or video', async function () {
  170. const fields = { reason: 'my super reason' }
  171. await makePostBodyRequest({
  172. url: server.url,
  173. path,
  174. token: userToken,
  175. fields,
  176. expectedStatus: HttpStatusCode.BAD_REQUEST_400
  177. })
  178. })
  179. it('Should fail with a non authenticated user', async function () {
  180. const fields = { video: { id: server.store.videoCreated.id }, reason: 'my super reason' }
  181. await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  182. })
  183. it('Should fail with a reason too short', async function () {
  184. const fields = { video: { id: server.store.videoCreated.id }, reason: 'h' }
  185. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  186. })
  187. it('Should fail with a too big reason', async function () {
  188. const fields = { video: { id: server.store.videoCreated.id }, reason: 'super'.repeat(605) }
  189. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  190. })
  191. it('Should succeed with the correct parameters (basic)', async function () {
  192. const fields: AbuseCreate = { video: { id: server.store.videoCreated.shortUUID }, reason: 'my super reason' }
  193. const res = await makePostBodyRequest({
  194. url: server.url,
  195. path,
  196. token: userToken,
  197. fields,
  198. expectedStatus: HttpStatusCode.OK_200
  199. })
  200. abuseId = res.body.abuse.id
  201. })
  202. it('Should fail with a wrong predefined reason', async function () {
  203. const fields = { video: server.store.videoCreated, reason: 'my super reason', predefinedReasons: [ 'wrongPredefinedReason' ] }
  204. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  205. })
  206. it('Should fail with negative timestamps', async function () {
  207. const fields = { video: { id: server.store.videoCreated.id, startAt: -1 }, reason: 'my super reason' }
  208. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  209. })
  210. it('Should fail mith misordered startAt/endAt', async function () {
  211. const fields = { video: { id: server.store.videoCreated.id, startAt: 5, endAt: 1 }, reason: 'my super reason' }
  212. await makePostBodyRequest({ url: server.url, path, token: userToken, fields })
  213. })
  214. it('Should succeed with the correct parameters (advanced)', async function () {
  215. const fields: AbuseCreate = {
  216. video: {
  217. id: server.store.videoCreated.id,
  218. startAt: 1,
  219. endAt: 5
  220. },
  221. reason: 'my super reason',
  222. predefinedReasons: [ 'serverRules' ]
  223. }
  224. await makePostBodyRequest({ url: server.url, path, token: userToken, fields, expectedStatus: HttpStatusCode.OK_200 })
  225. })
  226. })
  227. describe('When updating an abuse', function () {
  228. it('Should fail with a non authenticated user', async function () {
  229. await command.update({ token: 'blabla', abuseId, body: {}, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  230. })
  231. it('Should fail with a non admin user', async function () {
  232. await command.update({ token: userToken, abuseId, body: {}, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
  233. })
  234. it('Should fail with a bad abuse id', async function () {
  235. await command.update({ abuseId: 45, body: {}, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  236. })
  237. it('Should fail with a bad state', async function () {
  238. const body = { state: 5 }
  239. await command.update({ abuseId, body, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
  240. })
  241. it('Should fail with a bad moderation comment', async function () {
  242. const body = { moderationComment: 'b'.repeat(3001) }
  243. await command.update({ abuseId, body, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
  244. })
  245. it('Should succeed with the correct params', async function () {
  246. const body = { state: AbuseState.ACCEPTED }
  247. await command.update({ abuseId, body })
  248. })
  249. })
  250. describe('When creating an abuse message', function () {
  251. const message = 'my super message'
  252. it('Should fail with an invalid abuse id', async function () {
  253. await command.addMessage({ token: userToken2, abuseId: 888, message, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  254. })
  255. it('Should fail with a non authenticated user', async function () {
  256. await command.addMessage({ token: 'fake_token', abuseId, message, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  257. })
  258. it('Should fail with an invalid logged in user', async function () {
  259. await command.addMessage({ token: userToken2, abuseId, message, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
  260. })
  261. it('Should fail with an invalid message', async function () {
  262. await command.addMessage({ token: userToken, abuseId, message: 'a'.repeat(5000), expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
  263. })
  264. it('Should succeed with the correct params', async function () {
  265. const res = await command.addMessage({ token: userToken, abuseId, message })
  266. messageId = res.body.abuseMessage.id
  267. })
  268. })
  269. describe('When listing abuse messages', function () {
  270. it('Should fail with an invalid abuse id', async function () {
  271. await command.listMessages({ token: userToken, abuseId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  272. })
  273. it('Should fail with a non authenticated user', async function () {
  274. await command.listMessages({ token: 'fake_token', abuseId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  275. })
  276. it('Should fail with an invalid logged in user', async function () {
  277. await command.listMessages({ token: userToken2, abuseId, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
  278. })
  279. it('Should succeed with the correct params', async function () {
  280. await command.listMessages({ token: userToken, abuseId })
  281. })
  282. })
  283. describe('When deleting an abuse message', function () {
  284. it('Should fail with an invalid abuse id', async function () {
  285. await command.deleteMessage({ token: userToken, abuseId: 888, messageId, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  286. })
  287. it('Should fail with an invalid message id', async function () {
  288. await command.deleteMessage({ token: userToken, abuseId, messageId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  289. })
  290. it('Should fail with a non authenticated user', async function () {
  291. await command.deleteMessage({ token: 'fake_token', abuseId, messageId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  292. })
  293. it('Should fail with an invalid logged in user', async function () {
  294. await command.deleteMessage({ token: userToken2, abuseId, messageId, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
  295. })
  296. it('Should succeed with the correct params', async function () {
  297. await command.deleteMessage({ token: userToken, abuseId, messageId })
  298. })
  299. })
  300. describe('When deleting a video abuse', function () {
  301. it('Should fail with a non authenticated user', async function () {
  302. await command.delete({ token: 'blabla', abuseId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
  303. })
  304. it('Should fail with a non admin user', async function () {
  305. await command.delete({ token: userToken, abuseId, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
  306. })
  307. it('Should fail with a bad abuse id', async function () {
  308. await command.delete({ abuseId: 45, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
  309. })
  310. it('Should succeed with the correct params', async function () {
  311. await command.delete({ abuseId })
  312. })
  313. })
  314. describe('When trying to manage messages of a remote abuse', function () {
  315. let remoteAbuseId: number
  316. let anotherServer: PeerTubeServer
  317. before(async function () {
  318. this.timeout(50000)
  319. anotherServer = await createSingleServer(2)
  320. await setAccessTokensToServers([ anotherServer ])
  321. await doubleFollow(anotherServer, server)
  322. const server2VideoId = await anotherServer.videos.getId({ uuid: server.store.videoCreated.uuid })
  323. await anotherServer.abuses.report({ reason: 'remote server', videoId: server2VideoId })
  324. await waitJobs([ server, anotherServer ])
  325. const body = await command.getAdminList({ sort: '-createdAt' })
  326. remoteAbuseId = body.data[0].id
  327. })
  328. it('Should fail when listing abuse messages of a remote abuse', async function () {
  329. await command.listMessages({ abuseId: remoteAbuseId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
  330. })
  331. it('Should fail when creating abuse message of a remote abuse', async function () {
  332. await command.addMessage({ abuseId: remoteAbuseId, message: 'message', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
  333. })
  334. after(async function () {
  335. await cleanupTests([ anotherServer ])
  336. })
  337. })
  338. after(async function () {
  339. await cleanupTests([ server ])
  340. })
  341. })