users.ts 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080
  1. /* tslint:disable:no-unused-expression */
  2. import { omit } from 'lodash'
  3. import 'mocha'
  4. import { join } from 'path'
  5. import { User, UserRole, VideoImport, VideoImportState } from '../../../../shared'
  6. import {
  7. addVideoChannel,
  8. blockUser,
  9. cleanupTests,
  10. createUser,
  11. deleteMe,
  12. flushAndRunServer,
  13. getMyUserInformation,
  14. getMyUserVideoRating,
  15. getUsersList,
  16. immutableAssign,
  17. makeGetRequest,
  18. makePostBodyRequest,
  19. makePutBodyRequest,
  20. makeUploadRequest,
  21. registerUser,
  22. removeUser,
  23. ServerInfo,
  24. setAccessTokensToServers,
  25. unblockUser,
  26. updateUser,
  27. uploadVideo,
  28. userLogin
  29. } from '../../../../shared/extra-utils'
  30. import {
  31. checkBadCountPagination,
  32. checkBadSortPagination,
  33. checkBadStartPagination
  34. } from '../../../../shared/extra-utils/requests/check-api-params'
  35. import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
  36. import { VideoPrivacy } from '../../../../shared/models/videos'
  37. import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
  38. import { expect } from 'chai'
  39. import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
  40. describe('Test users API validators', function () {
  41. const path = '/api/v1/users/'
  42. let userId: number
  43. let rootId: number
  44. let moderatorId: number
  45. let videoId: number
  46. let server: ServerInfo
  47. let serverWithRegistrationDisabled: ServerInfo
  48. let userAccessToken = ''
  49. let moderatorAccessToken = ''
  50. let channelId: number
  51. // ---------------------------------------------------------------
  52. before(async function () {
  53. this.timeout(30000)
  54. {
  55. const res = await Promise.all([
  56. flushAndRunServer(1, { signup: { limit: 7 } }),
  57. flushAndRunServer(2)
  58. ])
  59. server = res[0]
  60. serverWithRegistrationDisabled = res[1]
  61. await setAccessTokensToServers([ server ])
  62. }
  63. {
  64. const user = {
  65. username: 'user1',
  66. password: 'my super password'
  67. }
  68. const videoQuota = 42000000
  69. await createUser({
  70. url: server.url,
  71. accessToken: server.accessToken,
  72. username: user.username,
  73. password: user.password,
  74. videoQuota: videoQuota
  75. })
  76. userAccessToken = await userLogin(server, user)
  77. }
  78. {
  79. const moderator = {
  80. username: 'moderator1',
  81. password: 'super password'
  82. }
  83. await createUser({
  84. url: server.url,
  85. accessToken: server.accessToken,
  86. username: moderator.username,
  87. password: moderator.password,
  88. role: UserRole.MODERATOR
  89. })
  90. moderatorAccessToken = await userLogin(server, moderator)
  91. }
  92. {
  93. const moderator = {
  94. username: 'moderator2',
  95. password: 'super password'
  96. }
  97. await createUser({
  98. url: server.url,
  99. accessToken: server.accessToken,
  100. username: moderator.username,
  101. password: moderator.password,
  102. role: UserRole.MODERATOR
  103. })
  104. }
  105. {
  106. const res = await getMyUserInformation(server.url, server.accessToken)
  107. channelId = res.body.videoChannels[ 0 ].id
  108. }
  109. {
  110. const res = await uploadVideo(server.url, server.accessToken, {})
  111. videoId = res.body.video.id
  112. }
  113. {
  114. const res = await getUsersList(server.url, server.accessToken)
  115. const users: User[] = res.body.data
  116. userId = users.find(u => u.username === 'user1').id
  117. rootId = users.find(u => u.username === 'root').id
  118. moderatorId = users.find(u => u.username === 'moderator2').id
  119. }
  120. })
  121. describe('When listing users', function () {
  122. it('Should fail with a bad start pagination', async function () {
  123. await checkBadStartPagination(server.url, path, server.accessToken)
  124. })
  125. it('Should fail with a bad count pagination', async function () {
  126. await checkBadCountPagination(server.url, path, server.accessToken)
  127. })
  128. it('Should fail with an incorrect sort', async function () {
  129. await checkBadSortPagination(server.url, path, server.accessToken)
  130. })
  131. it('Should fail with a non authenticated user', async function () {
  132. await makeGetRequest({
  133. url: server.url,
  134. path,
  135. statusCodeExpected: 401
  136. })
  137. })
  138. it('Should fail with a non admin user', async function () {
  139. await makeGetRequest({
  140. url: server.url,
  141. path,
  142. token: userAccessToken,
  143. statusCodeExpected: 403
  144. })
  145. })
  146. })
  147. describe('When adding a new user', function () {
  148. const baseCorrectParams = {
  149. username: 'user2',
  150. email: 'test@example.com',
  151. password: 'my super password',
  152. videoQuota: -1,
  153. videoQuotaDaily: -1,
  154. role: UserRole.USER,
  155. adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST
  156. }
  157. it('Should fail with a too small username', async function () {
  158. const fields = immutableAssign(baseCorrectParams, { username: '' })
  159. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  160. })
  161. it('Should fail with a too long username', async function () {
  162. const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
  163. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  164. })
  165. it('Should fail with a not lowercase username', async function () {
  166. const fields = immutableAssign(baseCorrectParams, { username: 'Toto' })
  167. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  168. })
  169. it('Should fail with an incorrect username', async function () {
  170. const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
  171. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  172. })
  173. it('Should fail with a missing email', async function () {
  174. const fields = omit(baseCorrectParams, 'email')
  175. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  176. })
  177. it('Should fail with an invalid email', async function () {
  178. const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
  179. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  180. })
  181. it('Should fail with a too small password', async function () {
  182. const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
  183. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  184. })
  185. it('Should fail with a too long password', async function () {
  186. const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
  187. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  188. })
  189. it('Should fail with invalid admin flags', async function () {
  190. const fields = immutableAssign(baseCorrectParams, { adminFlags: 'toto' })
  191. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  192. })
  193. it('Should fail with an non authenticated user', async function () {
  194. await makePostBodyRequest({
  195. url: server.url,
  196. path,
  197. token: 'super token',
  198. fields: baseCorrectParams,
  199. statusCodeExpected: 401
  200. })
  201. })
  202. it('Should fail if we add a user with the same username', async function () {
  203. const fields = immutableAssign(baseCorrectParams, { username: 'user1' })
  204. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
  205. })
  206. it('Should fail if we add a user with the same email', async function () {
  207. const fields = immutableAssign(baseCorrectParams, { email: 'user1@example.com' })
  208. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
  209. })
  210. it('Should fail without a videoQuota', async function () {
  211. const fields = omit(baseCorrectParams, 'videoQuota')
  212. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  213. })
  214. it('Should fail without a videoQuotaDaily', async function () {
  215. const fields = omit(baseCorrectParams, 'videoQuotaDaily')
  216. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  217. })
  218. it('Should fail with an invalid videoQuota', async function () {
  219. const fields = immutableAssign(baseCorrectParams, { videoQuota: -5 })
  220. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  221. })
  222. it('Should fail with an invalid videoQuotaDaily', async function () {
  223. const fields = immutableAssign(baseCorrectParams, { videoQuotaDaily: -7 })
  224. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  225. })
  226. it('Should fail without a user role', async function () {
  227. const fields = omit(baseCorrectParams, 'role')
  228. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  229. })
  230. it('Should fail with an invalid user role', async function () {
  231. const fields = immutableAssign(baseCorrectParams, { role: 88989 })
  232. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  233. })
  234. it('Should fail with a "peertube" username', async function () {
  235. const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
  236. await makePostBodyRequest({
  237. url: server.url,
  238. path,
  239. token: server.accessToken,
  240. fields,
  241. statusCodeExpected: 409
  242. })
  243. })
  244. it('Should fail to create a moderator or an admin with a moderator', async function () {
  245. for (const role of [ UserRole.MODERATOR, UserRole.ADMINISTRATOR ]) {
  246. const fields = immutableAssign(baseCorrectParams, { role })
  247. await makePostBodyRequest({
  248. url: server.url,
  249. path,
  250. token: moderatorAccessToken,
  251. fields,
  252. statusCodeExpected: 403
  253. })
  254. }
  255. })
  256. it('Should succeed to create a user with a moderator', async function () {
  257. const fields = immutableAssign(baseCorrectParams, { username: 'a4656', email: 'a4656@example.com', role: UserRole.USER })
  258. await makePostBodyRequest({
  259. url: server.url,
  260. path,
  261. token: moderatorAccessToken,
  262. fields,
  263. statusCodeExpected: 200
  264. })
  265. })
  266. it('Should succeed with the correct params', async function () {
  267. await makePostBodyRequest({
  268. url: server.url,
  269. path,
  270. token: server.accessToken,
  271. fields: baseCorrectParams,
  272. statusCodeExpected: 200
  273. })
  274. })
  275. it('Should fail with a non admin user', async function () {
  276. const user = {
  277. username: 'user1',
  278. password: 'my super password'
  279. }
  280. userAccessToken = await userLogin(server, user)
  281. const fields = {
  282. username: 'user3',
  283. email: 'test@example.com',
  284. password: 'my super password',
  285. videoQuota: 42000000
  286. }
  287. await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
  288. })
  289. })
  290. describe('When updating my account', function () {
  291. it('Should fail with an invalid email attribute', async function () {
  292. const fields = {
  293. email: 'blabla'
  294. }
  295. await makePutBodyRequest({ url: server.url, path: path + 'me', token: server.accessToken, fields })
  296. })
  297. it('Should fail with a too small password', async function () {
  298. const fields = {
  299. currentPassword: 'my super password',
  300. password: 'bla'
  301. }
  302. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  303. })
  304. it('Should fail with a too long password', async function () {
  305. const fields = {
  306. currentPassword: 'my super password',
  307. password: 'super'.repeat(61)
  308. }
  309. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  310. })
  311. it('Should fail without the current password', async function () {
  312. const fields = {
  313. currentPassword: 'my super password',
  314. password: 'super'.repeat(61)
  315. }
  316. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  317. })
  318. it('Should fail with an invalid current password', async function () {
  319. const fields = {
  320. currentPassword: 'my super password fail',
  321. password: 'super'.repeat(61)
  322. }
  323. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 401 })
  324. })
  325. it('Should fail with an invalid NSFW policy attribute', async function () {
  326. const fields = {
  327. nsfwPolicy: 'hello'
  328. }
  329. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  330. })
  331. it('Should fail with an invalid autoPlayVideo attribute', async function () {
  332. const fields = {
  333. autoPlayVideo: -1
  334. }
  335. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  336. })
  337. it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
  338. const fields = {
  339. videosHistoryEnabled: -1
  340. }
  341. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  342. })
  343. it('Should fail with an non authenticated user', async function () {
  344. const fields = {
  345. currentPassword: 'my super password',
  346. password: 'my super password'
  347. }
  348. await makePutBodyRequest({ url: server.url, path: path + 'me', token: 'super token', fields, statusCodeExpected: 401 })
  349. })
  350. it('Should fail with a too long description', async function () {
  351. const fields = {
  352. description: 'super'.repeat(201)
  353. }
  354. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  355. })
  356. it('Should fail with an invalid videoLanguages attribute', async function () {
  357. {
  358. const fields = {
  359. videoLanguages: 'toto'
  360. }
  361. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  362. }
  363. {
  364. const languages = []
  365. for (let i = 0; i < 1000; i++) {
  366. languages.push('fr')
  367. }
  368. const fields = {
  369. videoLanguages: languages
  370. }
  371. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  372. }
  373. })
  374. it('Should fail with an invalid theme', async function () {
  375. const fields = { theme: 'invalid' }
  376. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  377. })
  378. it('Should fail with an unknown theme', async function () {
  379. const fields = { theme: 'peertube-theme-unknown' }
  380. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
  381. })
  382. it('Should succeed to change password with the correct params', async function () {
  383. const fields = {
  384. currentPassword: 'my super password',
  385. password: 'my super password',
  386. nsfwPolicy: 'blur',
  387. autoPlayVideo: false,
  388. email: 'super_email@example.com',
  389. theme: 'default'
  390. }
  391. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
  392. })
  393. it('Should succeed without password change with the correct params', async function () {
  394. const fields = {
  395. nsfwPolicy: 'blur',
  396. autoPlayVideo: false
  397. }
  398. await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
  399. })
  400. })
  401. describe('When updating my avatar', function () {
  402. it('Should fail without an incorrect input file', async function () {
  403. const fields = {}
  404. const attaches = {
  405. 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
  406. }
  407. await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
  408. })
  409. it('Should fail with a big file', async function () {
  410. const fields = {}
  411. const attaches = {
  412. 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
  413. }
  414. await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
  415. })
  416. it('Should fail with an unauthenticated user', async function () {
  417. const fields = {}
  418. const attaches = {
  419. 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
  420. }
  421. await makeUploadRequest({
  422. url: server.url,
  423. path: path + '/me/avatar/pick',
  424. fields,
  425. attaches,
  426. statusCodeExpected: 401
  427. })
  428. })
  429. it('Should succeed with the correct params', async function () {
  430. const fields = {}
  431. const attaches = {
  432. 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png')
  433. }
  434. await makeUploadRequest({
  435. url: server.url,
  436. path: path + '/me/avatar/pick',
  437. token: server.accessToken,
  438. fields,
  439. attaches,
  440. statusCodeExpected: 200
  441. })
  442. })
  443. })
  444. describe('When getting a user', function () {
  445. it('Should fail with an non authenticated user', async function () {
  446. await makeGetRequest({ url: server.url, path: path + userId, token: 'super token', statusCodeExpected: 401 })
  447. })
  448. it('Should fail with a non admin user', async function () {
  449. await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 403 })
  450. })
  451. it('Should succeed with the correct params', async function () {
  452. await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, statusCodeExpected: 200 })
  453. })
  454. })
  455. describe('When updating a user', function () {
  456. it('Should fail with an invalid email attribute', async function () {
  457. const fields = {
  458. email: 'blabla'
  459. }
  460. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  461. })
  462. it('Should fail with an invalid emailVerified attribute', async function () {
  463. const fields = {
  464. emailVerified: 'yes'
  465. }
  466. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  467. })
  468. it('Should fail with an invalid videoQuota attribute', async function () {
  469. const fields = {
  470. videoQuota: -90
  471. }
  472. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  473. })
  474. it('Should fail with an invalid user role attribute', async function () {
  475. const fields = {
  476. role: 54878
  477. }
  478. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  479. })
  480. it('Should fail with a too small password', async function () {
  481. const fields = {
  482. currentPassword: 'my super password',
  483. password: 'bla'
  484. }
  485. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  486. })
  487. it('Should fail with a too long password', async function () {
  488. const fields = {
  489. currentPassword: 'my super password',
  490. password: 'super'.repeat(61)
  491. }
  492. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
  493. })
  494. it('Should fail with an non authenticated user', async function () {
  495. const fields = {
  496. videoQuota: 42
  497. }
  498. await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
  499. })
  500. it('Should fail when updating root role', async function () {
  501. const fields = {
  502. role: UserRole.MODERATOR
  503. }
  504. await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
  505. })
  506. it('Should fail with invalid admin flags', async function () {
  507. const fields = { adminFlags: 'toto' }
  508. await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  509. })
  510. it('Should fail to update an admin with a moderator', async function () {
  511. const fields = {
  512. videoQuota: 42
  513. }
  514. await makePutBodyRequest({
  515. url: server.url,
  516. path: path + moderatorId,
  517. token: moderatorAccessToken,
  518. fields,
  519. statusCodeExpected: 403
  520. })
  521. })
  522. it('Should succeed to update a user with a moderator', async function () {
  523. const fields = {
  524. videoQuota: 42
  525. }
  526. await makePutBodyRequest({
  527. url: server.url,
  528. path: path + userId,
  529. token: moderatorAccessToken,
  530. fields,
  531. statusCodeExpected: 204
  532. })
  533. })
  534. it('Should succeed with the correct params', async function () {
  535. const fields = {
  536. email: 'email@example.com',
  537. emailVerified: true,
  538. videoQuota: 42,
  539. role: UserRole.USER
  540. }
  541. await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
  542. })
  543. })
  544. describe('When getting my information', function () {
  545. it('Should fail with a non authenticated user', async function () {
  546. await getMyUserInformation(server.url, 'fake_token', 401)
  547. })
  548. it('Should success with the correct parameters', async function () {
  549. await getMyUserInformation(server.url, userAccessToken)
  550. })
  551. })
  552. describe('When getting my video rating', function () {
  553. it('Should fail with a non authenticated user', async function () {
  554. await getMyUserVideoRating(server.url, 'fake_token', videoId, 401)
  555. })
  556. it('Should fail with an incorrect video uuid', async function () {
  557. await getMyUserVideoRating(server.url, server.accessToken, 'blabla', 400)
  558. })
  559. it('Should fail with an unknown video', async function () {
  560. await getMyUserVideoRating(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
  561. })
  562. it('Should succeed with the correct parameters', async function () {
  563. await getMyUserVideoRating(server.url, server.accessToken, videoId)
  564. })
  565. })
  566. describe('When retrieving my global ratings', function () {
  567. const path = '/api/v1/accounts/user1/ratings'
  568. it('Should fail with a bad start pagination', async function () {
  569. await checkBadStartPagination(server.url, path, userAccessToken)
  570. })
  571. it('Should fail with a bad count pagination', async function () {
  572. await checkBadCountPagination(server.url, path, userAccessToken)
  573. })
  574. it('Should fail with an incorrect sort', async function () {
  575. await checkBadSortPagination(server.url, path, userAccessToken)
  576. })
  577. it('Should fail with a unauthenticated user', async function () {
  578. await makeGetRequest({ url: server.url, path, statusCodeExpected: 401 })
  579. })
  580. it('Should fail with a another user', async function () {
  581. await makeGetRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 403 })
  582. })
  583. it('Should fail with a bad type', async function () {
  584. await makeGetRequest({ url: server.url, path, token: userAccessToken, query: { rating: 'toto ' }, statusCodeExpected: 400 })
  585. })
  586. it('Should succeed with the correct params', async function () {
  587. await makeGetRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 200 })
  588. })
  589. })
  590. describe('When blocking/unblocking/removing user', function () {
  591. it('Should fail with an incorrect id', async function () {
  592. await removeUser(server.url, 'blabla', server.accessToken, 400)
  593. await blockUser(server.url, 'blabla', server.accessToken, 400)
  594. await unblockUser(server.url, 'blabla', server.accessToken, 400)
  595. })
  596. it('Should fail with the root user', async function () {
  597. await removeUser(server.url, rootId, server.accessToken, 400)
  598. await blockUser(server.url, rootId, server.accessToken, 400)
  599. await unblockUser(server.url, rootId, server.accessToken, 400)
  600. })
  601. it('Should return 404 with a non existing id', async function () {
  602. await removeUser(server.url, 4545454, server.accessToken, 404)
  603. await blockUser(server.url, 4545454, server.accessToken, 404)
  604. await unblockUser(server.url, 4545454, server.accessToken, 404)
  605. })
  606. it('Should fail with a non admin user', async function () {
  607. await removeUser(server.url, userId, userAccessToken, 403)
  608. await blockUser(server.url, userId, userAccessToken, 403)
  609. await unblockUser(server.url, userId, userAccessToken, 403)
  610. })
  611. it('Should fail on a moderator with a moderator', async function () {
  612. await removeUser(server.url, moderatorId, moderatorAccessToken, 403)
  613. await blockUser(server.url, moderatorId, moderatorAccessToken, 403)
  614. await unblockUser(server.url, moderatorId, moderatorAccessToken, 403)
  615. })
  616. it('Should succeed on a user with a moderator', async function () {
  617. await blockUser(server.url, userId, moderatorAccessToken)
  618. await unblockUser(server.url, userId, moderatorAccessToken)
  619. })
  620. })
  621. describe('When deleting our account', function () {
  622. it('Should fail with with the root account', async function () {
  623. await deleteMe(server.url, server.accessToken, 400)
  624. })
  625. })
  626. describe('When registering a new user', function () {
  627. const registrationPath = path + '/register'
  628. const baseCorrectParams = {
  629. username: 'user3',
  630. displayName: 'super user',
  631. email: 'test3@example.com',
  632. password: 'my super password'
  633. }
  634. it('Should fail with a too small username', async function () {
  635. const fields = immutableAssign(baseCorrectParams, { username: '' })
  636. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  637. })
  638. it('Should fail with a too long username', async function () {
  639. const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
  640. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  641. })
  642. it('Should fail with an incorrect username', async function () {
  643. const fields = immutableAssign(baseCorrectParams, { username: 'my username' })
  644. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  645. })
  646. it('Should fail with a missing email', async function () {
  647. const fields = omit(baseCorrectParams, 'email')
  648. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  649. })
  650. it('Should fail with an invalid email', async function () {
  651. const fields = immutableAssign(baseCorrectParams, { email: 'test_example.com' })
  652. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  653. })
  654. it('Should fail with a too small password', async function () {
  655. const fields = immutableAssign(baseCorrectParams, { password: 'bla' })
  656. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  657. })
  658. it('Should fail with a too long password', async function () {
  659. const fields = immutableAssign(baseCorrectParams, { password: 'super'.repeat(61) })
  660. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  661. })
  662. it('Should fail if we register a user with the same username', async function () {
  663. const fields = immutableAssign(baseCorrectParams, { username: 'root' })
  664. await makePostBodyRequest({
  665. url: server.url,
  666. path: registrationPath,
  667. token: server.accessToken,
  668. fields,
  669. statusCodeExpected: 409
  670. })
  671. })
  672. it('Should fail with a "peertube" username', async function () {
  673. const fields = immutableAssign(baseCorrectParams, { username: 'peertube' })
  674. await makePostBodyRequest({
  675. url: server.url,
  676. path: registrationPath,
  677. token: server.accessToken,
  678. fields,
  679. statusCodeExpected: 409
  680. })
  681. })
  682. it('Should fail if we register a user with the same email', async function () {
  683. const fields = immutableAssign(baseCorrectParams, { email: 'admin' + server.internalServerNumber + '@example.com' })
  684. await makePostBodyRequest({
  685. url: server.url,
  686. path: registrationPath,
  687. token: server.accessToken,
  688. fields,
  689. statusCodeExpected: 409
  690. })
  691. })
  692. it('Should fail with a bad display name', async function () {
  693. const fields = immutableAssign(baseCorrectParams, { displayName: 'a'.repeat(150) })
  694. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  695. })
  696. it('Should fail with a bad channel name', async function () {
  697. const fields = immutableAssign(baseCorrectParams, { channel: { name: '[]azf', displayName: 'toto' } })
  698. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  699. })
  700. it('Should fail with a bad channel display name', async function () {
  701. const fields = immutableAssign(baseCorrectParams, { channel: { name: 'toto', displayName: '' } })
  702. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  703. })
  704. it('Should fail with a channel name that is the same than user username', async function () {
  705. const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
  706. const fields = immutableAssign(baseCorrectParams, source)
  707. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
  708. })
  709. it('Should fail with an existing channel', async function () {
  710. const videoChannelAttributesArg = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
  711. await addVideoChannel(server.url, server.accessToken, videoChannelAttributesArg)
  712. const fields = immutableAssign(baseCorrectParams, { channel: { name: 'existing_channel', displayName: 'toto' } })
  713. await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields, statusCodeExpected: 409 })
  714. })
  715. it('Should succeed with the correct params', async function () {
  716. const fields = immutableAssign(baseCorrectParams, { channel: { name: 'super_channel', displayName: 'toto' } })
  717. await makePostBodyRequest({
  718. url: server.url,
  719. path: registrationPath,
  720. token: server.accessToken,
  721. fields: fields,
  722. statusCodeExpected: 204
  723. })
  724. })
  725. it('Should fail on a server with registration disabled', async function () {
  726. const fields = {
  727. username: 'user4',
  728. email: 'test4@example.com',
  729. password: 'my super password 4'
  730. }
  731. await makePostBodyRequest({
  732. url: serverWithRegistrationDisabled.url,
  733. path: registrationPath,
  734. token: serverWithRegistrationDisabled.accessToken,
  735. fields,
  736. statusCodeExpected: 403
  737. })
  738. })
  739. })
  740. describe('When registering multiple users on a server with users limit', function () {
  741. it('Should fail when after 3 registrations', async function () {
  742. await registerUser(server.url, 'user42', 'super password', 403)
  743. })
  744. })
  745. describe('When having a video quota', function () {
  746. it('Should fail with a user having too many videos', async function () {
  747. await updateUser({
  748. url: server.url,
  749. userId: rootId,
  750. accessToken: server.accessToken,
  751. videoQuota: 42
  752. })
  753. await uploadVideo(server.url, server.accessToken, {}, 403)
  754. })
  755. it('Should fail with a registered user having too many videos', async function () {
  756. this.timeout(30000)
  757. const user = {
  758. username: 'user3',
  759. password: 'my super password'
  760. }
  761. userAccessToken = await userLogin(server, user)
  762. const videoAttributes = { fixture: 'video_short2.webm' }
  763. await uploadVideo(server.url, userAccessToken, videoAttributes)
  764. await uploadVideo(server.url, userAccessToken, videoAttributes)
  765. await uploadVideo(server.url, userAccessToken, videoAttributes)
  766. await uploadVideo(server.url, userAccessToken, videoAttributes)
  767. await uploadVideo(server.url, userAccessToken, videoAttributes)
  768. await uploadVideo(server.url, userAccessToken, videoAttributes, 403)
  769. })
  770. it('Should fail to import with HTTP/Torrent/magnet', async function () {
  771. this.timeout(120000)
  772. const baseAttributes = {
  773. channelId: 1,
  774. privacy: VideoPrivacy.PUBLIC
  775. }
  776. await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
  777. await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
  778. await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
  779. await waitJobs([ server ])
  780. const res = await getMyVideoImports(server.url, server.accessToken)
  781. expect(res.body.total).to.equal(3)
  782. const videoImports: VideoImport[] = res.body.data
  783. expect(videoImports).to.have.lengthOf(3)
  784. for (const videoImport of videoImports) {
  785. expect(videoImport.state.id).to.equal(VideoImportState.FAILED)
  786. expect(videoImport.error).not.to.be.undefined
  787. expect(videoImport.error).to.contain('user video quota is exceeded')
  788. }
  789. })
  790. })
  791. describe('When having a daily video quota', function () {
  792. it('Should fail with a user having too many videos', async function () {
  793. await updateUser({
  794. url: server.url,
  795. userId: rootId,
  796. accessToken: server.accessToken,
  797. videoQuotaDaily: 42
  798. })
  799. await uploadVideo(server.url, server.accessToken, {}, 403)
  800. })
  801. })
  802. describe('When having an absolute and daily video quota', function () {
  803. it('Should fail if exceeding total quota', async function () {
  804. await updateUser({
  805. url: server.url,
  806. userId: rootId,
  807. accessToken: server.accessToken,
  808. videoQuota: 42,
  809. videoQuotaDaily: 1024 * 1024 * 1024
  810. })
  811. await uploadVideo(server.url, server.accessToken, {}, 403)
  812. })
  813. it('Should fail if exceeding daily quota', async function () {
  814. await updateUser({
  815. url: server.url,
  816. userId: rootId,
  817. accessToken: server.accessToken,
  818. videoQuota: 1024 * 1024 * 1024,
  819. videoQuotaDaily: 42
  820. })
  821. await uploadVideo(server.url, server.accessToken, {}, 403)
  822. })
  823. })
  824. describe('When asking a password reset', function () {
  825. const path = '/api/v1/users/ask-reset-password'
  826. it('Should fail with a missing email', async function () {
  827. const fields = {}
  828. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  829. })
  830. it('Should fail with an invalid email', async function () {
  831. const fields = { email: 'hello' }
  832. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  833. })
  834. it('Should success with the correct params', async function () {
  835. const fields = { email: 'admin@example.com' }
  836. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
  837. })
  838. })
  839. describe('When asking for an account verification email', function () {
  840. const path = '/api/v1/users/ask-send-verify-email'
  841. it('Should fail with a missing email', async function () {
  842. const fields = {}
  843. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  844. })
  845. it('Should fail with an invalid email', async function () {
  846. const fields = { email: 'hello' }
  847. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
  848. })
  849. it('Should succeed with the correct params', async function () {
  850. const fields = { email: 'admin@example.com' }
  851. await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
  852. })
  853. })
  854. after(async function () {
  855. await cleanupTests([ server, serverWithRegistrationDisabled ])
  856. })
  857. })