aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-02-06 12:26:58 +0100
committerChocobozzz <me@florianbigard.com>2019-02-06 12:26:58 +0100
commit73471b1a52f242e86364ffb077ea6cadb3b07ae2 (patch)
tree43dbb7748e281f8d80f15326f489cdea10ec857d /server/tests
parentc22419dd265c0c7185bf4197a1cb286eb3d8ebc0 (diff)
parentf5305c04aae14467d6f957b713c5a902275cbb89 (diff)
downloadPeerTube-73471b1a52f242e86364ffb077ea6cadb3b07ae2.tar.gz
PeerTube-73471b1a52f242e86364ffb077ea6cadb3b07ae2.tar.zst
PeerTube-73471b1a52f242e86364ffb077ea6cadb3b07ae2.zip
Merge branch 'release/v1.2.0'
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/api/activitypub/client.ts6
-rw-r--r--server/tests/api/activitypub/fetch.ts9
-rw-r--r--server/tests/api/activitypub/helpers.ts10
-rw-r--r--server/tests/api/activitypub/refresher.ts19
-rw-r--r--server/tests/api/activitypub/security.ts12
-rw-r--r--server/tests/api/check-params/accounts.ts14
-rw-r--r--server/tests/api/check-params/blocklist.ts8
-rw-r--r--server/tests/api/check-params/config.ts6
-rw-r--r--server/tests/api/check-params/contact-form.ts96
-rw-r--r--server/tests/api/check-params/follows.ts8
-rw-r--r--server/tests/api/check-params/index.ts3
-rw-r--r--server/tests/api/check-params/jobs.ts18
-rw-r--r--server/tests/api/check-params/redundancy.ts2
-rw-r--r--server/tests/api/check-params/search.ts8
-rw-r--r--server/tests/api/check-params/services.ts10
-rw-r--r--server/tests/api/check-params/user-notifications.ts297
-rw-r--r--server/tests/api/check-params/user-subscriptions.ts11
-rw-r--r--server/tests/api/check-params/users.ts31
-rw-r--r--server/tests/api/check-params/video-abuses.ts14
-rw-r--r--server/tests/api/check-params/video-blacklist.ts126
-rw-r--r--server/tests/api/check-params/video-captions.ts4
-rw-r--r--server/tests/api/check-params/video-channels.ts8
-rw-r--r--server/tests/api/check-params/video-comments.ts10
-rw-r--r--server/tests/api/check-params/video-imports.ts10
-rw-r--r--server/tests/api/check-params/videos-filter.ts2
-rw-r--r--server/tests/api/check-params/videos-history.ts72
-rw-r--r--server/tests/api/check-params/videos.ts17
-rw-r--r--server/tests/api/redundancy/redundancy.ts36
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts6
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts4
-rw-r--r--server/tests/api/search/search-videos.ts2
-rw-r--r--server/tests/api/server/config.ts56
-rw-r--r--server/tests/api/server/contact-form.ts86
-rw-r--r--server/tests/api/server/email.ts16
-rw-r--r--server/tests/api/server/follow-constraints.ts20
-rw-r--r--server/tests/api/server/follows.ts27
-rw-r--r--server/tests/api/server/handle-down.ts16
-rw-r--r--server/tests/api/server/index.ts1
-rw-r--r--server/tests/api/server/jobs.ts12
-rw-r--r--server/tests/api/server/no-client.ts4
-rw-r--r--server/tests/api/server/reverse-proxy.ts4
-rw-r--r--server/tests/api/server/stats.ts14
-rw-r--r--server/tests/api/server/tracker.ts4
-rw-r--r--server/tests/api/users/blocklist.ts12
-rw-r--r--server/tests/api/users/index.ts3
-rw-r--r--server/tests/api/users/user-notifications.ts1017
-rw-r--r--server/tests/api/users/user-subscriptions.ts19
-rw-r--r--server/tests/api/users/users-multiple-servers.ts10
-rw-r--r--server/tests/api/users/users-verification.ts13
-rw-r--r--server/tests/api/users/users.ts12
-rw-r--r--server/tests/api/videos/index.ts1
-rw-r--r--server/tests/api/videos/multiple-servers.ts15
-rw-r--r--server/tests/api/videos/services.ts12
-rw-r--r--server/tests/api/videos/single-server.ts2
-rw-r--r--server/tests/api/videos/video-abuse.ts6
-rw-r--r--server/tests/api/videos/video-blacklist-management.ts192
-rw-r--r--server/tests/api/videos/video-blacklist.ts305
-rw-r--r--server/tests/api/videos/video-captions.ts15
-rw-r--r--server/tests/api/videos/video-change-ownership.ts4
-rw-r--r--server/tests/api/videos/video-channels.ts6
-rw-r--r--server/tests/api/videos/video-comments.ts6
-rw-r--r--server/tests/api/videos/video-description.ts6
-rw-r--r--server/tests/api/videos/video-imports.ts6
-rw-r--r--server/tests/api/videos/video-nsfw.ts17
-rw-r--r--server/tests/api/videos/video-privacy.ts12
-rw-r--r--server/tests/api/videos/video-schedule-update.ts4
-rw-r--r--server/tests/api/videos/video-transcoder.ts34
-rw-r--r--server/tests/api/videos/videos-filter.ts2
-rw-r--r--server/tests/api/videos/videos-history.ts87
-rw-r--r--server/tests/api/videos/videos-overview.ts4
-rw-r--r--server/tests/cli/create-import-video-file-job.ts4
-rw-r--r--server/tests/cli/create-transcoding-job.ts4
-rw-r--r--server/tests/cli/index.ts1
-rw-r--r--server/tests/cli/optimize-old-videos.ts4
-rw-r--r--server/tests/cli/peertube.ts2
-rw-r--r--server/tests/cli/reset-password.ts2
-rw-r--r--server/tests/cli/update-host.ts8
-rw-r--r--server/tests/client.ts2
-rw-r--r--server/tests/feeds/feeds.ts6
-rw-r--r--server/tests/fixtures/video_short.avibin0 -> 584656 bytes
-rw-r--r--server/tests/fixtures/video_short.mkvbin0 -> 40642 bytes
-rw-r--r--server/tests/fixtures/video_short_240p.mp4bin0 -> 14082 bytes
-rw-r--r--server/tests/helpers/comment-model.ts25
-rw-r--r--server/tests/helpers/core-utils.ts52
-rw-r--r--server/tests/helpers/index.ts1
-rw-r--r--server/tests/misc-endpoints.ts82
-rw-r--r--server/tests/real-world/populate-database.ts2
-rw-r--r--server/tests/real-world/real-world.ts4
-rw-r--r--server/tests/utils/cli/cli.ts24
-rw-r--r--server/tests/utils/feeds/feeds.ts32
-rw-r--r--server/tests/utils/index.ts19
-rw-r--r--server/tests/utils/miscs/email.ts25
-rw-r--r--server/tests/utils/miscs/miscs.ts101
-rw-r--r--server/tests/utils/miscs/sql.ts38
-rw-r--r--server/tests/utils/miscs/stubs.ts14
-rw-r--r--server/tests/utils/overviews/overviews.ts18
-rw-r--r--server/tests/utils/requests/activitypub.ts43
-rw-r--r--server/tests/utils/requests/check-api-params.ts40
-rw-r--r--server/tests/utils/requests/requests.ts168
-rw-r--r--server/tests/utils/search/video-channels.ts22
-rw-r--r--server/tests/utils/search/videos.ts77
-rw-r--r--server/tests/utils/server/activitypub.ts14
-rw-r--r--server/tests/utils/server/clients.ts19
-rw-r--r--server/tests/utils/server/config.ts135
-rw-r--r--server/tests/utils/server/follows.ts79
-rw-r--r--server/tests/utils/server/jobs.ts78
-rw-r--r--server/tests/utils/server/redundancy.ts17
-rw-r--r--server/tests/utils/server/servers.ts185
-rw-r--r--server/tests/utils/server/stats.ts22
-rw-r--r--server/tests/utils/users/accounts.ts63
-rw-r--r--server/tests/utils/users/blocklist.ts197
-rw-r--r--server/tests/utils/users/login.ts62
-rw-r--r--server/tests/utils/users/user-subscriptions.ts82
-rw-r--r--server/tests/utils/users/users.ts298
-rw-r--r--server/tests/utils/videos/services.ts23
-rw-r--r--server/tests/utils/videos/video-abuses.ts65
-rw-r--r--server/tests/utils/videos/video-blacklist.ts67
-rw-r--r--server/tests/utils/videos/video-captions.ts71
-rw-r--r--server/tests/utils/videos/video-change-ownership.ts54
-rw-r--r--server/tests/utils/videos/video-channels.ts118
-rw-r--r--server/tests/utils/videos/video-comments.ts87
-rw-r--r--server/tests/utils/videos/video-history.ts14
-rw-r--r--server/tests/utils/videos/video-imports.ts51
-rw-r--r--server/tests/utils/videos/videos.ts576
124 files changed, 2626 insertions, 3532 deletions
diff --git a/server/tests/api/activitypub/client.ts b/server/tests/api/activitypub/client.ts
index ea0682634..6d90d8643 100644
--- a/server/tests/api/activitypub/client.ts
+++ b/server/tests/api/activitypub/client.ts
@@ -8,10 +8,10 @@ import {
8 flushTests, 8 flushTests,
9 killallServers, 9 killallServers,
10 makeActivityPubGetRequest, 10 makeActivityPubGetRequest,
11 runServer,
12 ServerInfo, 11 ServerInfo,
13 setAccessTokensToServers, uploadVideo 12 setAccessTokensToServers,
14} from '../../utils' 13 uploadVideo
14} from '../../../../shared/utils'
15 15
16const expect = chai.expect 16const expect = chai.expect
17 17
diff --git a/server/tests/api/activitypub/fetch.ts b/server/tests/api/activitypub/fetch.ts
index a42c606c6..03609c1a9 100644
--- a/server/tests/api/activitypub/fetch.ts
+++ b/server/tests/api/activitypub/fetch.ts
@@ -11,12 +11,13 @@ import {
11 killallServers, 11 killallServers,
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 setActorField,
15 setVideoField,
14 uploadVideo, 16 uploadVideo,
15 userLogin 17 userLogin,
16} from '../../utils' 18 waitJobs
19} from '../../../../shared/utils'
17import * as chai from 'chai' 20import * as chai from 'chai'
18import { setActorField, setVideoField } from '../../utils/miscs/sql'
19import { waitJobs } from '../../utils/server/jobs'
20import { Video } from '../../../../shared/models/videos' 21import { Video } from '../../../../shared/models/videos'
21 22
22const expect = chai.expect 23const expect = chai.expect
diff --git a/server/tests/api/activitypub/helpers.ts b/server/tests/api/activitypub/helpers.ts
index 610846247..ac6e755c3 100644
--- a/server/tests/api/activitypub/helpers.ts
+++ b/server/tests/api/activitypub/helpers.ts
@@ -2,7 +2,7 @@
2 2
3import 'mocha' 3import 'mocha'
4import { expect } from 'chai' 4import { expect } from 'chai'
5import { buildRequestStub } from '../../utils' 5import { buildRequestStub } from '../../../../shared/utils/miscs/stubs'
6import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto' 6import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto'
7import { cloneDeep } from 'lodash' 7import { cloneDeep } from 'lodash'
8import { buildSignedActivity } from '../../../helpers/activitypub' 8import { buildSignedActivity } from '../../../helpers/activitypub'
@@ -91,7 +91,7 @@ describe('Test activity pub helpers', function () {
91 req.headers = mastodonObject.headers 91 req.headers = mastodonObject.headers
92 req.headers.signature = 'Signature ' + req.headers.signature 92 req.headers.signature = 'Signature ' + req.headers.signature
93 93
94 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 94 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
95 const publicKey = require('./json/mastodon/public-key.json').publicKey 95 const publicKey = require('./json/mastodon/public-key.json').publicKey
96 96
97 const actor = { publicKey } 97 const actor = { publicKey }
@@ -110,7 +110,7 @@ describe('Test activity pub helpers', function () {
110 req.headers = mastodonObject.headers 110 req.headers = mastodonObject.headers
111 req.headers.signature = 'Signature ' + req.headers.signature 111 req.headers.signature = 'Signature ' + req.headers.signature
112 112
113 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 113 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
114 const publicKey = require('./json/mastodon/bad-public-key.json').publicKey 114 const publicKey = require('./json/mastodon/bad-public-key.json').publicKey
115 115
116 const actor = { publicKey } 116 const actor = { publicKey }
@@ -150,7 +150,7 @@ describe('Test activity pub helpers', function () {
150 150
151 let errored = false 151 let errored = false
152 try { 152 try {
153 parseHTTPSignature(req, 3600 * 365 * 3) 153 parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
154 } catch { 154 } catch {
155 errored = true 155 errored = true
156 } 156 }
@@ -168,7 +168,7 @@ describe('Test activity pub helpers', function () {
168 req.headers = mastodonObject.headers 168 req.headers = mastodonObject.headers
169 req.headers.signature = 'Signature ' + req.headers.signature 169 req.headers.signature = 'Signature ' + req.headers.signature
170 170
171 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 171 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
172 const publicKey = require('./json/mastodon/public-key.json').publicKey 172 const publicKey = require('./json/mastodon/public-key.json').publicKey
173 173
174 const actor = { publicKey } 174 const actor = { publicKey }
diff --git a/server/tests/api/activitypub/refresher.ts b/server/tests/api/activitypub/refresher.ts
index 67e04f79e..62ad8a0b5 100644
--- a/server/tests/api/activitypub/refresher.ts
+++ b/server/tests/api/activitypub/refresher.ts
@@ -1,10 +1,19 @@
1/* tslint:disable:no-unused-expression */ 1/* tslint:disable:no-unused-expression */
2 2
3import 'mocha' 3import 'mocha'
4import { doubleFollow, getVideo, reRunServer } from '../../utils' 4import {
5import { flushAndRunMultipleServers, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo, wait } from '../../utils/index' 5 doubleFollow,
6import { waitJobs } from '../../utils/server/jobs' 6 flushAndRunMultipleServers,
7import { setVideoField } from '../../utils/miscs/sql' 7 getVideo,
8 killallServers,
9 reRunServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo,
13 wait,
14 setVideoField,
15 waitJobs
16} from '../../../../shared/utils'
8 17
9describe('Test AP refresher', function () { 18describe('Test AP refresher', function () {
10 let servers: ServerInfo[] = [] 19 let servers: ServerInfo[] = []
@@ -13,7 +22,7 @@ describe('Test AP refresher', function () {
13 let videoUUID3: string 22 let videoUUID3: string
14 23
15 before(async function () { 24 before(async function () {
16 this.timeout(30000) 25 this.timeout(60000)
17 26
18 servers = await flushAndRunMultipleServers(2) 27 servers = await flushAndRunMultipleServers(2)
19 28
diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts
index 7349749f1..342ae0fa1 100644
--- a/server/tests/api/activitypub/security.ts
+++ b/server/tests/api/activitypub/security.ts
@@ -2,13 +2,19 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushAndRunMultipleServers, flushTests, killallServers, ServerInfo } from '../../utils' 5import {
6 flushAndRunMultipleServers,
7 flushTests,
8 killallServers,
9 makeFollowRequest,
10 makePOSTAPRequest,
11 ServerInfo,
12 setActorField
13} from '../../../../shared/utils'
6import { HTTP_SIGNATURE } from '../../../initializers' 14import { HTTP_SIGNATURE } from '../../../initializers'
7import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' 15import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
8import * as chai from 'chai' 16import * as chai from 'chai'
9import { setActorField } from '../../utils/miscs/sql'
10import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' 17import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
11import { makeFollowRequest, makePOSTAPRequest } from '../../utils/requests/activitypub'
12 18
13const expect = chai.expect 19const expect = chai.expect
14 20
diff --git a/server/tests/api/check-params/accounts.ts b/server/tests/api/check-params/accounts.ts
index 9e0b1e35c..68f9519c6 100644
--- a/server/tests/api/check-params/accounts.ts
+++ b/server/tests/api/check-params/accounts.ts
@@ -2,11 +2,15 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, killallServers, runServer, ServerInfo } from '../../utils' 5import { flushTests, killallServers, runServer, ServerInfo } from '../../../../shared/utils'
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6import {
7import { getAccount } from '../../utils/users/accounts' 7 checkBadCountPagination,
8 8 checkBadSortPagination,
9describe('Test users API validators', function () { 9 checkBadStartPagination
10} from '../../../../shared/utils/requests/check-api-params'
11import { getAccount } from '../../../../shared/utils/users/accounts'
12
13describe('Test accounts API validators', function () {
10 const path = '/api/v1/accounts/' 14 const path = '/api/v1/accounts/'
11 let server: ServerInfo 15 let server: ServerInfo
12 16
diff --git a/server/tests/api/check-params/blocklist.ts b/server/tests/api/check-params/blocklist.ts
index c745ac975..c20453c16 100644
--- a/server/tests/api/check-params/blocklist.ts
+++ b/server/tests/api/check-params/blocklist.ts
@@ -13,8 +13,12 @@ import {
13 makePostBodyRequest, 13 makePostBodyRequest,
14 ServerInfo, 14 ServerInfo,
15 setAccessTokensToServers, userLogin 15 setAccessTokensToServers, userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 17import {
18 checkBadCountPagination,
19 checkBadSortPagination,
20 checkBadStartPagination
21} from '../../../../shared/utils/requests/check-api-params'
18 22
19describe('Test blocklist API validators', function () { 23describe('Test blocklist API validators', function () {
20 let servers: ServerInfo[] 24 let servers: ServerInfo[]
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index d807f910b..4038ecbf0 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -7,7 +7,7 @@ import { CustomConfig } from '../../../../shared/models/server/custom-config.mod
7import { 7import {
8 createUser, flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePutBodyRequest, runServer, ServerInfo, 8 createUser, flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePutBodyRequest, runServer, ServerInfo,
9 setAccessTokensToServers, userLogin, immutableAssign 9 setAccessTokensToServers, userLogin, immutableAssign
10} from '../../utils' 10} from '../../../../shared/utils'
11 11
12describe('Test config API validators', function () { 12describe('Test config API validators', function () {
13 const path = '/api/v1/config/custom' 13 const path = '/api/v1/config/custom'
@@ -48,12 +48,16 @@ describe('Test config API validators', function () {
48 admin: { 48 admin: {
49 email: 'superadmin1@example.com' 49 email: 'superadmin1@example.com'
50 }, 50 },
51 contactForm: {
52 enabled: false
53 },
51 user: { 54 user: {
52 videoQuota: 5242881, 55 videoQuota: 5242881,
53 videoQuotaDaily: 318742 56 videoQuotaDaily: 318742
54 }, 57 },
55 transcoding: { 58 transcoding: {
56 enabled: true, 59 enabled: true,
60 allowAdditionalExtensions: true,
57 threads: 1, 61 threads: 1,
58 resolutions: { 62 resolutions: {
59 '240p': false, 63 '240p': false,
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts
new file mode 100644
index 000000000..c7e014b1f
--- /dev/null
+++ b/server/tests/api/check-params/contact-form.ts
@@ -0,0 +1,96 @@
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4
5import {
6 flushTests,
7 immutableAssign,
8 killallServers,
9 reRunServer,
10 runServer,
11 ServerInfo,
12 setAccessTokensToServers
13} from '../../../../shared/utils'
14import {
15 checkBadCountPagination,
16 checkBadSortPagination,
17 checkBadStartPagination
18} from '../../../../shared/utils/requests/check-api-params'
19import { getAccount } from '../../../../shared/utils/users/accounts'
20import { sendContactForm } from '../../../../shared/utils/server/contact-form'
21import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
22
23describe('Test contact form API validators', function () {
24 let server: ServerInfo
25 const emails: object[] = []
26 const defaultBody = {
27 fromName: 'super name',
28 fromEmail: 'toto@example.com',
29 body: 'Hello, how are you?'
30 }
31
32 // ---------------------------------------------------------------
33
34 before(async function () {
35 this.timeout(60000)
36
37 await flushTests()
38 await MockSmtpServer.Instance.collectEmails(emails)
39
40 // Email is disabled
41 server = await runServer(1)
42 })
43
44 it('Should not accept a contact form if emails are disabled', async function () {
45 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
46 })
47
48 it('Should not accept a contact form if it is disabled in the configuration', async function () {
49 this.timeout(10000)
50
51 killallServers([ server ])
52
53 // Contact form is disabled
54 await reRunServer(server, { smtp: { hostname: 'localhost' }, contact_form: { enabled: false } })
55 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
56 })
57
58 it('Should not accept a contact form if from email is invalid', async function () {
59 this.timeout(10000)
60
61 killallServers([ server ])
62
63 // Email & contact form enabled
64 await reRunServer(server, { smtp: { hostname: 'localhost' } })
65
66 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail' }))
67 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail@' }))
68 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: undefined }))
69 })
70
71 it('Should not accept a contact form if from name is invalid', async function () {
72 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: 'name'.repeat(100) }))
73 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: '' }))
74 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: undefined }))
75 })
76
77 it('Should not accept a contact form if body is invalid', async function () {
78 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'body'.repeat(5000) }))
79 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'a' }))
80 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: undefined }))
81 })
82
83 it('Should accept a contact form with the correct parameters', async function () {
84 await sendContactForm(immutableAssign(defaultBody, { url: server.url }))
85 })
86
87 after(async function () {
88 MockSmtpServer.Instance.kill()
89 killallServers([ server ])
90
91 // Keep the logs if the test failed
92 if (this['ok']) {
93 await flushTests()
94 }
95 })
96})
diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts
index cdc95c81a..2ad1575a3 100644
--- a/server/tests/api/check-params/follows.ts
+++ b/server/tests/api/check-params/follows.ts
@@ -5,8 +5,12 @@ import 'mocha'
5import { 5import {
6 createUser, flushTests, killallServers, makeDeleteRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers, 6 createUser, flushTests, killallServers, makeDeleteRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
7 userLogin 7 userLogin
8} from '../../utils' 8} from '../../../../shared/utils'
9import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 9import {
10 checkBadCountPagination,
11 checkBadSortPagination,
12 checkBadStartPagination
13} from '../../../../shared/utils/requests/check-api-params'
10 14
11describe('Test server follows API validators', function () { 15describe('Test server follows API validators', function () {
12 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
index 877ceb0a7..77c17036a 100644
--- a/server/tests/api/check-params/index.ts
+++ b/server/tests/api/check-params/index.ts
@@ -1,12 +1,13 @@
1// Order of the tests we want to execute
2import './accounts' 1import './accounts'
3import './blocklist' 2import './blocklist'
4import './config' 3import './config'
4import './contact-form'
5import './follows' 5import './follows'
6import './jobs' 6import './jobs'
7import './redundancy' 7import './redundancy'
8import './search' 8import './search'
9import './services' 9import './services'
10import './user-notifications'
10import './user-subscriptions' 11import './user-subscriptions'
11import './users' 12import './users'
12import './video-abuses' 13import './video-abuses'
diff --git a/server/tests/api/check-params/jobs.ts b/server/tests/api/check-params/jobs.ts
index ce3ac8809..89760ff98 100644
--- a/server/tests/api/check-params/jobs.ts
+++ b/server/tests/api/check-params/jobs.ts
@@ -2,9 +2,21 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { createUser, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, userLogin } from '../../utils' 5import {
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6 createUser,
7import { makeGetRequest } from '../../utils/requests/requests' 7 flushTests,
8 killallServers,
9 runServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 userLogin
13} from '../../../../shared/utils'
14import {
15 checkBadCountPagination,
16 checkBadSortPagination,
17 checkBadStartPagination
18} from '../../../../shared/utils/requests/check-api-params'
19import { makeGetRequest } from '../../../../shared/utils/requests/requests'
8 20
9describe('Test jobs API validators', function () { 21describe('Test jobs API validators', function () {
10 const path = '/api/v1/jobs/failed' 22 const path = '/api/v1/jobs/failed'
diff --git a/server/tests/api/check-params/redundancy.ts b/server/tests/api/check-params/redundancy.ts
index aa588e3dd..ff4726ceb 100644
--- a/server/tests/api/check-params/redundancy.ts
+++ b/server/tests/api/check-params/redundancy.ts
@@ -12,7 +12,7 @@ import {
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 userLogin 14 userLogin
15} from '../../utils' 15} from '../../../../shared/utils'
16 16
17describe('Test server redundancy API validators', function () { 17describe('Test server redundancy API validators', function () {
18 let servers: ServerInfo[] 18 let servers: ServerInfo[]
diff --git a/server/tests/api/check-params/search.ts b/server/tests/api/check-params/search.ts
index eabf602ac..aa81965f3 100644
--- a/server/tests/api/check-params/search.ts
+++ b/server/tests/api/check-params/search.ts
@@ -2,8 +2,12 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../utils' 5import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../../../shared/utils'
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6import {
7 checkBadCountPagination,
8 checkBadSortPagination,
9 checkBadStartPagination
10} from '../../../../shared/utils/requests/check-api-params'
7 11
8describe('Test videos API validator', function () { 12describe('Test videos API validator', function () {
9 let server: ServerInfo 13 let server: ServerInfo
diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts
index fcde7e179..28591af9d 100644
--- a/server/tests/api/check-params/services.ts
+++ b/server/tests/api/check-params/services.ts
@@ -2,7 +2,15 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils' 5import {
6 flushTests,
7 killallServers,
8 makeGetRequest,
9 runServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo
13} from '../../../../shared/utils'
6 14
7describe('Test services API validators', function () { 15describe('Test services API validators', function () {
8 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/api/check-params/user-notifications.ts b/server/tests/api/check-params/user-notifications.ts
new file mode 100644
index 000000000..714f481e9
--- /dev/null
+++ b/server/tests/api/check-params/user-notifications.ts
@@ -0,0 +1,297 @@
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4import * as io from 'socket.io-client'
5
6import {
7 flushTests,
8 immutableAssign,
9 killallServers,
10 makeGetRequest,
11 makePostBodyRequest,
12 makePutBodyRequest,
13 runServer,
14 ServerInfo,
15 setAccessTokensToServers,
16 wait
17} from '../../../../shared/utils'
18import {
19 checkBadCountPagination,
20 checkBadSortPagination,
21 checkBadStartPagination
22} from '../../../../shared/utils/requests/check-api-params'
23import { UserNotificationSetting, UserNotificationSettingValue } from '../../../../shared/models/users'
24
25describe('Test user notifications API validators', function () {
26 let server: ServerInfo
27
28 // ---------------------------------------------------------------
29
30 before(async function () {
31 this.timeout(30000)
32
33 await flushTests()
34
35 server = await runServer(1)
36
37 await setAccessTokensToServers([ server ])
38 })
39
40 describe('When listing my notifications', function () {
41 const path = '/api/v1/users/me/notifications'
42
43 it('Should fail with a bad start pagination', async function () {
44 await checkBadStartPagination(server.url, path, server.accessToken)
45 })
46
47 it('Should fail with a bad count pagination', async function () {
48 await checkBadCountPagination(server.url, path, server.accessToken)
49 })
50
51 it('Should fail with an incorrect sort', async function () {
52 await checkBadSortPagination(server.url, path, server.accessToken)
53 })
54
55 it('Should fail with an incorrect unread parameter', async function () {
56 await makeGetRequest({
57 url: server.url,
58 path,
59 query: {
60 unread: 'toto'
61 },
62 token: server.accessToken,
63 statusCodeExpected: 200
64 })
65 })
66
67 it('Should fail with a non authenticated user', async function () {
68 await makeGetRequest({
69 url: server.url,
70 path,
71 statusCodeExpected: 401
72 })
73 })
74
75 it('Should succeed with the correct parameters', async function () {
76 await makeGetRequest({
77 url: server.url,
78 path,
79 token: server.accessToken,
80 statusCodeExpected: 200
81 })
82 })
83 })
84
85 describe('When marking as read my notifications', function () {
86 const path = '/api/v1/users/me/notifications/read'
87
88 it('Should fail with wrong ids parameters', async function () {
89 await makePostBodyRequest({
90 url: server.url,
91 path,
92 fields: {
93 ids: [ 'hello' ]
94 },
95 token: server.accessToken,
96 statusCodeExpected: 400
97 })
98
99 await makePostBodyRequest({
100 url: server.url,
101 path,
102 fields: {
103 ids: [ ]
104 },
105 token: server.accessToken,
106 statusCodeExpected: 400
107 })
108
109 await makePostBodyRequest({
110 url: server.url,
111 path,
112 fields: {
113 ids: 5
114 },
115 token: server.accessToken,
116 statusCodeExpected: 400
117 })
118 })
119
120 it('Should fail with a non authenticated user', async function () {
121 await makePostBodyRequest({
122 url: server.url,
123 path,
124 fields: {
125 ids: [ 5 ]
126 },
127 statusCodeExpected: 401
128 })
129 })
130
131 it('Should succeed with the correct parameters', async function () {
132 await makePostBodyRequest({
133 url: server.url,
134 path,
135 fields: {
136 ids: [ 5 ]
137 },
138 token: server.accessToken,
139 statusCodeExpected: 204
140 })
141 })
142 })
143
144 describe('When marking as read my notifications', function () {
145 const path = '/api/v1/users/me/notifications/read-all'
146
147 it('Should fail with a non authenticated user', async function () {
148 await makePostBodyRequest({
149 url: server.url,
150 path,
151 statusCodeExpected: 401
152 })
153 })
154
155 it('Should succeed with the correct parameters', async function () {
156 await makePostBodyRequest({
157 url: server.url,
158 path,
159 token: server.accessToken,
160 statusCodeExpected: 204
161 })
162 })
163 })
164
165 describe('When updating my notification settings', function () {
166 const path = '/api/v1/users/me/notification-settings'
167 const correctFields: UserNotificationSetting = {
168 newVideoFromSubscription: UserNotificationSettingValue.WEB,
169 newCommentOnMyVideo: UserNotificationSettingValue.WEB,
170 videoAbuseAsModerator: UserNotificationSettingValue.WEB,
171 blacklistOnMyVideo: UserNotificationSettingValue.WEB,
172 myVideoImportFinished: UserNotificationSettingValue.WEB,
173 myVideoPublished: UserNotificationSettingValue.WEB,
174 commentMention: UserNotificationSettingValue.WEB,
175 newFollow: UserNotificationSettingValue.WEB,
176 newUserRegistration: UserNotificationSettingValue.WEB
177 }
178
179 it('Should fail with missing fields', async function () {
180 await makePutBodyRequest({
181 url: server.url,
182 path,
183 token: server.accessToken,
184 fields: { newVideoFromSubscription: UserNotificationSettingValue.WEB },
185 statusCodeExpected: 400
186 })
187 })
188
189 it('Should fail with incorrect field values', async function () {
190 {
191 const fields = immutableAssign(correctFields, { newCommentOnMyVideo: 15 })
192
193 await makePutBodyRequest({
194 url: server.url,
195 path,
196 token: server.accessToken,
197 fields,
198 statusCodeExpected: 400
199 })
200 }
201
202 {
203 const fields = immutableAssign(correctFields, { newCommentOnMyVideo: 'toto' })
204
205 await makePutBodyRequest({
206 url: server.url,
207 path,
208 fields,
209 token: server.accessToken,
210 statusCodeExpected: 400
211 })
212 }
213 })
214
215 it('Should fail with a non authenticated user', async function () {
216 await makePutBodyRequest({
217 url: server.url,
218 path,
219 fields: correctFields,
220 statusCodeExpected: 401
221 })
222 })
223
224 it('Should succeed with the correct parameters', async function () {
225 await makePutBodyRequest({
226 url: server.url,
227 path,
228 token: server.accessToken,
229 fields: correctFields,
230 statusCodeExpected: 204
231 })
232 })
233 })
234
235 describe('When connecting to my notification socket', function () {
236 it('Should fail with no token', function (next) {
237 const socket = io('http://localhost:9001/user-notifications', { reconnection: false })
238
239 socket.on('error', () => {
240 socket.removeListener('error', this)
241 socket.disconnect()
242 next()
243 })
244
245 socket.on('connect', () => {
246 socket.disconnect()
247 next(new Error('Connected with a missing token.'))
248 })
249 })
250
251 it('Should fail with an invalid token', function (next) {
252 const socket = io('http://localhost:9001/user-notifications', {
253 query: { accessToken: 'bad_access_token' },
254 reconnection: false
255 })
256
257 socket.on('error', () => {
258 socket.removeListener('error', this)
259 socket.disconnect()
260 next()
261 })
262
263 socket.on('connect', () => {
264 socket.disconnect()
265 next(new Error('Connected with an invalid token.'))
266 })
267 })
268
269 it('Should success with the correct token', function (next) {
270 const socket = io('http://localhost:9001/user-notifications', {
271 query: { accessToken: server.accessToken },
272 reconnection: false
273 })
274
275 const errorListener = socket.on('error', err => {
276 next(new Error('Error in connection: ' + err))
277 })
278
279 socket.on('connect', async () => {
280 socket.removeListener('error', errorListener)
281 socket.disconnect()
282
283 await wait(500)
284 next()
285 })
286 })
287 })
288
289 after(async function () {
290 killallServers([ server ])
291
292 // Keep the logs if the test failed
293 if (this['ok']) {
294 await flushTests()
295 }
296 })
297})
diff --git a/server/tests/api/check-params/user-subscriptions.ts b/server/tests/api/check-params/user-subscriptions.ts
index 6af7ed43b..8a9ced7c1 100644
--- a/server/tests/api/check-params/user-subscriptions.ts
+++ b/server/tests/api/check-params/user-subscriptions.ts
@@ -13,9 +13,14 @@ import {
13 ServerInfo, 13 ServerInfo,
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 17
18import { waitJobs } from '../../utils/server/jobs' 18import {
19 checkBadCountPagination,
20 checkBadSortPagination,
21 checkBadStartPagination
22} from '../../../../shared/utils/requests/check-api-params'
23import { waitJobs } from '../../../../shared/utils/server/jobs'
19 24
20describe('Test user subscriptions API validators', function () { 25describe('Test user subscriptions API validators', function () {
21 const path = '/api/v1/users/me/subscriptions' 26 const path = '/api/v1/users/me/subscriptions'
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index 273be1679..a3e8e2e9c 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -9,11 +9,15 @@ import {
9 createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest, 9 createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
10 makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers, 10 makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
11 updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser 11 updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser
12} from '../../utils' 12} from '../../../../shared/utils'
13import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 13import {
14import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports' 14 checkBadCountPagination,
15 checkBadSortPagination,
16 checkBadStartPagination
17} from '../../../../shared/utils/requests/check-api-params'
18import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
15import { VideoPrivacy } from '../../../../shared/models/videos' 19import { VideoPrivacy } from '../../../../shared/models/videos'
16import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
17import { expect } from 'chai' 21import { expect } from 'chai'
18 22
19describe('Test users API validators', function () { 23describe('Test users API validators', function () {
@@ -99,13 +103,13 @@ describe('Test users API validators', function () {
99 } 103 }
100 104
101 it('Should fail with a too small username', async function () { 105 it('Should fail with a too small username', async function () {
102 const fields = immutableAssign(baseCorrectParams, { username: 'fi' }) 106 const fields = immutableAssign(baseCorrectParams, { username: '' })
103 107
104 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 108 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
105 }) 109 })
106 110
107 it('Should fail with a too long username', async function () { 111 it('Should fail with a too long username', async function () {
108 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' }) 112 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
109 113
110 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 114 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
111 }) 115 })
@@ -304,6 +308,14 @@ describe('Test users API validators', function () {
304 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) 308 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
305 }) 309 })
306 310
311 it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
312 const fields = {
313 videosHistoryEnabled: -1
314 }
315
316 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
317 })
318
307 it('Should fail with an non authenticated user', async function () { 319 it('Should fail with an non authenticated user', async function () {
308 const fields = { 320 const fields = {
309 currentPassword: 'my super password', 321 currentPassword: 'my super password',
@@ -473,11 +485,10 @@ describe('Test users API validators', function () {
473 email: 'email@example.com', 485 email: 'email@example.com',
474 emailVerified: true, 486 emailVerified: true,
475 videoQuota: 42, 487 videoQuota: 42,
476 role: UserRole.MODERATOR 488 role: UserRole.USER
477 } 489 }
478 490
479 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 }) 491 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
480 userAccessToken = await userLogin(server, user)
481 }) 492 })
482 }) 493 })
483 494
@@ -550,13 +561,13 @@ describe('Test users API validators', function () {
550 } 561 }
551 562
552 it('Should fail with a too small username', async function () { 563 it('Should fail with a too small username', async function () {
553 const fields = immutableAssign(baseCorrectParams, { username: 'ji' }) 564 const fields = immutableAssign(baseCorrectParams, { username: '' })
554 565
555 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields }) 566 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
556 }) 567 })
557 568
558 it('Should fail with a too long username', async function () { 569 it('Should fail with a too long username', async function () {
559 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' }) 570 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
560 571
561 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields }) 572 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
562 }) 573 })
diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts
index d2bed6a2a..3b8f5f14d 100644
--- a/server/tests/api/check-params/video-abuses.ts
+++ b/server/tests/api/check-params/video-abuses.ts
@@ -15,8 +15,12 @@ import {
15 updateVideoAbuse, 15 updateVideoAbuse,
16 uploadVideo, 16 uploadVideo,
17 userLogin 17 userLogin
18} from '../../utils' 18} from '../../../../shared/utils'
19import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 19import {
20 checkBadCountPagination,
21 checkBadSortPagination,
22 checkBadStartPagination
23} from '../../../../shared/utils/requests/check-api-params'
20import { VideoAbuseState } from '../../../../shared/models/videos' 24import { VideoAbuseState } from '../../../../shared/models/videos'
21 25
22describe('Test video abuses API validators', function () { 26describe('Test video abuses API validators', function () {
@@ -109,8 +113,8 @@ describe('Test video abuses API validators', function () {
109 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 113 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
110 }) 114 })
111 115
112 it('Should fail with a reason too big', async function () { 116 it('Should fail with a too big reason', async function () {
113 const fields = { reason: 'super'.repeat(61) } 117 const fields = { reason: 'super'.repeat(605) }
114 118
115 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 119 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
116 }) 120 })
@@ -150,7 +154,7 @@ describe('Test video abuses API validators', function () {
150 }) 154 })
151 155
152 it('Should fail with a bad moderation comment', async function () { 156 it('Should fail with a bad moderation comment', async function () {
153 const body = { moderationComment: 'b'.repeat(305) } 157 const body = { moderationComment: 'b'.repeat(3001) }
154 await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400) 158 await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400)
155 }) 159 })
156 160
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts
index 473216236..6b82643f4 100644
--- a/server/tests/api/check-params/video-blacklist.ts
+++ b/server/tests/api/check-params/video-blacklist.ts
@@ -4,25 +4,33 @@ import 'mocha'
4 4
5import { 5import {
6 createUser, 6 createUser,
7 doubleFollow,
8 flushAndRunMultipleServers,
7 flushTests, 9 flushTests,
8 getBlacklistedVideosList, getVideo, getVideoWithToken, 10 getBlacklistedVideosList,
11 getVideo,
12 getVideoWithToken,
9 killallServers, 13 killallServers,
10 makePostBodyRequest, 14 makePostBodyRequest,
11 makePutBodyRequest, 15 makePutBodyRequest,
12 removeVideoFromBlacklist, 16 removeVideoFromBlacklist,
13 runServer,
14 ServerInfo, 17 ServerInfo,
15 setAccessTokensToServers, 18 setAccessTokensToServers,
16 uploadVideo, 19 uploadVideo,
17 userLogin 20 userLogin, waitJobs
18} from '../../utils' 21} from '../../../../shared/utils'
19import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 22import {
23 checkBadCountPagination,
24 checkBadSortPagination,
25 checkBadStartPagination
26} from '../../../../shared/utils/requests/check-api-params'
20import { VideoDetails } from '../../../../shared/models/videos' 27import { VideoDetails } from '../../../../shared/models/videos'
21import { expect } from 'chai' 28import { expect } from 'chai'
22 29
23describe('Test video blacklist API validators', function () { 30describe('Test video blacklist API validators', function () {
24 let server: ServerInfo 31 let servers: ServerInfo[]
25 let notBlacklistedVideoId: number 32 let notBlacklistedVideoId: number
33 let remoteVideoUUID: string
26 let userAccessToken1 = '' 34 let userAccessToken1 = ''
27 let userAccessToken2 = '' 35 let userAccessToken2 = ''
28 36
@@ -32,75 +40,89 @@ describe('Test video blacklist API validators', function () {
32 this.timeout(120000) 40 this.timeout(120000)
33 41
34 await flushTests() 42 await flushTests()
43 servers = await flushAndRunMultipleServers(2)
35 44
36 server = await runServer(1) 45 await setAccessTokensToServers(servers)
37 46 await doubleFollow(servers[0], servers[1])
38 await setAccessTokensToServers([ server ])
39 47
40 { 48 {
41 const username = 'user1' 49 const username = 'user1'
42 const password = 'my super password' 50 const password = 'my super password'
43 await createUser(server.url, server.accessToken, username, password) 51 await createUser(servers[0].url, servers[0].accessToken, username, password)
44 userAccessToken1 = await userLogin(server, { username, password }) 52 userAccessToken1 = await userLogin(servers[0], { username, password })
45 } 53 }
46 54
47 { 55 {
48 const username = 'user2' 56 const username = 'user2'
49 const password = 'my super password' 57 const password = 'my super password'
50 await createUser(server.url, server.accessToken, username, password) 58 await createUser(servers[0].url, servers[0].accessToken, username, password)
51 userAccessToken2 = await userLogin(server, { username, password }) 59 userAccessToken2 = await userLogin(servers[0], { username, password })
52 } 60 }
53 61
54 { 62 {
55 const res = await uploadVideo(server.url, userAccessToken1, {}) 63 const res = await uploadVideo(servers[0].url, userAccessToken1, {})
56 server.video = res.body.video 64 servers[0].video = res.body.video
57 } 65 }
58 66
59 { 67 {
60 const res = await uploadVideo(server.url, server.accessToken, {}) 68 const res = await uploadVideo(servers[0].url, servers[0].accessToken, {})
61 notBlacklistedVideoId = res.body.video.uuid 69 notBlacklistedVideoId = res.body.video.uuid
62 } 70 }
71
72 {
73 const res = await uploadVideo(servers[1].url, servers[1].accessToken, {})
74 remoteVideoUUID = res.body.video.uuid
75 }
76
77 await waitJobs(servers)
63 }) 78 })
64 79
65 describe('When adding a video in blacklist', function () { 80 describe('When adding a video in blacklist', function () {
66 const basePath = '/api/v1/videos/' 81 const basePath = '/api/v1/videos/'
67 82
68 it('Should fail with nothing', async function () { 83 it('Should fail with nothing', async function () {
69 const path = basePath + server.video + '/blacklist' 84 const path = basePath + servers[0].video + '/blacklist'
70 const fields = {} 85 const fields = {}
71 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 86 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
72 }) 87 })
73 88
74 it('Should fail with a wrong video', async function () { 89 it('Should fail with a wrong video', async function () {
75 const wrongPath = '/api/v1/videos/blabla/blacklist' 90 const wrongPath = '/api/v1/videos/blabla/blacklist'
76 const fields = {} 91 const fields = {}
77 await makePostBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) 92 await makePostBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields })
78 }) 93 })
79 94
80 it('Should fail with a non authenticated user', async function () { 95 it('Should fail with a non authenticated user', async function () {
81 const path = basePath + server.video + '/blacklist' 96 const path = basePath + servers[0].video + '/blacklist'
82 const fields = {} 97 const fields = {}
83 await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) 98 await makePostBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 })
84 }) 99 })
85 100
86 it('Should fail with a non admin user', async function () { 101 it('Should fail with a non admin user', async function () {
87 const path = basePath + server.video + '/blacklist' 102 const path = basePath + servers[0].video + '/blacklist'
88 const fields = {} 103 const fields = {}
89 await makePostBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) 104 await makePostBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 })
90 }) 105 })
91 106
92 it('Should fail with an invalid reason', async function () { 107 it('Should fail with an invalid reason', async function () {
93 const path = basePath + server.video.uuid + '/blacklist' 108 const path = basePath + servers[0].video.uuid + '/blacklist'
94 const fields = { reason: 'a'.repeat(305) } 109 const fields = { reason: 'a'.repeat(305) }
95 110
96 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 111 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
112 })
113
114 it('Should fail to unfederate a remote video', async function () {
115 const path = basePath + remoteVideoUUID + '/blacklist'
116 const fields = { unfederate: true }
117
118 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 409 })
97 }) 119 })
98 120
99 it('Should succeed with the correct params', async function () { 121 it('Should succeed with the correct params', async function () {
100 const path = basePath + server.video.uuid + '/blacklist' 122 const path = basePath + servers[0].video.uuid + '/blacklist'
101 const fields = { } 123 const fields = { }
102 124
103 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) 125 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 })
104 }) 126 })
105 }) 127 })
106 128
@@ -110,61 +132,61 @@ describe('Test video blacklist API validators', function () {
110 it('Should fail with a wrong video', async function () { 132 it('Should fail with a wrong video', async function () {
111 const wrongPath = '/api/v1/videos/blabla/blacklist' 133 const wrongPath = '/api/v1/videos/blabla/blacklist'
112 const fields = {} 134 const fields = {}
113 await makePutBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) 135 await makePutBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields })
114 }) 136 })
115 137
116 it('Should fail with a video not blacklisted', async function () { 138 it('Should fail with a video not blacklisted', async function () {
117 const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist' 139 const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist'
118 const fields = {} 140 const fields = {}
119 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 404 }) 141 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 404 })
120 }) 142 })
121 143
122 it('Should fail with a non authenticated user', async function () { 144 it('Should fail with a non authenticated user', async function () {
123 const path = basePath + server.video + '/blacklist' 145 const path = basePath + servers[0].video + '/blacklist'
124 const fields = {} 146 const fields = {}
125 await makePutBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) 147 await makePutBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 })
126 }) 148 })
127 149
128 it('Should fail with a non admin user', async function () { 150 it('Should fail with a non admin user', async function () {
129 const path = basePath + server.video + '/blacklist' 151 const path = basePath + servers[0].video + '/blacklist'
130 const fields = {} 152 const fields = {}
131 await makePutBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) 153 await makePutBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 })
132 }) 154 })
133 155
134 it('Should fail with an invalid reason', async function () { 156 it('Should fail with an invalid reason', async function () {
135 const path = basePath + server.video.uuid + '/blacklist' 157 const path = basePath + servers[0].video.uuid + '/blacklist'
136 const fields = { reason: 'a'.repeat(305) } 158 const fields = { reason: 'a'.repeat(305) }
137 159
138 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 160 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
139 }) 161 })
140 162
141 it('Should succeed with the correct params', async function () { 163 it('Should succeed with the correct params', async function () {
142 const path = basePath + server.video.uuid + '/blacklist' 164 const path = basePath + servers[0].video.uuid + '/blacklist'
143 const fields = { reason: 'hello' } 165 const fields = { reason: 'hello' }
144 166
145 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) 167 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 })
146 }) 168 })
147 }) 169 })
148 170
149 describe('When getting blacklisted video', function () { 171 describe('When getting blacklisted video', function () {
150 172
151 it('Should fail with a non authenticated user', async function () { 173 it('Should fail with a non authenticated user', async function () {
152 await getVideo(server.url, server.video.uuid, 401) 174 await getVideo(servers[0].url, servers[0].video.uuid, 401)
153 }) 175 })
154 176
155 it('Should fail with another user', async function () { 177 it('Should fail with another user', async function () {
156 await getVideoWithToken(server.url, userAccessToken2, server.video.uuid, 403) 178 await getVideoWithToken(servers[0].url, userAccessToken2, servers[0].video.uuid, 403)
157 }) 179 })
158 180
159 it('Should succeed with the owner authenticated user', async function () { 181 it('Should succeed with the owner authenticated user', async function () {
160 const res = await getVideoWithToken(server.url, userAccessToken1, server.video.uuid, 200) 182 const res = await getVideoWithToken(servers[0].url, userAccessToken1, servers[0].video.uuid, 200)
161 const video: VideoDetails = res.body 183 const video: VideoDetails = res.body
162 184
163 expect(video.blacklisted).to.be.true 185 expect(video.blacklisted).to.be.true
164 }) 186 })
165 187
166 it('Should succeed with an admin', async function () { 188 it('Should succeed with an admin', async function () {
167 const res = await getVideoWithToken(server.url, server.accessToken, server.video.uuid, 200) 189 const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 200)
168 const video: VideoDetails = res.body 190 const video: VideoDetails = res.body
169 191
170 expect(video.blacklisted).to.be.true 192 expect(video.blacklisted).to.be.true
@@ -173,24 +195,24 @@ describe('Test video blacklist API validators', function () {
173 195
174 describe('When removing a video in blacklist', function () { 196 describe('When removing a video in blacklist', function () {
175 it('Should fail with a non authenticated user', async function () { 197 it('Should fail with a non authenticated user', async function () {
176 await removeVideoFromBlacklist(server.url, 'fake token', server.video.uuid, 401) 198 await removeVideoFromBlacklist(servers[0].url, 'fake token', servers[0].video.uuid, 401)
177 }) 199 })
178 200
179 it('Should fail with a non admin user', async function () { 201 it('Should fail with a non admin user', async function () {
180 await removeVideoFromBlacklist(server.url, userAccessToken2, server.video.uuid, 403) 202 await removeVideoFromBlacklist(servers[0].url, userAccessToken2, servers[0].video.uuid, 403)
181 }) 203 })
182 204
183 it('Should fail with an incorrect id', async function () { 205 it('Should fail with an incorrect id', async function () {
184 await removeVideoFromBlacklist(server.url, server.accessToken, 'hello', 400) 206 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, 'hello', 400)
185 }) 207 })
186 208
187 it('Should fail with a not blacklisted video', async function () { 209 it('Should fail with a not blacklisted video', async function () {
188 // The video was not added to the blacklist so it should fail 210 // The video was not added to the blacklist so it should fail
189 await removeVideoFromBlacklist(server.url, server.accessToken, notBlacklistedVideoId, 404) 211 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, notBlacklistedVideoId, 404)
190 }) 212 })
191 213
192 it('Should succeed with the correct params', async function () { 214 it('Should succeed with the correct params', async function () {
193 await removeVideoFromBlacklist(server.url, server.accessToken, server.video.uuid, 204) 215 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 204)
194 }) 216 })
195 }) 217 })
196 218
@@ -198,28 +220,28 @@ describe('Test video blacklist API validators', function () {
198 const basePath = '/api/v1/videos/blacklist/' 220 const basePath = '/api/v1/videos/blacklist/'
199 221
200 it('Should fail with a non authenticated user', async function () { 222 it('Should fail with a non authenticated user', async function () {
201 await getBlacklistedVideosList(server.url, 'fake token', 401) 223 await getBlacklistedVideosList(servers[0].url, 'fake token', 401)
202 }) 224 })
203 225
204 it('Should fail with a non admin user', async function () { 226 it('Should fail with a non admin user', async function () {
205 await getBlacklistedVideosList(server.url, userAccessToken2, 403) 227 await getBlacklistedVideosList(servers[0].url, userAccessToken2, 403)
206 }) 228 })
207 229
208 it('Should fail with a bad start pagination', async function () { 230 it('Should fail with a bad start pagination', async function () {
209 await checkBadStartPagination(server.url, basePath, server.accessToken) 231 await checkBadStartPagination(servers[0].url, basePath, servers[0].accessToken)
210 }) 232 })
211 233
212 it('Should fail with a bad count pagination', async function () { 234 it('Should fail with a bad count pagination', async function () {
213 await checkBadCountPagination(server.url, basePath, server.accessToken) 235 await checkBadCountPagination(servers[0].url, basePath, servers[0].accessToken)
214 }) 236 })
215 237
216 it('Should fail with an incorrect sort', async function () { 238 it('Should fail with an incorrect sort', async function () {
217 await checkBadSortPagination(server.url, basePath, server.accessToken) 239 await checkBadSortPagination(servers[0].url, basePath, servers[0].accessToken)
218 }) 240 })
219 }) 241 })
220 242
221 after(async function () { 243 after(async function () {
222 killallServers([ server ]) 244 killallServers(servers)
223 245
224 // Keep the logs if the test failed 246 // Keep the logs if the test failed
225 if (this['ok']) { 247 if (this['ok']) {
diff --git a/server/tests/api/check-params/video-captions.ts b/server/tests/api/check-params/video-captions.ts
index 8d46971a1..e4d36fd4f 100644
--- a/server/tests/api/check-params/video-captions.ts
+++ b/server/tests/api/check-params/video-captions.ts
@@ -13,9 +13,9 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { join } from 'path' 17import { join } from 'path'
18import { createVideoCaption } from '../../utils/videos/video-captions' 18import { createVideoCaption } from '../../../../shared/utils/videos/video-captions'
19 19
20describe('Test video captions API validator', function () { 20describe('Test video captions API validator', function () {
21 const path = '/api/v1/videos/' 21 const path = '/api/v1/videos/'
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts
index e5696224d..14e4deaf7 100644
--- a/server/tests/api/check-params/video-channels.ts
+++ b/server/tests/api/check-params/video-channels.ts
@@ -20,8 +20,12 @@ import {
20 ServerInfo, 20 ServerInfo,
21 setAccessTokensToServers, 21 setAccessTokensToServers,
22 userLogin 22 userLogin
23} from '../../utils' 23} from '../../../../shared/utils'
24import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 24import {
25 checkBadCountPagination,
26 checkBadSortPagination,
27 checkBadStartPagination
28} from '../../../../shared/utils/requests/check-api-params'
25import { User } from '../../../../shared/models/users' 29import { User } from '../../../../shared/models/users'
26import { join } from 'path' 30import { join } from 'path'
27 31
diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts
index 5241832fe..5981780ed 100644
--- a/server/tests/api/check-params/video-comments.ts
+++ b/server/tests/api/check-params/video-comments.ts
@@ -6,9 +6,13 @@ import {
6 createUser, 6 createUser,
7 flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers, 7 flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
8 uploadVideo, userLogin 8 uploadVideo, userLogin
9} from '../../utils' 9} from '../../../../shared/utils'
10import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 10import {
11import { addVideoCommentThread } from '../../utils/videos/video-comments' 11 checkBadCountPagination,
12 checkBadSortPagination,
13 checkBadStartPagination
14} from '../../../../shared/utils/requests/check-api-params'
15import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
12 16
13const expect = chai.expect 17const expect = chai.expect
14 18
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts
index b51f3d2cd..7bf187007 100644
--- a/server/tests/api/check-params/video-imports.ts
+++ b/server/tests/api/check-params/video-imports.ts
@@ -18,9 +18,13 @@ import {
18 setAccessTokensToServers, 18 setAccessTokensToServers,
19 updateCustomSubConfig, 19 updateCustomSubConfig,
20 userLogin 20 userLogin
21} from '../../utils' 21} from '../../../../shared/utils'
22import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 22import {
23import { getMagnetURI, getYoutubeVideoUrl } from '../../utils/videos/video-imports' 23 checkBadCountPagination,
24 checkBadSortPagination,
25 checkBadStartPagination
26} from '../../../../shared/utils/requests/check-api-params'
27import { getMagnetURI, getYoutubeVideoUrl } from '../../../../shared/utils/videos/video-imports'
24 28
25describe('Test video imports API validator', function () { 29describe('Test video imports API validator', function () {
26 const path = '/api/v1/videos/imports' 30 const path = '/api/v1/videos/imports'
diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts
index 784cd8ba1..e998c8a3d 100644
--- a/server/tests/api/check-params/videos-filter.ts
+++ b/server/tests/api/check-params/videos-filter.ts
@@ -11,7 +11,7 @@ import {
11 ServerInfo, 11 ServerInfo,
12 setAccessTokensToServers, 12 setAccessTokensToServers,
13 userLogin 13 userLogin
14} from '../../utils' 14} from '../../../../shared/utils'
15import { UserRole } from '../../../../shared/models/users' 15import { UserRole } from '../../../../shared/models/users'
16 16
17const expect = chai.expect 17const expect = chai.expect
diff --git a/server/tests/api/check-params/videos-history.ts b/server/tests/api/check-params/videos-history.ts
index 808c3b616..8c079a956 100644
--- a/server/tests/api/check-params/videos-history.ts
+++ b/server/tests/api/check-params/videos-history.ts
@@ -3,20 +3,25 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 checkBadCountPagination,
7 checkBadStartPagination,
6 flushTests, 8 flushTests,
7 killallServers, 9 killallServers,
10 makeGetRequest,
8 makePostBodyRequest, 11 makePostBodyRequest,
9 makePutBodyRequest, 12 makePutBodyRequest,
10 runServer, 13 runServer,
11 ServerInfo, 14 ServerInfo,
12 setAccessTokensToServers, 15 setAccessTokensToServers,
13 uploadVideo 16 uploadVideo
14} from '../../utils' 17} from '../../../../shared/utils'
15 18
16const expect = chai.expect 19const expect = chai.expect
17 20
18describe('Test videos history API validator', function () { 21describe('Test videos history API validator', function () {
19 let path: string 22 let watchingPath: string
23 let myHistoryPath = '/api/v1/users/me/history/videos'
24 let myHistoryRemove = myHistoryPath + '/remove'
20 let server: ServerInfo 25 let server: ServerInfo
21 26
22 // --------------------------------------------------------------- 27 // ---------------------------------------------------------------
@@ -33,14 +38,14 @@ describe('Test videos history API validator', function () {
33 const res = await uploadVideo(server.url, server.accessToken, {}) 38 const res = await uploadVideo(server.url, server.accessToken, {})
34 const videoUUID = res.body.video.uuid 39 const videoUUID = res.body.video.uuid
35 40
36 path = '/api/v1/videos/' + videoUUID + '/watching' 41 watchingPath = '/api/v1/videos/' + videoUUID + '/watching'
37 }) 42 })
38 43
39 describe('When notifying a user is watching a video', function () { 44 describe('When notifying a user is watching a video', function () {
40 45
41 it('Should fail with an unauthenticated user', async function () { 46 it('Should fail with an unauthenticated user', async function () {
42 const fields = { currentTime: 5 } 47 const fields = { currentTime: 5 }
43 await makePutBodyRequest({ url: server.url, path, fields, statusCodeExpected: 401 }) 48 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, statusCodeExpected: 401 })
44 }) 49 })
45 50
46 it('Should fail with an incorrect video id', async function () { 51 it('Should fail with an incorrect video id', async function () {
@@ -58,13 +63,68 @@ describe('Test videos history API validator', function () {
58 63
59 it('Should fail with a bad current time', async function () { 64 it('Should fail with a bad current time', async function () {
60 const fields = { currentTime: 'hello' } 65 const fields = { currentTime: 'hello' }
61 await makePutBodyRequest({ url: server.url, path, fields, token: server.accessToken, statusCodeExpected: 400 }) 66 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, token: server.accessToken, statusCodeExpected: 400 })
62 }) 67 })
63 68
64 it('Should succeed with the correct parameters', async function () { 69 it('Should succeed with the correct parameters', async function () {
65 const fields = { currentTime: 5 } 70 const fields = { currentTime: 5 }
66 71
67 await makePutBodyRequest({ url: server.url, path, fields, token: server.accessToken, statusCodeExpected: 204 }) 72 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, token: server.accessToken, statusCodeExpected: 204 })
73 })
74 })
75
76 describe('When listing user videos history', function () {
77 it('Should fail with a bad start pagination', async function () {
78 await checkBadStartPagination(server.url, myHistoryPath, server.accessToken)
79 })
80
81 it('Should fail with a bad count pagination', async function () {
82 await checkBadCountPagination(server.url, myHistoryPath, server.accessToken)
83 })
84
85 it('Should fail with an unauthenticated user', async function () {
86 await makeGetRequest({ url: server.url, path: myHistoryPath, statusCodeExpected: 401 })
87 })
88
89 it('Should succeed with the correct params', async function () {
90 await makeGetRequest({ url: server.url, token: server.accessToken, path: myHistoryPath, statusCodeExpected: 200 })
91 })
92 })
93
94 describe('When removing user videos history', function () {
95 it('Should fail with an unauthenticated user', async function () {
96 await makePostBodyRequest({ url: server.url, path: myHistoryPath + '/remove', statusCodeExpected: 401 })
97 })
98
99 it('Should fail with a bad beforeDate parameter', async function () {
100 const body = { beforeDate: '15' }
101 await makePostBodyRequest({
102 url: server.url,
103 token: server.accessToken,
104 path: myHistoryRemove,
105 fields: body,
106 statusCodeExpected: 400
107 })
108 })
109
110 it('Should succeed with a valid beforeDate param', async function () {
111 const body = { beforeDate: new Date().toISOString() }
112 await makePostBodyRequest({
113 url: server.url,
114 token: server.accessToken,
115 path: myHistoryRemove,
116 fields: body,
117 statusCodeExpected: 204
118 })
119 })
120
121 it('Should succeed without body', async function () {
122 await makePostBodyRequest({
123 url: server.url,
124 token: server.accessToken,
125 path: myHistoryRemove,
126 statusCodeExpected: 204
127 })
68 }) 128 })
69 }) 129 })
70 130
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 699f135c7..f26b91435 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -8,9 +8,13 @@ import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enu
8import { 8import {
9 createUser, flushTests, getMyUserInformation, getVideo, getVideosList, immutableAssign, killallServers, makeDeleteRequest, 9 createUser, flushTests, getMyUserInformation, getVideo, getVideosList, immutableAssign, killallServers, makeDeleteRequest,
10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin 10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin
11} from '../../utils' 11} from '../../../../shared/utils'
12import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 12import {
13import { getAccountsList } from '../../utils/users/accounts' 13 checkBadCountPagination,
14 checkBadSortPagination,
15 checkBadStartPagination
16} from '../../../../shared/utils/requests/check-api-params'
17import { getAccountsList } from '../../../../shared/utils/users/accounts'
14 18
15const expect = chai.expect 19const expect = chai.expect
16 20
@@ -316,10 +320,15 @@ describe('Test videos API validator', function () {
316 320
317 it('Should fail without an incorrect input file', async function () { 321 it('Should fail without an incorrect input file', async function () {
318 const fields = baseCorrectParams 322 const fields = baseCorrectParams
319 const attaches = { 323 let attaches = {
320 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm') 324 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
321 } 325 }
322 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 326 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
327
328 attaches = {
329 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mkv')
330 }
331 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
323 }) 332 })
324 333
325 it('Should fail with an incorrect thumbnail file', async function () { 334 it('Should fail with an incorrect thumbnail file', async function () {
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index a8a2f305f..9d3ce8153 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -18,15 +18,16 @@ import {
18 wait, 18 wait,
19 waitUntilLog, 19 waitUntilLog,
20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken 20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken
21} from '../../utils' 21} from '../../../../shared/utils'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23
23import * as magnetUtil from 'magnet-uri' 24import * as magnetUtil from 'magnet-uri'
24import { updateRedundancy } from '../../utils/server/redundancy' 25import { updateRedundancy } from '../../../../shared/utils/server/redundancy'
25import { ActorFollow } from '../../../../shared/models/actors' 26import { ActorFollow } from '../../../../shared/models/actors'
26import { readdir } from 'fs-extra' 27import { readdir } from 'fs-extra'
27import { join } from 'path' 28import { join } from 'path'
28import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy' 29import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy'
29import { getStats } from '../../utils/server/stats' 30import { getStats } from '../../../../shared/utils/server/stats'
30import { ServerStats } from '../../../../shared/models/server/server-stats.model' 31import { ServerStats } from '../../../../shared/models/server/server-stats.model'
31 32
32const expect = chai.expect 33const expect = chai.expect
@@ -136,7 +137,7 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
136 if (!videoUUID) videoUUID = video1Server2UUID 137 if (!videoUUID) videoUUID = video1Server2UUID
137 138
138 const webseeds = [ 139 const webseeds = [
139 'http://localhost:9001/static/webseed/' + videoUUID, 140 'http://localhost:9001/static/redundancy/' + videoUUID,
140 'http://localhost:9002/static/webseed/' + videoUUID 141 'http://localhost:9002/static/webseed/' + videoUUID
141 ] 142 ]
142 143
@@ -148,20 +149,23 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
148 for (const file of video.files) { 149 for (const file of video.files) {
149 checkMagnetWebseeds(file, webseeds, server) 150 checkMagnetWebseeds(file, webseeds, server)
150 151
151 // Only servers 1 and 2 have the video 152 await makeGetRequest({
152 if (server.serverNumber !== 3) { 153 url: servers[0].url,
153 await makeGetRequest({ 154 statusCodeExpected: 200,
154 url: server.url, 155 path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`,
155 statusCodeExpected: 200, 156 contentType: null
156 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, 157 })
157 contentType: null 158 await makeGetRequest({
158 }) 159 url: servers[1].url,
159 } 160 statusCodeExpected: 200,
161 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`,
162 contentType: null
163 })
160 } 164 }
161 } 165 }
162 166
163 for (const directory of [ 'test1', 'test2' ]) { 167 for (const directory of [ 'test1/redundancy', 'test2/videos' ]) {
164 const files = await readdir(join(root(), directory, 'videos')) 168 const files = await readdir(join(root(), directory))
165 expect(files).to.have.length.at.least(4) 169 expect(files).to.have.length.at.least(4)
166 170
167 for (const resolution of [ 240, 360, 480, 720 ]) { 171 for (const resolution of [ 240, 360, 480, 720 ]) {
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index a287c5bdf..a411e973b 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -17,10 +17,10 @@ import {
17 uploadVideo, 17 uploadVideo,
18 userLogin, 18 userLogin,
19 wait 19 wait
20} from '../../utils' 20} from '../../../../shared/utils'
21import { waitJobs } from '../../utils/server/jobs' 21import { waitJobs } from '../../../../shared/utils/server/jobs'
22import { VideoChannel } from '../../../../shared/models/videos' 22import { VideoChannel } from '../../../../shared/models/videos'
23import { searchVideoChannel } from '../../utils/search/video-channels' 23import { searchVideoChannel } from '../../../../shared/utils/search/video-channels'
24 24
25const expect = chai.expect 25const expect = chai.expect
26 26
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index 28f4fac50..f881917e7 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -16,8 +16,8 @@ import {
16 uploadVideo, 16 uploadVideo,
17 wait, 17 wait,
18 searchVideo 18 searchVideo
19} from '../../utils' 19} from '../../../../shared/utils'
20import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
21import { Video, VideoPrivacy } from '../../../../shared/models/videos' 21import { Video, VideoPrivacy } from '../../../../shared/models/videos'
22 22
23const expect = chai.expect 23const expect = chai.expect
diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts
index f1392ffea..50da837da 100644
--- a/server/tests/api/search/search-videos.ts
+++ b/server/tests/api/search/search-videos.ts
@@ -13,7 +13,7 @@ import {
13 uploadVideo, 13 uploadVideo,
14 wait, 14 wait,
15 immutableAssign 15 immutableAssign
16} from '../../utils' 16} from '../../../../shared/utils'
17 17
18const expect = chai.expect 18const expect = chai.expect
19 19
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index facd1688d..bebfc7398 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -4,8 +4,11 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { About } from '../../../../shared/models/server/about.model' 5import { About } from '../../../../shared/models/server/about.model'
6import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 6import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
7import { deleteCustomConfig, getAbout, killallServers, reRunServer } from '../../utils'
8import { 7import {
8 deleteCustomConfig,
9 getAbout,
10 killallServers,
11 reRunServer,
9 flushTests, 12 flushTests,
10 getConfig, 13 getConfig,
11 getCustomConfig, 14 getCustomConfig,
@@ -13,7 +16,8 @@ import {
13 runServer, 16 runServer,
14 setAccessTokensToServers, 17 setAccessTokensToServers,
15 updateCustomConfig 18 updateCustomConfig
16} from '../../utils/index' 19} from '../../../../shared/utils'
20import { ServerConfig } from '../../../../shared/models'
17 21
18const expect = chai.expect 22const expect = chai.expect
19 23
@@ -29,17 +33,24 @@ function checkInitialConfig (data: CustomConfig) {
29 expect(data.instance.defaultNSFWPolicy).to.equal('display') 33 expect(data.instance.defaultNSFWPolicy).to.equal('display')
30 expect(data.instance.customizations.css).to.be.empty 34 expect(data.instance.customizations.css).to.be.empty
31 expect(data.instance.customizations.javascript).to.be.empty 35 expect(data.instance.customizations.javascript).to.be.empty
36
32 expect(data.services.twitter.username).to.equal('@Chocobozzz') 37 expect(data.services.twitter.username).to.equal('@Chocobozzz')
33 expect(data.services.twitter.whitelisted).to.be.false 38 expect(data.services.twitter.whitelisted).to.be.false
39
34 expect(data.cache.previews.size).to.equal(1) 40 expect(data.cache.previews.size).to.equal(1)
35 expect(data.cache.captions.size).to.equal(1) 41 expect(data.cache.captions.size).to.equal(1)
42
36 expect(data.signup.enabled).to.be.true 43 expect(data.signup.enabled).to.be.true
37 expect(data.signup.limit).to.equal(4) 44 expect(data.signup.limit).to.equal(4)
38 expect(data.signup.requiresEmailVerification).to.be.false 45 expect(data.signup.requiresEmailVerification).to.be.false
46
39 expect(data.admin.email).to.equal('admin1@example.com') 47 expect(data.admin.email).to.equal('admin1@example.com')
48 expect(data.contactForm.enabled).to.be.true
49
40 expect(data.user.videoQuota).to.equal(5242880) 50 expect(data.user.videoQuota).to.equal(5242880)
41 expect(data.user.videoQuotaDaily).to.equal(-1) 51 expect(data.user.videoQuotaDaily).to.equal(-1)
42 expect(data.transcoding.enabled).to.be.false 52 expect(data.transcoding.enabled).to.be.false
53 expect(data.transcoding.allowAdditionalExtensions).to.be.false
43 expect(data.transcoding.threads).to.equal(2) 54 expect(data.transcoding.threads).to.equal(2)
44 expect(data.transcoding.resolutions['240p']).to.be.true 55 expect(data.transcoding.resolutions['240p']).to.be.true
45 expect(data.transcoding.resolutions['360p']).to.be.true 56 expect(data.transcoding.resolutions['360p']).to.be.true
@@ -59,23 +70,32 @@ function checkUpdatedConfig (data: CustomConfig) {
59 expect(data.instance.defaultNSFWPolicy).to.equal('blur') 70 expect(data.instance.defaultNSFWPolicy).to.equal('blur')
60 expect(data.instance.customizations.javascript).to.equal('alert("coucou")') 71 expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
61 expect(data.instance.customizations.css).to.equal('body { background-color: red; }') 72 expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
73
62 expect(data.services.twitter.username).to.equal('@Kuja') 74 expect(data.services.twitter.username).to.equal('@Kuja')
63 expect(data.services.twitter.whitelisted).to.be.true 75 expect(data.services.twitter.whitelisted).to.be.true
76
64 expect(data.cache.previews.size).to.equal(2) 77 expect(data.cache.previews.size).to.equal(2)
65 expect(data.cache.captions.size).to.equal(3) 78 expect(data.cache.captions.size).to.equal(3)
79
66 expect(data.signup.enabled).to.be.false 80 expect(data.signup.enabled).to.be.false
67 expect(data.signup.limit).to.equal(5) 81 expect(data.signup.limit).to.equal(5)
68 expect(data.signup.requiresEmailVerification).to.be.true 82 expect(data.signup.requiresEmailVerification).to.be.true
83
69 expect(data.admin.email).to.equal('superadmin1@example.com') 84 expect(data.admin.email).to.equal('superadmin1@example.com')
85 expect(data.contactForm.enabled).to.be.false
86
70 expect(data.user.videoQuota).to.equal(5242881) 87 expect(data.user.videoQuota).to.equal(5242881)
71 expect(data.user.videoQuotaDaily).to.equal(318742) 88 expect(data.user.videoQuotaDaily).to.equal(318742)
89
72 expect(data.transcoding.enabled).to.be.true 90 expect(data.transcoding.enabled).to.be.true
73 expect(data.transcoding.threads).to.equal(1) 91 expect(data.transcoding.threads).to.equal(1)
92 expect(data.transcoding.allowAdditionalExtensions).to.be.true
74 expect(data.transcoding.resolutions['240p']).to.be.false 93 expect(data.transcoding.resolutions['240p']).to.be.false
75 expect(data.transcoding.resolutions['360p']).to.be.true 94 expect(data.transcoding.resolutions['360p']).to.be.true
76 expect(data.transcoding.resolutions['480p']).to.be.true 95 expect(data.transcoding.resolutions['480p']).to.be.true
77 expect(data.transcoding.resolutions['720p']).to.be.false 96 expect(data.transcoding.resolutions['720p']).to.be.false
78 expect(data.transcoding.resolutions['1080p']).to.be.false 97 expect(data.transcoding.resolutions['1080p']).to.be.false
98
79 expect(data.import.videos.http.enabled).to.be.false 99 expect(data.import.videos.http.enabled).to.be.false
80 expect(data.import.videos.torrent.enabled).to.be.false 100 expect(data.import.videos.torrent.enabled).to.be.false
81} 101}
@@ -93,7 +113,7 @@ describe('Test config', function () {
93 113
94 it('Should have a correct config on a server with registration enabled', async function () { 114 it('Should have a correct config on a server with registration enabled', async function () {
95 const res = await getConfig(server.url) 115 const res = await getConfig(server.url)
96 const data = res.body 116 const data: ServerConfig = res.body
97 117
98 expect(data.signup.allowed).to.be.true 118 expect(data.signup.allowed).to.be.true
99 }) 119 })
@@ -108,11 +128,23 @@ describe('Test config', function () {
108 ]) 128 ])
109 129
110 const res = await getConfig(server.url) 130 const res = await getConfig(server.url)
111 const data = res.body 131 const data: ServerConfig = res.body
112 132
113 expect(data.signup.allowed).to.be.false 133 expect(data.signup.allowed).to.be.false
114 }) 134 })
115 135
136 it('Should have the correct video allowed extensions', async function () {
137 const res = await getConfig(server.url)
138 const data: ServerConfig = res.body
139
140 expect(data.video.file.extensions).to.have.lengthOf(3)
141 expect(data.video.file.extensions).to.contain('.mp4')
142 expect(data.video.file.extensions).to.contain('.webm')
143 expect(data.video.file.extensions).to.contain('.ogv')
144
145 expect(data.contactForm.enabled).to.be.true
146 })
147
116 it('Should get the customized configuration', async function () { 148 it('Should get the customized configuration', async function () {
117 const res = await getCustomConfig(server.url, server.accessToken) 149 const res = await getCustomConfig(server.url, server.accessToken)
118 const data = res.body as CustomConfig 150 const data = res.body as CustomConfig
@@ -156,12 +188,16 @@ describe('Test config', function () {
156 admin: { 188 admin: {
157 email: 'superadmin1@example.com' 189 email: 'superadmin1@example.com'
158 }, 190 },
191 contactForm: {
192 enabled: false
193 },
159 user: { 194 user: {
160 videoQuota: 5242881, 195 videoQuota: 5242881,
161 videoQuotaDaily: 318742 196 videoQuotaDaily: 318742
162 }, 197 },
163 transcoding: { 198 transcoding: {
164 enabled: true, 199 enabled: true,
200 allowAdditionalExtensions: true,
165 threads: 1, 201 threads: 1,
166 resolutions: { 202 resolutions: {
167 '240p': false, 203 '240p': false,
@@ -190,6 +226,18 @@ describe('Test config', function () {
190 checkUpdatedConfig(data) 226 checkUpdatedConfig(data)
191 }) 227 })
192 228
229 it('Should have the correct updated video allowed extensions', async function () {
230 const res = await getConfig(server.url)
231 const data: ServerConfig = res.body
232
233 expect(data.video.file.extensions).to.have.length.above(3)
234 expect(data.video.file.extensions).to.contain('.mp4')
235 expect(data.video.file.extensions).to.contain('.webm')
236 expect(data.video.file.extensions).to.contain('.ogv')
237 expect(data.video.file.extensions).to.contain('.flv')
238 expect(data.video.file.extensions).to.contain('.mkv')
239 })
240
193 it('Should have the configuration updated after a restart', async function () { 241 it('Should have the configuration updated after a restart', async function () {
194 this.timeout(10000) 242 this.timeout(10000)
195 243
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
new file mode 100644
index 000000000..93221d0a3
--- /dev/null
+++ b/server/tests/api/server/contact-form.ts
@@ -0,0 +1,86 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, wait } from '../../../../shared/utils'
6import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
7import { waitJobs } from '../../../../shared/utils/server/jobs'
8import { sendContactForm } from '../../../../shared/utils/server/contact-form'
9
10const expect = chai.expect
11
12describe('Test contact form', function () {
13 let server: ServerInfo
14 const emails: object[] = []
15
16 before(async function () {
17 this.timeout(30000)
18
19 await MockSmtpServer.Instance.collectEmails(emails)
20
21 await flushTests()
22
23 const overrideConfig = {
24 smtp: {
25 hostname: 'localhost'
26 }
27 }
28 server = await runServer(1, overrideConfig)
29 await setAccessTokensToServers([ server ])
30 })
31
32 it('Should send a contact form', async function () {
33 this.timeout(10000)
34
35 await sendContactForm({
36 url: server.url,
37 fromEmail: 'toto@example.com',
38 body: 'my super message',
39 fromName: 'Super toto'
40 })
41
42 await waitJobs(server)
43
44 expect(emails).to.have.lengthOf(1)
45
46 const email = emails[0]
47
48 expect(email['from'][0]['address']).equal('toto@example.com')
49 expect(email['to'][0]['address']).equal('admin1@example.com')
50 expect(email['subject']).contains('Contact form')
51 expect(email['text']).contains('my super message')
52 })
53
54 it('Should not be able to send another contact form because of the anti spam checker', async function () {
55 await sendContactForm({
56 url: server.url,
57 fromEmail: 'toto@example.com',
58 body: 'my super message',
59 fromName: 'Super toto'
60 })
61
62 await sendContactForm({
63 url: server.url,
64 fromEmail: 'toto@example.com',
65 body: 'my super message',
66 fromName: 'Super toto',
67 expectedStatus: 403
68 })
69 })
70
71 it('Should be able to send another contact form after a while', async function () {
72 await wait(1000)
73
74 await sendContactForm({
75 url: server.url,
76 fromEmail: 'toto@example.com',
77 body: 'my super message',
78 fromName: 'Super toto'
79 })
80 })
81
82 after(async function () {
83 MockSmtpServer.Instance.kill()
84 killallServers([ server ])
85 })
86})
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index 713a27143..f96c57b66 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -14,11 +14,14 @@ import {
14 unblockUser, 14 unblockUser,
15 uploadVideo, 15 uploadVideo,
16 userLogin, 16 userLogin,
17 verifyEmail 17 verifyEmail,
18} from '../../utils' 18 flushTests,
19import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 19 killallServers,
20import { mockSmtpServer } from '../../utils/miscs/email' 20 ServerInfo,
21import { waitJobs } from '../../utils/server/jobs' 21 setAccessTokensToServers
22} from '../../../../shared/utils'
23import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
22 25
23const expect = chai.expect 26const expect = chai.expect
24 27
@@ -38,7 +41,7 @@ describe('Test emails', function () {
38 before(async function () { 41 before(async function () {
39 this.timeout(30000) 42 this.timeout(30000)
40 43
41 await mockSmtpServer(emails) 44 await MockSmtpServer.Instance.collectEmails(emails)
42 45
43 await flushTests() 46 await flushTests()
44 47
@@ -248,6 +251,7 @@ describe('Test emails', function () {
248 }) 251 })
249 252
250 after(async function () { 253 after(async function () {
254 MockSmtpServer.Instance.kill()
251 killallServers([ server ]) 255 killallServers([ server ])
252 }) 256 })
253}) 257})
diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts
index 3135fc568..8bb073c41 100644
--- a/server/tests/api/server/follow-constraints.ts
+++ b/server/tests/api/server/follow-constraints.ts
@@ -2,11 +2,21 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { doubleFollow, getAccountVideos, getVideo, getVideoChannelVideos, getVideoWithToken } from '../../utils' 5import {
6import { flushAndRunMultipleServers, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 6 doubleFollow,
7import { unfollow } from '../../utils/server/follows' 7 getAccountVideos,
8import { userLogin } from '../../utils/users/login' 8 getVideo,
9import { createUser } from '../../utils/users/users' 9 getVideoChannelVideos,
10 getVideoWithToken,
11 flushAndRunMultipleServers,
12 killallServers,
13 ServerInfo,
14 setAccessTokensToServers,
15 uploadVideo
16} from '../../../../shared/utils'
17import { unfollow } from '../../../../shared/utils/server/follows'
18import { userLogin } from '../../../../shared/utils/users/login'
19import { createUser } from '../../../../shared/utils/users/users'
10 20
11const expect = chai.expect 21const expect = chai.expect
12 22
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index e80e93e7f..b0fc5d293 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -4,7 +4,7 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { Video, VideoPrivacy } from '../../../../shared/models/videos' 5import { Video, VideoPrivacy } from '../../../../shared/models/videos'
6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
7import { completeVideoCheck } from '../../utils' 7import { completeVideoCheck } from '../../../../shared/utils'
8import { 8import {
9 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
10 getVideosList, 10 getVideosList,
@@ -12,21 +12,26 @@ import {
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo 14 uploadVideo
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { dateIsValid } from '../../utils/miscs/miscs' 16import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
17import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows' 17import {
18import { expectAccountFollows } from '../../utils/users/accounts' 18 follow,
19import { userLogin } from '../../utils/users/login' 19 getFollowersListPaginationAndSort,
20import { createUser } from '../../utils/users/users' 20 getFollowingListPaginationAndSort,
21 unfollow
22} from '../../../../shared/utils/server/follows'
23import { expectAccountFollows } from '../../../../shared/utils/users/accounts'
24import { userLogin } from '../../../../shared/utils/users/login'
25import { createUser } from '../../../../shared/utils/users/users'
21import { 26import {
22 addVideoCommentReply, 27 addVideoCommentReply,
23 addVideoCommentThread, 28 addVideoCommentThread,
24 getVideoCommentThreads, 29 getVideoCommentThreads,
25 getVideoThreadComments 30 getVideoThreadComments
26} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
27import { rateVideo } from '../../utils/videos/videos' 32import { rateVideo } from '../../../../shared/utils/videos/videos'
28import { waitJobs } from '../../utils/server/jobs' 33import { waitJobs } from '../../../../shared/utils/server/jobs'
29import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions' 34import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
30import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' 35import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
31 36
32const expect = chai.expect 37const expect = chai.expect
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index 0421b2b40..cd7baadad 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -5,24 +5,30 @@ import 'mocha'
5import { JobState, Video } from '../../../../shared/models' 5import { JobState, Video } from '../../../../shared/models'
6import { VideoPrivacy } from '../../../../shared/models/videos' 6import { VideoPrivacy } from '../../../../shared/models/videos'
7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
8import { completeVideoCheck, getVideo, immutableAssign, reRunServer, unfollow, updateVideo, viewVideo } from '../../utils' 8
9import { 9import {
10 completeVideoCheck,
10 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
12 getVideo,
11 getVideosList, 13 getVideosList,
14 immutableAssign,
12 killallServers, 15 killallServers,
16 reRunServer,
13 ServerInfo, 17 ServerInfo,
14 setAccessTokensToServers, 18 setAccessTokensToServers,
19 unfollow,
20 updateVideo,
15 uploadVideo, 21 uploadVideo,
16 wait 22 wait
17} from '../../utils/index' 23} from '../../../../shared/utils'
18import { follow, getFollowersListPaginationAndSort } from '../../utils/server/follows' 24import { follow, getFollowersListPaginationAndSort } from '../../../../shared/utils/server/follows'
19import { getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 25import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
20import { 26import {
21 addVideoCommentReply, 27 addVideoCommentReply,
22 addVideoCommentThread, 28 addVideoCommentThread,
23 getVideoCommentThreads, 29 getVideoCommentThreads,
24 getVideoThreadComments 30 getVideoThreadComments
25} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
26 32
27const expect = chai.expect 33const expect = chai.expect
28 34
diff --git a/server/tests/api/server/index.ts b/server/tests/api/server/index.ts
index 6afcab1f9..1f80cc6cf 100644
--- a/server/tests/api/server/index.ts
+++ b/server/tests/api/server/index.ts
@@ -1,4 +1,5 @@
1import './config' 1import './config'
2import './contact-form'
2import './email' 3import './email'
3import './follow-constraints' 4import './follow-constraints'
4import './follows' 5import './follows'
diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts
index cd59d9a1b..52948b1d6 100644
--- a/server/tests/api/server/jobs.ts
+++ b/server/tests/api/server/jobs.ts
@@ -2,12 +2,12 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
6import { doubleFollow } from '../../utils/server/follows' 6import { doubleFollow } from '../../../../shared/utils/server/follows'
7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
8import { flushAndRunMultipleServers } from '../../utils/server/servers' 8import { flushAndRunMultipleServers } from '../../../../shared/utils/server/servers'
9import { uploadVideo } from '../../utils/videos/videos' 9import { uploadVideo } from '../../../../shared/utils/videos/videos'
10import { dateIsValid } from '../../utils/miscs/miscs' 10import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
11 11
12const expect = chai.expect 12const expect = chai.expect
13 13
diff --git a/server/tests/api/server/no-client.ts b/server/tests/api/server/no-client.ts
index 6d6ce8532..3b95ce945 100644
--- a/server/tests/api/server/no-client.ts
+++ b/server/tests/api/server/no-client.ts
@@ -4,8 +4,8 @@ import {
4 flushTests, 4 flushTests,
5 killallServers, 5 killallServers,
6 ServerInfo 6 ServerInfo
7} from '../../utils/index' 7} from '../../../../shared/utils'
8import { runServer } from '../../utils/server/servers' 8import { runServer } from '../../../../shared/utils/server/servers'
9 9
10describe('Start and stop server without web client routes', function () { 10describe('Start and stop server without web client routes', function () {
11 let server: ServerInfo 11 let server: ServerInfo
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts
index e2c2a293e..d4c08c346 100644
--- a/server/tests/api/server/reverse-proxy.ts
+++ b/server/tests/api/server/reverse-proxy.ts
@@ -15,7 +15,7 @@ import {
15 userLogin, 15 userLogin,
16 viewVideo, 16 viewVideo,
17 wait 17 wait
18} from '../../utils' 18} from '../../../../shared/utils'
19const expect = chai.expect 19const expect = chai.expect
20 20
21import { 21import {
@@ -23,7 +23,7 @@ import {
23 flushTests, 23 flushTests,
24 runServer, 24 runServer,
25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig 25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig
26} from '../../utils/index' 26} from '../../../../shared/utils/index'
27 27
28describe('Test application behind a reverse proxy', function () { 28describe('Test application behind a reverse proxy', function () {
29 let server = null 29 let server = null
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index cb229e876..aaa6c62f7 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -13,11 +13,11 @@ import {
13 uploadVideo, 13 uploadVideo,
14 viewVideo, 14 viewVideo,
15 wait 15 wait
16} from '../../utils' 16} from '../../../../shared/utils'
17import { flushTests, setAccessTokensToServers } from '../../utils/index' 17import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
18import { getStats } from '../../utils/server/stats' 18import { getStats } from '../../../../shared/utils/server/stats'
19import { addVideoCommentThread } from '../../utils/videos/video-comments' 19import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
20import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
21 21
22const expect = chai.expect 22const expect = chai.expect
23 23
@@ -39,7 +39,7 @@ describe('Test stats (excluding redundancy)', function () {
39 } 39 }
40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) 40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
41 41
42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, {}) 42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
43 const videoUUID = resVideo.body.video.uuid 43 const videoUUID = resVideo.body.video.uuid
44 44
45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') 45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment')
@@ -60,6 +60,7 @@ describe('Test stats (excluding redundancy)', function () {
60 expect(data.totalLocalVideoComments).to.equal(1) 60 expect(data.totalLocalVideoComments).to.equal(1)
61 expect(data.totalLocalVideos).to.equal(1) 61 expect(data.totalLocalVideos).to.equal(1)
62 expect(data.totalLocalVideoViews).to.equal(1) 62 expect(data.totalLocalVideoViews).to.equal(1)
63 expect(data.totalLocalVideoFilesSize).to.equal(218910)
63 expect(data.totalUsers).to.equal(2) 64 expect(data.totalUsers).to.equal(2)
64 expect(data.totalVideoComments).to.equal(1) 65 expect(data.totalVideoComments).to.equal(1)
65 expect(data.totalVideos).to.equal(1) 66 expect(data.totalVideos).to.equal(1)
@@ -74,6 +75,7 @@ describe('Test stats (excluding redundancy)', function () {
74 expect(data.totalLocalVideoComments).to.equal(0) 75 expect(data.totalLocalVideoComments).to.equal(0)
75 expect(data.totalLocalVideos).to.equal(0) 76 expect(data.totalLocalVideos).to.equal(0)
76 expect(data.totalLocalVideoViews).to.equal(0) 77 expect(data.totalLocalVideoViews).to.equal(0)
78 expect(data.totalLocalVideoFilesSize).to.equal(0)
77 expect(data.totalUsers).to.equal(1) 79 expect(data.totalUsers).to.equal(1)
78 expect(data.totalVideoComments).to.equal(1) 80 expect(data.totalVideoComments).to.equal(1)
79 expect(data.totalVideos).to.equal(1) 81 expect(data.totalVideos).to.equal(1)
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts
index 856f2f4d1..25ca00029 100644
--- a/server/tests/api/server/tracker.ts
+++ b/server/tests/api/server/tracker.ts
@@ -2,8 +2,8 @@
2 2
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import 'mocha' 4import 'mocha'
5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../utils' 5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils'
6import { flushTests, setAccessTokensToServers } from '../../utils/index' 6import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
7import { VideoDetails } from '../../../../shared/models/videos' 7import { VideoDetails } from '../../../../shared/models/videos'
8import * as WebTorrent from 'webtorrent' 8import * as WebTorrent from 'webtorrent'
9 9
diff --git a/server/tests/api/users/blocklist.ts b/server/tests/api/users/blocklist.ts
index eed4b9f3e..4bca27a94 100644
--- a/server/tests/api/users/blocklist.ts
+++ b/server/tests/api/users/blocklist.ts
@@ -12,16 +12,16 @@ import {
12 ServerInfo, 12 ServerInfo,
13 uploadVideo, 13 uploadVideo,
14 userLogin 14 userLogin
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { setAccessTokensToServers } from '../../utils/users/login' 16import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
17import { getVideosListWithToken, getVideosList } from '../../utils/videos/videos' 17import { getVideosListWithToken, getVideosList } from '../../../../shared/utils/videos/videos'
18import { 18import {
19 addVideoCommentReply, 19 addVideoCommentReply,
20 addVideoCommentThread, 20 addVideoCommentThread,
21 getVideoCommentThreads, 21 getVideoCommentThreads,
22 getVideoThreadComments 22 getVideoThreadComments
23} from '../../utils/videos/video-comments' 23} from '../../../../shared/utils/videos/video-comments'
24import { waitJobs } from '../../utils/server/jobs' 24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 25import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
26import { 26import {
27 addAccountToAccountBlocklist, 27 addAccountToAccountBlocklist,
@@ -36,7 +36,7 @@ import {
36 removeAccountFromServerBlocklist, 36 removeAccountFromServerBlocklist,
37 removeServerFromAccountBlocklist, 37 removeServerFromAccountBlocklist,
38 removeServerFromServerBlocklist 38 removeServerFromServerBlocklist
39} from '../../utils/users/blocklist' 39} from '../../../../shared/utils/users/blocklist'
40 40
41const expect = chai.expect 41const expect = chai.expect
42 42
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts
index ff433315d..52ba6984e 100644
--- a/server/tests/api/users/index.ts
+++ b/server/tests/api/users/index.ts
@@ -1,5 +1,6 @@
1import './users-verification'
2import './user-notifications'
1import './blocklist' 3import './blocklist'
2import './user-subscriptions' 4import './user-subscriptions'
3import './users' 5import './users'
4import './users-multiple-servers' 6import './users-multiple-servers'
5import './users-verification'
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts
new file mode 100644
index 000000000..5260d64cc
--- /dev/null
+++ b/server/tests/api/users/user-notifications.ts
@@ -0,0 +1,1017 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 addVideoToBlacklist,
7 createUser,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 flushTests,
11 getMyUserInformation,
12 immutableAssign,
13 registerUser,
14 removeVideoFromBlacklist,
15 reportVideoAbuse,
16 updateMyUser,
17 updateVideo,
18 updateVideoChannel,
19 userLogin,
20 wait
21} from '../../../../shared/utils'
22import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
23import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { getUserNotificationSocket } from '../../../../shared/utils/socket/socket-io'
26import {
27 checkCommentMention,
28 CheckerBaseParams,
29 checkMyVideoImportIsFinished,
30 checkNewActorFollow,
31 checkNewBlacklistOnMyVideo,
32 checkNewCommentOnMyVideo,
33 checkNewVideoAbuseForModerators,
34 checkNewVideoFromSubscription,
35 checkUserRegistered,
36 checkVideoIsPublished,
37 getLastNotification,
38 getUserNotifications,
39 markAsReadNotifications,
40 updateMyNotificationSettings,
41 markAsReadAllNotifications
42} from '../../../../shared/utils/users/user-notifications'
43import {
44 User,
45 UserNotification,
46 UserNotificationSetting,
47 UserNotificationSettingValue,
48 UserNotificationType
49} from '../../../../shared/models/users'
50import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
51import { addUserSubscription, removeUserSubscription } from '../../../../shared/utils/users/user-subscriptions'
52import { VideoPrivacy } from '../../../../shared/models/videos'
53import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
54import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
55import * as uuidv4 from 'uuid/v4'
56import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/utils/users/blocklist'
57
58const expect = chai.expect
59
60async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalParams: any = {}) {
61 const name = 'remote video ' + uuidv4()
62
63 const data = Object.assign({ name }, additionalParams)
64 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data)
65
66 await waitJobs(servers)
67
68 return { uuid: res.body.video.uuid, name }
69}
70
71async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParams: any = {}) {
72 const name = 'local video ' + uuidv4()
73
74 const data = Object.assign({ name }, additionalParams)
75 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data)
76
77 await waitJobs(servers)
78
79 return { uuid: res.body.video.uuid, name }
80}
81
82describe('Test users notifications', function () {
83 let servers: ServerInfo[] = []
84 let userAccessToken: string
85 let userNotifications: UserNotification[] = []
86 let adminNotifications: UserNotification[] = []
87 let adminNotificationsServer2: UserNotification[] = []
88 const emails: object[] = []
89 let channelId: number
90
91 const allNotificationSettings: UserNotificationSetting = {
92 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
93 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
94 videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
95 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
96 myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
97 myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
98 commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
99 newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
100 newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
101 }
102
103 before(async function () {
104 this.timeout(120000)
105
106 await MockSmtpServer.Instance.collectEmails(emails)
107
108 await flushTests()
109
110 const overrideConfig = {
111 smtp: {
112 hostname: 'localhost'
113 }
114 }
115 servers = await flushAndRunMultipleServers(2, overrideConfig)
116
117 // Get the access tokens
118 await setAccessTokensToServers(servers)
119
120 // Server 1 and server 2 follow each other
121 await doubleFollow(servers[0], servers[1])
122
123 await waitJobs(servers)
124
125 const user = {
126 username: 'user_1',
127 password: 'super password'
128 }
129 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000)
130 userAccessToken = await userLogin(servers[0], user)
131
132 await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings)
133 await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, allNotificationSettings)
134 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings)
135
136 {
137 const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken)
138 socket.on('new-notification', n => userNotifications.push(n))
139 }
140 {
141 const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken)
142 socket.on('new-notification', n => adminNotifications.push(n))
143 }
144 {
145 const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken)
146 socket.on('new-notification', n => adminNotificationsServer2.push(n))
147 }
148
149 {
150 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
151 channelId = resChannel.body.videoChannels[0].id
152 }
153 })
154
155 describe('New video from my subscription notification', function () {
156 let baseParams: CheckerBaseParams
157
158 before(() => {
159 baseParams = {
160 server: servers[0],
161 emails,
162 socketNotifications: userNotifications,
163 token: userAccessToken
164 }
165 })
166
167 it('Should not send notifications if the user does not follow the video publisher', async function () {
168 await uploadVideoByLocalAccount(servers)
169
170 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
171 expect(notification).to.be.undefined
172
173 expect(emails).to.have.lengthOf(0)
174 expect(userNotifications).to.have.lengthOf(0)
175 })
176
177 it('Should send a new video notification if the user follows the local video publisher', async function () {
178 this.timeout(15000)
179
180 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9001')
181 await waitJobs(servers)
182
183 const { name, uuid } = await uploadVideoByLocalAccount(servers)
184 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
185 })
186
187 it('Should send a new video notification from a remote account', async function () {
188 this.timeout(50000) // Server 2 has transcoding enabled
189
190 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9002')
191 await waitJobs(servers)
192
193 const { name, uuid } = await uploadVideoByRemoteAccount(servers)
194 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
195 })
196
197 it('Should send a new video notification on a scheduled publication', async function () {
198 this.timeout(20000)
199
200 // In 2 seconds
201 let updateAt = new Date(new Date().getTime() + 2000)
202
203 const data = {
204 privacy: VideoPrivacy.PRIVATE,
205 scheduleUpdate: {
206 updateAt: updateAt.toISOString(),
207 privacy: VideoPrivacy.PUBLIC
208 }
209 }
210 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
211
212 await wait(6000)
213 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
214 })
215
216 it('Should send a new video notification on a remote scheduled publication', async function () {
217 this.timeout(20000)
218
219 // In 2 seconds
220 let updateAt = new Date(new Date().getTime() + 2000)
221
222 const data = {
223 privacy: VideoPrivacy.PRIVATE,
224 scheduleUpdate: {
225 updateAt: updateAt.toISOString(),
226 privacy: VideoPrivacy.PUBLIC
227 }
228 }
229 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
230 await waitJobs(servers)
231
232 await wait(6000)
233 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
234 })
235
236 it('Should not send a notification before the video is published', async function () {
237 this.timeout(20000)
238
239 let updateAt = new Date(new Date().getTime() + 100000)
240
241 const data = {
242 privacy: VideoPrivacy.PRIVATE,
243 scheduleUpdate: {
244 updateAt: updateAt.toISOString(),
245 privacy: VideoPrivacy.PUBLIC
246 }
247 }
248 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
249
250 await wait(6000)
251 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
252 })
253
254 it('Should send a new video notification when a video becomes public', async function () {
255 this.timeout(10000)
256
257 const data = { privacy: VideoPrivacy.PRIVATE }
258 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
259
260 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
261
262 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
263
264 await wait(500)
265 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
266 })
267
268 it('Should send a new video notification when a remote video becomes public', async function () {
269 this.timeout(20000)
270
271 const data = { privacy: VideoPrivacy.PRIVATE }
272 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
273
274 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
275
276 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
277
278 await waitJobs(servers)
279 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
280 })
281
282 it('Should not send a new video notification when a video becomes unlisted', async function () {
283 this.timeout(20000)
284
285 const data = { privacy: VideoPrivacy.PRIVATE }
286 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
287
288 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
289
290 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
291 })
292
293 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
294 this.timeout(20000)
295
296 const data = { privacy: VideoPrivacy.PRIVATE }
297 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
298
299 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
300
301 await waitJobs(servers)
302 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
303 })
304
305 it('Should send a new video notification after a video import', async function () {
306 this.timeout(30000)
307
308 const name = 'video import ' + uuidv4()
309
310 const attributes = {
311 name,
312 channelId,
313 privacy: VideoPrivacy.PUBLIC,
314 targetUrl: getYoutubeVideoUrl()
315 }
316 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
317 const uuid = res.body.video.uuid
318
319 await waitJobs(servers)
320
321 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
322 })
323 })
324
325 describe('Comment on my video notifications', function () {
326 let baseParams: CheckerBaseParams
327
328 before(() => {
329 baseParams = {
330 server: servers[0],
331 emails,
332 socketNotifications: userNotifications,
333 token: userAccessToken
334 }
335 })
336
337 it('Should not send a new comment notification after a comment on another video', async function () {
338 this.timeout(10000)
339
340 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
341 const uuid = resVideo.body.video.uuid
342
343 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
344 const commentId = resComment.body.comment.id
345
346 await wait(500)
347 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
348 })
349
350 it('Should not send a new comment notification if I comment my own video', async function () {
351 this.timeout(10000)
352
353 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
354 const uuid = resVideo.body.video.uuid
355
356 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
357 const commentId = resComment.body.comment.id
358
359 await wait(500)
360 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
361 })
362
363 it('Should not send a new comment notification if the account is muted', async function () {
364 this.timeout(10000)
365
366 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
367
368 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
369 const uuid = resVideo.body.video.uuid
370
371 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
372 const commentId = resComment.body.comment.id
373
374 await wait(500)
375 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
376
377 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
378 })
379
380 it('Should send a new comment notification after a local comment on my video', async function () {
381 this.timeout(10000)
382
383 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
384 const uuid = resVideo.body.video.uuid
385
386 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
387 const commentId = resComment.body.comment.id
388
389 await wait(500)
390 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
391 })
392
393 it('Should send a new comment notification after a remote comment on my video', async function () {
394 this.timeout(10000)
395
396 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
397 const uuid = resVideo.body.video.uuid
398
399 await waitJobs(servers)
400
401 const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
402 const commentId = resComment.body.comment.id
403
404 await waitJobs(servers)
405 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
406 })
407
408 it('Should send a new comment notification after a local reply on my video', async function () {
409 this.timeout(10000)
410
411 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
412 const uuid = resVideo.body.video.uuid
413
414 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
415 const threadId = resThread.body.comment.id
416
417 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
418 const commentId = resComment.body.comment.id
419
420 await wait(500)
421 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
422 })
423
424 it('Should send a new comment notification after a remote reply on my video', async function () {
425 this.timeout(10000)
426
427 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
428 const uuid = resVideo.body.video.uuid
429 await waitJobs(servers)
430
431 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
432 const threadId = resThread.body.comment.id
433
434 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
435 const commentId = resComment.body.comment.id
436
437 await waitJobs(servers)
438 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
439 })
440 })
441
442 describe('Mention notifications', function () {
443 let baseParams: CheckerBaseParams
444
445 before(async () => {
446 baseParams = {
447 server: servers[0],
448 emails,
449 socketNotifications: userNotifications,
450 token: userAccessToken
451 }
452
453 await updateMyUser({
454 url: servers[0].url,
455 accessToken: servers[0].accessToken,
456 displayName: 'super root name'
457 })
458
459 await updateMyUser({
460 url: servers[1].url,
461 accessToken: servers[1].accessToken,
462 displayName: 'super root 2 name'
463 })
464 })
465
466 it('Should not send a new mention comment notification if I mention the video owner', async function () {
467 this.timeout(10000)
468
469 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
470 const uuid = resVideo.body.video.uuid
471
472 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
473 const commentId = resComment.body.comment.id
474
475 await wait(500)
476 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
477 })
478
479 it('Should not send a new mention comment notification if I mention myself', async function () {
480 this.timeout(10000)
481
482 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
483 const uuid = resVideo.body.video.uuid
484
485 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello')
486 const commentId = resComment.body.comment.id
487
488 await wait(500)
489 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
490 })
491
492 it('Should not send a new mention notification if the account is muted', async function () {
493 this.timeout(10000)
494
495 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
496
497 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
498 const uuid = resVideo.body.video.uuid
499
500 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
501 const commentId = resComment.body.comment.id
502
503 await wait(500)
504 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
505
506 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
507 })
508
509 it('Should send a new mention notification after local comments', async function () {
510 this.timeout(10000)
511
512 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
513 const uuid = resVideo.body.video.uuid
514
515 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1')
516 const threadId = resThread.body.comment.id
517
518 await wait(500)
519 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence')
520
521 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1')
522 const commentId = resComment.body.comment.id
523
524 await wait(500)
525 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence')
526 })
527
528 it('Should send a new mention notification after remote comments', async function () {
529 this.timeout(20000)
530
531 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
532 const uuid = resVideo.body.video.uuid
533
534 await waitJobs(servers)
535 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'hello @user_1@localhost:9001 1')
536 const threadId = resThread.body.comment.id
537
538 await waitJobs(servers)
539 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'presence')
540
541 const text = '@user_1@localhost:9001 hello 2 @root@localhost:9001'
542 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, text)
543 const commentId = resComment.body.comment.id
544
545 await waitJobs(servers)
546 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root 2 name', 'presence')
547 })
548 })
549
550 describe('Video abuse for moderators notification' , function () {
551 let baseParams: CheckerBaseParams
552
553 before(() => {
554 baseParams = {
555 server: servers[0],
556 emails,
557 socketNotifications: adminNotifications,
558 token: servers[0].accessToken
559 }
560 })
561
562 it('Should send a notification to moderators on local video abuse', async function () {
563 this.timeout(10000)
564
565 const name = 'video for abuse ' + uuidv4()
566 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
567 const uuid = resVideo.body.video.uuid
568
569 await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
570
571 await waitJobs(servers)
572 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
573 })
574
575 it('Should send a notification to moderators on remote video abuse', async function () {
576 this.timeout(10000)
577
578 const name = 'video for abuse ' + uuidv4()
579 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
580 const uuid = resVideo.body.video.uuid
581
582 await waitJobs(servers)
583
584 await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
585
586 await waitJobs(servers)
587 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
588 })
589 })
590
591 describe('Video blacklist on my video', function () {
592 let baseParams: CheckerBaseParams
593
594 before(() => {
595 baseParams = {
596 server: servers[0],
597 emails,
598 socketNotifications: userNotifications,
599 token: userAccessToken
600 }
601 })
602
603 it('Should send a notification to video owner on blacklist', async function () {
604 this.timeout(10000)
605
606 const name = 'video for abuse ' + uuidv4()
607 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
608 const uuid = resVideo.body.video.uuid
609
610 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
611
612 await waitJobs(servers)
613 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'blacklist')
614 })
615
616 it('Should send a notification to video owner on unblacklist', async function () {
617 this.timeout(10000)
618
619 const name = 'video for abuse ' + uuidv4()
620 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
621 const uuid = resVideo.body.video.uuid
622
623 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
624
625 await waitJobs(servers)
626 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
627 await waitJobs(servers)
628
629 await wait(500)
630 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'unblacklist')
631 })
632 })
633
634 describe('My video is published', function () {
635 let baseParams: CheckerBaseParams
636
637 before(() => {
638 baseParams = {
639 server: servers[1],
640 emails,
641 socketNotifications: adminNotificationsServer2,
642 token: servers[1].accessToken
643 }
644 })
645
646 it('Should not send a notification if transcoding is not enabled', async function () {
647 const { name, uuid } = await uploadVideoByLocalAccount(servers)
648 await waitJobs(servers)
649
650 await checkVideoIsPublished(baseParams, name, uuid, 'absence')
651 })
652
653 it('Should not send a notification if the wait transcoding is false', async function () {
654 this.timeout(50000)
655
656 await uploadVideoByRemoteAccount(servers, { waitTranscoding: false })
657 await waitJobs(servers)
658
659 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
660 if (notification) {
661 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
662 }
663 })
664
665 it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
666 this.timeout(50000)
667
668 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
669 await waitJobs(servers)
670
671 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
672 })
673
674 it('Should send a notification with a transcoded video', async function () {
675 this.timeout(50000)
676
677 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true })
678 await waitJobs(servers)
679
680 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
681 })
682
683 it('Should send a notification when an imported video is transcoded', async function () {
684 this.timeout(50000)
685
686 const name = 'video import ' + uuidv4()
687
688 const attributes = {
689 name,
690 channelId,
691 privacy: VideoPrivacy.PUBLIC,
692 targetUrl: getYoutubeVideoUrl(),
693 waitTranscoding: true
694 }
695 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
696 const uuid = res.body.video.uuid
697
698 await waitJobs(servers)
699 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
700 })
701
702 it('Should send a notification when the scheduled update has been proceeded', async function () {
703 this.timeout(70000)
704
705 // In 2 seconds
706 let updateAt = new Date(new Date().getTime() + 2000)
707
708 const data = {
709 privacy: VideoPrivacy.PRIVATE,
710 scheduleUpdate: {
711 updateAt: updateAt.toISOString(),
712 privacy: VideoPrivacy.PUBLIC
713 }
714 }
715 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
716
717 await wait(6000)
718 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
719 })
720 })
721
722 describe('My video is imported', function () {
723 let baseParams: CheckerBaseParams
724
725 before(() => {
726 baseParams = {
727 server: servers[0],
728 emails,
729 socketNotifications: adminNotifications,
730 token: servers[0].accessToken
731 }
732 })
733
734 it('Should send a notification when the video import failed', async function () {
735 this.timeout(70000)
736
737 const name = 'video import ' + uuidv4()
738
739 const attributes = {
740 name,
741 channelId,
742 privacy: VideoPrivacy.PRIVATE,
743 targetUrl: getBadVideoUrl()
744 }
745 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
746 const uuid = res.body.video.uuid
747
748 await waitJobs(servers)
749 await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence')
750 })
751
752 it('Should send a notification when the video import succeeded', async function () {
753 this.timeout(70000)
754
755 const name = 'video import ' + uuidv4()
756
757 const attributes = {
758 name,
759 channelId,
760 privacy: VideoPrivacy.PRIVATE,
761 targetUrl: getYoutubeVideoUrl()
762 }
763 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
764 const uuid = res.body.video.uuid
765
766 await waitJobs(servers)
767 await checkMyVideoImportIsFinished(baseParams, name, uuid, getYoutubeVideoUrl(), true, 'presence')
768 })
769 })
770
771 describe('New registration', function () {
772 let baseParams: CheckerBaseParams
773
774 before(() => {
775 baseParams = {
776 server: servers[0],
777 emails,
778 socketNotifications: adminNotifications,
779 token: servers[0].accessToken
780 }
781 })
782
783 it('Should send a notification only to moderators when a user registers on the instance', async function () {
784 await registerUser(servers[0].url, 'user_45', 'password')
785
786 await waitJobs(servers)
787
788 await checkUserRegistered(baseParams, 'user_45', 'presence')
789
790 const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
791 await checkUserRegistered(immutableAssign(baseParams, userOverride), 'user_45', 'absence')
792 })
793 })
794
795 describe('New actor follow', function () {
796 let baseParams: CheckerBaseParams
797 let myChannelName = 'super channel name'
798 let myUserName = 'super user name'
799
800 before(async () => {
801 baseParams = {
802 server: servers[0],
803 emails,
804 socketNotifications: userNotifications,
805 token: userAccessToken
806 }
807
808 await updateMyUser({
809 url: servers[0].url,
810 accessToken: servers[0].accessToken,
811 displayName: 'super root name'
812 })
813
814 await updateMyUser({
815 url: servers[0].url,
816 accessToken: userAccessToken,
817 displayName: myUserName
818 })
819
820 await updateMyUser({
821 url: servers[1].url,
822 accessToken: servers[1].accessToken,
823 displayName: 'super root 2 name'
824 })
825
826 await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName })
827 })
828
829 it('Should notify when a local channel is following one of our channel', async function () {
830 this.timeout(10000)
831
832 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
833 await waitJobs(servers)
834
835 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence')
836
837 await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
838 })
839
840 it('Should notify when a remote channel is following one of our channel', async function () {
841 this.timeout(10000)
842
843 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
844 await waitJobs(servers)
845
846 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence')
847
848 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
849 })
850
851 it('Should notify when a local account is following one of our channel', async function () {
852 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001')
853
854 await waitJobs(servers)
855
856 await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
857 })
858
859 it('Should notify when a remote account is following one of our channel', async function () {
860 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001')
861
862 await waitJobs(servers)
863
864 await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
865 })
866 })
867
868 describe('Mark as read', function () {
869 it('Should mark as read some notifications', async function () {
870 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3)
871 const ids = res.body.data.map(n => n.id)
872
873 await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids)
874 })
875
876 it('Should have the notifications marked as read', async function () {
877 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10)
878
879 const notifications = res.body.data as UserNotification[]
880 expect(notifications[ 0 ].read).to.be.false
881 expect(notifications[ 1 ].read).to.be.false
882 expect(notifications[ 2 ].read).to.be.true
883 expect(notifications[ 3 ].read).to.be.true
884 expect(notifications[ 4 ].read).to.be.true
885 expect(notifications[ 5 ].read).to.be.false
886 })
887
888 it('Should only list read notifications', async function () {
889 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false)
890
891 const notifications = res.body.data as UserNotification[]
892 for (const notification of notifications) {
893 expect(notification.read).to.be.true
894 }
895 })
896
897 it('Should only list unread notifications', async function () {
898 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
899
900 const notifications = res.body.data as UserNotification[]
901 for (const notification of notifications) {
902 expect(notification.read).to.be.false
903 }
904 })
905
906 it('Should mark as read all notifications', async function () {
907 await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken)
908
909 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
910
911 expect(res.body.total).to.equal(0)
912 expect(res.body.data).to.have.lengthOf(0)
913 })
914 })
915
916 describe('Notification settings', function () {
917 let baseParams: CheckerBaseParams
918
919 before(() => {
920 baseParams = {
921 server: servers[0],
922 emails,
923 socketNotifications: userNotifications,
924 token: userAccessToken
925 }
926 })
927
928 it('Should not have notifications', async function () {
929 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
930 newVideoFromSubscription: UserNotificationSettingValue.NONE
931 }))
932
933 {
934 const res = await getMyUserInformation(servers[0].url, userAccessToken)
935 const info = res.body as User
936 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
937 }
938
939 const { name, uuid } = await uploadVideoByLocalAccount(servers)
940
941 const check = { web: true, mail: true }
942 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
943 })
944
945 it('Should only have web notifications', async function () {
946 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
947 newVideoFromSubscription: UserNotificationSettingValue.WEB
948 }))
949
950 {
951 const res = await getMyUserInformation(servers[0].url, userAccessToken)
952 const info = res.body as User
953 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB)
954 }
955
956 const { name, uuid } = await uploadVideoByLocalAccount(servers)
957
958 {
959 const check = { mail: true, web: false }
960 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
961 }
962
963 {
964 const check = { mail: false, web: true }
965 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
966 }
967 })
968
969 it('Should only have mail notifications', async function () {
970 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
971 newVideoFromSubscription: UserNotificationSettingValue.EMAIL
972 }))
973
974 {
975 const res = await getMyUserInformation(servers[0].url, userAccessToken)
976 const info = res.body as User
977 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
978 }
979
980 const { name, uuid } = await uploadVideoByLocalAccount(servers)
981
982 {
983 const check = { mail: false, web: true }
984 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
985 }
986
987 {
988 const check = { mail: true, web: false }
989 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
990 }
991 })
992
993 it('Should have email and web notifications', async function () {
994 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
995 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
996 }))
997
998 {
999 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1000 const info = res.body as User
1001 expect(info.notificationSettings.newVideoFromSubscription).to.equal(
1002 UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1003 )
1004 }
1005
1006 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1007
1008 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
1009 })
1010 })
1011
1012 after(async function () {
1013 MockSmtpServer.Instance.kill()
1014
1015 killallServers(servers)
1016 })
1017})
diff --git a/server/tests/api/users/user-subscriptions.ts b/server/tests/api/users/user-subscriptions.ts
index 65b80540c..88a7187d6 100644
--- a/server/tests/api/users/user-subscriptions.ts
+++ b/server/tests/api/users/user-subscriptions.ts
@@ -2,18 +2,27 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { createUser, doubleFollow, flushAndRunMultipleServers, follow, getVideosList, unfollow, updateVideo, userLogin } from '../../utils' 5import {
6import { killallServers, ServerInfo, uploadVideo } from '../../utils/index' 6 createUser,
7import { setAccessTokensToServers } from '../../utils/users/login' 7 doubleFollow,
8 flushAndRunMultipleServers,
9 follow,
10 getVideosList,
11 unfollow,
12 updateVideo,
13 userLogin
14} from '../../../../shared/utils'
15import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
16import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
8import { Video, VideoChannel } from '../../../../shared/models/videos' 17import { Video, VideoChannel } from '../../../../shared/models/videos'
9import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
10import { 19import {
11 addUserSubscription, 20 addUserSubscription,
12 listUserSubscriptions, 21 listUserSubscriptions,
13 listUserSubscriptionVideos, 22 listUserSubscriptionVideos,
14 removeUserSubscription, 23 removeUserSubscription,
15 getUserSubscription, areSubscriptionsExist 24 getUserSubscription, areSubscriptionsExist
16} from '../../utils/users/user-subscriptions' 25} from '../../../../shared/utils/users/user-subscriptions'
17 26
18const expect = chai.expect 27const expect = chai.expect
19 28
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts
index d8699db17..006d6cdf0 100644
--- a/server/tests/api/users/users-multiple-servers.ts
+++ b/server/tests/api/users/users-multiple-servers.ts
@@ -13,13 +13,13 @@ import {
13 removeUser, 13 removeUser,
14 updateMyUser, 14 updateMyUser,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index' 17import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../../../shared/utils/index'
18import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts' 18import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../../../shared/utils/users/accounts'
19import { setAccessTokensToServers } from '../../utils/users/login' 19import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
20import { User } from '../../../../shared/models/users' 20import { User } from '../../../../shared/models/users'
21import { VideoChannel } from '../../../../shared/models/videos' 21import { VideoChannel } from '../../../../shared/models/videos'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23 23
24const expect = chai.expect 24const expect = chai.expect
25 25
diff --git a/server/tests/api/users/users-verification.ts b/server/tests/api/users/users-verification.ts
index fa5f5e371..babeda2b8 100644
--- a/server/tests/api/users/users-verification.ts
+++ b/server/tests/api/users/users-verification.ts
@@ -4,11 +4,11 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 registerUser, flushTests, getUserInformation, getMyUserInformation, killallServers, 6 registerUser, flushTests, getUserInformation, getMyUserInformation, killallServers,
7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig 7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig, wait
8} from '../../utils' 8} from '../../../../shared/utils'
9import { setAccessTokensToServers } from '../../utils/users/login' 9import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
10import { mockSmtpServer } from '../../utils/miscs/email' 10import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
11import { waitJobs } from '../../utils/server/jobs' 11import { waitJobs } from '../../../../shared/utils/server/jobs'
12 12
13const expect = chai.expect 13const expect = chai.expect
14 14
@@ -30,7 +30,7 @@ describe('Test users account verification', function () {
30 before(async function () { 30 before(async function () {
31 this.timeout(30000) 31 this.timeout(30000)
32 32
33 await mockSmtpServer(emails) 33 await MockSmtpServer.Instance.collectEmails(emails)
34 34
35 await flushTests() 35 await flushTests()
36 36
@@ -123,6 +123,7 @@ describe('Test users account verification', function () {
123 }) 123 })
124 124
125 after(async function () { 125 after(async function () {
126 MockSmtpServer.Instance.kill()
126 killallServers([ server ]) 127 killallServers([ server ])
127 128
128 // Keep the logs if the test failed 129 // Keep the logs if the test failed
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index e7bb845b9..ad98ab1c7 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -32,10 +32,10 @@ import {
32 updateUser, 32 updateUser,
33 uploadVideo, 33 uploadVideo,
34 userLogin 34 userLogin
35} from '../../utils/index' 35} from '../../../../shared/utils/index'
36import { follow } from '../../utils/server/follows' 36import { follow } from '../../../../shared/utils/server/follows'
37import { setAccessTokensToServers } from '../../utils/users/login' 37import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
38import { getMyVideos } from '../../utils/videos/videos' 38import { getMyVideos } from '../../../../shared/utils/videos/videos'
39 39
40const expect = chai.expect 40const expect = chai.expect
41 41
@@ -501,10 +501,6 @@ describe('Test users', function () {
501 accessTokenUser = await userLogin(server, user) 501 accessTokenUser = await userLogin(server, user)
502 }) 502 })
503 503
504 it('Should not be able to delete a user by a moderator', async function () {
505 await removeUser(server.url, 2, accessTokenUser, 403)
506 })
507
508 it('Should be able to list video blacklist by a moderator', async function () { 504 it('Should be able to list video blacklist by a moderator', async function () {
509 await getBlacklistedVideosList(server.url, accessTokenUser) 505 await getBlacklistedVideosList(server.url, accessTokenUser)
510 }) 506 })
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts
index 9bdb78491..97f467aae 100644
--- a/server/tests/api/videos/index.ts
+++ b/server/tests/api/videos/index.ts
@@ -3,7 +3,6 @@ import './services'
3import './single-server' 3import './single-server'
4import './video-abuse' 4import './video-abuse'
5import './video-blacklist' 5import './video-blacklist'
6import './video-blacklist-management'
7import './video-captions' 6import './video-captions'
8import './video-change-ownership' 7import './video-change-ownership'
9import './video-channels' 8import './video-channels'
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index b9ace2885..6c281e49e 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -8,6 +8,7 @@ import { VideoPrivacy } from '../../../../shared/models/videos'
8import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 8import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
9import { 9import {
10 addVideoChannel, 10 addVideoChannel,
11 checkTmpIsEmpty,
11 checkVideoFilesWereRemoved, 12 checkVideoFilesWereRemoved,
12 completeVideoCheck, 13 completeVideoCheck,
13 createUser, 14 createUser,
@@ -31,15 +32,15 @@ import {
31 viewVideo, 32 viewVideo,
32 wait, 33 wait,
33 webtorrentAdd 34 webtorrentAdd
34} from '../../utils' 35} from '../../../../shared/utils'
35import { 36import {
36 addVideoCommentReply, 37 addVideoCommentReply,
37 addVideoCommentThread, 38 addVideoCommentThread,
38 deleteVideoComment, 39 deleteVideoComment,
39 getVideoCommentThreads, 40 getVideoCommentThreads,
40 getVideoThreadComments 41 getVideoThreadComments
41} from '../../utils/videos/video-comments' 42} from '../../../../shared/utils/videos/video-comments'
42import { waitJobs } from '../../utils/server/jobs' 43import { waitJobs } from '../../../../shared/utils/server/jobs'
43 44
44const expect = chai.expect 45const expect = chai.expect
45 46
@@ -1008,6 +1009,14 @@ describe('Test multiple servers', function () {
1008 }) 1009 })
1009 }) 1010 })
1010 1011
1012 describe('TMP directory', function () {
1013 it('Should have an empty tmp directory', async function () {
1014 for (const server of servers) {
1015 await checkTmpIsEmpty(server)
1016 }
1017 })
1018 })
1019
1011 after(async function () { 1020 after(async function () {
1012 killallServers(servers) 1021 killallServers(servers)
1013 1022
diff --git a/server/tests/api/videos/services.ts b/server/tests/api/videos/services.ts
index 2f1424292..2da86964f 100644
--- a/server/tests/api/videos/services.ts
+++ b/server/tests/api/videos/services.ts
@@ -2,8 +2,16 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, getOEmbed, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 5import {
6import { runServer } from '../../utils/server/servers' 6 flushTests,
7 getOEmbed,
8 getVideosList,
9 killallServers,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo
13} from '../../../../shared/utils/index'
14import { runServer } from '../../../../shared/utils/server/servers'
7 15
8const expect = chai.expect 16const expect = chai.expect
9 17
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index 089c3df25..069dec67c 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -28,7 +28,7 @@ import {
28 uploadVideo, 28 uploadVideo,
29 viewVideo, 29 viewVideo,
30 wait 30 wait
31} from '../../utils' 31} from '../../../../shared/utils'
32 32
33const expect = chai.expect 33const expect = chai.expect
34 34
diff --git a/server/tests/api/videos/video-abuse.ts b/server/tests/api/videos/video-abuse.ts
index a17f3c8de..3a7b623da 100644
--- a/server/tests/api/videos/video-abuse.ts
+++ b/server/tests/api/videos/video-abuse.ts
@@ -14,9 +14,9 @@ import {
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 updateVideoAbuse, 15 updateVideoAbuse,
16 uploadVideo 16 uploadVideo
17} from '../../utils/index' 17} from '../../../../shared/utils/index'
18import { doubleFollow } from '../../utils/server/follows' 18import { doubleFollow } from '../../../../shared/utils/server/follows'
19import { waitJobs } from '../../utils/server/jobs' 19import { waitJobs } from '../../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-blacklist-management.ts b/server/tests/api/videos/video-blacklist-management.ts
deleted file mode 100644
index fab577b30..000000000
--- a/server/tests/api/videos/video-blacklist-management.ts
+++ /dev/null
@@ -1,192 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import { orderBy } from 'lodash'
5import 'mocha'
6import {
7 addVideoToBlacklist,
8 flushAndRunMultipleServers,
9 getBlacklistedVideosList,
10 getMyVideos,
11 getSortedBlacklistedVideosList,
12 getVideosList,
13 killallServers,
14 removeVideoFromBlacklist,
15 ServerInfo,
16 setAccessTokensToServers,
17 updateVideoBlacklist,
18 uploadVideo
19} from '../../utils/index'
20import { doubleFollow } from '../../utils/server/follows'
21import { waitJobs } from '../../utils/server/jobs'
22import { VideoAbuse } from '../../../../shared/models/videos'
23
24const expect = chai.expect
25
26describe('Test video blacklist management', function () {
27 let servers: ServerInfo[] = []
28 let videoId: number
29
30 async function blacklistVideosOnServer (server: ServerInfo) {
31 const res = await getVideosList(server.url)
32
33 const videos = res.body.data
34 for (let video of videos) {
35 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
36 }
37 }
38
39 before(async function () {
40 this.timeout(50000)
41
42 // Run servers
43 servers = await flushAndRunMultipleServers(2)
44
45 // Get the access tokens
46 await setAccessTokensToServers(servers)
47
48 // Server 1 and server 2 follow each other
49 await doubleFollow(servers[0], servers[1])
50
51 // Upload 2 videos on server 2
52 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' })
53 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' })
54
55 // Wait videos propagation, server 2 has transcoding enabled
56 await waitJobs(servers)
57
58 // Blacklist the two videos on server 1
59 await blacklistVideosOnServer(servers[0])
60 })
61
62 describe('When listing blacklisted videos', function () {
63 it('Should display all the blacklisted videos', async function () {
64 const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken)
65
66 expect(res.body.total).to.equal(2)
67
68 const blacklistedVideos = res.body.data
69 expect(blacklistedVideos).to.be.an('array')
70 expect(blacklistedVideos.length).to.equal(2)
71
72 for (const blacklistedVideo of blacklistedVideos) {
73 expect(blacklistedVideo.reason).to.equal('super reason')
74 videoId = blacklistedVideo.video.id
75 }
76 })
77
78 it('Should get the correct sort when sorting by descending id', async function () {
79 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id')
80 expect(res.body.total).to.equal(2)
81
82 const blacklistedVideos = res.body.data
83 expect(blacklistedVideos).to.be.an('array')
84 expect(blacklistedVideos.length).to.equal(2)
85
86 const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ])
87
88 expect(blacklistedVideos).to.deep.equal(result)
89 })
90
91 it('Should get the correct sort when sorting by descending video name', async function () {
92 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
93 expect(res.body.total).to.equal(2)
94
95 const blacklistedVideos = res.body.data
96 expect(blacklistedVideos).to.be.an('array')
97 expect(blacklistedVideos.length).to.equal(2)
98
99 const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ])
100
101 expect(blacklistedVideos).to.deep.equal(result)
102 })
103
104 it('Should get the correct sort when sorting by ascending creation date', async function () {
105 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
106 expect(res.body.total).to.equal(2)
107
108 const blacklistedVideos = res.body.data
109 expect(blacklistedVideos).to.be.an('array')
110 expect(blacklistedVideos.length).to.equal(2)
111
112 const result = orderBy(res.body.data, [ 'createdAt' ])
113
114 expect(blacklistedVideos).to.deep.equal(result)
115 })
116 })
117
118 describe('When updating blacklisted videos', function () {
119 it('Should change the reason', async function () {
120 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
121
122 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
123 const video = res.body.data.find(b => b.video.id === videoId)
124
125 expect(video.reason).to.equal('my super reason updated')
126 })
127 })
128
129 describe('When listing my videos', function () {
130 it('Should display blacklisted videos', async function () {
131 await blacklistVideosOnServer(servers[1])
132
133 const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5)
134
135 expect(res.body.total).to.equal(2)
136 expect(res.body.data).to.have.lengthOf(2)
137
138 for (const video of res.body.data) {
139 expect(video.blacklisted).to.be.true
140 expect(video.blacklistedReason).to.equal('super reason')
141 }
142 })
143 })
144
145 describe('When removing a blacklisted video', function () {
146 let videoToRemove: VideoAbuse
147 let blacklist = []
148
149 it('Should not have any video in videos list on server 1', async function () {
150 const res = await getVideosList(servers[0].url)
151 expect(res.body.total).to.equal(0)
152 expect(res.body.data).to.be.an('array')
153 expect(res.body.data.length).to.equal(0)
154 })
155
156 it('Should remove a video from the blacklist on server 1', async function () {
157 // Get one video in the blacklist
158 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
159 videoToRemove = res.body.data[0]
160 blacklist = res.body.data.slice(1)
161
162 // Remove it
163 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id)
164 })
165
166 it('Should have the ex-blacklisted video in videos list on server 1', async function () {
167 const res = await getVideosList(servers[0].url)
168 expect(res.body.total).to.equal(1)
169
170 const videos = res.body.data
171 expect(videos).to.be.an('array')
172 expect(videos.length).to.equal(1)
173
174 expect(videos[0].name).to.equal(videoToRemove.video.name)
175 expect(videos[0].id).to.equal(videoToRemove.video.id)
176 })
177
178 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
179 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
180 expect(res.body.total).to.equal(1)
181
182 const videos = res.body.data
183 expect(videos).to.be.an('array')
184 expect(videos.length).to.equal(1)
185 expect(videos).to.deep.equal(blacklist)
186 })
187 })
188
189 after(async function () {
190 killallServers(servers)
191 })
192})
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts
index de4c68f1d..d39ad63b4 100644
--- a/server/tests/api/videos/video-blacklist.ts
+++ b/server/tests/api/videos/video-blacklist.ts
@@ -1,24 +1,43 @@
1/* tslint:disable:no-unused-expression */ 1/* tslint:disable:no-unused-expression */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { orderBy } from 'lodash'
4import 'mocha' 5import 'mocha'
5import { 6import {
6 addVideoToBlacklist, 7 addVideoToBlacklist,
7 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
9 getBlacklistedVideosList,
10 getMyVideos,
11 getSortedBlacklistedVideosList,
8 getVideosList, 12 getVideosList,
9 killallServers, 13 killallServers,
14 removeVideoFromBlacklist,
10 searchVideo, 15 searchVideo,
11 ServerInfo, 16 ServerInfo,
12 setAccessTokensToServers, 17 setAccessTokensToServers,
13 uploadVideo 18 updateVideo,
14} from '../../utils/index' 19 updateVideoBlacklist,
15import { doubleFollow } from '../../utils/server/follows' 20 uploadVideo,
16import { waitJobs } from '../../utils/server/jobs' 21 viewVideo
22} from '../../../../shared/utils/index'
23import { doubleFollow } from '../../../../shared/utils/server/follows'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VideoBlacklist } from '../../../../shared/models/videos'
17 26
18const expect = chai.expect 27const expect = chai.expect
19 28
20describe('Test video blacklists', function () { 29describe('Test video blacklist management', function () {
21 let servers: ServerInfo[] = [] 30 let servers: ServerInfo[] = []
31 let videoId: number
32
33 async function blacklistVideosOnServer (server: ServerInfo) {
34 const res = await getVideosList(server.url)
35
36 const videos = res.body.data
37 for (let video of videos) {
38 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
39 }
40 }
22 41
23 before(async function () { 42 before(async function () {
24 this.timeout(50000) 43 this.timeout(50000)
@@ -32,58 +51,270 @@ describe('Test video blacklists', function () {
32 // Server 1 and server 2 follow each other 51 // Server 1 and server 2 follow each other
33 await doubleFollow(servers[0], servers[1]) 52 await doubleFollow(servers[0], servers[1])
34 53
35 // Upload a video on server 2 54 // Upload 2 videos on server 2
36 const videoAttributes = { 55 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' })
37 name: 'my super name for server 2', 56 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' })
38 description: 'my super description for server 2'
39 }
40 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
41 57
42 // Wait videos propagation, server 2 has transcoding enabled 58 // Wait videos propagation, server 2 has transcoding enabled
43 await waitJobs(servers) 59 await waitJobs(servers)
44 60
45 const res = await getVideosList(servers[0].url) 61 // Blacklist the two videos on server 1
46 const videos = res.body.data 62 await blacklistVideosOnServer(servers[0])
63 })
64
65 describe('When listing/searching videos', function () {
47 66
48 expect(videos.length).to.equal(1) 67 it('Should not have the video blacklisted in videos list/search on server 1', async function () {
68 {
69 const res = await getVideosList(servers[ 0 ].url)
49 70
50 servers[0].remoteVideo = videos.find(video => video.name === 'my super name for server 2') 71 expect(res.body.total).to.equal(0)
72 expect(res.body.data).to.be.an('array')
73 expect(res.body.data.length).to.equal(0)
74 }
75
76 {
77 const res = await searchVideo(servers[ 0 ].url, 'name')
78
79 expect(res.body.total).to.equal(0)
80 expect(res.body.data).to.be.an('array')
81 expect(res.body.data.length).to.equal(0)
82 }
83 })
84
85 it('Should have the blacklisted video in videos list/search on server 2', async function () {
86 {
87 const res = await getVideosList(servers[ 1 ].url)
88
89 expect(res.body.total).to.equal(2)
90 expect(res.body.data).to.be.an('array')
91 expect(res.body.data.length).to.equal(2)
92 }
93
94 {
95 const res = await searchVideo(servers[ 1 ].url, 'video')
96
97 expect(res.body.total).to.equal(2)
98 expect(res.body.data).to.be.an('array')
99 expect(res.body.data.length).to.equal(2)
100 }
101 })
51 }) 102 })
52 103
53 it('Should blacklist a remote video on server 1', async function () { 104 describe('When listing blacklisted videos', function () {
54 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id) 105 it('Should display all the blacklisted videos', async function () {
106 const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken)
107
108 expect(res.body.total).to.equal(2)
109
110 const blacklistedVideos = res.body.data
111 expect(blacklistedVideos).to.be.an('array')
112 expect(blacklistedVideos.length).to.equal(2)
113
114 for (const blacklistedVideo of blacklistedVideos) {
115 expect(blacklistedVideo.reason).to.equal('super reason')
116 videoId = blacklistedVideo.video.id
117 }
118 })
119
120 it('Should get the correct sort when sorting by descending id', async function () {
121 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id')
122 expect(res.body.total).to.equal(2)
123
124 const blacklistedVideos = res.body.data
125 expect(blacklistedVideos).to.be.an('array')
126 expect(blacklistedVideos.length).to.equal(2)
127
128 const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ])
129
130 expect(blacklistedVideos).to.deep.equal(result)
131 })
132
133 it('Should get the correct sort when sorting by descending video name', async function () {
134 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
135 expect(res.body.total).to.equal(2)
136
137 const blacklistedVideos = res.body.data
138 expect(blacklistedVideos).to.be.an('array')
139 expect(blacklistedVideos.length).to.equal(2)
140
141 const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ])
142
143 expect(blacklistedVideos).to.deep.equal(result)
144 })
145
146 it('Should get the correct sort when sorting by ascending creation date', async function () {
147 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
148 expect(res.body.total).to.equal(2)
149
150 const blacklistedVideos = res.body.data
151 expect(blacklistedVideos).to.be.an('array')
152 expect(blacklistedVideos.length).to.equal(2)
153
154 const result = orderBy(res.body.data, [ 'createdAt' ])
155
156 expect(blacklistedVideos).to.deep.equal(result)
157 })
55 }) 158 })
56 159
57 it('Should not have the video blacklisted in videos list on server 1', async function () { 160 describe('When updating blacklisted videos', function () {
58 const res = await getVideosList(servers[0].url) 161 it('Should change the reason', async function () {
162 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
163
164 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
165 const video = res.body.data.find(b => b.video.id === videoId)
59 166
60 expect(res.body.total).to.equal(0) 167 expect(video.reason).to.equal('my super reason updated')
61 expect(res.body.data).to.be.an('array') 168 })
62 expect(res.body.data.length).to.equal(0)
63 }) 169 })
64 170
65 it('Should not have the video blacklisted in videos search on server 1', async function () { 171 describe('When listing my videos', function () {
66 const res = await searchVideo(servers[0].url, 'name') 172 it('Should display blacklisted videos', async function () {
173 await blacklistVideosOnServer(servers[1])
174
175 const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5)
67 176
68 expect(res.body.total).to.equal(0) 177 expect(res.body.total).to.equal(2)
69 expect(res.body.data).to.be.an('array') 178 expect(res.body.data).to.have.lengthOf(2)
70 expect(res.body.data.length).to.equal(0) 179
180 for (const video of res.body.data) {
181 expect(video.blacklisted).to.be.true
182 expect(video.blacklistedReason).to.equal('super reason')
183 }
184 })
71 }) 185 })
72 186
73 it('Should have the blacklisted video in videos list on server 2', async function () { 187 describe('When removing a blacklisted video', function () {
74 const res = await getVideosList(servers[1].url) 188 let videoToRemove: VideoBlacklist
189 let blacklist = []
190
191 it('Should not have any video in videos list on server 1', async function () {
192 const res = await getVideosList(servers[0].url)
193 expect(res.body.total).to.equal(0)
194 expect(res.body.data).to.be.an('array')
195 expect(res.body.data.length).to.equal(0)
196 })
197
198 it('Should remove a video from the blacklist on server 1', async function () {
199 // Get one video in the blacklist
200 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
201 videoToRemove = res.body.data[0]
202 blacklist = res.body.data.slice(1)
203
204 // Remove it
205 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id)
206 })
207
208 it('Should have the ex-blacklisted video in videos list on server 1', async function () {
209 const res = await getVideosList(servers[0].url)
210 expect(res.body.total).to.equal(1)
211
212 const videos = res.body.data
213 expect(videos).to.be.an('array')
214 expect(videos.length).to.equal(1)
215
216 expect(videos[0].name).to.equal(videoToRemove.video.name)
217 expect(videos[0].id).to.equal(videoToRemove.video.id)
218 })
219
220 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
221 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
222 expect(res.body.total).to.equal(1)
75 223
76 expect(res.body.total).to.equal(1) 224 const videos = res.body.data
77 expect(res.body.data).to.be.an('array') 225 expect(videos).to.be.an('array')
78 expect(res.body.data.length).to.equal(1) 226 expect(videos.length).to.equal(1)
227 expect(videos).to.deep.equal(blacklist)
228 })
79 }) 229 })
80 230
81 it('Should have the video blacklisted in videos search on server 2', async function () { 231 describe('When blacklisting local videos', function () {
82 const res = await searchVideo(servers[1].url, 'name') 232 let video3UUID: string
233 let video4UUID: string
234
235 before(async function () {
236 this.timeout(10000)
237
238 {
239 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'Video 3' })
240 video3UUID = res.body.video.uuid
241 }
242 {
243 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'Video 4' })
244 video4UUID = res.body.video.uuid
245 }
246
247 await waitJobs(servers)
248 })
249
250 it('Should blacklist video 3 and keep it federated', async function () {
251 this.timeout(10000)
252
253 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video3UUID, 'super reason', false)
254
255 await waitJobs(servers)
256
257 {
258 const res = await getVideosList(servers[ 0 ].url)
259 expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined
260 }
261
262 {
263 const res = await getVideosList(servers[ 1 ].url)
264 expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined
265 }
266 })
267
268 it('Should unfederate the video', async function () {
269 this.timeout(10000)
270
271 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, 'super reason', true)
272
273 await waitJobs(servers)
274
275 for (const server of servers) {
276 const res = await getVideosList(server.url)
277 expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
278 }
279 })
280
281 it('Should have the video unfederated even after an Update AP message', async function () {
282 this.timeout(10000)
283
284 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, { description: 'super description' })
285
286 await waitJobs(servers)
287
288 for (const server of servers) {
289 const res = await getVideosList(server.url)
290 expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
291 }
292 })
293
294 it('Should have the correct video blacklist unfederate attribute', async function () {
295 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
296
297 const blacklistedVideos: VideoBlacklist[] = res.body.data
298 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID)
299 const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID)
300
301 expect(video3Blacklisted.unfederated).to.be.false
302 expect(video4Blacklisted.unfederated).to.be.true
303 })
304
305 it('Should remove the video from blacklist and refederate the video', async function () {
306 this.timeout(10000)
307
308 await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID)
309
310 await waitJobs(servers)
311
312 for (const server of servers) {
313 const res = await getVideosList(server.url)
314 expect(res.body.data.find(v => v.uuid === video4UUID)).to.not.be.undefined
315 }
316 })
83 317
84 expect(res.body.total).to.equal(1)
85 expect(res.body.data).to.be.an('array')
86 expect(res.body.data.length).to.equal(1)
87 }) 318 })
88 319
89 after(async function () { 320 after(async function () {
diff --git a/server/tests/api/videos/video-captions.ts b/server/tests/api/videos/video-captions.ts
index 6e441410d..57bee713f 100644
--- a/server/tests/api/videos/video-captions.ts
+++ b/server/tests/api/videos/video-captions.ts
@@ -2,10 +2,17 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { checkVideoFilesWereRemoved, doubleFollow, flushAndRunMultipleServers, removeVideo, uploadVideo, wait } from '../../utils' 5import {
6import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 6 checkVideoFilesWereRemoved,
7import { waitJobs } from '../../utils/server/jobs' 7 doubleFollow,
8import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions' 8 flushAndRunMultipleServers,
9 removeVideo,
10 uploadVideo,
11 wait
12} from '../../../../shared/utils'
13import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
14import { waitJobs } from '../../../../shared/utils/server/jobs'
15import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
9import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' 16import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
10 17
11const expect = chai.expect 18const expect = chai.expect
diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts
index 1578a471d..25675a966 100644
--- a/server/tests/api/videos/video-change-ownership.ts
+++ b/server/tests/api/videos/video-change-ownership.ts
@@ -18,8 +18,8 @@ import {
18 uploadVideo, 18 uploadVideo,
19 userLogin, 19 userLogin,
20 getVideo 20 getVideo
21} from '../../utils' 21} from '../../../../shared/utils'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23import { User } from '../../../../shared/models/users' 23import { User } from '../../../../shared/models/users'
24import { VideoDetails } from '../../../../shared/models/videos' 24import { VideoDetails } from '../../../../shared/models/videos'
25 25
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index 41429a3d8..63514d69c 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -13,7 +13,7 @@ import {
13 updateVideoChannelAvatar, 13 updateVideoChannelAvatar,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { 17import {
18 addVideoChannel, 18 addVideoChannel,
19 deleteVideoChannel, 19 deleteVideoChannel,
@@ -26,8 +26,8 @@ import {
26 ServerInfo, 26 ServerInfo,
27 setAccessTokensToServers, 27 setAccessTokensToServers,
28 updateVideoChannel 28 updateVideoChannel
29} from '../../utils/index' 29} from '../../../../shared/utils/index'
30import { waitJobs } from '../../utils/server/jobs' 30import { waitJobs } from '../../../../shared/utils/server/jobs'
31 31
32const expect = chai.expect 32const expect = chai.expect
33 33
diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts
index d6e07c5b3..ce1b17e35 100644
--- a/server/tests/api/videos/video-comments.ts
+++ b/server/tests/api/videos/video-comments.ts
@@ -3,7 +3,7 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 5import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
6import { testImage } from '../../utils' 6import { testImage } from '../../../../shared/utils'
7import { 7import {
8 dateIsValid, 8 dateIsValid,
9 flushTests, 9 flushTests,
@@ -13,14 +13,14 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 updateMyAvatar, 14 updateMyAvatar,
15 uploadVideo 15 uploadVideo
16} from '../../utils/index' 16} from '../../../../shared/utils/index'
17import { 17import {
18 addVideoCommentReply, 18 addVideoCommentReply,
19 addVideoCommentThread, 19 addVideoCommentThread,
20 deleteVideoComment, 20 deleteVideoComment,
21 getVideoCommentThreads, 21 getVideoCommentThreads,
22 getVideoThreadComments 22 getVideoThreadComments
23} from '../../utils/videos/video-comments' 23} from '../../../../shared/utils/videos/video-comments'
24 24
25const expect = chai.expect 25const expect = chai.expect
26 26
diff --git a/server/tests/api/videos/video-description.ts b/server/tests/api/videos/video-description.ts
index dd5cd78c0..cbda0b9a6 100644
--- a/server/tests/api/videos/video-description.ts
+++ b/server/tests/api/videos/video-description.ts
@@ -12,9 +12,9 @@ import {
12 setAccessTokensToServers, 12 setAccessTokensToServers,
13 updateVideo, 13 updateVideo,
14 uploadVideo 14 uploadVideo
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { doubleFollow } from '../../utils/server/follows' 16import { doubleFollow } from '../../../../shared/utils/server/follows'
17import { waitJobs } from '../../utils/server/jobs' 17import { waitJobs } from '../../../../shared/utils/server/jobs'
18 18
19const expect = chai.expect 19const expect = chai.expect
20 20
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index aaee79a4a..cd4988553 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -14,9 +14,9 @@ import {
14 killallServers, 14 killallServers,
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers 16 setAccessTokensToServers
17} from '../../utils' 17} from '../../../../shared/utils'
18import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
19import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../utils/videos/video-imports' 19import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../../../shared/utils/videos/video-imports'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-nsfw.ts b/server/tests/api/videos/video-nsfw.ts
index eab7a6991..df1ee2eb9 100644
--- a/server/tests/api/videos/video-nsfw.ts
+++ b/server/tests/api/videos/video-nsfw.ts
@@ -2,10 +2,17 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 5import {
6import { userLogin } from '../../utils/users/login' 6 flushTests,
7import { createUser } from '../../utils/users/users' 7 getVideosList,
8import { getMyVideos } from '../../utils/videos/videos' 8 killallServers,
9 ServerInfo,
10 setAccessTokensToServers,
11 uploadVideo
12} from '../../../../shared/utils/index'
13import { userLogin } from '../../../../shared/utils/users/login'
14import { createUser } from '../../../../shared/utils/users/users'
15import { getMyVideos } from '../../../../shared/utils/videos/videos'
9import { 16import {
10 getAccountVideos, 17 getAccountVideos,
11 getConfig, 18 getConfig,
@@ -18,7 +25,7 @@ import {
18 searchVideoWithToken, 25 searchVideoWithToken,
19 updateCustomConfig, 26 updateCustomConfig,
20 updateMyUser 27 updateMyUser
21} from '../../utils' 28} from '../../../../shared/utils'
22import { ServerConfig } from '../../../../shared/models' 29import { ServerConfig } from '../../../../shared/models'
23import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 30import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
24import { User } from '../../../../shared/models/users' 31import { User } from '../../../../shared/models/users'
diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts
index 9fefca7e3..0b4e66369 100644
--- a/server/tests/api/videos/video-privacy.ts
+++ b/server/tests/api/videos/video-privacy.ts
@@ -10,12 +10,12 @@ import {
10 ServerInfo, 10 ServerInfo,
11 setAccessTokensToServers, 11 setAccessTokensToServers,
12 uploadVideo 12 uploadVideo
13} from '../../utils/index' 13} from '../../../../shared/utils/index'
14import { doubleFollow } from '../../utils/server/follows' 14import { doubleFollow } from '../../../../shared/utils/server/follows'
15import { userLogin } from '../../utils/users/login' 15import { userLogin } from '../../../../shared/utils/users/login'
16import { createUser } from '../../utils/users/users' 16import { createUser } from '../../../../shared/utils/users/users'
17import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../utils/videos/videos' 17import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/utils/videos/videos'
18import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
19 19
20const expect = chai.expect 20const expect = chai.expect
21 21
diff --git a/server/tests/api/videos/video-schedule-update.ts b/server/tests/api/videos/video-schedule-update.ts
index b226a9d50..632c4244c 100644
--- a/server/tests/api/videos/video-schedule-update.ts
+++ b/server/tests/api/videos/video-schedule-update.ts
@@ -15,8 +15,8 @@ import {
15 updateVideo, 15 updateVideo,
16 uploadVideo, 16 uploadVideo,
17 wait 17 wait
18} from '../../utils' 18} from '../../../../shared/utils'
19import { waitJobs } from '../../utils/server/jobs' 19import { waitJobs } from '../../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index 23920d452..eefd32ef8 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -19,9 +19,9 @@ import {
19 setAccessTokensToServers, 19 setAccessTokensToServers,
20 uploadVideo, 20 uploadVideo,
21 webtorrentAdd 21 webtorrentAdd
22} from '../../utils' 22} from '../../../../shared/utils'
23import { join } from 'path' 23import { extname, join } from 'path'
24import { waitJobs } from '../../utils/server/jobs' 24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' 25import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
26 26
27const expect = chai.expect 27const expect = chai.expect
@@ -321,6 +321,34 @@ describe('Test video transcoding', function () {
321 } 321 }
322 }) 322 })
323 323
324 it('Should accept and transcode additional extensions', async function () {
325 this.timeout(300000)
326
327 for (const fixture of [ 'video_short.mkv', 'video_short.avi' ]) {
328 const videoAttributes = {
329 name: fixture,
330 fixture
331 }
332
333 await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributes)
334
335 await waitJobs(servers)
336
337 for (const server of servers) {
338 const res = await getVideosList(server.url)
339
340 const video = res.body.data.find(v => v.name === videoAttributes.name)
341 const res2 = await getVideo(server.url, video.id)
342 const videoDetails = res2.body
343
344 expect(videoDetails.files).to.have.lengthOf(4)
345
346 const magnetUri = videoDetails.files[ 0 ].magnetUri
347 expect(magnetUri).to.contain('.mp4')
348 }
349 }
350 })
351
324 after(async function () { 352 after(async function () {
325 killallServers(servers) 353 killallServers(servers)
326 }) 354 })
diff --git a/server/tests/api/videos/videos-filter.ts b/server/tests/api/videos/videos-filter.ts
index a7588129f..59e37ad86 100644
--- a/server/tests/api/videos/videos-filter.ts
+++ b/server/tests/api/videos/videos-filter.ts
@@ -13,7 +13,7 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { Video, VideoPrivacy } from '../../../../shared/models/videos' 17import { Video, VideoPrivacy } from '../../../../shared/models/videos'
18import { UserRole } from '../../../../shared/models/users' 18import { UserRole } from '../../../../shared/models/users'
19 19
diff --git a/server/tests/api/videos/videos-history.ts b/server/tests/api/videos/videos-history.ts
index 6d289b288..f654a422b 100644
--- a/server/tests/api/videos/videos-history.ts
+++ b/server/tests/api/videos/videos-history.ts
@@ -3,17 +3,21 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 createUser,
6 flushTests, 7 flushTests,
7 getVideosListWithToken, 8 getVideosListWithToken,
8 getVideoWithToken, 9 getVideoWithToken,
9 killallServers, makePutBodyRequest, 10 killallServers,
10 runServer, searchVideoWithToken, 11 runServer,
12 searchVideoWithToken,
11 ServerInfo, 13 ServerInfo,
12 setAccessTokensToServers, 14 setAccessTokensToServers,
13 uploadVideo 15 updateMyUser,
14} from '../../utils' 16 uploadVideo,
17 userLogin
18} from '../../../../shared/utils'
15import { Video, VideoDetails } from '../../../../shared/models/videos' 19import { Video, VideoDetails } from '../../../../shared/models/videos'
16import { userWatchVideo } from '../../utils/videos/video-history' 20import { listMyVideosHistory, removeMyVideosHistory, userWatchVideo } from '../../../../shared/utils/videos/video-history'
17 21
18const expect = chai.expect 22const expect = chai.expect
19 23
@@ -22,6 +26,8 @@ describe('Test videos history', function () {
22 let video1UUID: string 26 let video1UUID: string
23 let video2UUID: string 27 let video2UUID: string
24 let video3UUID: string 28 let video3UUID: string
29 let video3WatchedDate: Date
30 let userAccessToken: string
25 31
26 before(async function () { 32 before(async function () {
27 this.timeout(30000) 33 this.timeout(30000)
@@ -46,6 +52,13 @@ describe('Test videos history', function () {
46 const res = await uploadVideo(server.url, server.accessToken, { name: 'video 3' }) 52 const res = await uploadVideo(server.url, server.accessToken, { name: 'video 3' })
47 video3UUID = res.body.video.uuid 53 video3UUID = res.body.video.uuid
48 } 54 }
55
56 const user = {
57 username: 'user_1',
58 password: 'super password'
59 }
60 await createUser(server.url, server.accessToken, user.username, user.password)
61 userAccessToken = await userLogin(server, user)
49 }) 62 })
50 63
51 it('Should get videos, without watching history', async function () { 64 it('Should get videos, without watching history', async function () {
@@ -62,8 +75,8 @@ describe('Test videos history', function () {
62 }) 75 })
63 76
64 it('Should watch the first and second video', async function () { 77 it('Should watch the first and second video', async function () {
65 await userWatchVideo(server.url, server.accessToken, video1UUID, 3)
66 await userWatchVideo(server.url, server.accessToken, video2UUID, 8) 78 await userWatchVideo(server.url, server.accessToken, video2UUID, 8)
79 await userWatchVideo(server.url, server.accessToken, video1UUID, 3)
67 }) 80 })
68 81
69 it('Should return the correct history when listing, searching and getting videos', async function () { 82 it('Should return the correct history when listing, searching and getting videos', async function () {
@@ -117,6 +130,68 @@ describe('Test videos history', function () {
117 } 130 }
118 }) 131 })
119 132
133 it('Should have these videos when listing my history', async function () {
134 video3WatchedDate = new Date()
135 await userWatchVideo(server.url, server.accessToken, video3UUID, 2)
136
137 const res = await listMyVideosHistory(server.url, server.accessToken)
138
139 expect(res.body.total).to.equal(3)
140
141 const videos: Video[] = res.body.data
142 expect(videos[0].name).to.equal('video 3')
143 expect(videos[1].name).to.equal('video 1')
144 expect(videos[2].name).to.equal('video 2')
145 })
146
147 it('Should not have videos history on another user', async function () {
148 const res = await listMyVideosHistory(server.url, userAccessToken)
149
150 expect(res.body.total).to.equal(0)
151 expect(res.body.data).to.have.lengthOf(0)
152 })
153
154 it('Should clear my history', async function () {
155 await removeMyVideosHistory(server.url, server.accessToken, video3WatchedDate.toISOString())
156 })
157
158 it('Should have my history cleared', async function () {
159 const res = await listMyVideosHistory(server.url, server.accessToken)
160
161 expect(res.body.total).to.equal(1)
162
163 const videos: Video[] = res.body.data
164 expect(videos[0].name).to.equal('video 3')
165 })
166
167 it('Should disable videos history', async function () {
168 await updateMyUser({
169 url: server.url,
170 accessToken: server.accessToken,
171 videosHistoryEnabled: false
172 })
173
174 await userWatchVideo(server.url, server.accessToken, video2UUID, 8, 409)
175 })
176
177 it('Should re-enable videos history', async function () {
178 await updateMyUser({
179 url: server.url,
180 accessToken: server.accessToken,
181 videosHistoryEnabled: true
182 })
183
184 await userWatchVideo(server.url, server.accessToken, video1UUID, 8)
185
186 const res = await listMyVideosHistory(server.url, server.accessToken)
187
188 expect(res.body.total).to.equal(2)
189
190 const videos: Video[] = res.body.data
191 expect(videos[0].name).to.equal('video 1')
192 expect(videos[1].name).to.equal('video 3')
193 })
194
120 after(async function () { 195 after(async function () {
121 killallServers([ server ]) 196 killallServers([ server ])
122 197
diff --git a/server/tests/api/videos/videos-overview.ts b/server/tests/api/videos/videos-overview.ts
index 7d1f29c92..7221bcae6 100644
--- a/server/tests/api/videos/videos-overview.ts
+++ b/server/tests/api/videos/videos-overview.ts
@@ -2,8 +2,8 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils' 5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../../../shared/utils'
6import { getVideosOverview } from '../../utils/overviews/overviews' 6import { getVideosOverview } from '../../../../shared/utils/overviews/overviews'
7import { VideosOverview } from '../../../../shared/models/overviews' 7import { VideosOverview } from '../../../../shared/models/overviews'
8 8
9const expect = chai.expect 9const expect = chai.expect
diff --git a/server/tests/cli/create-import-video-file-job.ts b/server/tests/cli/create-import-video-file-job.ts
index 13bcfd209..4acda47b1 100644
--- a/server/tests/cli/create-import-video-file-job.ts
+++ b/server/tests/cli/create-import-video-file-job.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo 17 uploadVideo
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/cli/create-transcoding-job.ts b/server/tests/cli/create-transcoding-job.ts
index c2e3840c5..50be5fa19 100644
--- a/server/tests/cli/create-transcoding-job.ts
+++ b/server/tests/cli/create-transcoding-job.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo, wait 17 uploadVideo, wait
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/cli/index.ts b/server/tests/cli/index.ts
index 6201314ce..c6b7ec078 100644
--- a/server/tests/cli/index.ts
+++ b/server/tests/cli/index.ts
@@ -1,6 +1,7 @@
1// Order of the tests we want to execute 1// Order of the tests we want to execute
2import './create-import-video-file-job' 2import './create-import-video-file-job'
3import './create-transcoding-job' 3import './create-transcoding-job'
4import './optimize-old-videos'
4import './peertube' 5import './peertube'
5import './reset-password' 6import './reset-password'
6import './update-host' 7import './update-host'
diff --git a/server/tests/cli/optimize-old-videos.ts b/server/tests/cli/optimize-old-videos.ts
index 66dd39cce..6f6bc25a6 100644
--- a/server/tests/cli/optimize-old-videos.ts
+++ b/server/tests/cli/optimize-old-videos.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo, viewVideo, wait 17 uploadVideo, viewVideo, wait
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils' 20import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils'
21import { VIDEO_TRANSCODING_FPS } from '../../initializers' 21import { VIDEO_TRANSCODING_FPS } from '../../initializers'
22import { join } from 'path' 22import { join } from 'path'
diff --git a/server/tests/cli/peertube.ts b/server/tests/cli/peertube.ts
index 7a712bc4e..e2836d0c3 100644
--- a/server/tests/cli/peertube.ts
+++ b/server/tests/cli/peertube.ts
@@ -11,7 +11,7 @@ import {
11 runServer, 11 runServer,
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers 13 setAccessTokensToServers
14} from '../utils' 14} from '../../../shared/utils'
15 15
16describe('Test CLI wrapper', function () { 16describe('Test CLI wrapper', function () {
17 let server: ServerInfo 17 let server: ServerInfo
diff --git a/server/tests/cli/reset-password.ts b/server/tests/cli/reset-password.ts
index bf937d1c0..1b65f7e39 100644
--- a/server/tests/cli/reset-password.ts
+++ b/server/tests/cli/reset-password.ts
@@ -10,7 +10,7 @@ import {
10 runServer, 10 runServer,
11 ServerInfo, 11 ServerInfo,
12 setAccessTokensToServers 12 setAccessTokensToServers
13} from '../utils' 13} from '../../../shared/utils'
14 14
15describe('Test reset password scripts', function () { 15describe('Test reset password scripts', function () {
16 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts
index b89e72ab7..811ea6a9f 100644
--- a/server/tests/cli/update-host.ts
+++ b/server/tests/cli/update-host.ts
@@ -3,8 +3,8 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoDetails } from '../../../shared/models/videos' 5import { VideoDetails } from '../../../shared/models/videos'
6import { waitJobs } from '../utils/server/jobs' 6import { waitJobs } from '../../../shared/utils/server/jobs'
7import { addVideoCommentThread } from '../utils/videos/video-comments' 7import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
8import { 8import {
9 addVideoChannel, 9 addVideoChannel,
10 createUser, 10 createUser,
@@ -21,8 +21,8 @@ import {
21 ServerInfo, 21 ServerInfo,
22 setAccessTokensToServers, 22 setAccessTokensToServers,
23 uploadVideo 23 uploadVideo
24} from '../utils' 24} from '../../../shared/utils'
25import { getAccountsList } from '../utils/users/accounts' 25import { getAccountsList } from '../../../shared/utils/users/accounts'
26 26
27const expect = chai.expect 27const expect = chai.expect
28 28
diff --git a/server/tests/client.ts b/server/tests/client.ts
index b33a653b1..06b4a9c5a 100644
--- a/server/tests/client.ts
+++ b/server/tests/client.ts
@@ -15,7 +15,7 @@ import {
15 updateCustomConfig, 15 updateCustomConfig,
16 updateCustomSubConfig, 16 updateCustomSubConfig,
17 uploadVideo 17 uploadVideo
18} from './utils' 18} from '../../shared/utils'
19 19
20const expect = chai.expect 20const expect = chai.expect
21 21
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 28fe3493b..a771474bc 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -13,10 +13,10 @@ import {
13 ServerInfo, 13 ServerInfo,
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 uploadVideo, userLogin 15 uploadVideo, userLogin
16} from '../utils' 16} from '../../../shared/utils'
17import * as libxmljs from 'libxmljs' 17import * as libxmljs from 'libxmljs'
18import { addVideoCommentThread } from '../utils/videos/video-comments' 18import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20import { User } from '../../../shared/models/users' 20import { User } from '../../../shared/models/users'
21 21
22chai.use(require('chai-xml')) 22chai.use(require('chai-xml'))
diff --git a/server/tests/fixtures/video_short.avi b/server/tests/fixtures/video_short.avi
new file mode 100644
index 000000000..88979cab2
--- /dev/null
+++ b/server/tests/fixtures/video_short.avi
Binary files differ
diff --git a/server/tests/fixtures/video_short.mkv b/server/tests/fixtures/video_short.mkv
new file mode 100644
index 000000000..a67f4f806
--- /dev/null
+++ b/server/tests/fixtures/video_short.mkv
Binary files differ
diff --git a/server/tests/fixtures/video_short_240p.mp4 b/server/tests/fixtures/video_short_240p.mp4
new file mode 100644
index 000000000..db074940b
--- /dev/null
+++ b/server/tests/fixtures/video_short_240p.mp4
Binary files differ
diff --git a/server/tests/helpers/comment-model.ts b/server/tests/helpers/comment-model.ts
new file mode 100644
index 000000000..76bb0f212
--- /dev/null
+++ b/server/tests/helpers/comment-model.ts
@@ -0,0 +1,25 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { VideoCommentModel } from '../../models/video/video-comment'
6
7const expect = chai.expect
8
9class CommentMock {
10 text: string
11
12 extractMentions = VideoCommentModel.prototype.extractMentions
13}
14
15describe('Comment model', function () {
16 it('Should correctly extract mentions', async function () {
17 const comment = new CommentMock()
18
19 comment.text = '@florian @jean@localhost:9000 @flo @another@localhost:9000 @flo2@jean.com hello ' +
20 'email@localhost:9000 coucou.com no? @chocobozzz @chocobozzz @end'
21 const result = comment.extractMentions().sort()
22
23 expect(result).to.deep.equal([ 'another', 'chocobozzz', 'end', 'flo', 'florian', 'jean' ])
24 })
25})
diff --git a/server/tests/helpers/core-utils.ts b/server/tests/helpers/core-utils.ts
index a6d829a9f..e604cf7e3 100644
--- a/server/tests/helpers/core-utils.ts
+++ b/server/tests/helpers/core-utils.ts
@@ -2,13 +2,16 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { snakeCase, isNumber } from 'lodash'
5import { 6import {
6 parseBytes 7 parseBytes, objectConverter
7} from '../../helpers/core-utils' 8} from '../../helpers/core-utils'
9import { isNumeric } from 'validator'
8 10
9const expect = chai.expect 11const expect = chai.expect
10 12
11describe('Parse Bytes', function () { 13describe('Parse Bytes', function () {
14
12 it('Should pass when given valid value', async function () { 15 it('Should pass when given valid value', async function () {
13 // just return it 16 // just return it
14 expect(parseBytes(1024)).to.be.eq(1024) 17 expect(parseBytes(1024)).to.be.eq(1024)
@@ -45,4 +48,51 @@ describe('Parse Bytes', function () {
45 it('Should be invalid when given invalid value', async function () { 48 it('Should be invalid when given invalid value', async function () {
46 expect(parseBytes('6GB 1GB')).to.be.eq(6) 49 expect(parseBytes('6GB 1GB')).to.be.eq(6)
47 }) 50 })
51
52 it('Should convert an object', async function () {
53 function keyConverter (k: string) {
54 return snakeCase(k)
55 }
56
57 function valueConverter (v: any) {
58 if (isNumeric(v + '')) return parseInt('' + v, 10)
59
60 return v
61 }
62
63 const obj = {
64 mySuperKey: 'hello',
65 mySuper2Key: '45',
66 mySuper3Key: {
67 mySuperSubKey: '15',
68 mySuperSub2Key: 'hello',
69 mySuperSub3Key: [ '1', 'hello', 2 ],
70 mySuperSub4Key: 4
71 },
72 mySuper4Key: 45,
73 toto: {
74 super_key: '15',
75 superKey2: 'hello'
76 },
77 super_key: {
78 superKey4: 15
79 }
80 }
81
82 const res = objectConverter(obj, keyConverter, valueConverter)
83
84 expect(res.my_super_key).to.equal('hello')
85 expect(res.my_super_2_key).to.equal(45)
86 expect(res.my_super_3_key.my_super_sub_key).to.equal(15)
87 expect(res.my_super_3_key.my_super_sub_2_key).to.equal('hello')
88 expect(res.my_super_3_key.my_super_sub_3_key).to.deep.equal([ 1, 'hello', 2 ])
89 expect(res.my_super_3_key.my_super_sub_4_key).to.equal(4)
90 expect(res.toto.super_key).to.equal(15)
91 expect(res.toto.super_key_2).to.equal('hello')
92 expect(res.super_key.super_key_4).to.equal(15)
93
94 // Immutable
95 expect(res.mySuperKey).to.be.undefined
96 expect(obj['my_super_key']).to.be.undefined
97 })
48}) 98})
diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts
index 40c7dc70e..551208245 100644
--- a/server/tests/helpers/index.ts
+++ b/server/tests/helpers/index.ts
@@ -1 +1,2 @@
1import './core-utils' 1import './core-utils'
2import './comment-model'
diff --git a/server/tests/misc-endpoints.ts b/server/tests/misc-endpoints.ts
index 8fab20971..5f82719da 100644
--- a/server/tests/misc-endpoints.ts
+++ b/server/tests/misc-endpoints.ts
@@ -2,7 +2,18 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo } from './utils' 5import {
6 addVideoChannel,
7 createUser,
8 flushTests,
9 killallServers,
10 makeGetRequest,
11 runServer,
12 ServerInfo,
13 setAccessTokensToServers,
14 uploadVideo
15} from '../../shared/utils'
16import { VideoPrivacy } from '../../shared/models/videos'
6 17
7const expect = chai.expect 18const expect = chai.expect
8 19
@@ -15,6 +26,7 @@ describe('Test misc endpoints', function () {
15 await flushTests() 26 await flushTests()
16 27
17 server = await runServer(1) 28 server = await runServer(1)
29 await setAccessTokensToServers([ server ])
18 }) 30 })
19 31
20 describe('Test a well known endpoints', function () { 32 describe('Test a well known endpoints', function () {
@@ -60,6 +72,16 @@ describe('Test misc endpoints', function () {
60 72
61 expect(res.body.tracking).to.equal('N') 73 expect(res.body.tracking).to.equal('N')
62 }) 74 })
75
76 it('Should get change-password location', async function () {
77 const res = await makeGetRequest({
78 url: server.url,
79 path: '/.well-known/change-password',
80 statusCodeExpected: 302
81 })
82
83 expect(res.header.location).to.equal('/my-account/settings')
84 })
63 }) 85 })
64 86
65 describe('Test classic static endpoints', function () { 87 describe('Test classic static endpoints', function () {
@@ -93,6 +115,64 @@ describe('Test misc endpoints', function () {
93 }) 115 })
94 }) 116 })
95 117
118 describe('Test bots endpoints', function () {
119
120 it('Should get the empty sitemap', async function () {
121 const res = await makeGetRequest({
122 url: server.url,
123 path: '/sitemap.xml',
124 statusCodeExpected: 200
125 })
126
127 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
128 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
129 })
130
131 it('Should get the empty cached sitemap', async function () {
132 const res = await makeGetRequest({
133 url: server.url,
134 path: '/sitemap.xml',
135 statusCodeExpected: 200
136 })
137
138 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
139 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
140 })
141
142 it('Should add videos, channel and accounts and get sitemap', async function () {
143 this.timeout(35000)
144
145 await uploadVideo(server.url, server.accessToken, { name: 'video 1', nsfw: false })
146 await uploadVideo(server.url, server.accessToken, { name: 'video 2', nsfw: false })
147 await uploadVideo(server.url, server.accessToken, { name: 'video 3', privacy: VideoPrivacy.PRIVATE })
148
149 await addVideoChannel(server.url, server.accessToken, { name: 'channel1', displayName: 'channel 1' })
150 await addVideoChannel(server.url, server.accessToken, { name: 'channel2', displayName: 'channel 2' })
151
152 await createUser(server.url, server.accessToken, 'user1', 'password')
153 await createUser(server.url, server.accessToken, 'user2', 'password')
154
155 const res = await makeGetRequest({
156 url: server.url,
157 path: '/sitemap.xml?t=1', // avoid using cache
158 statusCodeExpected: 200
159 })
160
161 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
162 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
163
164 expect(res.text).to.contain('<video:title><![CDATA[video 1]]></video:title>')
165 expect(res.text).to.contain('<video:title><![CDATA[video 2]]></video:title>')
166 expect(res.text).to.not.contain('<video:title><![CDATA[video 3]]></video:title>')
167
168 expect(res.text).to.contain('<url><loc>http://localhost:9001/video-channels/channel1</loc></url>')
169 expect(res.text).to.contain('<url><loc>http://localhost:9001/video-channels/channel2</loc></url>')
170
171 expect(res.text).to.contain('<url><loc>http://localhost:9001/accounts/user1</loc></url>')
172 expect(res.text).to.contain('<url><loc>http://localhost:9001/accounts/user2</loc></url>')
173 })
174 })
175
96 after(async function () { 176 after(async function () {
97 killallServers([ server ]) 177 killallServers([ server ])
98 }) 178 })
diff --git a/server/tests/real-world/populate-database.ts b/server/tests/real-world/populate-database.ts
index a7fdbd1dc..016503498 100644
--- a/server/tests/real-world/populate-database.ts
+++ b/server/tests/real-world/populate-database.ts
@@ -10,7 +10,7 @@ import {
10 ServerInfo, 10 ServerInfo,
11 setAccessTokensToServers, 11 setAccessTokensToServers,
12 uploadVideo 12 uploadVideo
13} from '../utils' 13} from '../../../shared/utils'
14import * as Bluebird from 'bluebird' 14import * as Bluebird from 'bluebird'
15 15
16start() 16start()
diff --git a/server/tests/real-world/real-world.ts b/server/tests/real-world/real-world.ts
index a96469b11..ac3baaf9a 100644
--- a/server/tests/real-world/real-world.ts
+++ b/server/tests/real-world/real-world.ts
@@ -16,8 +16,8 @@ import {
16 updateVideo, 16 updateVideo,
17 uploadVideo, viewVideo, 17 uploadVideo, viewVideo,
18 wait 18 wait
19} from '../utils' 19} from '../../../shared/utils'
20import { getJobsListPaginationAndSort } from '../utils/server/jobs' 20import { getJobsListPaginationAndSort } from '../../../shared/utils/server/jobs'
21 21
22interface ServerInfo extends DefaultServerInfo { 22interface ServerInfo extends DefaultServerInfo {
23 requestsNumber: number 23 requestsNumber: number
diff --git a/server/tests/utils/cli/cli.ts b/server/tests/utils/cli/cli.ts
deleted file mode 100644
index 54d05e9c6..000000000
--- a/server/tests/utils/cli/cli.ts
+++ /dev/null
@@ -1,24 +0,0 @@
1import { exec } from 'child_process'
2
3import { ServerInfo } from '../server/servers'
4
5function getEnvCli (server?: ServerInfo) {
6 return `NODE_ENV=test NODE_APP_INSTANCE=${server.serverNumber}`
7}
8
9async function execCLI (command: string) {
10 return new Promise<string>((res, rej) => {
11 exec(command, (err, stdout, stderr) => {
12 if (err) return rej(err)
13
14 return res(stdout)
15 })
16 })
17}
18
19// ---------------------------------------------------------------------------
20
21export {
22 execCLI,
23 getEnvCli
24}
diff --git a/server/tests/utils/feeds/feeds.ts b/server/tests/utils/feeds/feeds.ts
deleted file mode 100644
index af6df2b20..000000000
--- a/server/tests/utils/feeds/feeds.ts
+++ /dev/null
@@ -1,32 +0,0 @@
1import * as request from 'supertest'
2
3type FeedType = 'videos' | 'video-comments'
4
5function getXMLfeed (url: string, feed: FeedType, format?: string) {
6 const path = '/feeds/' + feed + '.xml'
7
8 return request(url)
9 .get(path)
10 .query((format) ? { format: format } : {})
11 .set('Accept', 'application/xml')
12 .expect(200)
13 .expect('Content-Type', /xml/)
14}
15
16function getJSONfeed (url: string, feed: FeedType, query: any = {}) {
17 const path = '/feeds/' + feed + '.json'
18
19 return request(url)
20 .get(path)
21 .query(query)
22 .set('Accept', 'application/json')
23 .expect(200)
24 .expect('Content-Type', /json/)
25}
26
27// ---------------------------------------------------------------------------
28
29export {
30 getXMLfeed,
31 getJSONfeed
32}
diff --git a/server/tests/utils/index.ts b/server/tests/utils/index.ts
deleted file mode 100644
index 8349631c9..000000000
--- a/server/tests/utils/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
1export * from './server/activitypub'
2export * from './cli/cli'
3export * from './server/clients'
4export * from './server/config'
5export * from './users/login'
6export * from './miscs/miscs'
7export * from './miscs/stubs'
8export * from './server/follows'
9export * from './requests/requests'
10export * from './server/servers'
11export * from './videos/services'
12export * from './users/users'
13export * from './videos/video-abuses'
14export * from './videos/video-blacklist'
15export * from './videos/video-channels'
16export * from './videos/videos'
17export * from './videos/video-change-ownership'
18export * from './feeds/feeds'
19export * from './search/videos'
diff --git a/server/tests/utils/miscs/email.ts b/server/tests/utils/miscs/email.ts
deleted file mode 100644
index 21accd09d..000000000
--- a/server/tests/utils/miscs/email.ts
+++ /dev/null
@@ -1,25 +0,0 @@
1import * as MailDev from 'maildev'
2
3function mockSmtpServer (emailsCollection: object[]) {
4 const maildev = new MailDev({
5 ip: '127.0.0.1',
6 smtp: 1025,
7 disableWeb: true,
8 silent: true
9 })
10 maildev.on('new', email => emailsCollection.push(email))
11
12 return new Promise((res, rej) => {
13 maildev.listen(err => {
14 if (err) return rej(err)
15
16 return res()
17 })
18 })
19}
20
21// ---------------------------------------------------------------------------
22
23export {
24 mockSmtpServer
25}
diff --git a/server/tests/utils/miscs/miscs.ts b/server/tests/utils/miscs/miscs.ts
deleted file mode 100644
index 589daa420..000000000
--- a/server/tests/utils/miscs/miscs.ts
+++ /dev/null
@@ -1,101 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import { isAbsolute, join } from 'path'
5import * as request from 'supertest'
6import * as WebTorrent from 'webtorrent'
7import { pathExists, readFile } from 'fs-extra'
8import * as ffmpeg from 'fluent-ffmpeg'
9
10const expect = chai.expect
11let webtorrent = new WebTorrent()
12
13function immutableAssign <T, U> (target: T, source: U) {
14 return Object.assign<{}, T, U>({}, target, source)
15}
16
17 // Default interval -> 5 minutes
18function dateIsValid (dateString: string, interval = 300000) {
19 const dateToCheck = new Date(dateString)
20 const now = new Date()
21
22 return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval
23}
24
25function wait (milliseconds: number) {
26 return new Promise(resolve => setTimeout(resolve, milliseconds))
27}
28
29function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
30 if (refreshWebTorrent === true) webtorrent = new WebTorrent()
31
32 return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
33}
34
35function root () {
36 // We are in server/tests/utils/miscs
37 return join(__dirname, '..', '..', '..', '..')
38}
39
40async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
41 const res = await request(url)
42 .get(imagePath)
43 .expect(200)
44
45 const body = res.body
46
47 const data = await readFile(join(__dirname, '..', '..', 'fixtures', imageName + extension))
48 const minLength = body.length - ((20 * body.length) / 100)
49 const maxLength = body.length + ((20 * body.length) / 100)
50
51 expect(data.length).to.be.above(minLength)
52 expect(data.length).to.be.below(maxLength)
53}
54
55function buildAbsoluteFixturePath (path: string, customTravisPath = false) {
56 if (isAbsolute(path)) {
57 return path
58 }
59
60 if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path)
61
62 return join(__dirname, '..', '..', 'fixtures', path)
63}
64
65async function generateHighBitrateVideo () {
66 const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
67
68 const exists = await pathExists(tempFixturePath)
69 if (!exists) {
70
71 // Generate a random, high bitrate video on the fly, so we don't have to include
72 // a large file in the repo. The video needs to have a certain minimum length so
73 // that FFmpeg properly applies bitrate limits.
74 // https://stackoverflow.com/a/15795112
75 return new Promise<string>(async (res, rej) => {
76 ffmpeg()
77 .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
78 .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
79 .outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
80 .output(tempFixturePath)
81 .on('error', rej)
82 .on('end', () => res(tempFixturePath))
83 .run()
84 })
85 }
86
87 return tempFixturePath
88}
89
90// ---------------------------------------------------------------------------
91
92export {
93 dateIsValid,
94 wait,
95 webtorrentAdd,
96 immutableAssign,
97 testImage,
98 buildAbsoluteFixturePath,
99 root,
100 generateHighBitrateVideo
101}
diff --git a/server/tests/utils/miscs/sql.ts b/server/tests/utils/miscs/sql.ts
deleted file mode 100644
index 027f78131..000000000
--- a/server/tests/utils/miscs/sql.ts
+++ /dev/null
@@ -1,38 +0,0 @@
1import * as Sequelize from 'sequelize'
2
3function getSequelize (serverNumber: number) {
4 const dbname = 'peertube_test' + serverNumber
5 const username = 'peertube'
6 const password = 'peertube'
7 const host = 'localhost'
8 const port = 5432
9
10 return new Sequelize(dbname, username, password, {
11 dialect: 'postgres',
12 host,
13 port,
14 operatorsAliases: false,
15 logging: false
16 })
17}
18
19function setActorField (serverNumber: number, to: string, field: string, value: string) {
20 const seq = getSequelize(serverNumber)
21
22 const options = { type: Sequelize.QueryTypes.UPDATE }
23
24 return seq.query(`UPDATE actor SET "${field}" = '${value}' WHERE url = '${to}'`, options)
25}
26
27function setVideoField (serverNumber: number, uuid: string, field: string, value: string) {
28 const seq = getSequelize(serverNumber)
29
30 const options = { type: Sequelize.QueryTypes.UPDATE }
31
32 return seq.query(`UPDATE video SET "${field}" = '${value}' WHERE uuid = '${uuid}'`, options)
33}
34
35export {
36 setVideoField,
37 setActorField
38}
diff --git a/server/tests/utils/miscs/stubs.ts b/server/tests/utils/miscs/stubs.ts
deleted file mode 100644
index d1eb0e3b2..000000000
--- a/server/tests/utils/miscs/stubs.ts
+++ /dev/null
@@ -1,14 +0,0 @@
1function buildRequestStub (): any {
2 return { }
3}
4
5function buildResponseStub (): any {
6 return {
7 locals: {}
8 }
9}
10
11export {
12 buildResponseStub,
13 buildRequestStub
14}
diff --git a/server/tests/utils/overviews/overviews.ts b/server/tests/utils/overviews/overviews.ts
deleted file mode 100644
index 23e3ceb1e..000000000
--- a/server/tests/utils/overviews/overviews.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1import { makeGetRequest } from '../requests/requests'
2
3function getVideosOverview (url: string, useCache = false) {
4 const path = '/api/v1/overviews/videos'
5
6 const query = {
7 t: useCache ? undefined : new Date().getTime()
8 }
9
10 return makeGetRequest({
11 url,
12 path,
13 query,
14 statusCodeExpected: 200
15 })
16}
17
18export { getVideosOverview }
diff --git a/server/tests/utils/requests/activitypub.ts b/server/tests/utils/requests/activitypub.ts
deleted file mode 100644
index 96fee60a8..000000000
--- a/server/tests/utils/requests/activitypub.ts
+++ /dev/null
@@ -1,43 +0,0 @@
1import { doRequest } from '../../../helpers/requests'
2import { HTTP_SIGNATURE } from '../../../initializers'
3import { buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
4import { activityPubContextify } from '../../../helpers/activitypub'
5
6function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) {
7 const options = {
8 method: 'POST',
9 uri: url,
10 json: body,
11 httpSignature,
12 headers
13 }
14
15 return doRequest(options)
16}
17
18async function makeFollowRequest (to: { url: string }, by: { url: string, privateKey }) {
19 const follow = {
20 type: 'Follow',
21 id: by.url + '/toto',
22 actor: by.url,
23 object: to.url
24 }
25
26 const body = activityPubContextify(follow)
27
28 const httpSignature = {
29 algorithm: HTTP_SIGNATURE.ALGORITHM,
30 authorizationHeaderName: HTTP_SIGNATURE.HEADER_NAME,
31 keyId: by.url,
32 key: by.privateKey,
33 headers: HTTP_SIGNATURE.HEADERS_TO_SIGN
34 }
35 const headers = buildGlobalHeaders(body)
36
37 return makePOSTAPRequest(to.url, body, httpSignature, headers)
38}
39
40export {
41 makePOSTAPRequest,
42 makeFollowRequest
43}
diff --git a/server/tests/utils/requests/check-api-params.ts b/server/tests/utils/requests/check-api-params.ts
deleted file mode 100644
index a2a549682..000000000
--- a/server/tests/utils/requests/check-api-params.ts
+++ /dev/null
@@ -1,40 +0,0 @@
1import { makeGetRequest } from './requests'
2import { immutableAssign } from '../miscs/miscs'
3
4function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
5 return makeGetRequest({
6 url,
7 path,
8 token,
9 query: immutableAssign(query, { start: 'hello' }),
10 statusCodeExpected: 400
11 })
12}
13
14function checkBadCountPagination (url: string, path: string, token?: string, query = {}) {
15 return makeGetRequest({
16 url,
17 path,
18 token,
19 query: immutableAssign(query, { count: 'hello' }),
20 statusCodeExpected: 400
21 })
22}
23
24function checkBadSortPagination (url: string, path: string, token?: string, query = {}) {
25 return makeGetRequest({
26 url,
27 path,
28 token,
29 query: immutableAssign(query, { sort: 'hello' }),
30 statusCodeExpected: 400
31 })
32}
33
34// ---------------------------------------------------------------------------
35
36export {
37 checkBadStartPagination,
38 checkBadCountPagination,
39 checkBadSortPagination
40}
diff --git a/server/tests/utils/requests/requests.ts b/server/tests/utils/requests/requests.ts
deleted file mode 100644
index 5796540f7..000000000
--- a/server/tests/utils/requests/requests.ts
+++ /dev/null
@@ -1,168 +0,0 @@
1import * as request from 'supertest'
2import { buildAbsoluteFixturePath } from '../miscs/miscs'
3import { isAbsolute, join } from 'path'
4
5function makeGetRequest (options: {
6 url: string,
7 path: string,
8 query?: any,
9 token?: string,
10 statusCodeExpected?: number,
11 contentType?: string
12}) {
13 if (!options.statusCodeExpected) options.statusCodeExpected = 400
14 if (options.contentType === undefined) options.contentType = 'application/json'
15
16 const req = request(options.url)
17 .get(options.path)
18
19 if (options.contentType) req.set('Accept', options.contentType)
20 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
21 if (options.query) req.query(options.query)
22
23 return req.expect(options.statusCodeExpected)
24}
25
26function makeDeleteRequest (options: {
27 url: string,
28 path: string,
29 token?: string,
30 statusCodeExpected?: number
31}) {
32 if (!options.statusCodeExpected) options.statusCodeExpected = 400
33
34 const req = request(options.url)
35 .delete(options.path)
36 .set('Accept', 'application/json')
37
38 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
39
40 return req.expect(options.statusCodeExpected)
41}
42
43function makeUploadRequest (options: {
44 url: string,
45 method?: 'POST' | 'PUT',
46 path: string,
47 token?: string,
48 fields: { [ fieldName: string ]: any },
49 attaches: { [ attachName: string ]: any | any[] },
50 statusCodeExpected?: number
51}) {
52 if (!options.statusCodeExpected) options.statusCodeExpected = 400
53
54 let req: request.Test
55 if (options.method === 'PUT') {
56 req = request(options.url).put(options.path)
57 } else {
58 req = request(options.url).post(options.path)
59 }
60
61 req.set('Accept', 'application/json')
62
63 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
64
65 Object.keys(options.fields).forEach(field => {
66 const value = options.fields[field]
67
68 if (Array.isArray(value)) {
69 for (let i = 0; i < value.length; i++) {
70 req.field(field + '[' + i + ']', value[i])
71 }
72 } else {
73 req.field(field, value)
74 }
75 })
76
77 Object.keys(options.attaches).forEach(attach => {
78 const value = options.attaches[attach]
79 if (Array.isArray(value)) {
80 req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
81 } else {
82 req.attach(attach, buildAbsoluteFixturePath(value))
83 }
84 })
85
86 return req.expect(options.statusCodeExpected)
87}
88
89function makePostBodyRequest (options: {
90 url: string,
91 path: string,
92 token?: string,
93 fields?: { [ fieldName: string ]: any },
94 statusCodeExpected?: number
95}) {
96 if (!options.fields) options.fields = {}
97 if (!options.statusCodeExpected) options.statusCodeExpected = 400
98
99 const req = request(options.url)
100 .post(options.path)
101 .set('Accept', 'application/json')
102
103 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
104
105 return req.send(options.fields)
106 .expect(options.statusCodeExpected)
107}
108
109function makePutBodyRequest (options: {
110 url: string,
111 path: string,
112 token?: string,
113 fields: { [ fieldName: string ]: any },
114 statusCodeExpected?: number
115}) {
116 if (!options.statusCodeExpected) options.statusCodeExpected = 400
117
118 const req = request(options.url)
119 .put(options.path)
120 .set('Accept', 'application/json')
121
122 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
123
124 return req.send(options.fields)
125 .expect(options.statusCodeExpected)
126}
127
128function makeHTMLRequest (url: string, path: string) {
129 return request(url)
130 .get(path)
131 .set('Accept', 'text/html')
132 .expect(200)
133}
134
135function updateAvatarRequest (options: {
136 url: string,
137 path: string,
138 accessToken: string,
139 fixture: string
140}) {
141 let filePath = ''
142 if (isAbsolute(options.fixture)) {
143 filePath = options.fixture
144 } else {
145 filePath = join(__dirname, '..', '..', 'fixtures', options.fixture)
146 }
147
148 return makeUploadRequest({
149 url: options.url,
150 path: options.path,
151 token: options.accessToken,
152 fields: {},
153 attaches: { avatarfile: filePath },
154 statusCodeExpected: 200
155 })
156}
157
158// ---------------------------------------------------------------------------
159
160export {
161 makeHTMLRequest,
162 makeGetRequest,
163 makeUploadRequest,
164 makePostBodyRequest,
165 makePutBodyRequest,
166 makeDeleteRequest,
167 updateAvatarRequest
168}
diff --git a/server/tests/utils/search/video-channels.ts b/server/tests/utils/search/video-channels.ts
deleted file mode 100644
index 0532134ae..000000000
--- a/server/tests/utils/search/video-channels.ts
+++ /dev/null
@@ -1,22 +0,0 @@
1import { makeGetRequest } from '../requests/requests'
2
3function searchVideoChannel (url: string, search: string, token?: string, statusCodeExpected = 200) {
4 const path = '/api/v1/search/video-channels'
5
6 return makeGetRequest({
7 url,
8 path,
9 query: {
10 sort: '-createdAt',
11 search
12 },
13 token,
14 statusCodeExpected
15 })
16}
17
18// ---------------------------------------------------------------------------
19
20export {
21 searchVideoChannel
22}
diff --git a/server/tests/utils/search/videos.ts b/server/tests/utils/search/videos.ts
deleted file mode 100644
index 8c0037ccc..000000000
--- a/server/tests/utils/search/videos.ts
+++ /dev/null
@@ -1,77 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as request from 'supertest'
4import { VideosSearchQuery } from '../../../../shared/models/search'
5import { immutableAssign } from '../miscs/miscs'
6
7function searchVideo (url: string, search: string) {
8 const path = '/api/v1/search/videos'
9 const req = request(url)
10 .get(path)
11 .query({ sort: '-publishedAt', search })
12 .set('Accept', 'application/json')
13
14 return req.expect(200)
15 .expect('Content-Type', /json/)
16}
17
18function searchVideoWithToken (url: string, search: string, token: string, query: { nsfw?: boolean } = {}) {
19 const path = '/api/v1/search/videos'
20 const req = request(url)
21 .get(path)
22 .set('Authorization', 'Bearer ' + token)
23 .query(immutableAssign(query, { sort: '-publishedAt', search }))
24 .set('Accept', 'application/json')
25
26 return req.expect(200)
27 .expect('Content-Type', /json/)
28}
29
30function searchVideoWithPagination (url: string, search: string, start: number, count: number, sort?: string) {
31 const path = '/api/v1/search/videos'
32
33 const req = request(url)
34 .get(path)
35 .query({ start })
36 .query({ search })
37 .query({ count })
38
39 if (sort) req.query({ sort })
40
41 return req.set('Accept', 'application/json')
42 .expect(200)
43 .expect('Content-Type', /json/)
44}
45
46function searchVideoWithSort (url: string, search: string, sort: string) {
47 const path = '/api/v1/search/videos'
48
49 return request(url)
50 .get(path)
51 .query({ search })
52 .query({ sort })
53 .set('Accept', 'application/json')
54 .expect(200)
55 .expect('Content-Type', /json/)
56}
57
58function advancedVideosSearch (url: string, options: VideosSearchQuery) {
59 const path = '/api/v1/search/videos'
60
61 return request(url)
62 .get(path)
63 .query(options)
64 .set('Accept', 'application/json')
65 .expect(200)
66 .expect('Content-Type', /json/)
67}
68
69// ---------------------------------------------------------------------------
70
71export {
72 searchVideo,
73 advancedVideosSearch,
74 searchVideoWithToken,
75 searchVideoWithPagination,
76 searchVideoWithSort
77}
diff --git a/server/tests/utils/server/activitypub.ts b/server/tests/utils/server/activitypub.ts
deleted file mode 100644
index eccb198ca..000000000
--- a/server/tests/utils/server/activitypub.ts
+++ /dev/null
@@ -1,14 +0,0 @@
1import * as request from 'supertest'
2
3function makeActivityPubGetRequest (url: string, path: string, expectedStatus = 200) {
4 return request(url)
5 .get(path)
6 .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8')
7 .expect(expectedStatus)
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 makeActivityPubGetRequest
14}
diff --git a/server/tests/utils/server/clients.ts b/server/tests/utils/server/clients.ts
deleted file mode 100644
index 273aac747..000000000
--- a/server/tests/utils/server/clients.ts
+++ /dev/null
@@ -1,19 +0,0 @@
1import * as request from 'supertest'
2import * as urlUtil from 'url'
3
4function getClient (url: string) {
5 const path = '/api/v1/oauth-clients/local'
6
7 return request(url)
8 .get(path)
9 .set('Host', urlUtil.parse(url).host)
10 .set('Accept', 'application/json')
11 .expect(200)
12 .expect('Content-Type', /json/)
13}
14
15// ---------------------------------------------------------------------------
16
17export {
18 getClient
19}
diff --git a/server/tests/utils/server/config.ts b/server/tests/utils/server/config.ts
deleted file mode 100644
index aa3100d34..000000000
--- a/server/tests/utils/server/config.ts
+++ /dev/null
@@ -1,135 +0,0 @@
1import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../requests/requests'
2import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
3
4function getConfig (url: string) {
5 const path = '/api/v1/config'
6
7 return makeGetRequest({
8 url,
9 path,
10 statusCodeExpected: 200
11 })
12}
13
14function getAbout (url: string) {
15 const path = '/api/v1/config/about'
16
17 return makeGetRequest({
18 url,
19 path,
20 statusCodeExpected: 200
21 })
22}
23
24function getCustomConfig (url: string, token: string, statusCodeExpected = 200) {
25 const path = '/api/v1/config/custom'
26
27 return makeGetRequest({
28 url,
29 token,
30 path,
31 statusCodeExpected
32 })
33}
34
35function updateCustomConfig (url: string, token: string, newCustomConfig: CustomConfig, statusCodeExpected = 200) {
36 const path = '/api/v1/config/custom'
37
38 return makePutBodyRequest({
39 url,
40 token,
41 path,
42 fields: newCustomConfig,
43 statusCodeExpected
44 })
45}
46
47function updateCustomSubConfig (url: string, token: string, newConfig: any) {
48 const updateParams: CustomConfig = {
49 instance: {
50 name: 'PeerTube updated',
51 shortDescription: 'my short description',
52 description: 'my super description',
53 terms: 'my super terms',
54 defaultClientRoute: '/videos/recently-added',
55 defaultNSFWPolicy: 'blur',
56 customizations: {
57 javascript: 'alert("coucou")',
58 css: 'body { background-color: red; }'
59 }
60 },
61 services: {
62 twitter: {
63 username: '@MySuperUsername',
64 whitelisted: true
65 }
66 },
67 cache: {
68 previews: {
69 size: 2
70 },
71 captions: {
72 size: 3
73 }
74 },
75 signup: {
76 enabled: false,
77 limit: 5,
78 requiresEmailVerification: false
79 },
80 admin: {
81 email: 'superadmin1@example.com'
82 },
83 user: {
84 videoQuota: 5242881,
85 videoQuotaDaily: 318742
86 },
87 transcoding: {
88 enabled: true,
89 threads: 1,
90 resolutions: {
91 '240p': false,
92 '360p': true,
93 '480p': true,
94 '720p': false,
95 '1080p': false
96 }
97 },
98 import: {
99 videos: {
100 http: {
101 enabled: false
102 },
103 torrent: {
104 enabled: false
105 }
106 }
107 }
108 }
109
110 Object.assign(updateParams, newConfig)
111
112 return updateCustomConfig(url, token, updateParams)
113}
114
115function deleteCustomConfig (url: string, token: string, statusCodeExpected = 200) {
116 const path = '/api/v1/config/custom'
117
118 return makeDeleteRequest({
119 url,
120 token,
121 path,
122 statusCodeExpected
123 })
124}
125
126// ---------------------------------------------------------------------------
127
128export {
129 getConfig,
130 getCustomConfig,
131 updateCustomConfig,
132 getAbout,
133 deleteCustomConfig,
134 updateCustomSubConfig
135}
diff --git a/server/tests/utils/server/follows.ts b/server/tests/utils/server/follows.ts
deleted file mode 100644
index 7741757a6..000000000
--- a/server/tests/utils/server/follows.ts
+++ /dev/null
@@ -1,79 +0,0 @@
1import * as request from 'supertest'
2import { ServerInfo } from './servers'
3import { waitJobs } from './jobs'
4
5function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
6 const path = '/api/v1/server/followers'
7
8 return request(url)
9 .get(path)
10 .query({ start })
11 .query({ count })
12 .query({ sort })
13 .query({ search })
14 .set('Accept', 'application/json')
15 .expect(200)
16 .expect('Content-Type', /json/)
17}
18
19function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
20 const path = '/api/v1/server/following'
21
22 return request(url)
23 .get(path)
24 .query({ start })
25 .query({ count })
26 .query({ sort })
27 .query({ search })
28 .set('Accept', 'application/json')
29 .expect(200)
30 .expect('Content-Type', /json/)
31}
32
33async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) {
34 const path = '/api/v1/server/following'
35
36 const followingHosts = following.map(f => f.replace(/^http:\/\//, ''))
37 const res = await request(follower)
38 .post(path)
39 .set('Accept', 'application/json')
40 .set('Authorization', 'Bearer ' + accessToken)
41 .send({ 'hosts': followingHosts })
42 .expect(expectedStatus)
43
44 return res
45}
46
47async function unfollow (url: string, accessToken: string, target: ServerInfo, expectedStatus = 204) {
48 const path = '/api/v1/server/following/' + target.host
49
50 const res = await request(url)
51 .delete(path)
52 .set('Accept', 'application/json')
53 .set('Authorization', 'Bearer ' + accessToken)
54 .expect(expectedStatus)
55
56 return res
57}
58
59async function doubleFollow (server1: ServerInfo, server2: ServerInfo) {
60 await Promise.all([
61 follow(server1.url, [ server2.url ], server1.accessToken),
62 follow(server2.url, [ server1.url ], server2.accessToken)
63 ])
64
65 // Wait request propagation
66 await waitJobs([ server1, server2 ])
67
68 return true
69}
70
71// ---------------------------------------------------------------------------
72
73export {
74 getFollowersListPaginationAndSort,
75 getFollowingListPaginationAndSort,
76 unfollow,
77 follow,
78 doubleFollow
79}
diff --git a/server/tests/utils/server/jobs.ts b/server/tests/utils/server/jobs.ts
deleted file mode 100644
index 26180ec72..000000000
--- a/server/tests/utils/server/jobs.ts
+++ /dev/null
@@ -1,78 +0,0 @@
1import * as request from 'supertest'
2import { Job, JobState } from '../../../../shared/models'
3import { ServerInfo } from './servers'
4import { wait } from '../miscs/miscs'
5
6function getJobsList (url: string, accessToken: string, state: JobState) {
7 const path = '/api/v1/jobs/' + state
8
9 return request(url)
10 .get(path)
11 .set('Accept', 'application/json')
12 .set('Authorization', 'Bearer ' + accessToken)
13 .expect(200)
14 .expect('Content-Type', /json/)
15}
16
17function getJobsListPaginationAndSort (url: string, accessToken: string, state: JobState, start: number, count: number, sort: string) {
18 const path = '/api/v1/jobs/' + state
19
20 return request(url)
21 .get(path)
22 .query({ start })
23 .query({ count })
24 .query({ sort })
25 .set('Accept', 'application/json')
26 .set('Authorization', 'Bearer ' + accessToken)
27 .expect(200)
28 .expect('Content-Type', /json/)
29}
30
31async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
32 let servers: ServerInfo[]
33
34 if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ]
35 else servers = serversArg as ServerInfo[]
36
37 const states: JobState[] = [ 'waiting', 'active', 'delayed' ]
38 const tasks: Promise<any>[] = []
39 let pendingRequests: boolean
40
41 do {
42 pendingRequests = false
43
44 // Check if each server has pending request
45 for (const server of servers) {
46 for (const state of states) {
47 const p = getJobsListPaginationAndSort(server.url, server.accessToken, state, 0, 10, '-createdAt')
48 .then(res => res.body.data)
49 .then((jobs: Job[]) => jobs.filter(j => j.type !== 'videos-views'))
50 .then(jobs => {
51 if (jobs.length !== 0) pendingRequests = true
52 })
53 tasks.push(p)
54 }
55 }
56
57 await Promise.all(tasks)
58
59 // Retry, in case of new jobs were created
60 if (pendingRequests === false) {
61 await wait(1000)
62
63 await Promise.all(tasks)
64 }
65
66 if (pendingRequests) {
67 await wait(1000)
68 }
69 } while (pendingRequests)
70}
71
72// ---------------------------------------------------------------------------
73
74export {
75 getJobsList,
76 waitJobs,
77 getJobsListPaginationAndSort
78}
diff --git a/server/tests/utils/server/redundancy.ts b/server/tests/utils/server/redundancy.ts
deleted file mode 100644
index c39ff2c8b..000000000
--- a/server/tests/utils/server/redundancy.ts
+++ /dev/null
@@ -1,17 +0,0 @@
1import { makePutBodyRequest } from '../requests/requests'
2
3async function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) {
4 const path = '/api/v1/server/redundancy/' + host
5
6 return makePutBodyRequest({
7 url,
8 path,
9 token: accessToken,
10 fields: { redundancyAllowed },
11 statusCodeExpected: expectedStatus
12 })
13}
14
15export {
16 updateRedundancy
17}
diff --git a/server/tests/utils/server/servers.ts b/server/tests/utils/server/servers.ts
deleted file mode 100644
index f358a21f1..000000000
--- a/server/tests/utils/server/servers.ts
+++ /dev/null
@@ -1,185 +0,0 @@
1import { ChildProcess, exec, fork } from 'child_process'
2import { join } from 'path'
3import { root, wait } from '../miscs/miscs'
4import { readFile } from 'fs-extra'
5
6interface ServerInfo {
7 app: ChildProcess,
8 url: string
9 host: string
10 serverNumber: number
11
12 client: {
13 id: string,
14 secret: string
15 }
16
17 user: {
18 username: string,
19 password: string,
20 email?: string
21 }
22
23 accessToken?: string
24
25 video?: {
26 id: number
27 uuid: string
28 name: string
29 account: {
30 name: string
31 }
32 }
33
34 remoteVideo?: {
35 id: number
36 uuid: string
37 }
38}
39
40function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
41 let apps = []
42 let i = 0
43
44 return new Promise<ServerInfo[]>(res => {
45 function anotherServerDone (serverNumber, app) {
46 apps[serverNumber - 1] = app
47 i++
48 if (i === totalServers) {
49 return res(apps)
50 }
51 }
52
53 flushTests()
54 .then(() => {
55 for (let j = 1; j <= totalServers; j++) {
56 runServer(j, configOverride).then(app => anotherServerDone(j, app))
57 }
58 })
59 })
60}
61
62function flushTests () {
63 return new Promise<void>((res, rej) => {
64 return exec('npm run clean:server:test', err => {
65 if (err) return rej(err)
66
67 return res()
68 })
69 })
70}
71
72function runServer (serverNumber: number, configOverride?: Object, args = []) {
73 const server: ServerInfo = {
74 app: null,
75 serverNumber: serverNumber,
76 url: `http://localhost:${9000 + serverNumber}`,
77 host: `localhost:${9000 + serverNumber}`,
78 client: {
79 id: null,
80 secret: null
81 },
82 user: {
83 username: null,
84 password: null
85 }
86 }
87
88 // These actions are async so we need to be sure that they have both been done
89 const serverRunString = {
90 'Server listening': false
91 }
92 const key = 'Database peertube_test' + serverNumber + ' is ready'
93 serverRunString[key] = false
94
95 const regexps = {
96 client_id: 'Client id: (.+)',
97 client_secret: 'Client secret: (.+)',
98 user_username: 'Username: (.+)',
99 user_password: 'User password: (.+)'
100 }
101
102 // Share the environment
103 const env = Object.create(process.env)
104 env['NODE_ENV'] = 'test'
105 env['NODE_APP_INSTANCE'] = serverNumber.toString()
106
107 if (configOverride !== undefined) {
108 env['NODE_CONFIG'] = JSON.stringify(configOverride)
109 }
110
111 const options = {
112 silent: true,
113 env: env,
114 detached: true
115 }
116
117 return new Promise<ServerInfo>(res => {
118 server.app = fork(join(__dirname, '..', '..', '..', '..', 'dist', 'server.js'), args, options)
119 server.app.stdout.on('data', function onStdout (data) {
120 let dontContinue = false
121
122 // Capture things if we want to
123 for (const key of Object.keys(regexps)) {
124 const regexp = regexps[key]
125 const matches = data.toString().match(regexp)
126 if (matches !== null) {
127 if (key === 'client_id') server.client.id = matches[1]
128 else if (key === 'client_secret') server.client.secret = matches[1]
129 else if (key === 'user_username') server.user.username = matches[1]
130 else if (key === 'user_password') server.user.password = matches[1]
131 }
132 }
133
134 // Check if all required sentences are here
135 for (const key of Object.keys(serverRunString)) {
136 if (data.toString().indexOf(key) !== -1) serverRunString[key] = true
137 if (serverRunString[key] === false) dontContinue = true
138 }
139
140 // If no, there is maybe one thing not already initialized (client/user credentials generation...)
141 if (dontContinue === true) return
142
143 server.app.stdout.removeListener('data', onStdout)
144 res(server)
145 })
146 })
147}
148
149async function reRunServer (server: ServerInfo, configOverride?: any) {
150 const newServer = await runServer(server.serverNumber, configOverride)
151 server.app = newServer.app
152
153 return server
154}
155
156function killallServers (servers: ServerInfo[]) {
157 for (const server of servers) {
158 process.kill(-server.app.pid)
159 }
160}
161
162async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
163 const logfile = join(root(), 'test' + server.serverNumber, 'logs/peertube.log')
164
165 while (true) {
166 const buf = await readFile(logfile)
167
168 const matches = buf.toString().match(new RegExp(str, 'g'))
169 if (matches && matches.length === count) return
170
171 await wait(1000)
172 }
173}
174
175// ---------------------------------------------------------------------------
176
177export {
178 ServerInfo,
179 flushAndRunMultipleServers,
180 flushTests,
181 runServer,
182 killallServers,
183 reRunServer,
184 waitUntilLog
185}
diff --git a/server/tests/utils/server/stats.ts b/server/tests/utils/server/stats.ts
deleted file mode 100644
index 6f079ad18..000000000
--- a/server/tests/utils/server/stats.ts
+++ /dev/null
@@ -1,22 +0,0 @@
1import { makeGetRequest } from '../requests/requests'
2
3function getStats (url: string, useCache = false) {
4 const path = '/api/v1/server/stats'
5
6 const query = {
7 t: useCache ? undefined : new Date().getTime()
8 }
9
10 return makeGetRequest({
11 url,
12 path,
13 query,
14 statusCodeExpected: 200
15 })
16}
17
18// ---------------------------------------------------------------------------
19
20export {
21 getStats
22}
diff --git a/server/tests/utils/users/accounts.ts b/server/tests/utils/users/accounts.ts
deleted file mode 100644
index 257fa5b27..000000000
--- a/server/tests/utils/users/accounts.ts
+++ /dev/null
@@ -1,63 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import { expect } from 'chai'
4import { existsSync, readdir } from 'fs-extra'
5import { join } from 'path'
6import { Account } from '../../../../shared/models/actors'
7import { root } from '../miscs/miscs'
8import { makeGetRequest } from '../requests/requests'
9
10function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
11 const path = '/api/v1/accounts'
12
13 return makeGetRequest({
14 url,
15 query: { sort },
16 path,
17 statusCodeExpected
18 })
19}
20
21function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
22 const path = '/api/v1/accounts/' + accountName
23
24 return makeGetRequest({
25 url,
26 path,
27 statusCodeExpected
28 })
29}
30
31async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
32 const res = await getAccountsList(url)
33 const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
34
35 const message = `${nameWithDomain} on ${url}`
36 expect(account.followersCount).to.equal(followersCount, message)
37 expect(account.followingCount).to.equal(followingCount, message)
38}
39
40async function checkActorFilesWereRemoved (actorUUID: string, serverNumber: number) {
41 const testDirectory = 'test' + serverNumber
42
43 for (const directory of [ 'avatars' ]) {
44 const directoryPath = join(root(), testDirectory, directory)
45
46 const directoryExists = existsSync(directoryPath)
47 expect(directoryExists).to.be.true
48
49 const files = await readdir(directoryPath)
50 for (const file of files) {
51 expect(file).to.not.contain(actorUUID)
52 }
53 }
54}
55
56// ---------------------------------------------------------------------------
57
58export {
59 getAccount,
60 expectAccountFollows,
61 getAccountsList,
62 checkActorFilesWereRemoved
63}
diff --git a/server/tests/utils/users/blocklist.ts b/server/tests/utils/users/blocklist.ts
deleted file mode 100644
index 5feb84179..000000000
--- a/server/tests/utils/users/blocklist.ts
+++ /dev/null
@@ -1,197 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import { makeGetRequest, makeDeleteRequest, makePostBodyRequest } from '../requests/requests'
4
5function getAccountBlocklistByAccount (
6 url: string,
7 token: string,
8 start: number,
9 count: number,
10 sort = '-createdAt',
11 statusCodeExpected = 200
12) {
13 const path = '/api/v1/users/me/blocklist/accounts'
14
15 return makeGetRequest({
16 url,
17 token,
18 query: { start, count, sort },
19 path,
20 statusCodeExpected
21 })
22}
23
24function addAccountToAccountBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
25 const path = '/api/v1/users/me/blocklist/accounts'
26
27 return makePostBodyRequest({
28 url,
29 path,
30 token,
31 fields: {
32 accountName: accountToBlock
33 },
34 statusCodeExpected
35 })
36}
37
38function removeAccountFromAccountBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
39 const path = '/api/v1/users/me/blocklist/accounts/' + accountToUnblock
40
41 return makeDeleteRequest({
42 url,
43 path,
44 token,
45 statusCodeExpected
46 })
47}
48
49function getServerBlocklistByAccount (
50 url: string,
51 token: string,
52 start: number,
53 count: number,
54 sort = '-createdAt',
55 statusCodeExpected = 200
56) {
57 const path = '/api/v1/users/me/blocklist/servers'
58
59 return makeGetRequest({
60 url,
61 token,
62 query: { start, count, sort },
63 path,
64 statusCodeExpected
65 })
66}
67
68function addServerToAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
69 const path = '/api/v1/users/me/blocklist/servers'
70
71 return makePostBodyRequest({
72 url,
73 path,
74 token,
75 fields: {
76 host: serverToBlock
77 },
78 statusCodeExpected
79 })
80}
81
82function removeServerFromAccountBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
83 const path = '/api/v1/users/me/blocklist/servers/' + serverToBlock
84
85 return makeDeleteRequest({
86 url,
87 path,
88 token,
89 statusCodeExpected
90 })
91}
92
93function getAccountBlocklistByServer (
94 url: string,
95 token: string,
96 start: number,
97 count: number,
98 sort = '-createdAt',
99 statusCodeExpected = 200
100) {
101 const path = '/api/v1/server/blocklist/accounts'
102
103 return makeGetRequest({
104 url,
105 token,
106 query: { start, count, sort },
107 path,
108 statusCodeExpected
109 })
110}
111
112function addAccountToServerBlocklist (url: string, token: string, accountToBlock: string, statusCodeExpected = 204) {
113 const path = '/api/v1/server/blocklist/accounts'
114
115 return makePostBodyRequest({
116 url,
117 path,
118 token,
119 fields: {
120 accountName: accountToBlock
121 },
122 statusCodeExpected
123 })
124}
125
126function removeAccountFromServerBlocklist (url: string, token: string, accountToUnblock: string, statusCodeExpected = 204) {
127 const path = '/api/v1/server/blocklist/accounts/' + accountToUnblock
128
129 return makeDeleteRequest({
130 url,
131 path,
132 token,
133 statusCodeExpected
134 })
135}
136
137function getServerBlocklistByServer (
138 url: string,
139 token: string,
140 start: number,
141 count: number,
142 sort = '-createdAt',
143 statusCodeExpected = 200
144) {
145 const path = '/api/v1/server/blocklist/servers'
146
147 return makeGetRequest({
148 url,
149 token,
150 query: { start, count, sort },
151 path,
152 statusCodeExpected
153 })
154}
155
156function addServerToServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
157 const path = '/api/v1/server/blocklist/servers'
158
159 return makePostBodyRequest({
160 url,
161 path,
162 token,
163 fields: {
164 host: serverToBlock
165 },
166 statusCodeExpected
167 })
168}
169
170function removeServerFromServerBlocklist (url: string, token: string, serverToBlock: string, statusCodeExpected = 204) {
171 const path = '/api/v1/server/blocklist/servers/' + serverToBlock
172
173 return makeDeleteRequest({
174 url,
175 path,
176 token,
177 statusCodeExpected
178 })
179}
180
181// ---------------------------------------------------------------------------
182
183export {
184 getAccountBlocklistByAccount,
185 addAccountToAccountBlocklist,
186 removeAccountFromAccountBlocklist,
187 getServerBlocklistByAccount,
188 addServerToAccountBlocklist,
189 removeServerFromAccountBlocklist,
190
191 getAccountBlocklistByServer,
192 addAccountToServerBlocklist,
193 removeAccountFromServerBlocklist,
194 getServerBlocklistByServer,
195 addServerToServerBlocklist,
196 removeServerFromServerBlocklist
197}
diff --git a/server/tests/utils/users/login.ts b/server/tests/utils/users/login.ts
deleted file mode 100644
index ddeb9df2a..000000000
--- a/server/tests/utils/users/login.ts
+++ /dev/null
@@ -1,62 +0,0 @@
1import * as request from 'supertest'
2
3import { ServerInfo } from '../server/servers'
4
5type Client = { id: string, secret: string }
6type User = { username: string, password: string }
7type Server = { url: string, client: Client, user: User }
8
9function login (url: string, client: Client, user: User, expectedStatus = 200) {
10 const path = '/api/v1/users/token'
11
12 const body = {
13 client_id: client.id,
14 client_secret: client.secret,
15 username: user.username,
16 password: user.password,
17 response_type: 'code',
18 grant_type: 'password',
19 scope: 'upload'
20 }
21
22 return request(url)
23 .post(path)
24 .type('form')
25 .send(body)
26 .expect(expectedStatus)
27}
28
29async function serverLogin (server: Server) {
30 const res = await login(server.url, server.client, server.user, 200)
31
32 return res.body.access_token as string
33}
34
35async function userLogin (server: Server, user: User, expectedStatus = 200) {
36 const res = await login(server.url, server.client, user, expectedStatus)
37
38 return res.body.access_token as string
39}
40
41function setAccessTokensToServers (servers: ServerInfo[]) {
42 const tasks: Promise<any>[] = []
43
44 for (const server of servers) {
45 const p = serverLogin(server).then(t => server.accessToken = t)
46 tasks.push(p)
47 }
48
49 return Promise.all(tasks)
50}
51
52// ---------------------------------------------------------------------------
53
54export {
55 login,
56 serverLogin,
57 userLogin,
58 setAccessTokensToServers,
59 Server,
60 Client,
61 User
62}
diff --git a/server/tests/utils/users/user-subscriptions.ts b/server/tests/utils/users/user-subscriptions.ts
deleted file mode 100644
index 7148fbfca..000000000
--- a/server/tests/utils/users/user-subscriptions.ts
+++ /dev/null
@@ -1,82 +0,0 @@
1import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../requests/requests'
2
3function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
4 const path = '/api/v1/users/me/subscriptions'
5
6 return makePostBodyRequest({
7 url,
8 path,
9 token,
10 statusCodeExpected,
11 fields: { uri: targetUri }
12 })
13}
14
15function listUserSubscriptions (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
16 const path = '/api/v1/users/me/subscriptions'
17
18 return makeGetRequest({
19 url,
20 path,
21 token,
22 statusCodeExpected,
23 query: { sort }
24 })
25}
26
27function listUserSubscriptionVideos (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
28 const path = '/api/v1/users/me/subscriptions/videos'
29
30 return makeGetRequest({
31 url,
32 path,
33 token,
34 statusCodeExpected,
35 query: { sort }
36 })
37}
38
39function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
40 const path = '/api/v1/users/me/subscriptions/' + uri
41
42 return makeGetRequest({
43 url,
44 path,
45 token,
46 statusCodeExpected
47 })
48}
49
50function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
51 const path = '/api/v1/users/me/subscriptions/' + uri
52
53 return makeDeleteRequest({
54 url,
55 path,
56 token,
57 statusCodeExpected
58 })
59}
60
61function areSubscriptionsExist (url: string, token: string, uris: string[], statusCodeExpected = 200) {
62 const path = '/api/v1/users/me/subscriptions/exist'
63
64 return makeGetRequest({
65 url,
66 path,
67 query: { 'uris[]': uris },
68 token,
69 statusCodeExpected
70 })
71}
72
73// ---------------------------------------------------------------------------
74
75export {
76 areSubscriptionsExist,
77 addUserSubscription,
78 listUserSubscriptions,
79 getUserSubscription,
80 listUserSubscriptionVideos,
81 removeUserSubscription
82}
diff --git a/server/tests/utils/users/users.ts b/server/tests/utils/users/users.ts
deleted file mode 100644
index f12992315..000000000
--- a/server/tests/utils/users/users.ts
+++ /dev/null
@@ -1,298 +0,0 @@
1import * as request from 'supertest'
2import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests'
3
4import { UserRole } from '../../../../shared/index'
5import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type'
6
7function createUser (
8 url: string,
9 accessToken: string,
10 username: string,
11 password: string,
12 videoQuota = 1000000,
13 videoQuotaDaily = -1,
14 role: UserRole = UserRole.USER,
15 specialStatus = 200
16) {
17 const path = '/api/v1/users'
18 const body = {
19 username,
20 password,
21 role,
22 email: username + '@example.com',
23 videoQuota,
24 videoQuotaDaily
25 }
26
27 return request(url)
28 .post(path)
29 .set('Accept', 'application/json')
30 .set('Authorization', 'Bearer ' + accessToken)
31 .send(body)
32 .expect(specialStatus)
33}
34
35function registerUser (url: string, username: string, password: string, specialStatus = 204) {
36 const path = '/api/v1/users/register'
37 const body = {
38 username,
39 password,
40 email: username + '@example.com'
41 }
42
43 return request(url)
44 .post(path)
45 .set('Accept', 'application/json')
46 .send(body)
47 .expect(specialStatus)
48}
49
50function getMyUserInformation (url: string, accessToken: string, specialStatus = 200) {
51 const path = '/api/v1/users/me'
52
53 return request(url)
54 .get(path)
55 .set('Accept', 'application/json')
56 .set('Authorization', 'Bearer ' + accessToken)
57 .expect(specialStatus)
58 .expect('Content-Type', /json/)
59}
60
61function deleteMe (url: string, accessToken: string, specialStatus = 204) {
62 const path = '/api/v1/users/me'
63
64 return request(url)
65 .delete(path)
66 .set('Accept', 'application/json')
67 .set('Authorization', 'Bearer ' + accessToken)
68 .expect(specialStatus)
69}
70
71function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = 200) {
72 const path = '/api/v1/users/me/video-quota-used'
73
74 return request(url)
75 .get(path)
76 .set('Accept', 'application/json')
77 .set('Authorization', 'Bearer ' + accessToken)
78 .expect(specialStatus)
79 .expect('Content-Type', /json/)
80}
81
82function getUserInformation (url: string, accessToken: string, userId: number) {
83 const path = '/api/v1/users/' + userId
84
85 return request(url)
86 .get(path)
87 .set('Accept', 'application/json')
88 .set('Authorization', 'Bearer ' + accessToken)
89 .expect(200)
90 .expect('Content-Type', /json/)
91}
92
93function getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = 200) {
94 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
95
96 return request(url)
97 .get(path)
98 .set('Accept', 'application/json')
99 .set('Authorization', 'Bearer ' + accessToken)
100 .expect(specialStatus)
101 .expect('Content-Type', /json/)
102}
103
104function getUsersList (url: string, accessToken: string) {
105 const path = '/api/v1/users'
106
107 return request(url)
108 .get(path)
109 .set('Accept', 'application/json')
110 .set('Authorization', 'Bearer ' + accessToken)
111 .expect(200)
112 .expect('Content-Type', /json/)
113}
114
115function getUsersListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string, search?: string) {
116 const path = '/api/v1/users'
117
118 return request(url)
119 .get(path)
120 .query({ start })
121 .query({ count })
122 .query({ sort })
123 .query({ search })
124 .set('Accept', 'application/json')
125 .set('Authorization', 'Bearer ' + accessToken)
126 .expect(200)
127 .expect('Content-Type', /json/)
128}
129
130function removeUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
131 const path = '/api/v1/users'
132
133 return request(url)
134 .delete(path + '/' + userId)
135 .set('Accept', 'application/json')
136 .set('Authorization', 'Bearer ' + accessToken)
137 .expect(expectedStatus)
138}
139
140function blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204, reason?: string) {
141 const path = '/api/v1/users'
142 let body: any
143 if (reason) body = { reason }
144
145 return request(url)
146 .post(path + '/' + userId + '/block')
147 .send(body)
148 .set('Accept', 'application/json')
149 .set('Authorization', 'Bearer ' + accessToken)
150 .expect(expectedStatus)
151}
152
153function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
154 const path = '/api/v1/users'
155
156 return request(url)
157 .post(path + '/' + userId + '/unblock')
158 .set('Accept', 'application/json')
159 .set('Authorization', 'Bearer ' + accessToken)
160 .expect(expectedStatus)
161}
162
163function updateMyUser (options: {
164 url: string
165 accessToken: string,
166 currentPassword?: string,
167 newPassword?: string,
168 nsfwPolicy?: NSFWPolicyType,
169 email?: string,
170 autoPlayVideo?: boolean
171 displayName?: string,
172 description?: string
173}) {
174 const path = '/api/v1/users/me'
175
176 const toSend = {}
177 if (options.currentPassword !== undefined && options.currentPassword !== null) toSend['currentPassword'] = options.currentPassword
178 if (options.newPassword !== undefined && options.newPassword !== null) toSend['password'] = options.newPassword
179 if (options.nsfwPolicy !== undefined && options.nsfwPolicy !== null) toSend['nsfwPolicy'] = options.nsfwPolicy
180 if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
181 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
182 if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
183 if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
184
185 return makePutBodyRequest({
186 url: options.url,
187 path,
188 token: options.accessToken,
189 fields: toSend,
190 statusCodeExpected: 204
191 })
192}
193
194function updateMyAvatar (options: {
195 url: string,
196 accessToken: string,
197 fixture: string
198}) {
199 const path = '/api/v1/users/me/avatar/pick'
200
201 return updateAvatarRequest(Object.assign(options, { path }))
202}
203
204function updateUser (options: {
205 url: string
206 userId: number,
207 accessToken: string,
208 email?: string,
209 emailVerified?: boolean,
210 videoQuota?: number,
211 videoQuotaDaily?: number,
212 role?: UserRole
213}) {
214 const path = '/api/v1/users/' + options.userId
215
216 const toSend = {}
217 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
218 if (options.emailVerified !== undefined && options.emailVerified !== null) toSend['emailVerified'] = options.emailVerified
219 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
220 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
221 if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
222
223 return makePutBodyRequest({
224 url: options.url,
225 path,
226 token: options.accessToken,
227 fields: toSend,
228 statusCodeExpected: 204
229 })
230}
231
232function askResetPassword (url: string, email: string) {
233 const path = '/api/v1/users/ask-reset-password'
234
235 return makePostBodyRequest({
236 url,
237 path,
238 fields: { email },
239 statusCodeExpected: 204
240 })
241}
242
243function resetPassword (url: string, userId: number, verificationString: string, password: string, statusCodeExpected = 204) {
244 const path = '/api/v1/users/' + userId + '/reset-password'
245
246 return makePostBodyRequest({
247 url,
248 path,
249 fields: { password, verificationString },
250 statusCodeExpected
251 })
252}
253
254function askSendVerifyEmail (url: string, email: string) {
255 const path = '/api/v1/users/ask-send-verify-email'
256
257 return makePostBodyRequest({
258 url,
259 path,
260 fields: { email },
261 statusCodeExpected: 204
262 })
263}
264
265function verifyEmail (url: string, userId: number, verificationString: string, statusCodeExpected = 204) {
266 const path = '/api/v1/users/' + userId + '/verify-email'
267
268 return makePostBodyRequest({
269 url,
270 path,
271 fields: { verificationString },
272 statusCodeExpected
273 })
274}
275
276// ---------------------------------------------------------------------------
277
278export {
279 createUser,
280 registerUser,
281 getMyUserInformation,
282 getMyUserVideoRating,
283 deleteMe,
284 getMyUserVideoQuotaUsed,
285 getUsersList,
286 getUsersListPaginationAndSort,
287 removeUser,
288 updateUser,
289 updateMyUser,
290 getUserInformation,
291 blockUser,
292 unblockUser,
293 askResetPassword,
294 resetPassword,
295 updateMyAvatar,
296 askSendVerifyEmail,
297 verifyEmail
298}
diff --git a/server/tests/utils/videos/services.ts b/server/tests/utils/videos/services.ts
deleted file mode 100644
index 1a53dd4cf..000000000
--- a/server/tests/utils/videos/services.ts
+++ /dev/null
@@ -1,23 +0,0 @@
1import * as request from 'supertest'
2
3function getOEmbed (url: string, oembedUrl: string, format?: string, maxHeight?: number, maxWidth?: number) {
4 const path = '/services/oembed'
5 const query = {
6 url: oembedUrl,
7 format,
8 maxheight: maxHeight,
9 maxwidth: maxWidth
10 }
11
12 return request(url)
13 .get(path)
14 .query(query)
15 .set('Accept', 'application/json')
16 .expect(200)
17}
18
19// ---------------------------------------------------------------------------
20
21export {
22 getOEmbed
23}
diff --git a/server/tests/utils/videos/video-abuses.ts b/server/tests/utils/videos/video-abuses.ts
deleted file mode 100644
index 4ad82ad8c..000000000
--- a/server/tests/utils/videos/video-abuses.ts
+++ /dev/null
@@ -1,65 +0,0 @@
1import * as request from 'supertest'
2import { VideoAbuseUpdate } from '../../../../shared/models/videos/abuse/video-abuse-update.model'
3import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests'
4
5function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
6 const path = '/api/v1/videos/' + videoId + '/abuse'
7
8 return request(url)
9 .post(path)
10 .set('Accept', 'application/json')
11 .set('Authorization', 'Bearer ' + token)
12 .send({ reason })
13 .expect(specialStatus)
14}
15
16function getVideoAbusesList (url: string, token: string) {
17 const path = '/api/v1/videos/abuse'
18
19 return request(url)
20 .get(path)
21 .query({ sort: 'createdAt' })
22 .set('Accept', 'application/json')
23 .set('Authorization', 'Bearer ' + token)
24 .expect(200)
25 .expect('Content-Type', /json/)
26}
27
28function updateVideoAbuse (
29 url: string,
30 token: string,
31 videoId: string | number,
32 videoAbuseId: number,
33 body: VideoAbuseUpdate,
34 statusCodeExpected = 204
35) {
36 const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
37
38 return makePutBodyRequest({
39 url,
40 token,
41 path,
42 fields: body,
43 statusCodeExpected
44 })
45}
46
47function deleteVideoAbuse (url: string, token: string, videoId: string | number, videoAbuseId: number, statusCodeExpected = 204) {
48 const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
49
50 return makeDeleteRequest({
51 url,
52 token,
53 path,
54 statusCodeExpected
55 })
56}
57
58// ---------------------------------------------------------------------------
59
60export {
61 reportVideoAbuse,
62 getVideoAbusesList,
63 updateVideoAbuse,
64 deleteVideoAbuse
65}
diff --git a/server/tests/utils/videos/video-blacklist.ts b/server/tests/utils/videos/video-blacklist.ts
deleted file mode 100644
index 2c176fde0..000000000
--- a/server/tests/utils/videos/video-blacklist.ts
+++ /dev/null
@@ -1,67 +0,0 @@
1import * as request from 'supertest'
2
3function addVideoToBlacklist (url: string, token: string, videoId: number | string, reason?: string, specialStatus = 204) {
4 const path = '/api/v1/videos/' + videoId + '/blacklist'
5
6 return request(url)
7 .post(path)
8 .send({ reason })
9 .set('Accept', 'application/json')
10 .set('Authorization', 'Bearer ' + token)
11 .expect(specialStatus)
12}
13
14function updateVideoBlacklist (url: string, token: string, videoId: number, reason?: string, specialStatus = 204) {
15 const path = '/api/v1/videos/' + videoId + '/blacklist'
16
17 return request(url)
18 .put(path)
19 .send({ reason })
20 .set('Accept', 'application/json')
21 .set('Authorization', 'Bearer ' + token)
22 .expect(specialStatus)
23}
24
25function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, specialStatus = 204) {
26 const path = '/api/v1/videos/' + videoId + '/blacklist'
27
28 return request(url)
29 .delete(path)
30 .set('Accept', 'application/json')
31 .set('Authorization', 'Bearer ' + token)
32 .expect(specialStatus)
33}
34
35function getBlacklistedVideosList (url: string, token: string, specialStatus = 200) {
36 const path = '/api/v1/videos/blacklist/'
37
38 return request(url)
39 .get(path)
40 .query({ sort: 'createdAt' })
41 .set('Accept', 'application/json')
42 .set('Authorization', 'Bearer ' + token)
43 .expect(specialStatus)
44 .expect('Content-Type', /json/)
45}
46
47function getSortedBlacklistedVideosList (url: string, token: string, sort: string, specialStatus = 200) {
48 const path = '/api/v1/videos/blacklist/'
49
50 return request(url)
51 .get(path)
52 .query({ sort: sort })
53 .set('Accept', 'application/json')
54 .set('Authorization', 'Bearer ' + token)
55 .expect(specialStatus)
56 .expect('Content-Type', /json/)
57}
58
59// ---------------------------------------------------------------------------
60
61export {
62 addVideoToBlacklist,
63 removeVideoFromBlacklist,
64 getBlacklistedVideosList,
65 getSortedBlacklistedVideosList,
66 updateVideoBlacklist
67}
diff --git a/server/tests/utils/videos/video-captions.ts b/server/tests/utils/videos/video-captions.ts
deleted file mode 100644
index 8d67f617b..000000000
--- a/server/tests/utils/videos/video-captions.ts
+++ /dev/null
@@ -1,71 +0,0 @@
1import { makeDeleteRequest, makeGetRequest, makeUploadRequest } from '../requests/requests'
2import * as request from 'supertest'
3import * as chai from 'chai'
4import { buildAbsoluteFixturePath } from '../miscs/miscs'
5
6const expect = chai.expect
7
8function createVideoCaption (args: {
9 url: string,
10 accessToken: string
11 videoId: string | number
12 language: string
13 fixture: string,
14 mimeType?: string,
15 statusCodeExpected?: number
16}) {
17 const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language
18
19 const captionfile = buildAbsoluteFixturePath(args.fixture)
20 const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile
21
22 return makeUploadRequest({
23 method: 'PUT',
24 url: args.url,
25 path,
26 token: args.accessToken,
27 fields: {},
28 attaches: {
29 captionfile: captionfileAttach
30 },
31 statusCodeExpected: args.statusCodeExpected || 204
32 })
33}
34
35function listVideoCaptions (url: string, videoId: string | number) {
36 const path = '/api/v1/videos/' + videoId + '/captions'
37
38 return makeGetRequest({
39 url,
40 path,
41 statusCodeExpected: 200
42 })
43}
44
45function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) {
46 const path = '/api/v1/videos/' + videoId + '/captions/' + language
47
48 return makeDeleteRequest({
49 url,
50 token,
51 path,
52 statusCodeExpected: 204
53 })
54}
55
56async function testCaptionFile (url: string, captionPath: string, containsString: string) {
57 const res = await request(url)
58 .get(captionPath)
59 .expect(200)
60
61 expect(res.text).to.contain(containsString)
62}
63
64// ---------------------------------------------------------------------------
65
66export {
67 createVideoCaption,
68 listVideoCaptions,
69 testCaptionFile,
70 deleteVideoCaption
71}
diff --git a/server/tests/utils/videos/video-change-ownership.ts b/server/tests/utils/videos/video-change-ownership.ts
deleted file mode 100644
index f288692ea..000000000
--- a/server/tests/utils/videos/video-change-ownership.ts
+++ /dev/null
@@ -1,54 +0,0 @@
1import * as request from 'supertest'
2
3function changeVideoOwnership (url: string, token: string, videoId: number | string, username) {
4 const path = '/api/v1/videos/' + videoId + '/give-ownership'
5
6 return request(url)
7 .post(path)
8 .set('Accept', 'application/json')
9 .set('Authorization', 'Bearer ' + token)
10 .send({ username })
11 .expect(204)
12}
13
14function getVideoChangeOwnershipList (url: string, token: string) {
15 const path = '/api/v1/videos/ownership'
16
17 return request(url)
18 .get(path)
19 .query({ sort: '-createdAt' })
20 .set('Accept', 'application/json')
21 .set('Authorization', 'Bearer ' + token)
22 .expect(200)
23 .expect('Content-Type', /json/)
24}
25
26function acceptChangeOwnership (url: string, token: string, ownershipId: string, channelId: number, expectedStatus = 204) {
27 const path = '/api/v1/videos/ownership/' + ownershipId + '/accept'
28
29 return request(url)
30 .post(path)
31 .set('Accept', 'application/json')
32 .set('Authorization', 'Bearer ' + token)
33 .send({ channelId })
34 .expect(expectedStatus)
35}
36
37function refuseChangeOwnership (url: string, token: string, ownershipId: string, expectedStatus = 204) {
38 const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse'
39
40 return request(url)
41 .post(path)
42 .set('Accept', 'application/json')
43 .set('Authorization', 'Bearer ' + token)
44 .expect(expectedStatus)
45}
46
47// ---------------------------------------------------------------------------
48
49export {
50 changeVideoOwnership,
51 getVideoChangeOwnershipList,
52 acceptChangeOwnership,
53 refuseChangeOwnership
54}
diff --git a/server/tests/utils/videos/video-channels.ts b/server/tests/utils/videos/video-channels.ts
deleted file mode 100644
index 70e8d1a6b..000000000
--- a/server/tests/utils/videos/video-channels.ts
+++ /dev/null
@@ -1,118 +0,0 @@
1import * as request from 'supertest'
2import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos'
3import { updateAvatarRequest } from '../requests/requests'
4
5function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
6 const path = '/api/v1/video-channels'
7
8 const req = request(url)
9 .get(path)
10 .query({ start: start })
11 .query({ count: count })
12
13 if (sort) req.query({ sort })
14
15 return req.set('Accept', 'application/json')
16 .expect(200)
17 .expect('Content-Type', /json/)
18}
19
20function getAccountVideoChannelsList (url: string, accountName: string, specialStatus = 200) {
21 const path = '/api/v1/accounts/' + accountName + '/video-channels'
22
23 return request(url)
24 .get(path)
25 .set('Accept', 'application/json')
26 .expect(specialStatus)
27 .expect('Content-Type', /json/)
28}
29
30function addVideoChannel (
31 url: string,
32 token: string,
33 videoChannelAttributesArg: VideoChannelCreate,
34 expectedStatus = 200
35) {
36 const path = '/api/v1/video-channels/'
37
38 // Default attributes
39 let attributes = {
40 displayName: 'my super video channel',
41 description: 'my super channel description',
42 support: 'my super channel support'
43 }
44 attributes = Object.assign(attributes, videoChannelAttributesArg)
45
46 return request(url)
47 .post(path)
48 .send(attributes)
49 .set('Accept', 'application/json')
50 .set('Authorization', 'Bearer ' + token)
51 .expect(expectedStatus)
52}
53
54function updateVideoChannel (
55 url: string,
56 token: string,
57 channelName: string,
58 attributes: VideoChannelUpdate,
59 expectedStatus = 204
60) {
61 const body = {}
62 const path = '/api/v1/video-channels/' + channelName
63
64 if (attributes.displayName) body['displayName'] = attributes.displayName
65 if (attributes.description) body['description'] = attributes.description
66 if (attributes.support) body['support'] = attributes.support
67
68 return request(url)
69 .put(path)
70 .send(body)
71 .set('Accept', 'application/json')
72 .set('Authorization', 'Bearer ' + token)
73 .expect(expectedStatus)
74}
75
76function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = 204) {
77 const path = '/api/v1/video-channels/' + channelName
78
79 return request(url)
80 .delete(path)
81 .set('Accept', 'application/json')
82 .set('Authorization', 'Bearer ' + token)
83 .expect(expectedStatus)
84}
85
86function getVideoChannel (url: string, channelName: string) {
87 const path = '/api/v1/video-channels/' + channelName
88
89 return request(url)
90 .get(path)
91 .set('Accept', 'application/json')
92 .expect(200)
93 .expect('Content-Type', /json/)
94}
95
96function updateVideoChannelAvatar (options: {
97 url: string,
98 accessToken: string,
99 fixture: string,
100 videoChannelName: string | number
101}) {
102
103 const path = '/api/v1/video-channels/' + options.videoChannelName + '/avatar/pick'
104
105 return updateAvatarRequest(Object.assign(options, { path }))
106}
107
108// ---------------------------------------------------------------------------
109
110export {
111 updateVideoChannelAvatar,
112 getVideoChannelsList,
113 getAccountVideoChannelsList,
114 addVideoChannel,
115 updateVideoChannel,
116 deleteVideoChannel,
117 getVideoChannel
118}
diff --git a/server/tests/utils/videos/video-comments.ts b/server/tests/utils/videos/video-comments.ts
deleted file mode 100644
index 0ebf69ced..000000000
--- a/server/tests/utils/videos/video-comments.ts
+++ /dev/null
@@ -1,87 +0,0 @@
1import * as request from 'supertest'
2import { makeDeleteRequest } from '../requests/requests'
3
4function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) {
5 const path = '/api/v1/videos/' + videoId + '/comment-threads'
6
7 const req = request(url)
8 .get(path)
9 .query({ start: start })
10 .query({ count: count })
11
12 if (sort) req.query({ sort })
13 if (token) req.set('Authorization', 'Bearer ' + token)
14
15 return req.set('Accept', 'application/json')
16 .expect(200)
17 .expect('Content-Type', /json/)
18}
19
20function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) {
21 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
22
23 const req = request(url)
24 .get(path)
25 .set('Accept', 'application/json')
26
27 if (token) req.set('Authorization', 'Bearer ' + token)
28
29 return req.expect(200)
30 .expect('Content-Type', /json/)
31}
32
33function addVideoCommentThread (url: string, token: string, videoId: number | string, text: string, expectedStatus = 200) {
34 const path = '/api/v1/videos/' + videoId + '/comment-threads'
35
36 return request(url)
37 .post(path)
38 .send({ text })
39 .set('Accept', 'application/json')
40 .set('Authorization', 'Bearer ' + token)
41 .expect(expectedStatus)
42}
43
44function addVideoCommentReply (
45 url: string,
46 token: string,
47 videoId: number | string,
48 inReplyToCommentId: number,
49 text: string,
50 expectedStatus = 200
51) {
52 const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId
53
54 return request(url)
55 .post(path)
56 .send({ text })
57 .set('Accept', 'application/json')
58 .set('Authorization', 'Bearer ' + token)
59 .expect(expectedStatus)
60}
61
62function deleteVideoComment (
63 url: string,
64 token: string,
65 videoId: number | string,
66 commentId: number,
67 statusCodeExpected = 204
68) {
69 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
70
71 return makeDeleteRequest({
72 url,
73 path,
74 token,
75 statusCodeExpected
76 })
77}
78
79// ---------------------------------------------------------------------------
80
81export {
82 getVideoCommentThreads,
83 getVideoThreadComments,
84 addVideoCommentThread,
85 addVideoCommentReply,
86 deleteVideoComment
87}
diff --git a/server/tests/utils/videos/video-history.ts b/server/tests/utils/videos/video-history.ts
deleted file mode 100644
index 7635478f7..000000000
--- a/server/tests/utils/videos/video-history.ts
+++ /dev/null
@@ -1,14 +0,0 @@
1import { makePutBodyRequest } from '../requests/requests'
2
3function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number) {
4 const path = '/api/v1/videos/' + videoId + '/watching'
5 const fields = { currentTime }
6
7 return makePutBodyRequest({ url, path, token, fields, statusCodeExpected: 204 })
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 userWatchVideo
14}
diff --git a/server/tests/utils/videos/video-imports.ts b/server/tests/utils/videos/video-imports.ts
deleted file mode 100644
index eb985a5b1..000000000
--- a/server/tests/utils/videos/video-imports.ts
+++ /dev/null
@@ -1,51 +0,0 @@
1import { VideoImportCreate } from '../../../../shared/models/videos'
2import { makeGetRequest, makeUploadRequest } from '../requests/requests'
3
4function getYoutubeVideoUrl () {
5 return 'https://youtu.be/msX3jv1XdvM'
6}
7
8function getMagnetURI () {
9 // tslint:disable:max-line-length
10 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
11}
12
13function importVideo (url: string, token: string, attributes: VideoImportCreate) {
14 const path = '/api/v1/videos/imports'
15
16 let attaches: any = {}
17 if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
18
19 return makeUploadRequest({
20 url,
21 path,
22 token,
23 attaches,
24 fields: attributes,
25 statusCodeExpected: 200
26 })
27}
28
29function getMyVideoImports (url: string, token: string, sort?: string) {
30 const path = '/api/v1/users/me/videos/imports'
31
32 const query = {}
33 if (sort) query['sort'] = sort
34
35 return makeGetRequest({
36 url,
37 query,
38 path,
39 token,
40 statusCodeExpected: 200
41 })
42}
43
44// ---------------------------------------------------------------------------
45
46export {
47 getYoutubeVideoUrl,
48 importVideo,
49 getMagnetURI,
50 getMyVideoImports
51}
diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts
deleted file mode 100644
index d6c3e5dac..000000000
--- a/server/tests/utils/videos/videos.ts
+++ /dev/null
@@ -1,576 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import { expect } from 'chai'
4import { existsSync, readdir, readFile } from 'fs-extra'
5import * as parseTorrent from 'parse-torrent'
6import { extname, join } from 'path'
7import * as request from 'supertest'
8import {
9 buildAbsoluteFixturePath,
10 getMyUserInformation,
11 immutableAssign,
12 makeGetRequest,
13 makePutBodyRequest,
14 makeUploadRequest,
15 root,
16 ServerInfo,
17 testImage
18} from '../'
19import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
20import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers/constants'
21import { dateIsValid, webtorrentAdd } from '../miscs/miscs'
22
23type VideoAttributes = {
24 name?: string
25 category?: number
26 licence?: number
27 language?: string
28 nsfw?: boolean
29 commentsEnabled?: boolean
30 waitTranscoding?: boolean
31 description?: string
32 tags?: string[]
33 channelId?: number
34 privacy?: VideoPrivacy
35 fixture?: string
36 thumbnailfile?: string
37 previewfile?: string
38 scheduleUpdate?: {
39 updateAt: string
40 privacy?: VideoPrivacy
41 }
42}
43
44function getVideoCategories (url: string) {
45 const path = '/api/v1/videos/categories'
46
47 return makeGetRequest({
48 url,
49 path,
50 statusCodeExpected: 200
51 })
52}
53
54function getVideoLicences (url: string) {
55 const path = '/api/v1/videos/licences'
56
57 return makeGetRequest({
58 url,
59 path,
60 statusCodeExpected: 200
61 })
62}
63
64function getVideoLanguages (url: string) {
65 const path = '/api/v1/videos/languages'
66
67 return makeGetRequest({
68 url,
69 path,
70 statusCodeExpected: 200
71 })
72}
73
74function getVideoPrivacies (url: string) {
75 const path = '/api/v1/videos/privacies'
76
77 return makeGetRequest({
78 url,
79 path,
80 statusCodeExpected: 200
81 })
82}
83
84function getVideo (url: string, id: number | string, expectedStatus = 200) {
85 const path = '/api/v1/videos/' + id
86
87 return request(url)
88 .get(path)
89 .set('Accept', 'application/json')
90 .expect(expectedStatus)
91}
92
93function viewVideo (url: string, id: number | string, expectedStatus = 204, xForwardedFor?: string) {
94 const path = '/api/v1/videos/' + id + '/views'
95
96 const req = request(url)
97 .post(path)
98 .set('Accept', 'application/json')
99
100 if (xForwardedFor) {
101 req.set('X-Forwarded-For', xForwardedFor)
102 }
103
104 return req.expect(expectedStatus)
105}
106
107function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) {
108 const path = '/api/v1/videos/' + id
109
110 return request(url)
111 .get(path)
112 .set('Authorization', 'Bearer ' + token)
113 .set('Accept', 'application/json')
114 .expect(expectedStatus)
115}
116
117function getVideoDescription (url: string, descriptionPath: string) {
118 return request(url)
119 .get(descriptionPath)
120 .set('Accept', 'application/json')
121 .expect(200)
122 .expect('Content-Type', /json/)
123}
124
125function getVideosList (url: string) {
126 const path = '/api/v1/videos'
127
128 return request(url)
129 .get(path)
130 .query({ sort: 'name' })
131 .set('Accept', 'application/json')
132 .expect(200)
133 .expect('Content-Type', /json/)
134}
135
136function getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) {
137 const path = '/api/v1/videos'
138
139 return request(url)
140 .get(path)
141 .set('Authorization', 'Bearer ' + token)
142 .query(immutableAssign(query, { sort: 'name' }))
143 .set('Accept', 'application/json')
144 .expect(200)
145 .expect('Content-Type', /json/)
146}
147
148function getLocalVideos (url: string) {
149 const path = '/api/v1/videos'
150
151 return request(url)
152 .get(path)
153 .query({ sort: 'name', filter: 'local' })
154 .set('Accept', 'application/json')
155 .expect(200)
156 .expect('Content-Type', /json/)
157}
158
159function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string) {
160 const path = '/api/v1/users/me/videos'
161
162 const req = request(url)
163 .get(path)
164 .query({ start: start })
165 .query({ count: count })
166
167 if (sort) req.query({ sort })
168
169 return req.set('Accept', 'application/json')
170 .set('Authorization', 'Bearer ' + accessToken)
171 .expect(200)
172 .expect('Content-Type', /json/)
173}
174
175function getAccountVideos (
176 url: string,
177 accessToken: string,
178 accountName: string,
179 start: number,
180 count: number,
181 sort?: string,
182 query: { nsfw?: boolean } = {}
183) {
184 const path = '/api/v1/accounts/' + accountName + '/videos'
185
186 return makeGetRequest({
187 url,
188 path,
189 query: immutableAssign(query, {
190 start,
191 count,
192 sort
193 }),
194 token: accessToken,
195 statusCodeExpected: 200
196 })
197}
198
199function getVideoChannelVideos (
200 url: string,
201 accessToken: string,
202 videoChannelName: string,
203 start: number,
204 count: number,
205 sort?: string,
206 query: { nsfw?: boolean } = {}
207) {
208 const path = '/api/v1/video-channels/' + videoChannelName + '/videos'
209
210 return makeGetRequest({
211 url,
212 path,
213 query: immutableAssign(query, {
214 start,
215 count,
216 sort
217 }),
218 token: accessToken,
219 statusCodeExpected: 200
220 })
221}
222
223function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
224 const path = '/api/v1/videos'
225
226 const req = request(url)
227 .get(path)
228 .query({ start: start })
229 .query({ count: count })
230
231 if (sort) req.query({ sort })
232
233 return req.set('Accept', 'application/json')
234 .expect(200)
235 .expect('Content-Type', /json/)
236}
237
238function getVideosListSort (url: string, sort: string) {
239 const path = '/api/v1/videos'
240
241 return request(url)
242 .get(path)
243 .query({ sort: sort })
244 .set('Accept', 'application/json')
245 .expect(200)
246 .expect('Content-Type', /json/)
247}
248
249function getVideosWithFilters (url: string, query: { tagsAllOf: string[], categoryOneOf: number[] | number }) {
250 const path = '/api/v1/videos'
251
252 return request(url)
253 .get(path)
254 .query(query)
255 .set('Accept', 'application/json')
256 .expect(200)
257 .expect('Content-Type', /json/)
258}
259
260function removeVideo (url: string, token: string, id: number | string, expectedStatus = 204) {
261 const path = '/api/v1/videos'
262
263 return request(url)
264 .delete(path + '/' + id)
265 .set('Accept', 'application/json')
266 .set('Authorization', 'Bearer ' + token)
267 .expect(expectedStatus)
268}
269
270async function checkVideoFilesWereRemoved (
271 videoUUID: string,
272 serverNumber: number,
273 directories = [ 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
274) {
275 const testDirectory = 'test' + serverNumber
276
277 for (const directory of directories) {
278 const directoryPath = join(root(), testDirectory, directory)
279
280 const directoryExists = existsSync(directoryPath)
281 expect(directoryExists).to.be.true
282
283 const files = await readdir(directoryPath)
284 for (const file of files) {
285 expect(file).to.not.contain(videoUUID)
286 }
287 }
288}
289
290async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) {
291 const path = '/api/v1/videos/upload'
292 let defaultChannelId = '1'
293
294 try {
295 const res = await getMyUserInformation(url, accessToken)
296 defaultChannelId = res.body.videoChannels[0].id
297 } catch (e) { /* empty */ }
298
299 // Override default attributes
300 const attributes = Object.assign({
301 name: 'my super video',
302 category: 5,
303 licence: 4,
304 language: 'zh',
305 channelId: defaultChannelId,
306 nsfw: true,
307 waitTranscoding: false,
308 description: 'my super description',
309 support: 'my super support text',
310 tags: [ 'tag' ],
311 privacy: VideoPrivacy.PUBLIC,
312 commentsEnabled: true,
313 fixture: 'video_short.webm'
314 }, videoAttributesArg)
315
316 const req = request(url)
317 .post(path)
318 .set('Accept', 'application/json')
319 .set('Authorization', 'Bearer ' + accessToken)
320 .field('name', attributes.name)
321 .field('nsfw', JSON.stringify(attributes.nsfw))
322 .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
323 .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
324 .field('privacy', attributes.privacy.toString())
325 .field('channelId', attributes.channelId)
326
327 if (attributes.description !== undefined) {
328 req.field('description', attributes.description)
329 }
330 if (attributes.language !== undefined) {
331 req.field('language', attributes.language.toString())
332 }
333 if (attributes.category !== undefined) {
334 req.field('category', attributes.category.toString())
335 }
336 if (attributes.licence !== undefined) {
337 req.field('licence', attributes.licence.toString())
338 }
339
340 for (let i = 0; i < attributes.tags.length; i++) {
341 req.field('tags[' + i + ']', attributes.tags[i])
342 }
343
344 if (attributes.thumbnailfile !== undefined) {
345 req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
346 }
347 if (attributes.previewfile !== undefined) {
348 req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
349 }
350
351 if (attributes.scheduleUpdate) {
352 req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt)
353
354 if (attributes.scheduleUpdate.privacy) {
355 req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy)
356 }
357 }
358
359 return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
360 .expect(specialStatus)
361}
362
363function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, statusCodeExpected = 204) {
364 const path = '/api/v1/videos/' + id
365 const body = {}
366
367 if (attributes.name) body['name'] = attributes.name
368 if (attributes.category) body['category'] = attributes.category
369 if (attributes.licence) body['licence'] = attributes.licence
370 if (attributes.language) body['language'] = attributes.language
371 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
372 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
373 if (attributes.description) body['description'] = attributes.description
374 if (attributes.tags) body['tags'] = attributes.tags
375 if (attributes.privacy) body['privacy'] = attributes.privacy
376 if (attributes.channelId) body['channelId'] = attributes.channelId
377 if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate
378
379 // Upload request
380 if (attributes.thumbnailfile || attributes.previewfile) {
381 const attaches: any = {}
382 if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile
383 if (attributes.previewfile) attaches.previewfile = attributes.previewfile
384
385 return makeUploadRequest({
386 url,
387 method: 'PUT',
388 path,
389 token: accessToken,
390 fields: body,
391 attaches,
392 statusCodeExpected
393 })
394 }
395
396 return makePutBodyRequest({
397 url,
398 path,
399 fields: body,
400 token: accessToken,
401 statusCodeExpected
402 })
403}
404
405function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) {
406 const path = '/api/v1/videos/' + id + '/rate'
407
408 return request(url)
409 .put(path)
410 .set('Accept', 'application/json')
411 .set('Authorization', 'Bearer ' + accessToken)
412 .send({ rating })
413 .expect(specialStatus)
414}
415
416function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
417 return new Promise<any>((res, rej) => {
418 const torrentName = videoUUID + '-' + resolution + '.torrent'
419 const torrentPath = join(__dirname, '..', '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName)
420 readFile(torrentPath, (err, data) => {
421 if (err) return rej(err)
422
423 return res(parseTorrent(data))
424 })
425 })
426}
427
428async function completeVideoCheck (
429 url: string,
430 video: any,
431 attributes: {
432 name: string
433 category: number
434 licence: number
435 language: string
436 nsfw: boolean
437 commentsEnabled: boolean
438 description: string
439 publishedAt?: string
440 support: string
441 account: {
442 name: string
443 host: string
444 }
445 isLocal: boolean
446 tags: string[]
447 privacy: number
448 likes?: number
449 dislikes?: number
450 duration: number
451 channel: {
452 displayName: string
453 name: string
454 description
455 isLocal: boolean
456 }
457 fixture: string
458 files: {
459 resolution: number
460 size: number
461 }[],
462 thumbnailfile?: string
463 previewfile?: string
464 }
465) {
466 if (!attributes.likes) attributes.likes = 0
467 if (!attributes.dislikes) attributes.dislikes = 0
468
469 expect(video.name).to.equal(attributes.name)
470 expect(video.category.id).to.equal(attributes.category)
471 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
472 expect(video.licence.id).to.equal(attributes.licence)
473 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
474 expect(video.language.id).to.equal(attributes.language)
475 expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
476 expect(video.privacy.id).to.deep.equal(attributes.privacy)
477 expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
478 expect(video.nsfw).to.equal(attributes.nsfw)
479 expect(video.description).to.equal(attributes.description)
480 expect(video.account.id).to.be.a('number')
481 expect(video.account.uuid).to.be.a('string')
482 expect(video.account.host).to.equal(attributes.account.host)
483 expect(video.account.name).to.equal(attributes.account.name)
484 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
485 expect(video.channel.name).to.equal(attributes.channel.name)
486 expect(video.likes).to.equal(attributes.likes)
487 expect(video.dislikes).to.equal(attributes.dislikes)
488 expect(video.isLocal).to.equal(attributes.isLocal)
489 expect(video.duration).to.equal(attributes.duration)
490 expect(dateIsValid(video.createdAt)).to.be.true
491 expect(dateIsValid(video.publishedAt)).to.be.true
492 expect(dateIsValid(video.updatedAt)).to.be.true
493
494 if (attributes.publishedAt) {
495 expect(video.publishedAt).to.equal(attributes.publishedAt)
496 }
497
498 const res = await getVideo(url, video.uuid)
499 const videoDetails: VideoDetails = res.body
500
501 expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
502 expect(videoDetails.tags).to.deep.equal(attributes.tags)
503 expect(videoDetails.account.name).to.equal(attributes.account.name)
504 expect(videoDetails.account.host).to.equal(attributes.account.host)
505 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
506 expect(video.channel.name).to.equal(attributes.channel.name)
507 expect(videoDetails.channel.host).to.equal(attributes.account.host)
508 expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
509 expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
510 expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
511 expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
512
513 for (const attributeFile of attributes.files) {
514 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
515 expect(file).not.to.be.undefined
516
517 let extension = extname(attributes.fixture)
518 // Transcoding enabled on server 2, extension will always be .mp4
519 if (attributes.account.host === 'localhost:9002') extension = '.mp4'
520
521 const magnetUri = file.magnetUri
522 expect(file.magnetUri).to.have.lengthOf.above(2)
523 expect(file.torrentUrl).to.equal(`http://${attributes.account.host}/static/torrents/${videoDetails.uuid}-${file.resolution.id}.torrent`)
524 expect(file.fileUrl).to.equal(`http://${attributes.account.host}/static/webseed/${videoDetails.uuid}-${file.resolution.id}${extension}`)
525 expect(file.resolution.id).to.equal(attributeFile.resolution)
526 expect(file.resolution.label).to.equal(attributeFile.resolution + 'p')
527
528 const minSize = attributeFile.size - ((10 * attributeFile.size) / 100)
529 const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100)
530 expect(file.size,
531 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')')
532 .to.be.above(minSize).and.below(maxSize)
533
534 {
535 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
536 }
537
538 if (attributes.previewfile) {
539 await testImage(url, attributes.previewfile, videoDetails.previewPath)
540 }
541
542 const torrent = await webtorrentAdd(magnetUri, true)
543 expect(torrent.files).to.be.an('array')
544 expect(torrent.files.length).to.equal(1)
545 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
546 }
547}
548
549// ---------------------------------------------------------------------------
550
551export {
552 getVideoDescription,
553 getVideoCategories,
554 getVideoLicences,
555 getVideoPrivacies,
556 getVideoLanguages,
557 getMyVideos,
558 getAccountVideos,
559 getVideoChannelVideos,
560 getVideo,
561 getVideoWithToken,
562 getVideosList,
563 getVideosListPagination,
564 getVideosListSort,
565 removeVideo,
566 getVideosListWithToken,
567 uploadVideo,
568 getVideosWithFilters,
569 updateVideo,
570 rateVideo,
571 viewVideo,
572 parseTorrentVideo,
573 getLocalVideos,
574 completeVideoCheck,
575 checkVideoFilesWereRemoved
576}