Convert tests to typescript
authorChocobozzz <florian.bigard@gmail.com>
Mon, 4 Sep 2017 19:21:47 +0000 (21:21 +0200)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 4 Sep 2017 19:30:18 +0000 (21:30 +0200)
73 files changed:
package.json
scripts/reset-password.ts
scripts/test.sh
server/initializers/constants.ts
server/tests/api/check-params/index.js [deleted file]
server/tests/api/check-params/index.ts [new file with mode: 0644]
server/tests/api/check-params/pods.js [deleted file]
server/tests/api/check-params/pods.ts [new file with mode: 0644]
server/tests/api/check-params/remotes.js [deleted file]
server/tests/api/check-params/remotes.ts [new file with mode: 0644]
server/tests/api/check-params/request-schedulers.js [deleted file]
server/tests/api/check-params/request-schedulers.ts [new file with mode: 0644]
server/tests/api/check-params/users.js [deleted file]
server/tests/api/check-params/users.ts [new file with mode: 0644]
server/tests/api/check-params/video-abuses.js [deleted file]
server/tests/api/check-params/video-abuses.ts [new file with mode: 0644]
server/tests/api/check-params/video-blacklists.js [deleted file]
server/tests/api/check-params/video-blacklists.ts [new file with mode: 0644]
server/tests/api/check-params/videos.js [deleted file]
server/tests/api/check-params/videos.ts [new file with mode: 0644]
server/tests/api/config.js [deleted file]
server/tests/api/config.ts [new file with mode: 0644]
server/tests/api/friends-advanced.js [deleted file]
server/tests/api/friends-advanced.ts [new file with mode: 0644]
server/tests/api/friends-basic.js [deleted file]
server/tests/api/friends-basic.ts [new file with mode: 0644]
server/tests/api/index.js [deleted file]
server/tests/api/index.ts [new file with mode: 0644]
server/tests/api/multiple-pods.js [deleted file]
server/tests/api/multiple-pods.ts [new file with mode: 0644]
server/tests/api/request-schedulers.js [deleted file]
server/tests/api/request-schedulers.ts [new file with mode: 0644]
server/tests/api/single-pod.js [deleted file]
server/tests/api/single-pod.ts [new file with mode: 0644]
server/tests/api/users.js [deleted file]
server/tests/api/users.ts [new file with mode: 0644]
server/tests/api/video-abuse.js [deleted file]
server/tests/api/video-abuse.ts [new file with mode: 0644]
server/tests/api/video-blacklist.js [deleted file]
server/tests/api/video-blacklist.ts [new file with mode: 0644]
server/tests/api/video-transcoder.js [deleted file]
server/tests/api/video-transcoder.ts [new file with mode: 0644]
server/tests/client.js [deleted file]
server/tests/client.ts [new file with mode: 0644]
server/tests/index.js [deleted file]
server/tests/index.ts [new file with mode: 0644]
server/tests/utils/clients.js [deleted file]
server/tests/utils/clients.ts [new file with mode: 0644]
server/tests/utils/config.js [deleted file]
server/tests/utils/config.ts [new file with mode: 0644]
server/tests/utils/index.ts [new file with mode: 0644]
server/tests/utils/login.js [deleted file]
server/tests/utils/login.ts [new file with mode: 0644]
server/tests/utils/miscs.js [deleted file]
server/tests/utils/miscs.ts [new file with mode: 0644]
server/tests/utils/pods.js [deleted file]
server/tests/utils/pods.ts [new file with mode: 0644]
server/tests/utils/request-schedulers.js [deleted file]
server/tests/utils/request-schedulers.ts [new file with mode: 0644]
server/tests/utils/requests.js [deleted file]
server/tests/utils/requests.ts [new file with mode: 0644]
server/tests/utils/servers.js [deleted file]
server/tests/utils/servers.ts [new file with mode: 0644]
server/tests/utils/users.js [deleted file]
server/tests/utils/users.ts [new file with mode: 0644]
server/tests/utils/video-abuses.js [deleted file]
server/tests/utils/video-abuses.ts [new file with mode: 0644]
server/tests/utils/video-blacklists.js [deleted file]
server/tests/utils/video-blacklists.ts [new file with mode: 0644]
server/tests/utils/videos.js [deleted file]
server/tests/utils/videos.ts [new file with mode: 0644]
tsconfig.json
yarn.lock

index 900d040529dc86325a826b1c76b5aefc40108c17..6be7af382c51daf8a85410bbcfcec0e2fd783f6b 100644 (file)
@@ -78,8 +78,8 @@
     "safe-buffer": "^5.0.1",
     "scripty": "^1.5.0",
     "sequelize": "^4.7.5",
-    "ts-node": "^3.0.6",
     "typescript": "^2.5.2",
+    "ts-node": "^3.3.0",
     "validator": "^8.1.0",
     "winston": "^2.1.1",
     "ws": "^3.1.0"
     "@types/async": "^2.0.40",
     "@types/bcrypt": "^1.0.0",
     "@types/body-parser": "^1.16.3",
+    "@types/chai": "^4.0.4",
     "@types/commander": "^2.9.1",
     "@types/config": "^0.0.32",
     "@types/express": "^4.0.35",
     "@types/lodash": "^4.14.64",
     "@types/magnet-uri": "^5.1.1",
     "@types/mkdirp": "^0.5.1",
+    "@types/mocha": "^2.2.42",
     "@types/morgan": "^1.7.32",
     "@types/multer": "^1.3.3",
     "@types/node": "^8.0.3",
     "@types/request": "^2.0.3",
     "@types/sequelize": "^4.0.55",
+    "@types/supertest": "^2.0.3",
     "@types/validator": "^6.2.0",
+    "@types/webtorrent": "^0.98.4",
     "@types/winston": "^2.3.2",
     "@types/ws": "^3.0.2",
     "chai": "^4.1.1",
index 09f27bfa49b043fb406c57b872caa9322a584e7a..5ab7d01e5d38ba54bd456f44f3850f255412486f 100755 (executable)
@@ -6,14 +6,14 @@ program
   .option('-u, --user [user]', 'User')
   .parse(process.argv)
 
-if (program.user === undefined) {
+if (program['user'] === undefined) {
   console.error('All parameters are mandatory.')
   process.exit(-1)
 }
 
 db.init(true)
   .then(() => {
-    return db.User.loadByUsername(program.user)
+    return db.User.loadByUsername(program['user'])
   })
   .then(user => {
     if (!user) {
index 6c6312d5268009446417f9ac3c3d97184bcbdd26..b193a10bca1d9013bc6bbc2e8e01fe558b1004e8 100755 (executable)
@@ -7,4 +7,4 @@ npm test || exit -1
 
 cd .. || exit -1
 npm run tslint -- --type-check --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" || exit -1
-mocha --bail server/tests
+mocha --require ts-node/register --bail server/tests/index.ts
index b93a858598c2a916cde2321f0931cee59045191d..2e3472d1e1c4697426055a9ef0259b7bead5724f 100644 (file)
@@ -110,7 +110,7 @@ const CONSTRAINTS_FIELDS = {
     NAME: { min: 3, max: 50 }, // Length
     DESCRIPTION: { min: 3, max: 250 }, // Length
     EXTNAME: [ '.mp4', '.ogv', '.webm' ],
-    INFO_HASH: { min: 40, max: 40 }, // Length, infohash is 20 bytes length but we represent it in hexa so 20 * 2
+    INFO_HASH: { min: 40, max: 40 }, // Length, info hash is 20 bytes length but we represent it in hexadecimal so 20 * 2
     DURATION: { min: 1, max: 7200 }, // Number
     TAGS: { min: 0, max: 3 }, // Number of total tags
     TAG: { min: 2, max: 10 }, // Length
diff --git a/server/tests/api/check-params/index.js b/server/tests/api/check-params/index.js
deleted file mode 100644 (file)
index 1ba16ff..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict'
-
-// Order of the tests we want to execute
-require('./pods')
-require('./remotes')
-require('./users')
-require('./request-schedulers')
-require('./videos')
-require('./video-abuses')
-require('./video-blacklists')
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
new file mode 100644 (file)
index 0000000..97f2a19
--- /dev/null
@@ -0,0 +1,8 @@
+// Order of the tests we want to execute
+import './pods'
+import './remotes'
+import './users'
+import './request-schedulers'
+import './videos'
+import './video-abuses'
+import './video-blacklists'
diff --git a/server/tests/api/check-params/pods.js b/server/tests/api/check-params/pods.js
deleted file mode 100644 (file)
index 35ea590..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const requestsUtils = require('../../utils/requests')
-const serversUtils = require('../../utils/servers')
-const usersUtils = require('../../utils/users')
-
-describe('Test pods API validators', function () {
-  const path = '/api/v1/pods/'
-  let server = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(45000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When managing friends', function () {
-    let userAccessToken = null
-
-    before(function (done) {
-      usersUtils.createUser(server.url, server.accessToken, 'user1', 'password', function () {
-        server.user = {
-          username: 'user1',
-          password: 'password'
-        }
-
-        loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-          if (err) throw err
-
-          userAccessToken = accessToken
-
-          done()
-        })
-      })
-    })
-
-    describe('When making friends', function () {
-      const body = {
-        hosts: [ 'localhost:9002' ]
-      }
-
-      it('Should fail without hosts', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail if hosts is not an array', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send({ hosts: 'localhost:9002' })
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail if the array is not composed by hosts', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send({ hosts: [ 'localhost:9002', 'localhost:coucou' ] })
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail if the array is composed with http schemes', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send({ hosts: [ 'localhost:9002', 'http://localhost:9003' ] })
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail if hosts are not unique', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send({ urls: [ 'localhost:9002', 'localhost:9002' ] })
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail with an invalid token', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send(body)
-          .set('Authorization', 'Bearer faketoken')
-          .set('Accept', 'application/json')
-          .expect(401, done)
-      })
-
-      it('Should fail if the user is not an administrator', function (done) {
-        request(server.url)
-          .post(path + '/makefriends')
-          .send(body)
-          .set('Authorization', 'Bearer ' + userAccessToken)
-          .set('Accept', 'application/json')
-          .expect(403, done)
-      })
-    })
-
-    describe('When quitting friends', function () {
-      it('Should fail with an invalid token', function (done) {
-        request(server.url)
-          .get(path + '/quitfriends')
-          .query({ start: 'hello' })
-          .set('Authorization', 'Bearer faketoken')
-          .set('Accept', 'application/json')
-          .expect(401, done)
-      })
-
-      it('Should fail if the user is not an administrator', function (done) {
-        request(server.url)
-          .get(path + '/quitfriends')
-          .query({ start: 'hello' })
-          .set('Authorization', 'Bearer ' + userAccessToken)
-          .set('Accept', 'application/json')
-          .expect(403, done)
-      })
-    })
-
-    describe('When removing one friend', function () {
-      it('Should fail with an invalid token', function (done) {
-       request(server.url)
-          .delete(path + '/1')
-          .set('Authorization', 'Bearer faketoken')
-          .set('Accept', 'application/json')
-          .expect(401, done)
-      })
-
-      it('Should fail if the user is not an administrator', function (done) {
-       request(server.url)
-          .delete(path + '/1')
-          .set('Authorization', 'Bearer ' + userAccessToken)
-          .set('Accept', 'application/json')
-          .expect(403, done)
-      })
-
-      it('Should fail with an undefined id', function (done) {
-        request(server.url)
-          .delete(path + '/' + undefined)
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail with an invalid id', function (done) {
-       request(server.url)
-          .delete(path + '/foobar')
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(400, done)
-      })
-
-      it('Should fail if the pod is not a friend', function (done) {
-       request(server.url)
-          .delete(path + '/-1')
-          .set('Authorization', 'Bearer ' + server.accessToken)
-          .set('Accept', 'application/json')
-          .expect(404, done)
-      })
-
-      it('Should succeed with the correct parameters')
-    })
-  })
-
-  describe('When adding a pod', function () {
-    it('Should fail with nothing', function (done) {
-      const data = {}
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-    })
-
-    it('Should fail without public key', function (done) {
-      const data = {
-        email: 'testexample.com',
-        host: 'coucou.com'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-    })
-
-    it('Should fail without an email', function (done) {
-      const data = {
-        host: 'coucou.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-    })
-
-    it('Should fail without an invalid email', function (done) {
-      const data = {
-        host: 'coucou.com',
-        email: 'testexample.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-    })
-
-    it('Should fail without a host', function (done) {
-      const data = {
-        email: 'testexample.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-    })
-
-    it('Should fail with an incorrect host', function (done) {
-      const data = {
-        host: 'http://coucou.com',
-        email: 'testexample.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, function () {
-        data.host = 'http://coucou'
-        requestsUtils.makePostBodyRequest(server.url, path, null, data, function () {
-          data.host = 'coucou'
-          requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
-        })
-      })
-    })
-
-    it('Should succeed with the correct parameters', function (done) {
-      const data = {
-        host: 'coucou.com',
-        email: 'test@example.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200)
-    })
-
-    it('Should fail with a host that already exists', function (done) {
-      const data = {
-        host: 'coucou.com',
-        email: 'test@example.com',
-        publicKey: 'mysuperpublickey'
-      }
-      requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 409)
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/pods.ts b/server/tests/api/check-params/pods.ts
new file mode 100644 (file)
index 0000000..27c0809
--- /dev/null
@@ -0,0 +1,259 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import 'mocha'
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  createUser,
+  loginAndGetAccessToken,
+  setAccessTokensToServers,
+  killallServers,
+  makePostBodyRequest
+} from '../../utils'
+
+describe('Test pods API validators', function () {
+  const path = '/api/v1/pods/'
+  let server: ServerInfo
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(45000)
+
+    await flushTests()
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+  })
+
+  describe('When managing friends', function () {
+    let userAccessToken = null
+
+    before(async function () {
+      await createUser(server.url, server.accessToken, 'user1', 'password')
+      server.user = {
+        username: 'user1',
+        password: 'password'
+      }
+
+      userAccessToken = await loginAndGetAccessToken(server)
+    })
+
+    describe('When making friends', function () {
+      const body = {
+        hosts: [ 'localhost:9002' ]
+      }
+
+      it('Should fail without hosts', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail if hosts is not an array', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send({ hosts: 'localhost:9002' })
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail if the array is not composed by hosts', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send({ hosts: [ 'localhost:9002', 'localhost:coucou' ] })
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail if the array is composed with http schemes', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send({ hosts: [ 'localhost:9002', 'http://localhost:9003' ] })
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail if hosts are not unique', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send({ urls: [ 'localhost:9002', 'localhost:9002' ] })
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail with an invalid token', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send(body)
+                .set('Authorization', 'Bearer faketoken')
+                .set('Accept', 'application/json')
+                .expect(401)
+      })
+
+      it('Should fail if the user is not an administrator', async function () {
+        await request(server.url)
+                .post(path + '/makefriends')
+                .send(body)
+                .set('Authorization', 'Bearer ' + userAccessToken)
+                .set('Accept', 'application/json')
+                .expect(403)
+      })
+    })
+
+    describe('When quitting friends', function () {
+      it('Should fail with an invalid token', async function () {
+        await request(server.url)
+                .get(path + '/quitfriends')
+                .query({ start: 'hello' })
+                .set('Authorization', 'Bearer faketoken')
+                .set('Accept', 'application/json')
+                .expect(401)
+      })
+
+      it('Should fail if the user is not an administrator', async function () {
+        await request(server.url)
+                .get(path + '/quitfriends')
+                .query({ start: 'hello' })
+                .set('Authorization', 'Bearer ' + userAccessToken)
+                .set('Accept', 'application/json')
+                .expect(403)
+      })
+    })
+
+    describe('When removing one friend', function () {
+      it('Should fail with an invalid token', async function () {
+       await request(server.url)
+                .delete(path + '/1')
+                .set('Authorization', 'Bearer faketoken')
+                .set('Accept', 'application/json')
+                .expect(401)
+      })
+
+      it('Should fail if the user is not an administrator', async function () {
+       await request(server.url)
+                .delete(path + '/1')
+                .set('Authorization', 'Bearer ' + userAccessToken)
+                .set('Accept', 'application/json')
+                .expect(403)
+      })
+
+      it('Should fail with an undefined id', async function () {
+        await request(server.url)
+                .delete(path + '/' + undefined)
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail with an invalid id', async function () {
+             await request(server.url)
+                .delete(path + '/foobar')
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(400)
+      })
+
+      it('Should fail if the pod is not a friend', async function () {
+             await request(server.url)
+                .delete(path + '/-1')
+                .set('Authorization', 'Bearer ' + server.accessToken)
+                .set('Accept', 'application/json')
+                .expect(404)
+      })
+
+      it('Should succeed with the correct parameters')
+    })
+  })
+
+  describe('When adding a pod', function () {
+    it('Should fail with nothing', async function () {
+      const fields = {}
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should fail without public key', async function () {
+      const fields = {
+        email: 'test.example.com',
+        host: 'coucou.com'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should fail without an email', async function () {
+      const fields = {
+        host: 'coucou.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should fail without an invalid email', async function () {
+      const fields = {
+        host: 'coucou.com',
+        email: 'test.example.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should fail without a host', async function () {
+      const fields = {
+        email: 'test.example.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should fail with an incorrect host', async function () {
+      const fields = {
+        host: 'http://coucou.com',
+        email: 'test.example.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields })
+
+      fields.host = 'http://coucou'
+      await makePostBodyRequest({ url: server.url, path, fields })
+
+      fields.host = 'coucou'
+      await makePostBodyRequest({ url: server.url, path, fields })
+    })
+
+    it('Should succeed with the correct parameters', async function () {
+      const fields = {
+        host: 'coucou.com',
+        email: 'test@example.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields, statusCodeExpected: 200 })
+    })
+
+    it('Should fail with a host that already exists', async function () {
+      const fields = {
+        host: 'coucou.com',
+        email: 'test@example.com',
+        publicKey: 'my super public key'
+      }
+      await makePostBodyRequest({ url: server.url, path, fields, statusCodeExpected: 409 })
+    })
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/remotes.js b/server/tests/api/check-params/remotes.js
deleted file mode 100644 (file)
index 7cb99c4..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const serversUtils = require('../../utils/servers')
-
-describe('Test remote videos API validators', function () {
-  let server = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(20000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When making a secure request', function () {
-    it('Should check a secure request')
-  })
-
-  describe('When adding a video', function () {
-    it('Should check when adding a video')
-
-    it('Should not add an existing uuid')
-  })
-
-  describe('When removing a video', function () {
-    it('Should check when removing a video')
-  })
-
-  describe('When reporting abuse on a video', function () {
-    it('Should check when reporting a video abuse')
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/remotes.ts b/server/tests/api/check-params/remotes.ts
new file mode 100644 (file)
index 0000000..b36f1c0
--- /dev/null
@@ -0,0 +1,52 @@
+/* tslint:disable:no-unused-expression */
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  setAccessTokensToServers,
+  killallServers
+} from '../../utils'
+
+describe('Test remote videos API validators', function () {
+  let server: ServerInfo
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(20000)
+
+    await flushTests()
+
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+  })
+
+  describe('When making a secure request', async function () {
+    it('Should check a secure request')
+  })
+
+  describe('When adding a video', async function () {
+    it('Should check when adding a video')
+
+    it('Should not add an existing uuid')
+  })
+
+  describe('When removing a video', async function () {
+    it('Should check when removing a video')
+  })
+
+  describe('When reporting abuse on a video', async function () {
+    it('Should check when reporting a video abuse')
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/request-schedulers.js b/server/tests/api/check-params/request-schedulers.js
deleted file mode 100644 (file)
index 9ba0df7..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const usersUtils = require('../../utils/users')
-const serversUtils = require('../../utils/servers')
-
-describe('Test request schedulers stats API validators', function () {
-  const path = '/api/v1/request-schedulers/stats'
-  let server = null
-  let userAccessToken = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(20000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      },
-      function (next) {
-        const username = 'user'
-        const password = 'my super password'
-
-        usersUtils.createUser(server.url, server.accessToken, username, password, next)
-      },
-      function (next) {
-        const user = {
-          username: 'user',
-          password: 'my super password'
-        }
-
-        loginUtils.getUserAccessToken(server, user, function (err, accessToken) {
-          if (err) throw err
-
-          userAccessToken = accessToken
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should fail with an non authenticated user', function (done) {
-    request(server.url)
-      .get(path)
-      .set('Accept', 'application/json')
-      .expect(401, done)
-  })
-
-  it('Should fail with a non admin user', function (done) {
-    request(server.url)
-      .get(path)
-      .set('Authorization', 'Bearer ' + userAccessToken)
-      .set('Accept', 'application/json')
-      .expect(403, done)
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/request-schedulers.ts b/server/tests/api/check-params/request-schedulers.ts
new file mode 100644 (file)
index 0000000..c39f594
--- /dev/null
@@ -0,0 +1,65 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import 'mocha'
+
+import {
+  flushTests,
+  runServer,
+  createUser,
+  setAccessTokensToServers,
+  killallServers,
+  getUserAccessToken
+} from '../../utils'
+
+describe('Test request schedulers stats API validators', function () {
+  const path = '/api/v1/request-schedulers/stats'
+  let server = null
+  let userAccessToken = null
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(20000)
+
+    await flushTests()
+
+    server = await runServer(1)
+    await setAccessTokensToServers([ server ])
+
+    const username = 'user'
+    const password = 'my super password'
+    await createUser(server.url, server.accessToken, username, password)
+
+    const user = {
+      username: 'user',
+      password: 'my super password'
+    }
+
+    userAccessToken = await getUserAccessToken(server, user)
+  })
+
+  it('Should fail with an non authenticated user', async function () {
+    await request(server.url)
+            .get(path)
+            .set('Accept', 'application/json')
+            .expect(401)
+  })
+
+  it('Should fail with a non admin user', async function () {
+    await request(server.url)
+            .get(path)
+            .set('Authorization', 'Bearer ' + userAccessToken)
+            .set('Accept', 'application/json')
+            .expect(403)
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/users.js b/server/tests/api/check-params/users.js
deleted file mode 100644 (file)
index 9e7115d..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const requestsUtils = require('../../utils/requests')
-const serversUtils = require('../../utils/servers')
-const usersUtils = require('../../utils/users')
-const videosUtils = require('../../utils/videos')
-
-describe('Test users API validators', function () {
-  const path = '/api/v1/users/'
-  let userId = null
-  let rootId = null
-  let videoId = null
-  let server = null
-  let serverWithRegistrationDisabled = null
-  let userAccessToken = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (serverCreated) {
-          server = serverCreated
-
-          next()
-        })
-      },
-      function (next) {
-        serversUtils.runServer(2, function (serverCreated) {
-          serverWithRegistrationDisabled = serverCreated
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      },
-      function (next) {
-        const username = 'user1'
-        const password = 'my super password'
-
-        usersUtils.createUser(server.url, server.accessToken, username, password, next)
-      },
-      function (next) {
-        const videoAttributes = {}
-        videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, next)
-      },
-      function (next) {
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          videoId = videos[0].id
-
-          next()
-        })
-      },
-      function (next) {
-        const user = {
-          username: 'user1',
-          password: 'my super password'
-        }
-
-        loginUtils.getUserAccessToken(server, user, function (err, accessToken) {
-          if (err) throw err
-
-          userAccessToken = accessToken
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When listing users', function () {
-    it('Should fail with a bad start pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ start: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with a bad count pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ count: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with an incorrect sort', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-  })
-
-  describe('When adding a new user', function () {
-    it('Should fail with a too small username', function (done) {
-      const data = {
-        username: 'ji',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too long username', function (done) {
-      const data = {
-        username: 'mysuperusernamewhichisverylong',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with an incorrect username', function (done) {
-      const data = {
-        username: 'my username',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a missing email', function (done) {
-      const data = {
-        username: 'ji',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with an invalid email', function (done) {
-      const data = {
-        username: 'mysuperusernamewhichisverylong',
-        email: 'testexample.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too small password', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'test@example.com',
-        password: 'bla'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too long password', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'test@example.com',
-        password: 'my super long password which is very very very very very very very very very very very very very very' +
-                  'very very very very very very very very very very very very very very very veryv very very very very' +
-                  'very very very very very very very very very very very very very very very very very very very very long'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with an non authenticated user', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'test@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401)
-    })
-
-    it('Should fail if we add a user with the same username', function (done) {
-      const data = {
-        username: 'user1',
-        email: 'test@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409)
-    })
-
-    it('Should fail if we add a user with the same email', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'user1@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409)
-    })
-
-    it('Should succeed with the correct params', function (done) {
-      const data = {
-        username: 'user2',
-        email: 'test@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204)
-    })
-
-    it('Should fail with a non admin user', function (done) {
-      server.user = {
-        username: 'user1',
-        email: 'test@example.com',
-        password: 'my super password'
-      }
-
-      loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-        if (err) throw err
-
-        userAccessToken = accessToken
-
-        const data = {
-          username: 'user3',
-          email: 'test@example.com',
-          password: 'my super password'
-        }
-
-        requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403)
-      })
-    })
-  })
-
-  describe('When updating a user', function () {
-    before(function (done) {
-      usersUtils.getUsersList(server.url, function (err, res) {
-        if (err) throw err
-
-        userId = res.body.data[1].id
-        rootId = res.body.data[2].id
-        done()
-      })
-    })
-
-    it('Should fail with a too small password', function (done) {
-      const data = {
-        password: 'bla'
-      }
-
-      requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done)
-    })
-
-    it('Should fail with a too long password', function (done) {
-      const data = {
-        password: 'my super long password which is very very very very very very very very very very very very very very' +
-                  'very very very very very very very very very very very very very very very veryv very very very very' +
-                  'very very very very very very very very very very very very very very very very very very very very long'
-      }
-
-      requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done)
-    })
-
-    it('Should fail with an invalid display NSFW attribute', function (done) {
-      const data = {
-        displayNSFW: -1
-      }
-
-      requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done)
-    })
-
-    it('Should fail with an non authenticated user', function (done) {
-      const data = {
-        password: 'my super password'
-      }
-
-      requestsUtils.makePutBodyRequest(server.url, path + userId, 'super token', data, done, 401)
-    })
-
-    it('Should succeed with the correct params', function (done) {
-      const data = {
-        password: 'my super password',
-        displayNSFW: true
-      }
-
-      requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done, 204)
-    })
-  })
-
-  describe('When getting my information', function () {
-    it('Should fail with a non authenticated user', function (done) {
-      request(server.url)
-        .get(path + 'me')
-        .set('Authorization', 'Bearer faketoken')
-        .set('Accept', 'application/json')
-        .expect(401, done)
-    })
-
-    it('Should success with the correct parameters', function (done) {
-      request(server.url)
-        .get(path + 'me')
-        .set('Authorization', 'Bearer ' + userAccessToken)
-        .set('Accept', 'application/json')
-        .expect(200, done)
-    })
-  })
-
-  describe('When getting my video rating', function () {
-    it('Should fail with a non authenticated user', function (done) {
-      request(server.url)
-        .get(path + 'me/videos/' + videoId + '/rating')
-        .set('Authorization', 'Bearer faketoken')
-        .set('Accept', 'application/json')
-        .expect(401, done)
-    })
-
-    it('Should fail with an incorrect video uuid', function (done) {
-      request(server.url)
-        .get(path + 'me/videos/blabla/rating')
-        .set('Authorization', 'Bearer ' + userAccessToken)
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with an unknown video', function (done) {
-      request(server.url)
-        .get(path + 'me/videos/4da6fde3-88f7-4d16-b119-108df5630b06/rating')
-        .set('Authorization', 'Bearer ' + userAccessToken)
-        .set('Accept', 'application/json')
-        .expect(404, done)
-    })
-
-    it('Should success with the correct parameters', function (done) {
-      request(server.url)
-        .get(path + 'me/videos/' + videoId + '/rating')
-        .set('Authorization', 'Bearer ' + userAccessToken)
-        .set('Accept', 'application/json')
-        .expect(200, done)
-    })
-  })
-
-  describe('When removing an user', function () {
-    it('Should fail with an incorrect id', function (done) {
-      request(server.url)
-        .delete(path + 'bla-bla')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail with the root user', function (done) {
-      request(server.url)
-        .delete(path + rootId)
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should return 404 with a non existing id', function (done) {
-      request(server.url)
-        .delete(path + '45')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(404, done)
-    })
-  })
-
-  describe('When removing an user', function () {
-    it('Should fail with an incorrect id', function (done) {
-      request(server.url)
-        .delete(path + 'bla-bla')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail with the root user', function (done) {
-      request(server.url)
-        .delete(path + rootId)
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should return 404 with a non existing id', function (done) {
-      request(server.url)
-        .delete(path + '45')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(404, done)
-    })
-  })
-
-  describe('When register a new user', function () {
-    const registrationPath = path + '/register'
-
-    it('Should fail with a too small username', function (done) {
-      const data = {
-        username: 'ji',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too long username', function (done) {
-      const data = {
-        username: 'mysuperusernamewhichisverylong',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with an incorrect username', function (done) {
-      const data = {
-        username: 'my username',
-        email: 'test@example.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a missing email', function (done) {
-      const data = {
-        username: 'ji',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with an invalid email', function (done) {
-      const data = {
-        username: 'mysuperusernamewhichisverylong',
-        email: 'testexample.com',
-        password: 'mysuperpassword'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too small password', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'test@example.com',
-        password: 'bla'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a too long password', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'test@example.com',
-        password: 'my super long password which is very very very very very very very very very very very very very very' +
-                  'very very very very very very very very very very very very very very very veryv very very very very' +
-                  'very very very very very very very very very very very very very very very very very very very very long'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done)
-    })
-
-    it('Should fail if we register a user with the same username', function (done) {
-      const data = {
-        username: 'root',
-        email: 'test@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done, 409)
-    })
-
-    it('Should fail if we register a user with the same email', function (done) {
-      const data = {
-        username: 'myusername',
-        email: 'admin1@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done, 409)
-    })
-
-    it('Should succeed with the correct params', function (done) {
-      const data = {
-        username: 'user3',
-        email: 'test3@example.com',
-        password: 'my super password'
-      }
-
-      requestsUtils.makePostBodyRequest(server.url, registrationPath, server.accessToken, data, done, 204)
-    })
-
-    it('Should fail on a server with registration disabled', function (done) {
-      const data = {
-        username: 'user4',
-        email: 'test4@example.com',
-        password: 'my super password 4'
-      }
-
-      requestsUtils.makePostBodyRequest(serverWithRegistrationDisabled.url, registrationPath, serverWithRegistrationDisabled.accessToken, data, done, 403)
-    })
-  })
-
-  describe('When registering multiple users on a server with users limit', function () {
-    it('Should fail when after 3 registrations', function (done) {
-      usersUtils.registerUser(server.url, 'user42', 'super password', 403, done)
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-    process.kill(-serverWithRegistrationDisabled.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
new file mode 100644 (file)
index 0000000..643a82a
--- /dev/null
@@ -0,0 +1,502 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import 'mocha'
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  uploadVideo,
+  getVideosList,
+  makePutBodyRequest,
+  createUser,
+  loginAndGetAccessToken,
+  getUsersList,
+  registerUser,
+  setAccessTokensToServers,
+  killallServers,
+  makePostBodyRequest,
+  getUserAccessToken
+} from '../../utils'
+
+describe('Test users API validators', function () {
+  const path = '/api/v1/users/'
+  let userId: number
+  let rootId: number
+  let videoId: number
+  let server: ServerInfo
+  let serverWithRegistrationDisabled: ServerInfo
+  let userAccessToken = ''
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+
+    server = await runServer(1)
+    serverWithRegistrationDisabled = await runServer(2)
+
+    await setAccessTokensToServers([ server ])
+
+    const username = 'user1'
+    const password = 'my super password'
+    await createUser(server.url, server.accessToken, username, password)
+
+    const videoAttributes = {}
+    await uploadVideo(server.url, server.accessToken, videoAttributes)
+
+    const res = await getVideosList(server.url)
+    const videos = res.body.data
+    videoId = videos[0].id
+
+    const user = {
+      username: 'user1',
+      password: 'my super password'
+    }
+    userAccessToken = await getUserAccessToken(server, user)
+  })
+
+  describe('When listing users', function () {
+    it('Should fail with a bad start pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ start: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with a bad count pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ count: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with an incorrect sort', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+  })
+
+  describe('When adding a new user', function () {
+    it('Should fail with a too small username', async function () {
+      const fields = {
+        username: 'ji',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too long username', async function () {
+      const fields = {
+        username: 'my_super_username_which_is_very_long',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with an incorrect username', async function () {
+      const fields = {
+        username: 'my username',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a missing email', async function () {
+      const fields = {
+        username: 'ji',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with an invalid email', async function () {
+      const fields = {
+        username: 'my_super_username_which_is_very_long',
+        email: 'test_example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too small password', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'test@example.com',
+        password: 'bla'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too long password', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'test@example.com',
+        password: 'my super long password which is very very very very very very very very very very very very very very' +
+                  'very very very very very very very very very very very very very very very veryv very very very very' +
+                  'very very very very very very very very very very very very very very very very very very very very long'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with an non authenticated user', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: 'super token', fields, statusCodeExpected: 401 })
+    })
+
+    it('Should fail if we add a user with the same username', async function () {
+      const fields = {
+        username: 'user1',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
+    })
+
+    it('Should fail if we add a user with the same email', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'user1@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 409 })
+    })
+
+    it('Should succeed with the correct params', async function () {
+      const fields = {
+        username: 'user2',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 })
+    })
+
+    it('Should fail with a non admin user', async function () {
+      server.user = {
+        username: 'user1',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+
+      userAccessToken = await loginAndGetAccessToken(server)
+      const fields = {
+        username: 'user3',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+      await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
+    })
+  })
+
+  describe('When updating a user', function () {
+    before(async function () {
+      const res = await getUsersList(server.url)
+
+      userId = res.body.data[1].id
+      rootId = res.body.data[2].id
+    })
+
+    it('Should fail with a too small password', async function () {
+      const fields = {
+        password: 'bla'
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + userId, token: userAccessToken, fields })
+    })
+
+    it('Should fail with a too long password', async function () {
+      const fields = {
+        password: 'my super long password which is very very very very very very very very very very very very very very' +
+                  'very very very very very very very very very very very very very very very veryv very very very very' +
+                  'very very very very very very very very very very very very very very very very very very very very long'
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + userId, token: userAccessToken, fields })
+    })
+
+    it('Should fail with an invalid display NSFW attribute', async function () {
+      const fields = {
+        displayNSFW: -1
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + userId, token: userAccessToken, fields })
+    })
+
+    it('Should fail with an non authenticated user', async function () {
+      const fields = {
+        password: 'my super password'
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + userId, token: 'super token', fields, statusCodeExpected: 401 })
+    })
+
+    it('Should succeed with the correct params', async function () {
+      const fields = {
+        password: 'my super password',
+        displayNSFW: true
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + userId, token: userAccessToken, fields, statusCodeExpected: 204 })
+    })
+  })
+
+  describe('When getting my information', function () {
+    it('Should fail with a non authenticated user', async function () {
+      await request(server.url)
+              .get(path + 'me')
+              .set('Authorization', 'Bearer fake_token')
+              .set('Accept', 'application/json')
+              .expect(401)
+    })
+
+    it('Should success with the correct parameters', async function () {
+      await request(server.url)
+              .get(path + 'me')
+              .set('Authorization', 'Bearer ' + userAccessToken)
+              .set('Accept', 'application/json')
+              .expect(200)
+    })
+  })
+
+  describe('When getting my video rating', function () {
+    it('Should fail with a non authenticated user', async function () {
+      await request(server.url)
+              .get(path + 'me/videos/' + videoId + '/rating')
+              .set('Authorization', 'Bearer fake_token')
+              .set('Accept', 'application/json')
+              .expect(401)
+    })
+
+    it('Should fail with an incorrect video uuid', async function () {
+      await request(server.url)
+              .get(path + 'me/videos/blabla/rating')
+              .set('Authorization', 'Bearer ' + userAccessToken)
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with an unknown video', async function () {
+      await request(server.url)
+              .get(path + 'me/videos/4da6fde3-88f7-4d16-b119-108df5630b06/rating')
+              .set('Authorization', 'Bearer ' + userAccessToken)
+              .set('Accept', 'application/json')
+              .expect(404)
+    })
+
+    it('Should success with the correct parameters', async function () {
+      await request(server.url)
+              .get(path + 'me/videos/' + videoId + '/rating')
+              .set('Authorization', 'Bearer ' + userAccessToken)
+              .set('Accept', 'application/json')
+              .expect(200)
+    })
+  })
+
+  describe('When removing an user', function () {
+    it('Should fail with an incorrect id', async function () {
+      await request(server.url)
+              .delete(path + 'bla-bla')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail with the root user', async function () {
+      await request(server.url)
+              .delete(path + rootId)
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should return 404 with a non existing id', async function () {
+      await request(server.url)
+              .delete(path + '45')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(404)
+    })
+  })
+
+  describe('When removing an user', function () {
+    it('Should fail with an incorrect id', async function () {
+      await request(server.url)
+              .delete(path + 'bla-bla')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail with the root user', async function () {
+      await request(server.url)
+              .delete(path + rootId)
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should return 404 with a non existing id', async function () {
+      await request(server.url)
+              .delete(path + '45')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(404)
+    })
+  })
+
+  describe('When register a new user', function () {
+    const registrationPath = path + '/register'
+
+    it('Should fail with a too small username', async function () {
+      const fields = {
+        username: 'ji',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too long username', async function () {
+      const fields = {
+        username: 'my_super_username_which_is_very_long',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with an incorrect username', async function () {
+      const fields = {
+        username: 'my username',
+        email: 'test@example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a missing email', async function () {
+      const fields = {
+        username: 'ji',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with an invalid email', async function () {
+      const fields = {
+        username: 'my_super_username_which_is_very_long',
+        email: 'test_example.com',
+        password: 'my_super_password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too small password', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'test@example.com',
+        password: 'bla'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a too long password', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'test@example.com',
+        password: 'my super long password which is very very very very very very very very very very very very very very' +
+                  'very very very very very very very very very very very very very very very veryv very very very very' +
+                  'very very very very very very very very very very very very very very very very very very very very long'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail if we register a user with the same username', async function () {
+      const fields = {
+        username: 'root',
+        email: 'test@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields, statusCodeExpected: 409 })
+    })
+
+    it('Should fail if we register a user with the same email', async function () {
+      const fields = {
+        username: 'my_username',
+        email: 'admin1@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields, statusCodeExpected: 409 })
+    })
+
+    it('Should succeed with the correct params', async function () {
+      const fields = {
+        username: 'user3',
+        email: 'test3@example.com',
+        password: 'my super password'
+      }
+
+      await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields, statusCodeExpected: 204 })
+    })
+
+    it('Should fail on a server with registration disabled', async function () {
+      const fields = {
+        username: 'user4',
+        email: 'test4@example.com',
+        password: 'my super password 4'
+      }
+
+      await makePostBodyRequest({
+        url: serverWithRegistrationDisabled.url,
+        path: registrationPath,
+        token: serverWithRegistrationDisabled.accessToken,
+        fields,
+        statusCodeExpected: 403
+      })
+    })
+  })
+
+  describe('When registering multiple users on a server with users limit', function () {
+    it('Should fail when after 3 registrations', async function () {
+      await registerUser(server.url, 'user42', 'super password', 403)
+    })
+  })
+
+  after(async function () {
+    killallServers([ server, serverWithRegistrationDisabled ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/video-abuses.js b/server/tests/api/check-params/video-abuses.js
deleted file mode 100644 (file)
index 8c520aa..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const requestsUtils = require('../../utils/requests')
-const serversUtils = require('../../utils/servers')
-const usersUtils = require('../../utils/users')
-const videosUtils = require('../../utils/videos')
-
-describe('Test video abuses API validators', function () {
-  let server = null
-  let userAccessToken = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(20000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      },
-      function (next) {
-        const username = 'user1'
-        const password = 'my super password'
-
-        usersUtils.createUser(server.url, server.accessToken, username, password, next)
-      },
-      function (next) {
-        const user = {
-          username: 'user1',
-          password: 'my super password'
-        }
-
-        loginUtils.getUserAccessToken(server, user, function (err, accessToken) {
-          if (err) throw err
-
-          userAccessToken = accessToken
-
-          next()
-        })
-      },
-      // Upload some videos on each pods
-      function (next) {
-        const videoAttributes = {}
-        videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, next)
-      },
-      function (next) {
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          server.video = videos[0]
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When listing video abuses', function () {
-    const path = '/api/v1/videos/abuse'
-
-    it('Should fail with a bad start pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ start: 'hello' })
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with a bad count pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ count: 'hello' })
-        .set('Accept', 'application/json')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail with an incorrect sort', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail with a non authenticated user', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(401, done)
-    })
-
-    it('Should fail with a non admin user', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .set('Authorization', 'Bearer ' + userAccessToken)
-        .expect(403, done)
-    })
-  })
-
-  describe('When reporting a video abuse', function () {
-    const basePath = '/api/v1/videos/'
-
-    it('Should fail with nothing', function (done) {
-      const path = basePath + server.video.id + '/abuse'
-      const data = {}
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a wrong video', function (done) {
-      const wrongPath = '/api/v1/videos/blabla/abuse'
-      const data = {}
-      requestsUtils.makePostBodyRequest(server.url, wrongPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a non authenticated user', function (done) {
-      const data = {}
-      const path = basePath + server.video.id + '/abuse'
-      requestsUtils.makePostBodyRequest(server.url, path, 'hello', data, done, 401)
-    })
-
-    it('Should fail with a reason too short', function (done) {
-      const data = {
-        reason: 'h'
-      }
-      const path = basePath + server.video.id + '/abuse'
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a reason too big', function (done) {
-      const data = {
-        reason: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
-                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
-                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
-                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
-      }
-      const path = basePath + server.video.id + '/abuse'
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts
new file mode 100644 (file)
index 0000000..30d1577
--- /dev/null
@@ -0,0 +1,146 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import 'mocha'
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  uploadVideo,
+  getVideosList,
+  createUser,
+  setAccessTokensToServers,
+  killallServers,
+  makePostBodyRequest,
+  getUserAccessToken
+} from '../../utils'
+
+describe('Test video abuses API validators', function () {
+  let server: ServerInfo
+  let userAccessToken = ''
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(20000)
+
+    await flushTests()
+
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+
+    const username = 'user1'
+    const password = 'my super password'
+    await createUser(server.url, server.accessToken, username, password)
+
+    userAccessToken = await getUserAccessToken(server, { username, password })
+
+    // Upload a video
+    const videoAttributes = {}
+    await uploadVideo(server.url, server.accessToken, videoAttributes)
+
+    const res = await getVideosList(server.url)
+    const videos = res.body.data
+    server.video = videos[0]
+  })
+
+  describe('When listing video abuses', function () {
+    const path = '/api/v1/videos/abuse'
+
+    it('Should fail with a bad start pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ start: 'hello' })
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with a bad count pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ count: 'hello' })
+              .set('Accept', 'application/json')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail with an incorrect sort', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail with a non authenticated user', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(401)
+    })
+
+    it('Should fail with a non admin user', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .set('Authorization', 'Bearer ' + userAccessToken)
+              .expect(403)
+    })
+  })
+
+  describe('When reporting a video abuse', function () {
+    const basePath = '/api/v1/videos/'
+
+    it('Should fail with nothing', async function () {
+      const path = basePath + server.video.id + '/abuse'
+      const fields = {}
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a wrong video', async function () {
+      const wrongPath = '/api/v1/videos/blabla/abuse'
+      const fields = {}
+      await makePostBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields})
+    })
+
+    it('Should fail with a non authenticated user', async function () {
+      const fields = {}
+      const path = basePath + server.video.id + '/abuse'
+      await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 })
+    })
+
+    it('Should fail with a reason too short', async function () {
+      const fields = {
+        reason: 'h'
+      }
+      const path = basePath + server.video.id + '/abuse'
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a reason too big', async function () {
+      const fields = {
+        reason: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
+                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
+                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' +
+                '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
+      }
+      const path = basePath + server.video.id + '/abuse'
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/video-blacklists.js b/server/tests/api/check-params/video-blacklists.js
deleted file mode 100644 (file)
index 53b503e..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const requestsUtils = require('../../utils/requests')
-const serversUtils = require('../../utils/servers')
-const usersUtils = require('../../utils/users')
-const videosUtils = require('../../utils/videos')
-
-describe('Test video blacklists API validators', function () {
-  let server = null
-  let userAccessToken = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      },
-      function (next) {
-        const username = 'user1'
-        const password = 'my super password'
-
-        usersUtils.createUser(server.url, server.accessToken, username, password, next)
-      },
-      function (next) {
-        const user = {
-          username: 'user1',
-          password: 'my super password'
-        }
-
-        loginUtils.getUserAccessToken(server, user, function (err, accessToken) {
-          if (err) throw err
-
-          userAccessToken = accessToken
-
-          next()
-        })
-      },
-      // Upload a video
-      function (next) {
-        const videoAttributes = {}
-        videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, next)
-      },
-      function (next) {
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          server.video = videos[0]
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When adding a video in blacklist', function () {
-    const basePath = '/api/v1/videos/'
-
-    it('Should fail with nothing', function (done) {
-      const path = basePath + server.video + '/blacklist'
-      const data = {}
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail with a wrong video', function (done) {
-      const wrongPath = '/api/v1/videos/blabla/blacklist'
-      const data = {}
-      requestsUtils.makePostBodyRequest(server.url, wrongPath, server.accessToken, data, done)
-    })
-
-    it('Should fail with a non authenticated user', function (done) {
-      const data = {}
-      const path = basePath + server.video + '/blacklist'
-      requestsUtils.makePostBodyRequest(server.url, path, 'hello', data, done, 401)
-    })
-
-    it('Should fail with a non admin user', function (done) {
-      const data = {}
-      const path = basePath + server.video + '/blacklist'
-      requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403)
-    })
-
-    it('Should fail with a local video', function (done) {
-      const data = {}
-      const path = basePath + server.video.id + '/blacklist'
-      requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 403)
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/video-blacklists.ts b/server/tests/api/check-params/video-blacklists.ts
new file mode 100644 (file)
index 0000000..d0ad78f
--- /dev/null
@@ -0,0 +1,90 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  uploadVideo,
+  getVideosList,
+  createUser,
+  setAccessTokensToServers,
+  killallServers,
+  makePostBodyRequest,
+  getUserAccessToken
+} from '../../utils'
+
+describe('Test video blacklists API validators', function () {
+  let server: ServerInfo
+  let userAccessToken = ''
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+
+    const username = 'user1'
+    const password = 'my super password'
+    await createUser(server.url, server.accessToken, username, password)
+    userAccessToken = await getUserAccessToken(server, { username, password })
+
+    // Upload a video
+    const videoAttributes = {}
+    await uploadVideo(server.url, server.accessToken, videoAttributes)
+
+    const res = await getVideosList(server.url)
+
+    const videos = res.body.data
+    server.video = videos[0]
+  })
+
+  describe('When adding a video in blacklist', function () {
+    const basePath = '/api/v1/videos/'
+
+    it('Should fail with nothing', async function () {
+      const path = basePath + server.video + '/blacklist'
+      const fields = {}
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a wrong video', async function () {
+      const wrongPath = '/api/v1/videos/blabla/blacklist'
+      const fields = {}
+      await makePostBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a non authenticated user', async function () {
+      const fields = {}
+      const path = basePath + server.video + '/blacklist'
+      await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 })
+    })
+
+    it('Should fail with a non admin user', async function () {
+      const fields = {}
+      const path = basePath + server.video + '/blacklist'
+      await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields, statusCodeExpected: 403 })
+    })
+
+    it('Should fail with a local video', async function () {
+      const fields = {}
+      const path = basePath + server.video.id + '/blacklist'
+      await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 403 })
+    })
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/check-params/videos.js b/server/tests/api/check-params/videos.js
deleted file mode 100644 (file)
index ce6c495..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const expect = chai.expect
-const pathUtils = require('path')
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('../../utils/login')
-const requestsUtils = require('../../utils/requests')
-const serversUtils = require('../../utils/servers')
-const videosUtils = require('../../utils/videos')
-
-describe('Test videos API validator', function () {
-  const path = '/api/v1/videos/'
-  let server = null
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(20000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  describe('When listing a video', function () {
-    it('Should fail with a bad start pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ start: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with a bad count pagination', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ count: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with an incorrect sort', function (done) {
-      request(server.url)
-        .get(path)
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-  })
-
-  describe('When searching a video', function () {
-    it('Should fail with nothing', function (done) {
-      request(server.url)
-        .get(pathUtils.join(path, 'search'))
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with a bad start pagination', function (done) {
-      request(server.url)
-        .get(pathUtils.join(path, 'search', 'test'))
-        .query({ start: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with a bad count pagination', function (done) {
-      request(server.url)
-        .get(pathUtils.join(path, 'search', 'test'))
-        .query({ count: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should fail with an incorrect sort', function (done) {
-      request(server.url)
-        .get(pathUtils.join(path, 'search', 'test'))
-        .query({ sort: 'hello' })
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-  })
-
-  describe('When adding a video', function () {
-    it('Should fail with nothing', function (done) {
-      const data = {}
-      const attach = {}
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without name', function (done) {
-      const data = {
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a long name', function (done) {
-      const data = {
-        name: 'My very very very very very very very very very very very very very very very very long name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without a category', function (done) {
-      const data = {
-        name: 'my super name',
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a bad category', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 125,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without a licence', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a bad licence', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 125,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a bad language', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 4,
-        language: 563,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without nsfw attribute', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 4,
-        language: 6,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a bad nsfw attribue', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 4,
-        language: 6,
-        nsfw: 2,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without description', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a long description', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description which is very very very very very very very very very very very very very very' +
-                     'very very very very very very very very very very very very very very very very very very very very very' +
-                     'very very very very very very very very very very very very very very very long',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with too many tags', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a tag length too low', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 't' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a tag length too big', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'mysupertagtoolong', 'tag1' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without an input file', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {}
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail without an incorrect input file', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short_fake.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should fail with a too big duration', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_too_long.webm')
-      }
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
-    })
-
-    it('Should succeed with the correct parameters', function (done) {
-      this.timeout(10000)
-
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 1,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      const attach = {
-        'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short.webm')
-      }
-
-      requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () {
-        attach.videofile = pathUtils.join(__dirname, '..', 'fixtures', 'video_short.mp4')
-        requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () {
-          attach.videofile = pathUtils.join(__dirname, '..', 'fixtures', 'video_short.ogv')
-          requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done, 204)
-        }, false)
-      }, false)
-    })
-  })
-
-  describe('When updating a video', function () {
-    let videoId
-
-    before(function (done) {
-      videosUtils.getVideosList(server.url, function (err, res) {
-        if (err) throw err
-
-        videoId = res.body.data[0].id
-
-        return done()
-      })
-    })
-
-    it('Should fail with nothing', function (done) {
-      const data = {}
-      requestsUtils.makePutBodyRequest(server.url, path, server.accessToken, data, done)
-    })
-
-    it('Should fail without a valid uuid', function (done) {
-      const data = {
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + 'blabla', server.accessToken, data, done)
-    })
-
-    it('Should fail with an unknown id', function (done) {
-      const data = {
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + '4da6fde3-88f7-4d16-b119-108df5630b06', server.accessToken, data, done, 404)
-    })
-
-    it('Should fail with a long name', function (done) {
-      const data = {
-        name: 'My very very very very very very very very very very very very very very very very long name',
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a bad category', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 128,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a bad licence', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 128,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a bad language', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 3,
-        language: 896,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a bad nsfw attribute', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 5,
-        language: 6,
-        nsfw: -4,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a long description', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description which is very very very very very very very very very very very very very very' +
-                     'very very very very very very very very very very very very very very very very very very very very very' +
-                     'very very very very very very very very very very very very very very very long',
-        tags: [ 'tag1', 'tag2' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with too many tags', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a tag length too low', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'tag1', 't' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a tag length too big', function (done) {
-      const data = {
-        name: 'my super name',
-        category: 5,
-        licence: 2,
-        language: 6,
-        nsfw: false,
-        description: 'my super description',
-        tags: [ 'mysupertagtoolong', 'tag1' ]
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId, server.accessToken, data, done)
-    })
-
-    it('Should fail with a video of another user')
-
-    it('Should fail with a video of another pod')
-  })
-
-  describe('When getting a video', function () {
-    it('Should return the list of the videos with nothing', function (done) {
-      request(server.url)
-        .get(path)
-        .set('Accept', 'application/json')
-        .expect(200)
-        .expect('Content-Type', /json/)
-        .end(function (err, res) {
-          if (err) throw err
-
-          expect(res.body.data).to.be.an('array')
-          expect(res.body.data.length).to.equal(3)
-
-          done()
-        })
-    })
-
-    it('Should fail without a correct uuid', function (done) {
-      request(server.url)
-        .get(path + 'coucou')
-        .set('Accept', 'application/json')
-        .expect(400, done)
-    })
-
-    it('Should return 404 with an incorrect video', function (done) {
-      request(server.url)
-        .get(path + '4da6fde3-88f7-4d16-b119-108df5630b06')
-        .set('Accept', 'application/json')
-        .expect(404, done)
-    })
-
-    it('Should succeed with the correct parameters')
-  })
-
-  describe('When rating a video', function () {
-    let videoId
-
-    before(function (done) {
-      videosUtils.getVideosList(server.url, function (err, res) {
-        if (err) throw err
-
-        videoId = res.body.data[0].id
-
-        return done()
-      })
-    })
-
-    it('Should fail without a valid uuid', function (done) {
-      const data = {
-        rating: 'like'
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + 'blabla/rate', server.accessToken, data, done)
-    })
-
-    it('Should fail with an unknown id', function (done) {
-      const data = {
-        rating: 'like'
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + '4da6fde3-88f7-4d16-b119-108df5630b06/rate', server.accessToken, data, done, 404)
-    })
-
-    it('Should fail with a wrong rating', function (done) {
-      const data = {
-        rating: 'likes'
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId + '/rate', server.accessToken, data, done)
-    })
-
-    it('Should succeed with the correct parameters', function (done) {
-      const data = {
-        rating: 'like'
-      }
-      requestsUtils.makePutBodyRequest(server.url, path + videoId + '/rate', server.accessToken, data, done, 204)
-    })
-  })
-
-  describe('When removing a video', function () {
-    it('Should have 404 with nothing', function (done) {
-      request(server.url)
-        .delete(path)
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail without a correct uuid', function (done) {
-      request(server.url)
-        .delete(path + 'hello')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(400, done)
-    })
-
-    it('Should fail with a video which does not exist', function (done) {
-      request(server.url)
-        .delete(path + '4da6fde3-88f7-4d16-b119-108df5630b06')
-        .set('Authorization', 'Bearer ' + server.accessToken)
-        .expect(404, done)
-    })
-
-    it('Should fail with a video of another user')
-
-    it('Should fail with a video of another pod')
-
-    it('Should succeed with the correct parameters')
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
new file mode 100644 (file)
index 0000000..8d30769
--- /dev/null
@@ -0,0 +1,677 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import { join } from 'path'
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  getVideosList,
+  makePutBodyRequest,
+  setAccessTokensToServers,
+  killallServers,
+  makePostUploadRequest
+} from '../../utils'
+
+describe('Test videos API validator', function () {
+  const path = '/api/v1/videos/'
+  let server: ServerInfo
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(20000)
+
+    await flushTests()
+
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+  })
+
+  describe('When listing a video', function () {
+    it('Should fail with a bad start pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ start: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with a bad count pagination', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ count: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with an incorrect sort', async function () {
+      await request(server.url)
+              .get(path)
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+  })
+
+  describe('When searching a video', function () {
+    it('Should fail with nothing', async function () {
+      await request(server.url)
+              .get(join(path, 'search'))
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with a bad start pagination', async function () {
+      await request(server.url)
+              .get(join(path, 'search', 'test'))
+              .query({ start: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with a bad count pagination', async function () {
+      await request(server.url)
+              .get(join(path, 'search', 'test'))
+              .query({ count: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should fail with an incorrect sort', async function () {
+      await request(server.url)
+              .get(join(path, 'search', 'test'))
+              .query({ sort: 'hello' })
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+  })
+
+  describe('When adding a video', function () {
+    it('Should fail with nothing', async function () {
+      const fields = {}
+      const attaches = {}
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without name', async function () {
+      const fields = {
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a long name', async function () {
+      const fields = {
+        name: 'My very very very very very very very very very very very very very very very very long name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without a category', async function () {
+      const fields = {
+        name: 'my super name',
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a bad category', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 125,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without a licence', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a bad licence', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 125,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a bad language', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 4,
+        language: 563,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without nsfw attribute', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 4,
+        language: 6,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a bad nsfw attribue', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 4,
+        language: 6,
+        nsfw: 2,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without description', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a long description', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description which is very very very very very very very very very very very very very very' +
+                     'very very very very very very very very very very very very very very very very very very very very very' +
+                     'very very very very very very very very very very very very very very very long',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with too many tags', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a tag length too low', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 't' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a tag length too big', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'my_super_tag_too_long', 'tag1' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without an input file', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {}
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail without an incorrect input file', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short_fake.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should fail with a too big duration', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_too_long.webm')
+      }
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
+    })
+
+    it('Should succeed with the correct parameters', async function () {
+      this.timeout(10000)
+
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 1,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      const attaches = {
+        'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
+      }
+
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches, statusCodeExpected: 204 })
+
+      attaches.videofile = join(__dirname, '..', 'fixtures', 'video_short.mp4')
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches, statusCodeExpected: 204 })
+
+      attaches.videofile = join(__dirname, '..', 'fixtures', 'video_short.ogv')
+      await makePostUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches, statusCodeExpected: 204 })
+    })
+  })
+
+  describe('When updating a video', function () {
+    let videoId
+
+    before(async function () {
+      const res = await getVideosList(server.url)
+      videoId = res.body.data[0].id
+    })
+
+    it('Should fail with nothing', async function () {
+      const fields = {}
+      await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields })
+    })
+
+    it('Should fail without a valid uuid', async function () {
+      const fields = {
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + 'blabla', token: server.accessToken, fields })
+    })
+
+    it('Should fail with an unknown id', async function () {
+      const fields = {
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({
+        url: server.url,
+        path: path + '4da6fde3-88f7-4d16-b119-108df5630b06',
+        token: server.accessToken,
+        fields,
+        statusCodeExpected: 404
+      })
+    })
+
+    it('Should fail with a long name', async function () {
+      const fields = {
+        name: 'My very very very very very very very very very very very very very very very very long name',
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a bad category', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 128,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a bad licence', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 128,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a bad language', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 3,
+        language: 896,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a bad nsfw attribute', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 5,
+        language: 6,
+        nsfw: -4,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a long description', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description which is very very very very very very very very very very very very very very' +
+                     'very very very very very very very very very very very very very very very very very very very very very' +
+                     'very very very very very very very very very very very very very very very long',
+        tags: [ 'tag1', 'tag2' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with too many tags', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a tag length too low', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'tag1', 't' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a tag length too big', async function () {
+      const fields = {
+        name: 'my super name',
+        category: 5,
+        licence: 2,
+        language: 6,
+        nsfw: false,
+        description: 'my super description',
+        tags: [ 'my_super_tag_too_long', 'tag1' ]
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
+    })
+
+    it('Should fail with a video of another user')
+
+    it('Should fail with a video of another pod')
+  })
+
+  describe('When getting a video', function () {
+    it('Should return the list of the videos with nothing', async function () {
+      const res = await request(server.url)
+                          .get(path)
+                          .set('Accept', 'application/json')
+                          .expect(200)
+                          .expect('Content-Type', /json/)
+
+      expect(res.body.data).to.be.an('array')
+      expect(res.body.data.length).to.equal(3)
+    })
+
+    it('Should fail without a correct uuid', async function () {
+      await request(server.url)
+              .get(path + 'coucou')
+              .set('Accept', 'application/json')
+              .expect(400)
+    })
+
+    it('Should return 404 with an incorrect video', async function () {
+      await request(server.url)
+              .get(path + '4da6fde3-88f7-4d16-b119-108df5630b06')
+              .set('Accept', 'application/json')
+              .expect(404)
+    })
+
+    it('Should succeed with the correct parameters')
+  })
+
+  describe('When rating a video', function () {
+    let videoId
+
+    before(async function () {
+      const res = await getVideosList(server.url)
+      videoId = res.body.data[0].id
+    })
+
+    it('Should fail without a valid uuid', async function () {
+      const fields = {
+        rating: 'like'
+      }
+      await makePutBodyRequest({ url: server.url, path: path + 'blabla/rate', token: server.accessToken, fields })
+    })
+
+    it('Should fail with an unknown id', async function () {
+      const fields = {
+        rating: 'like'
+      }
+      await makePutBodyRequest({
+        url: server.url,
+        path: path + '4da6fde3-88f7-4d16-b119-108df5630b06/rate',
+        token: server.accessToken,
+        fields,
+        statusCodeExpected: 404
+      })
+    })
+
+    it('Should fail with a wrong rating', async function () {
+      const fields = {
+        rating: 'likes'
+      }
+      await makePutBodyRequest({ url: server.url, path: path + videoId + '/rate', token: server.accessToken, fields })
+    })
+
+    it('Should succeed with the correct parameters', async function () {
+      const fields = {
+        rating: 'like'
+      }
+      await makePutBodyRequest({
+        url: server.url,
+        path: path + videoId + '/rate',
+        token: server.accessToken,
+        fields,
+        statusCodeExpected: 204
+      })
+    })
+  })
+
+  describe('When removing a video', function () {
+    it('Should have 404 with nothing', async function () {
+      await request(server.url)
+              .delete(path)
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail without a correct uuid', async function () {
+      await request(server.url)
+              .delete(path + 'hello')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(400)
+    })
+
+    it('Should fail with a video which does not exist', async function () {
+      await request(server.url)
+              .delete(path + '4da6fde3-88f7-4d16-b119-108df5630b06')
+              .set('Authorization', 'Bearer ' + server.accessToken)
+              .expect(404)
+    })
+
+    it('Should fail with a video of another user')
+
+    it('Should fail with a video of another pod')
+
+    it('Should succeed with the correct parameters')
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/config.js b/server/tests/api/config.js
deleted file mode 100644 (file)
index dc3cce0..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const expect = chai.expect
-const series = require('async/series')
-
-const serversUtils = require('../utils/servers')
-const configUtils = require('../utils/config')
-const usersUtils = require('../utils/users')
-
-describe('Test config', function () {
-  let server = null
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should have a correct config on a server with registration enabled', function (done) {
-    configUtils.getConfig(server.url, function (err, res) {
-      if (err) throw err
-
-      const data = res.body
-
-      expect(data.signup.allowed).to.be.true
-
-      done()
-    })
-  })
-
-  it('Should have a correct config on a server with registration enabled and a users limit', function (done) {
-    series([
-      function (next) {
-        usersUtils.registerUser(server.url, 'user1', 'super password', next)
-      },
-
-      function (next) {
-        usersUtils.registerUser(server.url, 'user2', 'super password', next)
-      },
-
-      function (next) {
-        usersUtils.registerUser(server.url, 'user3', 'super password', next)
-      }
-
-    ], function (err) {
-      if (err) throw err
-
-      configUtils.getConfig(server.url, function (err, res) {
-        if (err) throw err
-
-        const data = res.body
-
-        expect(data.signup.allowed).to.be.false
-
-        done()
-      })
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/config.ts b/server/tests/api/config.ts
new file mode 100644 (file)
index 0000000..3dda3b4
--- /dev/null
@@ -0,0 +1,50 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  getConfig,
+  flushTests,
+  runServer,
+  registerUser
+} from '../utils'
+
+describe('Test config', function () {
+  let server = null
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+    server = await runServer(1)
+  })
+
+  it('Should have a correct config on a server with registration enabled', async function () {
+    const res = await getConfig(server.url)
+    const data = res.body
+
+    expect(data.signup.allowed).to.be.true
+  })
+
+  it('Should have a correct config on a server with registration enabled and a users limit', async function () {
+    await registerUser(server.url, 'user1', 'super password')
+    await registerUser(server.url, 'user2', 'super password')
+    await registerUser(server.url, 'user3', 'super password')
+
+    const res = await getConfig(server.url)
+    const data = res.body
+
+    expect(data.signup.allowed).to.be.false
+  })
+
+  after(async function () {
+    process.kill(-server.app.pid)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/friends-advanced.js b/server/tests/api/friends-advanced.js
deleted file mode 100644 (file)
index 89dc080..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const series = require('async/series')
-
-const loginUtils = require('../utils/login')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-
-describe('Test advanced friends', function () {
-  let servers = []
-
-  function makeFriends (podNumber, callback) {
-    const server = servers[podNumber - 1]
-    return podsUtils.makeFriends(server.url, server.accessToken, callback)
-  }
-
-  function quitFriends (podNumber, callback) {
-    const server = servers[podNumber - 1]
-    return podsUtils.quitFriends(server.url, server.accessToken, callback)
-  }
-
-  function removeFriend (podNumber, podNumberToRemove, callback) {
-    const server = servers[podNumber - 1]
-    const serverToRemove = servers[podNumberToRemove - 1]
-
-    getFriendsList(podNumber, function (err, res) {
-      if (err) throw err
-
-      let friendsList = res.body.data
-      let podToRemove = friendsList.find((friend) => (friend.host === serverToRemove.host))
-
-      return podsUtils.quitOneFriend(server.url, server.accessToken, podToRemove.id, callback)
-    })
-  }
-
-  function getFriendsList (podNumber, end) {
-    const server = servers[podNumber - 1]
-    return podsUtils.getFriendsList(server.url, end)
-  }
-
-  function uploadVideo (podNumber, callback) {
-    const videoAttributes = {
-      tags: [ 'tag1', 'tag2' ]
-    }
-    const server = servers[podNumber - 1]
-
-    return videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, callback)
-  }
-
-  function getVideos (podNumber, callback) {
-    return videosUtils.getVideosList(servers[podNumber - 1].url, callback)
-  }
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(120000)
-    serversUtils.flushAndRunMultipleServers(6, function (serversRun, urlsRun) {
-      servers = serversRun
-
-      each(servers, function (server, callbackEach) {
-        loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-          if (err) return callbackEach(err)
-
-          server.accessToken = accessToken
-          callbackEach()
-        })
-      }, done)
-    })
-  })
-
-  it('Should make friends with two pod each in a different group', function (done) {
-    this.timeout(20000)
-
-    series([
-      // Pod 3 makes friend with the first one
-      function (next) {
-        makeFriends(3, next)
-      },
-      // Pod 4 makes friend with the second one
-      function (next) {
-        makeFriends(4, next)
-      },
-      // Now if the fifth wants to make friends with the third et the first
-      function (next) {
-        makeFriends(5, next)
-      },
-      function (next) {
-        setTimeout(next, 11000)
-      }],
-      function (err) {
-        if (err) throw err
-
-        // It should have 0 friends
-        getFriendsList(5, function (err, res) {
-          if (err) throw err
-
-          expect(res.body.data.length).to.equal(0)
-
-          done()
-        })
-      }
-    )
-  })
-
-  it('Should quit all friends', function (done) {
-    this.timeout(10000)
-
-    series([
-      function (next) {
-        quitFriends(1, next)
-      },
-      function (next) {
-        quitFriends(2, next)
-      }],
-      function (err) {
-        if (err) throw err
-
-        each([ 1, 2, 3, 4, 5, 6 ], function (i, callback) {
-          getFriendsList(i, function (err, res) {
-            if (err) throw err
-
-            expect(res.body.data.length).to.equal(0)
-
-            callback()
-          })
-        }, done)
-      }
-    )
-  })
-
-  it('Should make friends with the pods 1, 2, 3', function (done) {
-    this.timeout(150000)
-
-    series([
-      // Pods 1, 2, 3 and 4 become friends
-      function (next) {
-        makeFriends(2, next)
-      },
-      function (next) {
-        makeFriends(1, next)
-      },
-      function (next) {
-        makeFriends(4, next)
-      },
-      // Check the pods 1, 2, 3 and 4 are friends
-      function (next) {
-        each([ 1, 2, 3, 4 ], function (i, callback) {
-          getFriendsList(i, function (err, res) {
-            if (err) throw err
-
-            expect(res.body.data.length).to.equal(3)
-
-            callback()
-          })
-        }, next)
-      },
-      // Kill pod 4
-      function (next) {
-        servers[3].app.kill()
-        next()
-      },
-      // Expulse pod 4 from pod 1 and 2
-      function (next) {
-        uploadVideo(1, next)
-      },
-      function (next) {
-        uploadVideo(2, next)
-      },
-      function (next) {
-        setTimeout(next, 11000)
-      },
-      function (next) {
-        uploadVideo(1, next)
-      },
-      function (next) {
-        uploadVideo(2, next)
-      },
-      function (next) {
-        setTimeout(next, 22000)
-      },
-      // Check the pods 1, 2 expulsed pod 4
-      function (next) {
-        each([ 1, 2 ], function (i, callback) {
-          getFriendsList(i, function (err, res) {
-            if (err) throw err
-
-            // Pod 4 should not be our friend
-            const result = res.body.data
-            expect(result.length).to.equal(2)
-            for (const pod of result) {
-              expect(pod.host).not.equal(servers[3].host)
-            }
-
-            callback()
-          })
-        }, next)
-      },
-      // Rerun server 4
-      function (next) {
-        serversUtils.runServer(4, function (server) {
-          servers[3].app = server.app
-          next()
-        })
-      },
-      function (next) {
-        getFriendsList(4, function (err, res) {
-          if (err) throw err
-
-          // Pod 4 didn't know pod 1 and 2 removed it
-          expect(res.body.data.length).to.equal(3)
-          next()
-        })
-      },
-      // Pod 6 asks pod 1, 2 and 3
-      function (next) {
-        makeFriends(6, next)
-      },
-      function (next) {
-        setTimeout(next, 11000)
-      }],
-      function (err) {
-        if (err) throw err
-
-        getFriendsList(6, function (err, res) {
-          if (err) throw err
-
-          // Pod 4 should not be our friend
-          const result = res.body.data
-          expect(result.length).to.equal(3)
-          for (const pod of result) {
-            expect(pod.host).not.equal(servers[3].host)
-          }
-
-          done()
-        })
-      }
-    )
-  })
-
-  it('Should pod 1 quit friends', function (done) {
-    this.timeout(25000)
-
-    series([
-      // Upload a video on server 3 for aditionnal tests
-      function (next) {
-        uploadVideo(3, next)
-      },
-      function (next) {
-        setTimeout(next, 15000)
-      },
-      function (next) {
-        quitFriends(1, next)
-      },
-      // Remove pod 1 from pod 2
-      function (next) {
-        getVideos(1, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          expect(videos).to.be.an('array')
-          expect(videos.length).to.equal(2)
-
-          next()
-        })
-      }],
-      function (err) {
-        if (err) throw err
-
-        getVideos(2, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          expect(videos).to.be.an('array')
-          expect(videos.length).to.equal(3)
-          done()
-        })
-      }
-    )
-  })
-
-  it('Should make friends between pod 1 and 2 and exchange their videos', function (done) {
-    this.timeout(20000)
-    makeFriends(1, function () {
-      setTimeout(function () {
-        getVideos(1, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          expect(videos).to.be.an('array')
-          expect(videos.length).to.equal(5)
-
-          done()
-        })
-      }, 11000)
-    })
-  })
-
-  it('Should allow pod 6 to quit pod 1 & 2 and be friend with pod 3', function (done) {
-    this.timeout(30000)
-
-    series([
-      // Pod 3 should have 4 friends
-      function (next) {
-        getFriendsList(3, function (err, res) {
-          if (err) throw err
-
-          const friendsList = res.body.data
-          expect(friendsList).to.be.an('array')
-          expect(friendsList.length).to.equal(4)
-
-          next()
-       })
-      },
-      // Pod 1, 2, 6 should have 3 friends each
-      function (next) {
-       each([ 1, 2, 6 ], function (i, callback) {
-          getFriendsList(i, function (err, res) {
-            if (err) throw err
-
-            const friendsList = res.body.data
-            expect(friendsList).to.be.an('array')
-            expect(friendsList.length).to.equal(3)
-
-            callback()
-          })
-        }, next)
-      },
-      function (next) {
-        removeFriend(6, 1, next)
-      },
-      function (next) {
-        removeFriend(6, 2, next)
-      },
-      // Pod 6 should now have only 1 friend (and it should be Pod 3)
-      function (next) {
-        getFriendsList(6, function (err, res) {
-          if (err) throw err
-
-          const friendsList = res.body.data
-          expect(friendsList).to.be.an('array')
-          expect(friendsList.length).to.equal(1)
-          expect(friendsList[0].host).to.equal(servers[2].host)
-
-          next()
-       })
-      },
-      // Pod 1 & 2 should not know friend 6 anymore
-      function (next) {
-        each([ 1, 2 ], function (i, callback) {
-          getFriendsList(i, function (err, res) {
-            if (err) throw err
-
-            const friendsList = res.body.data
-            expect(friendsList).to.be.an('array')
-            expect(friendsList.length).to.equal(2)
-
-            callback()
-          })
-        }, next)
-      },
-      // Pod 3 should know every pod
-      function (next) {
-        getFriendsList(3, function (err, res) {
-          if (err) throw err
-
-          const friendsList = res.body.data
-          expect(friendsList).to.be.an('array')
-          expect(friendsList.length).to.equal(4)
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/friends-advanced.ts b/server/tests/api/friends-advanced.ts
new file mode 100644 (file)
index 0000000..dc5c83c
--- /dev/null
@@ -0,0 +1,261 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  uploadVideo,
+  quitFriends,
+  getVideosList,
+  wait,
+  setAccessTokensToServers,
+  flushAndRunMultipleServers,
+  killallServers,
+  makeFriends,
+  getFriendsList,
+  quitOneFriend
+} from '../utils'
+
+describe('Test advanced friends', function () {
+  let servers: ServerInfo[] = []
+
+  async function makeFriendsWrapper (podNumber: number) {
+    const server = servers[podNumber - 1]
+    return await makeFriends(server.url, server.accessToken)
+  }
+
+  async function quitFriendsWrapper (podNumber: number) {
+    const server = servers[podNumber - 1]
+    return await quitFriends(server.url, server.accessToken)
+  }
+
+  async function removeFriendWrapper (podNumber: number, podNumberToRemove: number) {
+    const server = servers[podNumber - 1]
+    const serverToRemove = servers[podNumberToRemove - 1]
+
+    const res = await getFriendsList(server.url)
+
+    let friendsList = res.body.data
+    let podToRemove = friendsList.find(friend => (friend.host === serverToRemove.host))
+
+    return await quitOneFriend(server.url, server.accessToken, podToRemove.id)
+  }
+
+  async function getFriendsListWrapper (podNumber: number) {
+    const server = servers[podNumber - 1]
+    return await getFriendsList(server.url)
+  }
+
+  async function uploadVideoWrapper (podNumber: number) {
+    const videoAttributes = {
+      tags: [ 'tag1', 'tag2' ]
+    }
+    const server = servers[podNumber - 1]
+
+    return await uploadVideo(server.url, server.accessToken, videoAttributes)
+  }
+
+  async function getVideosWrapper (podNumber: number) {
+    return await getVideosList(servers[podNumber - 1].url)
+  }
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(120000)
+
+    servers = await flushAndRunMultipleServers(6)
+    await setAccessTokensToServers(servers)
+  })
+
+  it('Should make friends with two pod each in a different group', async function () {
+    this.timeout(20000)
+
+    // Pod 3 makes friend with the first one
+    await makeFriendsWrapper(3)
+
+    // Pod 4 makes friend with the second one
+    await makeFriendsWrapper(4)
+
+    // Now if the fifth wants to make friends with the third et the first
+    await makeFriendsWrapper(5)
+
+    await wait(11000)
+
+      // It should have 0 friends
+    const res = await getFriendsListWrapper(5)
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should quit all friends', async function () {
+    this.timeout(10000)
+
+    await quitFriendsWrapper(1)
+    await quitFriendsWrapper(2)
+
+    const serverNumbersToTest = [ 1, 2, 3, 4, 5, 6 ]
+    for (const i of serverNumbersToTest) {
+      const res = await getFriendsListWrapper(i)
+      expect(res.body.data.length).to.equal(0)
+    }
+  })
+
+  it('Should make friends with the pods 1, 2, 3', async function () {
+    this.timeout(150000)
+
+    // Pods 1, 2, 3 and 4 become friends
+    await makeFriendsWrapper(2)
+    await makeFriendsWrapper(1)
+    await makeFriendsWrapper(4)
+
+    // Check the pods 1, 2, 3 and 4 are friends
+    let serverNumbersToTest = [ 1, 2, 3, 4 ]
+    for (const i of serverNumbersToTest) {
+      const res = await getFriendsListWrapper(i)
+      expect(res.body.data.length).to.equal(3)
+    }
+
+    // Kill pod 4
+    servers[3].app.kill()
+
+    // Remove pod 4 from pod 1 and 2
+    await uploadVideoWrapper(1)
+    await uploadVideoWrapper(2)
+
+    await wait(11000)
+
+    await uploadVideoWrapper(1)
+    await uploadVideoWrapper(2)
+
+    await wait(11000)
+
+    serverNumbersToTest = [ 1, 2 ]
+
+    for (const i of serverNumbersToTest) {
+      const res = await getFriendsListWrapper(i)
+
+      // Pod 4 should not be our friend
+      const friends = res.body.data
+      expect(friends.length).to.equal(2)
+
+      for (const pod of friends) {
+        expect(pod.host).not.equal(servers[3].host)
+      }
+    }
+
+      // Rerun server 4
+    const newServer = await runServer(4)
+    servers[3].app = newServer.app
+    servers[3].app
+
+    const res1 = await getFriendsListWrapper(4)
+
+    // Pod 4 didn't know pod 1 and 2 removed it
+    expect(res1.body.data.length).to.equal(3)
+
+    // Pod 6 asks pod 1, 2 and 3
+    await makeFriendsWrapper(6)
+
+    await wait(11000)
+
+    const res2 = await getFriendsListWrapper(6)
+
+    // Pod 4 should not be our friend
+    const friends = res2.body.data
+    expect(friends.length).to.equal(3)
+    for (const pod of friends) {
+      expect(pod.host).not.equal(servers[3].host)
+    }
+  })
+
+  it('Should pod 1 quit friends', async function () {
+    this.timeout(25000)
+
+    // Upload a video on server 3 for additional tests
+    await uploadVideoWrapper(3)
+
+    await wait(15000)
+
+    await quitFriendsWrapper(1)
+
+    // Remove pod 1 from pod 2
+    const res1 = await getVideosWrapper(1)
+    const videos1 = res1.body.data
+    expect(videos1).to.be.an('array')
+    expect(videos1.length).to.equal(2)
+
+    const res2 = await getVideosWrapper(2)
+    const videos2 = res2.body.data
+    expect(videos2).to.be.an('array')
+    expect(videos2.length).to.equal(3)
+  })
+
+  it('Should make friends between pod 1 and 2 and exchange their videos', async function () {
+    this.timeout(20000)
+
+    await makeFriendsWrapper(1)
+
+    await wait(11000)
+
+    const res = await getVideosWrapper(1)
+    const videos = res.body.data
+    expect(videos).to.be.an('array')
+    expect(videos.length).to.equal(5)
+  })
+
+  it('Should allow pod 6 to quit pod 1 & 2 and be friend with pod 3', async function () {
+    this.timeout(30000)
+
+    // Pod 3 should have 4 friends
+    const res1 = await getFriendsListWrapper(3)
+    const friendsList1 = res1.body.data
+    expect(friendsList1).to.be.an('array')
+    expect(friendsList1.length).to.equal(4)
+
+    // Pod 1, 2, 6 should have 3 friends each
+    let serverNumbersToTest = [ 1, 2, 6 ]
+    for (const i of serverNumbersToTest) {
+      const res = await getFriendsListWrapper(i)
+      const friendsList = res.body.data
+      expect(friendsList).to.be.an('array')
+      expect(friendsList.length).to.equal(3)
+    }
+
+    await removeFriendWrapper(6, 1)
+    await removeFriendWrapper(6, 2)
+
+    // Pod 6 should now have only 1 friend (and it should be Pod 3)
+    const res2 = await getFriendsListWrapper(6)
+    const friendsList2 = res2.body.data
+    expect(friendsList2).to.be.an('array')
+    expect(friendsList2.length).to.equal(1)
+    expect(friendsList2[0].host).to.equal(servers[2].host)
+
+    // Pod 1 & 2 should not know friend 6 anymore
+    serverNumbersToTest = [ 1, 2 ]
+    for (const i of serverNumbersToTest) {
+      const res = await getFriendsListWrapper(i)
+      const friendsList = res.body.data
+      expect(friendsList).to.be.an('array')
+      expect(friendsList.length).to.equal(2)
+    }
+
+    // Pod 3 should know every pod
+    const res3 = await getFriendsListWrapper(3)
+    const friendsList3 = res3.body.data
+    expect(friendsList3).to.be.an('array')
+    expect(friendsList3.length).to.equal(4)
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/friends-basic.js b/server/tests/api/friends-basic.js
deleted file mode 100644 (file)
index 5f1fdd2..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const series = require('async/series')
-
-const loginUtils = require('../utils/login')
-const miscsUtils = require('../utils/miscs')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-
-describe('Test basic friends', function () {
-  let servers = []
-
-  function makeFriends (podNumber, callback) {
-    const server = servers[podNumber - 1]
-    return podsUtils.makeFriends(server.url, server.accessToken, callback)
-  }
-
-  function testMadeFriends (servers, serverToTest, callback) {
-    const friends = []
-    for (let i = 0; i < servers.length; i++) {
-      if (servers[i].url === serverToTest.url) continue
-      friends.push(servers[i].host)
-    }
-
-    podsUtils.getFriendsList(serverToTest.url, function (err, res) {
-      if (err) throw err
-
-      const result = res.body.data
-      expect(result).to.be.an('array')
-      expect(result.length).to.equal(2)
-
-      const resultHosts = [ result[0].host, result[1].host ]
-      expect(resultHosts[0]).to.not.equal(resultHosts[1])
-
-      const errorString = 'Friends host do not correspond for ' + serverToTest.host
-      expect(friends).to.contain(resultHosts[0], errorString)
-      expect(friends).to.contain(resultHosts[1], errorString)
-      callback()
-    })
-  }
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(120000)
-    serversUtils.flushAndRunMultipleServers(3, function (serversRun, urlsRun) {
-      servers = serversRun
-
-      each(servers, function (server, callbackEach) {
-        loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-          if (err) return callbackEach(err)
-
-          server.accessToken = accessToken
-          callbackEach()
-        })
-      }, done)
-    })
-  })
-
-  it('Should not have friends', function (done) {
-    each(servers, function (server, callback) {
-      podsUtils.getFriendsList(server.url, function (err, res) {
-        if (err) throw err
-
-        const result = res.body.data
-        expect(result).to.be.an('array')
-        expect(result.length).to.equal(0)
-        callback()
-      })
-    }, done)
-  })
-
-  it('Should make friends', function (done) {
-    this.timeout(120000)
-
-    series([
-      // The second pod make friend with the third
-      function (next) {
-        makeFriends(2, next)
-      },
-      // Wait for the request between pods
-      function (next) {
-        setTimeout(next, 11000)
-      },
-      // The second pod should have the third as a friend
-      function (next) {
-        podsUtils.getFriendsList(servers[1].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(1)
-
-          const pod = result[0]
-          expect(pod.host).to.equal(servers[2].host)
-          expect(pod.email).to.equal('admin3@example.com')
-          expect(pod.score).to.equal(20)
-          expect(miscsUtils.dateIsValid(pod.createdAt)).to.be.true
-
-          next()
-        })
-      },
-      // Same here, the third pod should have the second pod as a friend
-      function (next) {
-        podsUtils.getFriendsList(servers[2].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(1)
-
-          const pod = result[0]
-          expect(pod.host).to.equal(servers[1].host)
-          expect(pod.email).to.equal('admin2@example.com')
-          expect(pod.score).to.equal(20)
-          expect(miscsUtils.dateIsValid(pod.createdAt)).to.be.true
-
-          next()
-        })
-      },
-      // Finally the first pod make friend with the second pod
-      function (next) {
-        makeFriends(1, next)
-      },
-      // Wait for the request between pods
-      function (next) {
-        setTimeout(next, 11000)
-      }
-    ],
-    // Now each pod should be friend with the other ones
-    function (err) {
-      if (err) throw err
-      each(servers, function (server, callback) {
-        testMadeFriends(servers, server, callback)
-      }, done)
-    })
-  })
-
-  it('Should not be allowed to make friend again', function (done) {
-    this.timeout(10000)
-    const server = servers[1]
-    podsUtils.makeFriends(server.url, server.accessToken, 409, done)
-  })
-
-  it('Should quit friends of pod 2', function (done) {
-    this.timeout(10000)
-
-    series([
-      // Pod 1 quit friends
-      function (next) {
-        const server = servers[1]
-        podsUtils.quitFriends(server.url, server.accessToken, next)
-      },
-      // Pod 1 should not have friends anymore
-      function (next) {
-        podsUtils.getFriendsList(servers[1].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(0)
-
-          next()
-        })
-      },
-      // Other pods shouldn't have pod 1 too
-      function (next) {
-        each([ servers[0].url, servers[2].url ], function (url, callback) {
-          podsUtils.getFriendsList(url, function (err, res) {
-            if (err) throw err
-
-            const result = res.body.data
-            expect(result).to.be.an('array')
-            expect(result.length).to.equal(1)
-            expect(result[0].host).not.to.be.equal(servers[1].host)
-            callback()
-          })
-        }, next)
-      }
-    ], done)
-  })
-
-  it('Should allow pod 2 to make friend again', function (done) {
-    this.timeout(120000)
-
-    const server = servers[1]
-    podsUtils.makeFriends(server.url, server.accessToken, function () {
-      setTimeout(function () {
-        each(servers, function (server, callback) {
-          testMadeFriends(servers, server, callback)
-        }, done)
-      }, 11000)
-    })
-  })
-
-  it('Should allow pod 1 to quit only pod 2', function (done) {
-    series([
-      // Pod 1 quits pod 2
-      function (next) {
-        const server = servers[0]
-
-        // Get pod 2 id so we can query it
-        podsUtils.getFriendsList(server.url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          let pod = result.find((friend) => (friend.host === servers[1].host))
-
-          // Remove it from the friends list
-          podsUtils.quitOneFriend(server.url, server.accessToken, pod.id, next)
-        })
-      },
-
-      // Pod 1 should have only pod 3 in its friends list
-      function (next) {
-        podsUtils.getFriendsList(servers[0].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(1)
-
-          const pod = result[0]
-          expect(pod.host).to.equal(servers[2].host)
-
-          next()
-        })
-      },
-
-      // Pod 2 should have only pod 3 in its friends list
-      function (next) {
-        podsUtils.getFriendsList(servers[1].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(1)
-
-          const pod = result[0]
-          expect(pod.host).to.equal(servers[2].host)
-
-          next()
-        })
-      },
-
-      // Pod 3 should have both pods in its friends list
-      function (next) {
-        podsUtils.getFriendsList(servers[2].url, function (err, res) {
-          if (err) throw err
-
-          const result = res.body.data
-          expect(result).to.be.an('array')
-          expect(result.length).to.equal(2)
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/friends-basic.ts b/server/tests/api/friends-basic.ts
new file mode 100644 (file)
index 0000000..13edf62
--- /dev/null
@@ -0,0 +1,203 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  quitFriends,
+  wait,
+  setAccessTokensToServers,
+  flushAndRunMultipleServers,
+  killallServers,
+  makeFriends,
+  getFriendsList,
+  dateIsValid,
+  quitOneFriend
+} from '../utils'
+
+describe('Test basic friends', function () {
+  let servers = []
+
+  function makeFriendsWrapper (podNumber: number) {
+    const server = servers[podNumber - 1]
+    return makeFriends(server.url, server.accessToken)
+  }
+
+  async function testMadeFriends (servers: ServerInfo[], serverToTest: ServerInfo) {
+    const friends = []
+    for (let i = 0; i < servers.length; i++) {
+      if (servers[i].url === serverToTest.url) continue
+      friends.push(servers[i].host)
+    }
+
+    const res = await getFriendsList(serverToTest.url)
+
+    const result = res.body.data
+    expect(result).to.be.an('array')
+    expect(result.length).to.equal(2)
+
+    const resultHosts = [ result[0].host, result[1].host ]
+    expect(resultHosts[0]).to.not.equal(resultHosts[1])
+
+    const errorString = 'Friends host do not correspond for ' + serverToTest.host
+    expect(friends).to.contain(resultHosts[0], errorString)
+    expect(friends).to.contain(resultHosts[1], errorString)
+  }
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(120000)
+
+    servers = await flushAndRunMultipleServers(3)
+
+    await setAccessTokensToServers(servers)
+  })
+
+  it('Should not have friends', async function () {
+    for (const server of servers) {
+      const res = await getFriendsList(server.url)
+
+      const result = res.body.data
+      expect(result).to.be.an('array')
+      expect(result.length).to.equal(0)
+    }
+  })
+
+  it('Should make friends', async function () {
+    this.timeout(120000)
+
+    // The second pod make friend with the third
+    await makeFriendsWrapper(2)
+
+    // Wait for the request between pods
+    await wait(11000)
+
+    // The second pod should have the third as a friend
+    const res1 = await getFriendsList(servers[1].url)
+
+    const friends = res1.body.data
+    expect(friends).to.be.an('array')
+    expect(friends.length).to.equal(1)
+
+    const pod1 = friends[0]
+    expect(pod1.host).to.equal(servers[2].host)
+    expect(pod1.email).to.equal('admin3@example.com')
+    expect(pod1.score).to.equal(20)
+    expect(dateIsValid(pod1.createdAt)).to.be.true
+
+    // Same here, the third pod should have the second pod as a friend
+    const res2 = await getFriendsList(servers[2].url)
+    const result = res2.body.data
+    expect(result).to.be.an('array')
+    expect(result.length).to.equal(1)
+
+    const pod2 = result[0]
+    expect(pod2.host).to.equal(servers[1].host)
+    expect(pod2.email).to.equal('admin2@example.com')
+    expect(pod2.score).to.equal(20)
+    expect(dateIsValid(pod2.createdAt)).to.be.true
+
+    // Finally the first pod make friend with the second pod
+    await makeFriendsWrapper(1)
+
+    // Wait for the request between pods
+    await wait(11000)
+
+    // Now each pod should be friend with the other ones
+    for (const server of servers) {
+      await testMadeFriends(servers, server)
+    }
+  })
+
+  it('Should not be allowed to make friend again', async function () {
+    this.timeout(10000)
+
+    const server = servers[1]
+    await makeFriends(server.url, server.accessToken, 409)
+  })
+
+  it('Should quit friends of pod 2', async function () {
+    this.timeout(10000)
+
+    // Pod 1 quit friends
+    await quitFriends(servers[1].url, servers[1].accessToken)
+
+    // Pod 1 should not have friends anymore
+    const res = await getFriendsList(servers[1].url)
+    const friends = res.body.data
+    expect(friends).to.be.an('array')
+    expect(friends).to.have.lengthOf(0)
+
+    // Other pods shouldn't have pod 1 too
+    const serversToTest = [ servers[0].url, servers[2].url ]
+    for (const url of serversToTest) {
+      const res = await getFriendsList(url)
+      const friends = res.body.data
+
+      expect(friends).to.be.an('array')
+      expect(friends.length).to.equal(1)
+      expect(friends[0].host).not.to.be.equal(servers[1].host)
+    }
+  })
+
+  it('Should allow pod 2 to make friend again', async function () {
+    this.timeout(120000)
+
+    const server = servers[1]
+    await makeFriends(server.url, server.accessToken)
+    await wait(11000)
+
+    for (const server of servers) {
+      await testMadeFriends(servers, server)
+    }
+  })
+
+  it('Should allow pod 1 to quit only pod 2', async function () {
+    // Pod 1 quits pod 2
+    const server = servers[0]
+
+    // Get pod 2 id so we can query it
+    const res1 = await getFriendsList(server.url)
+    const friends1 = res1.body.data
+    let pod1 = friends1.find(friend => (friend.host === servers[1].host))
+
+    // Remove it from the friends list
+    await quitOneFriend(server.url, server.accessToken, pod1.id)
+
+    // Pod 1 should have only pod 3 in its friends list
+    const res2 = await getFriendsList(servers[0].url)
+    const friends2 = res2.body.data
+    expect(friends2).to.be.an('array')
+    expect(friends2.length).to.equal(1)
+
+    const pod2 = friends2[0]
+    expect(pod2.host).to.equal(servers[2].host)
+
+    // Pod 2 should have only pod 3 in its friends list
+    const res3 = await getFriendsList(servers[1].url)
+    const friends3 = res3.body.data
+    expect(friends3).to.be.an('array')
+    expect(friends3.length).to.equal(1)
+
+    const pod = friends3[0]
+    expect(pod.host).to.equal(servers[2].host)
+
+    // Pod 3 should have both pods in its friends list
+    const res4 = await getFriendsList(servers[2].url)
+    const friends4 = res4.body.data
+    expect(friends4).to.be.an('array')
+    expect(friends4.length).to.equal(2)
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/index.js b/server/tests/api/index.js
deleted file mode 100644 (file)
index 7404d7d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict'
-
-// Order of the tests we want to execute
-require('./config')
-require('./check-params')
-require('./friends-basic')
-require('./users')
-require('./single-pod')
-require('./video-abuse')
-require('./video-blacklist')
-require('./multiple-pods')
-require('./request-schedulers')
-require('./friends-advanced')
-require('./video-transcoder')
diff --git a/server/tests/api/index.ts b/server/tests/api/index.ts
new file mode 100644 (file)
index 0000000..f60d709
--- /dev/null
@@ -0,0 +1,12 @@
+// Order of the tests we want to execute
+import './config'
+import './check-params'
+import './friends-basic'
+import './users'
+import './single-pod'
+import './video-abuse'
+import './video-blacklist'
+import './multiple-pods'
+import './request-schedulers'
+import './friends-advanced'
+import './video-transcoder'
diff --git a/server/tests/api/multiple-pods.js b/server/tests/api/multiple-pods.js
deleted file mode 100644 (file)
index b281cc2..0000000
+++ /dev/null
@@ -1,854 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const eachSeries = require('async/eachSeries')
-const expect = chai.expect
-const parallel = require('async/parallel')
-const series = require('async/series')
-const WebTorrent = require('webtorrent')
-const webtorrent = new WebTorrent()
-
-const loginUtils = require('../utils/login')
-const miscsUtils = require('../utils/miscs')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-
-describe('Test multiple pods', function () {
-  let servers = []
-  const toRemove = []
-  let videoUUID = ''
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      // Run servers
-      function (next) {
-        serversUtils.flushAndRunMultipleServers(3, function (serversRun) {
-          servers = serversRun
-          next()
-        })
-      },
-      // Get the access tokens
-      function (next) {
-        each(servers, function (server, callbackEach) {
-          loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-            if (err) return callbackEach(err)
-
-            server.accessToken = accessToken
-            callbackEach()
-          })
-        }, next)
-      },
-      // The second pod make friend with the third
-      function (next) {
-        const server = servers[1]
-        podsUtils.makeFriends(server.url, server.accessToken, next)
-      },
-      // Wait for the request between pods
-      function (next) {
-        setTimeout(next, 10000)
-      },
-      // Pod 1 make friends too
-      function (next) {
-        const server = servers[0]
-        podsUtils.makeFriends(server.url, server.accessToken, next)
-      }
-    ], done)
-  })
-
-  it('Should not have videos for all pods', function (done) {
-    each(servers, function (server, callback) {
-      videosUtils.getVideosList(server.url, function (err, res) {
-        if (err) throw err
-
-        const videos = res.body.data
-        expect(videos).to.be.an('array')
-        expect(videos.length).to.equal(0)
-
-        callback()
-      })
-    }, done)
-  })
-
-  describe('Should upload the video and propagate on each pod', function () {
-    it('Should upload the video on pod 1 and propagate on each pod', function (done) {
-      // Pod 1 has video transcoding activated
-      this.timeout(15000)
-
-      series([
-        function (next) {
-          const videoAttributes = {
-            name: 'my super name for pod 1',
-            category: 5,
-            licence: 4,
-            language: 9,
-            nsfw: true,
-            description: 'my super description for pod 1',
-            tags: [ 'tag1p1', 'tag2p1' ],
-            fixture: 'video_short1.webm'
-          }
-          videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes, next)
-        },
-        function (next) {
-          setTimeout(next, 11000)
-        }],
-        // All pods should have this video
-        function (err) {
-          if (err) throw err
-
-          each(servers, function (server, callback) {
-            let baseMagnet = null
-
-            videosUtils.getVideosList(server.url, function (err, res) {
-              if (err) throw err
-
-              const videos = res.body.data
-              expect(videos).to.be.an('array')
-              expect(videos.length).to.equal(1)
-              const video = videos[0]
-              expect(video.name).to.equal('my super name for pod 1')
-              expect(video.category).to.equal(5)
-              expect(video.categoryLabel).to.equal('Sports')
-              expect(video.licence).to.equal(4)
-              expect(video.licenceLabel).to.equal('Attribution - Non Commercial')
-              expect(video.language).to.equal(9)
-              expect(video.languageLabel).to.equal('Japanese')
-              expect(video.nsfw).to.be.ok
-              expect(video.description).to.equal('my super description for pod 1')
-              expect(video.podHost).to.equal('localhost:9001')
-              expect(video.duration).to.equal(10)
-              expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ])
-              expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-              expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-              expect(video.author).to.equal('root')
-
-              expect(video.files).to.have.lengthOf(1)
-
-              const file = video.files[0]
-              const magnetUri = file.magnetUri
-              expect(file.magnetUri).to.exist
-              expect(file.resolution).to.equal(0)
-              expect(file.resolutionLabel).to.equal('original')
-              expect(file.size).to.equal(572456)
-
-              if (server.url !== 'http://localhost:9001') {
-                expect(video.isLocal).to.be.false
-              } else {
-                expect(video.isLocal).to.be.true
-              }
-
-              // All pods should have the same magnet Uri
-              if (baseMagnet === null) {
-                baseMagnet = magnetUri
-              } else {
-                expect(baseMagnet).to.equal(magnetUri)
-              }
-
-              videosUtils.testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) {
-                if (err) throw err
-                expect(test).to.equal(true)
-
-                callback()
-              })
-            })
-          }, done)
-        }
-      )
-    })
-
-    it('Should upload the video on pod 2 and propagate on each pod', function (done) {
-      this.timeout(60000)
-
-      series([
-        function (next) {
-          const videoAttributes = {
-            name: 'my super name for pod 2',
-            category: 4,
-            licence: 3,
-            language: 11,
-            nsfw: true,
-            description: 'my super description for pod 2',
-            tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
-            fixture: 'video_short2.webm'
-          }
-          videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes, next)
-        },
-        function (next) {
-          // Transcoding, so wait more that 22 seconds
-          setTimeout(next, 42000)
-        }],
-        // All pods should have this video
-        function (err) {
-          if (err) throw err
-
-          each(servers, function (server, callback) {
-            let baseMagnet = null
-
-            videosUtils.getVideosList(server.url, function (err, res) {
-              if (err) throw err
-
-              const videos = res.body.data
-              expect(videos).to.be.an('array')
-              expect(videos.length).to.equal(2)
-              const video = videos[1]
-              expect(video.name).to.equal('my super name for pod 2')
-              expect(video.category).to.equal(4)
-              expect(video.categoryLabel).to.equal('Art')
-              expect(video.licence).to.equal(3)
-              expect(video.licenceLabel).to.equal('Attribution - No Derivatives')
-              expect(video.language).to.equal(11)
-              expect(video.languageLabel).to.equal('German')
-              expect(video.nsfw).to.be.true
-              expect(video.description).to.equal('my super description for pod 2')
-              expect(video.podHost).to.equal('localhost:9002')
-              expect(video.duration).to.equal(5)
-              expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ])
-              expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-              expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-              expect(video.author).to.equal('root')
-
-              expect(video.files).to.have.lengthOf(1)
-
-              const file = video.files[0]
-              const magnetUri = file.magnetUri
-              expect(file.magnetUri).to.exist
-              expect(file.resolution).to.equal(0)
-              expect(file.resolutionLabel).to.equal('original')
-              expect(file.size).to.equal(942961)
-
-              if (server.url !== 'http://localhost:9002') {
-                expect(video.isLocal).to.be.false
-              } else {
-                expect(video.isLocal).to.be.true
-              }
-
-              // All pods should have the same magnet Uri
-              if (baseMagnet === null) {
-                baseMagnet = magnetUri
-              } else {
-                expect(baseMagnet).to.equal(magnetUri)
-              }
-
-              videosUtils.testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) {
-                if (err) throw err
-                expect(test).to.equal(true)
-
-                callback()
-              })
-            })
-          }, done)
-        }
-      )
-    })
-
-    it('Should upload two videos on pod 3 and propagate on each pod', function (done) {
-      this.timeout(45000)
-
-      series([
-        function (next) {
-          const videoAttributes = {
-            name: 'my super name for pod 3',
-            category: 6,
-            licence: 5,
-            language: 11,
-            nsfw: true,
-            description: 'my super description for pod 3',
-            tags: [ 'tag1p3' ],
-            fixture: 'video_short3.webm'
-          }
-          videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes, next)
-        },
-        function (next) {
-          const videoAttributes = {
-            name: 'my super name for pod 3-2',
-            category: 7,
-            licence: 6,
-            language: 12,
-            nsfw: false,
-            description: 'my super description for pod 3-2',
-            tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
-            fixture: 'video_short.webm'
-          }
-          videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes, next)
-        },
-        function (next) {
-          setTimeout(next, 33000)
-        }],
-        function (err) {
-          if (err) throw err
-
-          let baseMagnet = null
-          // All pods should have this video
-          each(servers, function (server, callback) {
-            videosUtils.getVideosList(server.url, function (err, res) {
-              if (err) throw err
-
-              const videos = res.body.data
-              expect(videos).to.be.an('array')
-              expect(videos.length).to.equal(4)
-
-              // We not sure about the order of the two last uploads
-              let video1 = null
-              let video2 = null
-              if (videos[2].name === 'my super name for pod 3') {
-                video1 = videos[2]
-                video2 = videos[3]
-              } else {
-                video1 = videos[3]
-                video2 = videos[2]
-              }
-
-              expect(video1.name).to.equal('my super name for pod 3')
-              expect(video1.category).to.equal(6)
-              expect(video1.categoryLabel).to.equal('Travels')
-              expect(video1.licence).to.equal(5)
-              expect(video1.licenceLabel).to.equal('Attribution - Non Commercial - Share Alike')
-              expect(video1.language).to.equal(11)
-              expect(video1.languageLabel).to.equal('German')
-              expect(video1.nsfw).to.be.ok
-              expect(video1.description).to.equal('my super description for pod 3')
-              expect(video1.podHost).to.equal('localhost:9003')
-              expect(video1.duration).to.equal(5)
-              expect(video1.tags).to.deep.equal([ 'tag1p3' ])
-              expect(video1.author).to.equal('root')
-              expect(miscsUtils.dateIsValid(video1.createdAt)).to.be.true
-              expect(miscsUtils.dateIsValid(video1.updatedAt)).to.be.true
-
-              expect(video1.files).to.have.lengthOf(1)
-
-              const file1 = video1.files[0]
-              const magnetUri1 = file1.magnetUri
-              expect(file1.magnetUri).to.exist
-              expect(file1.resolution).to.equal(0)
-              expect(file1.resolutionLabel).to.equal('original')
-              expect(file1.size).to.equal(292677)
-
-              expect(video2.name).to.equal('my super name for pod 3-2')
-              expect(video2.category).to.equal(7)
-              expect(video2.categoryLabel).to.equal('Gaming')
-              expect(video2.licence).to.equal(6)
-              expect(video2.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
-              expect(video2.language).to.equal(12)
-              expect(video2.languageLabel).to.equal('Korean')
-              expect(video2.nsfw).to.be.false
-              expect(video2.description).to.equal('my super description for pod 3-2')
-              expect(video2.podHost).to.equal('localhost:9003')
-              expect(video2.duration).to.equal(5)
-              expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ])
-              expect(video2.author).to.equal('root')
-              expect(miscsUtils.dateIsValid(video2.createdAt)).to.be.true
-              expect(miscsUtils.dateIsValid(video2.updatedAt)).to.be.true
-
-              expect(video2.files).to.have.lengthOf(1)
-
-              const file2 = video2.files[0]
-              const magnetUri2 = file2.magnetUri
-              expect(file2.magnetUri).to.exist
-              expect(file2.resolution).to.equal(0)
-              expect(file2.resolutionLabel).to.equal('original')
-              expect(file2.size).to.equal(218910)
-
-              if (server.url !== 'http://localhost:9003') {
-                expect(video1.isLocal).to.be.false
-                expect(video2.isLocal).to.be.false
-              } else {
-                expect(video1.isLocal).to.be.true
-                expect(video2.isLocal).to.be.true
-              }
-
-              // All pods should have the same magnet Uri
-              if (baseMagnet === null) {
-                baseMagnet = magnetUri2
-              } else {
-                expect(baseMagnet).to.equal(magnetUri2)
-              }
-
-              videosUtils.testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) {
-                if (err) throw err
-                expect(test).to.equal(true)
-
-                videosUtils.testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) {
-                  if (err) throw err
-                  expect(test).to.equal(true)
-
-                  callback()
-                })
-              })
-            })
-          }, done)
-        }
-      )
-    })
-  })
-
-  describe('Should seed the uploaded video', function () {
-    it('Should add the file 1 by asking pod 3', function (done) {
-      // Yes, this could be long
-      this.timeout(200000)
-
-      videosUtils.getVideosList(servers[2].url, function (err, res) {
-        if (err) throw err
-
-        const video = res.body.data[0]
-        toRemove.push(res.body.data[2])
-        toRemove.push(res.body.data[3])
-
-        webtorrent.add(video.files[0].magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-
-    it('Should add the file 2 by asking pod 1', function (done) {
-      // Yes, this could be long
-      this.timeout(200000)
-
-      videosUtils.getVideosList(servers[0].url, function (err, res) {
-        if (err) throw err
-
-        const video = res.body.data[1]
-
-        webtorrent.add(video.files[0].magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-
-    it('Should add the file 3 by asking pod 2', function (done) {
-      // Yes, this could be long
-      this.timeout(200000)
-
-      videosUtils.getVideosList(servers[1].url, function (err, res) {
-        if (err) throw err
-
-        const video = res.body.data[2]
-
-        webtorrent.add(video.files[0].magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-
-    it('Should add the file 3-2 by asking pod 1', function (done) {
-      // Yes, this could be long
-      this.timeout(200000)
-
-      videosUtils.getVideosList(servers[0].url, function (err, res) {
-        if (err) throw err
-
-        const video = res.body.data[3]
-
-        webtorrent.add(video.files[0].magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-  })
-
-  describe('Should update video views, likes and dislikes', function () {
-    let localVideosPod3 = []
-    let remoteVideosPod1 = []
-    let remoteVideosPod2 = []
-    let remoteVideosPod3 = []
-
-    before(function (done) {
-      parallel([
-        function (callback) {
-          videosUtils.getVideosList(servers[0].url, function (err, res) {
-            if (err) throw err
-
-            remoteVideosPod1 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
-
-            callback()
-          })
-        },
-
-        function (callback) {
-          videosUtils.getVideosList(servers[1].url, function (err, res) {
-            if (err) throw err
-
-            remoteVideosPod2 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
-
-            callback()
-          })
-        },
-
-        function (callback) {
-          videosUtils.getVideosList(servers[2].url, function (err, res) {
-            if (err) throw err
-
-            localVideosPod3 = res.body.data.filter(video => video.isLocal === true).map(video => video.id)
-            remoteVideosPod3 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
-
-            callback()
-          })
-        }
-      ], done)
-    })
-
-    it('Should view multiple videos on owned servers', function (done) {
-      this.timeout(30000)
-
-      parallel([
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          setTimeout(callback, 22000)
-        }
-      ], function (err) {
-        if (err) throw err
-
-        eachSeries(servers, function (server, callback) {
-          videosUtils.getVideosList(server.url, function (err, res) {
-            if (err) throw err
-
-            const videos = res.body.data
-            expect(videos.find(video => video.views === 3)).to.exist
-            expect(videos.find(video => video.views === 1)).to.exist
-
-            callback()
-          })
-        }, done)
-      })
-    })
-
-    it('Should view multiple videos on each servers', function (done) {
-      this.timeout(30000)
-
-      parallel([
-        function (callback) {
-          videosUtils.getVideo(servers[0].url, remoteVideosPod1[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[1].url, remoteVideosPod2[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[1].url, remoteVideosPod2[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, remoteVideosPod3[0], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
-        },
-
-        function (callback) {
-          setTimeout(callback, 22000)
-        }
-      ], function (err) {
-        if (err) throw err
-
-        let baseVideos = null
-        eachSeries(servers, function (server, callback) {
-          videosUtils.getVideosList(server.url, function (err, res) {
-            if (err) throw err
-
-            const videos = res.body.data
-
-            // Initialize base videos for future comparisons
-            if (baseVideos === null) {
-              baseVideos = videos
-              return callback()
-            }
-
-            baseVideos.forEach(baseVideo => {
-              const sameVideo = videos.find(video => video.name === baseVideo.name)
-              expect(baseVideo.views).to.equal(sameVideo.views)
-            })
-
-            callback()
-          })
-        }, done)
-      })
-    })
-
-    it('Should like and dislikes videos on different services', function (done) {
-      this.timeout(30000)
-
-      parallel([
-        function (callback) {
-          videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'dislike', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'like', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'dislike', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[1], 'dislike', callback)
-        },
-
-        function (callback) {
-          videosUtils.rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[0], 'like', callback)
-        },
-
-        function (callback) {
-          setTimeout(callback, 22000)
-        }
-      ], function (err) {
-        if (err) throw err
-
-        let baseVideos = null
-        eachSeries(servers, function (server, callback) {
-          videosUtils.getVideosList(server.url, function (err, res) {
-            if (err) throw err
-
-            const videos = res.body.data
-
-            // Initialize base videos for future comparisons
-            if (baseVideos === null) {
-              baseVideos = videos
-              return callback()
-            }
-
-            baseVideos.forEach(baseVideo => {
-              const sameVideo = videos.find(video => video.name === baseVideo.name)
-              expect(baseVideo.likes).to.equal(sameVideo.likes)
-              expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
-            })
-
-            callback()
-          })
-        }, done)
-      })
-    })
-  })
-
-  describe('Should manipulate these videos', function () {
-    it('Should update the video 3 by asking pod 3', function (done) {
-      this.timeout(15000)
-
-      const attributes = {
-        name: 'my super video updated',
-        category: 10,
-        licence: 7,
-        language: 13,
-        nsfw: true,
-        description: 'my super description updated',
-        tags: [ 'tagup1', 'tagup2' ]
-      }
-      videosUtils.updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes, function (err) {
-        if (err) throw err
-
-        setTimeout(done, 11000)
-      })
-    })
-
-    it('Should have the video 3 updated on each pod', function (done) {
-      this.timeout(200000)
-
-      each(servers, function (server, callback) {
-        // Avoid "duplicate torrent" errors
-        const webtorrent = new WebTorrent()
-
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          const videoUpdated = videos.find(function (video) {
-            return video.name === 'my super video updated'
-          })
-
-          expect(!!videoUpdated).to.be.true
-          expect(videoUpdated.category).to.equal(10)
-          expect(videoUpdated.categoryLabel).to.equal('Entertainment')
-          expect(videoUpdated.licence).to.equal(7)
-          expect(videoUpdated.licenceLabel).to.equal('Public Domain Dedication')
-          expect(videoUpdated.language).to.equal(13)
-          expect(videoUpdated.languageLabel).to.equal('French')
-          expect(videoUpdated.nsfw).to.be.ok
-          expect(videoUpdated.description).to.equal('my super description updated')
-          expect(videoUpdated.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
-          expect(miscsUtils.dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true
-
-          const file = videoUpdated.files[0]
-          const magnetUri = file.magnetUri
-          expect(file.magnetUri).to.exist
-          expect(file.resolution).to.equal(0)
-          expect(file.resolutionLabel).to.equal('original')
-          expect(file.size).to.equal(292677)
-
-          videosUtils.testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath, function (err, test) {
-            if (err) throw err
-            expect(test).to.equal(true)
-
-            webtorrent.add(videoUpdated.files[0].magnetUri, function (torrent) {
-              expect(torrent.files).to.exist
-              expect(torrent.files.length).to.equal(1)
-              expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-              callback()
-            })
-          })
-        })
-      }, done)
-    })
-
-    it('Should remove the videos 3 and 3-2 by asking pod 3', function (done) {
-      this.timeout(15000)
-
-      series([
-        function (next) {
-          videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, next)
-        },
-        function (next) {
-          videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id, next)
-        }],
-        function (err) {
-          if (err) throw err
-          setTimeout(done, 11000)
-        }
-      )
-    })
-
-    it('Should have videos 1 and 3 on each pod', function (done) {
-      each(servers, function (server, callback) {
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-          expect(videos).to.be.an('array')
-          expect(videos.length).to.equal(2)
-          expect(videos[0].name).not.to.equal(videos[1].name)
-          expect(videos[0].name).not.to.equal(toRemove[0].name)
-          expect(videos[1].name).not.to.equal(toRemove[0].name)
-          expect(videos[0].name).not.to.equal(toRemove[1].name)
-          expect(videos[1].name).not.to.equal(toRemove[1].name)
-
-          videoUUID = videos.find(video => video.name === 'my super name for pod 1').uuid
-
-          callback()
-        })
-      }, done)
-    })
-
-    it('Should get the same video by UUID on each pod', function (done) {
-      let baseVideo = null
-      each(servers, function (server, callback) {
-        videosUtils.getVideo(server.url, videoUUID, function (err, res) {
-          if (err) throw err
-
-          const video = res.body
-
-          if (baseVideo === null) {
-            baseVideo = video
-            return callback()
-          }
-
-          expect(baseVideo.name).to.equal(video.name)
-          expect(baseVideo.uuid).to.equal(video.uuid)
-          expect(baseVideo.category).to.equal(video.category)
-          expect(baseVideo.language).to.equal(video.language)
-          expect(baseVideo.licence).to.equal(video.licence)
-          expect(baseVideo.category).to.equal(video.category)
-          expect(baseVideo.nsfw).to.equal(video.nsfw)
-          expect(baseVideo.author).to.equal(video.author)
-          expect(baseVideo.tags).to.deep.equal(video.tags)
-
-          callback()
-        })
-      }, done)
-    })
-
-    it('Should get the preview from each pod', function (done) {
-      each(servers, function (server, callback) {
-        videosUtils.getVideo(server.url, videoUUID, function (err, res) {
-          if (err) throw err
-
-          const video = res.body
-
-          videosUtils.testVideoImage(server.url, 'video_short1-preview.webm', video.previewPath, function (err, test) {
-            if (err) throw err
-            expect(test).to.equal(true)
-
-            callback()
-          })
-        })
-      }, done)
-    })
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/multiple-pods.ts b/server/tests/api/multiple-pods.ts
new file mode 100644 (file)
index 0000000..7117ab2
--- /dev/null
@@ -0,0 +1,627 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+
+import {
+  dateIsValid,
+  flushAndRunMultipleServers,
+  flushTests,
+  getVideo,
+  getVideosList,
+  killallServers,
+  makeFriends,
+  rateVideo,
+  removeVideo,
+  ServerInfo,
+  setAccessTokensToServers,
+  testVideoImage,
+  updateVideo,
+  uploadVideo,
+  wait,
+  webtorrentAdd
+} from '../utils'
+
+const expect = chai.expect
+
+describe('Test multiple pods', function () {
+  let servers: ServerInfo[] = []
+  const toRemove = []
+  let videoUUID = ''
+
+  before(async function () {
+    this.timeout(120000)
+
+    servers = await flushAndRunMultipleServers(3)
+
+    // Get the access tokens
+    await setAccessTokensToServers(servers)
+
+    // The second pod make friend with the third
+    await makeFriends(servers[1].url, servers[1].accessToken)
+
+    // Wait for the request between pods
+    await wait(10000)
+
+    // Pod 1 make friends too
+    await makeFriends(servers[0].url, servers[0].accessToken)
+  })
+
+  it('Should not have videos for all pods', async function () {
+    for (const server of servers) {
+      const res = await getVideosList(server.url)
+      const videos = res.body.data
+      expect(videos).to.be.an('array')
+      expect(videos.length).to.equal(0)
+    }
+  })
+
+  describe('Should upload the video and propagate on each pod', function () {
+    it('Should upload the video on pod 1 and propagate on each pod', async function () {
+      // Pod 1 has video transcoding activated
+      this.timeout(15000)
+
+      const videoAttributes = {
+        name: 'my super name for pod 1',
+        category: 5,
+        licence: 4,
+        language: 9,
+        nsfw: true,
+        description: 'my super description for pod 1',
+        tags: [ 'tag1p1', 'tag2p1' ],
+        fixture: 'video_short1.webm'
+      }
+      await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
+
+      await wait(11000)
+
+      // All pods should have this video
+      for (const server of servers) {
+        let baseMagnet = null
+
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        expect(videos).to.be.an('array')
+        expect(videos.length).to.equal(1)
+        const video = videos[0]
+        expect(video.name).to.equal('my super name for pod 1')
+        expect(video.category).to.equal(5)
+        expect(video.categoryLabel).to.equal('Sports')
+        expect(video.licence).to.equal(4)
+        expect(video.licenceLabel).to.equal('Attribution - Non Commercial')
+        expect(video.language).to.equal(9)
+        expect(video.languageLabel).to.equal('Japanese')
+        expect(video.nsfw).to.be.ok
+        expect(video.description).to.equal('my super description for pod 1')
+        expect(video.podHost).to.equal('localhost:9001')
+        expect(video.duration).to.equal(10)
+        expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ])
+        expect(dateIsValid(video.createdAt)).to.be.true
+        expect(dateIsValid(video.updatedAt)).to.be.true
+        expect(video.author).to.equal('root')
+
+        expect(video.files).to.have.lengthOf(1)
+
+        const file = video.files[0]
+        const magnetUri = file.magnetUri
+        expect(file.magnetUri).to.have.lengthOf.above(2)
+        expect(file.resolution).to.equal(0)
+        expect(file.resolutionLabel).to.equal('original')
+        expect(file.size).to.equal(572456)
+
+        if (server.url !== 'http://localhost:9001') {
+          expect(video.isLocal).to.be.false
+        } else {
+          expect(video.isLocal).to.be.true
+        }
+
+        // All pods should have the same magnet Uri
+        if (baseMagnet === null) {
+          baseMagnet = magnetUri
+        } else {
+          expect(baseMagnet).to.equal(magnetUri)
+        }
+
+        const test = await testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath)
+        expect(test).to.equal(true)
+      }
+    })
+
+    it('Should upload the video on pod 2 and propagate on each pod', async function () {
+      this.timeout(60000)
+
+      const videoAttributes = {
+        name: 'my super name for pod 2',
+        category: 4,
+        licence: 3,
+        language: 11,
+        nsfw: true,
+        description: 'my super description for pod 2',
+        tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
+        fixture: 'video_short2.webm'
+      }
+      await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
+
+      // Transcoding, so wait more that 22 seconds
+      await wait(42000)
+
+      // All pods should have this video
+      for (const server of servers) {
+        let baseMagnet = null
+
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        expect(videos).to.be.an('array')
+        expect(videos.length).to.equal(2)
+        const video = videos[1]
+        expect(video.name).to.equal('my super name for pod 2')
+        expect(video.category).to.equal(4)
+        expect(video.categoryLabel).to.equal('Art')
+        expect(video.licence).to.equal(3)
+        expect(video.licenceLabel).to.equal('Attribution - No Derivatives')
+        expect(video.language).to.equal(11)
+        expect(video.languageLabel).to.equal('German')
+        expect(video.nsfw).to.be.true
+        expect(video.description).to.equal('my super description for pod 2')
+        expect(video.podHost).to.equal('localhost:9002')
+        expect(video.duration).to.equal(5)
+        expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ])
+        expect(dateIsValid(video.createdAt)).to.be.true
+        expect(dateIsValid(video.updatedAt)).to.be.true
+        expect(video.author).to.equal('root')
+
+        expect(video.files).to.have.lengthOf(1)
+
+        const file = video.files[0]
+        const magnetUri = file.magnetUri
+        expect(file.magnetUri).to.have.lengthOf.above(2)
+        expect(file.resolution).to.equal(0)
+        expect(file.resolutionLabel).to.equal('original')
+        expect(file.size).to.equal(942961)
+
+        if (server.url !== 'http://localhost:9002') {
+          expect(video.isLocal).to.be.false
+        } else {
+          expect(video.isLocal).to.be.true
+        }
+
+        // All pods should have the same magnet Uri
+        if (baseMagnet === null) {
+          baseMagnet = magnetUri
+        } else {
+          expect(baseMagnet).to.equal(magnetUri)
+        }
+
+        const test = await testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath)
+        expect(test).to.equal(true)
+      }
+    })
+
+    it('Should upload two videos on pod 3 and propagate on each pod', async function () {
+      this.timeout(45000)
+
+      const videoAttributes1 = {
+        name: 'my super name for pod 3',
+        category: 6,
+        licence: 5,
+        language: 11,
+        nsfw: true,
+        description: 'my super description for pod 3',
+        tags: [ 'tag1p3' ],
+        fixture: 'video_short3.webm'
+      }
+      await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1)
+
+      const videoAttributes2 = {
+        name: 'my super name for pod 3-2',
+        category: 7,
+        licence: 6,
+        language: 12,
+        nsfw: false,
+        description: 'my super description for pod 3-2',
+        tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
+        fixture: 'video_short.webm'
+      }
+      await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2)
+
+      await wait(33000)
+
+      let baseMagnet = null
+      // All pods should have this video
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        expect(videos).to.be.an('array')
+        expect(videos.length).to.equal(4)
+
+        // We not sure about the order of the two last uploads
+        let video1 = null
+        let video2 = null
+        if (videos[2].name === 'my super name for pod 3') {
+          video1 = videos[2]
+          video2 = videos[3]
+        } else {
+          video1 = videos[3]
+          video2 = videos[2]
+        }
+
+        expect(video1.name).to.equal('my super name for pod 3')
+        expect(video1.category).to.equal(6)
+        expect(video1.categoryLabel).to.equal('Travels')
+        expect(video1.licence).to.equal(5)
+        expect(video1.licenceLabel).to.equal('Attribution - Non Commercial - Share Alike')
+        expect(video1.language).to.equal(11)
+        expect(video1.languageLabel).to.equal('German')
+        expect(video1.nsfw).to.be.ok
+        expect(video1.description).to.equal('my super description for pod 3')
+        expect(video1.podHost).to.equal('localhost:9003')
+        expect(video1.duration).to.equal(5)
+        expect(video1.tags).to.deep.equal([ 'tag1p3' ])
+        expect(video1.author).to.equal('root')
+        expect(dateIsValid(video1.createdAt)).to.be.true
+        expect(dateIsValid(video1.updatedAt)).to.be.true
+
+        expect(video1.files).to.have.lengthOf(1)
+
+        const file1 = video1.files[0]
+        expect(file1.magnetUri).to.have.lengthOf.above(2)
+        expect(file1.resolution).to.equal(0)
+        expect(file1.resolutionLabel).to.equal('original')
+        expect(file1.size).to.equal(292677)
+
+        expect(video2.name).to.equal('my super name for pod 3-2')
+        expect(video2.category).to.equal(7)
+        expect(video2.categoryLabel).to.equal('Gaming')
+        expect(video2.licence).to.equal(6)
+        expect(video2.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
+        expect(video2.language).to.equal(12)
+        expect(video2.languageLabel).to.equal('Korean')
+        expect(video2.nsfw).to.be.false
+        expect(video2.description).to.equal('my super description for pod 3-2')
+        expect(video2.podHost).to.equal('localhost:9003')
+        expect(video2.duration).to.equal(5)
+        expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ])
+        expect(video2.author).to.equal('root')
+        expect(dateIsValid(video2.createdAt)).to.be.true
+        expect(dateIsValid(video2.updatedAt)).to.be.true
+
+        expect(video2.files).to.have.lengthOf(1)
+
+        const file2 = video2.files[0]
+        const magnetUri2 = file2.magnetUri
+        expect(file2.magnetUri).to.have.lengthOf.above(2)
+        expect(file2.resolution).to.equal(0)
+        expect(file2.resolutionLabel).to.equal('original')
+        expect(file2.size).to.equal(218910)
+
+        if (server.url !== 'http://localhost:9003') {
+          expect(video1.isLocal).to.be.false
+          expect(video2.isLocal).to.be.false
+        } else {
+          expect(video1.isLocal).to.be.true
+          expect(video2.isLocal).to.be.true
+        }
+
+        // All pods should have the same magnet Uri
+        if (baseMagnet === null) {
+          baseMagnet = magnetUri2
+        } else {
+          expect(baseMagnet).to.equal(magnetUri2)
+        }
+
+        const test1 = await testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath)
+        expect(test1).to.equal(true)
+
+        const test2 = await testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath)
+        expect(test2).to.equal(true)
+      }
+    })
+  })
+
+  describe('Should seed the uploaded video', function () {
+    it('Should add the file 1 by asking pod 3', async function () {
+      // Yes, this could be long
+      this.timeout(200000)
+
+      const res = await getVideosList(servers[2].url)
+
+      const video = res.body.data[0]
+      toRemove.push(res.body.data[2])
+      toRemove.push(res.body.data[3])
+
+      const torrent = await webtorrentAdd(video.files[0].magnetUri)
+      expect(torrent.files).to.be.an('array')
+      expect(torrent.files.length).to.equal(1)
+      expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+    })
+
+    it('Should add the file 2 by asking pod 1', async function () {
+      // Yes, this could be long
+      this.timeout(200000)
+
+      const res = await getVideosList(servers[0].url)
+
+      const video = res.body.data[1]
+
+      const torrent = await webtorrentAdd(video.files[0].magnetUri)
+      expect(torrent.files).to.be.an('array')
+      expect(torrent.files.length).to.equal(1)
+      expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+    })
+
+    it('Should add the file 3 by asking pod 2', async function () {
+      // Yes, this could be long
+      this.timeout(200000)
+
+      const res = await getVideosList(servers[1].url)
+
+      const video = res.body.data[2]
+
+      const torrent = await webtorrentAdd(video.files[0].magnetUri)
+      expect(torrent.files).to.be.an('array')
+      expect(torrent.files.length).to.equal(1)
+      expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+    })
+
+    it('Should add the file 3-2 by asking pod 1', async function () {
+      // Yes, this could be long
+      this.timeout(200000)
+
+      const res = await getVideosList(servers[0].url)
+
+      const video = res.body.data[3]
+
+      const torrent = await webtorrentAdd(video.files[0].magnetUri)
+      expect(torrent.files).to.be.an('array')
+      expect(torrent.files.length).to.equal(1)
+      expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+    })
+  })
+
+  describe('Should update video views, likes and dislikes', function () {
+    let localVideosPod3 = []
+    let remoteVideosPod1 = []
+    let remoteVideosPod2 = []
+    let remoteVideosPod3 = []
+
+    before(async function () {
+      const res1 = await getVideosList(servers[0].url)
+      remoteVideosPod1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.id)
+
+      const res2 = await getVideosList(servers[1].url)
+      remoteVideosPod2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.id)
+
+      const res3 = await getVideosList(servers[2].url)
+      localVideosPod3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.id)
+      remoteVideosPod3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.id)
+    })
+
+    it('Should view multiple videos on owned servers', async function () {
+      this.timeout(30000)
+
+      const tasks: Promise<any>[] = []
+      tasks.push(getVideo(servers[2].url, localVideosPod3[0]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[0]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[0]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[1]))
+
+      await Promise.all(tasks)
+
+      await wait(22000)
+
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        expect(videos.find(video => video.views === 3)).to.be.an('object')
+        expect(videos.find(video => video.views === 1)).to.be.an('object')
+      }
+    })
+
+    it('Should view multiple videos on each servers', async function () {
+      this.timeout(30000)
+
+      const tasks: Promise<any>[] = []
+      tasks.push(getVideo(servers[0].url, remoteVideosPod1[0]))
+      tasks.push(getVideo(servers[1].url, remoteVideosPod2[0]))
+      tasks.push(getVideo(servers[1].url, remoteVideosPod2[0]))
+      tasks.push(getVideo(servers[2].url, remoteVideosPod3[0]))
+      tasks.push(getVideo(servers[2].url, remoteVideosPod3[1]))
+      tasks.push(getVideo(servers[2].url, remoteVideosPod3[1]))
+      tasks.push(getVideo(servers[2].url, remoteVideosPod3[1]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[1]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[1]))
+      tasks.push(getVideo(servers[2].url, localVideosPod3[1]))
+
+      await Promise.all(tasks)
+
+      await wait(22000)
+
+      let baseVideos = null
+
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+
+        // Initialize base videos for future comparisons
+        if (baseVideos === null) {
+          baseVideos = videos
+          return
+        }
+
+        for (const baseVideo of baseVideos) {
+          const sameVideo = videos.find(video => video.name === baseVideo.name)
+          expect(baseVideo.views).to.equal(sameVideo.views)
+        }
+      }
+    })
+
+    it('Should like and dislikes videos on different services', async function () {
+      this.timeout(30000)
+
+      const tasks: Promise<any>[] = []
+      tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like'))
+      tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'dislike'))
+      tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like'))
+      tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'like'))
+      tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'dislike'))
+      tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[1], 'dislike'))
+      tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[0], 'like'))
+
+      await Promise.all(tasks)
+
+      await wait(22000)
+
+      let baseVideos = null
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+
+        // Initialize base videos for future comparisons
+        if (baseVideos === null) {
+          baseVideos = videos
+          return
+        }
+
+        baseVideos.forEach(baseVideo => {
+          const sameVideo = videos.find(video => video.name === baseVideo.name)
+          expect(baseVideo.likes).to.equal(sameVideo.likes)
+          expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
+        })
+      }
+    })
+  })
+
+  describe('Should manipulate these videos', function () {
+    it('Should update the video 3 by asking pod 3', async function () {
+      this.timeout(15000)
+
+      const attributes = {
+        name: 'my super video updated',
+        category: 10,
+        licence: 7,
+        language: 13,
+        nsfw: true,
+        description: 'my super description updated',
+        tags: [ 'tag_up_1', 'tag_up_2' ]
+      }
+
+      await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes)
+
+      await wait(11000)
+    })
+
+    it('Should have the video 3 updated on each pod', async function () {
+      this.timeout(200000)
+
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        const videoUpdated = videos.find(video => video.name === 'my super video updated')
+
+        expect(!!videoUpdated).to.be.true
+        expect(videoUpdated.category).to.equal(10)
+        expect(videoUpdated.categoryLabel).to.equal('Entertainment')
+        expect(videoUpdated.licence).to.equal(7)
+        expect(videoUpdated.licenceLabel).to.equal('Public Domain Dedication')
+        expect(videoUpdated.language).to.equal(13)
+        expect(videoUpdated.languageLabel).to.equal('French')
+        expect(videoUpdated.nsfw).to.be.ok
+        expect(videoUpdated.description).to.equal('my super description updated')
+        expect(videoUpdated.tags).to.deep.equal([ 'tag_up_1', 'tag_up_2' ])
+        expect(dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true
+
+        const file = videoUpdated.files[0]
+        expect(file.magnetUri).to.have.lengthOf.above(2)
+        expect(file.resolution).to.equal(0)
+        expect(file.resolutionLabel).to.equal('original')
+        expect(file.size).to.equal(292677)
+
+        const test = await testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath)
+        expect(test).to.equal(true)
+
+        // Avoid "duplicate torrent" errors
+        const refreshWebTorrent = true
+        const torrent = await webtorrentAdd(videoUpdated.files[0].magnetUri, refreshWebTorrent)
+        expect(torrent.files).to.be.an('array')
+        expect(torrent.files.length).to.equal(1)
+        expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+      }
+    })
+
+    it('Should remove the videos 3 and 3-2 by asking pod 3', async function () {
+      this.timeout(15000)
+
+      await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id)
+      await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id)
+
+      await wait(11000)
+    })
+
+    it('Should have videos 1 and 3 on each pod', async function () {
+      for (const server of servers) {
+        const res = await getVideosList(server.url)
+
+        const videos = res.body.data
+        expect(videos).to.be.an('array')
+        expect(videos.length).to.equal(2)
+        expect(videos[0].name).not.to.equal(videos[1].name)
+        expect(videos[0].name).not.to.equal(toRemove[0].name)
+        expect(videos[1].name).not.to.equal(toRemove[0].name)
+        expect(videos[0].name).not.to.equal(toRemove[1].name)
+        expect(videos[1].name).not.to.equal(toRemove[1].name)
+
+        videoUUID = videos.find(video => video.name === 'my super name for pod 1').uuid
+      }
+    })
+
+    it('Should get the same video by UUID on each pod', async function () {
+      let baseVideo = null
+      for (const server of servers) {
+        const res = await getVideo(server.url, videoUUID)
+
+        const video = res.body
+
+        if (baseVideo === null) {
+          baseVideo = video
+          return
+        }
+
+        expect(baseVideo.name).to.equal(video.name)
+        expect(baseVideo.uuid).to.equal(video.uuid)
+        expect(baseVideo.category).to.equal(video.category)
+        expect(baseVideo.language).to.equal(video.language)
+        expect(baseVideo.licence).to.equal(video.licence)
+        expect(baseVideo.category).to.equal(video.category)
+        expect(baseVideo.nsfw).to.equal(video.nsfw)
+        expect(baseVideo.author).to.equal(video.author)
+        expect(baseVideo.tags).to.deep.equal(video.tags)
+      }
+    })
+
+    it('Should get the preview from each pod', async function () {
+      for (const server of servers) {
+        const res = await getVideo(server.url, videoUUID)
+        const video = res.body
+
+        const test = await testVideoImage(server.url, 'video_short1-preview.webm', video.previewPath)
+        expect(test).to.equal(true)
+      }
+    })
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/request-schedulers.js b/server/tests/api/request-schedulers.js
deleted file mode 100644 (file)
index c5ea72a..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const request = require('supertest')
-
-const loginUtils = require('../utils/login')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-
-describe('Test requests schedulers stats', function () {
-  const requestSchedulerNames = [ 'requestScheduler', 'requestVideoQaduScheduler', 'requestVideoEventScheduler' ]
-  const path = '/api/v1/request-schedulers/stats'
-  let servers = []
-
-  function uploadVideo (server, callback) {
-    const videoAttributes = {
-      tags: [ 'tag1', 'tag2' ]
-    }
-
-    videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, callback)
-  }
-
-  function getRequestsStats (server, callback) {
-    request(server.url)
-      .get(path)
-      .set('Accept', 'application/json')
-      .set('Authorization', 'Bearer ' + server.accessToken)
-      .expect(200)
-      .end(callback)
-  }
-
-  // ---------------------------------------------------------------
-
-  before(function (done) {
-    this.timeout(120000)
-    serversUtils.flushAndRunMultipleServers(2, function (serversRun, urlsRun) {
-      servers = serversRun
-
-      each(servers, function (server, callbackEach) {
-        loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-          if (err) return callbackEach(err)
-
-          server.accessToken = accessToken
-          callbackEach()
-        })
-      }, function (err) {
-        if (err) throw err
-
-        const server1 = servers[0]
-        podsUtils.makeFriends(server1.url, server1.accessToken, done)
-      })
-    })
-  })
-
-  it('Should have a correct timer', function (done) {
-    const server = servers[0]
-
-    getRequestsStats(server, function (err, res) {
-      if (err) throw err
-
-      const requestSchedulers = res.body
-      for (const requestSchedulerName of requestSchedulerNames) {
-        const requestScheduler = requestSchedulers[requestSchedulerName]
-
-        expect(requestScheduler.remainingMilliSeconds).to.be.at.least(0)
-        expect(requestScheduler.remainingMilliSeconds).to.be.at.most(10000)
-      }
-
-      done()
-    })
-  })
-
-  it('Should have the correct total request', function (done) {
-    this.timeout(15000)
-
-    const server = servers[0]
-    // Ensure the requests of pod 1 won't be made
-    servers[1].app.kill()
-
-    uploadVideo(server, function (err) {
-      if (err) throw err
-
-      setTimeout(function () {
-        getRequestsStats(server, function (err, res) {
-          if (err) throw err
-
-          const requestSchedulers = res.body
-          const requestScheduler = requestSchedulers.requestScheduler
-          expect(requestScheduler.totalRequests).to.equal(1)
-
-          done()
-        })
-      }, 1000)
-    })
-  })
-
-  after(function (done) {
-    process.kill(-servers[0].app.pid)
-
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/request-schedulers.ts b/server/tests/api/request-schedulers.ts
new file mode 100644 (file)
index 0000000..2358ed8
--- /dev/null
@@ -0,0 +1,89 @@
+/* tslint:disable:no-unused-expression */
+
+import * as request from 'supertest'
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  uploadVideo,
+  makeFriends,
+  wait,
+  setAccessTokensToServers,
+  flushAndRunMultipleServers
+} from '../utils'
+
+describe('Test requests schedulers stats', function () {
+  const requestSchedulerNames = [ 'requestScheduler', 'requestVideoQaduScheduler', 'requestVideoEventScheduler' ]
+  const path = '/api/v1/request-schedulers/stats'
+  let servers: ServerInfo[] = []
+
+  function uploadVideoWrapper (server: ServerInfo) {
+    const videoAttributes = {
+      tags: [ 'tag1', 'tag2' ]
+    }
+
+    return uploadVideo(server.url, server.accessToken, videoAttributes)
+  }
+
+  function getRequestsStats (server: ServerInfo) {
+    return request(server.url)
+            .get(path)
+            .set('Accept', 'application/json')
+            .set('Authorization', 'Bearer ' + server.accessToken)
+            .expect(200)
+  }
+
+  // ---------------------------------------------------------------
+
+  before(async function () {
+    this.timeout(120000)
+
+    servers = await flushAndRunMultipleServers(2)
+
+    await setAccessTokensToServers(servers)
+
+    await makeFriends(servers[0].url, servers[0].accessToken)
+  })
+
+  it('Should have a correct timer', async function () {
+    const server = servers[0]
+
+    const res = await getRequestsStats(server)
+
+    const requestSchedulers = res.body
+    for (const requestSchedulerName of requestSchedulerNames) {
+      const requestScheduler = requestSchedulers[requestSchedulerName]
+
+      expect(requestScheduler.remainingMilliSeconds).to.be.at.least(0)
+      expect(requestScheduler.remainingMilliSeconds).to.be.at.most(10000)
+    }
+  })
+
+  it('Should have the correct total request', async function () {
+    this.timeout(15000)
+
+    const server = servers[0]
+    // Ensure the requests of pod 1 won't be made
+    servers[1].app.kill()
+
+    await uploadVideoWrapper(server)
+
+    await wait(1000)
+
+    const res = await getRequestsStats(server)
+    const requestSchedulers = res.body
+    const requestScheduler = requestSchedulers.requestScheduler
+    expect(requestScheduler.totalRequests).to.equal(1)
+  })
+
+  after(async function () {
+    process.kill(-servers[0].app.pid)
+
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/single-pod.js b/server/tests/api/single-pod.js
deleted file mode 100644 (file)
index 6933d18..0000000
+++ /dev/null
@@ -1,841 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const fs = require('fs')
-const keyBy = require('lodash/keyBy')
-const pathUtils = require('path')
-const series = require('async/series')
-const webtorrent = new (require('webtorrent'))()
-
-const loginUtils = require('../utils/login')
-const miscsUtils = require('../utils/miscs')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-
-describe('Test a single pod', function () {
-  let server = null
-  let videoId = -1
-  let videoUUID = ''
-  let videosListBase = null
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should list video categories', function (done) {
-    videosUtils.getVideoCategories(server.url, function (err, res) {
-      if (err) throw err
-
-      const categories = res.body
-      expect(Object.keys(categories)).to.have.length.above(10)
-
-      expect(categories[11]).to.equal('News')
-
-      done()
-    })
-  })
-
-  it('Should list video licences', function (done) {
-    videosUtils.getVideoLicences(server.url, function (err, res) {
-      if (err) throw err
-
-      const licences = res.body
-      expect(Object.keys(licences)).to.have.length.above(5)
-
-      expect(licences[3]).to.equal('Attribution - No Derivatives')
-
-      done()
-    })
-  })
-
-  it('Should list video languages', function (done) {
-    videosUtils.getVideoLanguages(server.url, function (err, res) {
-      if (err) throw err
-
-      const languages = res.body
-      expect(Object.keys(languages)).to.have.length.above(5)
-
-      expect(languages[3]).to.equal('Mandarin')
-
-      done()
-    })
-  })
-
-  it('Should not have videos', function (done) {
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should upload the video', function (done) {
-    const videoAttributes = {
-      name: 'my super name',
-      category: 2,
-      nsfw: true,
-      licence: 6,
-      tags: [ 'tag1', 'tag2', 'tag3' ]
-    }
-    videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, done)
-  })
-
-  it('Should seed the uploaded video', function (done) {
-    // Yes, this could be long
-    this.timeout(60000)
-
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      const video = res.body.data[0]
-      expect(video.name).to.equal('my super name')
-      expect(video.category).to.equal(2)
-      expect(video.categoryLabel).to.equal('Films')
-      expect(video.licence).to.equal(6)
-      expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
-      expect(video.language).to.equal(3)
-      expect(video.languageLabel).to.equal('Mandarin')
-      expect(video.nsfw).to.be.ok
-      expect(video.description).to.equal('my super description')
-      expect(video.podHost).to.equal('localhost:9001')
-      expect(video.author).to.equal('root')
-      expect(video.isLocal).to.be.true
-      expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
-      expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-      expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-      expect(video.files).to.have.lengthOf(1)
-
-      const file = video.files[0]
-      const magnetUri = file.magnetUri
-      expect(file.magnetUri).to.exist
-      expect(file.resolution).to.equal(0)
-      expect(file.resolutionLabel).to.equal('original')
-      expect(file.size).to.equal(218910)
-
-      videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
-        if (err) throw err
-        expect(test).to.equal(true)
-
-        videoId = video.id
-        videoUUID = video.uuid
-
-        webtorrent.add(magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-  })
-
-  it('Should get the video', function (done) {
-    // Yes, this could be long
-    this.timeout(60000)
-
-    videosUtils.getVideo(server.url, videoId, function (err, res) {
-      if (err) throw err
-
-      const video = res.body
-      expect(video.name).to.equal('my super name')
-      expect(video.category).to.equal(2)
-      expect(video.categoryLabel).to.equal('Films')
-      expect(video.licence).to.equal(6)
-      expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
-      expect(video.language).to.equal(3)
-      expect(video.languageLabel).to.equal('Mandarin')
-      expect(video.nsfw).to.be.ok
-      expect(video.description).to.equal('my super description')
-      expect(video.podHost).to.equal('localhost:9001')
-      expect(video.author).to.equal('root')
-      expect(video.isLocal).to.be.true
-      expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
-      expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-      expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-      expect(video.files).to.have.lengthOf(1)
-
-      const file = video.files[0]
-      const magnetUri = file.magnetUri
-      expect(file.magnetUri).to.exist
-      expect(file.resolution).to.equal(0)
-      expect(file.resolutionLabel).to.equal('original')
-      expect(file.size).to.equal(218910)
-
-      videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
-        if (err) throw err
-        expect(test).to.equal(true)
-
-        // Wait the async views increment
-        setTimeout(done, 500)
-      })
-    })
-  })
-
-  it('Should get the video by UUID', function (done) {
-    // Yes, this could be long
-    this.timeout(60000)
-
-    videosUtils.getVideo(server.url, videoUUID, function (err, res) {
-      if (err) throw err
-
-      const video = res.body
-      expect(video.name).to.equal('my super name')
-
-      // Wait the async views increment
-      setTimeout(done, 500)
-    })
-  })
-
-  it('Should have the views updated', function (done) {
-    videosUtils.getVideo(server.url, videoId, function (err, res) {
-      if (err) throw err
-
-      const video = res.body
-      expect(video.views).to.equal(2)
-
-      done()
-    })
-  })
-
-  it('Should search the video by name by default', function (done) {
-    videosUtils.searchVideo(server.url, 'my', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      const video = res.body.data[0]
-      expect(video.name).to.equal('my super name')
-      expect(video.category).to.equal(2)
-      expect(video.categoryLabel).to.equal('Films')
-      expect(video.licence).to.equal(6)
-      expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
-      expect(video.language).to.equal(3)
-      expect(video.languageLabel).to.equal('Mandarin')
-      expect(video.nsfw).to.be.ok
-      expect(video.description).to.equal('my super description')
-      expect(video.podHost).to.equal('localhost:9001')
-      expect(video.author).to.equal('root')
-      expect(video.isLocal).to.be.true
-      expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
-      expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-      expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-      expect(video.files).to.have.lengthOf(1)
-
-      const file = video.files[0]
-      const magnetUri = file.magnetUri
-      expect(file.magnetUri).to.exist
-      expect(file.resolution).to.equal(0)
-      expect(file.resolutionLabel).to.equal('original')
-      expect(file.size).to.equal(218910)
-
-      videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
-        if (err) throw err
-        expect(test).to.equal(true)
-
-        done()
-      })
-    })
-  })
-
-  // Not implemented yet
-  // it('Should search the video by podHost', function (done) {
-  //   videosUtils.searchVideo(server.url, '9001', 'host', function (err, res) {
-  //     if (err) throw err
-
-  //     expect(res.body.total).to.equal(1)
-  //     expect(res.body.data).to.be.an('array')
-  //     expect(res.body.data.length).to.equal(1)
-
-  //     const video = res.body.data[0]
-  //     expect(video.name).to.equal('my super name')
-  //     expect(video.description).to.equal('my super description')
-  //     expect(video.podHost).to.equal('localhost:9001')
-  //     expect(video.author).to.equal('root')
-  //     expect(video.isLocal).to.be.true
-  //     expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
-  //     expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-  //     expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-  //     videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
-  //       if (err) throw err
-  //       expect(test).to.equal(true)
-
-  //       done()
-  //     })
-  //   })
-  // })
-
-  it('Should search the video by tag', function (done) {
-    videosUtils.searchVideo(server.url, 'tag1', 'tags', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      const video = res.body.data[0]
-      expect(video.name).to.equal('my super name')
-      expect(video.category).to.equal(2)
-      expect(video.categoryLabel).to.equal('Films')
-      expect(video.licence).to.equal(6)
-      expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
-      expect(video.language).to.equal(3)
-      expect(video.languageLabel).to.equal('Mandarin')
-      expect(video.nsfw).to.be.ok
-      expect(video.description).to.equal('my super description')
-      expect(video.podHost).to.equal('localhost:9001')
-      expect(video.author).to.equal('root')
-      expect(video.isLocal).to.be.true
-      expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
-      expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-      expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-      expect(video.files).to.have.lengthOf(1)
-
-      const file = video.files[0]
-      const magnetUri = file.magnetUri
-      expect(file.magnetUri).to.exist
-      expect(file.resolution).to.equal(0)
-      expect(file.resolutionLabel).to.equal('original')
-      expect(file.size).to.equal(218910)
-
-      videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
-        if (err) throw err
-        expect(test).to.equal(true)
-
-        done()
-      })
-    })
-  })
-
-  it('Should not find a search by name by default', function (done) {
-    videosUtils.searchVideo(server.url, 'hello', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should not find a search by author', function (done) {
-    videosUtils.searchVideo(server.url, 'hello', 'author', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should not find a search by tag', function (done) {
-    videosUtils.searchVideo(server.url, 'hello', 'tags', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should remove the video', function (done) {
-    videosUtils.removeVideo(server.url, server.accessToken, videoId, function (err) {
-      if (err) throw err
-
-      fs.readdir(pathUtils.join(__dirname, '..', '..', '..', 'test1/videos/'), function (err, files) {
-        if (err) throw err
-
-        expect(files.length).to.equal(0)
-
-        fs.readdir(pathUtils.join(__dirname, '..', '..', '..', 'test1/thumbnails/'), function (err, files) {
-          if (err) throw err
-
-          expect(files.length).to.equal(0)
-
-          done()
-        })
-      })
-    })
-  })
-
-  it('Should not have videos', function (done) {
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should upload 6 videos', function (done) {
-    this.timeout(25000)
-    const videos = [
-      'video_short.mp4', 'video_short.ogv', 'video_short.webm',
-      'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
-    ]
-    each(videos, function (video, callbackEach) {
-      const videoAttributes = {
-        name: video + ' name',
-        description: video + ' description',
-        category: 2,
-        licence: 1,
-        language: 1,
-        nsfw: true,
-        tags: [ 'tag1', 'tag2', 'tag3' ],
-        fixture: video
-      }
-
-      videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, callbackEach)
-    }, done)
-  })
-
-  it('Should have the correct durations', function (done) {
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(6)
-      const videos = res.body.data
-      expect(videos).to.be.an('array')
-      expect(videos.length).to.equal(6)
-
-      const videosByName = keyBy(videos, 'name')
-      expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
-      expect(videosByName['video_short.ogv name'].duration).to.equal(5)
-      expect(videosByName['video_short.webm name'].duration).to.equal(5)
-      expect(videosByName['video_short1.webm name'].duration).to.equal(10)
-      expect(videosByName['video_short2.webm name'].duration).to.equal(5)
-      expect(videosByName['video_short3.webm name'].duration).to.equal(5)
-
-      done()
-    })
-  })
-
-  it('Should have the correct thumbnails', function (done) {
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      // For the next test
-      videosListBase = videos
-
-      each(videos, function (video, callbackEach) {
-        if (err) throw err
-        const videoName = video.name.replace(' name', '')
-
-        videosUtils.testVideoImage(server.url, videoName, video.thumbnailPath, function (err, test) {
-          if (err) throw err
-
-          expect(test).to.equal(true)
-          callbackEach()
-        })
-      }, done)
-    })
-  })
-
-  it('Should list only the two first videos', function (done) {
-    videosUtils.getVideosListPagination(server.url, 0, 2, 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(6)
-      expect(videos.length).to.equal(2)
-      expect(videos[0].name).to.equal(videosListBase[0].name)
-      expect(videos[1].name).to.equal(videosListBase[1].name)
-
-      done()
-    })
-  })
-
-  it('Should list only the next three videos', function (done) {
-    videosUtils.getVideosListPagination(server.url, 2, 3, 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(6)
-      expect(videos.length).to.equal(3)
-      expect(videos[0].name).to.equal(videosListBase[2].name)
-      expect(videos[1].name).to.equal(videosListBase[3].name)
-      expect(videos[2].name).to.equal(videosListBase[4].name)
-
-      done()
-    })
-  })
-
-  it('Should list the last video', function (done) {
-    videosUtils.getVideosListPagination(server.url, 5, 6, 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(6)
-      expect(videos.length).to.equal(1)
-      expect(videos[0].name).to.equal(videosListBase[5].name)
-
-      done()
-    })
-  })
-
-  it('Should search the first video', function (done) {
-    videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(4)
-      expect(videos.length).to.equal(1)
-      expect(videos[0].name).to.equal('video_short1.webm name')
-
-      done()
-    })
-  })
-
-  it('Should search the last two videos', function (done) {
-    videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(4)
-      expect(videos.length).to.equal(2)
-      expect(videos[0].name).to.equal('video_short3.webm name')
-      expect(videos[1].name).to.equal('video_short.webm name')
-
-      done()
-    })
-  })
-
-  it('Should search all the webm videos', function (done) {
-    videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 15, function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(4)
-      expect(videos.length).to.equal(4)
-
-      done()
-    })
-  })
-
-  it('Should search all the root author videos', function (done) {
-    videosUtils.searchVideoWithPagination(server.url, 'root', 'author', 0, 15, function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(6)
-      expect(videos.length).to.equal(6)
-
-      done()
-    })
-  })
-
-  // Not implemented yet
-  // it('Should search all the 9001 port videos', function (done) {
-  //   videosUtils.searchVideoWithPagination(server.url, '9001', 'host', 0, 15, function (err, res) {
-  //     if (err) throw err
-
-  //     const videos = res.body.data
-  //     expect(res.body.total).to.equal(6)
-  //     expect(videos.length).to.equal(6)
-
-  //     done()
-  //   })
-  // })
-
-  // it('Should search all the localhost videos', function (done) {
-  //   videosUtils.searchVideoWithPagination(server.url, 'localhost', 'host', 0, 15, function (err, res) {
-  //     if (err) throw err
-
-  //     const videos = res.body.data
-  //     expect(res.body.total).to.equal(6)
-  //     expect(videos.length).to.equal(6)
-
-  //     done()
-  //   })
-  // })
-
-  it('Should search the right magnetUri video', function (done) {
-    const video = videosListBase[0]
-    videosUtils.searchVideoWithPagination(server.url, encodeURIComponent(video.files[0].magnetUri), 'magnetUri', 0, 15, function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(1)
-      expect(videos.length).to.equal(1)
-      expect(videos[0].name).to.equal(video.name)
-
-      done()
-    })
-  })
-
-  it('Should list and sort by name in descending order', function (done) {
-    videosUtils.getVideosListSort(server.url, '-name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(6)
-      expect(videos.length).to.equal(6)
-      expect(videos[0].name).to.equal('video_short.webm name')
-      expect(videos[1].name).to.equal('video_short.ogv name')
-      expect(videos[2].name).to.equal('video_short.mp4 name')
-      expect(videos[3].name).to.equal('video_short3.webm name')
-      expect(videos[4].name).to.equal('video_short2.webm name')
-      expect(videos[5].name).to.equal('video_short1.webm name')
-
-      done()
-    })
-  })
-
-  it('Should search and sort by name in ascending order', function (done) {
-    videosUtils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) {
-      if (err) throw err
-
-      const videos = res.body.data
-      expect(res.body.total).to.equal(4)
-      expect(videos.length).to.equal(4)
-
-      expect(videos[0].name).to.equal('video_short1.webm name')
-      expect(videos[1].name).to.equal('video_short2.webm name')
-      expect(videos[2].name).to.equal('video_short3.webm name')
-      expect(videos[3].name).to.equal('video_short.webm name')
-
-      videoId = videos[2].id
-
-      done()
-    })
-  })
-
-  it('Should update a video', function (done) {
-    const attributes = {
-      name: 'my super video updated',
-      category: 4,
-      licence: 2,
-      language: 5,
-      nsfw: false,
-      description: 'my super description updated',
-      tags: [ 'tagup1', 'tagup2' ]
-    }
-    videosUtils.updateVideo(server.url, server.accessToken, videoId, attributes, done)
-  })
-
-  it('Should have the video updated', function (done) {
-    this.timeout(60000)
-
-    videosUtils.getVideo(server.url, videoId, function (err, res) {
-      if (err) throw err
-
-      const video = res.body
-
-      expect(video.name).to.equal('my super video updated')
-      expect(video.category).to.equal(4)
-      expect(video.categoryLabel).to.equal('Art')
-      expect(video.licence).to.equal(2)
-      expect(video.licenceLabel).to.equal('Attribution - Share Alike')
-      expect(video.language).to.equal(5)
-      expect(video.languageLabel).to.equal('Arabic')
-      expect(video.nsfw).to.be.ok
-      expect(video.description).to.equal('my super description updated')
-      expect(video.podHost).to.equal('localhost:9001')
-      expect(video.author).to.equal('root')
-      expect(video.isLocal).to.be.true
-      expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
-      expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-      expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-      expect(video.files).to.have.lengthOf(1)
-
-      const file = video.files[0]
-      const magnetUri = file.magnetUri
-      expect(file.magnetUri).to.exist
-      expect(file.resolution).to.equal(0)
-      expect(file.resolutionLabel).to.equal('original')
-      expect(file.size).to.equal(292677)
-
-      videosUtils.testVideoImage(server.url, 'video_short3.webm', video.thumbnailPath, function (err, test) {
-        if (err) throw err
-        expect(test).to.equal(true)
-
-        webtorrent.add(magnetUri, function (torrent) {
-          expect(torrent.files).to.exist
-          expect(torrent.files.length).to.equal(1)
-          expect(torrent.files[0].path).to.exist.and.to.not.equal('')
-
-          done()
-        })
-      })
-    })
-  })
-
-  it('Should update only the tags of a video', function (done) {
-    const attributes = {
-      tags: [ 'tag1', 'tag2', 'supertag' ]
-    }
-
-    videosUtils.updateVideo(server.url, server.accessToken, videoId, attributes, function (err) {
-      if (err) throw err
-
-      videosUtils.getVideo(server.url, videoId, function (err, res) {
-        if (err) throw err
-
-        const video = res.body
-
-        expect(video.name).to.equal('my super video updated')
-        expect(video.category).to.equal(4)
-        expect(video.categoryLabel).to.equal('Art')
-        expect(video.licence).to.equal(2)
-        expect(video.licenceLabel).to.equal('Attribution - Share Alike')
-        expect(video.language).to.equal(5)
-        expect(video.languageLabel).to.equal('Arabic')
-        expect(video.nsfw).to.be.ok
-        expect(video.description).to.equal('my super description updated')
-        expect(video.podHost).to.equal('localhost:9001')
-        expect(video.author).to.equal('root')
-        expect(video.isLocal).to.be.true
-        expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
-        expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-        expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-        expect(video.files).to.have.lengthOf(1)
-
-        const file = video.files[0]
-        const magnetUri = file.magnetUri
-        expect(file.magnetUri).to.exist
-        expect(file.resolution).to.equal(0)
-        expect(file.resolutionLabel).to.equal('original')
-        expect(file.size).to.equal(292677)
-
-        done()
-      })
-    })
-  })
-
-  it('Should update only the description of a video', function (done) {
-    const attributes = {
-      description: 'hello everybody'
-    }
-
-    videosUtils.updateVideo(server.url, server.accessToken, videoId, attributes, function (err) {
-      if (err) throw err
-
-      videosUtils.getVideo(server.url, videoId, function (err, res) {
-        if (err) throw err
-
-        const video = res.body
-
-        expect(video.name).to.equal('my super video updated')
-        expect(video.category).to.equal(4)
-        expect(video.categoryLabel).to.equal('Art')
-        expect(video.licence).to.equal(2)
-        expect(video.licenceLabel).to.equal('Attribution - Share Alike')
-        expect(video.language).to.equal(5)
-        expect(video.languageLabel).to.equal('Arabic')
-        expect(video.nsfw).to.be.ok
-        expect(video.description).to.equal('hello everybody')
-        expect(video.podHost).to.equal('localhost:9001')
-        expect(video.author).to.equal('root')
-        expect(video.isLocal).to.be.true
-        expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
-        expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
-        expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
-
-        expect(video.files).to.have.lengthOf(1)
-
-        const file = video.files[0]
-        const magnetUri = file.magnetUri
-        expect(file.magnetUri).to.exist
-        expect(file.resolution).to.equal(0)
-        expect(file.resolutionLabel).to.equal('original')
-        expect(file.size).to.equal(292677)
-
-        done()
-      })
-    })
-  })
-
-  it('Should like a video', function (done) {
-    videosUtils.rateVideo(server.url, server.accessToken, videoId, 'like', function (err) {
-      if (err) throw err
-
-      videosUtils.getVideo(server.url, videoId, function (err, res) {
-        if (err) throw err
-
-        const video = res.body
-
-        expect(video.likes).to.equal(1)
-        expect(video.dislikes).to.equal(0)
-
-        done()
-      })
-    })
-  })
-
-  it('Should dislike the same video', function (done) {
-    videosUtils.rateVideo(server.url, server.accessToken, videoId, 'dislike', function (err) {
-      if (err) throw err
-
-      videosUtils.getVideo(server.url, videoId, function (err, res) {
-        if (err) throw err
-
-        const video = res.body
-
-        expect(video.likes).to.equal(0)
-        expect(video.dislikes).to.equal(1)
-
-        done()
-      })
-    })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/single-pod.ts b/server/tests/api/single-pod.ts
new file mode 100644 (file)
index 0000000..83c981f
--- /dev/null
@@ -0,0 +1,683 @@
+/* tslint:disable:no-unused-expression */
+
+import { keyBy } from 'lodash'
+import { join } from 'path'
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  uploadVideo,
+  getVideosList,
+  rateVideo,
+  removeVideo,
+  wait,
+  setAccessTokensToServers,
+  searchVideo,
+  killallServers,
+  dateIsValid,
+  getVideoCategories,
+  getVideoLicences,
+  getVideoLanguages,
+  testVideoImage,
+  webtorrentAdd,
+  getVideo,
+  readdirPromise,
+  getVideosListPagination,
+  searchVideoWithPagination,
+  getVideosListSort,
+  searchVideoWithSort,
+  updateVideo
+} from '../utils'
+
+describe('Test a single pod', function () {
+  let server: ServerInfo = null
+  let videoId = -1
+  let videoUUID = ''
+  let videosListBase: any[] = null
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+
+    server = await runServer(1)
+
+    await setAccessTokensToServers([ server ])
+  })
+
+  it('Should list video categories', async function () {
+    const res = await getVideoCategories(server.url)
+
+    const categories = res.body
+    expect(Object.keys(categories)).to.have.length.above(10)
+
+    expect(categories[11]).to.equal('News')
+  })
+
+  it('Should list video licences', async function () {
+    const res = await getVideoLicences(server.url)
+
+    const licences = res.body
+    expect(Object.keys(licences)).to.have.length.above(5)
+
+    expect(licences[3]).to.equal('Attribution - No Derivatives')
+  })
+
+  it('Should list video languages', async function () {
+    const res = await getVideoLanguages(server.url)
+
+    const languages = res.body
+    expect(Object.keys(languages)).to.have.length.above(5)
+
+    expect(languages[3]).to.equal('Mandarin')
+  })
+
+  it('Should not have videos', async function () {
+    const res = await getVideosList(server.url)
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should upload the video', async function () {
+    const videoAttributes = {
+      name: 'my super name',
+      category: 2,
+      nsfw: true,
+      licence: 6,
+      tags: [ 'tag1', 'tag2', 'tag3' ]
+    }
+    await uploadVideo(server.url, server.accessToken, videoAttributes)
+  })
+
+  it('Should seed the uploaded video', async function () {
+    // Yes, this could be long
+    this.timeout(60000)
+
+    const res = await getVideosList(server.url)
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(1)
+
+    const video = res.body.data[0]
+    expect(video.name).to.equal('my super name')
+    expect(video.category).to.equal(2)
+    expect(video.categoryLabel).to.equal('Films')
+    expect(video.licence).to.equal(6)
+    expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
+    expect(video.language).to.equal(3)
+    expect(video.languageLabel).to.equal('Mandarin')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    const magnetUri = file.magnetUri
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(218910)
+
+    const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
+    expect(test).to.equal(true)
+
+    videoId = video.id
+    videoUUID = video.uuid
+
+    const torrent = await webtorrentAdd(magnetUri)
+    expect(torrent.files).to.be.an('array')
+    expect(torrent.files.length).to.equal(1)
+    expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+  })
+
+  it('Should get the video', async function () {
+    // Yes, this could be long
+    this.timeout(60000)
+
+    const res = await getVideo(server.url, videoId)
+
+    const video = res.body
+    expect(video.name).to.equal('my super name')
+    expect(video.category).to.equal(2)
+    expect(video.categoryLabel).to.equal('Films')
+    expect(video.licence).to.equal(6)
+    expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
+    expect(video.language).to.equal(3)
+    expect(video.languageLabel).to.equal('Mandarin')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(218910)
+
+    const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
+    expect(test).to.equal(true)
+
+    // Wait the async views increment
+    await wait(500)
+  })
+
+  it('Should get the video by UUID', async function () {
+    // Yes, this could be long
+    this.timeout(60000)
+
+    const res = await getVideo(server.url, videoUUID)
+
+    const video = res.body
+    expect(video.name).to.equal('my super name')
+
+    // Wait the async views increment
+    await wait(500)
+  })
+
+  it('Should have the views updated', async function () {
+    const res = await getVideo(server.url, videoId)
+
+    const video = res.body
+    expect(video.views).to.equal(2)
+  })
+
+  it('Should search the video by name by default', async function () {
+    const res = await searchVideo(server.url, 'my')
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(1)
+
+    const video = res.body.data[0]
+    expect(video.name).to.equal('my super name')
+    expect(video.category).to.equal(2)
+    expect(video.categoryLabel).to.equal('Films')
+    expect(video.licence).to.equal(6)
+    expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
+    expect(video.language).to.equal(3)
+    expect(video.languageLabel).to.equal('Mandarin')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(218910)
+
+    const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
+    expect(test).to.equal(true)
+  })
+
+  // Not implemented yet
+  // it('Should search the video by podHost', async function () {
+  //     const res = await   videosUtils.searchVideo(server.url, '9001', 'host')
+
+  //     expect(res.body.total).to.equal(1)
+  //     expect(res.body.data).to.be.an('array')
+  //     expect(res.body.data.length).to.equal(1)
+
+  //     const video = res.body.data[0]
+  //     expect(video.name).to.equal('my super name')
+  //     expect(video.description).to.equal('my super description')
+  //     expect(video.podHost).to.equal('localhost:9001')
+  //     expect(video.author).to.equal('root')
+  //     expect(video.isLocal).to.be.true
+  //     expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
+  //     expect(dateIsValid(video.createdAt)).to.be.true
+  //     expect(dateIsValid(video.updatedAt)).to.be.true
+
+  //     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
+  //       expect(test).to.equal(true)
+
+  //       done()
+  //     })
+  //   })
+  // })
+
+  it('Should search the video by tag', async function () {
+    const res = await searchVideo(server.url, 'tag1', 'tags')
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(1)
+
+    const video = res.body.data[0]
+    expect(video.name).to.equal('my super name')
+    expect(video.category).to.equal(2)
+    expect(video.categoryLabel).to.equal('Films')
+    expect(video.licence).to.equal(6)
+    expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
+    expect(video.language).to.equal(3)
+    expect(video.languageLabel).to.equal('Mandarin')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(218910)
+
+    const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
+    expect(test).to.equal(true)
+  })
+
+  it('Should not find a search by name by default', async function () {
+    const res = await searchVideo(server.url, 'hello')
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should not find a search by author', async function () {
+    const res = await searchVideo(server.url, 'hello', 'author')
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should not find a search by tag', async function () {
+    const res = await searchVideo(server.url, 'hello', 'tags')
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should remove the video', async function () {
+    await removeVideo(server.url, server.accessToken, videoId)
+
+    const files1 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/videos/'))
+    expect(files1).to.have.lengthOf(0)
+
+    const files2 = await readdirPromise(join(__dirname, '..', '..', '..', 'test1/thumbnails/'))
+    expect(files2).to.have.lengthOf(0)
+  })
+
+  it('Should not have videos', async function () {
+    const res = await getVideosList(server.url)
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data).to.have.lengthOf(0)
+  })
+
+  it('Should upload 6 videos', async function () {
+    this.timeout(25000)
+
+    const videos = [
+      'video_short.mp4', 'video_short.ogv', 'video_short.webm',
+      'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
+    ]
+
+    const tasks: Promise<any>[] = []
+    for (const video of videos) {
+      const videoAttributes = {
+        name: video + ' name',
+        description: video + ' description',
+        category: 2,
+        licence: 1,
+        language: 1,
+        nsfw: true,
+        tags: [ 'tag1', 'tag2', 'tag3' ],
+        fixture: video
+      }
+
+      const p = uploadVideo(server.url, server.accessToken, videoAttributes)
+      tasks.push(p)
+    }
+
+    await Promise.all(tasks)
+  })
+
+  it('Should have the correct durations', async function () {
+    const res = await getVideosList(server.url)
+
+    expect(res.body.total).to.equal(6)
+    const videos = res.body.data
+    expect(videos).to.be.an('array')
+    expect(videos).to.have.lengthOf(6)
+
+    const videosByName = keyBy<{ duration: number }>(videos, 'name')
+    expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
+    expect(videosByName['video_short.ogv name'].duration).to.equal(5)
+    expect(videosByName['video_short.webm name'].duration).to.equal(5)
+    expect(videosByName['video_short1.webm name'].duration).to.equal(10)
+    expect(videosByName['video_short2.webm name'].duration).to.equal(5)
+    expect(videosByName['video_short3.webm name'].duration).to.equal(5)
+  })
+
+  it('Should have the correct thumbnails', async function () {
+    const res = await getVideosList(server.url)
+
+    const videos = res.body.data
+    // For the next test
+    videosListBase = videos
+
+    for (const video of videos) {
+      const videoName = video.name.replace(' name', '')
+      const test = await testVideoImage(server.url, videoName, video.thumbnailPath)
+
+      expect(test).to.equal(true)
+    }
+  })
+
+  it('Should list only the two first videos', async function () {
+    const res = await getVideosListPagination(server.url, 0, 2, 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(6)
+    expect(videos.length).to.equal(2)
+    expect(videos[0].name).to.equal(videosListBase[0].name)
+    expect(videos[1].name).to.equal(videosListBase[1].name)
+  })
+
+  it('Should list only the next three videos', async function () {
+    const res = await getVideosListPagination(server.url, 2, 3, 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(6)
+    expect(videos.length).to.equal(3)
+    expect(videos[0].name).to.equal(videosListBase[2].name)
+    expect(videos[1].name).to.equal(videosListBase[3].name)
+    expect(videos[2].name).to.equal(videosListBase[4].name)
+  })
+
+  it('Should list the last video', async function () {
+    const res = await getVideosListPagination(server.url, 5, 6, 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(6)
+    expect(videos.length).to.equal(1)
+    expect(videos[0].name).to.equal(videosListBase[5].name)
+  })
+
+  it('Should search the first video', async function () {
+    const res = await searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(4)
+    expect(videos.length).to.equal(1)
+    expect(videos[0].name).to.equal('video_short1.webm name')
+  })
+
+  it('Should search the last two videos', async function () {
+    const res = await searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(4)
+    expect(videos.length).to.equal(2)
+    expect(videos[0].name).to.equal('video_short3.webm name')
+    expect(videos[1].name).to.equal('video_short.webm name')
+  })
+
+  it('Should search all the webm videos', async function () {
+    const res = await searchVideoWithPagination(server.url, 'webm', 'name', 0, 15)
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(4)
+    expect(videos.length).to.equal(4)
+  })
+
+  it('Should search all the root author videos', async function () {
+    const res = await searchVideoWithPagination(server.url, 'root', 'author', 0, 15)
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(6)
+    expect(videos.length).to.equal(6)
+  })
+
+  // Not implemented yet
+  // it('Should search all the 9001 port videos', async function () {
+  // const res = await   videosUtils.searchVideoWithPagination(server.url, '9001', 'host', 0, 15)
+
+  //     const videos = res.body.data
+  //     expect(res.body.total).to.equal(6)
+  //     expect(videos.length).to.equal(6)
+
+  //     done()
+  //   })
+  // })
+
+  // it('Should search all the localhost videos', async function () {
+  // const res = await   videosUtils.searchVideoWithPagination(server.url, 'localhost', 'host', 0, 15)
+
+  //     const videos = res.body.data
+  //     expect(res.body.total).to.equal(6)
+  //     expect(videos.length).to.equal(6)
+
+  //     done()
+  //   })
+  // })
+
+  it('Should search the right magnetUri video', async function () {
+    const video = videosListBase[0]
+    const res = await searchVideoWithPagination(server.url, encodeURIComponent(video.files[0].magnetUri), 'magnetUri', 0, 15)
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(1)
+    expect(videos.length).to.equal(1)
+    expect(videos[0].name).to.equal(video.name)
+  })
+
+  it('Should list and sort by name in descending order', async function () {
+    const res = await getVideosListSort(server.url, '-name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(6)
+    expect(videos.length).to.equal(6)
+    expect(videos[0].name).to.equal('video_short.webm name')
+    expect(videos[1].name).to.equal('video_short.ogv name')
+    expect(videos[2].name).to.equal('video_short.mp4 name')
+    expect(videos[3].name).to.equal('video_short3.webm name')
+    expect(videos[4].name).to.equal('video_short2.webm name')
+    expect(videos[5].name).to.equal('video_short1.webm name')
+  })
+
+  it('Should search and sort by name in ascending order', async function () {
+    const res = await searchVideoWithSort(server.url, 'webm', 'name')
+
+    const videos = res.body.data
+    expect(res.body.total).to.equal(4)
+    expect(videos.length).to.equal(4)
+
+    expect(videos[0].name).to.equal('video_short1.webm name')
+    expect(videos[1].name).to.equal('video_short2.webm name')
+    expect(videos[2].name).to.equal('video_short3.webm name')
+    expect(videos[3].name).to.equal('video_short.webm name')
+
+    videoId = videos[2].id
+  })
+
+  it('Should update a video', async function () {
+    const attributes = {
+      name: 'my super video updated',
+      category: 4,
+      licence: 2,
+      language: 5,
+      nsfw: false,
+      description: 'my super description updated',
+      tags: [ 'tagup1', 'tagup2' ]
+    }
+    await updateVideo(server.url, server.accessToken, videoId, attributes)
+  })
+
+  it('Should have the video updated', async function () {
+    this.timeout(60000)
+
+    const res = await getVideo(server.url, videoId)
+
+    const video = res.body
+
+    expect(video.name).to.equal('my super video updated')
+    expect(video.category).to.equal(4)
+    expect(video.categoryLabel).to.equal('Art')
+    expect(video.licence).to.equal(2)
+    expect(video.licenceLabel).to.equal('Attribution - Share Alike')
+    expect(video.language).to.equal(5)
+    expect(video.languageLabel).to.equal('Arabic')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description updated')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    const magnetUri = file.magnetUri
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(292677)
+
+    const test = await testVideoImage(server.url, 'video_short3.webm', video.thumbnailPath)
+    expect(test).to.equal(true)
+
+    const torrent = await webtorrentAdd(magnetUri)
+    expect(torrent.files).to.be.an('array')
+    expect(torrent.files.length).to.equal(1)
+    expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+  })
+
+  it('Should update only the tags of a video', async function () {
+    const attributes = {
+      tags: [ 'tag1', 'tag2', 'supertag' ]
+    }
+
+    await updateVideo(server.url, server.accessToken, videoId, attributes)
+
+    const res = await getVideo(server.url, videoId)
+    const video = res.body
+
+    expect(video.name).to.equal('my super video updated')
+    expect(video.category).to.equal(4)
+    expect(video.categoryLabel).to.equal('Art')
+    expect(video.licence).to.equal(2)
+    expect(video.licenceLabel).to.equal('Attribution - Share Alike')
+    expect(video.language).to.equal(5)
+    expect(video.languageLabel).to.equal('Arabic')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('my super description updated')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(292677)
+  })
+
+  it('Should update only the description of a video', async function () {
+    const attributes = {
+      description: 'hello everybody'
+    }
+
+    await updateVideo(server.url, server.accessToken, videoId, attributes)
+
+    const res = await getVideo(server.url, videoId)
+    const video = res.body
+
+    expect(video.name).to.equal('my super video updated')
+    expect(video.category).to.equal(4)
+    expect(video.categoryLabel).to.equal('Art')
+    expect(video.licence).to.equal(2)
+    expect(video.licenceLabel).to.equal('Attribution - Share Alike')
+    expect(video.language).to.equal(5)
+    expect(video.languageLabel).to.equal('Arabic')
+    expect(video.nsfw).to.be.ok
+    expect(video.description).to.equal('hello everybody')
+    expect(video.podHost).to.equal('localhost:9001')
+    expect(video.author).to.equal('root')
+    expect(video.isLocal).to.be.true
+    expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'supertag' ])
+    expect(dateIsValid(video.createdAt)).to.be.true
+    expect(dateIsValid(video.updatedAt)).to.be.true
+
+    expect(video.files).to.have.lengthOf(1)
+
+    const file = video.files[0]
+    expect(file.magnetUri).to.have.lengthOf.above(2)
+    expect(file.resolution).to.equal(0)
+    expect(file.resolutionLabel).to.equal('original')
+    expect(file.size).to.equal(292677)
+  })
+
+  it('Should like a video', async function () {
+    await rateVideo(server.url, server.accessToken, videoId, 'like')
+
+    const res = await getVideo(server.url, videoId)
+    const video = res.body
+
+    expect(video.likes).to.equal(1)
+    expect(video.dislikes).to.equal(0)
+  })
+
+  it('Should dislike the same video', async function () {
+    await rateVideo(server.url, server.accessToken, videoId, 'dislike')
+
+    const res = await getVideo(server.url, videoId)
+    const video = res.body
+
+    expect(video.likes).to.equal(0)
+    expect(video.dislikes).to.equal(1)
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/users.js b/server/tests/api/users.js
deleted file mode 100644 (file)
index dacecf2..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const expect = chai.expect
-const series = require('async/series')
-
-const loginUtils = require('../utils/login')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const usersUtils = require('../utils/users')
-const requestsUtils = require('../utils/requests')
-const videosUtils = require('../utils/videos')
-
-describe('Test users', function () {
-  let server = null
-  let accessToken = null
-  let accessTokenUser = null
-  let videoId = null
-  let userId = null
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should create a new client')
-
-  it('Should return the first client')
-
-  it('Should remove the last client')
-
-  it('Should not login with an invalid client id', function (done) {
-    const client = { id: 'client', password: server.client.secret }
-    loginUtils.login(server.url, client, server.user, 400, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.error).to.equal('invalid_client')
-      done()
-    })
-  })
-
-  it('Should not login with an invalid client password', function (done) {
-    const client = { id: server.client.id, password: 'coucou' }
-    loginUtils.login(server.url, client, server.user, 400, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.error).to.equal('invalid_client')
-      done()
-    })
-  })
-
-  it('Should not login with an invalid username', function (done) {
-    const user = { username: 'captain crochet', password: server.user.password }
-    loginUtils.login(server.url, server.client, user, 400, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.error).to.equal('invalid_grant')
-      done()
-    })
-  })
-
-  it('Should not login with an invalid password', function (done) {
-    const user = { username: server.user.username, password: 'mewthree' }
-    loginUtils.login(server.url, server.client, user, 400, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.error).to.equal('invalid_grant')
-      done()
-    })
-  })
-
-  it('Should not be able to upload a video', function (done) {
-    accessToken = 'mysupertoken'
-
-    const videoAttributes = {}
-    videosUtils.uploadVideo(server.url, accessToken, videoAttributes, 401, done)
-  })
-
-  it('Should not be able to make friends', function (done) {
-    accessToken = 'mysupertoken'
-    podsUtils.makeFriends(server.url, accessToken, 401, done)
-  })
-
-  it('Should not be able to quit friends', function (done) {
-    accessToken = 'mysupertoken'
-    podsUtils.quitFriends(server.url, accessToken, 401, done)
-  })
-
-  it('Should be able to login', function (done) {
-    loginUtils.login(server.url, server.client, server.user, 200, function (err, res) {
-      if (err) throw err
-
-      accessToken = res.body.access_token
-      done()
-    })
-  })
-
-  it('Should upload the video with the correct token', function (done) {
-    const videoAttributes = {}
-    videosUtils.uploadVideo(server.url, accessToken, videoAttributes, 204, function (err, res) {
-      if (err) throw err
-
-      videosUtils.getVideosList(server.url, function (err, res) {
-        if (err) throw err
-
-        const video = res.body.data[0]
-        expect(video.author).to.equal('root')
-
-        videoId = video.id
-        done()
-      })
-    })
-  })
-
-  it('Should upload the video again with the correct token', function (done) {
-    const videoAttributes = {}
-    videosUtils.uploadVideo(server.url, accessToken, videoAttributes, 204, done)
-  })
-
-  it('Should retrieve a video rating', function (done) {
-    videosUtils.rateVideo(server.url, accessToken, videoId, 'like', function (err) {
-      if (err) throw err
-
-      usersUtils.getUserVideoRating(server.url, accessToken, videoId, function (err, res) {
-        if (err) throw err
-
-        const rating = res.body
-
-        expect(rating.videoId).to.equal(videoId)
-        expect(rating.rating).to.equal('like')
-
-        done()
-      })
-    })
-  })
-
-  it('Should not be able to remove the video with an incorrect token', function (done) {
-    videosUtils.removeVideo(server.url, 'bad_token', videoId, 401, done)
-  })
-
-  it('Should not be able to remove the video with the token of another account')
-
-  it('Should be able to remove the video with the correct token', function (done) {
-    videosUtils.removeVideo(server.url, accessToken, videoId, done)
-  })
-
-  it('Should logout (revoke token)')
-
-  it('Should not be able to get the user informations')
-
-  it('Should not be able to upload a video')
-
-  it('Should not be able to remove a video')
-
-  it('Should not be able to rate a video', function (done) {
-    const path = '/api/v1/videos/'
-    const data = {
-      rating: 'likes'
-    }
-
-    requestsUtils.makePutBodyRequest(server.url, path + videoId, 'wrong token', data, done, 401)
-  })
-
-  it('Should be able to login again')
-
-  it('Should have an expired access token')
-
-  it('Should refresh the token')
-
-  it('Should be able to upload a video again')
-
-  it('Should be able to create a new user', function (done) {
-    usersUtils.createUser(server.url, accessToken, 'user_1', 'super password', done)
-  })
-
-  it('Should be able to login with this user', function (done) {
-    server.user = {
-      username: 'user_1',
-      password: 'super password'
-    }
-
-    loginUtils.loginAndGetAccessToken(server, function (err, token) {
-      if (err) throw err
-
-      accessTokenUser = token
-
-      done()
-    })
-  })
-
-  it('Should be able to get the user informations', function (done) {
-    usersUtils.getUserInformation(server.url, accessTokenUser, function (err, res) {
-      if (err) throw err
-
-      const user = res.body
-
-      expect(user.username).to.equal('user_1')
-      expect(user.email).to.equal('user_1@example.com')
-      expect(user.displayNSFW).to.be.false
-      expect(user.id).to.exist
-
-      done()
-    })
-  })
-
-  it('Should be able to upload a video with this user', function (done) {
-    this.timeout(5000)
-
-    const videoAttributes = {}
-    videosUtils.uploadVideo(server.url, accessTokenUser, videoAttributes, done)
-  })
-
-  it('Should list all the users', function (done) {
-    usersUtils.getUsersList(server.url, function (err, res) {
-      if (err) throw err
-
-      const result = res.body
-      const total = result.total
-      const users = result.data
-
-      expect(total).to.equal(2)
-      expect(users).to.be.an('array')
-      expect(users.length).to.equal(2)
-
-      const user = users[0]
-      expect(user.username).to.equal('user_1')
-      expect(user.email).to.equal('user_1@example.com')
-      expect(user.displayNSFW).to.be.false
-
-      const rootUser = users[1]
-      expect(rootUser.username).to.equal('root')
-      expect(rootUser.email).to.equal('admin1@example.com')
-      expect(rootUser.displayNSFW).to.be.false
-
-      userId = user.id
-
-      done()
-    })
-  })
-
-  it('Should list only the first user by username asc', function (done) {
-    usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, 'username', function (err, res) {
-      if (err) throw err
-
-      const result = res.body
-      const total = result.total
-      const users = result.data
-
-      expect(total).to.equal(2)
-      expect(users.length).to.equal(1)
-
-      const user = users[0]
-      expect(user.username).to.equal('root')
-      expect(user.email).to.equal('admin1@example.com')
-      expect(user.displayNSFW).to.be.false
-
-      done()
-    })
-  })
-
-  it('Should list only the first user by username desc', function (done) {
-    usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-username', function (err, res) {
-      if (err) throw err
-
-      const result = res.body
-      const total = result.total
-      const users = result.data
-
-      expect(total).to.equal(2)
-      expect(users.length).to.equal(1)
-
-      const user = users[0]
-      expect(user.username).to.equal('user_1')
-      expect(user.email).to.equal('user_1@example.com')
-      expect(user.displayNSFW).to.be.false
-
-      done()
-    })
-  })
-
-  it('Should list only the second user by createdAt desc', function (done) {
-    usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-createdAt', function (err, res) {
-      if (err) throw err
-
-      const result = res.body
-      const total = result.total
-      const users = result.data
-
-      expect(total).to.equal(2)
-      expect(users.length).to.equal(1)
-
-      const user = users[0]
-      expect(user.username).to.equal('user_1')
-      expect(user.email).to.equal('user_1@example.com')
-      expect(user.displayNSFW).to.be.false
-
-      done()
-    })
-  })
-
-  it('Should list all the users by createdAt asc', function (done) {
-    usersUtils.getUsersListPaginationAndSort(server.url, 0, 2, 'createdAt', function (err, res) {
-      if (err) throw err
-
-      const result = res.body
-      const total = result.total
-      const users = result.data
-
-      expect(total).to.equal(2)
-      expect(users.length).to.equal(2)
-
-      expect(users[0].username).to.equal('root')
-      expect(users[0].email).to.equal('admin1@example.com')
-      expect(users[0].displayNSFW).to.be.false
-
-      expect(users[1].username).to.equal('user_1')
-      expect(users[1].email).to.equal('user_1@example.com')
-      expect(users[1].displayNSFW).to.be.false
-
-      done()
-    })
-  })
-
-  it('Should update the user password', function (done) {
-    usersUtils.updateUser(server.url, userId, accessTokenUser, 'new password', null, function (err, res) {
-      if (err) throw err
-
-      server.user.password = 'new password'
-      loginUtils.login(server.url, server.client, server.user, 200, done)
-    })
-  })
-
-  it('Should be able to change the NSFW display attribute', function (done) {
-    usersUtils.updateUser(server.url, userId, accessTokenUser, null, true, function (err, res) {
-      if (err) throw err
-
-      usersUtils.getUserInformation(server.url, accessTokenUser, function (err, res) {
-        if (err) throw err
-
-        const user = res.body
-
-        expect(user.username).to.equal('user_1')
-        expect(user.email).to.equal('user_1@example.com')
-        expect(user.displayNSFW).to.be.ok
-        expect(user.id).to.exist
-
-        done()
-      })
-    })
-  })
-
-  it('Should be able to remove this user', function (done) {
-    usersUtils.removeUser(server.url, userId, accessToken, done)
-  })
-
-  it('Should not be able to login with this user', function (done) {
-    // server.user is already set to user 1
-    loginUtils.login(server.url, server.client, server.user, 400, done)
-  })
-
-  it('Should not have videos of this user', function (done) {
-    videosUtils.getVideosList(server.url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      const video = res.body.data[0]
-      expect(video.author).to.equal('root')
-
-      done()
-    })
-  })
-
-  it('Should register a new user', function (done) {
-    usersUtils.registerUser(server.url, 'user_15', 'my super password', done)
-  })
-
-  it('Should be able to login with this registered user', function (done) {
-    server.user = {
-      username: 'user_15',
-      password: 'my super password'
-    }
-
-    loginUtils.loginAndGetAccessToken(server, done)
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/users.ts b/server/tests/api/users.ts
new file mode 100644 (file)
index 0000000..fd3b511
--- /dev/null
@@ -0,0 +1,343 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  login,
+  uploadVideo,
+  makeFriends,
+  quitFriends,
+  getVideosList,
+  rateVideo,
+  getUserVideoRating,
+  removeVideo,
+  makePutBodyRequest,
+  createUser,
+  loginAndGetAccessToken,
+  getUserInformation,
+  getUsersList,
+  getUsersListPaginationAndSort,
+  updateUser,
+  registerUser,
+  removeUser
+} from '../utils'
+import { killallServers } from '../utils/servers'
+
+describe('Test users', function () {
+  let server: ServerInfo
+  let accessToken: string
+  let accessTokenUser: string
+  let videoId: number
+  let userId: number
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+    server = await runServer(1)
+  })
+
+  it('Should create a new client')
+
+  it('Should return the first client')
+
+  it('Should remove the last client')
+
+  it('Should not login with an invalid client id', async function () {
+    const client = { id: 'client', secret: server.client.secret }
+    const res = await login(server.url, client, server.user, 400)
+
+    expect(res.body.error).to.equal('invalid_client')
+  })
+
+  it('Should not login with an invalid client secret', async function () {
+    const client = { id: server.client.id, secret: 'coucou' }
+    const res = await login(server.url, client, server.user, 400)
+
+    expect(res.body.error).to.equal('invalid_client')
+  })
+
+  it('Should not login with an invalid username', async function () {
+    const user = { username: 'captain crochet', password: server.user.password }
+    const res = await login(server.url, server.client, user, 400)
+
+    expect(res.body.error).to.equal('invalid_grant')
+  })
+
+  it('Should not login with an invalid password', async function () {
+    const user = { username: server.user.username, password: 'mewthree' }
+    const res = await login(server.url, server.client, user, 400)
+
+    expect(res.body.error).to.equal('invalid_grant')
+  })
+
+  it('Should not be able to upload a video', async function () {
+    accessToken = 'my_super_token'
+
+    const videoAttributes = {}
+    await uploadVideo(server.url, accessToken, videoAttributes, 401)
+  })
+
+  it('Should not be able to make friends', async function () {
+    accessToken = 'my_super_token'
+    await makeFriends(server.url, accessToken, 401)
+  })
+
+  it('Should not be able to quit friends', async function () {
+    accessToken = 'my_super_token'
+    await quitFriends(server.url, accessToken, 401)
+  })
+
+  it('Should be able to login', async function () {
+    const res = await login(server.url, server.client, server.user, 200)
+
+    accessToken = res.body.access_token
+  })
+
+  it('Should upload the video with the correct token', async function () {
+    const videoAttributes = {}
+    await uploadVideo(server.url, accessToken, videoAttributes, 204)
+    const res = await getVideosList(server.url)
+    const video = res.body.data[0]
+
+    expect(video.author).to.equal('root')
+    videoId = video.id
+  })
+
+  it('Should upload the video again with the correct token', async function () {
+    const videoAttributes = {}
+    await uploadVideo(server.url, accessToken, videoAttributes, 204)
+  })
+
+  it('Should retrieve a video rating', async function () {
+    await rateVideo(server.url, accessToken, videoId, 'like')
+    const res = await getUserVideoRating(server.url, accessToken, videoId)
+    const rating = res.body
+
+    expect(rating.videoId).to.equal(videoId)
+    expect(rating.rating).to.equal('like')
+  })
+
+  it('Should not be able to remove the video with an incorrect token', async function () {
+    await removeVideo(server.url, 'bad_token', videoId, 401)
+  })
+
+  it('Should not be able to remove the video with the token of another account')
+
+  it('Should be able to remove the video with the correct token', async function () {
+    await removeVideo(server.url, accessToken, videoId)
+  })
+
+  it('Should logout (revoke token)')
+
+  it('Should not be able to get the user information')
+
+  it('Should not be able to upload a video')
+
+  it('Should not be able to remove a video')
+
+  it('Should not be able to rate a video', async function () {
+    const path = '/api/v1/videos/'
+    const data = {
+      rating: 'likes'
+    }
+
+    const options = {
+      url: server.url,
+      path: path + videoId,
+      token: 'wrong token',
+      fields: data,
+      statusCodeExpected: 401
+    }
+    await makePutBodyRequest(options)
+  })
+
+  it('Should be able to login again')
+
+  it('Should have an expired access token')
+
+  it('Should refresh the token')
+
+  it('Should be able to upload a video again')
+
+  it('Should be able to create a new user', async function () {
+    await createUser(server.url, accessToken, 'user_1', 'super password')
+  })
+
+  it('Should be able to login with this user', async function () {
+    server.user = {
+      username: 'user_1',
+      password: 'super password'
+    }
+
+    accessTokenUser = await loginAndGetAccessToken(server)
+  })
+
+  it('Should be able to get the user information', async function () {
+    const res = await getUserInformation(server.url, accessTokenUser)
+    const user = res.body
+
+    expect(user.username).to.equal('user_1')
+    expect(user.email).to.equal('user_1@example.com')
+    expect(user.displayNSFW).to.be.false
+    expect(user.id).to.be.a('number')
+  })
+
+  it('Should be able to upload a video with this user', async function () {
+    this.timeout(5000)
+
+    const videoAttributes = {}
+    await uploadVideo(server.url, accessTokenUser, videoAttributes)
+  })
+
+  it('Should list all the users', async function () {
+    const res = await getUsersList(server.url)
+    const result = res.body
+    const total = result.total
+    const users = result.data
+
+    expect(total).to.equal(2)
+    expect(users).to.be.an('array')
+    expect(users.length).to.equal(2)
+
+    const user = users[0]
+    expect(user.username).to.equal('user_1')
+    expect(user.email).to.equal('user_1@example.com')
+    expect(user.displayNSFW).to.be.false
+
+    const rootUser = users[1]
+    expect(rootUser.username).to.equal('root')
+    expect(rootUser.email).to.equal('admin1@example.com')
+    expect(rootUser.displayNSFW).to.be.false
+
+    userId = user.id
+  })
+
+  it('Should list only the first user by username asc', async function () {
+    const res = await getUsersListPaginationAndSort(server.url, 0, 1, 'username')
+
+    const result = res.body
+    const total = result.total
+    const users = result.data
+
+    expect(total).to.equal(2)
+    expect(users.length).to.equal(1)
+
+    const user = users[0]
+    expect(user.username).to.equal('root')
+    expect(user.email).to.equal('admin1@example.com')
+    expect(user.displayNSFW).to.be.false
+  })
+
+  it('Should list only the first user by username desc', async function () {
+    const res = await getUsersListPaginationAndSort(server.url, 0, 1, '-username')
+    const result = res.body
+    const total = result.total
+    const users = result.data
+
+    expect(total).to.equal(2)
+    expect(users.length).to.equal(1)
+
+    const user = users[0]
+    expect(user.username).to.equal('user_1')
+    expect(user.email).to.equal('user_1@example.com')
+    expect(user.displayNSFW).to.be.false
+  })
+
+  it('Should list only the second user by createdAt desc', async function () {
+    const res = await getUsersListPaginationAndSort(server.url, 0, 1, '-createdAt')
+    const result = res.body
+    const total = result.total
+    const users = result.data
+
+    expect(total).to.equal(2)
+    expect(users.length).to.equal(1)
+
+    const user = users[0]
+    expect(user.username).to.equal('user_1')
+    expect(user.email).to.equal('user_1@example.com')
+    expect(user.displayNSFW).to.be.false
+  })
+
+  it('Should list all the users by createdAt asc', async function () {
+    const res = await getUsersListPaginationAndSort(server.url, 0, 2, 'createdAt')
+    const result = res.body
+    const total = result.total
+    const users = result.data
+
+    expect(total).to.equal(2)
+    expect(users.length).to.equal(2)
+
+    expect(users[0].username).to.equal('root')
+    expect(users[0].email).to.equal('admin1@example.com')
+    expect(users[0].displayNSFW).to.be.false
+
+    expect(users[1].username).to.equal('user_1')
+    expect(users[1].email).to.equal('user_1@example.com')
+    expect(users[1].displayNSFW).to.be.false
+  })
+
+  it('Should update the user password', async function () {
+    await updateUser(server.url, userId, accessTokenUser, 'new password', null)
+    server.user.password = 'new password'
+
+    await login(server.url, server.client, server.user, 200)
+  })
+
+  it('Should be able to change the NSFW display attribute', async function () {
+    await updateUser(server.url, userId, accessTokenUser, null, true)
+
+    const res = await getUserInformation(server.url, accessTokenUser)
+    const user = res.body
+
+    expect(user.username).to.equal('user_1')
+    expect(user.email).to.equal('user_1@example.com')
+    expect(user.displayNSFW).to.be.ok
+    expect(user.id).to.be.a('number')
+  })
+
+  it('Should be able to remove this user', async function () {
+    await removeUser(server.url, userId, accessToken)
+  })
+
+  it('Should not be able to login with this user', async function () {
+    // server.user is already set to user 1
+    await login(server.url, server.client, server.user, 400)
+  })
+
+  it('Should not have videos of this user', async function () {
+    const res = await getVideosList(server.url)
+
+    expect(res.body.total).to.equal(1)
+
+    const video = res.body.data[0]
+    expect(video.author).to.equal('root')
+  })
+
+  it('Should register a new user', async function () {
+    await registerUser(server.url, 'user_15', 'my super password')
+  })
+
+  it('Should be able to login with this registered user', async function () {
+    server.user = {
+      username: 'user_15',
+      password: 'my super password'
+    }
+
+    await loginAndGetAccessToken(server)
+  })
+
+  after(async function () {
+    killallServers([ server ])
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/video-abuse.js b/server/tests/api/video-abuse.js
deleted file mode 100644 (file)
index be35a36..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const series = require('async/series')
-
-const loginUtils = require('../utils/login')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-const videoAbusesUtils = require('../utils/video-abuses')
-
-describe('Test video abuses', function () {
-  let servers = []
-
-  before(function (done) {
-    this.timeout(100000)
-
-    series([
-      // Run servers
-      function (next) {
-        serversUtils.flushAndRunMultipleServers(2, function (serversRun) {
-          servers = serversRun
-          next()
-        })
-      },
-      // Get the access tokens
-      function (next) {
-        each(servers, function (server, callbackEach) {
-          loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-            if (err) return callbackEach(err)
-
-            server.accessToken = accessToken
-            callbackEach()
-          })
-        }, next)
-      },
-      // Pod 1 makes friend with pod 2
-      function (next) {
-        const server = servers[0]
-        podsUtils.makeFriends(server.url, server.accessToken, next)
-      },
-      // Upload some videos on each pods
-      function (next) {
-        const videoAttributes = {
-          name: 'my super name for pod 1',
-          description: 'my super description for pod 1'
-        }
-        videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes, next)
-      },
-      function (next) {
-        const videoAttributes = {
-          name: 'my super name for pod 2',
-          description: 'my super description for pod 2'
-        }
-        videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes, next)
-      },
-      // Wait videos propagation
-      function (next) {
-        setTimeout(next, 22000)
-      },
-      function (next) {
-        videosUtils.getVideosList(servers[0].url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-
-          expect(videos.length).to.equal(2)
-
-          servers[0].video = videos.find(function (video) { return video.name === 'my super name for pod 1' })
-          servers[1].video = videos.find(function (video) { return video.name === 'my super name for pod 2' })
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should not have video abuses', function (done) {
-    videoAbusesUtils.getVideoAbusesList(servers[0].url, servers[0].accessToken, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should report abuse on a local video', function (done) {
-    this.timeout(15000)
-
-    const reason = 'my super bad reason'
-    videoAbusesUtils.reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason, function (err) {
-      if (err) throw err
-
-      // We wait requests propagation, even if the pod 1 is not supposed to make a request to pod 2
-      setTimeout(done, 11000)
-    })
-  })
-
-  it('Should have 1 video abuses on pod 1 and 0 on pod 2', function (done) {
-    videoAbusesUtils.getVideoAbusesList(servers[0].url, servers[0].accessToken, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      const abuse = res.body.data[0]
-      expect(abuse.reason).to.equal('my super bad reason')
-      expect(abuse.reporterUsername).to.equal('root')
-      expect(abuse.reporterPodHost).to.equal('localhost:9001')
-      expect(abuse.videoId).to.equal(servers[0].video.id)
-
-      videoAbusesUtils.getVideoAbusesList(servers[1].url, servers[1].accessToken, function (err, res) {
-        if (err) throw err
-
-        expect(res.body.total).to.equal(0)
-        expect(res.body.data).to.be.an('array')
-        expect(res.body.data.length).to.equal(0)
-
-        done()
-      })
-    })
-  })
-
-  it('Should report abuse on a remote video', function (done) {
-    this.timeout(15000)
-
-    const reason = 'my super bad reason 2'
-    videoAbusesUtils.reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason, function (err) {
-      if (err) throw err
-
-      // We wait requests propagation
-      setTimeout(done, 11000)
-    })
-  })
-
-  it('Should have 2 video abuse on pod 1 and 1 on pod 2', function (done) {
-    videoAbusesUtils.getVideoAbusesList(servers[0].url, servers[0].accessToken, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(2)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(2)
-
-      let abuse = res.body.data[0]
-      expect(abuse.reason).to.equal('my super bad reason')
-      expect(abuse.reporterUsername).to.equal('root')
-      expect(abuse.reporterPodHost).to.equal('localhost:9001')
-      expect(abuse.videoId).to.equal(servers[0].video.id)
-
-      abuse = res.body.data[1]
-      expect(abuse.reason).to.equal('my super bad reason 2')
-      expect(abuse.reporterUsername).to.equal('root')
-      expect(abuse.reporterPodHost).to.equal('localhost:9001')
-      expect(abuse.videoId).to.equal(servers[1].video.id)
-
-      videoAbusesUtils.getVideoAbusesList(servers[1].url, servers[1].accessToken, function (err, res) {
-        if (err) throw err
-
-        expect(res.body.total).to.equal(1)
-        expect(res.body.data).to.be.an('array')
-        expect(res.body.data.length).to.equal(1)
-
-        let abuse = res.body.data[0]
-        expect(abuse.reason).to.equal('my super bad reason 2')
-        expect(abuse.reporterUsername).to.equal('root')
-        expect(abuse.reporterPodHost).to.equal('localhost:9001')
-
-        done()
-      })
-    })
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/video-abuse.ts b/server/tests/api/video-abuse.ts
new file mode 100644 (file)
index 0000000..f2a2c32
--- /dev/null
@@ -0,0 +1,145 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushAndRunMultipleServers,
+  uploadVideo,
+  makeFriends,
+  getVideosList,
+  wait,
+  setAccessTokensToServers,
+  getVideoAbusesList,
+  reportVideoAbuse,
+  killallServers,
+  flushTests
+} from '../utils'
+
+describe('Test video abuses', function () {
+  let servers: ServerInfo[] = []
+
+  before(async function () {
+    this.timeout(100000)
+
+    // Run servers
+    servers = await flushAndRunMultipleServers(2)
+
+    // Get the access tokens
+    await setAccessTokensToServers(servers)
+
+    // Pod 1 makes friend with pod 2
+    await makeFriends(servers[0].url, servers[0].accessToken)
+
+    // Upload some videos on each pods
+    const video1Attributes = {
+      name: 'my super name for pod 1',
+      description: 'my super description for pod 1'
+    }
+    await uploadVideo(servers[0].url, servers[0].accessToken, video1Attributes)
+
+    const video2Attributes = {
+      name: 'my super name for pod 2',
+      description: 'my super description for pod 2'
+    }
+    await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes)
+
+    // Wait videos propagation
+    await wait(22000)
+
+    const res = await getVideosList(servers[0].url)
+    const videos = res.body.data
+
+    expect(videos.length).to.equal(2)
+
+    servers[0].video = videos.find(video => video.name === 'my super name for pod 1')
+    servers[1].video = videos.find(video => video.name === 'my super name for pod 2')
+  })
+
+  it('Should not have video abuses', async function () {
+    const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should report abuse on a local video', async function () {
+    this.timeout(15000)
+
+    const reason = 'my super bad reason'
+    await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[0].video.id, reason)
+
+    // We wait requests propagation, even if the pod 1 is not supposed to make a request to pod 2
+    await wait(11000)
+  })
+
+  it('Should have 1 video abuses on pod 1 and 0 on pod 2', async function () {
+    const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
+
+    expect(res1.body.total).to.equal(1)
+    expect(res1.body.data).to.be.an('array')
+    expect(res1.body.data.length).to.equal(1)
+
+    const abuse = res1.body.data[0]
+    expect(abuse.reason).to.equal('my super bad reason')
+    expect(abuse.reporterUsername).to.equal('root')
+    expect(abuse.reporterPodHost).to.equal('localhost:9001')
+    expect(abuse.videoId).to.equal(servers[0].video.id)
+
+    const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
+    expect(res2.body.total).to.equal(0)
+    expect(res2.body.data).to.be.an('array')
+    expect(res2.body.data.length).to.equal(0)
+  })
+
+  it('Should report abuse on a remote video', async function () {
+    this.timeout(15000)
+
+    const reason = 'my super bad reason 2'
+    await reportVideoAbuse(servers[0].url, servers[0].accessToken, servers[1].video.id, reason)
+
+    // We wait requests propagation
+    await wait(11000)
+  })
+
+  it('Should have 2 video abuse on pod 1 and 1 on pod 2', async function () {
+    const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken)
+    expect(res1.body.total).to.equal(2)
+    expect(res1.body.data).to.be.an('array')
+    expect(res1.body.data.length).to.equal(2)
+
+    const abuse1 = res1.body.data[0]
+    expect(abuse1.reason).to.equal('my super bad reason')
+    expect(abuse1.reporterUsername).to.equal('root')
+    expect(abuse1.reporterPodHost).to.equal('localhost:9001')
+    expect(abuse1.videoId).to.equal(servers[0].video.id)
+
+    const abuse2 = res1.body.data[1]
+    expect(abuse2.reason).to.equal('my super bad reason 2')
+    expect(abuse2.reporterUsername).to.equal('root')
+    expect(abuse2.reporterPodHost).to.equal('localhost:9001')
+    expect(abuse2.videoId).to.equal(servers[1].video.id)
+
+    const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken)
+    expect(res2.body.total).to.equal(1)
+    expect(res2.body.data).to.be.an('array')
+    expect(res2.body.data.length).to.equal(1)
+
+    const abuse3 = res2.body.data[0]
+    expect(abuse3.reason).to.equal('my super bad reason 2')
+    expect(abuse3.reporterUsername).to.equal('root')
+    expect(abuse3.reporterPodHost).to.equal('localhost:9001')
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/video-blacklist.js b/server/tests/api/video-blacklist.js
deleted file mode 100644 (file)
index 79a2fec..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const series = require('async/series')
-
-const loginUtils = require('../utils/login')
-const podsUtils = require('../utils/pods')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-const videoBlacklistsUtils = require('../utils/video-blacklists')
-
-describe('Test video blacklists', function () {
-  let servers = []
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      // Run servers
-      function (next) {
-        serversUtils.flushAndRunMultipleServers(2, function (serversRun) {
-          servers = serversRun
-          next()
-        })
-      },
-      // Get the access tokens
-      function (next) {
-        each(servers, function (server, callbackEach) {
-          loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-            if (err) return callbackEach(err)
-
-            server.accessToken = accessToken
-            callbackEach()
-          })
-        }, next)
-      },
-      // Pod 1 makes friend with pod 2
-      function (next) {
-        const server = servers[0]
-        podsUtils.makeFriends(server.url, server.accessToken, next)
-      },
-      // Upload a video on pod 2
-      function (next) {
-        const videoAttributes = {
-          name: 'my super name for pod 2',
-          description: 'my super description for pod 2'
-        }
-        videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes, next)
-      },
-      // Wait videos propagation
-      function (next) {
-        setTimeout(next, 22000)
-      },
-      function (next) {
-        videosUtils.getVideosList(servers[0].url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-
-          expect(videos.length).to.equal(1)
-
-          servers[0].remoteVideo = videos.find(function (video) { return video.name === 'my super name for pod 2' })
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('Should blacklist a remote video on pod 1', function (done) {
-    videoBlacklistsUtils.addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id, done)
-  })
-
-  it('Should not have the video blacklisted in videos list on pod 1', function (done) {
-    videosUtils.getVideosList(servers[0].url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should not have the video blacklisted in videos search on pod 1', function (done) {
-    videosUtils.searchVideo(servers[0].url, 'name', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(0)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(0)
-
-      done()
-    })
-  })
-
-  it('Should have the blacklisted video in videos list on pod 2', function (done) {
-    videosUtils.getVideosList(servers[1].url, function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      done()
-    })
-  })
-
-  it('Should have the video blacklisted in videos search on pod 2', function (done) {
-    videosUtils.searchVideo(servers[1].url, 'name', function (err, res) {
-      if (err) throw err
-
-      expect(res.body.total).to.equal(1)
-      expect(res.body.data).to.be.an('array')
-      expect(res.body.data.length).to.equal(1)
-
-      done()
-    })
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/video-blacklist.ts b/server/tests/api/video-blacklist.ts
new file mode 100644 (file)
index 0000000..e789611
--- /dev/null
@@ -0,0 +1,98 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  uploadVideo,
+  makeFriends,
+  getVideosList,
+  wait,
+  setAccessTokensToServers,
+  flushAndRunMultipleServers,
+  addVideoToBlacklist,
+  searchVideo,
+  killallServers
+} from '../utils'
+
+describe('Test video blacklists', function () {
+  let servers: ServerInfo[] = []
+
+  before(async function () {
+    this.timeout(120000)
+
+    // Run servers
+    servers = await flushAndRunMultipleServers(2)
+
+    // Get the access tokens
+    await setAccessTokensToServers(servers)
+
+    // Pod 1 makes friend with pod 2
+    await makeFriends(servers[0].url, servers[0].accessToken)
+
+    // Upload a video on pod 2
+    const videoAttributes = {
+      name: 'my super name for pod 2',
+      description: 'my super description for pod 2'
+    }
+    await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
+
+    // Wait videos propagation
+    await wait(22000)
+
+    const res = await getVideosList(servers[0].url)
+    const videos = res.body.data
+
+    expect(videos.length).to.equal(1)
+
+    servers[0].remoteVideo = videos.find(video => video.name === 'my super name for pod 2')
+  })
+
+  it('Should blacklist a remote video on pod 1', async function () {
+    await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id)
+  })
+
+  it('Should not have the video blacklisted in videos list on pod 1', async function () {
+    const res = await getVideosList(servers[0].url)
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should not have the video blacklisted in videos search on pod 1', async function () {
+    const res = await searchVideo(servers[0].url, 'name')
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(0)
+  })
+
+  it('Should have the blacklisted video in videos list on pod 2', async function () {
+    const res = await getVideosList(servers[1].url)
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(1)
+  })
+
+  it('Should have the video blacklisted in videos search on pod 2', async function () {
+    const res = await searchVideo(servers[1].url, 'name')
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.be.an('array')
+    expect(res.body.data.length).to.equal(1)
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/api/video-transcoder.js b/server/tests/api/video-transcoder.js
deleted file mode 100644 (file)
index c7af3cf..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const each = require('async/each')
-const expect = chai.expect
-const series = require('async/series')
-const webtorrent = new (require('webtorrent'))()
-
-const loginUtils = require('../utils/login')
-const serversUtils = require('../utils/servers')
-const videosUtils = require('../utils/videos')
-
-describe('Test video transcoding', function () {
-  let servers = []
-
-  before(function (done) {
-    this.timeout(30000)
-
-    series([
-      // Run servers
-      function (next) {
-        serversUtils.flushAndRunMultipleServers(2, function (serversRun) {
-          servers = serversRun
-          next()
-        })
-      },
-      // Get the access tokens
-      function (next) {
-        each(servers, function (server, callbackEach) {
-          loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
-            if (err) return callbackEach(err)
-
-            server.accessToken = accessToken
-            callbackEach()
-          })
-        }, next)
-      }
-    ], done)
-  })
-
-  it('Should not transcode video on server 1', function (done) {
-    this.timeout(60000)
-
-    const videoAttributes = {
-      name: 'my super name for pod 1',
-      description: 'my super description for pod 1',
-      fixture: 'video_short.webm'
-    }
-    videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes, function (err) {
-      if (err) throw err
-
-      setTimeout(function () {
-        videosUtils.getVideosList(servers[0].url, function (err, res) {
-          if (err) throw err
-
-          const video = res.body.data[0]
-          const magnetUri = video.files[0].magnetUri
-          expect(magnetUri).to.match(/\.webm/)
-
-          webtorrent.add(magnetUri, function (torrent) {
-            expect(torrent.files).to.exist
-            expect(torrent.files.length).to.equal(1)
-            expect(torrent.files[0].path).match(/\.webm$/)
-
-            done()
-          })
-        })
-      }, 30000)
-    })
-  })
-
-  it('Should transcode video on server 2', function (done) {
-    this.timeout(60000)
-
-    const videoAttributes = {
-      name: 'my super name for pod 2',
-      description: 'my super description for pod 2',
-      fixture: 'video_short.webm'
-    }
-    videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes, function (err) {
-      if (err) throw err
-
-      setTimeout(function () {
-        videosUtils.getVideosList(servers[1].url, function (err, res) {
-          if (err) throw err
-
-          const video = res.body.data[0]
-          const magnetUri = video.files[0].magnetUri
-          expect(magnetUri).to.match(/\.mp4/)
-
-          webtorrent.add(magnetUri, function (torrent) {
-            expect(torrent.files).to.exist
-            expect(torrent.files.length).to.equal(1)
-            expect(torrent.files[0].path).match(/\.mp4$/)
-
-            done()
-          })
-        })
-      }, 30000)
-    })
-  })
-
-  after(function (done) {
-    servers.forEach(function (server) {
-      process.kill(-server.app.pid)
-    })
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/api/video-transcoder.ts b/server/tests/api/video-transcoder.ts
new file mode 100644 (file)
index 0000000..228cef0
--- /dev/null
@@ -0,0 +1,86 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  uploadVideo,
+  getVideosList,
+  wait,
+  setAccessTokensToServers,
+  flushAndRunMultipleServers,
+  killallServers,
+  webtorrentAdd
+} from '../utils'
+
+describe('Test video transcoding', function () {
+  let servers: ServerInfo[] = []
+
+  before(async function () {
+    this.timeout(30000)
+
+    // Run servers
+    servers = await flushAndRunMultipleServers(2)
+
+    await setAccessTokensToServers(servers)
+  })
+
+  it('Should not transcode video on server 1', async function () {
+    this.timeout(60000)
+
+    const videoAttributes = {
+      name: 'my super name for pod 1',
+      description: 'my super description for pod 1',
+      fixture: 'video_short.webm'
+    }
+    await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
+
+    await wait(30000)
+
+    const res = await getVideosList(servers[0].url)
+    const video = res.body.data[0]
+    const magnetUri = video.files[0].magnetUri
+    expect(magnetUri).to.match(/\.webm/)
+
+    const torrent = await webtorrentAdd(magnetUri)
+    expect(torrent.files).to.be.an('array')
+    expect(torrent.files.length).to.equal(1)
+    expect(torrent.files[0].path).match(/\.webm$/)
+  })
+
+  it('Should transcode video on server 2', async function () {
+    this.timeout(60000)
+
+    const videoAttributes = {
+      name: 'my super name for pod 2',
+      description: 'my super description for pod 2',
+      fixture: 'video_short.webm'
+    }
+    await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
+
+    await wait(30000)
+
+    const res = await getVideosList(servers[1].url)
+
+    const video = res.body.data[0]
+    const magnetUri = video.files[0].magnetUri
+    expect(magnetUri).to.match(/\.mp4/)
+
+    const torrent = await webtorrentAdd(magnetUri)
+    expect(torrent.files).to.be.an('array')
+    expect(torrent.files.length).to.equal(1)
+    expect(torrent.files[0].path).match(/\.mp4$/)
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/client.js b/server/tests/client.js
deleted file mode 100644 (file)
index 0cdf0a2..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* eslint-disable no-unused-expressions */
-
-'use strict'
-
-const chai = require('chai')
-const expect = chai.expect
-const request = require('supertest')
-const series = require('async/series')
-
-const loginUtils = require('./utils/login')
-const serversUtils = require('./utils/servers')
-const videosUtils = require('./utils/videos')
-
-describe('Test a client controllers', function () {
-  let server = null
-
-  before(function (done) {
-    this.timeout(120000)
-
-    series([
-      function (next) {
-        serversUtils.flushTests(next)
-      },
-      function (next) {
-        serversUtils.runServer(1, function (server1) {
-          server = server1
-          next()
-        })
-      },
-      function (next) {
-        loginUtils.loginAndGetAccessToken(server, function (err, token) {
-          if (err) throw err
-          server.accessToken = token
-          next()
-        })
-      },
-      function (next) {
-        const videoAttributes = {
-          name: 'my super name for pod 1',
-          description: 'my super description for pod 1'
-        }
-        videosUtils.uploadVideo(server.url, server.accessToken, videoAttributes, next)
-      },
-      function (next) {
-        videosUtils.getVideosList(server.url, function (err, res) {
-          if (err) throw err
-
-          const videos = res.body.data
-
-          expect(videos.length).to.equal(1)
-
-          server.video = videos[0]
-
-          next()
-        })
-      }
-    ], done)
-  })
-
-  it('It should have valid opengraph tags on the watch page with video id', function (done) {
-    request(server.url)
-      .get('/videos/watch/' + server.video.id)
-      .expect(200, function (err, res) {
-        if (err) throw err
-
-        expect(res.text).to.contain('<meta property="og:title" content="my super name for pod 1" />')
-        expect(res.text).to.contain('<meta property="og:description" content="my super description for pod 1" />')
-
-        done()
-      })
-  })
-
-  it('It should have valid opengraph tags on the watch page with video uuid', function (done) {
-    request(server.url)
-      .get('/videos/watch/' + server.video.uuid)
-      .expect(200, function (err, res) {
-        if (err) throw err
-
-        expect(res.text).to.contain('<meta property="og:title" content="my super name for pod 1" />')
-        expect(res.text).to.contain('<meta property="og:description" content="my super description for pod 1" />')
-
-        done()
-      })
-  })
-
-  after(function (done) {
-    process.kill(-server.app.pid)
-
-    // Keep the logs if the test failed
-    if (this.ok) {
-      serversUtils.flushTests(done)
-    } else {
-      done()
-    }
-  })
-})
diff --git a/server/tests/client.ts b/server/tests/client.ts
new file mode 100644 (file)
index 0000000..5e5abba
--- /dev/null
@@ -0,0 +1,68 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+import * as request from 'supertest'
+const expect = chai.expect
+
+import {
+  ServerInfo,
+  flushTests,
+  runServer,
+  loginAndGetAccessToken,
+  uploadVideo,
+  getVideosList
+} from './utils'
+
+describe('Test a client controllers', function () {
+  let server: ServerInfo
+
+  before(async function () {
+    this.timeout(120000)
+
+    await flushTests()
+
+    server = await runServer(1)
+    server.accessToken = await loginAndGetAccessToken(server)
+
+    const videoAttributes = {
+      name: 'my super name for pod 1',
+      description: 'my super description for pod 1'
+    }
+    await uploadVideo(server.url, server.accessToken, videoAttributes)
+
+    const res = await getVideosList(server.url)
+    const videos = res.body.data
+
+    expect(videos.length).to.equal(1)
+
+    server.video = videos[0]
+  })
+
+  it('It should have valid Open Graph tags on the watch page with video id', async function () {
+    const res = await request(server.url)
+                        .get('/videos/watch/' + server.video.id)
+                        .expect(200)
+
+    expect(res.text).to.contain('<meta property="og:title" content="my super name for pod 1" />')
+    expect(res.text).to.contain('<meta property="og:description" content="my super description for pod 1" />')
+  })
+
+  it('It should have valid Open Graph tags on the watch page with video uuid', async function () {
+    const res = await request(server.url)
+                        .get('/videos/watch/' + server.video.uuid)
+                        .expect(200)
+
+    expect(res.text).to.contain('<meta property="og:title" content="my super name for pod 1" />')
+    expect(res.text).to.contain('<meta property="og:description" content="my super description for pod 1" />')
+  })
+
+  after(async function () {
+    process.kill(-server.app.pid)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
diff --git a/server/tests/index.js b/server/tests/index.js
deleted file mode 100644 (file)
index 0bc0523..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-'use strict'
-
-// Order of the tests we want to execute
-require('./client')
-require('./api/')
diff --git a/server/tests/index.ts b/server/tests/index.ts
new file mode 100644 (file)
index 0000000..26f0816
--- /dev/null
@@ -0,0 +1,3 @@
+// Order of the tests we want to execute
+import './client'
+import './api/'
diff --git a/server/tests/utils/clients.js b/server/tests/utils/clients.js
deleted file mode 100644 (file)
index b3ae18d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const clientsUtils = {
-  getClient: getClient
-}
-
-// ---------------------- Export functions --------------------
-
-function getClient (url, end) {
-  const path = '/api/v1/clients/local'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = clientsUtils
diff --git a/server/tests/utils/clients.ts b/server/tests/utils/clients.ts
new file mode 100644 (file)
index 0000000..22676bb
--- /dev/null
@@ -0,0 +1,17 @@
+import * as request from 'supertest'
+
+function getClient (url: string) {
+  const path = '/api/v1/clients/local'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getClient
+}
diff --git a/server/tests/utils/config.js b/server/tests/utils/config.js
deleted file mode 100644 (file)
index 0a507a6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const configsUtils = {
-  getConfig
-}
-
-// ---------------------- Export functions --------------------
-
-function getConfig (url, end) {
-  const path = '/api/v1/config'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = configsUtils
diff --git a/server/tests/utils/config.ts b/server/tests/utils/config.ts
new file mode 100644 (file)
index 0000000..d09c19c
--- /dev/null
@@ -0,0 +1,17 @@
+import * as request from 'supertest'
+
+function getConfig (url: string) {
+  const path = '/api/v1/config'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getConfig
+}
diff --git a/server/tests/utils/index.ts b/server/tests/utils/index.ts
new file mode 100644 (file)
index 0000000..9077b05
--- /dev/null
@@ -0,0 +1,12 @@
+export * from './clients'
+export * from './config'
+export * from './login'
+export * from './miscs'
+export * from './pods'
+export * from './request-schedulers'
+export * from './requests'
+export * from './servers'
+export * from './users'
+export * from './video-abuses'
+export * from './video-blacklists'
+export * from './videos'
diff --git a/server/tests/utils/login.js b/server/tests/utils/login.js
deleted file mode 100644 (file)
index c984c0b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const loginUtils = {
-  login,
-  loginAndGetAccessToken,
-  getUserAccessToken
-}
-
-// ---------------------- Export functions --------------------
-
-function login (url, client, user, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 200
-  }
-
-  const path = '/api/v1/users/token'
-
-  const body = {
-    client_id: client.id,
-    client_secret: client.secret,
-    username: user.username,
-    password: user.password,
-    response_type: 'code',
-    grant_type: 'password',
-    scope: 'upload'
-  }
-
-  request(url)
-    .post(path)
-    .type('form')
-    .send(body)
-    .expect(expectedStatus)
-    .end(end)
-}
-
-function loginAndGetAccessToken (server, callback) {
-  login(server.url, server.client, server.user, 200, function (err, res) {
-    if (err) return callback(err)
-
-    return callback(null, res.body.access_token)
-  })
-}
-
-function getUserAccessToken (server, user, callback) {
-  login(server.url, server.client, user, 200, function (err, res) {
-    if (err) return callback(err)
-
-    return callback(null, res.body.access_token)
-  })
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = loginUtils
diff --git a/server/tests/utils/login.ts b/server/tests/utils/login.ts
new file mode 100644 (file)
index 0000000..c9d4aed
--- /dev/null
@@ -0,0 +1,59 @@
+import * as request from 'supertest'
+
+import { ServerInfo } from './servers'
+
+type Client = { id: string, secret: string }
+type User = { username: string, password: string }
+type Server = { url: string, client: Client, user: User }
+
+function login (url: string, client: Client, user: User, expectedStatus = 200) {
+  const path = '/api/v1/users/token'
+
+  const body = {
+    client_id: client.id,
+    client_secret: client.secret,
+    username: user.username,
+    password: user.password,
+    response_type: 'code',
+    grant_type: 'password',
+    scope: 'upload'
+  }
+
+  return request(url)
+          .post(path)
+          .type('form')
+          .send(body)
+          .expect(expectedStatus)
+}
+
+async function loginAndGetAccessToken (server: Server) {
+  const res = await login(server.url, server.client, server.user, 200)
+
+  return res.body.access_token as string
+}
+
+async function getUserAccessToken (server, user) {
+  const res = await login(server.url, server.client, user, 200)
+
+  return res.body.access_token as string
+}
+
+function setAccessTokensToServers (servers: ServerInfo[]) {
+  const tasks: Promise<any>[] = []
+
+  for (const server of servers) {
+    const p = loginAndGetAccessToken(server).then(t => server.accessToken = t)
+    tasks.push(p)
+  }
+
+  return Promise.all(tasks)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  login,
+  loginAndGetAccessToken,
+  getUserAccessToken,
+  setAccessTokensToServers
+}
diff --git a/server/tests/utils/miscs.js b/server/tests/utils/miscs.js
deleted file mode 100644 (file)
index c4b6614..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-'use strict'
-
-const miscsUtils = {
-  dateIsValid
-}
-
-// ---------------------- Export functions --------------------
-
-function dateIsValid (dateString, interval) {
-  const dateToCheck = new Date(dateString)
-  const now = new Date()
-
-  // Check if the interval is more than 2 minutes
-  if (!interval) interval = 120000
-
-  if (now - dateToCheck > interval) return false
-
-  return true
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = miscsUtils
diff --git a/server/tests/utils/miscs.ts b/server/tests/utils/miscs.ts
new file mode 100644 (file)
index 0000000..424b0db
--- /dev/null
@@ -0,0 +1,52 @@
+import * as WebTorrent from 'webtorrent'
+import { readFile, readdir } from 'fs'
+
+let webtorrent = new WebTorrent()
+
+function readFilePromise (path: string) {
+  return new Promise<Buffer>((res, rej) => {
+    readFile(path, (err, data) => {
+      if (err) return rej(err)
+
+      return res(data)
+    })
+  })
+}
+
+function readdirPromise (path: string) {
+  return new Promise<string[]>((res, rej) => {
+    readdir(path, (err, files) => {
+      if (err) return rej(err)
+
+      return res(files)
+    })
+  })
+}
+
+  // Default interval -> 2 minutes
+function dateIsValid (dateString: string, interval = 120000) {
+  const dateToCheck = new Date(dateString)
+  const now = new Date()
+
+  return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval
+}
+
+function wait (milliseconds: number) {
+  return new Promise(resolve => setTimeout(resolve, milliseconds))
+}
+
+function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
+  if (refreshWebTorrent === true) webtorrent = new WebTorrent()
+
+  return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  readFilePromise,
+  readdirPromise,
+  dateIsValid,
+  wait,
+  webtorrentAdd
+}
diff --git a/server/tests/utils/pods.js b/server/tests/utils/pods.js
deleted file mode 100644 (file)
index cdabb64..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const podsUtils = {
-  getFriendsList,
-  makeFriends,
-  quitFriends,
-  quitOneFriend
-}
-
-// ---------------------- Export functions --------------------
-
-function getFriendsList (url, end) {
-  const path = '/api/v1/pods/'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function makeFriends (url, accessToken, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 204
-  }
-
-  // Which pod makes friends with which pod
-  const friendsMatrix = {
-    'http://localhost:9001': [
-      'localhost:9002'
-    ],
-    'http://localhost:9002': [
-      'localhost:9003'
-    ],
-    'http://localhost:9003': [
-      'localhost:9001'
-    ],
-    'http://localhost:9004': [
-      'localhost:9002'
-    ],
-    'http://localhost:9005': [
-      'localhost:9001',
-      'localhost:9004'
-    ],
-    'http://localhost:9006': [
-      'localhost:9001',
-      'localhost:9002',
-      'localhost:9003'
-    ]
-  }
-  const path = '/api/v1/pods/makefriends'
-
-  // The first pod make friend with the third
-  request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .send({ 'hosts': friendsMatrix[url] })
-    .expect(expectedStatus)
-    .end(function (err, res) {
-      if (err) throw err
-
-      // Wait for the request between pods
-      setTimeout(end, 1000)
-    })
-}
-
-function quitFriends (url, accessToken, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 204
-  }
-
-  const path = '/api/v1/pods/quitfriends'
-
-  // The first pod make friend with the third
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(expectedStatus)
-    .end(function (err, res) {
-      if (err) throw err
-
-      // Wait for the request between pods
-      setTimeout(end, 1000)
-    })
-}
-
-function quitOneFriend (url, accessToken, friendId, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 204
-  }
-
-  const path = '/api/v1/pods/' + friendId
-
-  request(url)
-    .delete(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(expectedStatus)
-    .end(function (err, res) {
-      if (err) throw err
-
-      end()
-    })
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = podsUtils
diff --git a/server/tests/utils/pods.ts b/server/tests/utils/pods.ts
new file mode 100644 (file)
index 0000000..0bea6db
--- /dev/null
@@ -0,0 +1,89 @@
+import * as request from 'supertest'
+
+import { wait } from './miscs'
+
+function getFriendsList (url: string) {
+  const path = '/api/v1/pods/'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+async function makeFriends (url: string, accessToken: string, expectedStatus = 204) {
+  // Which pod makes friends with which pod
+  const friendsMatrix = {
+    'http://localhost:9001': [
+      'localhost:9002'
+    ],
+    'http://localhost:9002': [
+      'localhost:9003'
+    ],
+    'http://localhost:9003': [
+      'localhost:9001'
+    ],
+    'http://localhost:9004': [
+      'localhost:9002'
+    ],
+    'http://localhost:9005': [
+      'localhost:9001',
+      'localhost:9004'
+    ],
+    'http://localhost:9006': [
+      'localhost:9001',
+      'localhost:9002',
+      'localhost:9003'
+    ]
+  }
+  const path = '/api/v1/pods/makefriends'
+
+  // The first pod make friend with the third
+  const res = await request(url)
+                      .post(path)
+                      .set('Accept', 'application/json')
+                      .set('Authorization', 'Bearer ' + accessToken)
+                      .send({ 'hosts': friendsMatrix[url] })
+                      .expect(expectedStatus)
+
+  // Wait request propagation
+  await wait(1000)
+
+  return res
+}
+
+async function quitFriends (url: string, accessToken: string, expectedStatus = 204) {
+  const path = '/api/v1/pods/quitfriends'
+
+  // The first pod make friend with the third
+  const res = await request(url)
+                      .get(path)
+                      .set('Accept', 'application/json')
+                      .set('Authorization', 'Bearer ' + accessToken)
+                      .expect(expectedStatus)
+
+  // Wait request propagation
+  await wait(1000)
+
+  return res
+}
+
+function quitOneFriend (url: string, accessToken: string, friendId: number, expectedStatus = 204) {
+  const path = '/api/v1/pods/' + friendId
+
+  return request(url)
+          .delete(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(expectedStatus)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getFriendsList,
+  makeFriends,
+  quitFriends,
+  quitOneFriend
+}
diff --git a/server/tests/utils/request-schedulers.js b/server/tests/utils/request-schedulers.js
deleted file mode 100644 (file)
index 16835ce..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const requestsStatsUtils = {
-  getRequestsStats
-}
-
-// ---------------------- Export functions --------------------
-
-function getRequestsStats (server, accessToken, callback) {
-  const path = '/api/v1/requests/stats'
-
-  request(server.url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(callback)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = requestsStatsUtils
diff --git a/server/tests/utils/request-schedulers.ts b/server/tests/utils/request-schedulers.ts
new file mode 100644 (file)
index 0000000..ae8227b
--- /dev/null
@@ -0,0 +1,18 @@
+import * as request from 'supertest'
+
+function getRequestsStats (server: { url: string }, accessToken: string) {
+  const path = '/api/v1/requests/stats'
+
+  return request(server.url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getRequestsStats
+}
diff --git a/server/tests/utils/requests.js b/server/tests/utils/requests.js
deleted file mode 100644 (file)
index 84cf348..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const requestsUtils = {
-  makePostUploadRequest,
-  makePostBodyRequest,
-  makePutBodyRequest
-}
-
-// ---------------------- Export functions --------------------
-
-function makePostUploadRequest (url, path, token, fields, attaches, done, statusCodeExpected) {
-  if (!statusCodeExpected) statusCodeExpected = 400
-
-  const req = request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-
-  if (token) req.set('Authorization', 'Bearer ' + token)
-
-  Object.keys(fields).forEach(function (field) {
-    const value = fields[field]
-
-    if (Array.isArray(value)) {
-      for (let i = 0; i < value.length; i++) {
-        req.field(field + '[' + i + ']', value[i])
-      }
-    } else {
-      req.field(field, value)
-    }
-  })
-
-  Object.keys(attaches).forEach(function (attach) {
-    const value = attaches[attach]
-    req.attach(attach, value)
-  })
-
-  req.expect(statusCodeExpected)
-     .end(done)
-}
-
-function makePostBodyRequest (url, path, token, fields, done, statusCodeExpected) {
-  if (!statusCodeExpected) statusCodeExpected = 400
-
-  const req = request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-
-  if (token) req.set('Authorization', 'Bearer ' + token)
-
-  req.send(fields)
-     .expect(statusCodeExpected)
-     .end(done)
-}
-
-function makePutBodyRequest (url, path, token, fields, done, statusCodeExpected) {
-  if (!statusCodeExpected) statusCodeExpected = 400
-
-  const req = request(url)
-    .put(path)
-    .set('Accept', 'application/json')
-
-  if (token) req.set('Authorization', 'Bearer ' + token)
-
-  req.send(fields)
-     .expect(statusCodeExpected)
-     .end(done)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = requestsUtils
diff --git a/server/tests/utils/requests.ts b/server/tests/utils/requests.ts
new file mode 100644 (file)
index 0000000..52b7a4c
--- /dev/null
@@ -0,0 +1,92 @@
+import * as request from 'supertest'
+
+function makeGetRequest (url: string, path: string) {
+  return request(url)
+    .get(path)
+    .set('Accept', 'application/json')
+    .expect(200)
+    .expect('Content-Type', /json/)
+}
+
+function makePostUploadRequest (options: {
+  url: string,
+  path: string,
+  token: string,
+  fields: { [ fieldName: string ]: any },
+  attaches: { [ attachName: string ]: any },
+  statusCodeExpected?: number
+}) {
+  if (!options.statusCodeExpected) options.statusCodeExpected = 400
+
+  const req = request(options.url)
+                .post(options.path)
+                .set('Accept', 'application/json')
+
+  if (options.token) req.set('Authorization', 'Bearer ' + options.token)
+
+  Object.keys(options.fields).forEach(field => {
+    const value = options.fields[field]
+
+    if (Array.isArray(value)) {
+      for (let i = 0; i < value.length; i++) {
+        req.field(field + '[' + i + ']', value[i])
+      }
+    } else {
+      req.field(field, value)
+    }
+  })
+
+  Object.keys(options.attaches).forEach(attach => {
+    const value = options.attaches[attach]
+    req.attach(attach, value)
+  })
+
+  return req.expect(options.statusCodeExpected)
+}
+
+function makePostBodyRequest (options: {
+  url: string,
+  path: string,
+  token?: string,
+  fields: { [ fieldName: string ]: any },
+  statusCodeExpected?: number
+}) {
+  if (!options.statusCodeExpected) options.statusCodeExpected = 400
+
+  const req = request(options.url)
+                .post(options.path)
+                .set('Accept', 'application/json')
+
+  if (options.token) req.set('Authorization', 'Bearer ' + options.token)
+
+  return req.send(options.fields)
+            .expect(options.statusCodeExpected)
+}
+
+function makePutBodyRequest (options: {
+  url: string,
+  path: string,
+  token: string,
+  fields: { [ fieldName: string ]: any },
+  statusCodeExpected?: number
+}) {
+  if (!options.statusCodeExpected) options.statusCodeExpected = 400
+
+  const req = request(options.url)
+                .put(options.path)
+                .set('Accept', 'application/json')
+
+  if (options.token) req.set('Authorization', 'Bearer ' + options.token)
+
+  return req.send(options.fields)
+            .expect(options.statusCodeExpected)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  makeGetRequest,
+  makePostUploadRequest,
+  makePostBodyRequest,
+  makePutBodyRequest
+}
diff --git a/server/tests/utils/servers.js b/server/tests/utils/servers.js
deleted file mode 100644 (file)
index c753c1f..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-'use strict'
-
-const childProcess = require('child_process')
-const exec = childProcess.exec
-const fork = childProcess.fork
-const pathUtils = require('path')
-
-const serversUtils = {
-  flushAndRunMultipleServers,
-  flushTests,
-  runServer
-}
-
-// ---------------------- Export functions --------------------
-
-function flushAndRunMultipleServers (totalServers, serversRun) {
-  let apps = []
-  let urls = []
-  let i = 0
-
-  function anotherServerDone (number, app, url) {
-    apps[number - 1] = app
-    urls[number - 1] = url
-    i++
-    if (i === totalServers) {
-      serversRun(apps, urls)
-    }
-  }
-
-  flushTests(function () {
-    for (let j = 1; j <= totalServers; j++) {
-      // For the virtual buffer
-      setTimeout(function () {
-        runServer(j, function (app, url) {
-          anotherServerDone(j, app, url)
-        })
-      }, 1000 * (j - 1))
-    }
-  })
-}
-
-function flushTests (callback) {
-  exec('npm run clean:server:test', callback)
-}
-
-function runServer (number, callback) {
-  const server = {
-    app: null,
-    url: `http://localhost:${9000 + number}`,
-    host: `localhost:${9000 + number}`,
-    client: {
-      id: null,
-      secret: null
-    },
-    user: {
-      username: null,
-      password: null
-    }
-  }
-
-  // These actions are async so we need to be sure that they have both been done
-  const serverRunString = {
-    'Server listening on port': false
-  }
-  const key = 'Database peertube_test' + number + ' is ready'
-  serverRunString[key] = false
-
-  const regexps = {
-    client_id: 'Client id: (.+)',
-    client_secret: 'Client secret: (.+)',
-    user_username: 'Username: (.+)',
-    user_password: 'User password: (.+)'
-  }
-
-  // Share the environment
-  const env = Object.create(process.env)
-  env.NODE_ENV = 'test'
-  env.NODE_APP_INSTANCE = number
-  const options = {
-    silent: true,
-    env: env,
-    detached: true
-  }
-
-  server.app = fork(pathUtils.join(__dirname, '..', '..', '..', 'dist', 'server.js'), [], options)
-  server.app.stdout.on('data', function onStdout (data) {
-    let dontContinue = false
-
-    // Capture things if we want to
-    for (const key of Object.keys(regexps)) {
-      const regexp = regexps[key]
-      const matches = data.toString().match(regexp)
-      if (matches !== null) {
-        if (key === 'client_id') server.client.id = matches[1]
-        else if (key === 'client_secret') server.client.secret = matches[1]
-        else if (key === 'user_username') server.user.username = matches[1]
-        else if (key === 'user_password') server.user.password = matches[1]
-      }
-    }
-
-    // Check if all required sentences are here
-    for (const key of Object.keys(serverRunString)) {
-      if (data.toString().indexOf(key) !== -1) serverRunString[key] = true
-      if (serverRunString[key] === false) dontContinue = true
-    }
-
-    // If no, there is maybe one thing not already initialized (client/user credentials generation...)
-    if (dontContinue === true) return
-
-    server.app.stdout.removeListener('data', onStdout)
-    callback(server)
-  })
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = serversUtils
diff --git a/server/tests/utils/servers.ts b/server/tests/utils/servers.ts
new file mode 100644 (file)
index 0000000..272a893
--- /dev/null
@@ -0,0 +1,153 @@
+import { ChildProcess, exec, fork } from 'child_process'
+import { join } from 'path'
+
+interface ServerInfo {
+  app: ChildProcess,
+  url: string
+  host: string
+
+  client: {
+    id: string,
+    secret: string
+  }
+
+  user: {
+    username: string,
+    password: string,
+    email?: string
+  }
+
+  accessToken?: string
+
+  video?: {
+    id: number
+    uuid: string
+  }
+
+  remoteVideo?: {
+    id: number
+    uuid: string
+  }
+}
+
+async function flushAndRunMultipleServers (totalServers) {
+  let apps = []
+  let i = 0
+
+  return new Promise<ServerInfo[]>(res => {
+    function anotherServerDone (serverNumber, app) {
+      apps[serverNumber - 1] = app
+      i++
+      if (i === totalServers) {
+        return res(apps)
+      }
+    }
+
+    flushTests()
+      .then(() => {
+        for (let j = 1; j <= totalServers; j++) {
+          // For the virtual buffer
+          setTimeout(() => {
+            runServer(j).then(app => anotherServerDone(j, app))
+          }, 1000 * (j - 1))
+        }
+      })
+  })
+}
+
+function flushTests () {
+  return new Promise<void>((res, rej) => {
+    return exec('npm run clean:server:test', err => {
+      if (err) return rej(err)
+
+      return res()
+    })
+  })
+}
+
+function runServer (serverNumber: number) {
+  const server: ServerInfo = {
+    app: null,
+    url: `http://localhost:${9000 + serverNumber}`,
+    host: `localhost:${9000 + serverNumber}`,
+    client: {
+      id: null,
+      secret: null
+    },
+    user: {
+      username: null,
+      password: null
+    }
+  }
+
+  // These actions are async so we need to be sure that they have both been done
+  const serverRunString = {
+    'Server listening on port': false
+  }
+  const key = 'Database peertube_test' + serverNumber + ' is ready'
+  serverRunString[key] = false
+
+  const regexps = {
+    client_id: 'Client id: (.+)',
+    client_secret: 'Client secret: (.+)',
+    user_username: 'Username: (.+)',
+    user_password: 'User password: (.+)'
+  }
+
+  // Share the environment
+  const env = Object.create(process.env)
+  env['NODE_ENV'] = 'test'
+  env['NODE_APP_INSTANCE'] = serverNumber.toString()
+  const options = {
+    silent: true,
+    env: env,
+    detached: true
+  }
+
+  return new Promise<ServerInfo>(res => {
+    server.app = fork(join(__dirname, '..', '..', '..', 'dist', 'server.js'), [], options)
+    server.app.stdout.on('data', function onStdout (data) {
+      let dontContinue = false
+
+      // Capture things if we want to
+      for (const key of Object.keys(regexps)) {
+        const regexp = regexps[key]
+        const matches = data.toString().match(regexp)
+        if (matches !== null) {
+          if (key === 'client_id') server.client.id = matches[1]
+          else if (key === 'client_secret') server.client.secret = matches[1]
+          else if (key === 'user_username') server.user.username = matches[1]
+          else if (key === 'user_password') server.user.password = matches[1]
+        }
+      }
+
+      // Check if all required sentences are here
+      for (const key of Object.keys(serverRunString)) {
+        if (data.toString().indexOf(key) !== -1) serverRunString[key] = true
+        if (serverRunString[key] === false) dontContinue = true
+      }
+
+      // If no, there is maybe one thing not already initialized (client/user credentials generation...)
+      if (dontContinue === true) return
+
+      server.app.stdout.removeListener('data', onStdout)
+      res(server)
+    })
+  })
+}
+
+function killallServers (servers: ServerInfo[]) {
+  for (const server of servers) {
+    process.kill(-server.app.pid)
+  }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  ServerInfo,
+  flushAndRunMultipleServers,
+  flushTests,
+  runServer,
+  killallServers
+}
diff --git a/server/tests/utils/users.js b/server/tests/utils/users.js
deleted file mode 100644 (file)
index 310dc0c..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const usersUtils = {
-  createUser,
-  registerUser,
-  getUserInformation,
-  getUserVideoRating,
-  getUsersList,
-  getUsersListPaginationAndSort,
-  removeUser,
-  updateUser
-}
-
-// ---------------------- Export functions --------------------
-
-function createUser (url, accessToken, username, password, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/users'
-  const body = {
-    username,
-    password,
-    email: username + '@example.com'
-  }
-
-  request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .send(body)
-    .expect(specialStatus)
-    .end(end)
-}
-
-function registerUser (url, username, password, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/users/register'
-  const body = {
-    username,
-    password,
-    email: username + '@example.com'
-  }
-
-  request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-    .send(body)
-    .expect(specialStatus)
-    .end(end)
-}
-
-function getUserInformation (url, accessToken, end) {
-  const path = '/api/v1/users/me'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getUserVideoRating (url, accessToken, videoId, end) {
-  const path = '/api/v1/users/me/videos/' + videoId + '/rating'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getUsersList (url, end) {
-  const path = '/api/v1/users'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getUsersListPaginationAndSort (url, start, count, sort, end) {
-  const path = '/api/v1/users'
-
-  request(url)
-    .get(path)
-    .query({ start: start })
-    .query({ count: count })
-    .query({ sort: sort })
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function removeUser (url, userId, accessToken, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 204
-  }
-
-  const path = '/api/v1/users'
-
-  request(url)
-    .delete(path + '/' + userId)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(expectedStatus)
-    .end(end)
-}
-
-function updateUser (url, userId, accessToken, newPassword, displayNSFW, end) {
-  const path = '/api/v1/users/' + userId
-
-  const toSend = {}
-  if (newPassword !== undefined && newPassword !== null) toSend.password = newPassword
-  if (displayNSFW !== undefined && displayNSFW !== null) toSend.displayNSFW = displayNSFW
-
-  request(url)
-    .put(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .send(toSend)
-    .expect(204)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = usersUtils
diff --git a/server/tests/utils/users.ts b/server/tests/utils/users.ts
new file mode 100644 (file)
index 0000000..6e4b5f2
--- /dev/null
@@ -0,0 +1,115 @@
+import * as request from 'supertest'
+
+function createUser (url: string, accessToken: string, username: string, password: string, specialStatus = 204) {
+  const path = '/api/v1/users'
+  const body = {
+    username,
+    password,
+    email: username + '@example.com'
+  }
+
+  return request(url)
+          .post(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .send(body)
+          .expect(specialStatus)
+}
+
+function registerUser (url: string, username: string, password: string, specialStatus = 204) {
+  const path = '/api/v1/users/register'
+  const body = {
+    username,
+    password,
+    email: username + '@example.com'
+  }
+
+  return request(url)
+          .post(path)
+          .set('Accept', 'application/json')
+          .send(body)
+          .expect(specialStatus)
+}
+
+function getUserInformation (url: string, accessToken: string) {
+  const path = '/api/v1/users/me'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getUserVideoRating (url: string, accessToken: string, videoId: number) {
+  const path = '/api/v1/users/me/videos/' + videoId + '/rating'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getUsersList (url: string) {
+  const path = '/api/v1/users'
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getUsersListPaginationAndSort (url: string, start: number, count: number, sort: string) {
+  const path = '/api/v1/users'
+
+  return request(url)
+          .get(path)
+          .query({ start })
+          .query({ count })
+          .query({ sort })
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function removeUser (url: string, userId: number, accessToken: string, expectedStatus = 204) {
+  const path = '/api/v1/users'
+
+  return request(url)
+          .delete(path + '/' + userId)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(expectedStatus)
+}
+
+function updateUser (url: string, userId: number, accessToken: string, newPassword: string, displayNSFW: boolean) {
+  const path = '/api/v1/users/' + userId
+
+  const toSend = {}
+  if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword
+  if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW
+
+  return request(url)
+          .put(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .send(toSend)
+          .expect(204)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  createUser,
+  registerUser,
+  getUserInformation,
+  getUserVideoRating,
+  getUsersList,
+  getUsersListPaginationAndSort,
+  removeUser,
+  updateUser
+}
diff --git a/server/tests/utils/video-abuses.js b/server/tests/utils/video-abuses.js
deleted file mode 100644 (file)
index c4dd879..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const videosAbuseUtils = {
-  getVideoAbusesList,
-  getVideoAbusesListPagination,
-  getVideoAbusesListSort,
-  reportVideoAbuse
-}
-
-// ---------------------- Export functions --------------------
-
-function reportVideoAbuse (url, token, videoId, reason, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/videos/' + videoId + '/abuse'
-
-  request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .send({ reason })
-    .expect(specialStatus)
-    .end(end)
-}
-
-function getVideoAbusesList (url, token, end) {
-  const path = '/api/v1/videos/abuse'
-
-  request(url)
-    .get(path)
-    .query({ sort: 'createdAt' })
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideoAbusesListPagination (url, token, start, count, end) {
-  const path = '/api/v1/videos/abuse'
-
-  request(url)
-    .get(path)
-    .query({ start: start })
-    .query({ count: count })
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideoAbusesListSort (url, token, sort, end) {
-  const path = '/api/v1/videos/abuse'
-
-  request(url)
-    .get(path)
-    .query({ sort: sort })
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = videosAbuseUtils
diff --git a/server/tests/utils/video-abuses.ts b/server/tests/utils/video-abuses.ts
new file mode 100644 (file)
index 0000000..f7ee958
--- /dev/null
@@ -0,0 +1,58 @@
+import * as request from 'supertest'
+
+function reportVideoAbuse (url: string, token: string, videoId: number, reason: string, specialStatus = 204) {
+  const path = '/api/v1/videos/' + videoId + '/abuse'
+
+  return request(url)
+          .post(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .send({ reason })
+          .expect(specialStatus)
+}
+
+function getVideoAbusesList (url: string, token: string) {
+  const path = '/api/v1/videos/abuse'
+
+  return request(url)
+          .get(path)
+          .query({ sort: 'createdAt' })
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getVideoAbusesListPagination (url: string, token: string, start: number, count: number) {
+  const path = '/api/v1/videos/abuse'
+
+  return request(url)
+          .get(path)
+          .query({ start: start })
+          .query({ count: count })
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getVideoAbusesListSort (url: string, token: string, sort: string) {
+  const path = '/api/v1/videos/abuse'
+
+  return request(url)
+          .get(path)
+          .query({ sort: sort })
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  reportVideoAbuse,
+  getVideoAbusesList,
+  getVideoAbusesListPagination,
+  getVideoAbusesListSort
+}
diff --git a/server/tests/utils/video-blacklists.js b/server/tests/utils/video-blacklists.js
deleted file mode 100644 (file)
index 0a58dd6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict'
-
-const request = require('supertest')
-
-const videosBlacklistsUtils = {
-  addVideoToBlacklist
-}
-
-// ---------------------- Export functions --------------------
-
-function addVideoToBlacklist (url, token, videoId, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/videos/' + videoId + '/blacklist'
-
-  request(url)
-    .post(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .expect(specialStatus)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = videosBlacklistsUtils
diff --git a/server/tests/utils/video-blacklists.ts b/server/tests/utils/video-blacklists.ts
new file mode 100644 (file)
index 0000000..6812d3a
--- /dev/null
@@ -0,0 +1,17 @@
+import * as request from 'supertest'
+
+function addVideoToBlacklist (url: string, token: string, videoId: number, specialStatus = 204) {
+  const path = '/api/v1/videos/' + videoId + '/blacklist'
+
+  return request(url)
+          .post(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .expect(specialStatus)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  addVideoToBlacklist
+}
diff --git a/server/tests/utils/videos.js b/server/tests/utils/videos.js
deleted file mode 100644 (file)
index cb3be68..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-'use strict'
-
-const fs = require('fs')
-const pathUtils = require('path')
-const request = require('supertest')
-
-const videosUtils = {
-  getVideoCategories,
-  getVideoLicences,
-  getVideoLanguages,
-  getAllVideosListBy,
-  getVideo,
-  getVideosList,
-  getVideosListPagination,
-  getVideosListSort,
-  removeVideo,
-  searchVideo,
-  searchVideoWithPagination,
-  searchVideoWithSort,
-  testVideoImage,
-  uploadVideo,
-  updateVideo,
-  rateVideo
-}
-
-// ---------------------- Export functions --------------------
-
-function getVideoCategories (url, end) {
-  const path = '/api/v1/videos/categories'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideoLicences (url, end) {
-  const path = '/api/v1/videos/licences'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideoLanguages (url, end) {
-  const path = '/api/v1/videos/languages'
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getAllVideosListBy (url, end) {
-  const path = '/api/v1/videos'
-
-  request(url)
-    .get(path)
-    .query({ sort: 'createdAt' })
-    .query({ start: 0 })
-    .query({ count: 10000 })
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideo (url, id, end) {
-  const path = '/api/v1/videos/' + id
-
-  request(url)
-    .get(path)
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideosList (url, end) {
-  const path = '/api/v1/videos'
-
-  request(url)
-    .get(path)
-    .query({ sort: 'name' })
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function getVideosListPagination (url, start, count, sort, end) {
-  if (!end) {
-    end = sort
-    sort = null
-  }
-
-  const path = '/api/v1/videos'
-
-  const req = request(url)
-              .get(path)
-              .query({ start: start })
-              .query({ count: count })
-
-  if (sort) req.query({ sort })
-
-  req.set('Accept', 'application/json')
-     .expect(200)
-     .expect('Content-Type', /json/)
-     .end(end)
-}
-
-function getVideosListSort (url, sort, end) {
-  const path = '/api/v1/videos'
-
-  request(url)
-    .get(path)
-    .query({ sort: sort })
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function removeVideo (url, token, id, expectedStatus, end) {
-  if (!end) {
-    end = expectedStatus
-    expectedStatus = 204
-  }
-
-  const path = '/api/v1/videos'
-
-  request(url)
-    .delete(path + '/' + id)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + token)
-    .expect(expectedStatus)
-    .end(end)
-}
-
-function searchVideo (url, search, field, end) {
-  if (!end) {
-    end = field
-    field = null
-  }
-
-  const path = '/api/v1/videos'
-  const req = request(url)
-              .get(path + '/search/' + search)
-              .set('Accept', 'application/json')
-
-  if (field) req.query({ field: field })
-  req.expect(200)
-     .expect('Content-Type', /json/)
-     .end(end)
-}
-
-function searchVideoWithPagination (url, search, field, start, count, sort, end) {
-  if (!end) {
-    end = sort
-    sort = null
-  }
-
-  const path = '/api/v1/videos'
-
-  const req = request(url)
-              .get(path + '/search/' + search)
-              .query({ start: start })
-              .query({ count: count })
-              .query({ field: field })
-
-  if (sort) req.query({ sort })
-
-  req.set('Accept', 'application/json')
-     .expect(200)
-     .expect('Content-Type', /json/)
-     .end(end)
-}
-
-function searchVideoWithSort (url, search, sort, end) {
-  const path = '/api/v1/videos'
-
-  request(url)
-    .get(path + '/search/' + search)
-    .query({ sort: sort })
-    .set('Accept', 'application/json')
-    .expect(200)
-    .expect('Content-Type', /json/)
-    .end(end)
-}
-
-function testVideoImage (url, imageName, imagePath, callback) {
-  // Don't test images if the node env is not set
-  // Because we need a special ffmpeg version for this test
-  if (process.env.NODE_TEST_IMAGE) {
-    request(url)
-      .get(imagePath)
-      .expect(200)
-      .end(function (err, res) {
-        if (err) return callback(err)
-
-        fs.readFile(pathUtils.join(__dirname, '..', 'api', 'fixtures', imageName + '.jpg'), function (err, data) {
-          if (err) return callback(err)
-
-          callback(null, data.equals(res.body))
-        })
-      })
-  } else {
-    console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.')
-    callback(null, true)
-  }
-}
-
-function uploadVideo (url, accessToken, videoAttributesArg, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/videos'
-
-  // Default attributes
-  let attributes = {
-    name: 'my super video',
-    category: 5,
-    licence: 4,
-    language: 3,
-    nsfw: true,
-    description: 'my super description',
-    tags: [ 'tag' ],
-    fixture: 'video_short.webm'
-  }
-  attributes = Object.assign(attributes, videoAttributesArg)
-
-  const req = request(url)
-              .post(path)
-              .set('Accept', 'application/json')
-              .set('Authorization', 'Bearer ' + accessToken)
-              .field('name', attributes.name)
-              .field('category', attributes.category)
-              .field('licence', attributes.licence)
-              .field('language', attributes.language)
-              .field('nsfw', attributes.nsfw)
-              .field('description', attributes.description)
-
-  for (let i = 0; i < attributes.tags.length; i++) {
-    req.field('tags[' + i + ']', attributes.tags[i])
-  }
-
-  let filepath = ''
-  if (pathUtils.isAbsolute(attributes.fixture)) {
-    filepath = attributes.fixture
-  } else {
-    filepath = pathUtils.join(__dirname, '..', 'api', 'fixtures', attributes.fixture)
-  }
-
-  req.attach('videofile', filepath)
-     .expect(specialStatus)
-     .end(end)
-}
-
-function updateVideo (url, accessToken, id, attributes, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/videos/' + id
-  const body = {}
-
-  if (attributes.name) body.name = attributes.name
-  if (attributes.category) body.category = attributes.category
-  if (attributes.licence) body.licence = attributes.licence
-  if (attributes.language) body.language = attributes.language
-  if (attributes.nsfw) body.nsfw = attributes.nsfw
-  if (attributes.description) body.description = attributes.description
-  if (attributes.tags) body.tags = attributes.tags
-
-  request(url)
-    .put(path)
-    .send(body)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .expect(specialStatus)
-    .end(end)
-}
-
-function rateVideo (url, accessToken, id, rating, specialStatus, end) {
-  if (!end) {
-    end = specialStatus
-    specialStatus = 204
-  }
-
-  const path = '/api/v1/videos/' + id + '/rate'
-
-  request(url)
-    .put(path)
-    .set('Accept', 'application/json')
-    .set('Authorization', 'Bearer ' + accessToken)
-    .send({ rating })
-    .expect(specialStatus)
-    .end(end)
-}
-
-// ---------------------------------------------------------------------------
-
-module.exports = videosUtils
diff --git a/server/tests/utils/videos.ts b/server/tests/utils/videos.ts
new file mode 100644 (file)
index 0000000..42b7dd0
--- /dev/null
@@ -0,0 +1,254 @@
+import * as request from 'supertest'
+import { join, isAbsolute } from 'path'
+
+import { makeGetRequest } from './requests'
+import { readFilePromise } from './miscs'
+
+type VideoAttributes = {
+  name?: string
+  category?: number
+  licence?: number
+  language?: number
+  nsfw?: boolean
+  description?: string
+  tags?: string[]
+  fixture?: string
+}
+
+function getVideoCategories (url: string) {
+  const path = '/api/v1/videos/categories'
+
+  return makeGetRequest(url, path)
+}
+
+function getVideoLicences (url: string) {
+  const path = '/api/v1/videos/licences'
+
+  return makeGetRequest(url, path)
+}
+
+function getVideoLanguages (url: string) {
+  const path = '/api/v1/videos/languages'
+
+  return makeGetRequest(url, path)
+}
+
+function getAllVideosListBy (url: string) {
+  const path = '/api/v1/videos'
+
+  return request(url)
+          .get(path)
+          .query({ sort: 'createdAt' })
+          .query({ start: 0 })
+          .query({ count: 10000 })
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getVideo (url: string, id: number | string) {
+  const path = '/api/v1/videos/' + id
+
+  return request(url)
+          .get(path)
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getVideosList (url: string) {
+  const path = '/api/v1/videos'
+
+  return request(url)
+          .get(path)
+          .query({ sort: 'name' })
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
+  const path = '/api/v1/videos'
+
+  const req = request(url)
+              .get(path)
+              .query({ start: start })
+              .query({ count: count })
+
+  if (sort) req.query({ sort })
+
+  return req.set('Accept', 'application/json')
+           .expect(200)
+           .expect('Content-Type', /json/)
+}
+
+function getVideosListSort (url: string, sort: string) {
+  const path = '/api/v1/videos'
+
+  return request(url)
+          .get(path)
+          .query({ sort: sort })
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+function removeVideo (url: string, token: string, id: number, expectedStatus = 204) {
+  const path = '/api/v1/videos'
+
+  return request(url)
+          .delete(path + '/' + id)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + token)
+          .expect(expectedStatus)
+}
+
+function searchVideo (url: string, search: string, field?: string) {
+  const path = '/api/v1/videos'
+  const req = request(url)
+                .get(path + '/search/' + search)
+                .set('Accept', 'application/json')
+
+  if (field) req.query({ field })
+
+  return req.expect(200)
+            .expect('Content-Type', /json/)
+}
+
+function searchVideoWithPagination (url: string, search: string, field: string, start: number, count: number, sort?: string) {
+  const path = '/api/v1/videos'
+
+  const req = request(url)
+                .get(path + '/search/' + search)
+                .query({ start })
+                .query({ count })
+                .query({ field })
+
+  if (sort) req.query({ sort })
+
+  return req.set('Accept', 'application/json')
+            .expect(200)
+            .expect('Content-Type', /json/)
+}
+
+function searchVideoWithSort (url: string, search: string, sort: string) {
+  const path = '/api/v1/videos'
+
+  return request(url)
+          .get(path + '/search/' + search)
+          .query({ sort })
+          .set('Accept', 'application/json')
+          .expect(200)
+          .expect('Content-Type', /json/)
+}
+
+async function testVideoImage (url: string, imageName: string, imagePath: string) {
+  // Don't test images if the node env is not set
+  // Because we need a special ffmpeg version for this test
+  if (process.env['NODE_TEST_IMAGE']) {
+    const res = await request(url)
+                        .get(imagePath)
+                        .expect(200)
+
+    const data = await readFilePromise(join(__dirname, '..', 'api', 'fixtures', imageName + '.jpg'))
+
+    return data.equals(res.body)
+  } else {
+    console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.')
+    return true
+  }
+}
+
+function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 204) {
+  const path = '/api/v1/videos'
+
+  // Default attributes
+  let attributes = {
+    name: 'my super video',
+    category: 5,
+    licence: 4,
+    language: 3,
+    nsfw: true,
+    description: 'my super description',
+    tags: [ 'tag' ],
+    fixture: 'video_short.webm'
+  }
+  attributes = Object.assign(attributes, videoAttributesArg)
+
+  const req = request(url)
+              .post(path)
+              .set('Accept', 'application/json')
+              .set('Authorization', 'Bearer ' + accessToken)
+              .field('name', attributes.name)
+              .field('category', attributes.category.toString())
+              .field('licence', attributes.licence.toString())
+              .field('language', attributes.language.toString())
+              .field('nsfw', JSON.stringify(attributes.nsfw))
+              .field('description', attributes.description)
+
+  for (let i = 0; i < attributes.tags.length; i++) {
+    req.field('tags[' + i + ']', attributes.tags[i])
+  }
+
+  let filepath = ''
+  if (isAbsolute(attributes.fixture)) {
+    filepath = attributes.fixture
+  } else {
+    filepath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture)
+  }
+
+  return req.attach('videofile', filepath)
+            .expect(specialStatus)
+}
+
+function updateVideo (url: string, accessToken: string, id: number, attributes: VideoAttributes, specialStatus = 204) {
+  const path = '/api/v1/videos/' + id
+  const body = {}
+
+  if (attributes.name) body['name'] = attributes.name
+  if (attributes.category) body['category'] = attributes.category
+  if (attributes.licence) body['licence'] = attributes.licence
+  if (attributes.language) body['language'] = attributes.language
+  if (attributes.nsfw) body['nsfw'] = attributes.nsfw
+  if (attributes.description) body['description'] = attributes.description
+  if (attributes.tags) body['tags'] = attributes.tags
+
+  return request(url)
+          .put(path)
+          .send(body)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .expect(specialStatus)
+}
+
+function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) {
+  const path = '/api/v1/videos/' + id + '/rate'
+
+  return request(url)
+          .put(path)
+          .set('Accept', 'application/json')
+          .set('Authorization', 'Bearer ' + accessToken)
+          .send({ rating })
+          .expect(specialStatus)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getVideoCategories,
+  getVideoLicences,
+  getVideoLanguages,
+  getAllVideosListBy,
+  getVideo,
+  getVideosList,
+  getVideosListPagination,
+  getVideosListSort,
+  removeVideo,
+  searchVideo,
+  searchVideoWithPagination,
+  searchVideoWithSort,
+  testVideoImage,
+  uploadVideo,
+  updateVideo,
+  rateVideo
+}
index 03988123061ca40930f983372bc293b10f6656b5..be910b309a00ed306741804874042e7f466452e0 100644 (file)
@@ -6,6 +6,7 @@
     "sourceMap": false,
     "outDir": "./dist",
     "lib": [
+      "dom",
       "es2015"
     ],
     "types": [
index 1a6af175a21965f75a9839f06af85762f3d042f9..68d86ba0a3f2457622c249cebd1ba3e54fbbfad0 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-1.0.0.tgz#2c523da191db7d41c06d17de235335c985effe9b"
 
+"@types/bittorrent-protocol@*":
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/@types/bittorrent-protocol/-/bittorrent-protocol-2.2.2.tgz#169e9633e1bd18e6b830d11cf42e611b1972cb83"
+  dependencies:
+    "@types/node" "*"
+
 "@types/bluebird@*", "@types/bluebird@^3.4.0":
   version "3.5.8"
   resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.8.tgz#242a83379f06c90f96acf6d1aeab3af6faebdb98"
     "@types/express" "*"
     "@types/node" "*"
 
+"@types/chai@^4.0.4":
+  version "4.0.4"
+  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.4.tgz#fe86315d9a66827feeb16f73bc954688ec950e18"
+
 "@types/commander@^2.9.1":
   version "2.9.2"
   resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.9.2.tgz#421f0cafd94a580991662711ea61fc37a5fcfede"
@@ -58,7 +68,7 @@
   version "4.14.74"
   resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168"
 
-"@types/magnet-uri@^5.1.1":
+"@types/magnet-uri@*", "@types/magnet-uri@^5.1.1":
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/@types/magnet-uri/-/magnet-uri-5.1.1.tgz#861aaf64c92a3137dd848fefc55cd352a8ea851a"
   dependencies:
   dependencies:
     "@types/node" "*"
 
+"@types/mocha@^2.2.42":
+  version "2.2.42"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.42.tgz#ab769f51d37646b6fe8d4a086a98c285b1fab3f5"
+
 "@types/morgan@^1.7.32":
   version "1.7.32"
   resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.7.32.tgz#fab1ece4dae172e1a377d563d33e3634fa04927d"
   version "6.0.88"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.88.tgz#f618f11a944f6a18d92b5c472028728a3e3d4b66"
 
+"@types/parse-torrent-file@*":
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/@types/parse-torrent-file/-/parse-torrent-file-4.0.1.tgz#056a6c18f3fac0cd7c6c74540f00496a3225976b"
+  dependencies:
+    "@types/node" "*"
+
+"@types/parse-torrent@*":
+  version "5.8.1"
+  resolved "https://registry.yarnpkg.com/@types/parse-torrent/-/parse-torrent-5.8.1.tgz#012fe6f50d12ed23d86f10ea831a4f0e1b0aacb6"
+  dependencies:
+    "@types/magnet-uri" "*"
+    "@types/node" "*"
+    "@types/parse-torrent-file" "*"
+
 "@types/request@^2.0.3":
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/@types/request/-/request-2.0.3.tgz#bdf0fba9488c822f77e97de3dd8fe357b2fb8c06"
     "@types/express-serve-static-core" "*"
     "@types/mime" "*"
 
+"@types/simple-peer@*":
+  version "6.1.2"
+  resolved "https://registry.yarnpkg.com/@types/simple-peer/-/simple-peer-6.1.2.tgz#236b57651572b91088536ea438176eb71fd51f6e"
+  dependencies:
+    "@types/node" "*"
+
+"@types/superagent@*":
+  version "3.5.5"
+  resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-3.5.5.tgz#f4378cec9105dce5f74979c8e4a1ff3fe18a5aca"
+  dependencies:
+    "@types/node" "*"
+
+"@types/supertest@^2.0.3":
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.3.tgz#edcae925c427dec6a7abe2697ee4b06fb29664c1"
+  dependencies:
+    "@types/superagent" "*"
+
 "@types/validator@*", "@types/validator@^6.2.0":
   version "6.2.2"
   resolved "https://registry.yarnpkg.com/@types/validator/-/validator-6.2.2.tgz#f10c4433e5d107c95cf895e53ae4d25a53c3fa32"
 
+"@types/webtorrent@^0.98.4":
+  version "0.98.4"
+  resolved "https://registry.yarnpkg.com/@types/webtorrent/-/webtorrent-0.98.4.tgz#cf8dbe22e3d5cf6915305f7f970b52bca01bf8b4"
+  dependencies:
+    "@types/bittorrent-protocol" "*"
+    "@types/node" "*"
+    "@types/parse-torrent" "*"
+    "@types/simple-peer" "*"
+
 "@types/winston@^2.3.2":
   version "2.3.5"
   resolved "https://registry.yarnpkg.com/@types/winston/-/winston-2.3.5.tgz#d8063460a7881e55a9dbfc41fcdfb5063312f3fb"
@@ -3715,7 +3770,7 @@ tryit@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
 
-ts-node@^3.0.6:
+ts-node@^3.3.0:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-3.3.0.tgz#c13c6a3024e30be1180dd53038fc209289d4bf69"
   dependencies: