aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api')
-rw-r--r--server/tests/api/activitypub/client.ts4
-rw-r--r--server/tests/api/activitypub/fetch.ts4
-rw-r--r--server/tests/api/activitypub/helpers.ts2
-rw-r--r--server/tests/api/activitypub/refresher.ts70
-rw-r--r--server/tests/api/activitypub/security.ts16
-rw-r--r--server/tests/api/check-params/accounts.ts2
-rw-r--r--server/tests/api/check-params/blocklist.ts14
-rw-r--r--server/tests/api/check-params/config.ts2
-rw-r--r--server/tests/api/check-params/contact-form.ts18
-rw-r--r--server/tests/api/check-params/debug.ts7
-rw-r--r--server/tests/api/check-params/follows.ts2
-rw-r--r--server/tests/api/check-params/index.ts1
-rw-r--r--server/tests/api/check-params/jobs.ts8
-rw-r--r--server/tests/api/check-params/logs.ts8
-rw-r--r--server/tests/api/check-params/plugins.ts15
-rw-r--r--server/tests/api/check-params/redundancy.ts145
-rw-r--r--server/tests/api/check-params/search.ts2
-rw-r--r--server/tests/api/check-params/services.ts2
-rw-r--r--server/tests/api/check-params/user-notifications.ts2
-rw-r--r--server/tests/api/check-params/user-subscriptions.ts2
-rw-r--r--server/tests/api/check-params/users.ts61
-rw-r--r--server/tests/api/check-params/video-abuses.ts20
-rw-r--r--server/tests/api/check-params/video-blacklist.ts15
-rw-r--r--server/tests/api/check-params/video-captions.ts4
-rw-r--r--server/tests/api/check-params/video-channels.ts12
-rw-r--r--server/tests/api/check-params/video-comments.ts52
-rw-r--r--server/tests/api/check-params/video-imports.ts17
-rw-r--r--server/tests/api/check-params/video-playlists.ts7
-rw-r--r--server/tests/api/check-params/videos-filter.ts6
-rw-r--r--server/tests/api/check-params/videos-history.ts9
-rw-r--r--server/tests/api/check-params/videos-overviews.ts33
-rw-r--r--server/tests/api/check-params/videos.ts38
-rw-r--r--server/tests/api/notifications/user-notifications.ts129
-rw-r--r--server/tests/api/redundancy/index.ts2
-rw-r--r--server/tests/api/redundancy/manage-redundancy.ts373
-rw-r--r--server/tests/api/redundancy/redundancy-constraints.ts200
-rw-r--r--server/tests/api/redundancy/redundancy.ts182
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts44
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts8
-rw-r--r--server/tests/api/search/search-videos.ts14
-rw-r--r--server/tests/api/server/auto-follows.ts21
-rw-r--r--server/tests/api/server/config.ts14
-rw-r--r--server/tests/api/server/contact-form.ts14
-rw-r--r--server/tests/api/server/email.ts78
-rw-r--r--server/tests/api/server/follow-constraints.ts8
-rw-r--r--server/tests/api/server/follows-moderation.ts18
-rw-r--r--server/tests/api/server/follows.ts88
-rw-r--r--server/tests/api/server/handle-down.ts36
-rw-r--r--server/tests/api/server/jobs.ts16
-rw-r--r--server/tests/api/server/logs.ts2
-rw-r--r--server/tests/api/server/no-client.ts2
-rw-r--r--server/tests/api/server/plugins.ts34
-rw-r--r--server/tests/api/server/reverse-proxy.ts2
-rw-r--r--server/tests/api/server/stats.ts54
-rw-r--r--server/tests/api/server/tracker.ts16
-rw-r--r--server/tests/api/users/blocklist.ts259
-rw-r--r--server/tests/api/users/user-subscriptions.ts15
-rw-r--r--server/tests/api/users/users-multiple-servers.ts11
-rw-r--r--server/tests/api/users/users-verification.ts2
-rw-r--r--server/tests/api/users/users.ts247
-rw-r--r--server/tests/api/videos/audio-only.ts27
-rw-r--r--server/tests/api/videos/multiple-servers.ts32
-rw-r--r--server/tests/api/videos/services.ts10
-rw-r--r--server/tests/api/videos/single-server.ts51
-rw-r--r--server/tests/api/videos/video-abuse.ts150
-rw-r--r--server/tests/api/videos/video-blacklist.ts86
-rw-r--r--server/tests/api/videos/video-captions.ts9
-rw-r--r--server/tests/api/videos/video-change-ownership.ts18
-rw-r--r--server/tests/api/videos/video-channels.ts79
-rw-r--r--server/tests/api/videos/video-comments.ts6
-rw-r--r--server/tests/api/videos/video-description.ts7
-rw-r--r--server/tests/api/videos/video-hls.ts29
-rw-r--r--server/tests/api/videos/video-imports.ts66
-rw-r--r--server/tests/api/videos/video-nsfw.ts72
-rw-r--r--server/tests/api/videos/video-playlist-thumbnails.ts53
-rw-r--r--server/tests/api/videos/video-playlists.ts392
-rw-r--r--server/tests/api/videos/video-privacy.ts11
-rw-r--r--server/tests/api/videos/video-schedule-update.ts3
-rw-r--r--server/tests/api/videos/video-transcoder.ts155
-rw-r--r--server/tests/api/videos/videos-filter.ts12
-rw-r--r--server/tests/api/videos/videos-history.ts2
-rw-r--r--server/tests/api/videos/videos-overview.ts87
-rw-r--r--server/tests/api/videos/videos-views-cleaner.ts16
83 files changed, 2711 insertions, 1151 deletions
diff --git a/server/tests/api/activitypub/client.ts b/server/tests/api/activitypub/client.ts
index 34c6be49b..d16f05108 100644
--- a/server/tests/api/activitypub/client.ts
+++ b/server/tests/api/activitypub/client.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -6,8 +6,6 @@ import {
6 cleanupTests, 6 cleanupTests,
7 doubleFollow, 7 doubleFollow,
8 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
9 flushTests,
10 killallServers,
11 makeActivityPubGetRequest, 9 makeActivityPubGetRequest,
12 ServerInfo, 10 ServerInfo,
13 setAccessTokensToServers, 11 setAccessTokensToServers,
diff --git a/server/tests/api/activitypub/fetch.ts b/server/tests/api/activitypub/fetch.ts
index 3d54c2042..35fd94eed 100644
--- a/server/tests/api/activitypub/fetch.ts
+++ b/server/tests/api/activitypub/fetch.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
@@ -8,9 +8,7 @@ import {
8 createUser, 8 createUser,
9 doubleFollow, 9 doubleFollow,
10 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
11 flushTests,
12 getVideosListSort, 11 getVideosListSort,
13 killallServers,
14 ServerInfo, 12 ServerInfo,
15 setAccessTokensToServers, 13 setAccessTokensToServers,
16 setActorField, 14 setActorField,
diff --git a/server/tests/api/activitypub/helpers.ts b/server/tests/api/activitypub/helpers.ts
index 8c00ba3d6..60d95b823 100644
--- a/server/tests/api/activitypub/helpers.ts
+++ b/server/tests/api/activitypub/helpers.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import { expect } from 'chai' 4import { expect } from 'chai'
diff --git a/server/tests/api/activitypub/refresher.ts b/server/tests/api/activitypub/refresher.ts
index aa4bc6c0f..232c5d823 100644
--- a/server/tests/api/activitypub/refresher.ts
+++ b/server/tests/api/activitypub/refresher.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
@@ -43,32 +43,32 @@ describe('Test AP refresher', function () {
43 await setDefaultVideoChannel(servers) 43 await setDefaultVideoChannel(servers)
44 44
45 { 45 {
46 videoUUID1 = (await uploadVideoAndGetId({ server: servers[ 1 ], videoName: 'video1' })).uuid 46 videoUUID1 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video1' })).uuid
47 videoUUID2 = (await uploadVideoAndGetId({ server: servers[ 1 ], videoName: 'video2' })).uuid 47 videoUUID2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video2' })).uuid
48 videoUUID3 = (await uploadVideoAndGetId({ server: servers[ 1 ], videoName: 'video3' })).uuid 48 videoUUID3 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video3' })).uuid
49 } 49 }
50 50
51 { 51 {
52 const a1 = await generateUserAccessToken(servers[ 1 ], 'user1') 52 const a1 = await generateUserAccessToken(servers[1], 'user1')
53 await uploadVideo(servers[ 1 ].url, a1, { name: 'video4' }) 53 await uploadVideo(servers[1].url, a1, { name: 'video4' })
54 54
55 const a2 = await generateUserAccessToken(servers[ 1 ], 'user2') 55 const a2 = await generateUserAccessToken(servers[1], 'user2')
56 await uploadVideo(servers[ 1 ].url, a2, { name: 'video5' }) 56 await uploadVideo(servers[1].url, a2, { name: 'video5' })
57 } 57 }
58 58
59 { 59 {
60 const playlistAttrs = { displayName: 'playlist1', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[ 1 ].videoChannel.id } 60 const playlistAttrs = { displayName: 'playlist1', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
61 const res = await createVideoPlaylist({ url: servers[ 1 ].url, token: servers[ 1 ].accessToken, playlistAttrs }) 61 const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs })
62 playlistUUID1 = res.body.videoPlaylist.uuid 62 playlistUUID1 = res.body.videoPlaylist.uuid
63 } 63 }
64 64
65 { 65 {
66 const playlistAttrs = { displayName: 'playlist2', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[ 1 ].videoChannel.id } 66 const playlistAttrs = { displayName: 'playlist2', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
67 const res = await createVideoPlaylist({ url: servers[ 1 ].url, token: servers[ 1 ].accessToken, playlistAttrs }) 67 const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs })
68 playlistUUID2 = res.body.videoPlaylist.uuid 68 playlistUUID2 = res.body.videoPlaylist.uuid
69 } 69 }
70 70
71 await doubleFollow(servers[ 0 ], servers[ 1 ]) 71 await doubleFollow(servers[0], servers[1])
72 }) 72 })
73 73
74 describe('Videos refresher', function () { 74 describe('Videos refresher', function () {
@@ -79,34 +79,34 @@ describe('Test AP refresher', function () {
79 await wait(10000) 79 await wait(10000)
80 80
81 // Change UUID so the remote server returns a 404 81 // Change UUID so the remote server returns a 404
82 await setVideoField(servers[ 1 ].internalServerNumber, videoUUID1, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b174f') 82 await setVideoField(servers[1].internalServerNumber, videoUUID1, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b174f')
83 83
84 await getVideo(servers[ 0 ].url, videoUUID1) 84 await getVideo(servers[0].url, videoUUID1)
85 await getVideo(servers[ 0 ].url, videoUUID2) 85 await getVideo(servers[0].url, videoUUID2)
86 86
87 await waitJobs(servers) 87 await waitJobs(servers)
88 88
89 await getVideo(servers[ 0 ].url, videoUUID1, 404) 89 await getVideo(servers[0].url, videoUUID1, 404)
90 await getVideo(servers[ 0 ].url, videoUUID2, 200) 90 await getVideo(servers[0].url, videoUUID2, 200)
91 }) 91 })
92 92
93 it('Should not update a remote video if the remote instance is down', async function () { 93 it('Should not update a remote video if the remote instance is down', async function () {
94 this.timeout(70000) 94 this.timeout(70000)
95 95
96 killallServers([ servers[ 1 ] ]) 96 killallServers([ servers[1] ])
97 97
98 await setVideoField(servers[ 1 ].internalServerNumber, videoUUID3, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b174e') 98 await setVideoField(servers[1].internalServerNumber, videoUUID3, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b174e')
99 99
100 // Video will need a refresh 100 // Video will need a refresh
101 await wait(10000) 101 await wait(10000)
102 102
103 await getVideo(servers[ 0 ].url, videoUUID3) 103 await getVideo(servers[0].url, videoUUID3)
104 // The refresh should fail 104 // The refresh should fail
105 await waitJobs([ servers[ 0 ] ]) 105 await waitJobs([ servers[0] ])
106 106
107 await reRunServer(servers[ 1 ]) 107 await reRunServer(servers[1])
108 108
109 await getVideo(servers[ 0 ].url, videoUUID3, 200) 109 await getVideo(servers[0].url, videoUUID3, 200)
110 }) 110 })
111 }) 111 })
112 112
@@ -118,16 +118,16 @@ describe('Test AP refresher', function () {
118 await wait(10000) 118 await wait(10000)
119 119
120 // Change actor name so the remote server returns a 404 120 // Change actor name so the remote server returns a 404
121 const to = 'http://localhost:' + servers[ 1 ].port + '/accounts/user2' 121 const to = 'http://localhost:' + servers[1].port + '/accounts/user2'
122 await setActorField(servers[ 1 ].internalServerNumber, to, 'preferredUsername', 'toto') 122 await setActorField(servers[1].internalServerNumber, to, 'preferredUsername', 'toto')
123 123
124 await getAccount(servers[ 0 ].url, 'user1@localhost:' + servers[ 1 ].port) 124 await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port)
125 await getAccount(servers[ 0 ].url, 'user2@localhost:' + servers[ 1 ].port) 125 await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port)
126 126
127 await waitJobs(servers) 127 await waitJobs(servers)
128 128
129 await getAccount(servers[ 0 ].url, 'user1@localhost:' + servers[ 1 ].port, 200) 129 await getAccount(servers[0].url, 'user1@localhost:' + servers[1].port, 200)
130 await getAccount(servers[ 0 ].url, 'user2@localhost:' + servers[ 1 ].port, 404) 130 await getAccount(servers[0].url, 'user2@localhost:' + servers[1].port, 404)
131 }) 131 })
132 }) 132 })
133 133
@@ -139,15 +139,15 @@ describe('Test AP refresher', function () {
139 await wait(10000) 139 await wait(10000)
140 140
141 // Change UUID so the remote server returns a 404 141 // Change UUID so the remote server returns a 404
142 await setPlaylistField(servers[ 1 ].internalServerNumber, playlistUUID2, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b178e') 142 await setPlaylistField(servers[1].internalServerNumber, playlistUUID2, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b178e')
143 143
144 await getVideoPlaylist(servers[ 0 ].url, playlistUUID1) 144 await getVideoPlaylist(servers[0].url, playlistUUID1)
145 await getVideoPlaylist(servers[ 0 ].url, playlistUUID2) 145 await getVideoPlaylist(servers[0].url, playlistUUID2)
146 146
147 await waitJobs(servers) 147 await waitJobs(servers)
148 148
149 await getVideoPlaylist(servers[ 0 ].url, playlistUUID1, 200) 149 await getVideoPlaylist(servers[0].url, playlistUUID1, 200)
150 await getVideoPlaylist(servers[ 0 ].url, playlistUUID2, 404) 150 await getVideoPlaylist(servers[0].url, playlistUUID2, 404)
151 }) 151 })
152 }) 152 })
153 153
diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts
index dc960c5c3..ac4bc7c6a 100644
--- a/server/tests/api/activitypub/security.ts
+++ b/server/tests/api/activitypub/security.ts
@@ -1,20 +1,14 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import { cleanupTests, closeAllSequelize, flushAndRunMultipleServers, ServerInfo, setActorField } from '../../../../shared/extra-utils'
6 cleanupTests,
7 closeAllSequelize,
8 flushAndRunMultipleServers,
9 killallServers,
10 ServerInfo,
11 setActorField
12} from '../../../../shared/extra-utils'
13import { HTTP_SIGNATURE } from '../../../initializers/constants' 6import { HTTP_SIGNATURE } from '../../../initializers/constants'
14import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' 7import { buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
15import * as chai from 'chai' 8import * as chai from 'chai'
16import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' 9import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
17import { makeFollowRequest, makePOSTAPRequest } from '../../../../shared/extra-utils/requests/activitypub' 10import { makeFollowRequest, makePOSTAPRequest } from '../../../../shared/extra-utils/requests/activitypub'
11import { buildDigest } from '@server/helpers/peertube-crypto'
18 12
19const expect = chai.expect 13const expect = chai.expect
20 14
@@ -33,7 +27,7 @@ function getAnnounceWithoutContext (server2: ServerInfo) {
33 if (Array.isArray(json[key])) { 27 if (Array.isArray(json[key])) {
34 result[key] = json[key].map(v => v.replace(':9002', `:${server2.port}`)) 28 result[key] = json[key].map(v => v.replace(':9002', `:${server2.port}`))
35 } else { 29 } else {
36 result[ key ] = json[ key ].replace(':9002', `:${server2.port}`) 30 result[key] = json[key].replace(':9002', `:${server2.port}`)
37 } 31 }
38 } 32 }
39 33
diff --git a/server/tests/api/check-params/accounts.ts b/server/tests/api/check-params/accounts.ts
index 4f79685bd..c29af7cd7 100644
--- a/server/tests/api/check-params/accounts.ts
+++ b/server/tests/api/check-params/accounts.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
diff --git a/server/tests/api/check-params/blocklist.ts b/server/tests/api/check-params/blocklist.ts
index 0661676ce..1219ec9bd 100644
--- a/server/tests/api/check-params/blocklist.ts
+++ b/server/tests/api/check-params/blocklist.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
@@ -175,13 +175,13 @@ describe('Test blocklist API validators', function () {
175 }) 175 })
176 }) 176 })
177 177
178 it('Should fail with an unknown server', async function () { 178 it('Should succeed with an unknown server', async function () {
179 await makePostBodyRequest({ 179 await makePostBodyRequest({
180 url: server.url, 180 url: server.url,
181 token: server.accessToken, 181 token: server.accessToken,
182 path, 182 path,
183 fields: { host: 'localhost:9003' }, 183 fields: { host: 'localhost:9003' },
184 statusCodeExpected: 404 184 statusCodeExpected: 204
185 }) 185 })
186 }) 186 })
187 187
@@ -218,7 +218,7 @@ describe('Test blocklist API validators', function () {
218 it('Should fail with an unknown server block', async function () { 218 it('Should fail with an unknown server block', async function () {
219 await makeDeleteRequest({ 219 await makeDeleteRequest({
220 url: server.url, 220 url: server.url,
221 path: path + '/localhost:9003', 221 path: path + '/localhost:9004',
222 token: server.accessToken, 222 token: server.accessToken,
223 statusCodeExpected: 404 223 statusCodeExpected: 404
224 }) 224 })
@@ -415,13 +415,13 @@ describe('Test blocklist API validators', function () {
415 }) 415 })
416 }) 416 })
417 417
418 it('Should fail with an unknown server', async function () { 418 it('Should succeed with an unknown server', async function () {
419 await makePostBodyRequest({ 419 await makePostBodyRequest({
420 url: server.url, 420 url: server.url,
421 token: server.accessToken, 421 token: server.accessToken,
422 path, 422 path,
423 fields: { host: 'localhost:9003' }, 423 fields: { host: 'localhost:9003' },
424 statusCodeExpected: 404 424 statusCodeExpected: 204
425 }) 425 })
426 }) 426 })
427 427
@@ -467,7 +467,7 @@ describe('Test blocklist API validators', function () {
467 it('Should fail with an unknown server block', async function () { 467 it('Should fail with an unknown server block', async function () {
468 await makeDeleteRequest({ 468 await makeDeleteRequest({
469 url: server.url, 469 url: server.url,
470 path: path + '/localhost:9003', 470 path: path + '/localhost:9004',
471 token: server.accessToken, 471 token: server.accessToken,
472 statusCodeExpected: 404 472 statusCodeExpected: 404
473 }) 473 })
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index 443fbcb60..f1a79806b 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import { omit } from 'lodash' 3import { omit } from 'lodash'
4import 'mocha' 4import 'mocha'
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts
index b3051945e..b2126b9b0 100644
--- a/server/tests/api/check-params/contact-form.ts
+++ b/server/tests/api/check-params/contact-form.ts
@@ -1,22 +1,8 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import { cleanupTests, flushAndRunServer, immutableAssign, killallServers, reRunServer, ServerInfo } from '../../../../shared/extra-utils'
6 flushTests,
7 immutableAssign,
8 killallServers,
9 reRunServer,
10 flushAndRunServer,
11 ServerInfo,
12 setAccessTokensToServers, cleanupTests
13} from '../../../../shared/extra-utils'
14import {
15 checkBadCountPagination,
16 checkBadSortPagination,
17 checkBadStartPagination
18} from '../../../../shared/extra-utils/requests/check-api-params'
19import { getAccount } from '../../../../shared/extra-utils/users/accounts'
20import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' 6import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form'
21import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' 7import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
22 8
diff --git a/server/tests/api/check-params/debug.ts b/server/tests/api/check-params/debug.ts
index 8dad26723..5fac73485 100644
--- a/server/tests/api/check-params/debug.ts
+++ b/server/tests/api/check-params/debug.ts
@@ -1,15 +1,14 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import {
6 cleanupTests,
6 createUser, 7 createUser,
7 flushTests,
8 killallServers,
9 flushAndRunServer, 8 flushAndRunServer,
10 ServerInfo, 9 ServerInfo,
11 setAccessTokensToServers, 10 setAccessTokensToServers,
12 userLogin, cleanupTests 11 userLogin
13} from '../../../../shared/extra-utils' 12} from '../../../../shared/extra-utils'
14import { makeGetRequest } from '../../../../shared/extra-utils/requests/requests' 13import { makeGetRequest } from '../../../../shared/extra-utils/requests/requests'
15 14
diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts
index be2a603a3..2c2224a45 100644
--- a/server/tests/api/check-params/follows.ts
+++ b/server/tests/api/check-params/follows.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
index 924c0df76..ef152f55c 100644
--- a/server/tests/api/check-params/index.ts
+++ b/server/tests/api/check-params/index.ts
@@ -23,3 +23,4 @@ import './video-playlists'
23import './videos' 23import './videos'
24import './videos-filter' 24import './videos-filter'
25import './videos-history' 25import './videos-history'
26import './videos-overviews'
diff --git a/server/tests/api/check-params/jobs.ts b/server/tests/api/check-params/jobs.ts
index 22e237964..8f4af8d16 100644
--- a/server/tests/api/check-params/jobs.ts
+++ b/server/tests/api/check-params/jobs.ts
@@ -1,16 +1,14 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import {
6 cleanupTests,
6 createUser, 7 createUser,
7 flushTests,
8 killallServers,
9 flushAndRunServer, 8 flushAndRunServer,
10 ServerInfo, 9 ServerInfo,
11 setAccessTokensToServers, 10 setAccessTokensToServers,
12 userLogin, 11 userLogin
13 cleanupTests
14} from '../../../../shared/extra-utils' 12} from '../../../../shared/extra-utils'
15import { 13import {
16 checkBadCountPagination, 14 checkBadCountPagination,
diff --git a/server/tests/api/check-params/logs.ts b/server/tests/api/check-params/logs.ts
index f9d96bcc0..719da54e6 100644
--- a/server/tests/api/check-params/logs.ts
+++ b/server/tests/api/check-params/logs.ts
@@ -1,16 +1,14 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import {
6 cleanupTests,
6 createUser, 7 createUser,
7 flushTests,
8 killallServers,
9 flushAndRunServer, 8 flushAndRunServer,
10 ServerInfo, 9 ServerInfo,
11 setAccessTokensToServers, 10 setAccessTokensToServers,
12 userLogin, 11 userLogin
13 cleanupTests
14} from '../../../../shared/extra-utils' 12} from '../../../../shared/extra-utils'
15import { makeGetRequest } from '../../../../shared/extra-utils/requests/requests' 13import { makeGetRequest } from '../../../../shared/extra-utils/requests/requests'
16 14
diff --git a/server/tests/api/check-params/plugins.ts b/server/tests/api/check-params/plugins.ts
index 9553bce17..07ded26ee 100644
--- a/server/tests/api/check-params/plugins.ts
+++ b/server/tests/api/check-params/plugins.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
@@ -64,6 +64,7 @@ describe('Test server plugins API validators', function () {
64 describe('With static plugin routes', function () { 64 describe('With static plugin routes', function () {
65 it('Should fail with an unknown plugin name/plugin version', async function () { 65 it('Should fail with an unknown plugin name/plugin version', async function () {
66 const paths = [ 66 const paths = [
67 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
67 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png', 68 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
68 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js', 69 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
69 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png', 70 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
@@ -86,6 +87,7 @@ describe('Test server plugins API validators', function () {
86 87
87 it('Should fail with invalid versions', async function () { 88 it('Should fail with invalid versions', async function () {
88 const paths = [ 89 const paths = [
90 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
89 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png', 91 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
90 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js', 92 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
91 '/themes/' + themeName + '/1/static/images/chocobo.png', 93 '/themes/' + themeName + '/1/static/images/chocobo.png',
@@ -112,6 +114,12 @@ describe('Test server plugins API validators', function () {
112 } 114 }
113 }) 115 })
114 116
117 it('Should fail with an unknown auth name', async function () {
118 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
119
120 await makeGetRequest({ url: server.url, path, statusCodeExpected: 404 })
121 })
122
115 it('Should fail with an unknown static file', async function () { 123 it('Should fail with an unknown static file', async function () {
116 const paths = [ 124 const paths = [
117 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png', 125 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
@@ -145,6 +153,9 @@ describe('Test server plugins API validators', function () {
145 for (const p of paths) { 153 for (const p of paths) {
146 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: 200 }) 154 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: 200 })
147 } 155 }
156
157 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
158 await makeGetRequest({ url: server.url, path: authPath, statusCodeExpected: 302 })
148 }) 159 })
149 }) 160 })
150 161
@@ -462,6 +473,8 @@ describe('Test server plugins API validators', function () {
462 }) 473 })
463 474
464 it('Should succeed with the correct parameters', async function () { 475 it('Should succeed with the correct parameters', async function () {
476 this.timeout(10000)
477
465 const it = [ 478 const it = [
466 { suffix: 'install', status: 200 }, 479 { suffix: 'install', status: 200 },
467 { suffix: 'update', status: 200 }, 480 { suffix: 'update', status: 200 },
diff --git a/server/tests/api/check-params/redundancy.ts b/server/tests/api/check-params/redundancy.ts
index 6471da840..b2370a094 100644
--- a/server/tests/api/check-params/redundancy.ts
+++ b/server/tests/api/check-params/redundancy.ts
@@ -1,23 +1,27 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { 5import {
6 checkBadCountPagination,
7 checkBadSortPagination,
8 checkBadStartPagination,
6 cleanupTests, 9 cleanupTests,
7 createUser, 10 createUser,
8 doubleFollow, 11 doubleFollow,
9 flushAndRunMultipleServers, 12 flushAndRunMultipleServers, makeDeleteRequest,
10 flushTests, 13 makeGetRequest, makePostBodyRequest,
11 killallServers,
12 makePutBodyRequest, 14 makePutBodyRequest,
13 ServerInfo, 15 ServerInfo,
14 setAccessTokensToServers, 16 setAccessTokensToServers, uploadVideoAndGetId,
15 userLogin 17 userLogin, waitJobs
16} from '../../../../shared/extra-utils' 18} from '../../../../shared/extra-utils'
17 19
18describe('Test server redundancy API validators', function () { 20describe('Test server redundancy API validators', function () {
19 let servers: ServerInfo[] 21 let servers: ServerInfo[]
20 let userAccessToken = null 22 let userAccessToken = null
23 let videoIdLocal: number
24 let videoIdRemote: number
21 25
22 // --------------------------------------------------------------- 26 // ---------------------------------------------------------------
23 27
@@ -34,11 +38,136 @@ describe('Test server redundancy API validators', function () {
34 password: 'password' 38 password: 'password'
35 } 39 }
36 40
37 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) 41 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
38 userAccessToken = await userLogin(servers[0], user) 42 userAccessToken = await userLogin(servers[0], user)
43
44 videoIdLocal = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video' })).id
45 videoIdRemote = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video' })).id
46
47 await waitJobs(servers)
48 })
49
50 describe('When listing redundancies', function () {
51 const path = '/api/v1/server/redundancy/videos'
52
53 let url: string
54 let token: string
55
56 before(function () {
57 url = servers[0].url
58 token = servers[0].accessToken
59 })
60
61 it('Should fail with an invalid token', async function () {
62 await makeGetRequest({ url, path, token: 'fake_token', statusCodeExpected: 401 })
63 })
64
65 it('Should fail if the user is not an administrator', async function () {
66 await makeGetRequest({ url, path, token: userAccessToken, statusCodeExpected: 403 })
67 })
68
69 it('Should fail with a bad start pagination', async function () {
70 await checkBadStartPagination(url, path, servers[0].accessToken)
71 })
72
73 it('Should fail with a bad count pagination', async function () {
74 await checkBadCountPagination(url, path, servers[0].accessToken)
75 })
76
77 it('Should fail with an incorrect sort', async function () {
78 await checkBadSortPagination(url, path, servers[0].accessToken)
79 })
80
81 it('Should fail with a bad target', async function () {
82 await makeGetRequest({ url, path, token, query: { target: 'bad target' } })
83 })
84
85 it('Should fail without target', async function () {
86 await makeGetRequest({ url, path, token })
87 })
88
89 it('Should succeed with the correct params', async function () {
90 await makeGetRequest({ url, path, token, query: { target: 'my-videos' }, statusCodeExpected: 200 })
91 })
92 })
93
94 describe('When manually adding a redundancy', function () {
95 const path = '/api/v1/server/redundancy/videos'
96
97 let url: string
98 let token: string
99
100 before(function () {
101 url = servers[0].url
102 token = servers[0].accessToken
103 })
104
105 it('Should fail with an invalid token', async function () {
106 await makePostBodyRequest({ url, path, token: 'fake_token', statusCodeExpected: 401 })
107 })
108
109 it('Should fail if the user is not an administrator', async function () {
110 await makePostBodyRequest({ url, path, token: userAccessToken, statusCodeExpected: 403 })
111 })
112
113 it('Should fail without a video id', async function () {
114 await makePostBodyRequest({ url, path, token })
115 })
116
117 it('Should fail with an incorrect video id', async function () {
118 await makePostBodyRequest({ url, path, token, fields: { videoId: 'peertube' } })
119 })
120
121 it('Should fail with a not found video id', async function () {
122 await makePostBodyRequest({ url, path, token, fields: { videoId: 6565 }, statusCodeExpected: 404 })
123 })
124
125 it('Should fail with a local a video id', async function () {
126 await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdLocal } })
127 })
128
129 it('Should succeed with the correct params', async function () {
130 await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdRemote }, statusCodeExpected: 204 })
131 })
132
133 it('Should fail if the video is already duplicated', async function () {
134 this.timeout(30000)
135
136 await waitJobs(servers)
137
138 await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdRemote }, statusCodeExpected: 409 })
139 })
140 })
141
142 describe('When manually removing a redundancy', function () {
143 const path = '/api/v1/server/redundancy/videos/'
144
145 let url: string
146 let token: string
147
148 before(function () {
149 url = servers[0].url
150 token = servers[0].accessToken
151 })
152
153 it('Should fail with an invalid token', async function () {
154 await makeDeleteRequest({ url, path: path + '1', token: 'fake_token', statusCodeExpected: 401 })
155 })
156
157 it('Should fail if the user is not an administrator', async function () {
158 await makeDeleteRequest({ url, path: path + '1', token: userAccessToken, statusCodeExpected: 403 })
159 })
160
161 it('Should fail with an incorrect video id', async function () {
162 await makeDeleteRequest({ url, path: path + 'toto', token })
163 })
164
165 it('Should fail with a not found video redundancy', async function () {
166 await makeDeleteRequest({ url, path: path + '454545', token, statusCodeExpected: 404 })
167 })
39 }) 168 })
40 169
41 describe('When updating redundancy', function () { 170 describe('When updating server redundancy', function () {
42 const path = '/api/v1/server/redundancy' 171 const path = '/api/v1/server/redundancy'
43 172
44 it('Should fail with an invalid token', async function () { 173 it('Should fail with an invalid token', async function () {
diff --git a/server/tests/api/check-params/search.ts b/server/tests/api/check-params/search.ts
index 8ad9d98bf..f8d0cd4ec 100644
--- a/server/tests/api/check-params/search.ts
+++ b/server/tests/api/check-params/search.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts
index d15753aed..457adfaab 100644
--- a/server/tests/api/check-params/services.ts
+++ b/server/tests/api/check-params/services.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
diff --git a/server/tests/api/check-params/user-notifications.ts b/server/tests/api/check-params/user-notifications.ts
index 3b06be7ef..2048fa667 100644
--- a/server/tests/api/check-params/user-notifications.ts
+++ b/server/tests/api/check-params/user-notifications.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as io from 'socket.io-client' 4import * as io from 'socket.io-client'
diff --git a/server/tests/api/check-params/user-subscriptions.ts b/server/tests/api/check-params/user-subscriptions.ts
index fa36c4078..1edba4d64 100644
--- a/server/tests/api/check-params/user-subscriptions.ts
+++ b/server/tests/api/check-params/user-subscriptions.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index 5d5af284c..4d597f0a3 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import { omit } from 'lodash' 3import { omit } from 'lodash'
4import 'mocha' 4import 'mocha'
@@ -16,12 +16,14 @@ import {
16 getMyUserVideoRating, 16 getMyUserVideoRating,
17 getUsersList, 17 getUsersList,
18 immutableAssign, 18 immutableAssign,
19 killallServers,
19 makeGetRequest, 20 makeGetRequest,
20 makePostBodyRequest, 21 makePostBodyRequest,
21 makePutBodyRequest, 22 makePutBodyRequest,
22 makeUploadRequest, 23 makeUploadRequest,
23 registerUser, 24 registerUser,
24 removeUser, 25 removeUser,
26 reRunServer,
25 ServerInfo, 27 ServerInfo,
26 setAccessTokensToServers, 28 setAccessTokensToServers,
27 unblockUser, 29 unblockUser,
@@ -39,6 +41,7 @@ import { VideoPrivacy } from '../../../../shared/models/videos'
39import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 41import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
40import { expect } from 'chai' 42import { expect } from 'chai'
41import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' 43import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
44import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
42 45
43describe('Test users API validators', function () { 46describe('Test users API validators', function () {
44 const path = '/api/v1/users/' 47 const path = '/api/v1/users/'
@@ -50,6 +53,9 @@ describe('Test users API validators', function () {
50 let serverWithRegistrationDisabled: ServerInfo 53 let serverWithRegistrationDisabled: ServerInfo
51 let userAccessToken = '' 54 let userAccessToken = ''
52 let moderatorAccessToken = '' 55 let moderatorAccessToken = ''
56 let emailPort: number
57 let overrideConfig: Object
58 // eslint-disable-next-line @typescript-eslint/no-unused-vars
53 let channelId: number 59 let channelId: number
54 60
55 // --------------------------------------------------------------- 61 // ---------------------------------------------------------------
@@ -57,9 +63,14 @@ describe('Test users API validators', function () {
57 before(async function () { 63 before(async function () {
58 this.timeout(30000) 64 this.timeout(30000)
59 65
66 const emails: object[] = []
67 emailPort = await MockSmtpServer.Instance.collectEmails(emails)
68
69 overrideConfig = { signup: { limit: 8 } }
70
60 { 71 {
61 const res = await Promise.all([ 72 const res = await Promise.all([
62 flushAndRunServer(1, { signup: { limit: 7 } }), 73 flushAndRunServer(1, overrideConfig),
63 flushAndRunServer(2) 74 flushAndRunServer(2)
64 ]) 75 ])
65 76
@@ -120,7 +131,7 @@ describe('Test users API validators', function () {
120 131
121 { 132 {
122 const res = await getMyUserInformation(server.url, server.accessToken) 133 const res = await getMyUserInformation(server.url, server.accessToken)
123 channelId = res.body.videoChannels[ 0 ].id 134 channelId = res.body.videoChannels[0].id
124 } 135 }
125 136
126 { 137 {
@@ -228,6 +239,40 @@ describe('Test users API validators', function () {
228 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 239 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
229 }) 240 })
230 241
242 it('Should fail with empty password and no smtp configured', async function () {
243 const fields = immutableAssign(baseCorrectParams, { password: '' })
244
245 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
246 })
247
248 it('Should succeed with no password on a server with smtp enabled', async function () {
249 this.timeout(10000)
250
251 killallServers([ server ])
252
253 const config = immutableAssign(overrideConfig, {
254 smtp: {
255 hostname: 'localhost',
256 port: emailPort
257 }
258 })
259 await reRunServer(server, config)
260
261 const fields = immutableAssign(baseCorrectParams, {
262 password: '',
263 username: 'create_password',
264 email: 'create_password@example.com'
265 })
266
267 await makePostBodyRequest({
268 url: server.url,
269 path: path,
270 token: server.accessToken,
271 fields,
272 statusCodeExpected: 200
273 })
274 })
275
231 it('Should fail with invalid admin flags', async function () { 276 it('Should fail with invalid admin flags', async function () {
232 const fields = immutableAssign(baseCorrectParams, { adminFlags: 'toto' }) 277 const fields = immutableAssign(baseCorrectParams, { adminFlags: 'toto' })
233 278
@@ -529,7 +574,7 @@ describe('Test users API validators', function () {
529 it('Should fail without an incorrect input file', async function () { 574 it('Should fail without an incorrect input file', async function () {
530 const fields = {} 575 const fields = {}
531 const attaches = { 576 const attaches = {
532 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4') 577 avatarfile: join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
533 } 578 }
534 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) 579 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
535 }) 580 })
@@ -537,7 +582,7 @@ describe('Test users API validators', function () {
537 it('Should fail with a big file', async function () { 582 it('Should fail with a big file', async function () {
538 const fields = {} 583 const fields = {}
539 const attaches = { 584 const attaches = {
540 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') 585 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
541 } 586 }
542 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) 587 await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
543 }) 588 })
@@ -545,7 +590,7 @@ describe('Test users API validators', function () {
545 it('Should fail with an unauthenticated user', async function () { 590 it('Should fail with an unauthenticated user', async function () {
546 const fields = {} 591 const fields = {}
547 const attaches = { 592 const attaches = {
548 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 593 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
549 } 594 }
550 await makeUploadRequest({ 595 await makeUploadRequest({
551 url: server.url, 596 url: server.url,
@@ -559,7 +604,7 @@ describe('Test users API validators', function () {
559 it('Should succeed with the correct params', async function () { 604 it('Should succeed with the correct params', async function () {
560 const fields = {} 605 const fields = {}
561 const attaches = { 606 const attaches = {
562 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 607 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
563 } 608 }
564 await makeUploadRequest({ 609 await makeUploadRequest({
565 url: server.url, 610 url: server.url,
@@ -1101,6 +1146,8 @@ describe('Test users API validators', function () {
1101 }) 1146 })
1102 1147
1103 after(async function () { 1148 after(async function () {
1149 MockSmtpServer.Instance.kill()
1150
1104 await cleanupTests([ server, serverWithRegistrationDisabled ]) 1151 await cleanupTests([ server, serverWithRegistrationDisabled ])
1105 }) 1152 })
1106}) 1153})
diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts
index bf29f8d4d..e643cb95e 100644
--- a/server/tests/api/check-params/video-abuses.ts
+++ b/server/tests/api/check-params/video-abuses.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
@@ -76,6 +76,22 @@ describe('Test video abuses API validators', function () {
76 statusCodeExpected: 403 76 statusCodeExpected: 403
77 }) 77 })
78 }) 78 })
79
80 it('Should fail with a bad id filter', async function () {
81 await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { id: 'toto' } })
82 })
83
84 it('Should fail with a bad state filter', async function () {
85 await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { state: 'toto' } })
86 })
87
88 it('Should fail with a bad videoIs filter', async function () {
89 await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { videoIs: 'toto' } })
90 })
91
92 it('Should succeed with the correct params', async function () {
93 await makeGetRequest({ url: server.url, path, token: server.accessToken, query: { id: 13 }, statusCodeExpected: 200 })
94 })
79 }) 95 })
80 96
81 describe('When reporting a video abuse', function () { 97 describe('When reporting a video abuse', function () {
@@ -126,6 +142,7 @@ describe('Test video abuses API validators', function () {
126 142
127 describe('When updating a video abuse', function () { 143 describe('When updating a video abuse', function () {
128 const basePath = '/api/v1/videos/' 144 const basePath = '/api/v1/videos/'
145 // eslint-disable-next-line @typescript-eslint/no-unused-vars
129 let path: string 146 let path: string
130 147
131 before(() => { 148 before(() => {
@@ -163,6 +180,7 @@ describe('Test video abuses API validators', function () {
163 180
164 describe('When deleting a video abuse', function () { 181 describe('When deleting a video abuse', function () {
165 const basePath = '/api/v1/videos/' 182 const basePath = '/api/v1/videos/'
183 // eslint-disable-next-line @typescript-eslint/no-unused-vars
166 let path: string 184 let path: string
167 185
168 before(() => { 186 before(() => {
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts
index 6466888fb..145f43980 100644
--- a/server/tests/api/check-params/video-blacklist.ts
+++ b/server/tests/api/check-params/video-blacklist.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4 4
@@ -7,25 +7,24 @@ import {
7 createUser, 7 createUser,
8 doubleFollow, 8 doubleFollow,
9 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
10 flushTests,
11 getBlacklistedVideosList, 10 getBlacklistedVideosList,
12 getVideo, 11 getVideo,
13 getVideoWithToken, 12 getVideoWithToken,
14 killallServers,
15 makePostBodyRequest, 13 makePostBodyRequest,
16 makePutBodyRequest, 14 makePutBodyRequest,
17 removeVideoFromBlacklist, 15 removeVideoFromBlacklist,
18 ServerInfo, 16 ServerInfo,
19 setAccessTokensToServers, 17 setAccessTokensToServers,
20 uploadVideo, 18 uploadVideo,
21 userLogin, waitJobs 19 userLogin,
20 waitJobs
22} from '../../../../shared/extra-utils' 21} from '../../../../shared/extra-utils'
23import { 22import {
24 checkBadCountPagination, 23 checkBadCountPagination,
25 checkBadSortPagination, 24 checkBadSortPagination,
26 checkBadStartPagination 25 checkBadStartPagination
27} from '../../../../shared/extra-utils/requests/check-api-params' 26} from '../../../../shared/extra-utils/requests/check-api-params'
28import { VideoDetails, VideoBlacklistType } from '../../../../shared/models/videos' 27import { VideoBlacklistType, VideoDetails } from '../../../../shared/models/videos'
29import { expect } from 'chai' 28import { expect } from 'chai'
30 29
31describe('Test video blacklist API validators', function () { 30describe('Test video blacklist API validators', function () {
@@ -48,14 +47,14 @@ describe('Test video blacklist API validators', function () {
48 { 47 {
49 const username = 'user1' 48 const username = 'user1'
50 const password = 'my super password' 49 const password = 'my super password'
51 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: username, password: password }) 50 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: username, password: password })
52 userAccessToken1 = await userLogin(servers[0], { username, password }) 51 userAccessToken1 = await userLogin(servers[0], { username, password })
53 } 52 }
54 53
55 { 54 {
56 const username = 'user2' 55 const username = 'user2'
57 const password = 'my super password' 56 const password = 'my super password'
58 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: username, password: password }) 57 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: username, password: password })
59 userAccessToken2 = await userLogin(servers[0], { username, password }) 58 userAccessToken2 = await userLogin(servers[0], { username, password })
60 } 59 }
61 60
@@ -120,7 +119,7 @@ describe('Test video blacklist API validators', function () {
120 119
121 it('Should succeed with the correct params', async function () { 120 it('Should succeed with the correct params', async function () {
122 const path = basePath + servers[0].video.uuid + '/blacklist' 121 const path = basePath + servers[0].video.uuid + '/blacklist'
123 const fields = { } 122 const fields = {}
124 123
125 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 }) 124 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 })
126 }) 125 })
diff --git a/server/tests/api/check-params/video-captions.ts b/server/tests/api/check-params/video-captions.ts
index 6ddc20d69..a5f5c3322 100644
--- a/server/tests/api/check-params/video-captions.ts
+++ b/server/tests/api/check-params/video-captions.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
@@ -50,7 +50,7 @@ describe('Test video captions API validator', function () {
50 describe('When adding video caption', function () { 50 describe('When adding video caption', function () {
51 const fields = { } 51 const fields = { }
52 const attaches = { 52 const attaches = {
53 'captionfile': join(__dirname, '..', '..', 'fixtures', 'subtitle-good1.vtt') 53 captionfile: join(__dirname, '..', '..', 'fixtures', 'subtitle-good1.vtt')
54 } 54 }
55 55
56 it('Should fail without a valid uuid', async function () { 56 it('Should fail without a valid uuid', async function () {
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts
index de88298d1..2795ad7d5 100644
--- a/server/tests/api/check-params/video-channels.ts
+++ b/server/tests/api/check-params/video-channels.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { omit } from 'lodash' 4import { omit } from 'lodash'
@@ -243,7 +243,7 @@ describe('Test video channels API validator', function () {
243 it('Should fail with an incorrect input file', async function () { 243 it('Should fail with an incorrect input file', async function () {
244 const fields = {} 244 const fields = {}
245 const attaches = { 245 const attaches = {
246 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4') 246 avatarfile: join(__dirname, '..', '..', 'fixtures', 'video_short.mp4')
247 } 247 }
248 await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) 248 await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches })
249 }) 249 })
@@ -251,7 +251,7 @@ describe('Test video channels API validator', function () {
251 it('Should fail with a big file', async function () { 251 it('Should fail with a big file', async function () {
252 const fields = {} 252 const fields = {}
253 const attaches = { 253 const attaches = {
254 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') 254 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
255 } 255 }
256 await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) 256 await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches })
257 }) 257 })
@@ -259,7 +259,7 @@ describe('Test video channels API validator', function () {
259 it('Should fail with an unauthenticated user', async function () { 259 it('Should fail with an unauthenticated user', async function () {
260 const fields = {} 260 const fields = {}
261 const attaches = { 261 const attaches = {
262 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 262 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
263 } 263 }
264 await makeUploadRequest({ 264 await makeUploadRequest({
265 url: server.url, 265 url: server.url,
@@ -273,7 +273,7 @@ describe('Test video channels API validator', function () {
273 it('Should succeed with the correct params', async function () { 273 it('Should succeed with the correct params', async function () {
274 const fields = {} 274 const fields = {}
275 const attaches = { 275 const attaches = {
276 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 276 avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
277 } 277 }
278 await makeUploadRequest({ 278 await makeUploadRequest({
279 url: server.url, 279 url: server.url,
@@ -324,7 +324,7 @@ describe('Test video channels API validator', function () {
324 }) 324 })
325 325
326 it('Should fail with an unknown video channel id', async function () { 326 it('Should fail with an unknown video channel id', async function () {
327 await deleteVideoChannel(server.url, server.accessToken,'super_channel2', 404) 327 await deleteVideoChannel(server.url, server.accessToken, 'super_channel2', 404)
328 }) 328 })
329 329
330 it('Should succeed with the correct parameters', async function () { 330 it('Should succeed with the correct parameters', async function () {
diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts
index 5cf90bacc..181282ce1 100644
--- a/server/tests/api/check-params/video-comments.ts
+++ b/server/tests/api/check-params/video-comments.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -29,6 +29,7 @@ describe('Test video comments API validator', function () {
29 let server: ServerInfo 29 let server: ServerInfo
30 let videoUUID: string 30 let videoUUID: string
31 let userAccessToken: string 31 let userAccessToken: string
32 let userAccessToken2: string
32 let commentId: number 33 let commentId: number
33 34
34 // --------------------------------------------------------------- 35 // ---------------------------------------------------------------
@@ -53,13 +54,16 @@ describe('Test video comments API validator', function () {
53 } 54 }
54 55
55 { 56 {
56 const user = { 57 const user = { username: 'user1', password: 'my super password' }
57 username: 'user1',
58 password: 'my super password'
59 }
60 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) 58 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
61 userAccessToken = await userLogin(server, user) 59 userAccessToken = await userLogin(server, user)
62 } 60 }
61
62 {
63 const user = { username: 'user2', password: 'my super password' }
64 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
65 userAccessToken2 = await userLogin(server, user)
66 }
63 }) 67 })
64 68
65 describe('When listing video comment threads', function () { 69 describe('When listing video comment threads', function () {
@@ -133,7 +137,7 @@ describe('Test video comments API validator', function () {
133 137
134 it('Should fail with a long comment', async function () { 138 it('Should fail with a long comment', async function () {
135 const fields = { 139 const fields = {
136 text: 'h'.repeat(3001) 140 text: 'h'.repeat(10001)
137 } 141 }
138 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields }) 142 await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields })
139 }) 143 })
@@ -176,7 +180,7 @@ describe('Test video comments API validator', function () {
176 180
177 it('Should fail with a long comment', async function () { 181 it('Should fail with a long comment', async function () {
178 const fields = { 182 const fields = {
179 text: 'h'.repeat(3001) 183 text: 'h'.repeat(10001)
180 } 184 }
181 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields }) 185 await makePostBodyRequest({ url: server.url, path: pathComment, token: server.accessToken, fields })
182 }) 186 })
@@ -224,6 +228,40 @@ describe('Test video comments API validator', function () {
224 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 }) 228 await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 })
225 }) 229 })
226 230
231 it('Should succeed with the same user', async function () {
232 let commentToDelete: number
233
234 {
235 const res = await addVideoCommentThread(server.url, userAccessToken, videoUUID, 'hello')
236 commentToDelete = res.body.comment.id
237 }
238
239 const path = '/api/v1/videos/' + videoUUID + '/comments/' + commentToDelete
240
241 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 })
242 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 })
243 })
244
245 it('Should succeed with the owner of the video', async function () {
246 let commentToDelete: number
247 let anotherVideoUUID: string
248
249 {
250 const res = await uploadVideo(server.url, userAccessToken, { name: 'video' })
251 anotherVideoUUID = res.body.video.uuid
252 }
253
254 {
255 const res = await addVideoCommentThread(server.url, server.accessToken, anotherVideoUUID, 'hello')
256 commentToDelete = res.body.comment.id
257 }
258
259 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
260
261 await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 })
262 await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 })
263 })
264
227 it('Should succeed with the correct parameters', async function () { 265 it('Should succeed with the correct parameters', async function () {
228 await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 }) 266 await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 })
229 }) 267 })
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts
index 231d5cc85..dbea39c48 100644
--- a/server/tests/api/check-params/video-imports.ts
+++ b/server/tests/api/check-params/video-imports.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import { omit } from 'lodash' 3import { omit } from 'lodash'
4import 'mocha' 4import 'mocha'
@@ -29,6 +29,7 @@ describe('Test video imports API validator', function () {
29 const path = '/api/v1/videos/imports' 29 const path = '/api/v1/videos/imports'
30 let server: ServerInfo 30 let server: ServerInfo
31 let userAccessToken = '' 31 let userAccessToken = ''
32 // eslint-disable-next-line @typescript-eslint/no-unused-vars
32 let accountName: string 33 let accountName: string
33 let channelId: number 34 let channelId: number
34 35
@@ -48,7 +49,7 @@ describe('Test video imports API validator', function () {
48 49
49 { 50 {
50 const res = await getMyUserInformation(server.url, server.accessToken) 51 const res = await getMyUserInformation(server.url, server.accessToken)
51 channelId = res.body.videoChannels[ 0 ].id 52 channelId = res.body.videoChannels[0].id
52 accountName = res.body.account.name + '@' + res.body.account.host 53 accountName = res.body.account.name + '@' + res.body.account.host
53 } 54 }
54 }) 55 })
@@ -196,7 +197,7 @@ describe('Test video imports API validator', function () {
196 it('Should fail with an incorrect thumbnail file', async function () { 197 it('Should fail with an incorrect thumbnail file', async function () {
197 const fields = baseCorrectParams 198 const fields = baseCorrectParams
198 const attaches = { 199 const attaches = {
199 'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 200 thumbnailfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
200 } 201 }
201 202
202 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) 203 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
@@ -205,7 +206,7 @@ describe('Test video imports API validator', function () {
205 it('Should fail with a big thumbnail file', async function () { 206 it('Should fail with a big thumbnail file', async function () {
206 const fields = baseCorrectParams 207 const fields = baseCorrectParams
207 const attaches = { 208 const attaches = {
208 'thumbnailfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') 209 thumbnailfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
209 } 210 }
210 211
211 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) 212 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
@@ -214,7 +215,7 @@ describe('Test video imports API validator', function () {
214 it('Should fail with an incorrect preview file', async function () { 215 it('Should fail with an incorrect preview file', async function () {
215 const fields = baseCorrectParams 216 const fields = baseCorrectParams
216 const attaches = { 217 const attaches = {
217 'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') 218 previewfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png')
218 } 219 }
219 220
220 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) 221 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
@@ -223,7 +224,7 @@ describe('Test video imports API validator', function () {
223 it('Should fail with a big preview file', async function () { 224 it('Should fail with a big preview file', async function () {
224 const fields = baseCorrectParams 225 const fields = baseCorrectParams
225 const attaches = { 226 const attaches = {
226 'previewfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') 227 previewfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
227 } 228 }
228 229
229 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) 230 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
@@ -232,7 +233,7 @@ describe('Test video imports API validator', function () {
232 it('Should fail with an invalid torrent file', async function () { 233 it('Should fail with an invalid torrent file', async function () {
233 const fields = omit(baseCorrectParams, 'targetUrl') 234 const fields = omit(baseCorrectParams, 'targetUrl')
234 const attaches = { 235 const attaches = {
235 'torrentfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') 236 torrentfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png')
236 } 237 }
237 238
238 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) 239 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
@@ -303,7 +304,7 @@ describe('Test video imports API validator', function () {
303 304
304 fields = omit(fields, 'magnetUri') 305 fields = omit(fields, 'magnetUri')
305 const attaches = { 306 const attaches = {
306 'torrentfile': join(__dirname, '..', '..', 'fixtures', 'video-720p.torrent') 307 torrentfile: join(__dirname, '..', '..', 'fixtures', 'video-720p.torrent')
307 } 308 }
308 309
309 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches, statusCodeExpected: 409 }) 310 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches, statusCodeExpected: 409 })
diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts
index df158f3b1..0410e737a 100644
--- a/server/tests/api/check-params/video-playlists.ts
+++ b/server/tests/api/check-params/video-playlists.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
@@ -36,6 +36,7 @@ describe('Test video playlists API validator', function () {
36 let privatePlaylistUUID: string 36 let privatePlaylistUUID: string
37 let watchLaterPlaylistId: number 37 let watchLaterPlaylistId: number
38 let videoId: number 38 let videoId: number
39 // eslint-disable-next-line @typescript-eslint/no-unused-vars
39 let videoId2: number 40 let videoId2: number
40 let playlistElementId: number 41 let playlistElementId: number
41 42
@@ -449,7 +450,7 @@ describe('Test video playlists API validator', function () {
449 videoId3 = (await uploadVideoAndGetId({ server, videoName: 'video 3' })).id 450 videoId3 = (await uploadVideoAndGetId({ server, videoName: 'video 3' })).id
450 videoId4 = (await uploadVideoAndGetId({ server, videoName: 'video 4' })).id 451 videoId4 = (await uploadVideoAndGetId({ server, videoName: 'video 4' })).id
451 452
452 for (let id of [ videoId3, videoId4 ]) { 453 for (const id of [ videoId3, videoId4 ]) {
453 await addVideoInPlaylist({ 454 await addVideoInPlaylist({
454 url: server.url, 455 url: server.url,
455 token: server.accessToken, 456 token: server.accessToken,
@@ -476,7 +477,7 @@ describe('Test video playlists API validator', function () {
476 } 477 }
477 478
478 { 479 {
479 const params = getBase({}, { playlistId: 42, expectedStatus: 404 }) 480 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
480 await reorderVideosPlaylist(params) 481 await reorderVideosPlaylist(params)
481 } 482 }
482 }) 483 })
diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts
index 811756745..ec8654db2 100644
--- a/server/tests/api/check-params/videos-filter.ts
+++ b/server/tests/api/check-params/videos-filter.ts
@@ -1,10 +1,9 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
5 cleanupTests, 5 cleanupTests,
6 createUser, 6 createUser,
7 createVideoPlaylist,
8 flushAndRunServer, 7 flushAndRunServer,
9 makeGetRequest, 8 makeGetRequest,
10 ServerInfo, 9 ServerInfo,
@@ -13,7 +12,6 @@ import {
13 userLogin 12 userLogin
14} from '../../../../shared/extra-utils' 13} from '../../../../shared/extra-utils'
15import { UserRole } from '../../../../shared/models/users' 14import { UserRole } from '../../../../shared/models/users'
16import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
17 15
18async function testEndpoints (server: ServerInfo, token: string, filter: string, statusCodeExpected: number) { 16async function testEndpoints (server: ServerInfo, token: string, filter: string, statusCodeExpected: number) {
19 const paths = [ 17 const paths = [
@@ -77,7 +75,7 @@ describe('Test videos filters', function () {
77 }) 75 })
78 76
79 it('Should succeed with a good filter', async function () { 77 it('Should succeed with a good filter', async function () {
80 await testEndpoints(server, server.accessToken,'local', 200) 78 await testEndpoints(server, server.accessToken, 'local', 200)
81 }) 79 })
82 80
83 it('Should fail to list all-local with a simple user', async function () { 81 it('Should fail to list all-local with a simple user', async function () {
diff --git a/server/tests/api/check-params/videos-history.ts b/server/tests/api/check-params/videos-history.ts
index 3739e3fad..941f62654 100644
--- a/server/tests/api/check-params/videos-history.ts
+++ b/server/tests/api/check-params/videos-history.ts
@@ -1,6 +1,5 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai'
4import 'mocha' 3import 'mocha'
5import { 4import {
6 checkBadCountPagination, 5 checkBadCountPagination,
@@ -15,12 +14,10 @@ import {
15 uploadVideo 14 uploadVideo
16} from '../../../../shared/extra-utils' 15} from '../../../../shared/extra-utils'
17 16
18const expect = chai.expect
19
20describe('Test videos history API validator', function () { 17describe('Test videos history API validator', function () {
18 const myHistoryPath = '/api/v1/users/me/history/videos'
19 const myHistoryRemove = myHistoryPath + '/remove'
21 let watchingPath: string 20 let watchingPath: string
22 let myHistoryPath = '/api/v1/users/me/history/videos'
23 let myHistoryRemove = myHistoryPath + '/remove'
24 let server: ServerInfo 21 let server: ServerInfo
25 22
26 // --------------------------------------------------------------- 23 // ---------------------------------------------------------------
diff --git a/server/tests/api/check-params/videos-overviews.ts b/server/tests/api/check-params/videos-overviews.ts
new file mode 100644
index 000000000..69d7fc471
--- /dev/null
+++ b/server/tests/api/check-params/videos-overviews.ts
@@ -0,0 +1,33 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import { cleanupTests, flushAndRunServer, ServerInfo } from '../../../../shared/extra-utils'
5import { getVideosOverview } from '@shared/extra-utils/overviews/overviews'
6
7describe('Test videos overview', function () {
8 let server: ServerInfo
9
10 // ---------------------------------------------------------------
11
12 before(async function () {
13 this.timeout(30000)
14
15 server = await flushAndRunServer(1)
16 })
17
18 describe('When getting videos overview', function () {
19
20 it('Should fail with a bad pagination', async function () {
21 await getVideosOverview(server.url, 0, 400)
22 await getVideosOverview(server.url, 100, 400)
23 })
24
25 it('Should succeed with a good pagination', async function () {
26 await getVideosOverview(server.url, 1)
27 })
28 })
29
30 after(async function () {
31 await cleanupTests([ server ])
32 })
33})
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 16ef1c505..0d4665954 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { omit } from 'lodash' 4import { omit } from 'lodash'
@@ -56,8 +56,8 @@ describe('Test videos API validator', function () {
56 56
57 { 57 {
58 const res = await getMyUserInformation(server.url, server.accessToken) 58 const res = await getMyUserInformation(server.url, server.accessToken)
59 channelId = res.body.videoChannels[ 0 ].id 59 channelId = res.body.videoChannels[0].id
60 channelName = res.body.videoChannels[ 0 ].name 60 channelName = res.body.videoChannels[0].name
61 accountName = res.body.account.name + '@' + res.body.account.host 61 accountName = res.body.account.name + '@' + res.body.account.host
62 } 62 }
63 }) 63 })
@@ -182,7 +182,7 @@ describe('Test videos API validator', function () {
182 describe('When adding a video', function () { 182 describe('When adding a video', function () {
183 let baseCorrectParams 183 let baseCorrectParams
184 const baseCorrectAttaches = { 184 const baseCorrectAttaches = {
185 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.webm') 185 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.webm')
186 } 186 }
187 187
188 before(function () { 188 before(function () {
@@ -330,7 +330,7 @@ describe('Test videos API validator', function () {
330 }) 330 })
331 331
332 it('Should fail with a bad originally published at attribute', async function () { 332 it('Should fail with a bad originally published at attribute', async function () {
333 const fields = immutableAssign(baseCorrectParams, { 'originallyPublishedAt': 'toto' }) 333 const fields = immutableAssign(baseCorrectParams, { originallyPublishedAt: 'toto' })
334 const attaches = baseCorrectAttaches 334 const attaches = baseCorrectAttaches
335 335
336 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 336 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -345,12 +345,12 @@ describe('Test videos API validator', function () {
345 it('Should fail with an incorrect input file', async function () { 345 it('Should fail with an incorrect input file', async function () {
346 const fields = baseCorrectParams 346 const fields = baseCorrectParams
347 let attaches = { 347 let attaches = {
348 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm') 348 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm')
349 } 349 }
350 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 350 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
351 351
352 attaches = { 352 attaches = {
353 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv') 353 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv')
354 } 354 }
355 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 355 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
356 }) 356 })
@@ -358,8 +358,8 @@ describe('Test videos API validator', function () {
358 it('Should fail with an incorrect thumbnail file', async function () { 358 it('Should fail with an incorrect thumbnail file', async function () {
359 const fields = baseCorrectParams 359 const fields = baseCorrectParams
360 const attaches = { 360 const attaches = {
361 'thumbnailfile': join(root(), 'server', 'tests', 'fixtures', 'avatar.png'), 361 thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'avatar.png'),
362 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') 362 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4')
363 } 363 }
364 364
365 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 365 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -368,8 +368,8 @@ describe('Test videos API validator', function () {
368 it('Should fail with a big thumbnail file', async function () { 368 it('Should fail with a big thumbnail file', async function () {
369 const fields = baseCorrectParams 369 const fields = baseCorrectParams
370 const attaches = { 370 const attaches = {
371 'thumbnailfile': join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png'), 371 thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png'),
372 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') 372 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4')
373 } 373 }
374 374
375 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 375 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -378,8 +378,8 @@ describe('Test videos API validator', function () {
378 it('Should fail with an incorrect preview file', async function () { 378 it('Should fail with an incorrect preview file', async function () {
379 const fields = baseCorrectParams 379 const fields = baseCorrectParams
380 const attaches = { 380 const attaches = {
381 'previewfile': join(root(), 'server', 'tests', 'fixtures', 'avatar.png'), 381 previewfile: join(root(), 'server', 'tests', 'fixtures', 'avatar.png'),
382 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') 382 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4')
383 } 383 }
384 384
385 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 385 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -388,8 +388,8 @@ describe('Test videos API validator', function () {
388 it('Should fail with a big preview file', async function () { 388 it('Should fail with a big preview file', async function () {
389 const fields = baseCorrectParams 389 const fields = baseCorrectParams
390 const attaches = { 390 const attaches = {
391 'previewfile': join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png'), 391 previewfile: join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png'),
392 'videofile': join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') 392 videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4')
393 } 393 }
394 394
395 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 395 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
@@ -566,7 +566,7 @@ describe('Test videos API validator', function () {
566 it('Should fail with an incorrect thumbnail file', async function () { 566 it('Should fail with an incorrect thumbnail file', async function () {
567 const fields = baseCorrectParams 567 const fields = baseCorrectParams
568 const attaches = { 568 const attaches = {
569 'thumbnailfile': join(root(), 'server', 'tests', 'fixtures', 'avatar.png') 569 thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'avatar.png')
570 } 570 }
571 571
572 await makeUploadRequest({ 572 await makeUploadRequest({
@@ -582,7 +582,7 @@ describe('Test videos API validator', function () {
582 it('Should fail with a big thumbnail file', async function () { 582 it('Should fail with a big thumbnail file', async function () {
583 const fields = baseCorrectParams 583 const fields = baseCorrectParams
584 const attaches = { 584 const attaches = {
585 'thumbnailfile': join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png') 585 thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png')
586 } 586 }
587 587
588 await makeUploadRequest({ 588 await makeUploadRequest({
@@ -598,7 +598,7 @@ describe('Test videos API validator', function () {
598 it('Should fail with an incorrect preview file', async function () { 598 it('Should fail with an incorrect preview file', async function () {
599 const fields = baseCorrectParams 599 const fields = baseCorrectParams
600 const attaches = { 600 const attaches = {
601 'previewfile': join(root(), 'server', 'tests', 'fixtures', 'avatar.png') 601 previewfile: join(root(), 'server', 'tests', 'fixtures', 'avatar.png')
602 } 602 }
603 603
604 await makeUploadRequest({ 604 await makeUploadRequest({
@@ -614,7 +614,7 @@ describe('Test videos API validator', function () {
614 it('Should fail with a big preview file', async function () { 614 it('Should fail with a big preview file', async function () {
615 const fields = baseCorrectParams 615 const fields = baseCorrectParams
616 const attaches = { 616 const attaches = {
617 'previewfile': join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png') 617 previewfile: join(root(), 'server', 'tests', 'fixtures', 'avatar-big.png')
618 } 618 }
619 619
620 await makeUploadRequest({ 620 await makeUploadRequest({
diff --git a/server/tests/api/notifications/user-notifications.ts b/server/tests/api/notifications/user-notifications.ts
index 15a34f5aa..dfa2234da 100644
--- a/server/tests/api/notifications/user-notifications.ts
+++ b/server/tests/api/notifications/user-notifications.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -63,7 +63,7 @@ import { addUserSubscription, removeUserSubscription } from '../../../../shared/
63import { VideoPrivacy } from '../../../../shared/models/videos' 63import { VideoPrivacy } from '../../../../shared/models/videos'
64import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports' 64import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
65import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments' 65import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
66import * as uuidv4 from 'uuid/v4' 66import { v4 as uuidv4 } from 'uuid'
67import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/extra-utils/users/blocklist' 67import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/extra-utils/users/blocklist'
68import { CustomConfig } from '../../../../shared/models/server' 68import { CustomConfig } from '../../../../shared/models/server'
69import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 69import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
@@ -74,7 +74,7 @@ async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalPara
74 const name = 'remote video ' + uuidv4() 74 const name = 'remote video ' + uuidv4()
75 75
76 const data = Object.assign({ name }, additionalParams) 76 const data = Object.assign({ name }, additionalParams)
77 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data) 77 const res = await uploadVideo(servers[1].url, servers[1].accessToken, data)
78 78
79 await waitJobs(servers) 79 await waitJobs(servers)
80 80
@@ -85,7 +85,7 @@ async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParam
85 const name = 'local video ' + uuidv4() 85 const name = 'local video ' + uuidv4()
86 86
87 const data = Object.assign({ name }, additionalParams) 87 const data = Object.assign({ name }, additionalParams)
88 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data) 88 const res = await uploadVideo(servers[0].url, servers[0].accessToken, data)
89 89
90 await waitJobs(servers) 90 await waitJobs(servers)
91 91
@@ -95,9 +95,9 @@ async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParam
95describe('Test users notifications', function () { 95describe('Test users notifications', function () {
96 let servers: ServerInfo[] = [] 96 let servers: ServerInfo[] = []
97 let userAccessToken: string 97 let userAccessToken: string
98 let userNotifications: UserNotification[] = [] 98 const userNotifications: UserNotification[] = []
99 let adminNotifications: UserNotification[] = [] 99 const adminNotifications: UserNotification[] = []
100 let adminNotificationsServer2: UserNotification[] = [] 100 const adminNotificationsServer2: UserNotification[] = []
101 const emails: object[] = [] 101 const emails: object[] = []
102 let channelId: number 102 let channelId: number
103 103
@@ -142,8 +142,8 @@ describe('Test users notifications', function () {
142 password: 'super password' 142 password: 'super password'
143 } 143 }
144 await createUser({ 144 await createUser({
145 url: servers[ 0 ].url, 145 url: servers[0].url,
146 accessToken: servers[ 0 ].accessToken, 146 accessToken: servers[0].accessToken,
147 username: user.username, 147 username: user.username,
148 password: user.password, 148 password: user.password,
149 videoQuota: 10 * 1000 * 1000 149 videoQuota: 10 * 1000 * 1000
@@ -155,15 +155,15 @@ describe('Test users notifications', function () {
155 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings) 155 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings)
156 156
157 { 157 {
158 const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken) 158 const socket = getUserNotificationSocket(servers[0].url, userAccessToken)
159 socket.on('new-notification', n => userNotifications.push(n)) 159 socket.on('new-notification', n => userNotifications.push(n))
160 } 160 }
161 { 161 {
162 const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken) 162 const socket = getUserNotificationSocket(servers[0].url, servers[0].accessToken)
163 socket.on('new-notification', n => adminNotifications.push(n)) 163 socket.on('new-notification', n => adminNotifications.push(n))
164 } 164 }
165 { 165 {
166 const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken) 166 const socket = getUserNotificationSocket(servers[1].url, servers[1].accessToken)
167 socket.on('new-notification', n => adminNotificationsServer2.push(n)) 167 socket.on('new-notification', n => adminNotificationsServer2.push(n))
168 } 168 }
169 169
@@ -190,7 +190,7 @@ describe('Test users notifications', function () {
190 190
191 await uploadVideoByLocalAccount(servers) 191 await uploadVideoByLocalAccount(servers)
192 192
193 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) 193 const notification = await getLastNotification(servers[0].url, userAccessToken)
194 expect(notification).to.be.undefined 194 expect(notification).to.be.undefined
195 195
196 expect(emails).to.have.lengthOf(0) 196 expect(emails).to.have.lengthOf(0)
@@ -221,7 +221,7 @@ describe('Test users notifications', function () {
221 this.timeout(20000) 221 this.timeout(20000)
222 222
223 // In 2 seconds 223 // In 2 seconds
224 let updateAt = new Date(new Date().getTime() + 2000) 224 const updateAt = new Date(new Date().getTime() + 2000)
225 225
226 const data = { 226 const data = {
227 privacy: VideoPrivacy.PRIVATE, 227 privacy: VideoPrivacy.PRIVATE,
@@ -240,7 +240,7 @@ describe('Test users notifications', function () {
240 this.timeout(50000) 240 this.timeout(50000)
241 241
242 // In 2 seconds 242 // In 2 seconds
243 let updateAt = new Date(new Date().getTime() + 2000) 243 const updateAt = new Date(new Date().getTime() + 2000)
244 244
245 const data = { 245 const data = {
246 privacy: VideoPrivacy.PRIVATE, 246 privacy: VideoPrivacy.PRIVATE,
@@ -259,7 +259,7 @@ describe('Test users notifications', function () {
259 it('Should not send a notification before the video is published', async function () { 259 it('Should not send a notification before the video is published', async function () {
260 this.timeout(20000) 260 this.timeout(20000)
261 261
262 let updateAt = new Date(new Date().getTime() + 1000000) 262 const updateAt = new Date(new Date().getTime() + 1000000)
263 263
264 const data = { 264 const data = {
265 privacy: VideoPrivacy.PRIVATE, 265 privacy: VideoPrivacy.PRIVATE,
@@ -386,7 +386,7 @@ describe('Test users notifications', function () {
386 it('Should not send a new comment notification if the account is muted', async function () { 386 it('Should not send a new comment notification if the account is muted', async function () {
387 this.timeout(10000) 387 this.timeout(10000)
388 388
389 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') 389 await addAccountToAccountBlocklist(servers[0].url, userAccessToken, 'root')
390 390
391 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 391 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
392 const uuid = resVideo.body.video.uuid 392 const uuid = resVideo.body.video.uuid
@@ -397,7 +397,7 @@ describe('Test users notifications', function () {
397 await wait(500) 397 await wait(500)
398 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') 398 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
399 399
400 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') 400 await removeAccountFromAccountBlocklist(servers[0].url, userAccessToken, 'root')
401 }) 401 })
402 402
403 it('Should send a new comment notification after a local comment on my video', async function () { 403 it('Should send a new comment notification after a local comment on my video', async function () {
@@ -456,9 +456,9 @@ describe('Test users notifications', function () {
456 await waitJobs(servers) 456 await waitJobs(servers)
457 457
458 { 458 {
459 const resThread = await addVideoCommentThread(servers[ 1 ].url, servers[ 1 ].accessToken, uuid, 'comment') 459 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
460 const threadId = resThread.body.comment.id 460 const threadId = resThread.body.comment.id
461 await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, uuid, threadId, 'reply') 461 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
462 } 462 }
463 463
464 await waitJobs(servers) 464 await waitJobs(servers)
@@ -530,7 +530,7 @@ describe('Test users notifications', function () {
530 it('Should not send a new mention notification if the account is muted', async function () { 530 it('Should not send a new mention notification if the account is muted', async function () {
531 this.timeout(10000) 531 this.timeout(10000)
532 532
533 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') 533 await addAccountToAccountBlocklist(servers[0].url, userAccessToken, 'root')
534 534
535 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 535 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
536 const uuid = resVideo.body.video.uuid 536 const uuid = resVideo.body.video.uuid
@@ -541,7 +541,7 @@ describe('Test users notifications', function () {
541 await wait(500) 541 await wait(500)
542 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') 542 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
543 543
544 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') 544 await removeAccountFromAccountBlocklist(servers[0].url, userAccessToken, 'root')
545 }) 545 })
546 546
547 it('Should not send a new mention notification if the remote account mention a local account', async function () { 547 it('Should not send a new mention notification if the remote account mention a local account', async function () {
@@ -585,7 +585,7 @@ describe('Test users notifications', function () {
585 585
586 await waitJobs(servers) 586 await waitJobs(servers)
587 587
588 const text1 = `hello @user_1@localhost:${servers[ 0 ].port} 1` 588 const text1 = `hello @user_1@localhost:${servers[0].port} 1`
589 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, text1) 589 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, text1)
590 const server2ThreadId = resThread.body.comment.id 590 const server2ThreadId = resThread.body.comment.id
591 591
@@ -596,7 +596,7 @@ describe('Test users notifications', function () {
596 const server1ThreadId = resThread2.body.data[0].id 596 const server1ThreadId = resThread2.body.data[0].id
597 await checkCommentMention(baseParams, uuid, server1ThreadId, server1ThreadId, 'super root 2 name', 'presence') 597 await checkCommentMention(baseParams, uuid, server1ThreadId, server1ThreadId, 'super root 2 name', 'presence')
598 598
599 const text2 = `@user_1@localhost:${servers[ 0 ].port} hello 2 @root@localhost:${servers[ 0 ].port}` 599 const text2 = `@user_1@localhost:${servers[0].port} hello 2 @root@localhost:${servers[0].port}`
600 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, server2ThreadId, text2) 600 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, server2ThreadId, text2)
601 601
602 await waitJobs(servers) 602 await waitJobs(servers)
@@ -611,7 +611,7 @@ describe('Test users notifications', function () {
611 }) 611 })
612 }) 612 })
613 613
614 describe('Video abuse for moderators notification' , function () { 614 describe('Video abuse for moderators notification', function () {
615 let baseParams: CheckerBaseParams 615 let baseParams: CheckerBaseParams
616 616
617 before(() => { 617 before(() => {
@@ -722,7 +722,7 @@ describe('Test users notifications', function () {
722 await uploadVideoByRemoteAccount(servers, { waitTranscoding: false }) 722 await uploadVideoByRemoteAccount(servers, { waitTranscoding: false })
723 await waitJobs(servers) 723 await waitJobs(servers)
724 724
725 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) 725 const notification = await getLastNotification(servers[0].url, userAccessToken)
726 if (notification) { 726 if (notification) {
727 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED) 727 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
728 } 728 }
@@ -769,7 +769,7 @@ describe('Test users notifications', function () {
769 this.timeout(70000) 769 this.timeout(70000)
770 770
771 // In 2 seconds 771 // In 2 seconds
772 let updateAt = new Date(new Date().getTime() + 2000) 772 const updateAt = new Date(new Date().getTime() + 2000)
773 773
774 const data = { 774 const data = {
775 privacy: VideoPrivacy.PRIVATE, 775 privacy: VideoPrivacy.PRIVATE,
@@ -787,7 +787,7 @@ describe('Test users notifications', function () {
787 it('Should not send a notification before the video is published', async function () { 787 it('Should not send a notification before the video is published', async function () {
788 this.timeout(20000) 788 this.timeout(20000)
789 789
790 let updateAt = new Date(new Date().getTime() + 1000000) 790 const updateAt = new Date(new Date().getTime() + 1000000)
791 791
792 const data = { 792 const data = {
793 privacy: VideoPrivacy.PRIVATE, 793 privacy: VideoPrivacy.PRIVATE,
@@ -970,8 +970,8 @@ describe('Test users notifications', function () {
970 970
971 describe('New actor follow', function () { 971 describe('New actor follow', function () {
972 let baseParams: CheckerBaseParams 972 let baseParams: CheckerBaseParams
973 let myChannelName = 'super channel name' 973 const myChannelName = 'super channel name'
974 let myUserName = 'super user name' 974 const myUserName = 'super user name'
975 975
976 before(async () => { 976 before(async () => {
977 baseParams = { 977 baseParams = {
@@ -1024,25 +1024,26 @@ describe('Test users notifications', function () {
1024 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port) 1024 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1025 }) 1025 })
1026 1026
1027 it('Should notify when a local account is following one of our channel', async function () { 1027 // PeerTube does not support accout -> account follows
1028 this.timeout(10000) 1028 // it('Should notify when a local account is following one of our channel', async function () {
1029 1029 // this.timeout(10000)
1030 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:' + servers[0].port) 1030 //
1031 1031 // await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:' + servers[0].port)
1032 await waitJobs(servers) 1032 //
1033 1033 // await waitJobs(servers)
1034 await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence') 1034 //
1035 }) 1035 // await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
1036 1036 // })
1037 it('Should notify when a remote account is following one of our channel', async function () { 1037
1038 this.timeout(10000) 1038 // it('Should notify when a remote account is following one of our channel', async function () {
1039 1039 // this.timeout(10000)
1040 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:' + servers[0].port) 1040 //
1041 1041 // await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:' + servers[0].port)
1042 await waitJobs(servers) 1042 //
1043 1043 // await waitJobs(servers)
1044 await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence') 1044 //
1045 }) 1045 // await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
1046 // })
1046 }) 1047 })
1047 1048
1048 describe('Video-related notifications when video auto-blacklist is enabled', function () { 1049 describe('Video-related notifications when video auto-blacklist is enabled', function () {
@@ -1143,7 +1144,7 @@ describe('Test users notifications', function () {
1143 it('Should send unblacklist but not published/subscription notes after unblacklisted if scheduled update pending', async function () { 1144 it('Should send unblacklist but not published/subscription notes after unblacklisted if scheduled update pending', async function () {
1144 this.timeout(20000) 1145 this.timeout(20000)
1145 1146
1146 let updateAt = new Date(new Date().getTime() + 1000000) 1147 const updateAt = new Date(new Date().getTime() + 1000000)
1147 1148
1148 const name = 'video with auto-blacklist and future schedule ' + uuidv4() 1149 const name = 'video with auto-blacklist and future schedule ' + uuidv4()
1149 1150
@@ -1176,7 +1177,7 @@ describe('Test users notifications', function () {
1176 this.timeout(20000) 1177 this.timeout(20000)
1177 1178
1178 // In 2 seconds 1179 // In 2 seconds
1179 let updateAt = new Date(new Date().getTime() + 2000) 1180 const updateAt = new Date(new Date().getTime() + 2000)
1180 1181
1181 const name = 'video with schedule done and still auto-blacklisted ' + uuidv4() 1182 const name = 'video with schedule done and still auto-blacklisted ' + uuidv4()
1182 1183
@@ -1221,26 +1222,26 @@ describe('Test users notifications', function () {
1221 1222
1222 describe('Mark as read', function () { 1223 describe('Mark as read', function () {
1223 it('Should mark as read some notifications', async function () { 1224 it('Should mark as read some notifications', async function () {
1224 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3) 1225 const res = await getUserNotifications(servers[0].url, userAccessToken, 2, 3)
1225 const ids = res.body.data.map(n => n.id) 1226 const ids = res.body.data.map(n => n.id)
1226 1227
1227 await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids) 1228 await markAsReadNotifications(servers[0].url, userAccessToken, ids)
1228 }) 1229 })
1229 1230
1230 it('Should have the notifications marked as read', async function () { 1231 it('Should have the notifications marked as read', async function () {
1231 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10) 1232 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10)
1232 1233
1233 const notifications = res.body.data as UserNotification[] 1234 const notifications = res.body.data as UserNotification[]
1234 expect(notifications[ 0 ].read).to.be.false 1235 expect(notifications[0].read).to.be.false
1235 expect(notifications[ 1 ].read).to.be.false 1236 expect(notifications[1].read).to.be.false
1236 expect(notifications[ 2 ].read).to.be.true 1237 expect(notifications[2].read).to.be.true
1237 expect(notifications[ 3 ].read).to.be.true 1238 expect(notifications[3].read).to.be.true
1238 expect(notifications[ 4 ].read).to.be.true 1239 expect(notifications[4].read).to.be.true
1239 expect(notifications[ 5 ].read).to.be.false 1240 expect(notifications[5].read).to.be.false
1240 }) 1241 })
1241 1242
1242 it('Should only list read notifications', async function () { 1243 it('Should only list read notifications', async function () {
1243 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false) 1244 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10, false)
1244 1245
1245 const notifications = res.body.data as UserNotification[] 1246 const notifications = res.body.data as UserNotification[]
1246 for (const notification of notifications) { 1247 for (const notification of notifications) {
@@ -1249,7 +1250,7 @@ describe('Test users notifications', function () {
1249 }) 1250 })
1250 1251
1251 it('Should only list unread notifications', async function () { 1252 it('Should only list unread notifications', async function () {
1252 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true) 1253 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10, true)
1253 1254
1254 const notifications = res.body.data as UserNotification[] 1255 const notifications = res.body.data as UserNotification[]
1255 for (const notification of notifications) { 1256 for (const notification of notifications) {
@@ -1258,9 +1259,9 @@ describe('Test users notifications', function () {
1258 }) 1259 })
1259 1260
1260 it('Should mark as read all notifications', async function () { 1261 it('Should mark as read all notifications', async function () {
1261 await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken) 1262 await markAsReadAllNotifications(servers[0].url, userAccessToken)
1262 1263
1263 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true) 1264 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10, true)
1264 1265
1265 expect(res.body.total).to.equal(0) 1266 expect(res.body.total).to.equal(0)
1266 expect(res.body.data).to.have.lengthOf(0) 1267 expect(res.body.data).to.have.lengthOf(0)
diff --git a/server/tests/api/redundancy/index.ts b/server/tests/api/redundancy/index.ts
index 8e69b95a6..37dc3f88c 100644
--- a/server/tests/api/redundancy/index.ts
+++ b/server/tests/api/redundancy/index.ts
@@ -1 +1,3 @@
1import './redundancy-constraints'
1import './redundancy' 2import './redundancy'
3import './manage-redundancy'
diff --git a/server/tests/api/redundancy/manage-redundancy.ts b/server/tests/api/redundancy/manage-redundancy.ts
new file mode 100644
index 000000000..4253124c8
--- /dev/null
+++ b/server/tests/api/redundancy/manage-redundancy.ts
@@ -0,0 +1,373 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 cleanupTests,
7 doubleFollow,
8 flushAndRunMultipleServers,
9 getLocalIdByUUID,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo,
13 uploadVideoAndGetId,
14 waitUntilLog
15} from '../../../../shared/extra-utils'
16import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
17import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy, updateRedundancy } from '@shared/extra-utils/server/redundancy'
18import { VideoPrivacy, VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
19
20const expect = chai.expect
21
22describe('Test manage videos redundancy', function () {
23 const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ]
24
25 let servers: ServerInfo[]
26 let video1Server2UUID: string
27 let video2Server2UUID: string
28 let redundanciesToRemove: number[] = []
29
30 before(async function () {
31 this.timeout(120000)
32
33 const config = {
34 transcoding: {
35 hls: {
36 enabled: true
37 }
38 },
39 redundancy: {
40 videos: {
41 check_interval: '1 second',
42 strategies: [
43 {
44 strategy: 'recently-added',
45 min_lifetime: '1 hour',
46 size: '10MB',
47 min_views: 0
48 }
49 ]
50 }
51 }
52 }
53 servers = await flushAndRunMultipleServers(3, config)
54
55 // Get the access tokens
56 await setAccessTokensToServers(servers)
57
58 {
59 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' })
60 video1Server2UUID = res.body.video.uuid
61 }
62
63 {
64 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2' })
65 video2Server2UUID = res.body.video.uuid
66 }
67
68 await waitJobs(servers)
69
70 // Server 1 and server 2 follow each other
71 await doubleFollow(servers[0], servers[1])
72 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true)
73
74 await waitJobs(servers)
75 })
76
77 it('Should not have redundancies on server 3', async function () {
78 for (const target of targets) {
79 const res = await listVideoRedundancies({
80 url: servers[2].url,
81 accessToken: servers[2].accessToken,
82 target
83 })
84
85 expect(res.body.total).to.equal(0)
86 expect(res.body.data).to.have.lengthOf(0)
87 }
88 })
89
90 it('Should not have "remote-videos" redundancies on server 2', async function () {
91 this.timeout(120000)
92
93 await waitJobs(servers)
94 await waitUntilLog(servers[0], 'Duplicated ', 10)
95 await waitJobs(servers)
96
97 const res = await listVideoRedundancies({
98 url: servers[1].url,
99 accessToken: servers[1].accessToken,
100 target: 'remote-videos'
101 })
102
103 expect(res.body.total).to.equal(0)
104 expect(res.body.data).to.have.lengthOf(0)
105 })
106
107 it('Should have "my-videos" redundancies on server 2', async function () {
108 this.timeout(120000)
109
110 const res = await listVideoRedundancies({
111 url: servers[1].url,
112 accessToken: servers[1].accessToken,
113 target: 'my-videos'
114 })
115
116 expect(res.body.total).to.equal(2)
117
118 const videos = res.body.data as VideoRedundancy[]
119 expect(videos).to.have.lengthOf(2)
120
121 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
122 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
123
124 expect(videos1.name).to.equal('video 1 server 2')
125 expect(videos2.name).to.equal('video 2 server 2')
126
127 expect(videos1.redundancies.files).to.have.lengthOf(4)
128 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
129
130 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
131
132 for (const r of redundancies) {
133 expect(r.strategy).to.be.null
134 expect(r.fileUrl).to.exist
135 expect(r.createdAt).to.exist
136 expect(r.updatedAt).to.exist
137 expect(r.expiresOn).to.exist
138 }
139 })
140
141 it('Should not have "my-videos" redundancies on server 1', async function () {
142 const res = await listVideoRedundancies({
143 url: servers[0].url,
144 accessToken: servers[0].accessToken,
145 target: 'my-videos'
146 })
147
148 expect(res.body.total).to.equal(0)
149 expect(res.body.data).to.have.lengthOf(0)
150 })
151
152 it('Should have "remote-videos" redundancies on server 1', async function () {
153 this.timeout(120000)
154
155 const res = await listVideoRedundancies({
156 url: servers[0].url,
157 accessToken: servers[0].accessToken,
158 target: 'remote-videos'
159 })
160
161 expect(res.body.total).to.equal(2)
162
163 const videos = res.body.data as VideoRedundancy[]
164 expect(videos).to.have.lengthOf(2)
165
166 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
167 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
168
169 expect(videos1.name).to.equal('video 1 server 2')
170 expect(videos2.name).to.equal('video 2 server 2')
171
172 expect(videos1.redundancies.files).to.have.lengthOf(4)
173 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
174
175 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
176
177 for (const r of redundancies) {
178 expect(r.strategy).to.equal('recently-added')
179 expect(r.fileUrl).to.exist
180 expect(r.createdAt).to.exist
181 expect(r.updatedAt).to.exist
182 expect(r.expiresOn).to.exist
183 }
184 })
185
186 it('Should correctly paginate and sort results', async function () {
187 {
188 const res = await listVideoRedundancies({
189 url: servers[0].url,
190 accessToken: servers[0].accessToken,
191 target: 'remote-videos',
192 sort: 'name',
193 start: 0,
194 count: 2
195 })
196
197 const videos = res.body.data
198 expect(videos[0].name).to.equal('video 1 server 2')
199 expect(videos[1].name).to.equal('video 2 server 2')
200 }
201
202 {
203 const res = await listVideoRedundancies({
204 url: servers[0].url,
205 accessToken: servers[0].accessToken,
206 target: 'remote-videos',
207 sort: '-name',
208 start: 0,
209 count: 2
210 })
211
212 const videos = res.body.data
213 expect(videos[0].name).to.equal('video 2 server 2')
214 expect(videos[1].name).to.equal('video 1 server 2')
215 }
216
217 {
218 const res = await listVideoRedundancies({
219 url: servers[0].url,
220 accessToken: servers[0].accessToken,
221 target: 'remote-videos',
222 sort: '-name',
223 start: 1,
224 count: 1
225 })
226
227 const videos = res.body.data
228 expect(videos[0].name).to.equal('video 1 server 2')
229 }
230 })
231
232 it('Should manually add a redundancy and list it', async function () {
233 this.timeout(120000)
234
235 const uuid = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid
236 await waitJobs(servers)
237 const videoId = await getLocalIdByUUID(servers[0].url, uuid)
238
239 await addVideoRedundancy({
240 url: servers[0].url,
241 accessToken: servers[0].accessToken,
242 videoId
243 })
244
245 await waitJobs(servers)
246 await waitUntilLog(servers[0], 'Duplicated ', 15)
247 await waitJobs(servers)
248
249 {
250 const res = await listVideoRedundancies({
251 url: servers[0].url,
252 accessToken: servers[0].accessToken,
253 target: 'remote-videos',
254 sort: '-name',
255 start: 0,
256 count: 5
257 })
258
259 const videos = res.body.data
260 expect(videos[0].name).to.equal('video 3 server 2')
261
262 const video = videos[0]
263 expect(video.redundancies.files).to.have.lengthOf(4)
264 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
265
266 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
267
268 for (const r of redundancies) {
269 redundanciesToRemove.push(r.id)
270
271 expect(r.strategy).to.equal('manual')
272 expect(r.fileUrl).to.exist
273 expect(r.createdAt).to.exist
274 expect(r.updatedAt).to.exist
275 expect(r.expiresOn).to.be.null
276 }
277 }
278
279 const res = await listVideoRedundancies({
280 url: servers[1].url,
281 accessToken: servers[1].accessToken,
282 target: 'my-videos',
283 sort: '-name',
284 start: 0,
285 count: 5
286 })
287
288 const videos = res.body.data
289 expect(videos[0].name).to.equal('video 3 server 2')
290
291 const video = videos[0]
292 expect(video.redundancies.files).to.have.lengthOf(4)
293 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
294
295 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
296
297 for (const r of redundancies) {
298 expect(r.strategy).to.be.null
299 expect(r.fileUrl).to.exist
300 expect(r.createdAt).to.exist
301 expect(r.updatedAt).to.exist
302 expect(r.expiresOn).to.be.null
303 }
304 })
305
306 it('Should manually remove a redundancy and remove it from the list', async function () {
307 this.timeout(120000)
308
309 for (const redundancyId of redundanciesToRemove) {
310 await removeVideoRedundancy({
311 url: servers[0].url,
312 accessToken: servers[0].accessToken,
313 redundancyId
314 })
315 }
316
317 {
318 const res = await listVideoRedundancies({
319 url: servers[0].url,
320 accessToken: servers[0].accessToken,
321 target: 'remote-videos',
322 sort: '-name',
323 start: 0,
324 count: 5
325 })
326
327 const videos = res.body.data
328 expect(videos).to.have.lengthOf(2)
329
330 expect(videos[0].name).to.equal('video 2 server 2')
331
332 redundanciesToRemove = []
333 const video = videos[0]
334 expect(video.redundancies.files).to.have.lengthOf(4)
335 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
336
337 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
338
339 for (const r of redundancies) {
340 redundanciesToRemove.push(r.id)
341 }
342 }
343 })
344
345 it('Should remove another (auto) redundancy', async function () {
346 {
347 for (const redundancyId of redundanciesToRemove) {
348 await removeVideoRedundancy({
349 url: servers[0].url,
350 accessToken: servers[0].accessToken,
351 redundancyId
352 })
353 }
354
355 const res = await listVideoRedundancies({
356 url: servers[0].url,
357 accessToken: servers[0].accessToken,
358 target: 'remote-videos',
359 sort: '-name',
360 start: 0,
361 count: 5
362 })
363
364 const videos = res.body.data
365 expect(videos[0].name).to.equal('video 1 server 2')
366 expect(videos).to.have.lengthOf(1)
367 }
368 })
369
370 after(async function () {
371 await cleanupTests(servers)
372 })
373})
diff --git a/server/tests/api/redundancy/redundancy-constraints.ts b/server/tests/api/redundancy/redundancy-constraints.ts
new file mode 100644
index 000000000..4fd8f065c
--- /dev/null
+++ b/server/tests/api/redundancy/redundancy-constraints.ts
@@ -0,0 +1,200 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 cleanupTests,
7 flushAndRunServer,
8 follow,
9 killallServers,
10 reRunServer,
11 ServerInfo,
12 setAccessTokensToServers,
13 uploadVideo,
14 waitUntilLog
15} from '../../../../shared/extra-utils'
16import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
17import { listVideoRedundancies, updateRedundancy } from '@shared/extra-utils/server/redundancy'
18
19const expect = chai.expect
20
21describe('Test redundancy constraints', function () {
22 let remoteServer: ServerInfo
23 let localServer: ServerInfo
24 let servers: ServerInfo[]
25
26 async function getTotalRedundanciesLocalServer () {
27 const res = await listVideoRedundancies({
28 url: localServer.url,
29 accessToken: localServer.accessToken,
30 target: 'my-videos'
31 })
32
33 return res.body.total
34 }
35
36 async function getTotalRedundanciesRemoteServer () {
37 const res = await listVideoRedundancies({
38 url: remoteServer.url,
39 accessToken: remoteServer.accessToken,
40 target: 'remote-videos'
41 })
42
43 return res.body.total
44 }
45
46 before(async function () {
47 this.timeout(120000)
48
49 {
50 const config = {
51 redundancy: {
52 videos: {
53 check_interval: '1 second',
54 strategies: [
55 {
56 strategy: 'recently-added',
57 min_lifetime: '1 hour',
58 size: '100MB',
59 min_views: 0
60 }
61 ]
62 }
63 }
64 }
65 remoteServer = await flushAndRunServer(1, config)
66 }
67
68 {
69 const config = {
70 remote_redundancy: {
71 videos: {
72 accept_from: 'nobody'
73 }
74 }
75 }
76 localServer = await flushAndRunServer(2, config)
77 }
78
79 servers = [ remoteServer, localServer ]
80
81 // Get the access tokens
82 await setAccessTokensToServers(servers)
83
84 await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 1 server 2' })
85
86 await waitJobs(servers)
87
88 // Server 1 and server 2 follow each other
89 await follow(remoteServer.url, [ localServer.url ], remoteServer.accessToken)
90 await waitJobs(servers)
91 await updateRedundancy(remoteServer.url, remoteServer.accessToken, localServer.host, true)
92
93 await waitJobs(servers)
94 })
95
96 it('Should have redundancy on server 1 but not on server 2 with a nobody filter', async function () {
97 this.timeout(120000)
98
99 await waitJobs(servers)
100 await waitUntilLog(remoteServer, 'Duplicated ', 5)
101 await waitJobs(servers)
102
103 {
104 const total = await getTotalRedundanciesRemoteServer()
105 expect(total).to.equal(1)
106 }
107
108 {
109 const total = await getTotalRedundanciesLocalServer()
110 expect(total).to.equal(0)
111 }
112 })
113
114 it('Should have redundancy on server 1 and on server 2 with an anybody filter', async function () {
115 this.timeout(120000)
116
117 const config = {
118 remote_redundancy: {
119 videos: {
120 accept_from: 'anybody'
121 }
122 }
123 }
124 await killallServers([ localServer ])
125 await reRunServer(localServer, config)
126
127 await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 2 server 2' })
128
129 await waitJobs(servers)
130 await waitUntilLog(remoteServer, 'Duplicated ', 10)
131 await waitJobs(servers)
132
133 {
134 const total = await getTotalRedundanciesRemoteServer()
135 expect(total).to.equal(2)
136 }
137
138 {
139 const total = await getTotalRedundanciesLocalServer()
140 expect(total).to.equal(1)
141 }
142 })
143
144 it('Should have redundancy on server 1 but not on server 2 with a followings filter', async function () {
145 this.timeout(120000)
146
147 const config = {
148 remote_redundancy: {
149 videos: {
150 accept_from: 'followings'
151 }
152 }
153 }
154 await killallServers([ localServer ])
155 await reRunServer(localServer, config)
156
157 await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 3 server 2' })
158
159 await waitJobs(servers)
160 await waitUntilLog(remoteServer, 'Duplicated ', 15)
161 await waitJobs(servers)
162
163 {
164 const total = await getTotalRedundanciesRemoteServer()
165 expect(total).to.equal(3)
166 }
167
168 {
169 const total = await getTotalRedundanciesLocalServer()
170 expect(total).to.equal(1)
171 }
172 })
173
174 it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () {
175 this.timeout(120000)
176
177 await follow(localServer.url, [ remoteServer.url ], localServer.accessToken)
178 await waitJobs(servers)
179
180 await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 4 server 2' })
181
182 await waitJobs(servers)
183 await waitUntilLog(remoteServer, 'Duplicated ', 20)
184 await waitJobs(servers)
185
186 {
187 const total = await getTotalRedundanciesRemoteServer()
188 expect(total).to.equal(4)
189 }
190
191 {
192 const total = await getTotalRedundanciesLocalServer()
193 expect(total).to.equal(2)
194 }
195 })
196
197 after(async function () {
198 await cleanupTests(servers)
199 })
200})
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index 1cdf93aa1..c5037a541 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -1,11 +1,12 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { VideoDetails } from '../../../../shared/models/videos' 5import { VideoDetails } from '../../../../shared/models/videos'
6import { 6import {
7 checkSegmentHash, 7 checkSegmentHash,
8 checkVideoFilesWereRemoved, cleanupTests, 8 checkVideoFilesWereRemoved,
9 cleanupTests,
9 doubleFollow, 10 doubleFollow,
10 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
11 getFollowingListPaginationAndSort, 12 getFollowingListPaginationAndSort,
@@ -28,11 +29,16 @@ import {
28import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 29import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
29 30
30import * as magnetUtil from 'magnet-uri' 31import * as magnetUtil from 'magnet-uri'
31import { updateRedundancy } from '../../../../shared/extra-utils/server/redundancy' 32import {
33 addVideoRedundancy,
34 listVideoRedundancies,
35 removeVideoRedundancy,
36 updateRedundancy
37} from '../../../../shared/extra-utils/server/redundancy'
32import { ActorFollow } from '../../../../shared/models/actors' 38import { ActorFollow } from '../../../../shared/models/actors'
33import { readdir } from 'fs-extra' 39import { readdir } from 'fs-extra'
34import { join } from 'path' 40import { join } from 'path'
35import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy' 41import { VideoRedundancy, VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../../shared/models/redundancy'
36import { getStats } from '../../../../shared/extra-utils/server/stats' 42import { getStats } from '../../../../shared/extra-utils/server/stats'
37import { ServerStats } from '../../../../shared/models/server/server-stats.model' 43import { ServerStats } from '../../../../shared/models/server/server-stats.model'
38 44
@@ -40,6 +46,7 @@ const expect = chai.expect
40 46
41let servers: ServerInfo[] = [] 47let servers: ServerInfo[] = []
42let video1Server2UUID: string 48let video1Server2UUID: string
49let video1Server2Id: number
43 50
44function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) { 51function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) {
45 const parsed = magnetUtil.decode(file.magnetUri) 52 const parsed = magnetUtil.decode(file.magnetUri)
@@ -52,7 +59,19 @@ function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: numbe
52 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length) 59 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length)
53} 60}
54 61
55async function flushAndRunServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { 62async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}) {
63 const strategies: any[] = []
64
65 if (strategy !== null) {
66 strategies.push(
67 immutableAssign({
68 min_lifetime: '1 hour',
69 strategy: strategy,
70 size: '400KB'
71 }, additionalParams)
72 )
73 }
74
56 const config = { 75 const config = {
57 transcoding: { 76 transcoding: {
58 hls: { 77 hls: {
@@ -62,36 +81,32 @@ async function flushAndRunServers (strategy: VideoRedundancyStrategy, additional
62 redundancy: { 81 redundancy: {
63 videos: { 82 videos: {
64 check_interval: '5 seconds', 83 check_interval: '5 seconds',
65 strategies: [ 84 strategies
66 immutableAssign({
67 min_lifetime: '1 hour',
68 strategy: strategy,
69 size: '400KB'
70 }, additionalParams)
71 ]
72 } 85 }
73 } 86 }
74 } 87 }
88
75 servers = await flushAndRunMultipleServers(3, config) 89 servers = await flushAndRunMultipleServers(3, config)
76 90
77 // Get the access tokens 91 // Get the access tokens
78 await setAccessTokensToServers(servers) 92 await setAccessTokensToServers(servers)
79 93
80 { 94 {
81 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 1 server 2' }) 95 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' })
82 video1Server2UUID = res.body.video.uuid 96 video1Server2UUID = res.body.video.uuid
97 video1Server2Id = res.body.video.id
83 98
84 await viewVideo(servers[ 1 ].url, video1Server2UUID) 99 await viewVideo(servers[1].url, video1Server2UUID)
85 } 100 }
86 101
87 await waitJobs(servers) 102 await waitJobs(servers)
88 103
89 // Server 1 and server 2 follow each other 104 // Server 1 and server 2 follow each other
90 await doubleFollow(servers[ 0 ], servers[ 1 ]) 105 await doubleFollow(servers[0], servers[1])
91 // Server 1 and server 3 follow each other 106 // Server 1 and server 3 follow each other
92 await doubleFollow(servers[ 0 ], servers[ 2 ]) 107 await doubleFollow(servers[0], servers[2])
93 // Server 2 and server 3 follow each other 108 // Server 2 and server 3 follow each other
94 await doubleFollow(servers[ 1 ], servers[ 2 ]) 109 await doubleFollow(servers[1], servers[2])
95 110
96 await waitJobs(servers) 111 await waitJobs(servers)
97} 112}
@@ -100,7 +115,7 @@ async function check1WebSeed (videoUUID?: string) {
100 if (!videoUUID) videoUUID = video1Server2UUID 115 if (!videoUUID) videoUUID = video1Server2UUID
101 116
102 const webseeds = [ 117 const webseeds = [
103 `http://localhost:${servers[ 1 ].port}/static/webseed/${videoUUID}` 118 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}`
104 ] 119 ]
105 120
106 for (const server of servers) { 121 for (const server of servers) {
@@ -118,8 +133,8 @@ async function check2Webseeds (videoUUID?: string) {
118 if (!videoUUID) videoUUID = video1Server2UUID 133 if (!videoUUID) videoUUID = video1Server2UUID
119 134
120 const webseeds = [ 135 const webseeds = [
121 `http://localhost:${servers[ 0 ].port}/static/redundancy/${videoUUID}`, 136 `http://localhost:${servers[0].port}/static/redundancy/${videoUUID}`,
122 `http://localhost:${servers[ 1 ].port}/static/webseed/${videoUUID}` 137 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}`
123 ] 138 ]
124 139
125 for (const server of servers) { 140 for (const server of servers) {
@@ -216,41 +231,50 @@ async function check1PlaylistRedundancies (videoUUID?: string) {
216 } 231 }
217} 232}
218 233
219async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) { 234async function checkStatsGlobal (strategy: VideoRedundancyStrategyWithManual) {
235 let totalSize: number = null
236 let statsLength = 1
237
238 if (strategy !== 'manual') {
239 totalSize = 409600
240 statsLength = 2
241 }
242
220 const res = await getStats(servers[0].url) 243 const res = await getStats(servers[0].url)
221 const data: ServerStats = res.body 244 const data: ServerStats = res.body
222 245
223 expect(data.videosRedundancy).to.have.lengthOf(1) 246 expect(data.videosRedundancy).to.have.lengthOf(statsLength)
224 const stat = data.videosRedundancy[0]
225 247
248 const stat = data.videosRedundancy[0]
226 expect(stat.strategy).to.equal(strategy) 249 expect(stat.strategy).to.equal(strategy)
227 expect(stat.totalSize).to.equal(409600) 250 expect(stat.totalSize).to.equal(totalSize)
251
252 return stat
253}
254
255async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategyWithManual) {
256 const stat = await checkStatsGlobal(strategy)
257
228 expect(stat.totalUsed).to.be.at.least(1).and.below(409601) 258 expect(stat.totalUsed).to.be.at.least(1).and.below(409601)
229 expect(stat.totalVideoFiles).to.equal(4) 259 expect(stat.totalVideoFiles).to.equal(4)
230 expect(stat.totalVideos).to.equal(1) 260 expect(stat.totalVideos).to.equal(1)
231} 261}
232 262
233async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) { 263async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategyWithManual) {
234 const res = await getStats(servers[0].url) 264 const stat = await checkStatsGlobal(strategy)
235 const data: ServerStats = res.body
236 265
237 expect(data.videosRedundancy).to.have.lengthOf(1)
238
239 const stat = data.videosRedundancy[0]
240 expect(stat.strategy).to.equal(strategy)
241 expect(stat.totalSize).to.equal(409600)
242 expect(stat.totalUsed).to.equal(0) 266 expect(stat.totalUsed).to.equal(0)
243 expect(stat.totalVideoFiles).to.equal(0) 267 expect(stat.totalVideoFiles).to.equal(0)
244 expect(stat.totalVideos).to.equal(0) 268 expect(stat.totalVideos).to.equal(0)
245} 269}
246 270
247async function enableRedundancyOnServer1 () { 271async function enableRedundancyOnServer1 () {
248 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) 272 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true)
249 273
250 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: '-createdAt' }) 274 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' })
251 const follows: ActorFollow[] = res.body.data 275 const follows: ActorFollow[] = res.body.data
252 const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) 276 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
253 const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) 277 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
254 278
255 expect(server3).to.not.be.undefined 279 expect(server3).to.not.be.undefined
256 expect(server3.following.hostRedundancyAllowed).to.be.false 280 expect(server3.following.hostRedundancyAllowed).to.be.false
@@ -260,12 +284,12 @@ async function enableRedundancyOnServer1 () {
260} 284}
261 285
262async function disableRedundancyOnServer1 () { 286async function disableRedundancyOnServer1 () {
263 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false) 287 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, false)
264 288
265 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: '-createdAt' }) 289 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' })
266 const follows: ActorFollow[] = res.body.data 290 const follows: ActorFollow[] = res.body.data
267 const server2 = follows.find(f => f.following.host === `localhost:${servers[ 1 ].port}`) 291 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
268 const server3 = follows.find(f => f.following.host === `localhost:${servers[ 2 ].port}`) 292 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
269 293
270 expect(server3).to.not.be.undefined 294 expect(server3).to.not.be.undefined
271 expect(server3.following.hostRedundancyAllowed).to.be.false 295 expect(server3.following.hostRedundancyAllowed).to.be.false
@@ -410,8 +434,8 @@ describe('Test videos redundancy', function () {
410 it('Should view 2 times the first video to have > min_views config', async function () { 434 it('Should view 2 times the first video to have > min_views config', async function () {
411 this.timeout(80000) 435 this.timeout(80000)
412 436
413 await viewVideo(servers[ 0 ].url, video1Server2UUID) 437 await viewVideo(servers[0].url, video1Server2UUID)
414 await viewVideo(servers[ 2 ].url, video1Server2UUID) 438 await viewVideo(servers[2].url, video1Server2UUID)
415 439
416 await wait(10000) 440 await wait(10000)
417 await waitJobs(servers) 441 await waitJobs(servers)
@@ -446,6 +470,74 @@ describe('Test videos redundancy', function () {
446 }) 470 })
447 }) 471 })
448 472
473 describe('With manual strategy', function () {
474 before(function () {
475 this.timeout(120000)
476
477 return flushAndRunServers(null)
478 })
479
480 it('Should have 1 webseed on the first video', async function () {
481 await check1WebSeed()
482 await check0PlaylistRedundancies()
483 await checkStatsWith1Webseed('manual')
484 })
485
486 it('Should create a redundancy on first video', async function () {
487 await addVideoRedundancy({
488 url: servers[0].url,
489 accessToken: servers[0].accessToken,
490 videoId: video1Server2Id
491 })
492 })
493
494 it('Should have 2 webseeds on the first video', async function () {
495 this.timeout(80000)
496
497 await waitJobs(servers)
498 await waitUntilLog(servers[0], 'Duplicated ', 5)
499 await waitJobs(servers)
500
501 await check2Webseeds()
502 await check1PlaylistRedundancies()
503 await checkStatsWith2Webseed('manual')
504 })
505
506 it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () {
507 this.timeout(80000)
508
509 const res = await listVideoRedundancies({
510 url: servers[0].url,
511 accessToken: servers[0].accessToken,
512 target: 'remote-videos'
513 })
514
515 const videos = res.body.data as VideoRedundancy[]
516 expect(videos).to.have.lengthOf(1)
517
518 const video = videos[0]
519 for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) {
520 await removeVideoRedundancy({
521 url: servers[0].url,
522 accessToken: servers[0].accessToken,
523 redundancyId: r.id
524 })
525 }
526
527 await waitJobs(servers)
528 await wait(5000)
529
530 await check1WebSeed()
531 await check0PlaylistRedundancies()
532
533 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ])
534 })
535
536 after(async function () {
537 await cleanupTests(servers)
538 })
539 })
540
449 describe('Test expiration', function () { 541 describe('Test expiration', function () {
450 const strategy = 'recently-added' 542 const strategy = 'recently-added'
451 543
@@ -528,7 +620,7 @@ describe('Test videos redundancy', function () {
528 await check1PlaylistRedundancies() 620 await check1PlaylistRedundancies()
529 await checkStatsWith2Webseed(strategy) 621 await checkStatsWith2Webseed(strategy)
530 622
531 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) 623 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2' })
532 video2Server2UUID = res.body.video.uuid 624 video2Server2UUID = res.body.video.uuid
533 }) 625 })
534 626
@@ -560,8 +652,8 @@ describe('Test videos redundancy', function () {
560 652
561 await waitJobs(servers) 653 await waitJobs(servers)
562 654
563 killallServers([ servers[ 0 ] ]) 655 killallServers([ servers[0] ])
564 await reRunServer(servers[ 0 ], { 656 await reRunServer(servers[0], {
565 redundancy: { 657 redundancy: {
566 videos: { 658 videos: {
567 check_interval: '1 second', 659 check_interval: '1 second',
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index d5f0a5457..d7e3ed5be 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -39,7 +39,7 @@ describe('Test ActivityPub video channels search', function () {
39 await setAccessTokensToServers(servers) 39 await setAccessTokensToServers(servers)
40 40
41 { 41 {
42 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: 'user1_server1', password: 'password' }) 42 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: 'user1_server1', password: 'password' })
43 const channel = { 43 const channel = {
44 name: 'channel1_server1', 44 name: 'channel1_server1',
45 displayName: 'Channel 1 server 1' 45 displayName: 'Channel 1 server 1'
@@ -49,7 +49,7 @@ describe('Test ActivityPub video channels search', function () {
49 49
50 { 50 {
51 const user = { username: 'user1_server2', password: 'password' } 51 const user = { username: 'user1_server2', password: 'password' }
52 await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) 52 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password })
53 userServer2Token = await userLogin(servers[1], user) 53 userServer2Token = await userLogin(servers[1], user)
54 54
55 const channel = { 55 const channel = {
@@ -70,8 +70,8 @@ describe('Test ActivityPub video channels search', function () {
70 this.timeout(15000) 70 this.timeout(15000)
71 71
72 { 72 {
73 const search = 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server3' 73 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server3'
74 const res = await searchVideoChannel(servers[ 0 ].url, search, servers[ 0 ].accessToken) 74 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken)
75 75
76 expect(res.body.total).to.equal(0) 76 expect(res.body.total).to.equal(0)
77 expect(res.body.data).to.be.an('array') 77 expect(res.body.data).to.be.an('array')
@@ -80,7 +80,7 @@ describe('Test ActivityPub video channels search', function () {
80 80
81 { 81 {
82 // Without token 82 // Without token
83 const search = 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server2' 83 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
84 const res = await searchVideoChannel(servers[0].url, search) 84 const res = await searchVideoChannel(servers[0].url, search)
85 85
86 expect(res.body.total).to.equal(0) 86 expect(res.body.total).to.equal(0)
@@ -91,35 +91,35 @@ describe('Test ActivityPub video channels search', function () {
91 91
92 it('Should search a local video channel', async function () { 92 it('Should search a local video channel', async function () {
93 const searches = [ 93 const searches = [
94 'http://localhost:' + servers[ 0 ].port + '/video-channels/channel1_server1', 94 'http://localhost:' + servers[0].port + '/video-channels/channel1_server1',
95 'channel1_server1@localhost:' + servers[ 0 ].port 95 'channel1_server1@localhost:' + servers[0].port
96 ] 96 ]
97 97
98 for (const search of searches) { 98 for (const search of searches) {
99 const res = await searchVideoChannel(servers[ 0 ].url, search) 99 const res = await searchVideoChannel(servers[0].url, search)
100 100
101 expect(res.body.total).to.equal(1) 101 expect(res.body.total).to.equal(1)
102 expect(res.body.data).to.be.an('array') 102 expect(res.body.data).to.be.an('array')
103 expect(res.body.data).to.have.lengthOf(1) 103 expect(res.body.data).to.have.lengthOf(1)
104 expect(res.body.data[ 0 ].name).to.equal('channel1_server1') 104 expect(res.body.data[0].name).to.equal('channel1_server1')
105 expect(res.body.data[ 0 ].displayName).to.equal('Channel 1 server 1') 105 expect(res.body.data[0].displayName).to.equal('Channel 1 server 1')
106 } 106 }
107 }) 107 })
108 108
109 it('Should search a remote video channel with URL or handle', async function () { 109 it('Should search a remote video channel with URL or handle', async function () {
110 const searches = [ 110 const searches = [
111 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server2', 111 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2',
112 'channel1_server2@localhost:' + servers[ 1 ].port 112 'channel1_server2@localhost:' + servers[1].port
113 ] 113 ]
114 114
115 for (const search of searches) { 115 for (const search of searches) {
116 const res = await searchVideoChannel(servers[ 0 ].url, search, servers[ 0 ].accessToken) 116 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken)
117 117
118 expect(res.body.total).to.equal(1) 118 expect(res.body.total).to.equal(1)
119 expect(res.body.data).to.be.an('array') 119 expect(res.body.data).to.be.an('array')
120 expect(res.body.data).to.have.lengthOf(1) 120 expect(res.body.data).to.have.lengthOf(1)
121 expect(res.body.data[ 0 ].name).to.equal('channel1_server2') 121 expect(res.body.data[0].name).to.equal('channel1_server2')
122 expect(res.body.data[ 0 ].displayName).to.equal('Channel 1 server 2') 122 expect(res.body.data[0].displayName).to.equal('Channel 1 server 2')
123 } 123 }
124 }) 124 })
125 125
@@ -137,13 +137,13 @@ describe('Test ActivityPub video channels search', function () {
137 137
138 await waitJobs(servers) 138 await waitJobs(servers)
139 139
140 const res = await getVideoChannelVideos(servers[0].url, null, 'channel1_server2@localhost:' + servers[ 1 ].port, 0, 5) 140 const res = await getVideoChannelVideos(servers[0].url, null, 'channel1_server2@localhost:' + servers[1].port, 0, 5)
141 expect(res.body.total).to.equal(0) 141 expect(res.body.total).to.equal(0)
142 expect(res.body.data).to.have.lengthOf(0) 142 expect(res.body.data).to.have.lengthOf(0)
143 }) 143 })
144 144
145 it('Should list video channel videos of server 2 with token', async function () { 145 it('Should list video channel videos of server 2 with token', async function () {
146 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'channel1_server2@localhost:' + servers[ 1 ].port, 0, 5) 146 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'channel1_server2@localhost:' + servers[1].port, 0, 5)
147 147
148 expect(res.body.total).to.equal(1) 148 expect(res.body.total).to.equal(1)
149 expect(res.body.data[0].name).to.equal('video 1 server 2') 149 expect(res.body.data[0].name).to.equal('video 1 server 2')
@@ -159,7 +159,7 @@ describe('Test ActivityPub video channels search', function () {
159 // Expire video channel 159 // Expire video channel
160 await wait(10000) 160 await wait(10000)
161 161
162 const search = 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server2' 162 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
163 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 163 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken)
164 expect(res.body.total).to.equal(1) 164 expect(res.body.total).to.equal(1)
165 expect(res.body.data).to.have.lengthOf(1) 165 expect(res.body.data).to.have.lengthOf(1)
@@ -182,12 +182,12 @@ describe('Test ActivityPub video channels search', function () {
182 // Expire video channel 182 // Expire video channel
183 await wait(10000) 183 await wait(10000)
184 184
185 const search = 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server2' 185 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
186 await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 186 await searchVideoChannel(servers[0].url, search, servers[0].accessToken)
187 187
188 await waitJobs(servers) 188 await waitJobs(servers)
189 189
190 const videoChannelName = 'channel1_server2@localhost:' + servers[ 1 ].port 190 const videoChannelName = 'channel1_server2@localhost:' + servers[1].port
191 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, videoChannelName, 0, 5, '-createdAt') 191 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, videoChannelName, 0, 5, '-createdAt')
192 192
193 expect(res.body.total).to.equal(2) 193 expect(res.body.total).to.equal(2)
@@ -204,7 +204,7 @@ describe('Test ActivityPub video channels search', function () {
204 // Expire video 204 // Expire video
205 await wait(10000) 205 await wait(10000)
206 206
207 const search = 'http://localhost:' + servers[ 1 ].port + '/video-channels/channel1_server2' 207 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
208 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 208 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken)
209 expect(res.body.total).to.equal(0) 209 expect(res.body.total).to.equal(0)
210 expect(res.body.data).to.have.lengthOf(0) 210 expect(res.body.data).to.have.lengthOf(0)
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index dbfefadda..c62dfca0d 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -34,12 +34,12 @@ describe('Test ActivityPub videos search', function () {
34 await setAccessTokensToServers(servers) 34 await setAccessTokensToServers(servers)
35 35
36 { 36 {
37 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video 1 on server 1' }) 37 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1 on server 1' })
38 videoServer1UUID = res.body.video.uuid 38 videoServer1UUID = res.body.video.uuid
39 } 39 }
40 40
41 { 41 {
42 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 1 on server 2' }) 42 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 on server 2' })
43 videoServer2UUID = res.body.video.uuid 43 videoServer2UUID = res.body.video.uuid
44 } 44 }
45 45
@@ -49,7 +49,7 @@ describe('Test ActivityPub videos search', function () {
49 it('Should not find a remote video', async function () { 49 it('Should not find a remote video', async function () {
50 { 50 {
51 const search = 'http://localhost:' + servers[1].port + '/videos/watch/43' 51 const search = 'http://localhost:' + servers[1].port + '/videos/watch/43'
52 const res = await searchVideoWithToken(servers[ 0 ].url, search, servers[ 0 ].accessToken) 52 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken)
53 53
54 expect(res.body.total).to.equal(0) 54 expect(res.body.total).to.equal(0)
55 expect(res.body.data).to.be.an('array') 55 expect(res.body.data).to.be.an('array')
diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts
index 7882d9373..4801fe04a 100644
--- a/server/tests/api/search/search-videos.ts
+++ b/server/tests/api/search/search-videos.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -78,7 +78,7 @@ describe('Test videos search', function () {
78 const attributes5 = immutableAssign(attributes1, { name: attributes1.name + ' - 5', licence: 2, language: undefined }) 78 const attributes5 = immutableAssign(attributes1, { name: attributes1.name + ' - 5', licence: 2, language: undefined })
79 await uploadVideo(server.url, server.accessToken, attributes5) 79 await uploadVideo(server.url, server.accessToken, attributes5)
80 80
81 const attributes6 = immutableAssign(attributes1, { name: attributes1.name + ' - 6', tags: [ 't1', 't2 '] }) 81 const attributes6 = immutableAssign(attributes1, { name: attributes1.name + ' - 6', tags: [ 't1', 't2' ] })
82 await uploadVideo(server.url, server.accessToken, attributes6) 82 await uploadVideo(server.url, server.accessToken, attributes6)
83 83
84 const attributes7 = immutableAssign(attributes1, { 84 const attributes7 = immutableAssign(attributes1, {
@@ -269,16 +269,16 @@ describe('Test videos search', function () {
269 { 269 {
270 const res = await advancedVideosSearch(server.url, query) 270 const res = await advancedVideosSearch(server.url, query)
271 expect(res.body.total).to.equal(2) 271 expect(res.body.total).to.equal(2)
272 expect(res.body.data[ 0 ].name).to.equal('1111 2222 3333 - 3') 272 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3')
273 expect(res.body.data[ 1 ].name).to.equal('1111 2222 3333 - 4') 273 expect(res.body.data[1].name).to.equal('1111 2222 3333 - 4')
274 } 274 }
275 275
276 { 276 {
277 const res = await advancedVideosSearch(server.url, immutableAssign(query, { languageOneOf: [ 'pl', 'en', '_unknown' ] })) 277 const res = await advancedVideosSearch(server.url, immutableAssign(query, { languageOneOf: [ 'pl', 'en', '_unknown' ] }))
278 expect(res.body.total).to.equal(3) 278 expect(res.body.total).to.equal(3)
279 expect(res.body.data[ 0 ].name).to.equal('1111 2222 3333 - 3') 279 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3')
280 expect(res.body.data[ 1 ].name).to.equal('1111 2222 3333 - 4') 280 expect(res.body.data[1].name).to.equal('1111 2222 3333 - 4')
281 expect(res.body.data[ 2 ].name).to.equal('1111 2222 3333 - 5') 281 expect(res.body.data[2].name).to.equal('1111 2222 3333 - 5')
282 } 282 }
283 283
284 { 284 {
diff --git a/server/tests/api/server/auto-follows.ts b/server/tests/api/server/auto-follows.ts
index a06f578fc..7efccc3e2 100644
--- a/server/tests/api/server/auto-follows.ts
+++ b/server/tests/api/server/auto-follows.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -59,9 +59,10 @@ async function server1Follows2 (servers: ServerInfo[]) {
59 59
60async function resetFollows (servers: ServerInfo[]) { 60async function resetFollows (servers: ServerInfo[]) {
61 try { 61 try {
62 await unfollow(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ]) 62 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
63 await unfollow(servers[ 1 ].url, servers[ 1 ].accessToken, servers[ 0 ]) 63 await unfollow(servers[1].url, servers[1].accessToken, servers[0])
64 } catch { /* empty */ } 64 } catch { /* empty */
65 }
65 66
66 await waitJobs(servers) 67 await waitJobs(servers)
67 68
@@ -163,8 +164,8 @@ describe('Test auto follows', function () {
163 await wait(5000) 164 await wait(5000)
164 await waitJobs(servers) 165 await waitJobs(servers)
165 166
166 await checkFollow(servers[ 0 ], servers[ 1 ], false) 167 await checkFollow(servers[0], servers[1], false)
167 await checkFollow(servers[ 1 ], servers[ 0 ], false) 168 await checkFollow(servers[1], servers[0], false)
168 }) 169 })
169 170
170 it('Should auto follow the index', async function () { 171 it('Should auto follow the index', async function () {
@@ -176,7 +177,7 @@ describe('Test auto follows', function () {
176 followings: { 177 followings: {
177 instance: { 178 instance: {
178 autoFollowIndex: { 179 autoFollowIndex: {
179 indexUrl: 'http://localhost:42100', 180 indexUrl: 'http://localhost:42100/api/v1/instances/hosts',
180 enabled: true 181 enabled: true
181 } 182 }
182 } 183 }
@@ -187,7 +188,7 @@ describe('Test auto follows', function () {
187 await wait(5000) 188 await wait(5000)
188 await waitJobs(servers) 189 await waitJobs(servers)
189 190
190 await checkFollow(servers[ 0 ], servers[ 1 ], true) 191 await checkFollow(servers[0], servers[1], true)
191 192
192 await resetFollows(servers) 193 await resetFollows(servers)
193 }) 194 })
@@ -200,8 +201,8 @@ describe('Test auto follows', function () {
200 await wait(5000) 201 await wait(5000)
201 await waitJobs(servers) 202 await waitJobs(servers)
202 203
203 await checkFollow(servers[ 0 ], servers[ 1 ], false) 204 await checkFollow(servers[0], servers[1], false)
204 await checkFollow(servers[ 0 ], servers[ 2 ], true) 205 await checkFollow(servers[0], servers[2], true)
205 }) 206 })
206 }) 207 })
207 208
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index cf99e5c0a..1d81e1dce 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
@@ -11,11 +11,14 @@ import {
11 getAbout, 11 getAbout,
12 getConfig, 12 getConfig,
13 getCustomConfig, 13 getCustomConfig,
14 killallServers, parallelTests, 14 killallServers,
15 parallelTests,
15 registerUser, 16 registerUser,
16 reRunServer, ServerInfo, 17 reRunServer,
18 ServerInfo,
17 setAccessTokensToServers, 19 setAccessTokensToServers,
18 updateCustomConfig, uploadVideo 20 updateCustomConfig,
21 uploadVideo
19} from '../../../../shared/extra-utils' 22} from '../../../../shared/extra-utils'
20import { ServerConfig } from '../../../../shared/models' 23import { ServerConfig } from '../../../../shared/models'
21 24
@@ -24,8 +27,7 @@ const expect = chai.expect
24function checkInitialConfig (server: ServerInfo, data: CustomConfig) { 27function checkInitialConfig (server: ServerInfo, data: CustomConfig) {
25 expect(data.instance.name).to.equal('PeerTube') 28 expect(data.instance.name).to.equal('PeerTube')
26 expect(data.instance.shortDescription).to.equal( 29 expect(data.instance.shortDescription).to.equal(
27 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser ' + 30 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.'
28 'with WebTorrent and Angular.'
29 ) 31 )
30 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') 32 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
31 33
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
index e4e895acb..8d1270358 100644
--- a/server/tests/api/server/contact-form.ts
+++ b/server/tests/api/server/contact-form.ts
@@ -1,16 +1,8 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import { cleanupTests, flushAndRunServer, ServerInfo, setAccessTokensToServers, wait } from '../../../../shared/extra-utils'
6 flushTests,
7 killallServers,
8 flushAndRunServer,
9 ServerInfo,
10 setAccessTokensToServers,
11 wait,
12 cleanupTests
13} from '../../../../shared/extra-utils'
14import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' 6import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
15import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 7import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
16import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form' 8import { sendContactForm } from '../../../../shared/extra-utils/server/contact-form'
@@ -54,7 +46,7 @@ describe('Test contact form', function () {
54 const email = emails[0] 46 const email = emails[0]
55 47
56 expect(email['from'][0]['address']).equal('test-admin@localhost') 48 expect(email['from'][0]['address']).equal('test-admin@localhost')
57 expect(email['from'][0]['name']).equal('toto@example.com') 49 expect(email['replyTo'][0]['address']).equal('toto@example.com')
58 expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com') 50 expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com')
59 expect(email['subject']).contains('my subject') 51 expect(email['subject']).contains('my subject')
60 expect(email['text']).contains('my super message') 52 expect(email['text']).contains('my super message')
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index c55a221f2..95b64a459 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -28,10 +28,12 @@ const expect = chai.expect
28describe('Test emails', function () { 28describe('Test emails', function () {
29 let server: ServerInfo 29 let server: ServerInfo
30 let userId: number 30 let userId: number
31 let userId2: number
31 let userAccessToken: string 32 let userAccessToken: string
32 let videoUUID: string 33 let videoUUID: string
33 let videoUserUUID: string 34 let videoUserUUID: string
34 let verificationString: string 35 let verificationString: string
36 let verificationString2: string
35 const emails: object[] = [] 37 const emails: object[] = []
36 const user = { 38 const user = {
37 username: 'user_1', 39 username: 'user_1',
@@ -122,6 +124,56 @@ describe('Test emails', function () {
122 }) 124 })
123 }) 125 })
124 126
127 describe('When creating a user without password', function () {
128 it('Should send a create password email', async function () {
129 this.timeout(10000)
130
131 await createUser({
132 url: server.url,
133 accessToken: server.accessToken,
134 username: 'create_password',
135 password: ''
136 })
137
138 await waitJobs(server)
139 expect(emails).to.have.lengthOf(2)
140
141 const email = emails[1]
142
143 expect(email['from'][0]['name']).equal('localhost:' + server.port)
144 expect(email['from'][0]['address']).equal('test-admin@localhost')
145 expect(email['to'][0]['address']).equal('create_password@example.com')
146 expect(email['subject']).contains('account')
147 expect(email['subject']).contains('password')
148
149 const verificationStringMatches = /verificationString=([a-z0-9]+)/.exec(email['text'])
150 expect(verificationStringMatches).not.to.be.null
151
152 verificationString2 = verificationStringMatches[1]
153 expect(verificationString2).to.have.length.above(2)
154
155 const userIdMatches = /userId=([0-9]+)/.exec(email['text'])
156 expect(userIdMatches).not.to.be.null
157
158 userId2 = parseInt(userIdMatches[1], 10)
159 })
160
161 it('Should not reset the password with an invalid verification string', async function () {
162 await resetPassword(server.url, userId2, verificationString2 + 'c', 'newly_created_password', 403)
163 })
164
165 it('Should reset the password', async function () {
166 await resetPassword(server.url, userId2, verificationString2, 'newly_created_password')
167 })
168
169 it('Should login with this new password', async function () {
170 await userLogin(server, {
171 username: 'create_password',
172 password: 'newly_created_password'
173 })
174 })
175 })
176
125 describe('When creating a video abuse', function () { 177 describe('When creating a video abuse', function () {
126 it('Should send the notification email', async function () { 178 it('Should send the notification email', async function () {
127 this.timeout(10000) 179 this.timeout(10000)
@@ -130,9 +182,9 @@ describe('Test emails', function () {
130 await reportVideoAbuse(server.url, server.accessToken, videoUUID, reason) 182 await reportVideoAbuse(server.url, server.accessToken, videoUUID, reason)
131 183
132 await waitJobs(server) 184 await waitJobs(server)
133 expect(emails).to.have.lengthOf(2) 185 expect(emails).to.have.lengthOf(3)
134 186
135 const email = emails[1] 187 const email = emails[2]
136 188
137 expect(email['from'][0]['name']).equal('localhost:' + server.port) 189 expect(email['from'][0]['name']).equal('localhost:' + server.port)
138 expect(email['from'][0]['address']).equal('test-admin@localhost') 190 expect(email['from'][0]['address']).equal('test-admin@localhost')
@@ -151,9 +203,9 @@ describe('Test emails', function () {
151 await blockUser(server.url, userId, server.accessToken, 204, reason) 203 await blockUser(server.url, userId, server.accessToken, 204, reason)
152 204
153 await waitJobs(server) 205 await waitJobs(server)
154 expect(emails).to.have.lengthOf(3) 206 expect(emails).to.have.lengthOf(4)
155 207
156 const email = emails[2] 208 const email = emails[3]
157 209
158 expect(email['from'][0]['name']).equal('localhost:' + server.port) 210 expect(email['from'][0]['name']).equal('localhost:' + server.port)
159 expect(email['from'][0]['address']).equal('test-admin@localhost') 211 expect(email['from'][0]['address']).equal('test-admin@localhost')
@@ -169,9 +221,9 @@ describe('Test emails', function () {
169 await unblockUser(server.url, userId, server.accessToken, 204) 221 await unblockUser(server.url, userId, server.accessToken, 204)
170 222
171 await waitJobs(server) 223 await waitJobs(server)
172 expect(emails).to.have.lengthOf(4) 224 expect(emails).to.have.lengthOf(5)
173 225
174 const email = emails[3] 226 const email = emails[4]
175 227
176 expect(email['from'][0]['name']).equal('localhost:' + server.port) 228 expect(email['from'][0]['name']).equal('localhost:' + server.port)
177 expect(email['from'][0]['address']).equal('test-admin@localhost') 229 expect(email['from'][0]['address']).equal('test-admin@localhost')
@@ -189,9 +241,9 @@ describe('Test emails', function () {
189 await addVideoToBlacklist(server.url, server.accessToken, videoUserUUID, reason) 241 await addVideoToBlacklist(server.url, server.accessToken, videoUserUUID, reason)
190 242
191 await waitJobs(server) 243 await waitJobs(server)
192 expect(emails).to.have.lengthOf(5) 244 expect(emails).to.have.lengthOf(6)
193 245
194 const email = emails[4] 246 const email = emails[5]
195 247
196 expect(email['from'][0]['name']).equal('localhost:' + server.port) 248 expect(email['from'][0]['name']).equal('localhost:' + server.port)
197 expect(email['from'][0]['address']).equal('test-admin@localhost') 249 expect(email['from'][0]['address']).equal('test-admin@localhost')
@@ -207,9 +259,9 @@ describe('Test emails', function () {
207 await removeVideoFromBlacklist(server.url, server.accessToken, videoUserUUID) 259 await removeVideoFromBlacklist(server.url, server.accessToken, videoUserUUID)
208 260
209 await waitJobs(server) 261 await waitJobs(server)
210 expect(emails).to.have.lengthOf(6) 262 expect(emails).to.have.lengthOf(7)
211 263
212 const email = emails[5] 264 const email = emails[6]
213 265
214 expect(email['from'][0]['name']).equal('localhost:' + server.port) 266 expect(email['from'][0]['name']).equal('localhost:' + server.port)
215 expect(email['from'][0]['address']).equal('test-admin@localhost') 267 expect(email['from'][0]['address']).equal('test-admin@localhost')
@@ -227,9 +279,9 @@ describe('Test emails', function () {
227 await askSendVerifyEmail(server.url, 'user_1@example.com') 279 await askSendVerifyEmail(server.url, 'user_1@example.com')
228 280
229 await waitJobs(server) 281 await waitJobs(server)
230 expect(emails).to.have.lengthOf(7) 282 expect(emails).to.have.lengthOf(8)
231 283
232 const email = emails[6] 284 const email = emails[7]
233 285
234 expect(email['from'][0]['name']).equal('localhost:' + server.port) 286 expect(email['from'][0]['name']).equal('localhost:' + server.port)
235 expect(email['from'][0]['address']).equal('test-admin@localhost') 287 expect(email['from'][0]['address']).equal('test-admin@localhost')
diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts
index 46663bf7c..a73440286 100644
--- a/server/tests/api/server/follow-constraints.ts
+++ b/server/tests/api/server/follow-constraints.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -35,11 +35,11 @@ describe('Test follow constraints', function () {
35 await setAccessTokensToServers(servers) 35 await setAccessTokensToServers(servers)
36 36
37 { 37 {
38 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video server 1' }) 38 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video server 1' })
39 video1UUID = res.body.video.uuid 39 video1UUID = res.body.video.uuid
40 } 40 }
41 { 41 {
42 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video server 2' }) 42 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video server 2' })
43 video2UUID = res.body.video.uuid 43 video2UUID = res.body.video.uuid
44 } 44 }
45 45
@@ -47,7 +47,7 @@ describe('Test follow constraints', function () {
47 username: 'user1', 47 username: 'user1',
48 password: 'super_password' 48 password: 'super_password'
49 } 49 }
50 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) 50 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
51 userAccessToken = await userLogin(servers[0], user) 51 userAccessToken = await userLogin(servers[0], user)
52 52
53 await doubleFollow(servers[0], servers[1]) 53 await doubleFollow(servers[0], servers[1])
diff --git a/server/tests/api/server/follows-moderation.ts b/server/tests/api/server/follows-moderation.ts
index 1984c9eb1..cee85cc4b 100644
--- a/server/tests/api/server/follows-moderation.ts
+++ b/server/tests/api/server/follows-moderation.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -24,7 +24,7 @@ const expect = chai.expect
24 24
25async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'accepted') { 25async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'accepted') {
26 { 26 {
27 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) 27 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
28 expect(res.body.total).to.equal(1) 28 expect(res.body.total).to.equal(1)
29 29
30 const follow = res.body.data[0] as ActorFollow 30 const follow = res.body.data[0] as ActorFollow
@@ -34,7 +34,7 @@ async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'acc
34 } 34 }
35 35
36 { 36 {
37 const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) 37 const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
38 expect(res.body.total).to.equal(1) 38 expect(res.body.total).to.equal(1)
39 39
40 const follow = res.body.data[0] as ActorFollow 40 const follow = res.body.data[0] as ActorFollow
@@ -46,12 +46,12 @@ async function checkServer1And2HasFollowers (servers: ServerInfo[], state = 'acc
46 46
47async function checkNoFollowers (servers: ServerInfo[]) { 47async function checkNoFollowers (servers: ServerInfo[]) {
48 { 48 {
49 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) 49 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
50 expect(res.body.total).to.equal(0) 50 expect(res.body.total).to.equal(0)
51 } 51 }
52 52
53 { 53 {
54 const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) 54 const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
55 expect(res.body.total).to.equal(0) 55 expect(res.body.total).to.equal(0)
56 } 56 }
57} 57}
@@ -164,17 +164,17 @@ describe('Test follows moderation', function () {
164 await waitJobs(servers) 164 await waitJobs(servers)
165 165
166 { 166 {
167 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) 167 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
168 expect(res.body.total).to.equal(2) 168 expect(res.body.total).to.equal(2)
169 } 169 }
170 170
171 { 171 {
172 const res = await getFollowersListPaginationAndSort({ url: servers[ 1 ].url, start: 0, count: 5, sort: 'createdAt' }) 172 const res = await getFollowersListPaginationAndSort({ url: servers[1].url, start: 0, count: 5, sort: 'createdAt' })
173 expect(res.body.total).to.equal(1) 173 expect(res.body.total).to.equal(1)
174 } 174 }
175 175
176 { 176 {
177 const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 5, sort: 'createdAt' }) 177 const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 5, sort: 'createdAt' })
178 expect(res.body.total).to.equal(1) 178 expect(res.body.total).to.equal(1)
179 } 179 }
180 180
@@ -184,7 +184,7 @@ describe('Test follows moderation', function () {
184 await checkServer1And2HasFollowers(servers) 184 await checkServer1And2HasFollowers(servers)
185 185
186 { 186 {
187 const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 5, sort: 'createdAt' }) 187 const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 5, sort: 'createdAt' })
188 expect(res.body.total).to.equal(0) 188 expect(res.body.total).to.equal(0)
189 } 189 }
190 }) 190 })
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index 4ffa9e791..b686af4e4 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -78,14 +78,14 @@ describe('Test follows', function () {
78 }) 78 })
79 79
80 it('Should have 2 followings on server 1', async function () { 80 it('Should have 2 followings on server 1', async function () {
81 let res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 1, sort: 'createdAt' }) 81 let res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 1, sort: 'createdAt' })
82 let follows = res.body.data 82 let follows = res.body.data
83 83
84 expect(res.body.total).to.equal(2) 84 expect(res.body.total).to.equal(2)
85 expect(follows).to.be.an('array') 85 expect(follows).to.be.an('array')
86 expect(follows.length).to.equal(1) 86 expect(follows.length).to.equal(1)
87 87
88 res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 1, count: 1, sort: 'createdAt' }) 88 res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 1, count: 1, sort: 'createdAt' })
89 follows = follows.concat(res.body.data) 89 follows = follows.concat(res.body.data)
90 90
91 const server2Follow = follows.find(f => f.following.host === 'localhost:' + servers[1].port) 91 const server2Follow = follows.find(f => f.following.host === 'localhost:' + servers[1].port)
@@ -101,7 +101,7 @@ describe('Test follows', function () {
101 const sort = 'createdAt' 101 const sort = 'createdAt'
102 const start = 0 102 const start = 0
103 const count = 1 103 const count = 1
104 const url = servers[ 0 ].url 104 const url = servers[0].url
105 105
106 { 106 {
107 const search = ':' + servers[1].port 107 const search = ':' + servers[1].port
@@ -112,7 +112,7 @@ describe('Test follows', function () {
112 112
113 expect(res.body.total).to.equal(1) 113 expect(res.body.total).to.equal(1)
114 expect(follows.length).to.equal(1) 114 expect(follows.length).to.equal(1)
115 expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[ 1 ].port) 115 expect(follows[0].following.host).to.equal('localhost:' + servers[1].port)
116 } 116 }
117 117
118 { 118 {
@@ -170,9 +170,9 @@ describe('Test follows', function () {
170 170
171 it('Should have 1 followers on server 2 and 3', async function () { 171 it('Should have 1 followers on server 2 and 3', async function () {
172 for (const server of [ servers[1], servers[2] ]) { 172 for (const server of [ servers[1], servers[2] ]) {
173 let res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 1, sort: 'createdAt' }) 173 const res = await getFollowersListPaginationAndSort({ url: server.url, start: 0, count: 1, sort: 'createdAt' })
174 174
175 let follows = res.body.data 175 const follows = res.body.data
176 expect(res.body.total).to.equal(1) 176 expect(res.body.total).to.equal(1)
177 expect(follows).to.be.an('array') 177 expect(follows).to.be.an('array')
178 expect(follows.length).to.equal(1) 178 expect(follows.length).to.equal(1)
@@ -181,7 +181,7 @@ describe('Test follows', function () {
181 }) 181 })
182 182
183 it('Should search/filter followers on server 2', async function () { 183 it('Should search/filter followers on server 2', async function () {
184 const url = servers[ 2 ].url 184 const url = servers[2].url
185 const start = 0 185 const start = 0
186 const count = 5 186 const count = 5
187 const sort = 'createdAt' 187 const sort = 'createdAt'
@@ -195,7 +195,7 @@ describe('Test follows', function () {
195 195
196 expect(res.body.total).to.equal(1) 196 expect(res.body.total).to.equal(1)
197 expect(follows.length).to.equal(1) 197 expect(follows.length).to.equal(1)
198 expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[ 2 ].port) 198 expect(follows[0].following.host).to.equal('localhost:' + servers[2].port)
199 } 199 }
200 200
201 { 201 {
@@ -241,7 +241,7 @@ describe('Test follows', function () {
241 }) 241 })
242 242
243 it('Should have 0 followers on server 1', async function () { 243 it('Should have 0 followers on server 1', async function () {
244 const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 5, sort: 'createdAt' }) 244 const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: 'createdAt' })
245 const follows = res.body.data 245 const follows = res.body.data
246 246
247 expect(res.body.total).to.equal(0) 247 expect(res.body.total).to.equal(0)
@@ -271,8 +271,8 @@ describe('Test follows', function () {
271 }) 271 })
272 272
273 it('Should not follow server 3 on server 1 anymore', async function () { 273 it('Should not follow server 3 on server 1 anymore', async function () {
274 const res = await getFollowingListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) 274 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
275 let follows = res.body.data 275 const follows = res.body.data
276 276
277 expect(res.body.total).to.equal(1) 277 expect(res.body.total).to.equal(1)
278 expect(follows).to.be.an('array') 278 expect(follows).to.be.an('array')
@@ -282,9 +282,9 @@ describe('Test follows', function () {
282 }) 282 })
283 283
284 it('Should not have server 1 as follower on server 3 anymore', async function () { 284 it('Should not have server 1 as follower on server 3 anymore', async function () {
285 const res = await getFollowersListPaginationAndSort({ url: servers[ 2 ].url, start: 0, count: 1, sort: 'createdAt' }) 285 const res = await getFollowersListPaginationAndSort({ url: servers[2].url, start: 0, count: 1, sort: 'createdAt' })
286 286
287 let follows = res.body.data 287 const follows = res.body.data
288 expect(res.body.total).to.equal(0) 288 expect(res.body.total).to.equal(0)
289 expect(follows).to.be.an('array') 289 expect(follows).to.be.an('array')
290 expect(follows.length).to.equal(0) 290 expect(follows.length).to.equal(0)
@@ -336,59 +336,59 @@ describe('Test follows', function () {
336 tags: [ 'tag1', 'tag2', 'tag3' ] 336 tags: [ 'tag1', 'tag2', 'tag3' ]
337 } 337 }
338 338
339 await uploadVideo(servers[ 2 ].url, servers[ 2 ].accessToken, { name: 'server3-2' }) 339 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-2' })
340 await uploadVideo(servers[ 2 ].url, servers[ 2 ].accessToken, { name: 'server3-3' }) 340 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-3' })
341 await uploadVideo(servers[ 2 ].url, servers[ 2 ].accessToken, video4Attributes) 341 await uploadVideo(servers[2].url, servers[2].accessToken, video4Attributes)
342 await uploadVideo(servers[ 2 ].url, servers[ 2 ].accessToken, { name: 'server3-5' }) 342 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-5' })
343 await uploadVideo(servers[ 2 ].url, servers[ 2 ].accessToken, { name: 'server3-6' }) 343 await uploadVideo(servers[2].url, servers[2].accessToken, { name: 'server3-6' })
344 344
345 { 345 {
346 const user = { username: 'captain', password: 'password' } 346 const user = { username: 'captain', password: 'password' }
347 await createUser({ url: servers[ 2 ].url, accessToken: servers[ 2 ].accessToken, username: user.username, password: user.password }) 347 await createUser({ url: servers[2].url, accessToken: servers[2].accessToken, username: user.username, password: user.password })
348 const userAccessToken = await userLogin(servers[ 2 ], user) 348 const userAccessToken = await userLogin(servers[2], user)
349 349
350 const resVideos = await getVideosList(servers[ 2 ].url) 350 const resVideos = await getVideosList(servers[2].url)
351 video4 = resVideos.body.data.find(v => v.name === 'server3-4') 351 video4 = resVideos.body.data.find(v => v.name === 'server3-4')
352 352
353 { 353 {
354 await rateVideo(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, 'like') 354 await rateVideo(servers[2].url, servers[2].accessToken, video4.id, 'like')
355 await rateVideo(servers[ 2 ].url, userAccessToken, video4.id, 'dislike') 355 await rateVideo(servers[2].url, userAccessToken, video4.id, 'dislike')
356 } 356 }
357 357
358 { 358 {
359 { 359 {
360 const text = 'my super first comment' 360 const text = 'my super first comment'
361 const res = await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, text) 361 const res = await addVideoCommentThread(servers[2].url, servers[2].accessToken, video4.id, text)
362 const threadId = res.body.comment.id 362 const threadId = res.body.comment.id
363 363
364 const text1 = 'my super answer to thread 1' 364 const text1 = 'my super answer to thread 1'
365 const childCommentRes = await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text1) 365 const childCommentRes = await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text1)
366 const childCommentId = childCommentRes.body.comment.id 366 const childCommentId = childCommentRes.body.comment.id
367 367
368 const text2 = 'my super answer to answer of thread 1' 368 const text2 = 'my super answer to answer of thread 1'
369 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, childCommentId, text2) 369 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, childCommentId, text2)
370 370
371 const text3 = 'my second answer to thread 1' 371 const text3 = 'my second answer to thread 1'
372 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text3) 372 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text3)
373 } 373 }
374 374
375 { 375 {
376 const text = 'will be deleted' 376 const text = 'will be deleted'
377 const res = await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, text) 377 const res = await addVideoCommentThread(servers[2].url, servers[2].accessToken, video4.id, text)
378 const threadId = res.body.comment.id 378 const threadId = res.body.comment.id
379 379
380 const text1 = 'answer to deleted' 380 const text1 = 'answer to deleted'
381 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text1) 381 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text1)
382 382
383 const text2 = 'will also be deleted' 383 const text2 = 'will also be deleted'
384 const childCommentRes = await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId, text2) 384 const childCommentRes = await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text2)
385 const childCommentId = childCommentRes.body.comment.id 385 const childCommentId = childCommentRes.body.comment.id
386 386
387 const text3 = 'my second answer to deleted' 387 const text3 = 'my second answer to deleted'
388 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, childCommentId, text3) 388 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, childCommentId, text3)
389 389
390 await deleteVideoComment(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, threadId) 390 await deleteVideoComment(servers[2].url, servers[2].accessToken, video4.id, threadId)
391 await deleteVideoComment(servers[ 2 ].url, servers[ 2 ].accessToken, video4.id, childCommentId) 391 await deleteVideoComment(servers[2].url, servers[2].accessToken, video4.id, childCommentId)
392 } 392 }
393 } 393 }
394 394
@@ -406,7 +406,7 @@ describe('Test follows', function () {
406 await waitJobs(servers) 406 await waitJobs(servers)
407 407
408 // Server 1 follows server 3 408 // Server 1 follows server 3
409 await follow(servers[ 0 ].url, [ servers[ 2 ].url ], servers[ 0 ].accessToken) 409 await follow(servers[0].url, [ servers[2].url ], servers[0].accessToken)
410 410
411 await waitJobs(servers) 411 await waitJobs(servers)
412 }) 412 })
@@ -424,7 +424,7 @@ describe('Test follows', function () {
424 }) 424 })
425 425
426 it('Should have propagated videos', async function () { 426 it('Should have propagated videos', async function () {
427 const res = await getVideosList(servers[ 0 ].url) 427 const res = await getVideosList(servers[0].url)
428 expect(res.body.total).to.equal(7) 428 expect(res.body.total).to.equal(7)
429 429
430 const video2 = res.body.data.find(v => v.name === 'server3-2') 430 const video2 = res.body.data.find(v => v.name === 'server3-2')
@@ -470,7 +470,7 @@ describe('Test follows', function () {
470 } 470 }
471 ] 471 ]
472 } 472 }
473 await completeVideoCheck(servers[ 0 ].url, video4, checkAttributes) 473 await completeVideoCheck(servers[0].url, video4, checkAttributes)
474 }) 474 })
475 475
476 it('Should have propagated comments', async function () { 476 it('Should have propagated comments', async function () {
@@ -481,34 +481,34 @@ describe('Test follows', function () {
481 expect(res1.body.data).to.have.lengthOf(2) 481 expect(res1.body.data).to.have.lengthOf(2)
482 482
483 { 483 {
484 const comment: VideoComment = res1.body.data[ 0 ] 484 const comment: VideoComment = res1.body.data[0]
485 expect(comment.inReplyToCommentId).to.be.null 485 expect(comment.inReplyToCommentId).to.be.null
486 expect(comment.text).equal('my super first comment') 486 expect(comment.text).equal('my super first comment')
487 expect(comment.videoId).to.equal(video4.id) 487 expect(comment.videoId).to.equal(video4.id)
488 expect(comment.id).to.equal(comment.threadId) 488 expect(comment.id).to.equal(comment.threadId)
489 expect(comment.account.name).to.equal('root') 489 expect(comment.account.name).to.equal('root')
490 expect(comment.account.host).to.equal('localhost:' + servers[ 2 ].port) 490 expect(comment.account.host).to.equal('localhost:' + servers[2].port)
491 expect(comment.totalReplies).to.equal(3) 491 expect(comment.totalReplies).to.equal(3)
492 expect(dateIsValid(comment.createdAt as string)).to.be.true 492 expect(dateIsValid(comment.createdAt as string)).to.be.true
493 expect(dateIsValid(comment.updatedAt as string)).to.be.true 493 expect(dateIsValid(comment.updatedAt as string)).to.be.true
494 494
495 const threadId = comment.threadId 495 const threadId = comment.threadId
496 496
497 const res2 = await getVideoThreadComments(servers[ 0 ].url, video4.id, threadId) 497 const res2 = await getVideoThreadComments(servers[0].url, video4.id, threadId)
498 498
499 const tree: VideoCommentThreadTree = res2.body 499 const tree: VideoCommentThreadTree = res2.body
500 expect(tree.comment.text).equal('my super first comment') 500 expect(tree.comment.text).equal('my super first comment')
501 expect(tree.children).to.have.lengthOf(2) 501 expect(tree.children).to.have.lengthOf(2)
502 502
503 const firstChild = tree.children[ 0 ] 503 const firstChild = tree.children[0]
504 expect(firstChild.comment.text).to.equal('my super answer to thread 1') 504 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
505 expect(firstChild.children).to.have.lengthOf(1) 505 expect(firstChild.children).to.have.lengthOf(1)
506 506
507 const childOfFirstChild = firstChild.children[ 0 ] 507 const childOfFirstChild = firstChild.children[0]
508 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1') 508 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
509 expect(childOfFirstChild.children).to.have.lengthOf(0) 509 expect(childOfFirstChild.children).to.have.lengthOf(0)
510 510
511 const secondChild = tree.children[ 1 ] 511 const secondChild = tree.children[1]
512 expect(secondChild.comment.text).to.equal('my second answer to thread 1') 512 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
513 expect(secondChild.children).to.have.lengthOf(0) 513 expect(secondChild.children).to.have.lengthOf(0)
514 } 514 }
@@ -569,7 +569,7 @@ describe('Test follows', function () {
569 569
570 await waitJobs(servers) 570 await waitJobs(servers)
571 571
572 let res = await getVideosList(servers[ 0 ].url) 572 const res = await getVideosList(servers[0].url)
573 expect(res.body.total).to.equal(1) 573 expect(res.body.total).to.equal(1)
574 }) 574 })
575 575
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index 7e36067f1..2cf6e15ad 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -8,6 +8,7 @@ import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-c
8 8
9import { 9import {
10 cleanupTests, 10 cleanupTests,
11 closeAllSequelize,
11 completeVideoCheck, 12 completeVideoCheck,
12 flushAndRunMultipleServers, 13 flushAndRunMultipleServers,
13 getVideo, 14 getVideo,
@@ -17,11 +18,12 @@ import {
17 reRunServer, 18 reRunServer,
18 ServerInfo, 19 ServerInfo,
19 setAccessTokensToServers, 20 setAccessTokensToServers,
21 setActorFollowScores,
20 unfollow, 22 unfollow,
21 updateVideo, 23 updateVideo,
22 uploadVideo, uploadVideoAndGetId, 24 uploadVideo,
23 wait, 25 uploadVideoAndGetId,
24 setActorFollowScores, closeAllSequelize 26 wait
25} from '../../../../shared/extra-utils' 27} from '../../../../shared/extra-utils'
26import { follow, getFollowersListPaginationAndSort } from '../../../../shared/extra-utils/server/follows' 28import { follow, getFollowersListPaginationAndSort } from '../../../../shared/extra-utils/server/follows'
27import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs' 29import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs'
@@ -44,7 +46,7 @@ describe('Test handle downs', function () {
44 let missedVideo2: Video 46 let missedVideo2: Video
45 let unlistedVideo: Video 47 let unlistedVideo: Video
46 48
47 let videoIdsServer1: number[] = [] 49 const videoIdsServer1: number[] = []
48 50
49 const videoAttributes = { 51 const videoAttributes = {
50 name: 'my super name for server 1', 52 name: 'my super name for server 1',
@@ -137,7 +139,7 @@ describe('Test handle downs', function () {
137 139
138 // Remove server 2 follower 140 // Remove server 2 follower
139 for (let i = 0; i < 10; i++) { 141 for (let i = 0; i < 10; i++) {
140 await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes) 142 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
141 } 143 }
142 144
143 await waitJobs(servers[0]) 145 await waitJobs(servers[0])
@@ -145,14 +147,14 @@ describe('Test handle downs', function () {
145 // Kill server 3 147 // Kill server 3
146 killallServers([ servers[2] ]) 148 killallServers([ servers[2] ])
147 149
148 const resLastVideo1 = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes) 150 const resLastVideo1 = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
149 missedVideo1 = resLastVideo1.body.video 151 missedVideo1 = resLastVideo1.body.video
150 152
151 const resLastVideo2 = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes) 153 const resLastVideo2 = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
152 missedVideo2 = resLastVideo2.body.video 154 missedVideo2 = resLastVideo2.body.video
153 155
154 // Unlisted video 156 // Unlisted video
155 let resVideo = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, unlistedVideoAttributes) 157 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, unlistedVideoAttributes)
156 unlistedVideo = resVideo.body.video 158 unlistedVideo = resVideo.body.video
157 159
158 // Add comments to video 2 160 // Add comments to video 2
@@ -174,7 +176,7 @@ describe('Test handle downs', function () {
174 await wait(11000) 176 await wait(11000)
175 177
176 // Only server 3 is still a follower of server 1 178 // Only server 3 is still a follower of server 1
177 const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) 179 const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
178 expect(res.body.data).to.be.an('array') 180 expect(res.body.data).to.be.an('array')
179 expect(res.body.data).to.have.lengthOf(1) 181 expect(res.body.data).to.have.lengthOf(1)
180 expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port) 182 expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port)
@@ -185,8 +187,8 @@ describe('Test handle downs', function () {
185 187
186 for (const state of states) { 188 for (const state of states) {
187 const res = await getJobsListPaginationAndSort({ 189 const res = await getJobsListPaginationAndSort({
188 url: servers[ 0 ].url, 190 url: servers[0].url,
189 accessToken: servers[ 0 ].accessToken, 191 accessToken: servers[0].accessToken,
190 state: state, 192 state: state,
191 start: 0, 193 start: 0,
192 count: 50, 194 count: 50,
@@ -209,7 +211,7 @@ describe('Test handle downs', function () {
209 211
210 await waitJobs(servers) 212 await waitJobs(servers)
211 213
212 const res = await getFollowersListPaginationAndSort({ url: servers[ 0 ].url, start: 0, count: 2, sort: 'createdAt' }) 214 const res = await getFollowersListPaginationAndSort({ url: servers[0].url, start: 0, count: 2, sort: 'createdAt' })
213 expect(res.body.data).to.be.an('array') 215 expect(res.body.data).to.be.an('array')
214 expect(res.body.data).to.have.lengthOf(2) 216 expect(res.body.data).to.have.lengthOf(2)
215 }) 217 })
@@ -221,8 +223,8 @@ describe('Test handle downs', function () {
221 expect(res1.body.data).to.be.an('array') 223 expect(res1.body.data).to.be.an('array')
222 expect(res1.body.data).to.have.lengthOf(11) 224 expect(res1.body.data).to.have.lengthOf(11)
223 225
224 await updateVideo(servers[0].url, servers[0].accessToken, missedVideo1.uuid, { }) 226 await updateVideo(servers[0].url, servers[0].accessToken, missedVideo1.uuid, {})
225 await updateVideo(servers[0].url, servers[0].accessToken, unlistedVideo.uuid, { }) 227 await updateVideo(servers[0].url, servers[0].accessToken, unlistedVideo.uuid, {})
226 228
227 await waitJobs(servers) 229 await waitJobs(servers)
228 230
@@ -313,14 +315,14 @@ describe('Test handle downs', function () {
313 this.timeout(120000) 315 this.timeout(120000)
314 316
315 for (let i = 0; i < 10; i++) { 317 for (let i = 0; i < 10; i++) {
316 const uuid = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'video ' + i })).uuid 318 const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video ' + i })).uuid
317 videoIdsServer1.push(uuid) 319 videoIdsServer1.push(uuid)
318 } 320 }
319 321
320 await waitJobs(servers) 322 await waitJobs(servers)
321 323
322 for (const id of videoIdsServer1) { 324 for (const id of videoIdsServer1) {
323 await getVideo(servers[ 1 ].url, id) 325 await getVideo(servers[1].url, id)
324 } 326 }
325 327
326 await waitJobs(servers) 328 await waitJobs(servers)
diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts
index 58d8c8c10..19c8836b5 100644
--- a/server/tests/api/server/jobs.ts
+++ b/server/tests/api/server/jobs.ts
@@ -1,8 +1,8 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { cleanupTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index' 5import { cleanupTests, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index'
6import { doubleFollow } from '../../../../shared/extra-utils/server/follows' 6import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs' 7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs'
8import { flushAndRunMultipleServers } from '../../../../shared/extra-utils/server/servers' 8import { flushAndRunMultipleServers } from '../../../../shared/extra-utils/server/servers'
@@ -44,8 +44,8 @@ describe('Test jobs', function () {
44 it('Should list jobs with sort, pagination and job type', async function () { 44 it('Should list jobs with sort, pagination and job type', async function () {
45 { 45 {
46 const res = await getJobsListPaginationAndSort({ 46 const res = await getJobsListPaginationAndSort({
47 url: servers[ 1 ].url, 47 url: servers[1].url,
48 accessToken: servers[ 1 ].accessToken, 48 accessToken: servers[1].accessToken,
49 state: 'completed', 49 state: 'completed',
50 start: 1, 50 start: 1,
51 count: 2, 51 count: 2,
@@ -54,9 +54,9 @@ describe('Test jobs', function () {
54 expect(res.body.total).to.be.above(2) 54 expect(res.body.total).to.be.above(2)
55 expect(res.body.data).to.have.lengthOf(2) 55 expect(res.body.data).to.have.lengthOf(2)
56 56
57 let job: Job = res.body.data[ 0 ] 57 let job: Job = res.body.data[0]
58 // Skip repeat jobs 58 // Skip repeat jobs
59 if (job.type === 'videos-views') job = res.body.data[ 1 ] 59 if (job.type === 'videos-views') job = res.body.data[1]
60 60
61 expect(job.state).to.equal('completed') 61 expect(job.state).to.equal('completed')
62 expect(job.type.startsWith('activitypub-')).to.be.true 62 expect(job.type.startsWith('activitypub-')).to.be.true
@@ -67,8 +67,8 @@ describe('Test jobs', function () {
67 67
68 { 68 {
69 const res = await getJobsListPaginationAndSort({ 69 const res = await getJobsListPaginationAndSort({
70 url: servers[ 1 ].url, 70 url: servers[1].url,
71 accessToken: servers[ 1 ].accessToken, 71 accessToken: servers[1].accessToken,
72 state: 'completed', 72 state: 'completed',
73 start: 0, 73 start: 0,
74 count: 100, 74 count: 100,
diff --git a/server/tests/api/server/logs.ts b/server/tests/api/server/logs.ts
index d3c877408..b8714c7a1 100644
--- a/server/tests/api/server/logs.ts
+++ b/server/tests/api/server/logs.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
diff --git a/server/tests/api/server/no-client.ts b/server/tests/api/server/no-client.ts
index 86edeb289..d0450aba0 100644
--- a/server/tests/api/server/no-client.ts
+++ b/server/tests/api/server/no-client.ts
@@ -9,7 +9,7 @@ describe('Start and stop server without web client routes', function () {
9 before(async function () { 9 before(async function () {
10 this.timeout(30000) 10 this.timeout(30000)
11 11
12 server = await flushAndRunServer(1, {}, ['--no-client']) 12 server = await flushAndRunServer(1, {}, [ '--no-client' ])
13 }) 13 })
14 14
15 it('Should fail getting the client', function () { 15 it('Should fail getting the client', function () {
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts
index b8a8a2fee..9885be4e8 100644
--- a/server/tests/api/server/plugins.ts
+++ b/server/tests/api/server/plugins.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
@@ -6,19 +6,29 @@ import {
6 cleanupTests, 6 cleanupTests,
7 closeAllSequelize, 7 closeAllSequelize,
8 flushAndRunServer, 8 flushAndRunServer,
9 getConfig, getMyUserInformation, getPluginPackageJSON, 9 getConfig,
10 getMyUserInformation,
10 getPlugin, 11 getPlugin,
12 getPluginPackageJSON,
11 getPluginRegisteredSettings, 13 getPluginRegisteredSettings,
12 getPluginsCSS, 14 getPluginsCSS,
13 installPlugin, killallServers, 15 getPublicSettings,
16 installPlugin,
17 killallServers,
14 listAvailablePlugins, 18 listAvailablePlugins,
15 listPlugins, reRunServer, 19 listPlugins,
20 reRunServer,
16 ServerInfo, 21 ServerInfo,
17 setAccessTokensToServers, 22 setAccessTokensToServers,
18 setPluginVersion, uninstallPlugin, 23 setPluginVersion,
19 updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin, 24 uninstallPlugin,
25 updateCustomSubConfig,
26 updateMyUser,
27 updatePlugin,
28 updatePluginPackageJSON,
20 updatePluginSettings, 29 updatePluginSettings,
21 wait, getPublicSettings 30 wait,
31 waitUntilLog
22} from '../../../../shared/extra-utils' 32} from '../../../../shared/extra-utils'
23import { PluginType } from '../../../../shared/models/plugins/plugin.type' 33import { PluginType } from '../../../../shared/models/plugins/plugin.type'
24import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' 34import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
@@ -88,7 +98,7 @@ describe('Test plugins', function () {
88 expect(res2.body.total).to.be.at.least(2) 98 expect(res2.body.total).to.be.at.least(2)
89 expect(data2).to.have.lengthOf(2) 99 expect(data2).to.have.lengthOf(2)
90 100
91 expect(data1[0].npmName).to.not.equal(data2[ 0 ].npmName) 101 expect(data1[0].npmName).to.not.equal(data2[0].npmName)
92 } 102 }
93 103
94 { 104 {
@@ -133,7 +143,7 @@ describe('Test plugins', function () {
133 it('Should have the correct global css', async function () { 143 it('Should have the correct global css', async function () {
134 const res = await getPluginsCSS(server.url) 144 const res = await getPluginsCSS(server.url)
135 145
136 expect(res.text).to.contain('--mainBackgroundColor') 146 expect(res.text).to.contain('background-color: red')
137 }) 147 })
138 148
139 it('Should have the plugin loaded in the configuration', async function () { 149 it('Should have the plugin loaded in the configuration', async function () {
@@ -249,6 +259,12 @@ describe('Test plugins', function () {
249 }) 259 })
250 }) 260 })
251 261
262 it('Should have watched settings changes', async function () {
263 this.timeout(10000)
264
265 await waitUntilLog(server, 'Settings changed!')
266 })
267
252 it('Should get a plugin and a theme', async function () { 268 it('Should get a plugin and a theme', async function () {
253 { 269 {
254 const res = await getPlugin({ 270 const res = await getPlugin({
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts
index b6b33a884..d0d79c4f6 100644
--- a/server/tests/api/server/reverse-proxy.ts
+++ b/server/tests/api/server/reverse-proxy.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index a01cd4b38..637525ff8 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -9,13 +9,13 @@ import {
9 doubleFollow, 9 doubleFollow,
10 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
11 follow, 11 follow,
12 killallServers, 12 ServerInfo, unfollow,
13 ServerInfo,
14 uploadVideo, 13 uploadVideo,
15 viewVideo, 14 viewVideo,
16 wait 15 wait,
16 userLogin
17} from '../../../../shared/extra-utils' 17} from '../../../../shared/extra-utils'
18import { flushTests, setAccessTokensToServers } from '../../../../shared/extra-utils/index' 18import { setAccessTokensToServers } from '../../../../shared/extra-utils/index'
19import { getStats } from '../../../../shared/extra-utils/server/stats' 19import { getStats } from '../../../../shared/extra-utils/server/stats'
20import { addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments' 20import { addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
21import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 21import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
@@ -24,6 +24,10 @@ const expect = chai.expect
24 24
25describe('Test stats (excluding redundancy)', function () { 25describe('Test stats (excluding redundancy)', function () {
26 let servers: ServerInfo[] = [] 26 let servers: ServerInfo[] = []
27 const user = {
28 username: 'user1',
29 password: 'super_password'
30 }
27 31
28 before(async function () { 32 before(async function () {
29 this.timeout(60000) 33 this.timeout(60000)
@@ -32,11 +36,7 @@ describe('Test stats (excluding redundancy)', function () {
32 36
33 await doubleFollow(servers[0], servers[1]) 37 await doubleFollow(servers[0], servers[1])
34 38
35 const user = { 39 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
36 username: 'user1',
37 password: 'super_password'
38 }
39 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password })
40 40
41 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' }) 41 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
42 const videoUUID = resVideo.body.video.uuid 42 const videoUUID = resVideo.body.video.uuid
@@ -96,6 +96,40 @@ describe('Test stats (excluding redundancy)', function () {
96 expect(data.totalInstanceFollowers).to.equal(0) 96 expect(data.totalInstanceFollowers).to.equal(0)
97 }) 97 })
98 98
99 it('Should have the correct total videos stats after an unfollow', async function () {
100 this.timeout(15000)
101
102 await unfollow(servers[2].url, servers[2].accessToken, servers[0])
103 await waitJobs(servers)
104
105 const res = await getStats(servers[2].url)
106 const data: ServerStats = res.body
107
108 expect(data.totalVideos).to.equal(0)
109 })
110
111 it('Should have the correct active users stats', async function () {
112 const server = servers[0]
113
114 {
115 const res = await getStats(server.url)
116 const data: ServerStats = res.body
117 expect(data.totalDailyActiveUsers).to.equal(1)
118 expect(data.totalWeeklyActiveUsers).to.equal(1)
119 expect(data.totalMonthlyActiveUsers).to.equal(1)
120 }
121
122 {
123 await userLogin(server, user)
124
125 const res = await getStats(server.url)
126 const data: ServerStats = res.body
127 expect(data.totalDailyActiveUsers).to.equal(2)
128 expect(data.totalWeeklyActiveUsers).to.equal(2)
129 expect(data.totalMonthlyActiveUsers).to.equal(2)
130 }
131 })
132
99 after(async function () { 133 after(async function () {
100 await cleanupTests(servers) 134 await cleanupTests(servers)
101 }) 135 })
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts
index 9d7eec8ca..5b56a83bb 100644
--- a/server/tests/api/server/tracker.ts
+++ b/server/tests/api/server/tracker.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await,@typescript-eslint/no-floating-promises */
2 2
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import 'mocha' 4import 'mocha'
@@ -49,7 +49,7 @@ describe('Test tracker', function () {
49 torrent.on('error', done) 49 torrent.on('error', done)
50 torrent.on('warning', warn => { 50 torrent.on('warning', warn => {
51 const message = typeof warn === 'string' ? warn : warn.message 51 const message = typeof warn === 'string' ? warn : warn.message
52 if (message.indexOf('Unknown infoHash ') !== -1) return done() 52 if (message.includes('Unknown infoHash ')) return done()
53 }) 53 })
54 54
55 torrent.on('done', () => done(new Error('No error on infohash'))) 55 torrent.on('done', () => done(new Error('No error on infohash')))
@@ -64,7 +64,7 @@ describe('Test tracker', function () {
64 torrent.on('error', done) 64 torrent.on('error', done)
65 torrent.on('warning', warn => { 65 torrent.on('warning', warn => {
66 const message = typeof warn === 'string' ? warn : warn.message 66 const message = typeof warn === 'string' ? warn : warn.message
67 if (message.indexOf('Unknown infoHash ') !== -1) return done(new Error('Error on infohash')) 67 if (message.includes('Unknown infoHash ')) return done(new Error('Error on infohash'))
68 }) 68 })
69 69
70 torrent.on('done', done) 70 torrent.on('done', done)
@@ -73,6 +73,8 @@ describe('Test tracker', function () {
73 it('Should disable the tracker', function (done) { 73 it('Should disable the tracker', function (done) {
74 this.timeout(20000) 74 this.timeout(20000)
75 75
76 const errCb = () => done(new Error('Tracker is enabled'))
77
76 killallServers([ server ]) 78 killallServers([ server ])
77 reRunServer(server, { tracker: { enabled: false } }) 79 reRunServer(server, { tracker: { enabled: false } })
78 .then(() => { 80 .then(() => {
@@ -83,10 +85,14 @@ describe('Test tracker', function () {
83 torrent.on('error', done) 85 torrent.on('error', done)
84 torrent.on('warning', warn => { 86 torrent.on('warning', warn => {
85 const message = typeof warn === 'string' ? warn : warn.message 87 const message = typeof warn === 'string' ? warn : warn.message
86 if (message.indexOf('disabled ') !== -1) return done() 88 if (message.includes('disabled ')) {
89 torrent.off('done', errCb)
90
91 return done()
92 }
87 }) 93 })
88 94
89 torrent.on('done', () => done(new Error('Tracker is enabled'))) 95 torrent.on('done', errCb)
90 }) 96 })
91 }) 97 })
92 98
diff --git a/server/tests/api/users/blocklist.ts b/server/tests/api/users/blocklist.ts
index 05e58017a..21b9ae4f8 100644
--- a/server/tests/api/users/blocklist.ts
+++ b/server/tests/api/users/blocklist.ts
@@ -1,21 +1,20 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { AccountBlock, ServerBlock, UserNotificationType, Video } from '../../../../shared/index' 5import { AccountBlock, ServerBlock, Video } from '../../../../shared/index'
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 createUser, deleteVideoComment, 8 createUser,
9 deleteVideoComment,
9 doubleFollow, 10 doubleFollow,
10 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
11 flushTests,
12 killallServers,
13 ServerInfo, 12 ServerInfo,
14 uploadVideo, 13 uploadVideo,
15 userLogin 14 userLogin
16} from '../../../../shared/extra-utils/index' 15} from '../../../../shared/extra-utils/index'
17import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' 16import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
18import { getVideosListWithToken, getVideosList } from '../../../../shared/extra-utils/videos/videos' 17import { getVideosList, getVideosListWithToken } from '../../../../shared/extra-utils/videos/videos'
19import { 18import {
20 addVideoCommentReply, 19 addVideoCommentReply,
21 addVideoCommentThread, 20 addVideoCommentThread,
@@ -79,7 +78,7 @@ async function checkCommentNotification (
79 const resComment = await addVideoCommentThread(comment.server.url, comment.token, comment.videoUUID, comment.text) 78 const resComment = await addVideoCommentThread(comment.server.url, comment.token, comment.videoUUID, comment.text)
80 const threadId = resComment.body.comment.id 79 const threadId = resComment.body.comment.id
81 80
82 await waitJobs([ mainServer, comment.server]) 81 await waitJobs([ mainServer, comment.server ])
83 82
84 const res = await getUserNotifications(mainServer.url, mainServer.accessToken, 0, 30) 83 const res = await getUserNotifications(mainServer.url, mainServer.accessToken, 0, 30)
85 const commentNotifications = res.body.data 84 const commentNotifications = res.body.data
@@ -90,7 +89,7 @@ async function checkCommentNotification (
90 89
91 await deleteVideoComment(comment.server.url, comment.token, comment.videoUUID, threadId) 90 await deleteVideoComment(comment.server.url, comment.token, comment.videoUUID, threadId)
92 91
93 await waitJobs([ mainServer, comment.server]) 92 await waitJobs([ mainServer, comment.server ])
94} 93}
95 94
96describe('Test blocklist', function () { 95describe('Test blocklist', function () {
@@ -109,7 +108,7 @@ describe('Test blocklist', function () {
109 108
110 { 109 {
111 const user = { username: 'user1', password: 'password' } 110 const user = { username: 'user1', password: 'password' }
112 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) 111 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
113 112
114 userToken1 = await userLogin(servers[0], user) 113 userToken1 = await userLogin(servers[0], user)
115 await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' }) 114 await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' })
@@ -117,14 +116,14 @@ describe('Test blocklist', function () {
117 116
118 { 117 {
119 const user = { username: 'moderator', password: 'password' } 118 const user = { username: 'moderator', password: 'password' }
120 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) 119 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
121 120
122 userModeratorToken = await userLogin(servers[0], user) 121 userModeratorToken = await userLogin(servers[0], user)
123 } 122 }
124 123
125 { 124 {
126 const user = { username: 'user2', password: 'password' } 125 const user = { username: 'user2', password: 'password' }
127 await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) 126 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password })
128 127
129 userToken2 = await userLogin(servers[1], user) 128 userToken2 = await userLogin(servers[1], user)
130 await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' }) 129 await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' })
@@ -143,14 +142,14 @@ describe('Test blocklist', function () {
143 await doubleFollow(servers[0], servers[1]) 142 await doubleFollow(servers[0], servers[1])
144 143
145 { 144 {
146 const resComment = await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, 'comment root 1') 145 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID1, 'comment root 1')
147 const resReply = await addVideoCommentReply(servers[ 0 ].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1') 146 const resReply = await addVideoCommentReply(servers[0].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1')
148 await addVideoCommentReply(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1') 147 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1')
149 } 148 }
150 149
151 { 150 {
152 const resComment = await addVideoCommentThread(servers[ 0 ].url, userToken1, videoUUID1, 'comment user 1') 151 const resComment = await addVideoCommentThread(servers[0].url, userToken1, videoUUID1, 'comment user 1')
153 await addVideoCommentReply(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1') 152 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1')
154 } 153 }
155 154
156 await waitJobs(servers) 155 await waitJobs(servers)
@@ -160,19 +159,19 @@ describe('Test blocklist', function () {
160 159
161 describe('When managing account blocklist', function () { 160 describe('When managing account blocklist', function () {
162 it('Should list all videos', function () { 161 it('Should list all videos', function () {
163 return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken) 162 return checkAllVideos(servers[0].url, servers[0].accessToken)
164 }) 163 })
165 164
166 it('Should list the comments', function () { 165 it('Should list the comments', function () {
167 return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 166 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
168 }) 167 })
169 168
170 it('Should block a remote account', async function () { 169 it('Should block a remote account', async function () {
171 await addAccountToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:' + servers[1].port) 170 await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
172 }) 171 })
173 172
174 it('Should hide its videos', async function () { 173 it('Should hide its videos', async function () {
175 const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken) 174 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
176 175
177 const videos: Video[] = res.body.data 176 const videos: Video[] = res.body.data
178 expect(videos).to.have.lengthOf(3) 177 expect(videos).to.have.lengthOf(3)
@@ -182,11 +181,11 @@ describe('Test blocklist', function () {
182 }) 181 })
183 182
184 it('Should block a local account', async function () { 183 it('Should block a local account', async function () {
185 await addAccountToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1') 184 await addAccountToAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1')
186 }) 185 })
187 186
188 it('Should hide its videos', async function () { 187 it('Should hide its videos', async function () {
189 const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken) 188 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
190 189
191 const videos: Video[] = res.body.data 190 const videos: Video[] = res.body.data
192 expect(videos).to.have.lengthOf(2) 191 expect(videos).to.have.lengthOf(2)
@@ -196,17 +195,17 @@ describe('Test blocklist', function () {
196 }) 195 })
197 196
198 it('Should hide its comments', async function () { 197 it('Should hide its comments', async function () {
199 const resThreads = await getVideoCommentThreads(servers[ 0 ].url, videoUUID1, 0, 5, '-createdAt', servers[ 0 ].accessToken) 198 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5, '-createdAt', servers[0].accessToken)
200 199
201 const threads: VideoComment[] = resThreads.body.data 200 const threads: VideoComment[] = resThreads.body.data
202 expect(threads).to.have.lengthOf(1) 201 expect(threads).to.have.lengthOf(1)
203 expect(threads[ 0 ].totalReplies).to.equal(0) 202 expect(threads[0].totalReplies).to.equal(0)
204 203
205 const t = threads.find(t => t.text === 'comment user 1') 204 const t = threads.find(t => t.text === 'comment user 1')
206 expect(t).to.be.undefined 205 expect(t).to.be.undefined
207 206
208 for (const thread of threads) { 207 for (const thread of threads) {
209 const res = await getVideoThreadComments(servers[ 0 ].url, videoUUID1, thread.id, servers[ 0 ].accessToken) 208 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, servers[0].accessToken)
210 209
211 const tree: VideoCommentThreadTree = res.body 210 const tree: VideoCommentThreadTree = res.body
212 expect(tree.children).to.have.lengthOf(0) 211 expect(tree.children).to.have.lengthOf(0)
@@ -217,37 +216,37 @@ describe('Test blocklist', function () {
217 this.timeout(20000) 216 this.timeout(20000)
218 217
219 { 218 {
220 const comment = { server: servers[ 0 ], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' } 219 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
221 await checkCommentNotification(servers[ 0 ], comment, 'absence') 220 await checkCommentNotification(servers[0], comment, 'absence')
222 } 221 }
223 222
224 { 223 {
225 const comment = { 224 const comment = {
226 server: servers[ 0 ], 225 server: servers[0],
227 token: userToken1, 226 token: userToken1,
228 videoUUID: videoUUID2, 227 videoUUID: videoUUID2,
229 text: 'hello @root@localhost:' + servers[ 0 ].port 228 text: 'hello @root@localhost:' + servers[0].port
230 } 229 }
231 await checkCommentNotification(servers[ 0 ], comment, 'absence') 230 await checkCommentNotification(servers[0], comment, 'absence')
232 } 231 }
233 }) 232 })
234 233
235 it('Should list all the videos with another user', async function () { 234 it('Should list all the videos with another user', async function () {
236 return checkAllVideos(servers[ 0 ].url, userToken1) 235 return checkAllVideos(servers[0].url, userToken1)
237 }) 236 })
238 237
239 it('Should list all the comments with another user', async function () { 238 it('Should list all the comments with another user', async function () {
240 return checkAllComments(servers[ 0 ].url, userToken1, videoUUID1) 239 return checkAllComments(servers[0].url, userToken1, videoUUID1)
241 }) 240 })
242 241
243 it('Should list blocked accounts', async function () { 242 it('Should list blocked accounts', async function () {
244 { 243 {
245 const res = await getAccountBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt') 244 const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
246 const blocks: AccountBlock[] = res.body.data 245 const blocks: AccountBlock[] = res.body.data
247 246
248 expect(res.body.total).to.equal(2) 247 expect(res.body.total).to.equal(2)
249 248
250 const block = blocks[ 0 ] 249 const block = blocks[0]
251 expect(block.byAccount.displayName).to.equal('root') 250 expect(block.byAccount.displayName).to.equal('root')
252 expect(block.byAccount.name).to.equal('root') 251 expect(block.byAccount.name).to.equal('root')
253 expect(block.blockedAccount.displayName).to.equal('user2') 252 expect(block.blockedAccount.displayName).to.equal('user2')
@@ -256,12 +255,12 @@ describe('Test blocklist', function () {
256 } 255 }
257 256
258 { 257 {
259 const res = await getAccountBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 1, 2, 'createdAt') 258 const res = await getAccountBlocklistByAccount(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt')
260 const blocks: AccountBlock[] = res.body.data 259 const blocks: AccountBlock[] = res.body.data
261 260
262 expect(res.body.total).to.equal(2) 261 expect(res.body.total).to.equal(2)
263 262
264 const block = blocks[ 0 ] 263 const block = blocks[0]
265 expect(block.byAccount.displayName).to.equal('root') 264 expect(block.byAccount.displayName).to.equal('root')
266 expect(block.byAccount.name).to.equal('root') 265 expect(block.byAccount.name).to.equal('root')
267 expect(block.blockedAccount.displayName).to.equal('user1') 266 expect(block.blockedAccount.displayName).to.equal('user1')
@@ -271,11 +270,11 @@ describe('Test blocklist', function () {
271 }) 270 })
272 271
273 it('Should unblock the remote account', async function () { 272 it('Should unblock the remote account', async function () {
274 await removeAccountFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:' + servers[1].port) 273 await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
275 }) 274 })
276 275
277 it('Should display its videos', async function () { 276 it('Should display its videos', async function () {
278 const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken) 277 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
279 278
280 const videos: Video[] = res.body.data 279 const videos: Video[] = res.body.data
281 expect(videos).to.have.lengthOf(3) 280 expect(videos).to.have.lengthOf(3)
@@ -285,48 +284,48 @@ describe('Test blocklist', function () {
285 }) 284 })
286 285
287 it('Should unblock the local account', async function () { 286 it('Should unblock the local account', async function () {
288 await removeAccountFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1') 287 await removeAccountFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'user1')
289 }) 288 })
290 289
291 it('Should display its comments', function () { 290 it('Should display its comments', function () {
292 return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 291 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
293 }) 292 })
294 293
295 it('Should have a notification from a non blocked account', async function () { 294 it('Should have a notification from a non blocked account', async function () {
296 this.timeout(20000) 295 this.timeout(20000)
297 296
298 { 297 {
299 const comment = { server: servers[ 1 ], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } 298 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
300 await checkCommentNotification(servers[ 0 ], comment, 'presence') 299 await checkCommentNotification(servers[0], comment, 'presence')
301 } 300 }
302 301
303 { 302 {
304 const comment = { 303 const comment = {
305 server: servers[ 0 ], 304 server: servers[0],
306 token: userToken1, 305 token: userToken1,
307 videoUUID: videoUUID2, 306 videoUUID: videoUUID2,
308 text: 'hello @root@localhost:' + servers[ 0 ].port 307 text: 'hello @root@localhost:' + servers[0].port
309 } 308 }
310 await checkCommentNotification(servers[ 0 ], comment, 'presence') 309 await checkCommentNotification(servers[0], comment, 'presence')
311 } 310 }
312 }) 311 })
313 }) 312 })
314 313
315 describe('When managing server blocklist', function () { 314 describe('When managing server blocklist', function () {
316 it('Should list all videos', function () { 315 it('Should list all videos', function () {
317 return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken) 316 return checkAllVideos(servers[0].url, servers[0].accessToken)
318 }) 317 })
319 318
320 it('Should list the comments', function () { 319 it('Should list the comments', function () {
321 return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 320 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
322 }) 321 })
323 322
324 it('Should block a remote server', async function () { 323 it('Should block a remote server', async function () {
325 await addServerToAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 324 await addServerToAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
326 }) 325 })
327 326
328 it('Should hide its videos', async function () { 327 it('Should hide its videos', async function () {
329 const res = await getVideosListWithToken(servers[ 0 ].url, servers[ 0 ].accessToken) 328 const res = await getVideosListWithToken(servers[0].url, servers[0].accessToken)
330 329
331 const videos: Video[] = res.body.data 330 const videos: Video[] = res.body.data
332 expect(videos).to.have.lengthOf(2) 331 expect(videos).to.have.lengthOf(2)
@@ -339,81 +338,81 @@ describe('Test blocklist', function () {
339 }) 338 })
340 339
341 it('Should list all the videos with another user', async function () { 340 it('Should list all the videos with another user', async function () {
342 return checkAllVideos(servers[ 0 ].url, userToken1) 341 return checkAllVideos(servers[0].url, userToken1)
343 }) 342 })
344 343
345 it('Should hide its comments', async function () { 344 it('Should hide its comments', async function () {
346 this.timeout(10000) 345 this.timeout(10000)
347 346
348 const resThreads = await addVideoCommentThread(servers[ 1 ].url, userToken2, videoUUID1, 'hidden comment 2') 347 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2')
349 const threadId = resThreads.body.comment.id 348 const threadId = resThreads.body.comment.id
350 349
351 await waitJobs(servers) 350 await waitJobs(servers)
352 351
353 await checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 352 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
354 353
355 await deleteVideoComment(servers[ 1 ].url, userToken2, videoUUID1, threadId) 354 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId)
356 }) 355 })
357 356
358 it('Should not have notifications from blocked server', async function () { 357 it('Should not have notifications from blocked server', async function () {
359 this.timeout(20000) 358 this.timeout(20000)
360 359
361 { 360 {
362 const comment = { server: servers[ 1 ], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' } 361 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
363 await checkCommentNotification(servers[ 0 ], comment, 'absence') 362 await checkCommentNotification(servers[0], comment, 'absence')
364 } 363 }
365 364
366 { 365 {
367 const comment = { 366 const comment = {
368 server: servers[ 1 ], 367 server: servers[1],
369 token: userToken2, 368 token: userToken2,
370 videoUUID: videoUUID1, 369 videoUUID: videoUUID1,
371 text: 'hello @root@localhost:' + servers[ 0 ].port 370 text: 'hello @root@localhost:' + servers[0].port
372 } 371 }
373 await checkCommentNotification(servers[ 0 ], comment, 'absence') 372 await checkCommentNotification(servers[0], comment, 'absence')
374 } 373 }
375 }) 374 })
376 375
377 it('Should list blocked servers', async function () { 376 it('Should list blocked servers', async function () {
378 const res = await getServerBlocklistByAccount(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt') 377 const res = await getServerBlocklistByAccount(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
379 const blocks: ServerBlock[] = res.body.data 378 const blocks: ServerBlock[] = res.body.data
380 379
381 expect(res.body.total).to.equal(1) 380 expect(res.body.total).to.equal(1)
382 381
383 const block = blocks[ 0 ] 382 const block = blocks[0]
384 expect(block.byAccount.displayName).to.equal('root') 383 expect(block.byAccount.displayName).to.equal('root')
385 expect(block.byAccount.name).to.equal('root') 384 expect(block.byAccount.name).to.equal('root')
386 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port) 385 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
387 }) 386 })
388 387
389 it('Should unblock the remote server', async function () { 388 it('Should unblock the remote server', async function () {
390 await removeServerFromAccountBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 389 await removeServerFromAccountBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
391 }) 390 })
392 391
393 it('Should display its videos', function () { 392 it('Should display its videos', function () {
394 return checkAllVideos(servers[ 0 ].url, servers[ 0 ].accessToken) 393 return checkAllVideos(servers[0].url, servers[0].accessToken)
395 }) 394 })
396 395
397 it('Should display its comments', function () { 396 it('Should display its comments', function () {
398 return checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 397 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
399 }) 398 })
400 399
401 it('Should have notification from unblocked server', async function () { 400 it('Should have notification from unblocked server', async function () {
402 this.timeout(20000) 401 this.timeout(20000)
403 402
404 { 403 {
405 const comment = { server: servers[ 1 ], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } 404 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
406 await checkCommentNotification(servers[ 0 ], comment, 'presence') 405 await checkCommentNotification(servers[0], comment, 'presence')
407 } 406 }
408 407
409 { 408 {
410 const comment = { 409 const comment = {
411 server: servers[ 1 ], 410 server: servers[1],
412 token: userToken2, 411 token: userToken2,
413 videoUUID: videoUUID1, 412 videoUUID: videoUUID1,
414 text: 'hello @root@localhost:' + servers[ 0 ].port 413 text: 'hello @root@localhost:' + servers[0].port
415 } 414 }
416 await checkCommentNotification(servers[ 0 ], comment, 'presence') 415 await checkCommentNotification(servers[0], comment, 'presence')
417 } 416 }
418 }) 417 })
419 }) 418 })
@@ -423,24 +422,24 @@ describe('Test blocklist', function () {
423 422
424 describe('When managing account blocklist', function () { 423 describe('When managing account blocklist', function () {
425 it('Should list all videos', async function () { 424 it('Should list all videos', async function () {
426 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 425 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
427 await checkAllVideos(servers[ 0 ].url, token) 426 await checkAllVideos(servers[0].url, token)
428 } 427 }
429 }) 428 })
430 429
431 it('Should list the comments', async function () { 430 it('Should list the comments', async function () {
432 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 431 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
433 await checkAllComments(servers[ 0 ].url, token, videoUUID1) 432 await checkAllComments(servers[0].url, token, videoUUID1)
434 } 433 }
435 }) 434 })
436 435
437 it('Should block a remote account', async function () { 436 it('Should block a remote account', async function () {
438 await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:' + servers[1].port) 437 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
439 }) 438 })
440 439
441 it('Should hide its videos', async function () { 440 it('Should hide its videos', async function () {
442 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 441 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
443 const res = await getVideosListWithToken(servers[ 0 ].url, token) 442 const res = await getVideosListWithToken(servers[0].url, token)
444 443
445 const videos: Video[] = res.body.data 444 const videos: Video[] = res.body.data
446 expect(videos).to.have.lengthOf(3) 445 expect(videos).to.have.lengthOf(3)
@@ -451,12 +450,12 @@ describe('Test blocklist', function () {
451 }) 450 })
452 451
453 it('Should block a local account', async function () { 452 it('Should block a local account', async function () {
454 await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1') 453 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'user1')
455 }) 454 })
456 455
457 it('Should hide its videos', async function () { 456 it('Should hide its videos', async function () {
458 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 457 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
459 const res = await getVideosListWithToken(servers[ 0 ].url, token) 458 const res = await getVideosListWithToken(servers[0].url, token)
460 459
461 const videos: Video[] = res.body.data 460 const videos: Video[] = res.body.data
462 expect(videos).to.have.lengthOf(2) 461 expect(videos).to.have.lengthOf(2)
@@ -467,18 +466,18 @@ describe('Test blocklist', function () {
467 }) 466 })
468 467
469 it('Should hide its comments', async function () { 468 it('Should hide its comments', async function () {
470 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 469 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
471 const resThreads = await getVideoCommentThreads(servers[ 0 ].url, videoUUID1, 0, 5, '-createdAt', token) 470 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5, '-createdAt', token)
472 471
473 const threads: VideoComment[] = resThreads.body.data 472 const threads: VideoComment[] = resThreads.body.data
474 expect(threads).to.have.lengthOf(1) 473 expect(threads).to.have.lengthOf(1)
475 expect(threads[ 0 ].totalReplies).to.equal(0) 474 expect(threads[0].totalReplies).to.equal(0)
476 475
477 const t = threads.find(t => t.text === 'comment user 1') 476 const t = threads.find(t => t.text === 'comment user 1')
478 expect(t).to.be.undefined 477 expect(t).to.be.undefined
479 478
480 for (const thread of threads) { 479 for (const thread of threads) {
481 const res = await getVideoThreadComments(servers[ 0 ].url, videoUUID1, thread.id, token) 480 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, token)
482 481
483 const tree: VideoCommentThreadTree = res.body 482 const tree: VideoCommentThreadTree = res.body
484 expect(tree.children).to.have.lengthOf(0) 483 expect(tree.children).to.have.lengthOf(0)
@@ -490,29 +489,29 @@ describe('Test blocklist', function () {
490 this.timeout(20000) 489 this.timeout(20000)
491 490
492 { 491 {
493 const comment = { server: servers[ 0 ], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' } 492 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'hidden comment' }
494 await checkCommentNotification(servers[ 0 ], comment, 'absence') 493 await checkCommentNotification(servers[0], comment, 'absence')
495 } 494 }
496 495
497 { 496 {
498 const comment = { 497 const comment = {
499 server: servers[ 1 ], 498 server: servers[1],
500 token: userToken2, 499 token: userToken2,
501 videoUUID: videoUUID1, 500 videoUUID: videoUUID1,
502 text: 'hello @root@localhost:' + servers[ 0 ].port 501 text: 'hello @root@localhost:' + servers[0].port
503 } 502 }
504 await checkCommentNotification(servers[ 0 ], comment, 'absence') 503 await checkCommentNotification(servers[0], comment, 'absence')
505 } 504 }
506 }) 505 })
507 506
508 it('Should list blocked accounts', async function () { 507 it('Should list blocked accounts', async function () {
509 { 508 {
510 const res = await getAccountBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt') 509 const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
511 const blocks: AccountBlock[] = res.body.data 510 const blocks: AccountBlock[] = res.body.data
512 511
513 expect(res.body.total).to.equal(2) 512 expect(res.body.total).to.equal(2)
514 513
515 const block = blocks[ 0 ] 514 const block = blocks[0]
516 expect(block.byAccount.displayName).to.equal('peertube') 515 expect(block.byAccount.displayName).to.equal('peertube')
517 expect(block.byAccount.name).to.equal('peertube') 516 expect(block.byAccount.name).to.equal('peertube')
518 expect(block.blockedAccount.displayName).to.equal('user2') 517 expect(block.blockedAccount.displayName).to.equal('user2')
@@ -521,12 +520,12 @@ describe('Test blocklist', function () {
521 } 520 }
522 521
523 { 522 {
524 const res = await getAccountBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 1, 2, 'createdAt') 523 const res = await getAccountBlocklistByServer(servers[0].url, servers[0].accessToken, 1, 2, 'createdAt')
525 const blocks: AccountBlock[] = res.body.data 524 const blocks: AccountBlock[] = res.body.data
526 525
527 expect(res.body.total).to.equal(2) 526 expect(res.body.total).to.equal(2)
528 527
529 const block = blocks[ 0 ] 528 const block = blocks[0]
530 expect(block.byAccount.displayName).to.equal('peertube') 529 expect(block.byAccount.displayName).to.equal('peertube')
531 expect(block.byAccount.name).to.equal('peertube') 530 expect(block.byAccount.name).to.equal('peertube')
532 expect(block.blockedAccount.displayName).to.equal('user1') 531 expect(block.blockedAccount.displayName).to.equal('user1')
@@ -536,12 +535,12 @@ describe('Test blocklist', function () {
536 }) 535 })
537 536
538 it('Should unblock the remote account', async function () { 537 it('Should unblock the remote account', async function () {
539 await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user2@localhost:' + servers[1].port) 538 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user2@localhost:' + servers[1].port)
540 }) 539 })
541 540
542 it('Should display its videos', async function () { 541 it('Should display its videos', async function () {
543 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 542 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
544 const res = await getVideosListWithToken(servers[ 0 ].url, token) 543 const res = await getVideosListWithToken(servers[0].url, token)
545 544
546 const videos: Video[] = res.body.data 545 const videos: Video[] = res.body.data
547 expect(videos).to.have.lengthOf(3) 546 expect(videos).to.have.lengthOf(3)
@@ -552,12 +551,12 @@ describe('Test blocklist', function () {
552 }) 551 })
553 552
554 it('Should unblock the local account', async function () { 553 it('Should unblock the local account', async function () {
555 await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'user1') 554 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'user1')
556 }) 555 })
557 556
558 it('Should display its comments', async function () { 557 it('Should display its comments', async function () {
559 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 558 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
560 await checkAllComments(servers[ 0 ].url, token, videoUUID1) 559 await checkAllComments(servers[0].url, token, videoUUID1)
561 } 560 }
562 }) 561 })
563 562
@@ -565,43 +564,43 @@ describe('Test blocklist', function () {
565 this.timeout(20000) 564 this.timeout(20000)
566 565
567 { 566 {
568 const comment = { server: servers[ 0 ], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' } 567 const comment = { server: servers[0], token: userToken1, videoUUID: videoUUID1, text: 'displayed comment' }
569 await checkCommentNotification(servers[ 0 ], comment, 'presence') 568 await checkCommentNotification(servers[0], comment, 'presence')
570 } 569 }
571 570
572 { 571 {
573 const comment = { 572 const comment = {
574 server: servers[ 1 ], 573 server: servers[1],
575 token: userToken2, 574 token: userToken2,
576 videoUUID: videoUUID1, 575 videoUUID: videoUUID1,
577 text: 'hello @root@localhost:' + servers[ 0 ].port 576 text: 'hello @root@localhost:' + servers[0].port
578 } 577 }
579 await checkCommentNotification(servers[ 0 ], comment, 'presence') 578 await checkCommentNotification(servers[0], comment, 'presence')
580 } 579 }
581 }) 580 })
582 }) 581 })
583 582
584 describe('When managing server blocklist', function () { 583 describe('When managing server blocklist', function () {
585 it('Should list all videos', async function () { 584 it('Should list all videos', async function () {
586 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 585 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
587 await checkAllVideos(servers[ 0 ].url, token) 586 await checkAllVideos(servers[0].url, token)
588 } 587 }
589 }) 588 })
590 589
591 it('Should list the comments', async function () { 590 it('Should list the comments', async function () {
592 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 591 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
593 await checkAllComments(servers[ 0 ].url, token, videoUUID1) 592 await checkAllComments(servers[0].url, token, videoUUID1)
594 } 593 }
595 }) 594 })
596 595
597 it('Should block a remote server', async function () { 596 it('Should block a remote server', async function () {
598 await addServerToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 597 await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
599 }) 598 })
600 599
601 it('Should hide its videos', async function () { 600 it('Should hide its videos', async function () {
602 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 601 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
603 const res1 = await getVideosList(servers[ 0 ].url) 602 const res1 = await getVideosList(servers[0].url)
604 const res2 = await getVideosListWithToken(servers[ 0 ].url, token) 603 const res2 = await getVideosListWithToken(servers[0].url, token)
605 604
606 for (const res of [ res1, res2 ]) { 605 for (const res of [ res1, res2 ]) {
607 const videos: Video[] = res.body.data 606 const videos: Video[] = res.body.data
@@ -619,60 +618,60 @@ describe('Test blocklist', function () {
619 it('Should hide its comments', async function () { 618 it('Should hide its comments', async function () {
620 this.timeout(10000) 619 this.timeout(10000)
621 620
622 const resThreads = await addVideoCommentThread(servers[ 1 ].url, userToken2, videoUUID1, 'hidden comment 2') 621 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2')
623 const threadId = resThreads.body.comment.id 622 const threadId = resThreads.body.comment.id
624 623
625 await waitJobs(servers) 624 await waitJobs(servers)
626 625
627 await checkAllComments(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID1) 626 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1)
628 627
629 await deleteVideoComment(servers[ 1 ].url, userToken2, videoUUID1, threadId) 628 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId)
630 }) 629 })
631 630
632 it('Should not have notification from blocked instances by instance', async function () { 631 it('Should not have notification from blocked instances by instance', async function () {
633 this.timeout(20000) 632 this.timeout(20000)
634 633
635 { 634 {
636 const comment = { server: servers[ 1 ], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' } 635 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'hidden comment' }
637 await checkCommentNotification(servers[ 0 ], comment, 'absence') 636 await checkCommentNotification(servers[0], comment, 'absence')
638 } 637 }
639 638
640 { 639 {
641 const comment = { 640 const comment = {
642 server: servers[ 1 ], 641 server: servers[1],
643 token: userToken2, 642 token: userToken2,
644 videoUUID: videoUUID1, 643 videoUUID: videoUUID1,
645 text: 'hello @root@localhost:' + servers[ 0 ].port 644 text: 'hello @root@localhost:' + servers[0].port
646 } 645 }
647 await checkCommentNotification(servers[ 0 ], comment, 'absence') 646 await checkCommentNotification(servers[0], comment, 'absence')
648 } 647 }
649 }) 648 })
650 649
651 it('Should list blocked servers', async function () { 650 it('Should list blocked servers', async function () {
652 const res = await getServerBlocklistByServer(servers[ 0 ].url, servers[ 0 ].accessToken, 0, 1, 'createdAt') 651 const res = await getServerBlocklistByServer(servers[0].url, servers[0].accessToken, 0, 1, 'createdAt')
653 const blocks: ServerBlock[] = res.body.data 652 const blocks: ServerBlock[] = res.body.data
654 653
655 expect(res.body.total).to.equal(1) 654 expect(res.body.total).to.equal(1)
656 655
657 const block = blocks[ 0 ] 656 const block = blocks[0]
658 expect(block.byAccount.displayName).to.equal('peertube') 657 expect(block.byAccount.displayName).to.equal('peertube')
659 expect(block.byAccount.name).to.equal('peertube') 658 expect(block.byAccount.name).to.equal('peertube')
660 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port) 659 expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
661 }) 660 })
662 661
663 it('Should unblock the remote server', async function () { 662 it('Should unblock the remote server', async function () {
664 await removeServerFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 663 await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
665 }) 664 })
666 665
667 it('Should list all videos', async function () { 666 it('Should list all videos', async function () {
668 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 667 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
669 await checkAllVideos(servers[ 0 ].url, token) 668 await checkAllVideos(servers[0].url, token)
670 } 669 }
671 }) 670 })
672 671
673 it('Should list the comments', async function () { 672 it('Should list the comments', async function () {
674 for (const token of [ userModeratorToken, servers[ 0 ].accessToken ]) { 673 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
675 await checkAllComments(servers[ 0 ].url, token, videoUUID1) 674 await checkAllComments(servers[0].url, token, videoUUID1)
676 } 675 }
677 }) 676 })
678 677
@@ -680,18 +679,18 @@ describe('Test blocklist', function () {
680 this.timeout(20000) 679 this.timeout(20000)
681 680
682 { 681 {
683 const comment = { server: servers[ 1 ], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' } 682 const comment = { server: servers[1], token: userToken2, videoUUID: videoUUID1, text: 'displayed comment' }
684 await checkCommentNotification(servers[ 0 ], comment, 'presence') 683 await checkCommentNotification(servers[0], comment, 'presence')
685 } 684 }
686 685
687 { 686 {
688 const comment = { 687 const comment = {
689 server: servers[ 1 ], 688 server: servers[1],
690 token: userToken2, 689 token: userToken2,
691 videoUUID: videoUUID1, 690 videoUUID: videoUUID1,
692 text: 'hello @root@localhost:' + servers[ 0 ].port 691 text: 'hello @root@localhost:' + servers[0].port
693 } 692 }
694 await checkCommentNotification(servers[ 0 ], comment, 'presence') 693 await checkCommentNotification(servers[0], comment, 'presence')
695 } 694 }
696 }) 695 })
697 }) 696 })
diff --git a/server/tests/api/users/user-subscriptions.ts b/server/tests/api/users/user-subscriptions.ts
index 08017f89c..7d6b0c6a9 100644
--- a/server/tests/api/users/user-subscriptions.ts
+++ b/server/tests/api/users/user-subscriptions.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -13,16 +13,17 @@ import {
13 updateVideo, 13 updateVideo,
14 userLogin 14 userLogin
15} from '../../../../shared/extra-utils' 15} from '../../../../shared/extra-utils'
16import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/extra-utils/index' 16import { ServerInfo, uploadVideo } from '../../../../shared/extra-utils/index'
17import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' 17import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
18import { Video, VideoChannel } from '../../../../shared/models/videos' 18import { Video, VideoChannel } from '../../../../shared/models/videos'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 19import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
20import { 20import {
21 addUserSubscription, 21 addUserSubscription,
22 areSubscriptionsExist,
23 getUserSubscription,
22 listUserSubscriptions, 24 listUserSubscriptions,
23 listUserSubscriptionVideos, 25 listUserSubscriptionVideos,
24 removeUserSubscription, 26 removeUserSubscription
25 getUserSubscription, areSubscriptionsExist
26} from '../../../../shared/extra-utils/users/user-subscriptions' 27} from '../../../../shared/extra-utils/users/user-subscriptions'
27 28
28const expect = chai.expect 29const expect = chai.expect
@@ -116,7 +117,7 @@ describe('Test users subscriptions', function () {
116 117
117 it('Should get subscription', async function () { 118 it('Should get subscription', async function () {
118 { 119 {
119 const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'user3_channel@localhost:' + servers[2].port) 120 const res = await getUserSubscription(servers[0].url, users[0].accessToken, 'user3_channel@localhost:' + servers[2].port)
120 const videoChannel: VideoChannel = res.body 121 const videoChannel: VideoChannel = res.body
121 122
122 expect(videoChannel.name).to.equal('user3_channel') 123 expect(videoChannel.name).to.equal('user3_channel')
@@ -127,7 +128,7 @@ describe('Test users subscriptions', function () {
127 } 128 }
128 129
129 { 130 {
130 const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'root_channel@localhost:' + servers[0].port) 131 const res = await getUserSubscription(servers[0].url, users[0].accessToken, 'root_channel@localhost:' + servers[0].port)
131 const videoChannel: VideoChannel = res.body 132 const videoChannel: VideoChannel = res.body
132 133
133 expect(videoChannel.name).to.equal('root_channel') 134 expect(videoChannel.name).to.equal('root_channel')
@@ -146,7 +147,7 @@ describe('Test users subscriptions', function () {
146 'user3_channel@localhost:' + servers[0].port 147 'user3_channel@localhost:' + servers[0].port
147 ] 148 ]
148 149
149 const res = await areSubscriptionsExist(servers[ 0 ].url, users[ 0 ].accessToken, uris) 150 const res = await areSubscriptionsExist(servers[0].url, users[0].accessToken, uris)
150 const body = res.body 151 const body = res.body
151 152
152 expect(body['user3_channel@localhost:' + servers[2].port]).to.be.true 153 expect(body['user3_channel@localhost:' + servers[2].port]).to.be.true
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts
index 791418318..591ce4959 100644
--- a/server/tests/api/users/users-multiple-servers.ts
+++ b/server/tests/api/users/users-multiple-servers.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -57,17 +57,17 @@ describe('Test users with multiple servers', function () {
57 password: 'password' 57 password: 'password'
58 } 58 }
59 const res = await createUser({ 59 const res = await createUser({
60 url: servers[ 0 ].url, 60 url: servers[0].url,
61 accessToken: servers[ 0 ].accessToken, 61 accessToken: servers[0].accessToken,
62 username: user.username, 62 username: user.username,
63 password: user.password 63 password: user.password
64 }) 64 })
65 userId = res.body.user.id 65 userId = res.body.user.id
66 userAccessToken = await userLogin(servers[ 0 ], user) 66 userAccessToken = await userLogin(servers[0], user)
67 } 67 }
68 68
69 { 69 {
70 const resVideo = await uploadVideo(servers[ 0 ].url, userAccessToken, {}) 70 const resVideo = await uploadVideo(servers[0].url, userAccessToken, {})
71 videoUUID = resVideo.body.video.uuid 71 videoUUID = resVideo.body.video.uuid
72 } 72 }
73 73
@@ -86,7 +86,6 @@ describe('Test users with multiple servers', function () {
86 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken) 86 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
87 user = res.body 87 user = res.body
88 88
89 const account: Account = user.account
90 expect(user.account.displayName).to.equal('my super display name') 89 expect(user.account.displayName).to.equal('my super display name')
91 90
92 await waitJobs(servers) 91 await waitJobs(servers)
diff --git a/server/tests/api/users/users-verification.ts b/server/tests/api/users/users-verification.ts
index 7cd61f539..675ebf690 100644
--- a/server/tests/api/users/users-verification.ts
+++ b/server/tests/api/users/users-verification.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 24203a731..c0cbce360 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -1,9 +1,10 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { User, UserRole, Video, MyUser, VideoPlaylistType } from '../../../../shared/index' 5import { MyUser, User, UserRole, Video, VideoAbuseState, VideoAbuseUpdate, VideoPlaylistType } from '../../../../shared/index'
6import { 6import {
7 addVideoCommentThread,
7 blockUser, 8 blockUser,
8 cleanupTests, 9 cleanupTests,
9 createUser, 10 createUser,
@@ -11,33 +12,41 @@ import {
11 flushAndRunServer, 12 flushAndRunServer,
12 getAccountRatings, 13 getAccountRatings,
13 getBlacklistedVideosList, 14 getBlacklistedVideosList,
15 getCustomConfig,
14 getMyUserInformation, 16 getMyUserInformation,
15 getMyUserVideoQuotaUsed, 17 getMyUserVideoQuotaUsed,
16 getMyUserVideoRating, 18 getMyUserVideoRating,
17 getUserInformation, 19 getUserInformation,
18 getUsersList, 20 getUsersList,
19 getUsersListPaginationAndSort, 21 getUsersListPaginationAndSort,
22 getVideoAbusesList,
20 getVideoChannel, 23 getVideoChannel,
21 getVideosList, installPlugin, 24 getVideosList,
25 installPlugin,
22 login, 26 login,
23 makePutBodyRequest, 27 makePutBodyRequest,
24 rateVideo, 28 rateVideo,
25 registerUserWithChannel, 29 registerUserWithChannel,
26 removeUser, 30 removeUser,
27 removeVideo, 31 removeVideo,
32 reportVideoAbuse,
28 ServerInfo, 33 ServerInfo,
29 testImage, 34 testImage,
30 unblockUser, 35 unblockUser,
36 updateCustomSubConfig,
31 updateMyAvatar, 37 updateMyAvatar,
32 updateMyUser, 38 updateMyUser,
33 updateUser, 39 updateUser,
40 updateVideoAbuse,
34 uploadVideo, 41 uploadVideo,
35 userLogin 42 userLogin,
43 waitJobs
36} from '../../../../shared/extra-utils' 44} from '../../../../shared/extra-utils'
37import { follow } from '../../../../shared/extra-utils/server/follows' 45import { follow } from '../../../../shared/extra-utils/server/follows'
38import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' 46import { logout, serverLogin, setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
39import { getMyVideos } from '../../../../shared/extra-utils/videos/videos' 47import { getMyVideos } from '../../../../shared/extra-utils/videos/videos'
40import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' 48import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
49import { CustomConfig } from '@shared/models/server'
41 50
42const expect = chai.expect 51const expect = chai.expect
43 52
@@ -54,7 +63,14 @@ describe('Test users', function () {
54 63
55 before(async function () { 64 before(async function () {
56 this.timeout(30000) 65 this.timeout(30000)
57 server = await flushAndRunServer(1) 66
67 server = await flushAndRunServer(1, {
68 rates_limit: {
69 login: {
70 max: 30
71 }
72 }
73 })
58 74
59 await setAccessTokensToServers([ server ]) 75 await setAccessTokensToServers([ server ])
60 76
@@ -121,13 +137,13 @@ describe('Test users', function () {
121 137
122 it('Should be able to login with an insensitive username', async function () { 138 it('Should be able to login with an insensitive username', async function () {
123 const user = { username: 'RoOt', password: server.user.password } 139 const user = { username: 'RoOt', password: server.user.password }
124 const res = await login(server.url, server.client, user, 200) 140 await login(server.url, server.client, user, 200)
125 141
126 const user2 = { username: 'rOoT', password: server.user.password } 142 const user2 = { username: 'rOoT', password: server.user.password }
127 const res2 = await login(server.url, server.client, user2, 200) 143 await login(server.url, server.client, user2, 200)
128 144
129 const user3 = { username: 'ROOt', password: server.user.password } 145 const user3 = { username: 'ROOt', password: server.user.password }
130 const res3 = await login(server.url, server.client, user3, 200) 146 await login(server.url, server.client, user3, 200)
131 }) 147 })
132 }) 148 })
133 149
@@ -137,7 +153,7 @@ describe('Test users', function () {
137 const videoAttributes = {} 153 const videoAttributes = {}
138 await uploadVideo(server.url, accessToken, videoAttributes) 154 await uploadVideo(server.url, accessToken, videoAttributes)
139 const res = await getVideosList(server.url) 155 const res = await getVideosList(server.url)
140 const video = res.body.data[ 0 ] 156 const video = res.body.data[0]
141 157
142 expect(video.account.name).to.equal('root') 158 expect(video.account.name).to.equal('root')
143 videoId = video.id 159 videoId = video.id
@@ -167,8 +183,8 @@ describe('Test users', function () {
167 const ratings = res.body 183 const ratings = res.body
168 184
169 expect(ratings.total).to.equal(1) 185 expect(ratings.total).to.equal(1)
170 expect(ratings.data[ 0 ].video.id).to.equal(videoId) 186 expect(ratings.data[0].video.id).to.equal(videoId)
171 expect(ratings.data[ 0 ].rating).to.equal('like') 187 expect(ratings.data[0].rating).to.equal('like')
172 }) 188 })
173 189
174 it('Should retrieve ratings list by rating type', async function () { 190 it('Should retrieve ratings list by rating type', async function () {
@@ -199,13 +215,17 @@ describe('Test users', function () {
199 }) 215 })
200 216
201 describe('Logout', function () { 217 describe('Logout', function () {
202 it('Should logout (revoke token)') 218 it('Should logout (revoke token)', async function () {
203 219 await logout(server.url, server.accessToken)
204 it('Should not be able to get the user information') 220 })
205 221
206 it('Should not be able to upload a video') 222 it('Should not be able to get the user information', async function () {
223 await getMyUserInformation(server.url, server.accessToken, 401)
224 })
207 225
208 it('Should not be able to remove a video') 226 it('Should not be able to upload a video', async function () {
227 await uploadVideo(server.url, server.accessToken, { name: 'video' }, 401)
228 })
209 229
210 it('Should not be able to rate a video', async function () { 230 it('Should not be able to rate a video', async function () {
211 const path = '/api/v1/videos/' 231 const path = '/api/v1/videos/'
@@ -223,13 +243,17 @@ describe('Test users', function () {
223 await makePutBodyRequest(options) 243 await makePutBodyRequest(options)
224 }) 244 })
225 245
226 it('Should be able to login again') 246 it('Should be able to login again', async function () {
247 server.accessToken = await serverLogin(server)
248 })
227 249
228 it('Should have an expired access token') 250 it('Should have an expired access token')
229 251
230 it('Should refresh the token') 252 it('Should refresh the token')
231 253
232 it('Should be able to upload a video again') 254 it('Should be able to get my user information again', async function () {
255 await getMyUserInformation(server.url, server.accessToken)
256 })
233 }) 257 })
234 258
235 describe('Creating a user', function () { 259 describe('Creating a user', function () {
@@ -253,7 +277,7 @@ describe('Test users', function () {
253 const res1 = await getMyUserInformation(server.url, accessTokenUser) 277 const res1 = await getMyUserInformation(server.url, accessTokenUser)
254 const userMe: MyUser = res1.body 278 const userMe: MyUser = res1.body
255 279
256 const res2 = await getUserInformation(server.url, server.accessToken, userMe.id) 280 const res2 = await getUserInformation(server.url, server.accessToken, userMe.id, true)
257 const userGet: User = res2.body 281 const userGet: User = res2.body
258 282
259 for (const user of [ userMe, userGet ]) { 283 for (const user of [ userMe, userGet ]) {
@@ -272,13 +296,23 @@ describe('Test users', function () {
272 296
273 expect(userMe.specialPlaylists).to.have.lengthOf(1) 297 expect(userMe.specialPlaylists).to.have.lengthOf(1)
274 expect(userMe.specialPlaylists[0].type).to.equal(VideoPlaylistType.WATCH_LATER) 298 expect(userMe.specialPlaylists[0].type).to.equal(VideoPlaylistType.WATCH_LATER)
299
300 // Check stats are included with withStats
301 expect(userGet.videosCount).to.be.a('number')
302 expect(userGet.videosCount).to.equal(0)
303 expect(userGet.videoCommentsCount).to.be.a('number')
304 expect(userGet.videoCommentsCount).to.equal(0)
305 expect(userGet.videoAbusesCount).to.be.a('number')
306 expect(userGet.videoAbusesCount).to.equal(0)
307 expect(userGet.videoAbusesAcceptedCount).to.be.a('number')
308 expect(userGet.videoAbusesAcceptedCount).to.equal(0)
275 }) 309 })
276 }) 310 })
277 311
278 describe('My videos & quotas', function () { 312 describe('My videos & quotas', function () {
279 313
280 it('Should be able to upload a video with this user', async function () { 314 it('Should be able to upload a video with this user', async function () {
281 this.timeout(5000) 315 this.timeout(10000)
282 316
283 const videoAttributes = { 317 const videoAttributes = {
284 name: 'super user video', 318 name: 'super user video',
@@ -307,7 +341,7 @@ describe('Test users', function () {
307 const videos = res.body.data 341 const videos = res.body.data
308 expect(videos).to.have.lengthOf(1) 342 expect(videos).to.have.lengthOf(1)
309 343
310 const video: Video = videos[ 0 ] 344 const video: Video = videos[0]
311 expect(video.name).to.equal('super user video') 345 expect(video.name).to.equal('super user video')
312 expect(video.thumbnailPath).to.not.be.null 346 expect(video.thumbnailPath).to.not.be.null
313 expect(video.previewPath).to.not.be.null 347 expect(video.previewPath).to.not.be.null
@@ -330,6 +364,36 @@ describe('Test users', function () {
330 expect(videos).to.have.lengthOf(0) 364 expect(videos).to.have.lengthOf(0)
331 } 365 }
332 }) 366 })
367
368 it('Should disable webtorrent, enable HLS, and update my quota', async function () {
369 this.timeout(60000)
370
371 {
372 const res = await getCustomConfig(server.url, server.accessToken)
373 const config = res.body as CustomConfig
374 config.transcoding.webtorrent.enabled = false
375 config.transcoding.hls.enabled = true
376 config.transcoding.enabled = true
377 await updateCustomSubConfig(server.url, server.accessToken, config)
378 }
379
380 {
381 const videoAttributes = {
382 name: 'super user video 2',
383 fixture: 'video_short.webm'
384 }
385 await uploadVideo(server.url, accessTokenUser, videoAttributes)
386
387 await waitJobs([ server ])
388 }
389
390 {
391 const res = await getMyUserVideoQuotaUsed(server.url, accessTokenUser)
392 const data = res.body
393
394 expect(data.videoQuotaUsed).to.be.greaterThan(220000)
395 }
396 })
333 }) 397 })
334 398
335 describe('Users listing', function () { 399 describe('Users listing', function () {
@@ -344,16 +408,19 @@ describe('Test users', function () {
344 expect(users).to.be.an('array') 408 expect(users).to.be.an('array')
345 expect(users.length).to.equal(2) 409 expect(users.length).to.equal(2)
346 410
347 const user = users[ 0 ] 411 const user = users[0]
348 expect(user.username).to.equal('user_1') 412 expect(user.username).to.equal('user_1')
349 expect(user.email).to.equal('user_1@example.com') 413 expect(user.email).to.equal('user_1@example.com')
350 expect(user.nsfwPolicy).to.equal('display') 414 expect(user.nsfwPolicy).to.equal('display')
351 415
352 const rootUser = users[ 1 ] 416 const rootUser = users[1]
353 expect(rootUser.username).to.equal('root') 417 expect(rootUser.username).to.equal('root')
354 expect(rootUser.email).to.equal('admin' + server.internalServerNumber + '@example.com') 418 expect(rootUser.email).to.equal('admin' + server.internalServerNumber + '@example.com')
355 expect(user.nsfwPolicy).to.equal('display') 419 expect(user.nsfwPolicy).to.equal('display')
356 420
421 expect(rootUser.lastLoginDate).to.exist
422 expect(user.lastLoginDate).to.exist
423
357 userId = user.id 424 userId = user.id
358 }) 425 })
359 426
@@ -367,7 +434,7 @@ describe('Test users', function () {
367 expect(total).to.equal(2) 434 expect(total).to.equal(2)
368 expect(users.length).to.equal(1) 435 expect(users.length).to.equal(1)
369 436
370 const user = users[ 0 ] 437 const user = users[0]
371 expect(user.username).to.equal('root') 438 expect(user.username).to.equal('root')
372 expect(user.email).to.equal('admin' + server.internalServerNumber + '@example.com') 439 expect(user.email).to.equal('admin' + server.internalServerNumber + '@example.com')
373 expect(user.roleLabel).to.equal('Administrator') 440 expect(user.roleLabel).to.equal('Administrator')
@@ -383,7 +450,7 @@ describe('Test users', function () {
383 expect(total).to.equal(2) 450 expect(total).to.equal(2)
384 expect(users.length).to.equal(1) 451 expect(users.length).to.equal(1)
385 452
386 const user = users[ 0 ] 453 const user = users[0]
387 expect(user.username).to.equal('user_1') 454 expect(user.username).to.equal('user_1')
388 expect(user.email).to.equal('user_1@example.com') 455 expect(user.email).to.equal('user_1@example.com')
389 expect(user.nsfwPolicy).to.equal('display') 456 expect(user.nsfwPolicy).to.equal('display')
@@ -398,7 +465,7 @@ describe('Test users', function () {
398 expect(total).to.equal(2) 465 expect(total).to.equal(2)
399 expect(users.length).to.equal(1) 466 expect(users.length).to.equal(1)
400 467
401 const user = users[ 0 ] 468 const user = users[0]
402 expect(user.username).to.equal('user_1') 469 expect(user.username).to.equal('user_1')
403 expect(user.email).to.equal('user_1@example.com') 470 expect(user.email).to.equal('user_1@example.com')
404 expect(user.nsfwPolicy).to.equal('display') 471 expect(user.nsfwPolicy).to.equal('display')
@@ -413,13 +480,13 @@ describe('Test users', function () {
413 expect(total).to.equal(2) 480 expect(total).to.equal(2)
414 expect(users.length).to.equal(2) 481 expect(users.length).to.equal(2)
415 482
416 expect(users[ 0 ].username).to.equal('root') 483 expect(users[0].username).to.equal('root')
417 expect(users[ 0 ].email).to.equal('admin' + server.internalServerNumber + '@example.com') 484 expect(users[0].email).to.equal('admin' + server.internalServerNumber + '@example.com')
418 expect(users[ 0 ].nsfwPolicy).to.equal('display') 485 expect(users[0].nsfwPolicy).to.equal('display')
419 486
420 expect(users[ 1 ].username).to.equal('user_1') 487 expect(users[1].username).to.equal('user_1')
421 expect(users[ 1 ].email).to.equal('user_1@example.com') 488 expect(users[1].email).to.equal('user_1@example.com')
422 expect(users[ 1 ].nsfwPolicy).to.equal('display') 489 expect(users[1].nsfwPolicy).to.equal('display')
423 }) 490 })
424 491
425 it('Should search user by username', async function () { 492 it('Should search user by username', async function () {
@@ -429,7 +496,7 @@ describe('Test users', function () {
429 expect(res.body.total).to.equal(1) 496 expect(res.body.total).to.equal(1)
430 expect(users.length).to.equal(1) 497 expect(users.length).to.equal(1)
431 498
432 expect(users[ 0 ].username).to.equal('root') 499 expect(users[0].username).to.equal('root')
433 }) 500 })
434 501
435 it('Should search user by email', async function () { 502 it('Should search user by email', async function () {
@@ -440,8 +507,8 @@ describe('Test users', function () {
440 expect(res.body.total).to.equal(1) 507 expect(res.body.total).to.equal(1)
441 expect(users.length).to.equal(1) 508 expect(users.length).to.equal(1)
442 509
443 expect(users[ 0 ].username).to.equal('user_1') 510 expect(users[0].username).to.equal('user_1')
444 expect(users[ 0 ].email).to.equal('user_1@example.com') 511 expect(users[0].email).to.equal('user_1@example.com')
445 } 512 }
446 513
447 { 514 {
@@ -451,8 +518,8 @@ describe('Test users', function () {
451 expect(res.body.total).to.equal(2) 518 expect(res.body.total).to.equal(2)
452 expect(users.length).to.equal(2) 519 expect(users.length).to.equal(2)
453 520
454 expect(users[ 0 ].username).to.equal('root') 521 expect(users[0].username).to.equal('root')
455 expect(users[ 1 ].username).to.equal('user_1') 522 expect(users[1].username).to.equal('user_1')
456 } 523 }
457 }) 524 })
458 }) 525 })
@@ -622,7 +689,6 @@ describe('Test users', function () {
622 }) 689 })
623 690
624 describe('Updating another user', function () { 691 describe('Updating another user', function () {
625
626 it('Should be able to update another user', async function () { 692 it('Should be able to update another user', async function () {
627 await updateUser({ 693 await updateUser({
628 url: server.url, 694 url: server.url,
@@ -691,12 +757,14 @@ describe('Test users', function () {
691 757
692 expect(res.body.total).to.equal(1) 758 expect(res.body.total).to.equal(1)
693 759
694 const video = res.body.data[ 0 ] 760 const video = res.body.data[0]
695 expect(video.account.name).to.equal('root') 761 expect(video.account.name).to.equal('root')
696 }) 762 })
697 }) 763 })
698 764
699 describe('Registering a new user', function () { 765 describe('Registering a new user', function () {
766 let user15AccessToken
767
700 it('Should register a new user', async function () { 768 it('Should register a new user', async function () {
701 const user = { displayName: 'super user 15', username: 'user_15', password: 'my super password' } 769 const user = { displayName: 'super user 15', username: 'user_15', password: 'my super password' }
702 const channel = { name: 'my_user_15_channel', displayName: 'my channel rocks' } 770 const channel = { name: 'my_user_15_channel', displayName: 'my channel rocks' }
@@ -710,18 +778,18 @@ describe('Test users', function () {
710 password: 'my super password' 778 password: 'my super password'
711 } 779 }
712 780
713 accessToken = await userLogin(server, user15) 781 user15AccessToken = await userLogin(server, user15)
714 }) 782 })
715 783
716 it('Should have the correct display name', async function () { 784 it('Should have the correct display name', async function () {
717 const res = await getMyUserInformation(server.url, accessToken) 785 const res = await getMyUserInformation(server.url, user15AccessToken)
718 const user: User = res.body 786 const user: User = res.body
719 787
720 expect(user.account.displayName).to.equal('super user 15') 788 expect(user.account.displayName).to.equal('super user 15')
721 }) 789 })
722 790
723 it('Should have the correct video quota', async function () { 791 it('Should have the correct video quota', async function () {
724 const res = await getMyUserInformation(server.url, accessToken) 792 const res = await getMyUserInformation(server.url, user15AccessToken)
725 const user = res.body 793 const user = res.body
726 794
727 expect(user.videoQuota).to.equal(5 * 1024 * 1024) 795 expect(user.videoQuota).to.equal(5 * 1024 * 1024)
@@ -739,7 +807,7 @@ describe('Test users', function () {
739 expect(res.body.data.find(u => u.username === 'user_15')).to.not.be.undefined 807 expect(res.body.data.find(u => u.username === 'user_15')).to.not.be.undefined
740 } 808 }
741 809
742 await deleteMe(server.url, accessToken) 810 await deleteMe(server.url, user15AccessToken)
743 811
744 { 812 {
745 const res = await getUsersList(server.url, server.accessToken) 813 const res = await getUsersList(server.url, server.accessToken)
@@ -749,6 +817,9 @@ describe('Test users', function () {
749 }) 817 })
750 818
751 describe('User blocking', function () { 819 describe('User blocking', function () {
820 let user16Id
821 let user16AccessToken
822
752 it('Should block and unblock a user', async function () { 823 it('Should block and unblock a user', async function () {
753 const user16 = { 824 const user16 = {
754 username: 'user_16', 825 username: 'user_16',
@@ -760,19 +831,95 @@ describe('Test users', function () {
760 username: user16.username, 831 username: user16.username,
761 password: user16.password 832 password: user16.password
762 }) 833 })
763 const user16Id = resUser.body.user.id 834 user16Id = resUser.body.user.id
764 835
765 accessToken = await userLogin(server, user16) 836 user16AccessToken = await userLogin(server, user16)
766 837
767 await getMyUserInformation(server.url, accessToken, 200) 838 await getMyUserInformation(server.url, user16AccessToken, 200)
768 await blockUser(server.url, user16Id, server.accessToken) 839 await blockUser(server.url, user16Id, server.accessToken)
769 840
770 await getMyUserInformation(server.url, accessToken, 401) 841 await getMyUserInformation(server.url, user16AccessToken, 401)
771 await userLogin(server, user16, 400) 842 await userLogin(server, user16, 400)
772 843
773 await unblockUser(server.url, user16Id, server.accessToken) 844 await unblockUser(server.url, user16Id, server.accessToken)
774 accessToken = await userLogin(server, user16) 845 user16AccessToken = await userLogin(server, user16)
775 await getMyUserInformation(server.url, accessToken, 200) 846 await getMyUserInformation(server.url, user16AccessToken, 200)
847 })
848 })
849
850 describe('User stats', function () {
851 let user17Id
852 let user17AccessToken
853
854 it('Should report correct initial statistics about a user', async function () {
855 const user17 = {
856 username: 'user_17',
857 password: 'my super password'
858 }
859 const resUser = await createUser({
860 url: server.url,
861 accessToken: server.accessToken,
862 username: user17.username,
863 password: user17.password
864 })
865
866 user17Id = resUser.body.user.id
867 user17AccessToken = await userLogin(server, user17)
868
869 const res = await getUserInformation(server.url, server.accessToken, user17Id, true)
870 const user: User = res.body
871
872 expect(user.videosCount).to.equal(0)
873 expect(user.videoCommentsCount).to.equal(0)
874 expect(user.videoAbusesCount).to.equal(0)
875 expect(user.videoAbusesCreatedCount).to.equal(0)
876 expect(user.videoAbusesAcceptedCount).to.equal(0)
877 })
878
879 it('Should report correct videos count', async function () {
880 const videoAttributes = {
881 name: 'video to test user stats'
882 }
883 await uploadVideo(server.url, user17AccessToken, videoAttributes)
884 const res1 = await getVideosList(server.url)
885 videoId = res1.body.data.find(video => video.name === videoAttributes.name).id
886
887 const res2 = await getUserInformation(server.url, server.accessToken, user17Id, true)
888 const user: User = res2.body
889
890 expect(user.videosCount).to.equal(1)
891 })
892
893 it('Should report correct video comments for user', async function () {
894 const text = 'super comment'
895 await addVideoCommentThread(server.url, user17AccessToken, videoId, text)
896
897 const res = await getUserInformation(server.url, server.accessToken, user17Id, true)
898 const user: User = res.body
899
900 expect(user.videoCommentsCount).to.equal(1)
901 })
902
903 it('Should report correct video abuses counts', async function () {
904 const reason = 'my super bad reason'
905 await reportVideoAbuse(server.url, user17AccessToken, videoId, reason)
906
907 const res1 = await getVideoAbusesList({ url: server.url, token: server.accessToken })
908 const abuseId = res1.body.data[0].id
909
910 const res2 = await getUserInformation(server.url, server.accessToken, user17Id, true)
911 const user2: User = res2.body
912
913 expect(user2.videoAbusesCount).to.equal(1) // number of incriminations
914 expect(user2.videoAbusesCreatedCount).to.equal(1) // number of reports created
915
916 const body: VideoAbuseUpdate = { state: VideoAbuseState.ACCEPTED }
917 await updateVideoAbuse(server.url, server.accessToken, videoId, abuseId, body)
918
919 const res3 = await getUserInformation(server.url, server.accessToken, user17Id, true)
920 const user3: User = res3.body
921
922 expect(user3.videoAbusesAcceptedCount).to.equal(1) // number of reports created accepted
776 }) 923 })
777 }) 924 })
778 925
diff --git a/server/tests/api/videos/audio-only.ts b/server/tests/api/videos/audio-only.ts
index f12d730cc..ac7a0b89c 100644
--- a/server/tests/api/videos/audio-only.ts
+++ b/server/tests/api/videos/audio-only.ts
@@ -1,28 +1,21 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 checkDirectoryIsEmpty,
7 checkSegmentHash,
8 checkTmpIsEmpty,
9 cleanupTests, 6 cleanupTests,
10 doubleFollow, 7 doubleFollow,
11 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
12 getPlaylist, 9 getVideo,
13 getVideo, makeGetRequest, makeRawRequest, 10 root,
14 removeVideo, root,
15 ServerInfo, 11 ServerInfo,
16 setAccessTokensToServers, updateCustomSubConfig, 12 setAccessTokensToServers,
17 updateVideo,
18 uploadVideo, 13 uploadVideo,
19 waitJobs, webtorrentAdd 14 waitJobs
20} from '../../../../shared/extra-utils' 15} from '../../../../shared/extra-utils'
21import { VideoDetails } from '../../../../shared/models/videos' 16import { VideoDetails } from '../../../../shared/models/videos'
22import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
23import { join } from 'path' 17import { join } from 'path'
24import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants' 18import { audio, getVideoStreamSize } from '@server/helpers/ffmpeg-utils'
25import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution, audio, getVideoStreamSize } from '@server/helpers/ffmpeg-utils'
26 19
27const expect = chai.expect 20const expect = chai.expect
28 21
@@ -87,14 +80,14 @@ describe('Test audio only video transcoding', function () {
87 80
88 it('0p transcoded video should not have video', async function () { 81 it('0p transcoded video should not have video', async function () {
89 const paths = [ 82 const paths = [
90 join(root(), 'test' + servers[ 0 ].internalServerNumber, 'videos', videoUUID + '-0.mp4'), 83 join(root(), 'test' + servers[0].internalServerNumber, 'videos', videoUUID + '-0.mp4'),
91 join(root(), 'test' + servers[ 0 ].internalServerNumber, 'streaming-playlists', 'hls', videoUUID, videoUUID + '-0-fragmented.mp4') 84 join(root(), 'test' + servers[0].internalServerNumber, 'streaming-playlists', 'hls', videoUUID, videoUUID + '-0-fragmented.mp4')
92 ] 85 ]
93 86
94 for (const path of paths) { 87 for (const path of paths) {
95 const { audioStream } = await audio.get(path) 88 const { audioStream } = await audio.get(path)
96 expect(audioStream[ 'codec_name' ]).to.be.equal('aac') 89 expect(audioStream['codec_name']).to.be.equal('aac')
97 expect(audioStream[ 'bit_rate' ]).to.be.at.most(384 * 8000) 90 expect(audioStream['bit_rate']).to.be.at.most(384 * 8000)
98 91
99 const size = await getVideoStreamSize(path) 92 const size = await getVideoStreamSize(path)
100 expect(size.height).to.equal(0) 93 expect(size.height).to.equal(0)
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index fa3e250ec..e3029f1ae 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -63,9 +63,9 @@ describe('Test multiple servers', function () {
63 displayName: 'my channel', 63 displayName: 'my channel',
64 description: 'super channel' 64 description: 'super channel'
65 } 65 }
66 await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel) 66 await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
67 const channelRes = await getVideoChannelsList(servers[ 0 ].url, 0, 1) 67 const channelRes = await getVideoChannelsList(servers[0].url, 0, 1)
68 videoChannelId = channelRes.body.data[ 0 ].id 68 videoChannelId = channelRes.body.data[0].id
69 } 69 }
70 70
71 // Server 1 and server 2 follow each other 71 // Server 1 and server 2 follow each other
@@ -163,7 +163,7 @@ describe('Test multiple servers', function () {
163 username: 'user1', 163 username: 'user1',
164 password: 'super_password' 164 password: 'super_password'
165 } 165 }
166 await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) 166 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password })
167 const userAccessToken = await userLogin(servers[1], user) 167 const userAccessToken = await userLogin(servers[1], user)
168 168
169 const videoAttributes = { 169 const videoAttributes = {
@@ -762,12 +762,12 @@ describe('Test multiple servers', function () {
762 762
763 { 763 {
764 const text = 'my super first comment' 764 const text = 'my super first comment'
765 await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text) 765 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, text)
766 } 766 }
767 767
768 { 768 {
769 const text = 'my super second comment' 769 const text = 'my super second comment'
770 await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text) 770 await addVideoCommentThread(servers[2].url, servers[2].accessToken, videoUUID, text)
771 } 771 }
772 772
773 await waitJobs(servers) 773 await waitJobs(servers)
@@ -777,7 +777,7 @@ describe('Test multiple servers', function () {
777 const threadId = res.body.data.find(c => c.text === 'my super first comment').id 777 const threadId = res.body.data.find(c => c.text === 'my super first comment').id
778 778
779 const text = 'my super answer to thread 1' 779 const text = 'my super answer to thread 1'
780 await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text) 780 await addVideoCommentReply(servers[1].url, servers[1].accessToken, videoUUID, threadId, text)
781 } 781 }
782 782
783 await waitJobs(servers) 783 await waitJobs(servers)
@@ -790,10 +790,10 @@ describe('Test multiple servers', function () {
790 const childCommentId = res2.body.children[0].comment.id 790 const childCommentId = res2.body.children[0].comment.id
791 791
792 const text3 = 'my second answer to thread 1' 792 const text3 = 'my second answer to thread 1'
793 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3) 793 await addVideoCommentReply(servers[2].url, servers[2].accessToken, videoUUID, threadId, text3)
794 794
795 const text2 = 'my super answer to answer of thread 1' 795 const text2 = 'my super answer to answer of thread 1'
796 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2) 796 await addVideoCommentReply(servers[2].url, servers[2].accessToken, videoUUID, childCommentId, text2)
797 } 797 }
798 798
799 await waitJobs(servers) 799 await waitJobs(servers)
@@ -900,9 +900,9 @@ describe('Test multiple servers', function () {
900 it('Should delete the thread comments', async function () { 900 it('Should delete the thread comments', async function () {
901 this.timeout(10000) 901 this.timeout(10000)
902 902
903 const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5) 903 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5)
904 const threadId = res.body.data.find(c => c.text === 'my super first comment').id 904 const threadId = res.body.data.find(c => c.text === 'my super first comment').id
905 await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId) 905 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId)
906 906
907 await waitJobs(servers) 907 await waitJobs(servers)
908 }) 908 })
@@ -945,9 +945,9 @@ describe('Test multiple servers', function () {
945 it('Should delete a remote thread by the origin server', async function () { 945 it('Should delete a remote thread by the origin server', async function () {
946 this.timeout(5000) 946 this.timeout(5000)
947 947
948 const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5) 948 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5)
949 const threadId = res.body.data.find(c => c.text === 'my super second comment').id 949 const threadId = res.body.data.find(c => c.text === 'my super second comment').id
950 await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId) 950 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId)
951 951
952 await waitJobs(servers) 952 await waitJobs(servers)
953 }) 953 })
@@ -1021,7 +1021,7 @@ describe('Test multiple servers', function () {
1021 const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm') 1021 const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm')
1022 1022
1023 await req.attach('videofile', filePath) 1023 await req.attach('videofile', filePath)
1024 .expect(200) 1024 .expect(200)
1025 1025
1026 await waitJobs(servers) 1026 await waitJobs(servers)
1027 1027
@@ -1046,7 +1046,7 @@ describe('Test multiple servers', function () {
1046 duration: 5, 1046 duration: 5,
1047 commentsEnabled: true, 1047 commentsEnabled: true,
1048 downloadEnabled: true, 1048 downloadEnabled: true,
1049 tags: [ ], 1049 tags: [],
1050 privacy: VideoPrivacy.PUBLIC, 1050 privacy: VideoPrivacy.PUBLIC,
1051 channel: { 1051 channel: {
1052 displayName: 'Main root channel', 1052 displayName: 'Main root channel',
diff --git a/server/tests/api/videos/services.ts b/server/tests/api/videos/services.ts
index 17172331f..5505a845a 100644
--- a/server/tests/api/videos/services.ts
+++ b/server/tests/api/videos/services.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -31,8 +31,8 @@ describe('Test services', function () {
31 31
32 const res = await getOEmbed(server.url, oembedUrl) 32 const res = await getOEmbed(server.url, oembedUrl)
33 const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + 33 const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' +
34 `src="http://localhost:${server.port}/videos/embed/${server.video.uuid}" ` + 34 `src="http://localhost:${server.port}/videos/embed/${server.video.uuid}" ` +
35 'frameborder="0" allowfullscreen></iframe>' 35 'frameborder="0" allowfullscreen></iframe>'
36 const expectedThumbnailUrl = 'http://localhost:' + server.port + '/static/previews/' + server.video.uuid + '.jpg' 36 const expectedThumbnailUrl = 'http://localhost:' + server.port + '/static/previews/' + server.video.uuid + '.jpg'
37 37
38 expect(res.body.html).to.equal(expectedHtml) 38 expect(res.body.html).to.equal(expectedHtml)
@@ -53,8 +53,8 @@ describe('Test services', function () {
53 53
54 const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) 54 const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth)
55 const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + 55 const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' +
56 `src="http://localhost:${server.port}/videos/embed/${server.video.uuid}" ` + 56 `src="http://localhost:${server.port}/videos/embed/${server.video.uuid}" ` +
57 'frameborder="0" allowfullscreen></iframe>' 57 'frameborder="0" allowfullscreen></iframe>'
58 58
59 expect(res.body.html).to.equal(expectedHtml) 59 expect(res.body.html).to.equal(expectedHtml)
60 expect(res.body.title).to.equal(server.video.name) 60 expect(res.body.title).to.equal(server.video.name)
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index 362d6b78f..0ae405950 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { keyBy } from 'lodash' 4import { keyBy } from 'lodash'
@@ -34,6 +34,7 @@ const expect = chai.expect
34describe('Test a single server', function () { 34describe('Test a single server', function () {
35 let server: ServerInfo = null 35 let server: ServerInfo = null
36 let videoId = -1 36 let videoId = -1
37 let videoId2 = -1
37 let videoUUID = '' 38 let videoUUID = ''
38 let videosListBase: any[] = null 39 let videosListBase: any[] = null
39 40
@@ -237,12 +238,11 @@ describe('Test a single server', function () {
237 it('Should upload 6 videos', async function () { 238 it('Should upload 6 videos', async function () {
238 this.timeout(25000) 239 this.timeout(25000)
239 240
240 const videos = [ 241 const videos = new Set([
241 'video_short.mp4', 'video_short.ogv', 'video_short.webm', 242 'video_short.mp4', 'video_short.ogv', 'video_short.webm',
242 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' 243 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
243 ] 244 ])
244 245
245 const tasks: Promise<any>[] = []
246 for (const video of videos) { 246 for (const video of videos) {
247 const videoAttributes = { 247 const videoAttributes = {
248 name: video + ' name', 248 name: video + ' name',
@@ -255,11 +255,8 @@ describe('Test a single server', function () {
255 fixture: video 255 fixture: video
256 } 256 }
257 257
258 const p = uploadVideo(server.url, server.accessToken, videoAttributes) 258 await uploadVideo(server.url, server.accessToken, videoAttributes)
259 tasks.push(p)
260 } 259 }
261
262 await Promise.all(tasks)
263 }) 260 })
264 261
265 it('Should have the correct durations', async function () { 262 it('Should have the correct durations', async function () {
@@ -345,6 +342,7 @@ describe('Test a single server', function () {
345 expect(videos[5].name).to.equal('video_short1.webm name') 342 expect(videos[5].name).to.equal('video_short1.webm name')
346 343
347 videoId = videos[3].uuid 344 videoId = videos[3].uuid
345 videoId2 = videos[5].uuid
348 }) 346 })
349 347
350 it('Should list and sort by trending in descending order', async function () { 348 it('Should list and sort by trending in descending order', async function () {
@@ -433,6 +431,43 @@ describe('Test a single server', function () {
433 expect(video.dislikes).to.equal(1) 431 expect(video.dislikes).to.equal(1)
434 }) 432 })
435 433
434 it('Should sort by originallyPublishedAt', async function () {
435 {
436
437 {
438 const now = new Date()
439 const attributes = { originallyPublishedAt: now.toISOString() }
440 await updateVideo(server.url, server.accessToken, videoId, attributes)
441
442 const res = await getVideosListSort(server.url, '-originallyPublishedAt')
443 const names = res.body.data.map(v => v.name)
444
445 expect(names[0]).to.equal('my super video updated')
446 expect(names[1]).to.equal('video_short2.webm name')
447 expect(names[2]).to.equal('video_short1.webm name')
448 expect(names[3]).to.equal('video_short.webm name')
449 expect(names[4]).to.equal('video_short.ogv name')
450 expect(names[5]).to.equal('video_short.mp4 name')
451 }
452
453 {
454 const now = new Date()
455 const attributes = { originallyPublishedAt: now.toISOString() }
456 await updateVideo(server.url, server.accessToken, videoId2, attributes)
457
458 const res = await getVideosListSort(server.url, '-originallyPublishedAt')
459 const names = res.body.data.map(v => v.name)
460
461 expect(names[0]).to.equal('video_short1.webm name')
462 expect(names[1]).to.equal('my super video updated')
463 expect(names[2]).to.equal('video_short2.webm name')
464 expect(names[3]).to.equal('video_short.webm name')
465 expect(names[4]).to.equal('video_short.ogv name')
466 expect(names[5]).to.equal('video_short.mp4 name')
467 }
468 }
469 })
470
436 after(async function () { 471 after(async function () {
437 await cleanupTests([ server ]) 472 await cleanupTests([ server ])
438 }) 473 })
diff --git a/server/tests/api/videos/video-abuse.ts b/server/tests/api/videos/video-abuse.ts
index 0cd6f22c7..a96be97f6 100644
--- a/server/tests/api/videos/video-abuse.ts
+++ b/server/tests/api/videos/video-abuse.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -13,7 +13,10 @@ import {
13 ServerInfo, 13 ServerInfo,
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 updateVideoAbuse, 15 updateVideoAbuse,
16 uploadVideo 16 uploadVideo,
17 removeVideo,
18 createUser,
19 userLogin
17} from '../../../../shared/extra-utils/index' 20} from '../../../../shared/extra-utils/index'
18import { doubleFollow } from '../../../../shared/extra-utils/server/follows' 21import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 22import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
@@ -68,7 +71,7 @@ describe('Test video abuses', function () {
68 }) 71 })
69 72
70 it('Should not have video abuses', async function () { 73 it('Should not have video abuses', async function () {
71 const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken) 74 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
72 75
73 expect(res.body.total).to.equal(0) 76 expect(res.body.total).to.equal(0)
74 expect(res.body.data).to.be.an('array') 77 expect(res.body.data).to.be.an('array')
@@ -86,7 +89,7 @@ describe('Test video abuses', function () {
86 }) 89 })
87 90
88 it('Should have 1 video abuses on server 1 and 0 on server 2', async function () { 91 it('Should have 1 video abuses on server 1 and 0 on server 2', async function () {
89 const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) 92 const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
90 93
91 expect(res1.body.total).to.equal(1) 94 expect(res1.body.total).to.equal(1)
92 expect(res1.body.data).to.be.an('array') 95 expect(res1.body.data).to.be.an('array')
@@ -97,8 +100,13 @@ describe('Test video abuses', function () {
97 expect(abuse.reporterAccount.name).to.equal('root') 100 expect(abuse.reporterAccount.name).to.equal('root')
98 expect(abuse.reporterAccount.host).to.equal('localhost:' + servers[0].port) 101 expect(abuse.reporterAccount.host).to.equal('localhost:' + servers[0].port)
99 expect(abuse.video.id).to.equal(servers[0].video.id) 102 expect(abuse.video.id).to.equal(servers[0].video.id)
103 expect(abuse.video.channel).to.exist
104 expect(abuse.count).to.equal(1)
105 expect(abuse.nth).to.equal(1)
106 expect(abuse.countReportsForReporter).to.equal(1)
107 expect(abuse.countReportsForReportee).to.equal(1)
100 108
101 const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) 109 const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
102 expect(res2.body.total).to.equal(0) 110 expect(res2.body.total).to.equal(0)
103 expect(res2.body.data).to.be.an('array') 111 expect(res2.body.data).to.be.an('array')
104 expect(res2.body.data.length).to.equal(0) 112 expect(res2.body.data.length).to.equal(0)
@@ -115,7 +123,7 @@ describe('Test video abuses', function () {
115 }) 123 })
116 124
117 it('Should have 2 video abuses on server 1 and 1 on server 2', async function () { 125 it('Should have 2 video abuses on server 1 and 1 on server 2', async function () {
118 const res1 = await getVideoAbusesList(servers[0].url, servers[0].accessToken) 126 const res1 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
119 expect(res1.body.total).to.equal(2) 127 expect(res1.body.total).to.equal(2)
120 expect(res1.body.data).to.be.an('array') 128 expect(res1.body.data).to.be.an('array')
121 expect(res1.body.data.length).to.equal(2) 129 expect(res1.body.data.length).to.equal(2)
@@ -128,6 +136,8 @@ describe('Test video abuses', function () {
128 expect(abuse1.state.id).to.equal(VideoAbuseState.PENDING) 136 expect(abuse1.state.id).to.equal(VideoAbuseState.PENDING)
129 expect(abuse1.state.label).to.equal('Pending') 137 expect(abuse1.state.label).to.equal('Pending')
130 expect(abuse1.moderationComment).to.be.null 138 expect(abuse1.moderationComment).to.be.null
139 expect(abuse1.count).to.equal(1)
140 expect(abuse1.nth).to.equal(1)
131 141
132 const abuse2: VideoAbuse = res1.body.data[1] 142 const abuse2: VideoAbuse = res1.body.data[1]
133 expect(abuse2.reason).to.equal('my super bad reason 2') 143 expect(abuse2.reason).to.equal('my super bad reason 2')
@@ -138,7 +148,7 @@ describe('Test video abuses', function () {
138 expect(abuse2.state.label).to.equal('Pending') 148 expect(abuse2.state.label).to.equal('Pending')
139 expect(abuse2.moderationComment).to.be.null 149 expect(abuse2.moderationComment).to.be.null
140 150
141 const res2 = await getVideoAbusesList(servers[1].url, servers[1].accessToken) 151 const res2 = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
142 expect(res2.body.total).to.equal(1) 152 expect(res2.body.total).to.equal(1)
143 expect(res2.body.data).to.be.an('array') 153 expect(res2.body.data).to.be.an('array')
144 expect(res2.body.data.length).to.equal(1) 154 expect(res2.body.data.length).to.equal(1)
@@ -156,7 +166,7 @@ describe('Test video abuses', function () {
156 const body = { state: VideoAbuseState.REJECTED } 166 const body = { state: VideoAbuseState.REJECTED }
157 await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body) 167 await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
158 168
159 const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken) 169 const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
160 expect(res.body.data[0].state.id).to.equal(VideoAbuseState.REJECTED) 170 expect(res.body.data[0].state.id).to.equal(VideoAbuseState.REJECTED)
161 }) 171 })
162 172
@@ -164,7 +174,7 @@ describe('Test video abuses', function () {
164 const body = { state: VideoAbuseState.ACCEPTED, moderationComment: 'It is valid' } 174 const body = { state: VideoAbuseState.ACCEPTED, moderationComment: 'It is valid' }
165 await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body) 175 await updateVideoAbuse(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid, abuseServer2.id, body)
166 176
167 const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken) 177 const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
168 expect(res.body.data[0].state.id).to.equal(VideoAbuseState.ACCEPTED) 178 expect(res.body.data[0].state.id).to.equal(VideoAbuseState.ACCEPTED)
169 expect(res.body.data[0].moderationComment).to.equal('It is valid') 179 expect(res.body.data[0].moderationComment).to.equal('It is valid')
170 }) 180 })
@@ -176,16 +186,16 @@ describe('Test video abuses', function () {
176 await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this') 186 await reportVideoAbuse(servers[1].url, servers[1].accessToken, servers[0].video.uuid, 'will mute this')
177 await waitJobs(servers) 187 await waitJobs(servers)
178 188
179 const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken) 189 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
180 expect(res.body.total).to.equal(3) 190 expect(res.body.total).to.equal(3)
181 } 191 }
182 192
183 const accountToBlock = 'root@localhost:' + servers[1].port 193 const accountToBlock = 'root@localhost:' + servers[1].port
184 194
185 { 195 {
186 await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, accountToBlock) 196 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
187 197
188 const res = await getVideoAbusesList(servers[ 0 ].url, servers[ 0 ].accessToken) 198 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
189 expect(res.body.total).to.equal(2) 199 expect(res.body.total).to.equal(2)
190 200
191 const abuse = res.body.data.find(a => a.reason === 'will mute this') 201 const abuse = res.body.data.find(a => a.reason === 'will mute this')
@@ -193,9 +203,9 @@ describe('Test video abuses', function () {
193 } 203 }
194 204
195 { 205 {
196 await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, accountToBlock) 206 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, accountToBlock)
197 207
198 const res = await getVideoAbusesList(servers[ 0 ].url, servers[ 0 ].accessToken) 208 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
199 expect(res.body.total).to.equal(3) 209 expect(res.body.total).to.equal(3)
200 } 210 }
201 }) 211 })
@@ -204,9 +214,9 @@ describe('Test video abuses', function () {
204 const serverToBlock = servers[1].host 214 const serverToBlock = servers[1].host
205 215
206 { 216 {
207 await addServerToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, servers[1].host) 217 await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, servers[1].host)
208 218
209 const res = await getVideoAbusesList(servers[ 0 ].url, servers[ 0 ].accessToken) 219 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
210 expect(res.body.total).to.equal(2) 220 expect(res.body.total).to.equal(2)
211 221
212 const abuse = res.body.data.find(a => a.reason === 'will mute this') 222 const abuse = res.body.data.find(a => a.reason === 'will mute this')
@@ -214,13 +224,73 @@ describe('Test video abuses', function () {
214 } 224 }
215 225
216 { 226 {
217 await removeServerFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, serverToBlock) 227 await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, serverToBlock)
218 228
219 const res = await getVideoAbusesList(servers[ 0 ].url, servers[ 0 ].accessToken) 229 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
220 expect(res.body.total).to.equal(3) 230 expect(res.body.total).to.equal(3)
221 } 231 }
222 }) 232 })
223 233
234 it('Should keep the video abuse when deleting the video', async function () {
235 this.timeout(10000)
236
237 await removeVideo(servers[1].url, servers[1].accessToken, abuseServer2.video.uuid)
238
239 await waitJobs(servers)
240
241 const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
242 expect(res.body.total).to.equal(2, "wrong number of videos returned")
243 expect(res.body.data.length).to.equal(2, "wrong number of videos returned")
244 expect(res.body.data[0].id).to.equal(abuseServer2.id, "wrong origin server id for first video")
245
246 const abuse: VideoAbuse = res.body.data[0]
247 expect(abuse.video.id).to.equal(abuseServer2.video.id, "wrong video id")
248 expect(abuse.video.channel).to.exist
249 expect(abuse.video.deleted).to.be.true
250 })
251
252 it('Should include counts of reports from reporter and reportee', async function () {
253 this.timeout(10000)
254
255 // register a second user to have two reporters/reportees
256 const user = { username: 'user2', password: 'password' }
257 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, ...user })
258 const userAccessToken = await userLogin(servers[0], user)
259
260 // upload a third video via this user
261 const video3Attributes = {
262 name: 'my second super name for server 1',
263 description: 'my second super description for server 1'
264 }
265 await uploadVideo(servers[0].url, userAccessToken, video3Attributes)
266
267 const res1 = await getVideosList(servers[0].url)
268 const videos = res1.body.data
269 const video3 = videos.find(video => video.name === 'my second super name for server 1')
270
271 // resume with the test
272 const reason3 = 'my super bad reason 3'
273 await reportVideoAbuse(servers[0].url, servers[0].accessToken, video3.id, reason3)
274 const reason4 = 'my super bad reason 4'
275 await reportVideoAbuse(servers[0].url, userAccessToken, servers[0].video.id, reason4)
276
277 const res2 = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
278
279 {
280 for (const abuse of res2.body.data as VideoAbuse[]) {
281 if (abuse.video.id === video3.id) {
282 expect(abuse.count).to.equal(1, "wrong reports count for video 3")
283 expect(abuse.nth).to.equal(1, "wrong report position in report list for video 3")
284 expect(abuse.countReportsForReportee).to.equal(1, "wrong reports count for reporter on video 3 abuse")
285 expect(abuse.countReportsForReporter).to.equal(3, "wrong reports count for reportee on video 3 abuse")
286 }
287 if (abuse.video.id === servers[0].video.id) {
288 expect(abuse.countReportsForReportee).to.equal(3, "wrong reports count for reporter on video 1 abuse")
289 }
290 }
291 }
292 })
293
224 it('Should delete the video abuse', async function () { 294 it('Should delete the video abuse', async function () {
225 this.timeout(10000) 295 this.timeout(10000)
226 296
@@ -229,16 +299,54 @@ describe('Test video abuses', function () {
229 await waitJobs(servers) 299 await waitJobs(servers)
230 300
231 { 301 {
232 const res = await getVideoAbusesList(servers[1].url, servers[1].accessToken) 302 const res = await getVideoAbusesList({ url: servers[1].url, token: servers[1].accessToken })
233 expect(res.body.total).to.equal(1) 303 expect(res.body.total).to.equal(1)
234 expect(res.body.data.length).to.equal(1) 304 expect(res.body.data.length).to.equal(1)
235 expect(res.body.data[0].id).to.not.equal(abuseServer2.id) 305 expect(res.body.data[0].id).to.not.equal(abuseServer2.id)
236 } 306 }
237 307
238 { 308 {
239 const res = await getVideoAbusesList(servers[0].url, servers[0].accessToken) 309 const res = await getVideoAbusesList({ url: servers[0].url, token: servers[0].accessToken })
240 expect(res.body.total).to.equal(3) 310 expect(res.body.total).to.equal(5)
311 }
312 })
313
314 it('Should list and filter video abuses', async function () {
315 async function list (query: Omit<Parameters<typeof getVideoAbusesList>[0], 'url' | 'token'>) {
316 const options = {
317 url: servers[0].url,
318 token: servers[0].accessToken
319 }
320
321 Object.assign(options, query)
322
323 const res = await getVideoAbusesList(options)
324
325 return res.body.data as VideoAbuse[]
241 } 326 }
327
328 expect(await list({ id: 56 })).to.have.lengthOf(0)
329 expect(await list({ id: 1 })).to.have.lengthOf(1)
330
331 expect(await list({ search: 'my super name for server 1' })).to.have.lengthOf(3)
332 expect(await list({ search: 'aaaaaaaaaaaaaaaaaaaaaaaaaa' })).to.have.lengthOf(0)
333
334 expect(await list({ searchVideo: 'my second super name for server 1' })).to.have.lengthOf(1)
335
336 expect(await list({ searchVideoChannel: 'root' })).to.have.lengthOf(3)
337 expect(await list({ searchVideoChannel: 'aaaa' })).to.have.lengthOf(0)
338
339 expect(await list({ searchReporter: 'user2' })).to.have.lengthOf(1)
340 expect(await list({ searchReporter: 'root' })).to.have.lengthOf(4)
341
342 expect(await list({ searchReportee: 'root' })).to.have.lengthOf(3)
343 expect(await list({ searchReportee: 'aaaa' })).to.have.lengthOf(0)
344
345 expect(await list({ videoIs: 'deleted' })).to.have.lengthOf(1)
346 expect(await list({ videoIs: 'blacklisted' })).to.have.lengthOf(0)
347
348 expect(await list({ state: VideoAbuseState.ACCEPTED })).to.have.lengthOf(0)
349 expect(await list({ state: VideoAbuseState.PENDING })).to.have.lengthOf(5)
242 }) 350 })
243 351
244 after(async function () { 352 after(async function () {
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts
index 854b2f0cb..67bc0114c 100644
--- a/server/tests/api/videos/video-blacklist.ts
+++ b/server/tests/api/videos/video-blacklist.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { orderBy } from 'lodash' 4import { orderBy } from 'lodash'
@@ -8,7 +8,8 @@ import {
8 cleanupTests, 8 cleanupTests,
9 createUser, 9 createUser,
10 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
11 getBlacklistedVideosList, getMyUserInformation, 11 getBlacklistedVideosList,
12 getMyUserInformation,
12 getMyVideos, 13 getMyVideos,
13 getVideosList, 14 getVideosList,
14 killallServers, 15 killallServers,
@@ -17,7 +18,6 @@ import {
17 searchVideo, 18 searchVideo,
18 ServerInfo, 19 ServerInfo,
19 setAccessTokensToServers, 20 setAccessTokensToServers,
20 setDefaultVideoChannel,
21 updateVideo, 21 updateVideo,
22 updateVideoBlacklist, 22 updateVideoBlacklist,
23 uploadVideo, 23 uploadVideo,
@@ -27,7 +27,7 @@ import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
27import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 27import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
28import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' 28import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos'
29import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' 29import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
30import { User, UserRole, UserUpdateMe } from '../../../../shared/models/users' 30import { User, UserRole } from '../../../../shared/models/users'
31import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports' 31import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
32 32
33const expect = chai.expect 33const expect = chai.expect
@@ -40,7 +40,7 @@ describe('Test video blacklist', function () {
40 const res = await getVideosList(server.url) 40 const res = await getVideosList(server.url)
41 41
42 const videos = res.body.data 42 const videos = res.body.data
43 for (let video of videos) { 43 for (const video of videos) {
44 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason') 44 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
45 } 45 }
46 } 46 }
@@ -72,7 +72,7 @@ describe('Test video blacklist', function () {
72 72
73 it('Should not have the video blacklisted in videos list/search on server 1', async function () { 73 it('Should not have the video blacklisted in videos list/search on server 1', async function () {
74 { 74 {
75 const res = await getVideosList(servers[ 0 ].url) 75 const res = await getVideosList(servers[0].url)
76 76
77 expect(res.body.total).to.equal(0) 77 expect(res.body.total).to.equal(0)
78 expect(res.body.data).to.be.an('array') 78 expect(res.body.data).to.be.an('array')
@@ -80,7 +80,7 @@ describe('Test video blacklist', function () {
80 } 80 }
81 81
82 { 82 {
83 const res = await searchVideo(servers[ 0 ].url, 'name') 83 const res = await searchVideo(servers[0].url, 'name')
84 84
85 expect(res.body.total).to.equal(0) 85 expect(res.body.total).to.equal(0)
86 expect(res.body.data).to.be.an('array') 86 expect(res.body.data).to.be.an('array')
@@ -90,7 +90,7 @@ describe('Test video blacklist', function () {
90 90
91 it('Should have the blacklisted video in videos list/search on server 2', async function () { 91 it('Should have the blacklisted video in videos list/search on server 2', async function () {
92 { 92 {
93 const res = await getVideosList(servers[ 1 ].url) 93 const res = await getVideosList(servers[1].url)
94 94
95 expect(res.body.total).to.equal(2) 95 expect(res.body.total).to.equal(2)
96 expect(res.body.data).to.be.an('array') 96 expect(res.body.data).to.be.an('array')
@@ -98,7 +98,7 @@ describe('Test video blacklist', function () {
98 } 98 }
99 99
100 { 100 {
101 const res = await searchVideo(servers[ 1 ].url, 'video') 101 const res = await searchVideo(servers[1].url, 'video')
102 102
103 expect(res.body.total).to.equal(2) 103 expect(res.body.total).to.equal(2)
104 expect(res.body.data).to.be.an('array') 104 expect(res.body.data).to.be.an('array')
@@ -125,8 +125,8 @@ describe('Test video blacklist', function () {
125 125
126 it('Should display all the blacklisted videos when applying manual type filter', async function () { 126 it('Should display all the blacklisted videos when applying manual type filter', async function () {
127 const res = await getBlacklistedVideosList({ 127 const res = await getBlacklistedVideosList({
128 url: servers[ 0 ].url, 128 url: servers[0].url,
129 token: servers[ 0 ].accessToken, 129 token: servers[0].accessToken,
130 type: VideoBlacklistType.MANUAL 130 type: VideoBlacklistType.MANUAL
131 }) 131 })
132 132
@@ -139,8 +139,8 @@ describe('Test video blacklist', function () {
139 139
140 it('Should display nothing when applying automatic type filter', async function () { 140 it('Should display nothing when applying automatic type filter', async function () {
141 const res = await getBlacklistedVideosList({ 141 const res = await getBlacklistedVideosList({
142 url: servers[ 0 ].url, 142 url: servers[0].url,
143 token: servers[ 0 ].accessToken, 143 token: servers[0].accessToken,
144 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 144 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
145 }) 145 })
146 146
@@ -152,7 +152,7 @@ describe('Test video blacklist', function () {
152 }) 152 })
153 153
154 it('Should get the correct sort when sorting by descending id', async function () { 154 it('Should get the correct sort when sorting by descending id', async function () {
155 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-id' }) 155 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: '-id' })
156 expect(res.body.total).to.equal(2) 156 expect(res.body.total).to.equal(2)
157 157
158 const blacklistedVideos = res.body.data 158 const blacklistedVideos = res.body.data
@@ -165,7 +165,7 @@ describe('Test video blacklist', function () {
165 }) 165 })
166 166
167 it('Should get the correct sort when sorting by descending video name', async function () { 167 it('Should get the correct sort when sorting by descending video name', async function () {
168 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) 168 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: '-name' })
169 expect(res.body.total).to.equal(2) 169 expect(res.body.total).to.equal(2)
170 170
171 const blacklistedVideos = res.body.data 171 const blacklistedVideos = res.body.data
@@ -178,7 +178,7 @@ describe('Test video blacklist', function () {
178 }) 178 })
179 179
180 it('Should get the correct sort when sorting by ascending creation date', async function () { 180 it('Should get the correct sort when sorting by ascending creation date', async function () {
181 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' }) 181 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: 'createdAt' })
182 expect(res.body.total).to.equal(2) 182 expect(res.body.total).to.equal(2)
183 183
184 const blacklistedVideos = res.body.data 184 const blacklistedVideos = res.body.data
@@ -195,7 +195,7 @@ describe('Test video blacklist', function () {
195 it('Should change the reason', async function () { 195 it('Should change the reason', async function () {
196 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated') 196 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
197 197
198 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) 198 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: '-name' })
199 const video = res.body.data.find(b => b.video.id === videoId) 199 const video = res.body.data.find(b => b.video.id === videoId)
200 200
201 expect(video.reason).to.equal('my super reason updated') 201 expect(video.reason).to.equal('my super reason updated')
@@ -231,7 +231,7 @@ describe('Test video blacklist', function () {
231 231
232 it('Should remove a video from the blacklist on server 1', async function () { 232 it('Should remove a video from the blacklist on server 1', async function () {
233 // Get one video in the blacklist 233 // Get one video in the blacklist
234 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) 234 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: '-name' })
235 videoToRemove = res.body.data[0] 235 videoToRemove = res.body.data[0]
236 blacklist = res.body.data.slice(1) 236 blacklist = res.body.data.slice(1)
237 237
@@ -252,7 +252,7 @@ describe('Test video blacklist', function () {
252 }) 252 })
253 253
254 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { 254 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
255 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) 255 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: '-name' })
256 expect(res.body.total).to.equal(1) 256 expect(res.body.total).to.equal(1)
257 257
258 const videos = res.body.data 258 const videos = res.body.data
@@ -274,7 +274,7 @@ describe('Test video blacklist', function () {
274 video3UUID = res.body.video.uuid 274 video3UUID = res.body.video.uuid
275 } 275 }
276 { 276 {
277 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'Video 4' }) 277 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'Video 4' })
278 video4UUID = res.body.video.uuid 278 video4UUID = res.body.video.uuid
279 } 279 }
280 280
@@ -284,17 +284,17 @@ describe('Test video blacklist', function () {
284 it('Should blacklist video 3 and keep it federated', async function () { 284 it('Should blacklist video 3 and keep it federated', async function () {
285 this.timeout(10000) 285 this.timeout(10000)
286 286
287 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video3UUID, 'super reason', false) 287 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, video3UUID, 'super reason', false)
288 288
289 await waitJobs(servers) 289 await waitJobs(servers)
290 290
291 { 291 {
292 const res = await getVideosList(servers[ 0 ].url) 292 const res = await getVideosList(servers[0].url)
293 expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined 293 expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined
294 } 294 }
295 295
296 { 296 {
297 const res = await getVideosList(servers[ 1 ].url) 297 const res = await getVideosList(servers[1].url)
298 expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined 298 expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined
299 } 299 }
300 }) 300 })
@@ -302,7 +302,7 @@ describe('Test video blacklist', function () {
302 it('Should unfederate the video', async function () { 302 it('Should unfederate the video', async function () {
303 this.timeout(10000) 303 this.timeout(10000)
304 304
305 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, 'super reason', true) 305 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, video4UUID, 'super reason', true)
306 306
307 await waitJobs(servers) 307 await waitJobs(servers)
308 308
@@ -315,7 +315,7 @@ describe('Test video blacklist', function () {
315 it('Should have the video unfederated even after an Update AP message', async function () { 315 it('Should have the video unfederated even after an Update AP message', async function () {
316 this.timeout(10000) 316 this.timeout(10000)
317 317
318 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, { description: 'super description' }) 318 await updateVideo(servers[0].url, servers[0].accessToken, video4UUID, { description: 'super description' })
319 319
320 await waitJobs(servers) 320 await waitJobs(servers)
321 321
@@ -326,7 +326,7 @@ describe('Test video blacklist', function () {
326 }) 326 })
327 327
328 it('Should have the correct video blacklist unfederate attribute', async function () { 328 it('Should have the correct video blacklist unfederate attribute', async function () {
329 const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' }) 329 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: 'createdAt' })
330 330
331 const blacklistedVideos: VideoBlacklist[] = res.body.data 331 const blacklistedVideos: VideoBlacklist[] = res.body.data
332 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID) 332 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID)
@@ -339,7 +339,7 @@ describe('Test video blacklist', function () {
339 it('Should remove the video from blacklist and refederate the video', async function () { 339 it('Should remove the video from blacklist and refederate the video', async function () {
340 this.timeout(10000) 340 this.timeout(10000)
341 341
342 await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID) 342 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, video4UUID)
343 343
344 await waitJobs(servers) 344 await waitJobs(servers)
345 345
@@ -362,9 +362,9 @@ describe('Test video blacklist', function () {
362 killallServers([ servers[0] ]) 362 killallServers([ servers[0] ])
363 363
364 const config = { 364 const config = {
365 'auto_blacklist': { 365 auto_blacklist: {
366 videos: { 366 videos: {
367 'of_users': { 367 of_users: {
368 enabled: true 368 enabled: true
369 } 369 }
370 } 370 }
@@ -375,8 +375,8 @@ describe('Test video blacklist', function () {
375 { 375 {
376 const user = { username: 'user_without_flag', password: 'password' } 376 const user = { username: 'user_without_flag', password: 'password' }
377 await createUser({ 377 await createUser({
378 url: servers[ 0 ].url, 378 url: servers[0].url,
379 accessToken: servers[ 0 ].accessToken, 379 accessToken: servers[0].accessToken,
380 username: user.username, 380 username: user.username,
381 adminFlags: UserAdminFlag.NONE, 381 adminFlags: UserAdminFlag.NONE,
382 password: user.password, 382 password: user.password,
@@ -393,8 +393,8 @@ describe('Test video blacklist', function () {
393 { 393 {
394 const user = { username: 'user_with_flag', password: 'password' } 394 const user = { username: 'user_with_flag', password: 'password' }
395 await createUser({ 395 await createUser({
396 url: servers[ 0 ].url, 396 url: servers[0].url,
397 accessToken: servers[ 0 ].accessToken, 397 accessToken: servers[0].accessToken,
398 username: user.username, 398 username: user.username,
399 adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST, 399 adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST,
400 password: user.password, 400 password: user.password,
@@ -411,8 +411,8 @@ describe('Test video blacklist', function () {
411 await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' }) 411 await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' })
412 412
413 const res = await getBlacklistedVideosList({ 413 const res = await getBlacklistedVideosList({
414 url: servers[ 0 ].url, 414 url: servers[0].url,
415 token: servers[ 0 ].accessToken, 415 token: servers[0].accessToken,
416 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 416 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
417 }) 417 })
418 418
@@ -428,11 +428,11 @@ describe('Test video blacklist', function () {
428 name: 'URL import', 428 name: 'URL import',
429 channelId: channelOfUserWithoutFlag 429 channelId: channelOfUserWithoutFlag
430 } 430 }
431 await importVideo(servers[ 0 ].url, userWithoutFlag, attributes) 431 await importVideo(servers[0].url, userWithoutFlag, attributes)
432 432
433 const res = await getBlacklistedVideosList({ 433 const res = await getBlacklistedVideosList({
434 url: servers[ 0 ].url, 434 url: servers[0].url,
435 token: servers[ 0 ].accessToken, 435 token: servers[0].accessToken,
436 sort: 'createdAt', 436 sort: 'createdAt',
437 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 437 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
438 }) 438 })
@@ -447,11 +447,11 @@ describe('Test video blacklist', function () {
447 name: 'Torrent import', 447 name: 'Torrent import',
448 channelId: channelOfUserWithoutFlag 448 channelId: channelOfUserWithoutFlag
449 } 449 }
450 await importVideo(servers[ 0 ].url, userWithoutFlag, attributes) 450 await importVideo(servers[0].url, userWithoutFlag, attributes)
451 451
452 const res = await getBlacklistedVideosList({ 452 const res = await getBlacklistedVideosList({
453 url: servers[ 0 ].url, 453 url: servers[0].url,
454 token: servers[ 0 ].accessToken, 454 token: servers[0].accessToken,
455 sort: 'createdAt', 455 sort: 'createdAt',
456 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 456 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
457 }) 457 })
@@ -464,8 +464,8 @@ describe('Test video blacklist', function () {
464 await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' }) 464 await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' })
465 465
466 const res = await getBlacklistedVideosList({ 466 const res = await getBlacklistedVideosList({
467 url: servers[ 0 ].url, 467 url: servers[0].url,
468 token: servers[ 0 ].accessToken, 468 token: servers[0].accessToken,
469 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 469 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
470 }) 470 })
471 471
diff --git a/server/tests/api/videos/video-captions.ts b/server/tests/api/videos/video-captions.ts
index 5e13f5949..b4ecb39f4 100644
--- a/server/tests/api/videos/video-captions.ts
+++ b/server/tests/api/videos/video-captions.ts
@@ -1,16 +1,17 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 checkVideoFilesWereRemoved, cleanupTests, 6 checkVideoFilesWereRemoved,
7 cleanupTests,
7 doubleFollow, 8 doubleFollow,
8 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
9 removeVideo, 10 removeVideo,
10 uploadVideo, 11 uploadVideo,
11 wait 12 wait
12} from '../../../../shared/extra-utils' 13} from '../../../../shared/extra-utils'
13import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index' 14import { ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index'
14import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 15import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
15import { 16import {
16 createVideoCaption, 17 createVideoCaption,
@@ -36,7 +37,7 @@ describe('Test video captions', function () {
36 37
37 await waitJobs(servers) 38 await waitJobs(servers)
38 39
39 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'my video name' }) 40 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'my video name' })
40 videoUUID = res.body.video.uuid 41 videoUUID = res.body.video.uuid
41 42
42 await waitJobs(servers) 43 await waitJobs(servers)
diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts
index 64ee2355a..dee6575b9 100644
--- a/server/tests/api/videos/video-change-ownership.ts
+++ b/server/tests/api/videos/video-change-ownership.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -38,7 +38,7 @@ describe('Test video change ownership - nominal', function () {
38 } 38 }
39 let firstUserAccessToken = '' 39 let firstUserAccessToken = ''
40 let secondUserAccessToken = '' 40 let secondUserAccessToken = ''
41 let lastRequestChangeOwnershipId = undefined 41 let lastRequestChangeOwnershipId = ''
42 42
43 before(async function () { 43 before(async function () {
44 this.timeout(50000) 44 this.timeout(50000)
@@ -48,15 +48,15 @@ describe('Test video change ownership - nominal', function () {
48 48
49 const videoQuota = 42000000 49 const videoQuota = 42000000
50 await createUser({ 50 await createUser({
51 url: servers[ 0 ].url, 51 url: servers[0].url,
52 accessToken: servers[ 0 ].accessToken, 52 accessToken: servers[0].accessToken,
53 username: firstUser.username, 53 username: firstUser.username,
54 password: firstUser.password, 54 password: firstUser.password,
55 videoQuota: videoQuota 55 videoQuota: videoQuota
56 }) 56 })
57 await createUser({ 57 await createUser({
58 url: servers[ 0 ].url, 58 url: servers[0].url,
59 accessToken: servers[ 0 ].accessToken, 59 accessToken: servers[0].accessToken,
60 username: secondUser.username, 60 username: secondUser.username,
61 password: secondUser.password, 61 password: secondUser.password,
62 videoQuota: videoQuota 62 videoQuota: videoQuota
@@ -209,7 +209,7 @@ describe('Test video change ownership - nominal', function () {
209}) 209})
210 210
211describe('Test video change ownership - quota too small', function () { 211describe('Test video change ownership - quota too small', function () {
212 let server: ServerInfo = undefined 212 let server: ServerInfo
213 const firstUser = { 213 const firstUser = {
214 username: 'first', 214 username: 'first',
215 password: 'My great password' 215 password: 'My great password'
@@ -220,14 +220,14 @@ describe('Test video change ownership - quota too small', function () {
220 } 220 }
221 let firstUserAccessToken = '' 221 let firstUserAccessToken = ''
222 let secondUserAccessToken = '' 222 let secondUserAccessToken = ''
223 let lastRequestChangeOwnershipId = undefined 223 let lastRequestChangeOwnershipId = ''
224 224
225 before(async function () { 225 before(async function () {
226 this.timeout(50000) 226 this.timeout(50000)
227 227
228 // Run one server 228 // Run one server
229 server = await flushAndRunServer(1) 229 server = await flushAndRunServer(1)
230 await setAccessTokensToServers([server]) 230 await setAccessTokensToServers([ server ])
231 231
232 const videoQuota = 42000000 232 const videoQuota = 42000000
233 const limitedVideoQuota = 10 233 const limitedVideoQuota = 10
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index 4f600cae8..876a6ab66 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -1,19 +1,21 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index' 5import { User, Video, VideoChannel, ViewsPerDate, VideoDetails } from '../../../../shared/index'
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 createUser, 8 createUser,
9 doubleFollow, 9 doubleFollow,
10 flushAndRunMultipleServers, getVideo, 10 flushAndRunMultipleServers,
11 getVideo,
11 getVideoChannelVideos, 12 getVideoChannelVideos,
12 testImage, 13 testImage,
13 updateVideo, 14 updateVideo,
14 updateVideoChannelAvatar, 15 updateVideoChannelAvatar,
15 uploadVideo, 16 uploadVideo,
16 userLogin 17 userLogin,
18 wait
17} from '../../../../shared/extra-utils' 19} from '../../../../shared/extra-utils'
18import { 20import {
19 addVideoChannel, 21 addVideoChannel,
@@ -24,7 +26,8 @@ import {
24 getVideoChannelsList, 26 getVideoChannelsList,
25 ServerInfo, 27 ServerInfo,
26 setAccessTokensToServers, 28 setAccessTokensToServers,
27 updateVideoChannel 29 updateVideoChannel,
30 viewVideo
28} from '../../../../shared/extra-utils/index' 31} from '../../../../shared/extra-utils/index'
29import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 32import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
30 33
@@ -73,14 +76,14 @@ describe('Test video channels', function () {
73 description: 'super video channel description', 76 description: 'super video channel description',
74 support: 'super video channel support text' 77 support: 'super video channel support text'
75 } 78 }
76 const res = await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel) 79 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
77 secondVideoChannelId = res.body.videoChannel.id 80 secondVideoChannelId = res.body.videoChannel.id
78 } 81 }
79 82
80 // The channel is 1 is propagated to servers 2 83 // The channel is 1 is propagated to servers 2
81 { 84 {
82 const videoAttributesArg = { name: 'my video name', channelId: secondVideoChannelId, support: 'video support field' } 85 const videoAttributesArg = { name: 'my video name', channelId: secondVideoChannelId, support: 'video support field' }
83 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributesArg) 86 const res = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributesArg)
84 videoUUID = res.body.video.uuid 87 videoUUID = res.body.video.uuid
85 } 88 }
86 89
@@ -106,7 +109,7 @@ describe('Test video channels', function () {
106 109
107 it('Should have two video channels when getting account channels on server 1', async function () { 110 it('Should have two video channels when getting account channels on server 1', async function () {
108 const res = await getAccountVideoChannelsList({ 111 const res = await getAccountVideoChannelsList({
109 url: servers[ 0 ].url, 112 url: servers[0].url,
110 accountName: userInfo.account.name + '@' + userInfo.account.host 113 accountName: userInfo.account.name + '@' + userInfo.account.host
111 }) 114 })
112 115
@@ -127,7 +130,7 @@ describe('Test video channels', function () {
127 it('Should paginate and sort account channels', async function () { 130 it('Should paginate and sort account channels', async function () {
128 { 131 {
129 const res = await getAccountVideoChannelsList({ 132 const res = await getAccountVideoChannelsList({
130 url: servers[ 0 ].url, 133 url: servers[0].url,
131 accountName: userInfo.account.name + '@' + userInfo.account.host, 134 accountName: userInfo.account.name + '@' + userInfo.account.host,
132 start: 0, 135 start: 0,
133 count: 1, 136 count: 1,
@@ -137,13 +140,13 @@ describe('Test video channels', function () {
137 expect(res.body.total).to.equal(2) 140 expect(res.body.total).to.equal(2)
138 expect(res.body.data).to.have.lengthOf(1) 141 expect(res.body.data).to.have.lengthOf(1)
139 142
140 const videoChannel: VideoChannel = res.body.data[ 0 ] 143 const videoChannel: VideoChannel = res.body.data[0]
141 expect(videoChannel.name).to.equal('root_channel') 144 expect(videoChannel.name).to.equal('root_channel')
142 } 145 }
143 146
144 { 147 {
145 const res = await getAccountVideoChannelsList({ 148 const res = await getAccountVideoChannelsList({
146 url: servers[ 0 ].url, 149 url: servers[0].url,
147 accountName: userInfo.account.name + '@' + userInfo.account.host, 150 accountName: userInfo.account.name + '@' + userInfo.account.host,
148 start: 0, 151 start: 0,
149 count: 1, 152 count: 1,
@@ -153,13 +156,13 @@ describe('Test video channels', function () {
153 expect(res.body.total).to.equal(2) 156 expect(res.body.total).to.equal(2)
154 expect(res.body.data).to.have.lengthOf(1) 157 expect(res.body.data).to.have.lengthOf(1)
155 158
156 const videoChannel: VideoChannel = res.body.data[ 0 ] 159 const videoChannel: VideoChannel = res.body.data[0]
157 expect(videoChannel.name).to.equal('second_video_channel') 160 expect(videoChannel.name).to.equal('second_video_channel')
158 } 161 }
159 162
160 { 163 {
161 const res = await getAccountVideoChannelsList({ 164 const res = await getAccountVideoChannelsList({
162 url: servers[ 0 ].url, 165 url: servers[0].url,
163 accountName: userInfo.account.name + '@' + userInfo.account.host, 166 accountName: userInfo.account.name + '@' + userInfo.account.host,
164 start: 1, 167 start: 1,
165 count: 1, 168 count: 1,
@@ -169,14 +172,14 @@ describe('Test video channels', function () {
169 expect(res.body.total).to.equal(2) 172 expect(res.body.total).to.equal(2)
170 expect(res.body.data).to.have.lengthOf(1) 173 expect(res.body.data).to.have.lengthOf(1)
171 174
172 const videoChannel: VideoChannel = res.body.data[ 0 ] 175 const videoChannel: VideoChannel = res.body.data[0]
173 expect(videoChannel.name).to.equal('root_channel') 176 expect(videoChannel.name).to.equal('root_channel')
174 } 177 }
175 }) 178 })
176 179
177 it('Should have one video channel when getting account channels on server 2', async function () { 180 it('Should have one video channel when getting account channels on server 2', async function () {
178 const res = await getAccountVideoChannelsList({ 181 const res = await getAccountVideoChannelsList({
179 url: servers[ 1 ].url, 182 url: servers[1].url,
180 accountName: userInfo.account.name + '@' + userInfo.account.host 183 accountName: userInfo.account.name + '@' + userInfo.account.host
181 }) 184 })
182 185
@@ -349,19 +352,55 @@ describe('Test video channels', function () {
349 it('Should create the main channel with an uuid if there is a conflict', async function () { 352 it('Should create the main channel with an uuid if there is a conflict', async function () {
350 { 353 {
351 const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' } 354 const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' }
352 await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel) 355 await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
353 } 356 }
354 357
355 { 358 {
356 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: 'toto', password: 'password' }) 359 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: 'toto', password: 'password' })
357 const accessToken = await userLogin(servers[ 0 ], { username: 'toto', password: 'password' }) 360 const accessToken = await userLogin(servers[0], { username: 'toto', password: 'password' })
358 361
359 const res = await getMyUserInformation(servers[ 0 ].url, accessToken) 362 const res = await getMyUserInformation(servers[0].url, accessToken)
360 const videoChannel = res.body.videoChannels[ 0 ] 363 const videoChannel = res.body.videoChannels[0]
361 expect(videoChannel.name).to.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/) 364 expect(videoChannel.name).to.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)
362 } 365 }
363 }) 366 })
364 367
368 it('Should report correct channel statistics', async function () {
369
370 {
371 const res = await getAccountVideoChannelsList({
372 url: servers[0].url,
373 accountName: userInfo.account.name + '@' + userInfo.account.host,
374 withStats: true
375 })
376 res.body.data.forEach((channel: VideoChannel) => {
377 expect(channel).to.haveOwnProperty('viewsPerDay')
378 expect(channel.viewsPerDay).to.have.length(30 + 1) // daysPrior + today
379 channel.viewsPerDay.forEach((v: ViewsPerDate) => {
380 expect(v.date).to.be.an('string')
381 expect(v.views).to.equal(0)
382 })
383 })
384 }
385
386 {
387 // video has been posted on channel firstVideoChannelId since last update
388 await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.1,127.0.0.1')
389 await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.2,127.0.0.1')
390
391 // Wait the repeatable job
392 await wait(8000)
393
394 const res = await getAccountVideoChannelsList({
395 url: servers[0].url,
396 accountName: userInfo.account.name + '@' + userInfo.account.host,
397 withStats: true
398 })
399 const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === firstVideoChannelId)
400 expect(channelWithView.viewsPerDay.slice(-1)[0].views).to.equal(2)
401 }
402 })
403
365 after(async function () { 404 after(async function () {
366 await cleanupTests(servers) 405 await cleanupTests(servers)
367 }) 406 })
diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts
index 06e4ff9c8..afb58e95a 100644
--- a/server/tests/api/videos/video-comments.ts
+++ b/server/tests/api/videos/video-comments.ts
@@ -1,17 +1,17 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
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 { cleanupTests, testImage } from '../../../../shared/extra-utils' 6import { cleanupTests, testImage } from '../../../../shared/extra-utils'
7import { 7import {
8 createUser,
8 dateIsValid, 9 dateIsValid,
9 flushAndRunServer, 10 flushAndRunServer,
11 getAccessToken,
10 ServerInfo, 12 ServerInfo,
11 setAccessTokensToServers, 13 setAccessTokensToServers,
12 updateMyAvatar, 14 updateMyAvatar,
13 getAccessToken,
14 createUser,
15 uploadVideo 15 uploadVideo
16} from '../../../../shared/extra-utils/index' 16} from '../../../../shared/extra-utils/index'
17import { 17import {
diff --git a/server/tests/api/videos/video-description.ts b/server/tests/api/videos/video-description.ts
index db4d278bf..b8e98e45f 100644
--- a/server/tests/api/videos/video-description.ts
+++ b/server/tests/api/videos/video-description.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -8,7 +8,6 @@ import {
8 getVideo, 8 getVideo,
9 getVideoDescription, 9 getVideoDescription,
10 getVideosList, 10 getVideosList,
11 killallServers,
12 ServerInfo, 11 ServerInfo,
13 setAccessTokensToServers, 12 setAccessTokensToServers,
14 updateVideo, 13 updateVideo,
@@ -23,7 +22,7 @@ describe('Test video description', function () {
23 let servers: ServerInfo[] = [] 22 let servers: ServerInfo[] = []
24 let videoUUID = '' 23 let videoUUID = ''
25 let videoId: number 24 let videoId: number
26 let longDescription = 'my super description for server 1'.repeat(50) 25 const longDescription = 'my super description for server 1'.repeat(50)
27 26
28 before(async function () { 27 before(async function () {
29 this.timeout(40000) 28 this.timeout(40000)
@@ -61,7 +60,7 @@ describe('Test video description', function () {
61 60
62 // 30 characters * 6 -> 240 characters 61 // 30 characters * 6 -> 240 characters
63 const truncatedDescription = 'my super description for server 1'.repeat(7) + 62 const truncatedDescription = 'my super description for server 1'.repeat(7) +
64 'my super descrip...' 63 'my super descrip...'
65 64
66 expect(video.description).to.equal(truncatedDescription) 65 expect(video.description).to.equal(truncatedDescription)
67 } 66 }
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts
index bde3b5656..6555bc8b6 100644
--- a/server/tests/api/videos/video-hls.ts
+++ b/server/tests/api/videos/video-hls.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -10,13 +10,16 @@ import {
10 doubleFollow, 10 doubleFollow,
11 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
12 getPlaylist, 12 getPlaylist,
13 getVideo, makeGetRequest, makeRawRequest, 13 getVideo,
14 makeRawRequest,
14 removeVideo, 15 removeVideo,
15 ServerInfo, 16 ServerInfo,
16 setAccessTokensToServers, updateCustomSubConfig, 17 setAccessTokensToServers,
18 updateCustomSubConfig,
17 updateVideo, 19 updateVideo,
18 uploadVideo, 20 uploadVideo,
19 waitJobs, webtorrentAdd 21 waitJobs,
22 webtorrentAdd
20} from '../../../../shared/extra-utils' 23} from '../../../../shared/extra-utils'
21import { VideoDetails } from '../../../../shared/models/videos' 24import { VideoDetails } from '../../../../shared/models/videos'
22import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type' 25import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
@@ -48,7 +51,9 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
48 51
49 expect(file.magnetUri).to.have.lengthOf.above(2) 52 expect(file.magnetUri).to.have.lengthOf.above(2)
50 expect(file.torrentUrl).to.equal(`${baseUrl}/static/torrents/${videoDetails.uuid}-${file.resolution.id}-hls.torrent`) 53 expect(file.torrentUrl).to.equal(`${baseUrl}/static/torrents/${videoDetails.uuid}-${file.resolution.id}-hls.torrent`)
51 expect(file.fileUrl).to.equal(`${baseUrl}/static/streaming-playlists/hls/${videoDetails.uuid}/${videoDetails.uuid}-${file.resolution.id}-fragmented.mp4`) 54 expect(file.fileUrl).to.equal(
55 `${baseUrl}/static/streaming-playlists/hls/${videoDetails.uuid}/${videoDetails.uuid}-${file.resolution.id}-fragmented.mp4`
56 )
52 expect(file.resolution.label).to.equal(resolution + 'p') 57 expect(file.resolution.label).to.equal(resolution + 'p')
53 58
54 await makeRawRequest(file.torrentUrl, 200) 59 await makeRawRequest(file.torrentUrl, 200)
@@ -66,7 +71,9 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
66 const masterPlaylist = res.text 71 const masterPlaylist = res.text
67 72
68 for (const resolution of resolutions) { 73 for (const resolution of resolutions) {
69 const reg = new RegExp('#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',FRAME-RATE=\\d+,CODECS="avc1.64001f,mp4a.40.2"') 74 const reg = new RegExp(
75 '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',FRAME-RATE=\\d+,CODECS="avc1.64001f,mp4a.40.2"'
76 )
70 77
71 expect(masterPlaylist).to.match(reg) 78 expect(masterPlaylist).to.match(reg)
72 expect(masterPlaylist).to.contain(`${resolution}.m3u8`) 79 expect(masterPlaylist).to.contain(`${resolution}.m3u8`)
@@ -102,7 +109,7 @@ describe('Test HLS videos', function () {
102 it('Should upload a video and transcode it to HLS', async function () { 109 it('Should upload a video and transcode it to HLS', async function () {
103 this.timeout(120000) 110 this.timeout(120000)
104 111
105 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video 1', fixture: 'video_short.webm' }) 112 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1', fixture: 'video_short.webm' })
106 videoUUID = res.body.video.uuid 113 videoUUID = res.body.video.uuid
107 114
108 await waitJobs(servers) 115 await waitJobs(servers)
@@ -113,7 +120,7 @@ describe('Test HLS videos', function () {
113 it('Should upload an audio file and transcode it to HLS', async function () { 120 it('Should upload an audio file and transcode it to HLS', async function () {
114 this.timeout(120000) 121 this.timeout(120000)
115 122
116 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video audio', fixture: 'sample.ogg' }) 123 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video audio', fixture: 'sample.ogg' })
117 videoAudioUUID = res.body.video.uuid 124 videoAudioUUID = res.body.video.uuid
118 125
119 await waitJobs(servers) 126 await waitJobs(servers)
@@ -124,7 +131,7 @@ describe('Test HLS videos', function () {
124 it('Should update the video', async function () { 131 it('Should update the video', async function () {
125 this.timeout(10000) 132 this.timeout(10000)
126 133
127 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, { name: 'video 1 updated' }) 134 await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { name: 'video 1 updated' })
128 135
129 await waitJobs(servers) 136 await waitJobs(servers)
130 137
@@ -134,8 +141,8 @@ describe('Test HLS videos', function () {
134 it('Should delete videos', async function () { 141 it('Should delete videos', async function () {
135 this.timeout(10000) 142 this.timeout(10000)
136 143
137 await removeVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID) 144 await removeVideo(servers[0].url, servers[0].accessToken, videoUUID)
138 await removeVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAudioUUID) 145 await removeVideo(servers[0].url, servers[0].accessToken, videoAudioUUID)
139 146
140 await waitJobs(servers) 147 await waitJobs(servers)
141 148
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index 1233ed6eb..4d5989f43 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -1,8 +1,8 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { VideoDetails, VideoImport, VideoPrivacy } from '../../../../shared/models/videos' 5import { VideoDetails, VideoImport, VideoPrivacy, VideoCaption } from '../../../../shared/models/videos'
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 doubleFollow, 8 doubleFollow,
@@ -11,13 +11,15 @@ import {
11 getMyVideos, 11 getMyVideos,
12 getVideo, 12 getVideo,
13 getVideosList, 13 getVideosList,
14 listVideoCaptions,
15 testCaptionFile,
14 immutableAssign, 16 immutableAssign,
15 killallServers,
16 ServerInfo, 17 ServerInfo,
17 setAccessTokensToServers 18 setAccessTokensToServers
18} from '../../../../shared/extra-utils' 19} from '../../../../shared/extra-utils'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 20import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
20import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../../../shared/extra-utils/videos/video-imports' 21import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
22import { testImage } from '../../../../shared/extra-utils/miscs/miscs'
21 23
22const expect = chai.expect 24const expect = chai.expect
23 25
@@ -61,11 +63,14 @@ describe('Test video imports', function () {
61 63
62 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4') 64 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
63 expect(videoMagnet.name).to.contain('super peertube2 video') 65 expect(videoMagnet.name).to.contain('super peertube2 video')
66
67 const resCaptions = await listVideoCaptions(url, idHttp)
68 expect(resCaptions.body.total).to.equal(2)
64 } 69 }
65 70
66 async function checkVideoServer2 (url: string, id: number | string) { 71 async function checkVideoServer2 (url: string, id: number | string) {
67 const res = await getVideo(url, id) 72 const res = await getVideo(url, id)
68 const video = res.body 73 const video: VideoDetails = res.body
69 74
70 expect(video.name).to.equal('my super name') 75 expect(video.name).to.equal('my super name')
71 expect(video.category.label).to.equal('Entertainment') 76 expect(video.category.label).to.equal('Entertainment')
@@ -76,6 +81,9 @@ describe('Test video imports', function () {
76 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ]) 81 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
77 82
78 expect(video.files).to.have.lengthOf(1) 83 expect(video.files).to.have.lengthOf(1)
84
85 const resCaptions = await listVideoCaptions(url, id)
86 expect(resCaptions.body.total).to.equal(2)
79 } 87 }
80 88
81 before(async function () { 89 before(async function () {
@@ -88,12 +96,12 @@ describe('Test video imports', function () {
88 96
89 { 97 {
90 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken) 98 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
91 channelIdServer1 = res.body.videoChannels[ 0 ].id 99 channelIdServer1 = res.body.videoChannels[0].id
92 } 100 }
93 101
94 { 102 {
95 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken) 103 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
96 channelIdServer2 = res.body.videoChannels[ 0 ].id 104 channelIdServer2 = res.body.videoChannels[0].id
97 } 105 }
98 106
99 await doubleFollow(servers[0], servers[1]) 107 await doubleFollow(servers[0], servers[1])
@@ -111,6 +119,48 @@ describe('Test video imports', function () {
111 const attributes = immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }) 119 const attributes = immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() })
112 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes) 120 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
113 expect(res.body.video.name).to.equal('small video - youtube') 121 expect(res.body.video.name).to.equal('small video - youtube')
122 expect(res.body.video.thumbnailPath).to.equal(`/static/thumbnails/${res.body.video.uuid}.jpg`)
123 expect(res.body.video.previewPath).to.equal(`/static/previews/${res.body.video.uuid}.jpg`)
124 await testImage(servers[0].url, 'video_import_thumbnail', res.body.video.thumbnailPath)
125 await testImage(servers[0].url, 'video_import_preview', res.body.video.previewPath)
126
127 const resCaptions = await listVideoCaptions(servers[0].url, res.body.video.id)
128 const videoCaptions: VideoCaption[] = resCaptions.body.data
129 expect(videoCaptions).to.have.lengthOf(2)
130
131 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
132 expect(enCaption).to.exist
133 expect(enCaption.language.label).to.equal('English')
134 expect(enCaption.captionPath).to.equal(`/static/video-captions/${res.body.video.uuid}-en.vtt`)
135 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT
136Kind: captions
137Language: en
138
13900:00:01.600 --> 00:00:04.200
140English (US)
141
14200:00:05.900 --> 00:00:07.999
143This is a subtitle in American English
144
14500:00:10.000 --> 00:00:14.000
146Adding subtitles is very easy to do`)
147
148 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
149 expect(frCaption).to.exist
150 expect(frCaption.language.label).to.equal('French')
151 expect(frCaption.captionPath).to.equal(`/static/video-captions/${res.body.video.uuid}-fr.vtt`)
152 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT
153Kind: captions
154Language: fr
155
15600:00:01.600 --> 00:00:04.200
157Français (FR)
158
15900:00:05.900 --> 00:00:07.999
160C'est un sous-titre français
161
16200:00:10.000 --> 00:00:14.000
163Ajouter un sous-titre est vraiment facile`)
114 } 164 }
115 165
116 { 166 {
@@ -214,7 +264,7 @@ describe('Test video imports', function () {
214 264
215 await checkVideoServer2(server.url, res.body.data[0].uuid) 265 await checkVideoServer2(server.url, res.body.data[0].uuid)
216 266
217 const [ ,videoHttp, videoMagnet, videoTorrent ] = res.body.data 267 const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data
218 await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) 268 await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
219 } 269 }
220 }) 270 })
diff --git a/server/tests/api/videos/video-nsfw.ts b/server/tests/api/videos/video-nsfw.ts
index ad6a4b43f..b16b484b9 100644
--- a/server/tests/api/videos/video-nsfw.ts
+++ b/server/tests/api/videos/video-nsfw.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -19,12 +19,20 @@ import {
19 updateCustomConfig, 19 updateCustomConfig,
20 updateMyUser 20 updateMyUser
21} from '../../../../shared/extra-utils' 21} from '../../../../shared/extra-utils'
22import { ServerConfig } from '../../../../shared/models' 22import { ServerConfig, VideosOverview } from '../../../../shared/models'
23import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 23import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
24import { User } from '../../../../shared/models/users' 24import { User } from '../../../../shared/models/users'
25import { getVideosOverview, getVideosOverviewWithToken } from '@shared/extra-utils/overviews/overviews'
25 26
26const expect = chai.expect 27const expect = chai.expect
27 28
29function createOverviewRes (res: any) {
30 const overview = res.body as VideosOverview
31
32 const videos = overview.categories[0].videos
33 return { body: { data: videos, total: videos.length } }
34}
35
28describe('Test video NSFW policy', function () { 36describe('Test video NSFW policy', function () {
29 let server: ServerInfo 37 let server: ServerInfo
30 let userAccessToken: string 38 let userAccessToken: string
@@ -36,22 +44,38 @@ describe('Test video NSFW policy', function () {
36 const user: User = res.body 44 const user: User = res.body
37 const videoChannelName = user.videoChannels[0].name 45 const videoChannelName = user.videoChannels[0].name
38 const accountName = user.account.name + '@' + user.account.host 46 const accountName = user.account.name + '@' + user.account.host
47 const hasQuery = Object.keys(query).length !== 0
48 let promises: Promise<any>[]
39 49
40 if (token) { 50 if (token) {
41 return Promise.all([ 51 promises = [
42 getVideosListWithToken(server.url, token, query), 52 getVideosListWithToken(server.url, token, query),
43 searchVideoWithToken(server.url, 'n', token, query), 53 searchVideoWithToken(server.url, 'n', token, query),
44 getAccountVideos(server.url, token, accountName, 0, 5, undefined, query), 54 getAccountVideos(server.url, token, accountName, 0, 5, undefined, query),
45 getVideoChannelVideos(server.url, token, videoChannelName, 0, 5, undefined, query) 55 getVideoChannelVideos(server.url, token, videoChannelName, 0, 5, undefined, query)
46 ]) 56 ]
57
58 // Overviews do not support video filters
59 if (!hasQuery) {
60 promises.push(getVideosOverviewWithToken(server.url, 1, token).then(res => createOverviewRes(res)))
61 }
62
63 return Promise.all(promises)
47 } 64 }
48 65
49 return Promise.all([ 66 promises = [
50 getVideosList(server.url), 67 getVideosList(server.url),
51 searchVideo(server.url, 'n'), 68 searchVideo(server.url, 'n'),
52 getAccountVideos(server.url, undefined, accountName, 0, 5), 69 getAccountVideos(server.url, undefined, accountName, 0, 5),
53 getVideoChannelVideos(server.url, undefined, videoChannelName, 0, 5) 70 getVideoChannelVideos(server.url, undefined, videoChannelName, 0, 5)
54 ]) 71 ]
72
73 // Overviews do not support video filters
74 if (!hasQuery) {
75 promises.push(getVideosOverview(server.url, 1).then(res => createOverviewRes(res)))
76 }
77
78 return Promise.all(promises)
55 }) 79 })
56 } 80 }
57 81
@@ -63,12 +87,12 @@ describe('Test video NSFW policy', function () {
63 await setAccessTokensToServers([ server ]) 87 await setAccessTokensToServers([ server ])
64 88
65 { 89 {
66 const attributes = { name: 'nsfw', nsfw: true } 90 const attributes = { name: 'nsfw', nsfw: true, category: 1 }
67 await uploadVideo(server.url, server.accessToken, attributes) 91 await uploadVideo(server.url, server.accessToken, attributes)
68 } 92 }
69 93
70 { 94 {
71 const attributes = { name: 'normal', nsfw: false } 95 const attributes = { name: 'normal', nsfw: false, category: 1 }
72 await uploadVideo(server.url, server.accessToken, attributes) 96 await uploadVideo(server.url, server.accessToken, attributes)
73 } 97 }
74 98
@@ -89,8 +113,8 @@ describe('Test video NSFW policy', function () {
89 113
90 const videos = res.body.data 114 const videos = res.body.data
91 expect(videos).to.have.lengthOf(2) 115 expect(videos).to.have.lengthOf(2)
92 expect(videos[ 0 ].name).to.equal('normal') 116 expect(videos[0].name).to.equal('normal')
93 expect(videos[ 1 ].name).to.equal('nsfw') 117 expect(videos[1].name).to.equal('nsfw')
94 } 118 }
95 }) 119 })
96 120
@@ -107,7 +131,7 @@ describe('Test video NSFW policy', function () {
107 131
108 const videos = res.body.data 132 const videos = res.body.data
109 expect(videos).to.have.lengthOf(1) 133 expect(videos).to.have.lengthOf(1)
110 expect(videos[ 0 ].name).to.equal('normal') 134 expect(videos[0].name).to.equal('normal')
111 } 135 }
112 }) 136 })
113 137
@@ -124,8 +148,8 @@ describe('Test video NSFW policy', function () {
124 148
125 const videos = res.body.data 149 const videos = res.body.data
126 expect(videos).to.have.lengthOf(2) 150 expect(videos).to.have.lengthOf(2)
127 expect(videos[ 0 ].name).to.equal('normal') 151 expect(videos[0].name).to.equal('normal')
128 expect(videos[ 1 ].name).to.equal('nsfw') 152 expect(videos[1].name).to.equal('nsfw')
129 } 153 }
130 }) 154 })
131 }) 155 })
@@ -154,8 +178,8 @@ describe('Test video NSFW policy', function () {
154 178
155 const videos = res.body.data 179 const videos = res.body.data
156 expect(videos).to.have.lengthOf(2) 180 expect(videos).to.have.lengthOf(2)
157 expect(videos[ 0 ].name).to.equal('normal') 181 expect(videos[0].name).to.equal('normal')
158 expect(videos[ 1 ].name).to.equal('nsfw') 182 expect(videos[1].name).to.equal('nsfw')
159 } 183 }
160 }) 184 })
161 185
@@ -171,8 +195,8 @@ describe('Test video NSFW policy', function () {
171 195
172 const videos = res.body.data 196 const videos = res.body.data
173 expect(videos).to.have.lengthOf(2) 197 expect(videos).to.have.lengthOf(2)
174 expect(videos[ 0 ].name).to.equal('normal') 198 expect(videos[0].name).to.equal('normal')
175 expect(videos[ 1 ].name).to.equal('nsfw') 199 expect(videos[1].name).to.equal('nsfw')
176 } 200 }
177 }) 201 })
178 202
@@ -188,7 +212,7 @@ describe('Test video NSFW policy', function () {
188 212
189 const videos = res.body.data 213 const videos = res.body.data
190 expect(videos).to.have.lengthOf(1) 214 expect(videos).to.have.lengthOf(1)
191 expect(videos[ 0 ].name).to.equal('normal') 215 expect(videos[0].name).to.equal('normal')
192 } 216 }
193 }) 217 })
194 218
@@ -198,8 +222,8 @@ describe('Test video NSFW policy', function () {
198 222
199 const videos = res.body.data 223 const videos = res.body.data
200 expect(videos).to.have.lengthOf(2) 224 expect(videos).to.have.lengthOf(2)
201 expect(videos[ 0 ].name).to.equal('normal') 225 expect(videos[0].name).to.equal('normal')
202 expect(videos[ 1 ].name).to.equal('nsfw') 226 expect(videos[1].name).to.equal('nsfw')
203 }) 227 })
204 228
205 it('Should display NSFW videos when the nsfw param === true', async function () { 229 it('Should display NSFW videos when the nsfw param === true', async function () {
@@ -208,7 +232,7 @@ describe('Test video NSFW policy', function () {
208 232
209 const videos = res.body.data 233 const videos = res.body.data
210 expect(videos).to.have.lengthOf(1) 234 expect(videos).to.have.lengthOf(1)
211 expect(videos[ 0 ].name).to.equal('nsfw') 235 expect(videos[0].name).to.equal('nsfw')
212 } 236 }
213 }) 237 })
214 238
@@ -218,7 +242,7 @@ describe('Test video NSFW policy', function () {
218 242
219 const videos = res.body.data 243 const videos = res.body.data
220 expect(videos).to.have.lengthOf(1) 244 expect(videos).to.have.lengthOf(1)
221 expect(videos[ 0 ].name).to.equal('normal') 245 expect(videos[0].name).to.equal('normal')
222 } 246 }
223 }) 247 })
224 248
@@ -228,8 +252,8 @@ describe('Test video NSFW policy', function () {
228 252
229 const videos = res.body.data 253 const videos = res.body.data
230 expect(videos).to.have.lengthOf(2) 254 expect(videos).to.have.lengthOf(2)
231 expect(videos[ 0 ].name).to.equal('normal') 255 expect(videos[0].name).to.equal('normal')
232 expect(videos[ 1 ].name).to.equal('nsfw') 256 expect(videos[1].name).to.equal('nsfw')
233 } 257 }
234 }) 258 })
235 }) 259 })
diff --git a/server/tests/api/videos/video-playlist-thumbnails.ts b/server/tests/api/videos/video-playlist-thumbnails.ts
index 73ab02c17..a93a0b7de 100644
--- a/server/tests/api/videos/video-playlist-thumbnails.ts
+++ b/server/tests/api/videos/video-playlist-thumbnails.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -8,14 +8,15 @@ import {
8 createVideoPlaylist, 8 createVideoPlaylist,
9 doubleFollow, 9 doubleFollow,
10 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
11 getVideoPlaylistsList, removeVideoFromPlaylist, 11 getVideoPlaylistsList,
12 removeVideoFromPlaylist,
13 reorderVideosPlaylist,
12 ServerInfo, 14 ServerInfo,
13 setAccessTokensToServers, 15 setAccessTokensToServers,
14 setDefaultVideoChannel, 16 setDefaultVideoChannel,
15 testImage, 17 testImage,
16 uploadVideoAndGetId, 18 uploadVideoAndGetId,
17 waitJobs, 19 waitJobs
18 reorderVideosPlaylist
19} from '../../../../shared/extra-utils' 20} from '../../../../shared/extra-utils'
20import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' 21import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
21 22
@@ -69,19 +70,19 @@ describe('Playlist thumbnail', function () {
69 this.timeout(30000) 70 this.timeout(30000)
70 71
71 const res = await createVideoPlaylist({ 72 const res = await createVideoPlaylist({
72 url: servers[ 1 ].url, 73 url: servers[1].url,
73 token: servers[ 1 ].accessToken, 74 token: servers[1].accessToken,
74 playlistAttrs: { 75 playlistAttrs: {
75 displayName: 'playlist without thumbnail', 76 displayName: 'playlist without thumbnail',
76 privacy: VideoPlaylistPrivacy.PUBLIC, 77 privacy: VideoPlaylistPrivacy.PUBLIC,
77 videoChannelId: servers[ 1 ].videoChannel.id 78 videoChannelId: servers[1].videoChannel.id
78 } 79 }
79 }) 80 })
80 playlistWithoutThumbnail = res.body.videoPlaylist.id 81 playlistWithoutThumbnail = res.body.videoPlaylist.id
81 82
82 const res2 = await addVideoInPlaylist({ 83 const res2 = await addVideoInPlaylist({
83 url: servers[ 1 ].url, 84 url: servers[1].url,
84 token: servers[ 1 ].accessToken, 85 token: servers[1].accessToken,
85 playlistId: playlistWithoutThumbnail, 86 playlistId: playlistWithoutThumbnail,
86 elementAttrs: { videoId: video1 } 87 elementAttrs: { videoId: video1 }
87 }) 88 })
@@ -99,20 +100,20 @@ describe('Playlist thumbnail', function () {
99 this.timeout(30000) 100 this.timeout(30000)
100 101
101 const res = await createVideoPlaylist({ 102 const res = await createVideoPlaylist({
102 url: servers[ 1 ].url, 103 url: servers[1].url,
103 token: servers[ 1 ].accessToken, 104 token: servers[1].accessToken,
104 playlistAttrs: { 105 playlistAttrs: {
105 displayName: 'playlist with thumbnail', 106 displayName: 'playlist with thumbnail',
106 privacy: VideoPlaylistPrivacy.PUBLIC, 107 privacy: VideoPlaylistPrivacy.PUBLIC,
107 videoChannelId: servers[ 1 ].videoChannel.id, 108 videoChannelId: servers[1].videoChannel.id,
108 thumbnailfile: 'thumbnail.jpg' 109 thumbnailfile: 'thumbnail.jpg'
109 } 110 }
110 }) 111 })
111 playlistWithThumbnail = res.body.videoPlaylist.id 112 playlistWithThumbnail = res.body.videoPlaylist.id
112 113
113 const res2 = await addVideoInPlaylist({ 114 const res2 = await addVideoInPlaylist({
114 url: servers[ 1 ].url, 115 url: servers[1].url,
115 token: servers[ 1 ].accessToken, 116 token: servers[1].accessToken,
116 playlistId: playlistWithThumbnail, 117 playlistId: playlistWithThumbnail,
117 elementAttrs: { videoId: video1 } 118 elementAttrs: { videoId: video1 }
118 }) 119 })
@@ -130,8 +131,8 @@ describe('Playlist thumbnail', function () {
130 this.timeout(30000) 131 this.timeout(30000)
131 132
132 const res = await addVideoInPlaylist({ 133 const res = await addVideoInPlaylist({
133 url: servers[ 1 ].url, 134 url: servers[1].url,
134 token: servers[ 1 ].accessToken, 135 token: servers[1].accessToken,
135 playlistId: playlistWithoutThumbnail, 136 playlistId: playlistWithoutThumbnail,
136 elementAttrs: { videoId: video2 } 137 elementAttrs: { videoId: video2 }
137 }) 138 })
@@ -159,8 +160,8 @@ describe('Playlist thumbnail', function () {
159 this.timeout(30000) 160 this.timeout(30000)
160 161
161 const res = await addVideoInPlaylist({ 162 const res = await addVideoInPlaylist({
162 url: servers[ 1 ].url, 163 url: servers[1].url,
163 token: servers[ 1 ].accessToken, 164 token: servers[1].accessToken,
164 playlistId: playlistWithThumbnail, 165 playlistId: playlistWithThumbnail,
165 elementAttrs: { videoId: video2 } 166 elementAttrs: { videoId: video2 }
166 }) 167 })
@@ -188,8 +189,8 @@ describe('Playlist thumbnail', function () {
188 this.timeout(30000) 189 this.timeout(30000)
189 190
190 await removeVideoFromPlaylist({ 191 await removeVideoFromPlaylist({
191 url: servers[ 1 ].url, 192 url: servers[1].url,
192 token: servers[ 1 ].accessToken, 193 token: servers[1].accessToken,
193 playlistId: playlistWithoutThumbnail, 194 playlistId: playlistWithoutThumbnail,
194 playlistElementId: withoutThumbnailE1 195 playlistElementId: withoutThumbnailE1
195 }) 196 })
@@ -206,8 +207,8 @@ describe('Playlist thumbnail', function () {
206 this.timeout(30000) 207 this.timeout(30000)
207 208
208 await removeVideoFromPlaylist({ 209 await removeVideoFromPlaylist({
209 url: servers[ 1 ].url, 210 url: servers[1].url,
210 token: servers[ 1 ].accessToken, 211 token: servers[1].accessToken,
211 playlistId: playlistWithThumbnail, 212 playlistId: playlistWithThumbnail,
212 playlistElementId: withThumbnailE1 213 playlistElementId: withThumbnailE1
213 }) 214 })
@@ -224,8 +225,8 @@ describe('Playlist thumbnail', function () {
224 this.timeout(30000) 225 this.timeout(30000)
225 226
226 await removeVideoFromPlaylist({ 227 await removeVideoFromPlaylist({
227 url: servers[ 1 ].url, 228 url: servers[1].url,
228 token: servers[ 1 ].accessToken, 229 token: servers[1].accessToken,
229 playlistId: playlistWithoutThumbnail, 230 playlistId: playlistWithoutThumbnail,
230 playlistElementId: withoutThumbnailE2 231 playlistElementId: withoutThumbnailE2
231 }) 232 })
@@ -242,8 +243,8 @@ describe('Playlist thumbnail', function () {
242 this.timeout(30000) 243 this.timeout(30000)
243 244
244 await removeVideoFromPlaylist({ 245 await removeVideoFromPlaylist({
245 url: servers[ 1 ].url, 246 url: servers[1].url,
246 token: servers[ 1 ].accessToken, 247 token: servers[1].accessToken,
247 playlistId: playlistWithThumbnail, 248 playlistId: playlistWithThumbnail,
248 playlistElementId: withThumbnailE2 249 playlistElementId: withThumbnailE2
249 }) 250 })
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts
index 9fd48ac7c..2bb97d7a8 100644
--- a/server/tests/api/videos/video-playlists.ts
+++ b/server/tests/api/videos/video-playlists.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -141,12 +141,12 @@ describe('Test video playlists', function () {
141 servers[2].videos = await Promise.all(serverPromises[2]) 141 servers[2].videos = await Promise.all(serverPromises[2])
142 } 142 }
143 143
144 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'NSFW video', nsfw: true })).id 144 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'NSFW video', nsfw: true })).id
145 145
146 { 146 {
147 await createUser({ 147 await createUser({
148 url: servers[ 0 ].url, 148 url: servers[0].url,
149 accessToken: servers[ 0 ].accessToken, 149 accessToken: servers[0].accessToken,
150 username: 'user1', 150 username: 'user1',
151 password: 'password' 151 password: 'password'
152 }) 152 })
@@ -158,17 +158,17 @@ describe('Test video playlists', function () {
158 158
159 describe('Get default playlists', function () { 159 describe('Get default playlists', function () {
160 it('Should list video playlist privacies', async function () { 160 it('Should list video playlist privacies', async function () {
161 const res = await getVideoPlaylistPrivacies(servers[ 0 ].url) 161 const res = await getVideoPlaylistPrivacies(servers[0].url)
162 162
163 const privacies = res.body 163 const privacies = res.body
164 expect(Object.keys(privacies)).to.have.length.at.least(3) 164 expect(Object.keys(privacies)).to.have.length.at.least(3)
165 165
166 expect(privacies[ 3 ]).to.equal('Private') 166 expect(privacies[3]).to.equal('Private')
167 }) 167 })
168 168
169 it('Should list watch later playlist', async function () { 169 it('Should list watch later playlist', async function () {
170 const url = servers[ 0 ].url 170 const url = servers[0].url
171 const accessToken = servers[ 0 ].accessToken 171 const accessToken = servers[0].accessToken
172 172
173 { 173 {
174 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER) 174 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
@@ -176,7 +176,7 @@ describe('Test video playlists', function () {
176 expect(res.body.total).to.equal(1) 176 expect(res.body.total).to.equal(1)
177 expect(res.body.data).to.have.lengthOf(1) 177 expect(res.body.data).to.have.lengthOf(1)
178 178
179 const playlist: VideoPlaylist = res.body.data[ 0 ] 179 const playlist: VideoPlaylist = res.body.data[0]
180 expect(playlist.displayName).to.equal('Watch later') 180 expect(playlist.displayName).to.equal('Watch later')
181 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER) 181 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER)
182 expect(playlist.type.label).to.equal('Watch later') 182 expect(playlist.type.label).to.equal('Watch later')
@@ -197,15 +197,15 @@ describe('Test video playlists', function () {
197 }) 197 })
198 198
199 it('Should get private playlist for a classic user', async function () { 199 it('Should get private playlist for a classic user', async function () {
200 const token = await generateUserAccessToken(servers[ 0 ], 'toto') 200 const token = await generateUserAccessToken(servers[0], 'toto')
201 201
202 const res = await getAccountPlaylistsListWithToken(servers[ 0 ].url, token, 'toto', 0, 5) 202 const res = await getAccountPlaylistsListWithToken(servers[0].url, token, 'toto', 0, 5)
203 203
204 expect(res.body.total).to.equal(1) 204 expect(res.body.total).to.equal(1)
205 expect(res.body.data).to.have.lengthOf(1) 205 expect(res.body.data).to.have.lengthOf(1)
206 206
207 const playlistId = res.body.data[ 0 ].id 207 const playlistId = res.body.data[0].id
208 await getPlaylistVideos(servers[ 0 ].url, token, playlistId, 0, 5) 208 await getPlaylistVideos(servers[0].url, token, playlistId, 0, 5)
209 }) 209 })
210 }) 210 })
211 211
@@ -215,14 +215,14 @@ describe('Test video playlists', function () {
215 this.timeout(30000) 215 this.timeout(30000)
216 216
217 await createVideoPlaylist({ 217 await createVideoPlaylist({
218 url: servers[ 0 ].url, 218 url: servers[0].url,
219 token: servers[ 0 ].accessToken, 219 token: servers[0].accessToken,
220 playlistAttrs: { 220 playlistAttrs: {
221 displayName: 'my super playlist', 221 displayName: 'my super playlist',
222 privacy: VideoPlaylistPrivacy.PUBLIC, 222 privacy: VideoPlaylistPrivacy.PUBLIC,
223 description: 'my super description', 223 description: 'my super description',
224 thumbnailfile: 'thumbnail.jpg', 224 thumbnailfile: 'thumbnail.jpg',
225 videoChannelId: servers[ 0 ].videoChannel.id 225 videoChannelId: servers[0].videoChannel.id
226 } 226 }
227 }) 227 })
228 228
@@ -233,7 +233,7 @@ describe('Test video playlists', function () {
233 expect(res.body.total).to.equal(1) 233 expect(res.body.total).to.equal(1)
234 expect(res.body.data).to.have.lengthOf(1) 234 expect(res.body.data).to.have.lengthOf(1)
235 235
236 const playlistFromList = res.body.data[ 0 ] as VideoPlaylist 236 const playlistFromList = res.body.data[0] as VideoPlaylist
237 237
238 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid) 238 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
239 const playlistFromGet = res2.body 239 const playlistFromGet = res2.body
@@ -266,12 +266,12 @@ describe('Test video playlists', function () {
266 266
267 { 267 {
268 const res = await createVideoPlaylist({ 268 const res = await createVideoPlaylist({
269 url: servers[ 1 ].url, 269 url: servers[1].url,
270 token: servers[ 1 ].accessToken, 270 token: servers[1].accessToken,
271 playlistAttrs: { 271 playlistAttrs: {
272 displayName: 'playlist 2', 272 displayName: 'playlist 2',
273 privacy: VideoPlaylistPrivacy.PUBLIC, 273 privacy: VideoPlaylistPrivacy.PUBLIC,
274 videoChannelId: servers[ 1 ].videoChannel.id 274 videoChannelId: servers[1].videoChannel.id
275 } 275 }
276 }) 276 })
277 playlistServer2Id1 = res.body.videoPlaylist.id 277 playlistServer2Id1 = res.body.videoPlaylist.id
@@ -279,13 +279,13 @@ describe('Test video playlists', function () {
279 279
280 { 280 {
281 const res = await createVideoPlaylist({ 281 const res = await createVideoPlaylist({
282 url: servers[ 1 ].url, 282 url: servers[1].url,
283 token: servers[ 1 ].accessToken, 283 token: servers[1].accessToken,
284 playlistAttrs: { 284 playlistAttrs: {
285 displayName: 'playlist 3', 285 displayName: 'playlist 3',
286 privacy: VideoPlaylistPrivacy.PUBLIC, 286 privacy: VideoPlaylistPrivacy.PUBLIC,
287 thumbnailfile: 'thumbnail.jpg', 287 thumbnailfile: 'thumbnail.jpg',
288 videoChannelId: servers[ 1 ].videoChannel.id 288 videoChannelId: servers[1].videoChannel.id
289 } 289 }
290 }) 290 })
291 291
@@ -293,24 +293,24 @@ describe('Test video playlists', function () {
293 playlistServer2UUID2 = res.body.videoPlaylist.uuid 293 playlistServer2UUID2 = res.body.videoPlaylist.uuid
294 } 294 }
295 295
296 for (let id of [ playlistServer2Id1, playlistServer2Id2 ]) { 296 for (const id of [ playlistServer2Id1, playlistServer2Id2 ]) {
297 await addVideoInPlaylist({ 297 await addVideoInPlaylist({
298 url: servers[ 1 ].url, 298 url: servers[1].url,
299 token: servers[ 1 ].accessToken, 299 token: servers[1].accessToken,
300 playlistId: id, 300 playlistId: id,
301 elementAttrs: { videoId: servers[ 1 ].videos[ 0 ].id, startTimestamp: 1, stopTimestamp: 2 } 301 elementAttrs: { videoId: servers[1].videos[0].id, startTimestamp: 1, stopTimestamp: 2 }
302 }) 302 })
303 await addVideoInPlaylist({ 303 await addVideoInPlaylist({
304 url: servers[ 1 ].url, 304 url: servers[1].url,
305 token: servers[ 1 ].accessToken, 305 token: servers[1].accessToken,
306 playlistId: id, 306 playlistId: id,
307 elementAttrs: { videoId: servers[ 1 ].videos[ 1 ].id } 307 elementAttrs: { videoId: servers[1].videos[1].id }
308 }) 308 })
309 } 309 }
310 310
311 await waitJobs(servers) 311 await waitJobs(servers)
312 312
313 for (const server of [ servers[ 0 ], servers[ 1 ] ]) { 313 for (const server of [ servers[0], servers[1] ]) {
314 const res = await getVideoPlaylistsList(server.url, 0, 5) 314 const res = await getVideoPlaylistsList(server.url, 0, 5)
315 315
316 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') 316 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
@@ -322,7 +322,7 @@ describe('Test video playlists', function () {
322 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath) 322 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath)
323 } 323 }
324 324
325 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5) 325 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
326 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined 326 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined
327 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined 327 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined
328 }) 328 })
@@ -331,13 +331,13 @@ describe('Test video playlists', function () {
331 this.timeout(30000) 331 this.timeout(30000)
332 332
333 // Server 2 and server 3 follow each other 333 // Server 2 and server 3 follow each other
334 await doubleFollow(servers[ 1 ], servers[ 2 ]) 334 await doubleFollow(servers[1], servers[2])
335 335
336 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5) 336 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
337 337
338 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') 338 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
339 expect(playlist2).to.not.be.undefined 339 expect(playlist2).to.not.be.undefined
340 await testImage(servers[ 2 ].url, 'thumbnail-playlist', playlist2.thumbnailPath) 340 await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath)
341 341
342 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined 342 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined
343 }) 343 })
@@ -349,25 +349,25 @@ describe('Test video playlists', function () {
349 this.timeout(30000) 349 this.timeout(30000)
350 350
351 { 351 {
352 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, 'createdAt') 352 const res = await getVideoPlaylistsList(servers[2].url, 1, 2, 'createdAt')
353 353
354 expect(res.body.total).to.equal(3) 354 expect(res.body.total).to.equal(3)
355 355
356 const data: VideoPlaylist[] = res.body.data 356 const data: VideoPlaylist[] = res.body.data
357 expect(data).to.have.lengthOf(2) 357 expect(data).to.have.lengthOf(2)
358 expect(data[ 0 ].displayName).to.equal('playlist 2') 358 expect(data[0].displayName).to.equal('playlist 2')
359 expect(data[ 1 ].displayName).to.equal('playlist 3') 359 expect(data[1].displayName).to.equal('playlist 3')
360 } 360 }
361 361
362 { 362 {
363 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, '-createdAt') 363 const res = await getVideoPlaylistsList(servers[2].url, 1, 2, '-createdAt')
364 364
365 expect(res.body.total).to.equal(3) 365 expect(res.body.total).to.equal(3)
366 366
367 const data: VideoPlaylist[] = res.body.data 367 const data: VideoPlaylist[] = res.body.data
368 expect(data).to.have.lengthOf(2) 368 expect(data).to.have.lengthOf(2)
369 expect(data[ 0 ].displayName).to.equal('playlist 2') 369 expect(data[0].displayName).to.equal('playlist 2')
370 expect(data[ 1 ].displayName).to.equal('my super playlist') 370 expect(data[1].displayName).to.equal('my super playlist')
371 } 371 }
372 }) 372 })
373 373
@@ -375,13 +375,13 @@ describe('Test video playlists', function () {
375 this.timeout(30000) 375 this.timeout(30000)
376 376
377 { 377 {
378 const res = await getVideoChannelPlaylistsList(servers[ 0 ].url, 'root_channel', 0, 2, '-createdAt') 378 const res = await getVideoChannelPlaylistsList(servers[0].url, 'root_channel', 0, 2, '-createdAt')
379 379
380 expect(res.body.total).to.equal(1) 380 expect(res.body.total).to.equal(1)
381 381
382 const data: VideoPlaylist[] = res.body.data 382 const data: VideoPlaylist[] = res.body.data
383 expect(data).to.have.lengthOf(1) 383 expect(data).to.have.lengthOf(1)
384 expect(data[ 0 ].displayName).to.equal('my super playlist') 384 expect(data[0].displayName).to.equal('my super playlist')
385 } 385 }
386 }) 386 })
387 387
@@ -389,37 +389,37 @@ describe('Test video playlists', function () {
389 this.timeout(30000) 389 this.timeout(30000)
390 390
391 { 391 {
392 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, '-createdAt') 392 const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, '-createdAt')
393 393
394 expect(res.body.total).to.equal(2) 394 expect(res.body.total).to.equal(2)
395 395
396 const data: VideoPlaylist[] = res.body.data 396 const data: VideoPlaylist[] = res.body.data
397 expect(data).to.have.lengthOf(1) 397 expect(data).to.have.lengthOf(1)
398 expect(data[ 0 ].displayName).to.equal('playlist 2') 398 expect(data[0].displayName).to.equal('playlist 2')
399 } 399 }
400 400
401 { 401 {
402 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, 'createdAt') 402 const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, 'createdAt')
403 403
404 expect(res.body.total).to.equal(2) 404 expect(res.body.total).to.equal(2)
405 405
406 const data: VideoPlaylist[] = res.body.data 406 const data: VideoPlaylist[] = res.body.data
407 expect(data).to.have.lengthOf(1) 407 expect(data).to.have.lengthOf(1)
408 expect(data[ 0 ].displayName).to.equal('playlist 3') 408 expect(data[0].displayName).to.equal('playlist 3')
409 } 409 }
410 410
411 { 411 {
412 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 0, 10, 'createdAt', '3') 412 const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '3')
413 413
414 expect(res.body.total).to.equal(1) 414 expect(res.body.total).to.equal(1)
415 415
416 const data: VideoPlaylist[] = res.body.data 416 const data: VideoPlaylist[] = res.body.data
417 expect(data).to.have.lengthOf(1) 417 expect(data).to.have.lengthOf(1)
418 expect(data[ 0 ].displayName).to.equal('playlist 3') 418 expect(data[0].displayName).to.equal('playlist 3')
419 } 419 }
420 420
421 { 421 {
422 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 0, 10, 'createdAt', '4') 422 const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '4')
423 423
424 expect(res.body.total).to.equal(0) 424 expect(res.body.total).to.equal(0)
425 425
@@ -432,8 +432,8 @@ describe('Test video playlists', function () {
432 this.timeout(30000) 432 this.timeout(30000)
433 433
434 await createVideoPlaylist({ 434 await createVideoPlaylist({
435 url: servers[ 1 ].url, 435 url: servers[1].url,
436 token: servers[ 1 ].accessToken, 436 token: servers[1].accessToken,
437 playlistAttrs: { 437 playlistAttrs: {
438 displayName: 'playlist unlisted', 438 displayName: 'playlist unlisted',
439 privacy: VideoPlaylistPrivacy.UNLISTED 439 privacy: VideoPlaylistPrivacy.UNLISTED
@@ -441,8 +441,8 @@ describe('Test video playlists', function () {
441 }) 441 })
442 442
443 await createVideoPlaylist({ 443 await createVideoPlaylist({
444 url: servers[ 1 ].url, 444 url: servers[1].url,
445 token: servers[ 1 ].accessToken, 445 token: servers[1].accessToken,
446 playlistAttrs: { 446 playlistAttrs: {
447 displayName: 'playlist private', 447 displayName: 'playlist private',
448 privacy: VideoPlaylistPrivacy.PRIVATE 448 privacy: VideoPlaylistPrivacy.PRIVATE
@@ -453,18 +453,18 @@ describe('Test video playlists', function () {
453 453
454 for (const server of servers) { 454 for (const server of servers) {
455 const results = [ 455 const results = [
456 await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[ 1 ].port, 0, 5, '-createdAt'), 456 await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[1].port, 0, 5, '-createdAt'),
457 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt') 457 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt')
458 ] 458 ]
459 459
460 expect(results[ 0 ].body.total).to.equal(2) 460 expect(results[0].body.total).to.equal(2)
461 expect(results[ 1 ].body.total).to.equal(3) 461 expect(results[1].body.total).to.equal(3)
462 462
463 for (const res of results) { 463 for (const res of results) {
464 const data: VideoPlaylist[] = res.body.data 464 const data: VideoPlaylist[] = res.body.data
465 expect(data).to.have.lengthOf(2) 465 expect(data).to.have.lengthOf(2)
466 expect(data[ 0 ].displayName).to.equal('playlist 3') 466 expect(data[0].displayName).to.equal('playlist 3')
467 expect(data[ 1 ].displayName).to.equal('playlist 2') 467 expect(data[1].displayName).to.equal('playlist 2')
468 } 468 }
469 } 469 }
470 }) 470 })
@@ -519,32 +519,32 @@ describe('Test video playlists', function () {
519 this.timeout(30000) 519 this.timeout(30000)
520 520
521 const addVideo = (elementAttrs: any) => { 521 const addVideo = (elementAttrs: any) => {
522 return addVideoInPlaylist({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, playlistId: playlistServer1Id, elementAttrs }) 522 return addVideoInPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: playlistServer1Id, elementAttrs })
523 } 523 }
524 524
525 const res = await createVideoPlaylist({ 525 const res = await createVideoPlaylist({
526 url: servers[ 0 ].url, 526 url: servers[0].url,
527 token: servers[ 0 ].accessToken, 527 token: servers[0].accessToken,
528 playlistAttrs: { 528 playlistAttrs: {
529 displayName: 'playlist 4', 529 displayName: 'playlist 4',
530 privacy: VideoPlaylistPrivacy.PUBLIC, 530 privacy: VideoPlaylistPrivacy.PUBLIC,
531 videoChannelId: servers[ 0 ].videoChannel.id 531 videoChannelId: servers[0].videoChannel.id
532 } 532 }
533 }) 533 })
534 534
535 playlistServer1Id = res.body.videoPlaylist.id 535 playlistServer1Id = res.body.videoPlaylist.id
536 playlistServer1UUID = res.body.videoPlaylist.uuid 536 playlistServer1UUID = res.body.videoPlaylist.uuid
537 537
538 await addVideo({ videoId: servers[ 0 ].videos[ 0 ].uuid, startTimestamp: 15, stopTimestamp: 28 }) 538 await addVideo({ videoId: servers[0].videos[0].uuid, startTimestamp: 15, stopTimestamp: 28 })
539 await addVideo({ videoId: servers[ 2 ].videos[ 1 ].uuid, startTimestamp: 35 }) 539 await addVideo({ videoId: servers[2].videos[1].uuid, startTimestamp: 35 })
540 await addVideo({ videoId: servers[ 2 ].videos[ 2 ].uuid }) 540 await addVideo({ videoId: servers[2].videos[2].uuid })
541 { 541 {
542 const res = await addVideo({ videoId: servers[ 0 ].videos[ 3 ].uuid, stopTimestamp: 35 }) 542 const res = await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 })
543 playlistElementServer1Video4 = res.body.videoPlaylistElement.id 543 playlistElementServer1Video4 = res.body.videoPlaylistElement.id
544 } 544 }
545 545
546 { 546 {
547 const res = await addVideo({ videoId: servers[ 0 ].videos[ 4 ].uuid, startTimestamp: 45, stopTimestamp: 60 }) 547 const res = await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 })
548 playlistElementServer1Video5 = res.body.videoPlaylistElement.id 548 playlistElementServer1Video5 = res.body.videoPlaylistElement.id
549 } 549 }
550 550
@@ -567,35 +567,35 @@ describe('Test video playlists', function () {
567 const videoElements: VideoPlaylistElement[] = res.body.data 567 const videoElements: VideoPlaylistElement[] = res.body.data
568 expect(videoElements).to.have.lengthOf(6) 568 expect(videoElements).to.have.lengthOf(6)
569 569
570 expect(videoElements[ 0 ].video.name).to.equal('video 0 server 1') 570 expect(videoElements[0].video.name).to.equal('video 0 server 1')
571 expect(videoElements[ 0 ].position).to.equal(1) 571 expect(videoElements[0].position).to.equal(1)
572 expect(videoElements[ 0 ].startTimestamp).to.equal(15) 572 expect(videoElements[0].startTimestamp).to.equal(15)
573 expect(videoElements[ 0 ].stopTimestamp).to.equal(28) 573 expect(videoElements[0].stopTimestamp).to.equal(28)
574 574
575 expect(videoElements[ 1 ].video.name).to.equal('video 1 server 3') 575 expect(videoElements[1].video.name).to.equal('video 1 server 3')
576 expect(videoElements[ 1 ].position).to.equal(2) 576 expect(videoElements[1].position).to.equal(2)
577 expect(videoElements[ 1 ].startTimestamp).to.equal(35) 577 expect(videoElements[1].startTimestamp).to.equal(35)
578 expect(videoElements[ 1 ].stopTimestamp).to.be.null 578 expect(videoElements[1].stopTimestamp).to.be.null
579 579
580 expect(videoElements[ 2 ].video.name).to.equal('video 2 server 3') 580 expect(videoElements[2].video.name).to.equal('video 2 server 3')
581 expect(videoElements[ 2 ].position).to.equal(3) 581 expect(videoElements[2].position).to.equal(3)
582 expect(videoElements[ 2 ].startTimestamp).to.be.null 582 expect(videoElements[2].startTimestamp).to.be.null
583 expect(videoElements[ 2 ].stopTimestamp).to.be.null 583 expect(videoElements[2].stopTimestamp).to.be.null
584 584
585 expect(videoElements[ 3 ].video.name).to.equal('video 3 server 1') 585 expect(videoElements[3].video.name).to.equal('video 3 server 1')
586 expect(videoElements[ 3 ].position).to.equal(4) 586 expect(videoElements[3].position).to.equal(4)
587 expect(videoElements[ 3 ].startTimestamp).to.be.null 587 expect(videoElements[3].startTimestamp).to.be.null
588 expect(videoElements[ 3 ].stopTimestamp).to.equal(35) 588 expect(videoElements[3].stopTimestamp).to.equal(35)
589 589
590 expect(videoElements[ 4 ].video.name).to.equal('video 4 server 1') 590 expect(videoElements[4].video.name).to.equal('video 4 server 1')
591 expect(videoElements[ 4 ].position).to.equal(5) 591 expect(videoElements[4].position).to.equal(5)
592 expect(videoElements[ 4 ].startTimestamp).to.equal(45) 592 expect(videoElements[4].startTimestamp).to.equal(45)
593 expect(videoElements[ 4 ].stopTimestamp).to.equal(60) 593 expect(videoElements[4].stopTimestamp).to.equal(60)
594 594
595 expect(videoElements[ 5 ].video.name).to.equal('NSFW video') 595 expect(videoElements[5].video.name).to.equal('NSFW video')
596 expect(videoElements[ 5 ].position).to.equal(6) 596 expect(videoElements[5].position).to.equal(6)
597 expect(videoElements[ 5 ].startTimestamp).to.equal(5) 597 expect(videoElements[5].startTimestamp).to.equal(5)
598 expect(videoElements[ 5 ].stopTimestamp).to.be.null 598 expect(videoElements[5].stopTimestamp).to.be.null
599 599
600 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2) 600 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2)
601 expect(res3.body.data).to.have.lengthOf(2) 601 expect(res3.body.data).to.have.lengthOf(2)
@@ -616,18 +616,18 @@ describe('Test video playlists', function () {
616 before(async function () { 616 before(async function () {
617 this.timeout(30000) 617 this.timeout(30000)
618 618
619 groupUser1 = [ Object.assign({}, servers[ 0 ], { accessToken: userAccessTokenServer1 }) ] 619 groupUser1 = [ Object.assign({}, servers[0], { accessToken: userAccessTokenServer1 }) ]
620 groupWithoutToken1 = [ Object.assign({}, servers[ 0 ], { accessToken: undefined }) ] 620 groupWithoutToken1 = [ Object.assign({}, servers[0], { accessToken: undefined }) ]
621 group1 = [ servers[ 0 ] ] 621 group1 = [ servers[0] ]
622 group2 = [ servers[ 1 ], servers[ 2 ] ] 622 group2 = [ servers[1], servers[2] ]
623 623
624 const res = await createVideoPlaylist({ 624 const res = await createVideoPlaylist({
625 url: servers[ 0 ].url, 625 url: servers[0].url,
626 token: userAccessTokenServer1, 626 token: userAccessTokenServer1,
627 playlistAttrs: { 627 playlistAttrs: {
628 displayName: 'playlist 56', 628 displayName: 'playlist 56',
629 privacy: VideoPlaylistPrivacy.PUBLIC, 629 privacy: VideoPlaylistPrivacy.PUBLIC,
630 videoChannelId: servers[ 0 ].videoChannel.id 630 videoChannelId: servers[0].videoChannel.id
631 } 631 }
632 }) 632 })
633 633
@@ -635,7 +635,7 @@ describe('Test video playlists', function () {
635 playlistServer1UUID2 = res.body.videoPlaylist.uuid 635 playlistServer1UUID2 = res.body.videoPlaylist.uuid
636 636
637 const addVideo = (elementAttrs: any) => { 637 const addVideo = (elementAttrs: any) => {
638 return addVideoInPlaylist({ url: servers[ 0 ].url, token: userAccessTokenServer1, playlistId: playlistServer1Id2, elementAttrs }) 638 return addVideoInPlaylist({ url: servers[0].url, token: userAccessTokenServer1, playlistId: playlistServer1Id2, elementAttrs })
639 } 639 }
640 640
641 video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userAccessTokenServer1 })).uuid 641 video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userAccessTokenServer1 })).uuid
@@ -656,7 +656,7 @@ describe('Test video playlists', function () {
656 const position = 1 656 const position = 1
657 657
658 { 658 {
659 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video1, { privacy: VideoPrivacy.PRIVATE }) 659 await updateVideo(servers[0].url, servers[0].accessToken, video1, { privacy: VideoPrivacy.PRIVATE })
660 await waitJobs(servers) 660 await waitJobs(servers)
661 661
662 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 662 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
@@ -666,7 +666,7 @@ describe('Test video playlists', function () {
666 } 666 }
667 667
668 { 668 {
669 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video1, { privacy: VideoPrivacy.PUBLIC }) 669 await updateVideo(servers[0].url, servers[0].accessToken, video1, { privacy: VideoPrivacy.PUBLIC })
670 await waitJobs(servers) 670 await waitJobs(servers)
671 671
672 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 672 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
@@ -684,7 +684,7 @@ describe('Test video playlists', function () {
684 const position = 1 684 const position = 1
685 685
686 { 686 {
687 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video1, 'reason', true) 687 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, video1, 'reason', true)
688 await waitJobs(servers) 688 await waitJobs(servers)
689 689
690 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 690 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
@@ -694,7 +694,7 @@ describe('Test video playlists', function () {
694 } 694 }
695 695
696 { 696 {
697 await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video1) 697 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, video1)
698 await waitJobs(servers) 698 await waitJobs(servers)
699 699
700 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 700 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
@@ -712,52 +712,52 @@ describe('Test video playlists', function () {
712 const position = 2 712 const position = 2
713 713
714 { 714 {
715 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port) 715 await addAccountToAccountBlocklist(servers[0].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port)
716 await waitJobs(servers) 716 await waitJobs(servers)
717 717
718 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) 718 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
719 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 719 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
720 720
721 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port) 721 await removeAccountFromAccountBlocklist(servers[0].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port)
722 await waitJobs(servers) 722 await waitJobs(servers)
723 723
724 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 724 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
725 } 725 }
726 726
727 { 727 {
728 await addServerToAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'localhost:' + servers[1].port) 728 await addServerToAccountBlocklist(servers[0].url, userAccessTokenServer1, 'localhost:' + servers[1].port)
729 await waitJobs(servers) 729 await waitJobs(servers)
730 730
731 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) 731 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
732 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 732 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
733 733
734 await removeServerFromAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'localhost:' + servers[1].port) 734 await removeServerFromAccountBlocklist(servers[0].url, userAccessTokenServer1, 'localhost:' + servers[1].port)
735 await waitJobs(servers) 735 await waitJobs(servers)
736 736
737 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 737 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
738 } 738 }
739 739
740 { 740 {
741 await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'root@localhost:' + servers[1].port) 741 await addAccountToServerBlocklist(servers[0].url, servers[0].accessToken, 'root@localhost:' + servers[1].port)
742 await waitJobs(servers) 742 await waitJobs(servers)
743 743
744 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) 744 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
745 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 745 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
746 746
747 await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'root@localhost:' + servers[1].port) 747 await removeAccountFromServerBlocklist(servers[0].url, servers[0].accessToken, 'root@localhost:' + servers[1].port)
748 await waitJobs(servers) 748 await waitJobs(servers)
749 749
750 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 750 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
751 } 751 }
752 752
753 { 753 {
754 await addServerToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 754 await addServerToServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
755 await waitJobs(servers) 755 await waitJobs(servers)
756 756
757 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) 757 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
758 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 758 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
759 759
760 await removeServerFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port) 760 await removeServerFromServerBlocklist(servers[0].url, servers[0].accessToken, 'localhost:' + servers[1].port)
761 await waitJobs(servers) 761 await waitJobs(servers)
762 762
763 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) 763 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
@@ -785,8 +785,8 @@ describe('Test video playlists', function () {
785 785
786 { 786 {
787 await reorderVideosPlaylist({ 787 await reorderVideosPlaylist({
788 url: servers[ 0 ].url, 788 url: servers[0].url,
789 token: servers[ 0 ].accessToken, 789 token: servers[0].accessToken,
790 playlistId: playlistServer1Id, 790 playlistId: playlistServer1Id,
791 elementAttrs: { 791 elementAttrs: {
792 startPosition: 2, 792 startPosition: 2,
@@ -813,8 +813,8 @@ describe('Test video playlists', function () {
813 813
814 { 814 {
815 await reorderVideosPlaylist({ 815 await reorderVideosPlaylist({
816 url: servers[ 0 ].url, 816 url: servers[0].url,
817 token: servers[ 0 ].accessToken, 817 token: servers[0].accessToken,
818 playlistId: playlistServer1Id, 818 playlistId: playlistServer1Id,
819 elementAttrs: { 819 elementAttrs: {
820 startPosition: 1, 820 startPosition: 1,
@@ -842,8 +842,8 @@ describe('Test video playlists', function () {
842 842
843 { 843 {
844 await reorderVideosPlaylist({ 844 await reorderVideosPlaylist({
845 url: servers[ 0 ].url, 845 url: servers[0].url,
846 token: servers[ 0 ].accessToken, 846 token: servers[0].accessToken,
847 playlistId: playlistServer1Id, 847 playlistId: playlistServer1Id,
848 elementAttrs: { 848 elementAttrs: {
849 startPosition: 6, 849 startPosition: 6,
@@ -868,7 +868,7 @@ describe('Test video playlists', function () {
868 ]) 868 ])
869 869
870 for (let i = 1; i <= elements.length; i++) { 870 for (let i = 1; i <= elements.length; i++) {
871 expect(elements[ i - 1 ].position).to.equal(i) 871 expect(elements[i - 1].position).to.equal(i)
872 } 872 }
873 } 873 }
874 } 874 }
@@ -878,8 +878,8 @@ describe('Test video playlists', function () {
878 this.timeout(30000) 878 this.timeout(30000)
879 879
880 await updateVideoPlaylistElement({ 880 await updateVideoPlaylistElement({
881 url: servers[ 0 ].url, 881 url: servers[0].url,
882 token: servers[ 0 ].accessToken, 882 token: servers[0].accessToken,
883 playlistId: playlistServer1Id, 883 playlistId: playlistServer1Id,
884 playlistElementId: playlistElementServer1Video4, 884 playlistElementId: playlistElementServer1Video4,
885 elementAttrs: { 885 elementAttrs: {
@@ -888,8 +888,8 @@ describe('Test video playlists', function () {
888 }) 888 })
889 889
890 await updateVideoPlaylistElement({ 890 await updateVideoPlaylistElement({
891 url: servers[ 0 ].url, 891 url: servers[0].url,
892 token: servers[ 0 ].accessToken, 892 token: servers[0].accessToken,
893 playlistId: playlistServer1Id, 893 playlistId: playlistServer1Id,
894 playlistElementId: playlistElementServer1Video5, 894 playlistElementId: playlistElementServer1Video5,
895 elementAttrs: { 895 elementAttrs: {
@@ -903,62 +903,62 @@ describe('Test video playlists', function () {
903 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 903 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
904 const elements: VideoPlaylistElement[] = res.body.data 904 const elements: VideoPlaylistElement[] = res.body.data
905 905
906 expect(elements[ 0 ].video.name).to.equal('video 3 server 1') 906 expect(elements[0].video.name).to.equal('video 3 server 1')
907 expect(elements[ 0 ].position).to.equal(1) 907 expect(elements[0].position).to.equal(1)
908 expect(elements[ 0 ].startTimestamp).to.equal(1) 908 expect(elements[0].startTimestamp).to.equal(1)
909 expect(elements[ 0 ].stopTimestamp).to.equal(35) 909 expect(elements[0].stopTimestamp).to.equal(35)
910 910
911 expect(elements[ 5 ].video.name).to.equal('video 4 server 1') 911 expect(elements[5].video.name).to.equal('video 4 server 1')
912 expect(elements[ 5 ].position).to.equal(6) 912 expect(elements[5].position).to.equal(6)
913 expect(elements[ 5 ].startTimestamp).to.equal(45) 913 expect(elements[5].startTimestamp).to.equal(45)
914 expect(elements[ 5 ].stopTimestamp).to.be.null 914 expect(elements[5].stopTimestamp).to.be.null
915 } 915 }
916 }) 916 })
917 917
918 it('Should check videos existence in my playlist', async function () { 918 it('Should check videos existence in my playlist', async function () {
919 const videoIds = [ 919 const videoIds = [
920 servers[ 0 ].videos[ 0 ].id, 920 servers[0].videos[0].id,
921 42000, 921 42000,
922 servers[ 0 ].videos[ 3 ].id, 922 servers[0].videos[3].id,
923 43000, 923 43000,
924 servers[ 0 ].videos[ 4 ].id 924 servers[0].videos[4].id
925 ] 925 ]
926 const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds) 926 const res = await doVideosExistInMyPlaylist(servers[0].url, servers[0].accessToken, videoIds)
927 const obj = res.body as VideoExistInPlaylist 927 const obj = res.body as VideoExistInPlaylist
928 928
929 { 929 {
930 const elem = obj[ servers[ 0 ].videos[ 0 ].id ] 930 const elem = obj[servers[0].videos[0].id]
931 expect(elem).to.have.lengthOf(1) 931 expect(elem).to.have.lengthOf(1)
932 expect(elem[ 0 ].playlistElementId).to.exist 932 expect(elem[0].playlistElementId).to.exist
933 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 933 expect(elem[0].playlistId).to.equal(playlistServer1Id)
934 expect(elem[ 0 ].startTimestamp).to.equal(15) 934 expect(elem[0].startTimestamp).to.equal(15)
935 expect(elem[ 0 ].stopTimestamp).to.equal(28) 935 expect(elem[0].stopTimestamp).to.equal(28)
936 } 936 }
937 937
938 { 938 {
939 const elem = obj[ servers[ 0 ].videos[ 3 ].id ] 939 const elem = obj[servers[0].videos[3].id]
940 expect(elem).to.have.lengthOf(1) 940 expect(elem).to.have.lengthOf(1)
941 expect(elem[ 0 ].playlistElementId).to.equal(playlistElementServer1Video4) 941 expect(elem[0].playlistElementId).to.equal(playlistElementServer1Video4)
942 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 942 expect(elem[0].playlistId).to.equal(playlistServer1Id)
943 expect(elem[ 0 ].startTimestamp).to.equal(1) 943 expect(elem[0].startTimestamp).to.equal(1)
944 expect(elem[ 0 ].stopTimestamp).to.equal(35) 944 expect(elem[0].stopTimestamp).to.equal(35)
945 } 945 }
946 946
947 { 947 {
948 const elem = obj[ servers[ 0 ].videos[ 4 ].id ] 948 const elem = obj[servers[0].videos[4].id]
949 expect(elem).to.have.lengthOf(1) 949 expect(elem).to.have.lengthOf(1)
950 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 950 expect(elem[0].playlistId).to.equal(playlistServer1Id)
951 expect(elem[ 0 ].startTimestamp).to.equal(45) 951 expect(elem[0].startTimestamp).to.equal(45)
952 expect(elem[ 0 ].stopTimestamp).to.equal(null) 952 expect(elem[0].stopTimestamp).to.equal(null)
953 } 953 }
954 954
955 expect(obj[ 42000 ]).to.have.lengthOf(0) 955 expect(obj[42000]).to.have.lengthOf(0)
956 expect(obj[ 43000 ]).to.have.lengthOf(0) 956 expect(obj[43000]).to.have.lengthOf(0)
957 }) 957 })
958 958
959 it('Should automatically update updatedAt field of playlists', async function () { 959 it('Should automatically update updatedAt field of playlists', async function () {
960 const server = servers[ 1 ] 960 const server = servers[1]
961 const videoId = servers[ 1 ].videos[ 5 ].id 961 const videoId = servers[1].videos[5].id
962 962
963 async function getPlaylistNames () { 963 async function getPlaylistNames () {
964 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt') 964 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt')
@@ -974,8 +974,8 @@ describe('Test video playlists', function () {
974 const element2 = res2.body.videoPlaylistElement.id 974 const element2 = res2.body.videoPlaylistElement.id
975 975
976 const names1 = await getPlaylistNames() 976 const names1 = await getPlaylistNames()
977 expect(names1[ 0 ]).to.equal('playlist 3 updated') 977 expect(names1[0]).to.equal('playlist 3 updated')
978 expect(names1[ 1 ]).to.equal('playlist 2') 978 expect(names1[1]).to.equal('playlist 2')
979 979
980 await removeVideoFromPlaylist({ 980 await removeVideoFromPlaylist({
981 url: server.url, 981 url: server.url,
@@ -985,8 +985,8 @@ describe('Test video playlists', function () {
985 }) 985 })
986 986
987 const names2 = await getPlaylistNames() 987 const names2 = await getPlaylistNames()
988 expect(names2[ 0 ]).to.equal('playlist 2') 988 expect(names2[0]).to.equal('playlist 2')
989 expect(names2[ 1 ]).to.equal('playlist 3 updated') 989 expect(names2[1]).to.equal('playlist 3 updated')
990 990
991 await removeVideoFromPlaylist({ 991 await removeVideoFromPlaylist({
992 url: server.url, 992 url: server.url,
@@ -996,23 +996,23 @@ describe('Test video playlists', function () {
996 }) 996 })
997 997
998 const names3 = await getPlaylistNames() 998 const names3 = await getPlaylistNames()
999 expect(names3[ 0 ]).to.equal('playlist 3 updated') 999 expect(names3[0]).to.equal('playlist 3 updated')
1000 expect(names3[ 1 ]).to.equal('playlist 2') 1000 expect(names3[1]).to.equal('playlist 2')
1001 }) 1001 })
1002 1002
1003 it('Should delete some elements', async function () { 1003 it('Should delete some elements', async function () {
1004 this.timeout(30000) 1004 this.timeout(30000)
1005 1005
1006 await removeVideoFromPlaylist({ 1006 await removeVideoFromPlaylist({
1007 url: servers[ 0 ].url, 1007 url: servers[0].url,
1008 token: servers[ 0 ].accessToken, 1008 token: servers[0].accessToken,
1009 playlistId: playlistServer1Id, 1009 playlistId: playlistServer1Id,
1010 playlistElementId: playlistElementServer1Video4 1010 playlistElementId: playlistElementServer1Video4
1011 }) 1011 })
1012 1012
1013 await removeVideoFromPlaylist({ 1013 await removeVideoFromPlaylist({
1014 url: servers[ 0 ].url, 1014 url: servers[0].url,
1015 token: servers[ 0 ].accessToken, 1015 token: servers[0].accessToken,
1016 playlistId: playlistServer1Id, 1016 playlistId: playlistServer1Id,
1017 playlistElementId: playlistElementNSFW 1017 playlistElementId: playlistElementNSFW
1018 }) 1018 })
@@ -1027,17 +1027,17 @@ describe('Test video playlists', function () {
1027 const elements: VideoPlaylistElement[] = res.body.data 1027 const elements: VideoPlaylistElement[] = res.body.data
1028 expect(elements).to.have.lengthOf(4) 1028 expect(elements).to.have.lengthOf(4)
1029 1029
1030 expect(elements[ 0 ].video.name).to.equal('video 0 server 1') 1030 expect(elements[0].video.name).to.equal('video 0 server 1')
1031 expect(elements[ 0 ].position).to.equal(1) 1031 expect(elements[0].position).to.equal(1)
1032 1032
1033 expect(elements[ 1 ].video.name).to.equal('video 2 server 3') 1033 expect(elements[1].video.name).to.equal('video 2 server 3')
1034 expect(elements[ 1 ].position).to.equal(2) 1034 expect(elements[1].position).to.equal(2)
1035 1035
1036 expect(elements[ 2 ].video.name).to.equal('video 1 server 3') 1036 expect(elements[2].video.name).to.equal('video 1 server 3')
1037 expect(elements[ 2 ].position).to.equal(3) 1037 expect(elements[2].position).to.equal(3)
1038 1038
1039 expect(elements[ 3 ].video.name).to.equal('video 4 server 1') 1039 expect(elements[3].video.name).to.equal('video 4 server 1')
1040 expect(elements[ 3 ].position).to.equal(4) 1040 expect(elements[3].position).to.equal(4)
1041 } 1041 }
1042 }) 1042 })
1043 1043
@@ -1045,12 +1045,12 @@ describe('Test video playlists', function () {
1045 this.timeout(30000) 1045 this.timeout(30000)
1046 1046
1047 const res = await createVideoPlaylist({ 1047 const res = await createVideoPlaylist({
1048 url: servers[ 0 ].url, 1048 url: servers[0].url,
1049 token: servers[ 0 ].accessToken, 1049 token: servers[0].accessToken,
1050 playlistAttrs: { 1050 playlistAttrs: {
1051 displayName: 'my super public playlist', 1051 displayName: 'my super public playlist',
1052 privacy: VideoPlaylistPrivacy.PUBLIC, 1052 privacy: VideoPlaylistPrivacy.PUBLIC,
1053 videoChannelId: servers[ 0 ].videoChannel.id 1053 videoChannelId: servers[0].videoChannel.id
1054 } 1054 }
1055 }) 1055 })
1056 const videoPlaylistIds = res.body.videoPlaylist 1056 const videoPlaylistIds = res.body.videoPlaylist
@@ -1062,16 +1062,16 @@ describe('Test video playlists', function () {
1062 } 1062 }
1063 1063
1064 const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } 1064 const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE }
1065 await updateVideoPlaylist({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs }) 1065 await updateVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs })
1066 1066
1067 await waitJobs(servers) 1067 await waitJobs(servers)
1068 1068
1069 for (const server of [ servers[ 1 ], servers[ 2 ] ]) { 1069 for (const server of [ servers[1], servers[2] ]) {
1070 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404) 1070 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404)
1071 } 1071 }
1072 await getVideoPlaylist(servers[ 0 ].url, videoPlaylistIds.uuid, 401) 1072 await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, 401)
1073 1073
1074 await getVideoPlaylistWithToken(servers[ 0 ].url, servers[ 0 ].accessToken, videoPlaylistIds.uuid, 200) 1074 await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, 200)
1075 }) 1075 })
1076 }) 1076 })
1077 1077
@@ -1080,7 +1080,7 @@ describe('Test video playlists', function () {
1080 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () { 1080 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () {
1081 this.timeout(30000) 1081 this.timeout(30000)
1082 1082
1083 await deleteVideoPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, playlistServer1Id) 1083 await deleteVideoPlaylist(servers[0].url, servers[0].accessToken, playlistServer1Id)
1084 1084
1085 await waitJobs(servers) 1085 await waitJobs(servers)
1086 1086
@@ -1103,15 +1103,15 @@ describe('Test video playlists', function () {
1103 const finder = data => data.find(p => p.displayName === 'my super playlist') 1103 const finder = data => data.find(p => p.displayName === 'my super playlist')
1104 1104
1105 { 1105 {
1106 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5) 1106 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
1107 expect(res.body.total).to.equal(3) 1107 expect(res.body.total).to.equal(3)
1108 expect(finder(res.body.data)).to.not.be.undefined 1108 expect(finder(res.body.data)).to.not.be.undefined
1109 } 1109 }
1110 1110
1111 await unfollow(servers[ 2 ].url, servers[ 2 ].accessToken, servers[ 0 ]) 1111 await unfollow(servers[2].url, servers[2].accessToken, servers[0])
1112 1112
1113 { 1113 {
1114 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5) 1114 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
1115 expect(res.body.total).to.equal(1) 1115 expect(res.body.total).to.equal(1)
1116 1116
1117 expect(finder(res.body.data)).to.be.undefined 1117 expect(finder(res.body.data)).to.be.undefined
@@ -1121,12 +1121,12 @@ describe('Test video playlists', function () {
1121 it('Should delete a channel and put the associated playlist in private mode', async function () { 1121 it('Should delete a channel and put the associated playlist in private mode', async function () {
1122 this.timeout(30000) 1122 this.timeout(30000)
1123 1123
1124 const res = await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'super_channel', displayName: 'super channel' }) 1124 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' })
1125 const videoChannelId = res.body.videoChannel.id 1125 const videoChannelId = res.body.videoChannel.id
1126 1126
1127 const res2 = await createVideoPlaylist({ 1127 const res2 = await createVideoPlaylist({
1128 url: servers[ 0 ].url, 1128 url: servers[0].url,
1129 token: servers[ 0 ].accessToken, 1129 token: servers[0].accessToken,
1130 playlistAttrs: { 1130 playlistAttrs: {
1131 displayName: 'channel playlist', 1131 displayName: 'channel playlist',
1132 privacy: VideoPlaylistPrivacy.PUBLIC, 1132 privacy: VideoPlaylistPrivacy.PUBLIC,
@@ -1137,15 +1137,15 @@ describe('Test video playlists', function () {
1137 1137
1138 await waitJobs(servers) 1138 await waitJobs(servers)
1139 1139
1140 await deleteVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, 'super_channel') 1140 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'super_channel')
1141 1141
1142 await waitJobs(servers) 1142 await waitJobs(servers)
1143 1143
1144 const res3 = await getVideoPlaylistWithToken(servers[ 0 ].url, servers[ 0 ].accessToken, videoPlaylistUUID) 1144 const res3 = await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistUUID)
1145 expect(res3.body.displayName).to.equal('channel playlist') 1145 expect(res3.body.displayName).to.equal('channel playlist')
1146 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE) 1146 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
1147 1147
1148 await getVideoPlaylist(servers[ 1 ].url, videoPlaylistUUID, 404) 1148 await getVideoPlaylist(servers[1].url, videoPlaylistUUID, 404)
1149 }) 1149 })
1150 1150
1151 it('Should delete an account and delete its playlists', async function () { 1151 it('Should delete an account and delete its playlists', async function () {
@@ -1153,20 +1153,20 @@ describe('Test video playlists', function () {
1153 1153
1154 const user = { username: 'user_1', password: 'password' } 1154 const user = { username: 'user_1', password: 'password' }
1155 const res = await createUser({ 1155 const res = await createUser({
1156 url: servers[ 0 ].url, 1156 url: servers[0].url,
1157 accessToken: servers[ 0 ].accessToken, 1157 accessToken: servers[0].accessToken,
1158 username: user.username, 1158 username: user.username,
1159 password: user.password 1159 password: user.password
1160 }) 1160 })
1161 1161
1162 const userId = res.body.user.id 1162 const userId = res.body.user.id
1163 const userAccessToken = await userLogin(servers[ 0 ], user) 1163 const userAccessToken = await userLogin(servers[0], user)
1164 1164
1165 const resChannel = await getMyUserInformation(servers[ 0 ].url, userAccessToken) 1165 const resChannel = await getMyUserInformation(servers[0].url, userAccessToken)
1166 const userChannel = (resChannel.body as User).videoChannels[ 0 ] 1166 const userChannel = (resChannel.body as User).videoChannels[0]
1167 1167
1168 await createVideoPlaylist({ 1168 await createVideoPlaylist({
1169 url: servers[ 0 ].url, 1169 url: servers[0].url,
1170 token: userAccessToken, 1170 token: userAccessToken,
1171 playlistAttrs: { 1171 playlistAttrs: {
1172 displayName: 'playlist to be deleted', 1172 displayName: 'playlist to be deleted',
@@ -1180,17 +1180,17 @@ describe('Test video playlists', function () {
1180 const finder = data => data.find(p => p.displayName === 'playlist to be deleted') 1180 const finder = data => data.find(p => p.displayName === 'playlist to be deleted')
1181 1181
1182 { 1182 {
1183 for (const server of [ servers[ 0 ], servers[ 1 ] ]) { 1183 for (const server of [ servers[0], servers[1] ]) {
1184 const res = await getVideoPlaylistsList(server.url, 0, 15) 1184 const res = await getVideoPlaylistsList(server.url, 0, 15)
1185 expect(finder(res.body.data)).to.not.be.undefined 1185 expect(finder(res.body.data)).to.not.be.undefined
1186 } 1186 }
1187 } 1187 }
1188 1188
1189 await removeUser(servers[ 0 ].url, userId, servers[ 0 ].accessToken) 1189 await removeUser(servers[0].url, userId, servers[0].accessToken)
1190 await waitJobs(servers) 1190 await waitJobs(servers)
1191 1191
1192 { 1192 {
1193 for (const server of [ servers[ 0 ], servers[ 1 ] ]) { 1193 for (const server of [ servers[0], servers[1] ]) {
1194 const res = await getVideoPlaylistsList(server.url, 0, 15) 1194 const res = await getVideoPlaylistsList(server.url, 0, 15)
1195 expect(finder(res.body.data)).to.be.undefined 1195 expect(finder(res.body.data)).to.be.undefined
1196 } 1196 }
diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts
index e630ca84a..4bbbb90f3 100644
--- a/server/tests/api/videos/video-privacy.ts
+++ b/server/tests/api/videos/video-privacy.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -6,7 +6,8 @@ import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enu
6import { 6import {
7 cleanupTests, 7 cleanupTests,
8 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
9 getVideosList, getVideosListWithToken, 9 getVideosList,
10 getVideosListWithToken,
10 ServerInfo, 11 ServerInfo,
11 setAccessTokensToServers, 12 setAccessTokensToServers,
12 uploadVideo 13 uploadVideo
@@ -110,7 +111,7 @@ describe('Test video privacy', function () {
110 username: 'hello', 111 username: 'hello',
111 password: 'super password' 112 password: 'super password'
112 } 113 }
113 await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) 114 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
114 115
115 anotherUserToken = await userLogin(servers[0], user) 116 anotherUserToken = await userLogin(servers[0], user)
116 await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, 403) 117 await getVideoWithToken(servers[0].url, anotherUserToken, privateVideoUUID, 403)
@@ -174,7 +175,7 @@ describe('Test video privacy', function () {
174 privacy: VideoPrivacy.PUBLIC 175 privacy: VideoPrivacy.PUBLIC
175 } 176 }
176 177
177 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, privateVideoId, attribute) 178 await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute)
178 } 179 }
179 180
180 { 181 {
@@ -182,7 +183,7 @@ describe('Test video privacy', function () {
182 name: 'internal video becomes public', 183 name: 'internal video becomes public',
183 privacy: VideoPrivacy.PUBLIC 184 privacy: VideoPrivacy.PUBLIC
184 } 185 }
185 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, internalVideoId, attribute) 186 await updateVideo(servers[0].url, servers[0].accessToken, internalVideoId, attribute)
186 } 187 }
187 188
188 await waitJobs(servers) 189 await waitJobs(servers)
diff --git a/server/tests/api/videos/video-schedule-update.ts b/server/tests/api/videos/video-schedule-update.ts
index 65a8eafb8..204f43611 100644
--- a/server/tests/api/videos/video-schedule-update.ts
+++ b/server/tests/api/videos/video-schedule-update.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -10,7 +10,6 @@ import {
10 getMyVideos, 10 getMyVideos,
11 getVideosList, 11 getVideosList,
12 getVideoWithToken, 12 getVideoWithToken,
13 killallServers,
14 ServerInfo, 13 ServerInfo,
15 setAccessTokensToServers, 14 setAccessTokensToServers,
16 updateVideo, 15 updateVideo,
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index 4be74901a..13b3530b1 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -1,29 +1,40 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { omit } from 'lodash' 5import { omit } from 'lodash'
6import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos' 6import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos'
7import { audio, canDoQuickTranscode, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' 7import {
8 audio,
9 canDoQuickTranscode,
10 getVideoFileBitrate,
11 getVideoFileFPS,
12 getVideoFileResolution,
13 getMetadataFromFile
14} from '../../../helpers/ffmpeg-utils'
8import { 15import {
9 buildAbsoluteFixturePath, 16 buildAbsoluteFixturePath,
10 cleanupTests, 17 cleanupTests,
11 doubleFollow, 18 doubleFollow,
12 flushAndRunMultipleServers, 19 flushAndRunMultipleServers,
13 generateHighBitrateVideo, 20 generateHighBitrateVideo,
21 generateVideoWithFramerate,
14 getMyVideos, 22 getMyVideos,
15 getVideo, 23 getVideo,
24 getVideoFileMetadataUrl,
16 getVideosList, 25 getVideosList,
17 makeGetRequest, 26 makeGetRequest,
18 root, 27 root,
19 ServerInfo, 28 ServerInfo,
20 setAccessTokensToServers, 29 setAccessTokensToServers,
21 uploadVideo, 30 uploadVideo, uploadVideoAndGetId,
22 waitJobs, 31 waitJobs,
23 webtorrentAdd 32 webtorrentAdd
24} from '../../../../shared/extra-utils' 33} from '../../../../shared/extra-utils'
25import { join } from 'path' 34import { join } from 'path'
26import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' 35import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
36import { FfprobeData } from 'fluent-ffmpeg'
37import { VideoFileMetadata } from '@shared/models/videos/video-file-metadata'
27 38
28const expect = chai.expect 39const expect = chai.expect
29 40
@@ -55,19 +66,19 @@ describe('Test video transcoding', function () {
55 66
56 for (const server of servers) { 67 for (const server of servers) {
57 const res = await getVideosList(server.url) 68 const res = await getVideosList(server.url)
58 const video = res.body.data[ 0 ] 69 const video = res.body.data[0]
59 70
60 const res2 = await getVideo(server.url, video.id) 71 const res2 = await getVideo(server.url, video.id)
61 const videoDetails = res2.body 72 const videoDetails = res2.body
62 expect(videoDetails.files).to.have.lengthOf(1) 73 expect(videoDetails.files).to.have.lengthOf(1)
63 74
64 const magnetUri = videoDetails.files[ 0 ].magnetUri 75 const magnetUri = videoDetails.files[0].magnetUri
65 expect(magnetUri).to.match(/\.webm/) 76 expect(magnetUri).to.match(/\.webm/)
66 77
67 const torrent = await webtorrentAdd(magnetUri, true) 78 const torrent = await webtorrentAdd(magnetUri, true)
68 expect(torrent.files).to.be.an('array') 79 expect(torrent.files).to.be.an('array')
69 expect(torrent.files.length).to.equal(1) 80 expect(torrent.files.length).to.equal(1)
70 expect(torrent.files[ 0 ].path).match(/\.webm$/) 81 expect(torrent.files[0].path).match(/\.webm$/)
71 } 82 }
72 }) 83 })
73 84
@@ -92,13 +103,13 @@ describe('Test video transcoding', function () {
92 103
93 expect(videoDetails.files).to.have.lengthOf(4) 104 expect(videoDetails.files).to.have.lengthOf(4)
94 105
95 const magnetUri = videoDetails.files[ 0 ].magnetUri 106 const magnetUri = videoDetails.files[0].magnetUri
96 expect(magnetUri).to.match(/\.mp4/) 107 expect(magnetUri).to.match(/\.mp4/)
97 108
98 const torrent = await webtorrentAdd(magnetUri, true) 109 const torrent = await webtorrentAdd(magnetUri, true)
99 expect(torrent.files).to.be.an('array') 110 expect(torrent.files).to.be.an('array')
100 expect(torrent.files.length).to.equal(1) 111 expect(torrent.files.length).to.equal(1)
101 expect(torrent.files[ 0 ].path).match(/\.mp4$/) 112 expect(torrent.files[0].path).match(/\.mp4$/)
102 } 113 }
103 }) 114 })
104 115
@@ -126,8 +137,8 @@ describe('Test video transcoding', function () {
126 const probe = await audio.get(path) 137 const probe = await audio.get(path)
127 138
128 if (probe.audioStream) { 139 if (probe.audioStream) {
129 expect(probe.audioStream[ 'codec_name' ]).to.be.equal('aac') 140 expect(probe.audioStream['codec_name']).to.be.equal('aac')
130 expect(probe.audioStream[ 'bit_rate' ]).to.be.at.most(384 * 8000) 141 expect(probe.audioStream['bit_rate']).to.be.at.most(384 * 8000)
131 } else { 142 } else {
132 this.fail('Could not retrieve the audio stream on ' + probe.absolutePath) 143 this.fail('Could not retrieve the audio stream on ' + probe.absolutePath)
133 } 144 }
@@ -211,10 +222,10 @@ describe('Test video transcoding', function () {
211 const videoDetails: VideoDetails = res2.body 222 const videoDetails: VideoDetails = res2.body
212 223
213 expect(videoDetails.files).to.have.lengthOf(4) 224 expect(videoDetails.files).to.have.lengthOf(4)
214 expect(videoDetails.files[ 0 ].fps).to.be.above(58).and.below(62) 225 expect(videoDetails.files[0].fps).to.be.above(58).and.below(62)
215 expect(videoDetails.files[ 1 ].fps).to.be.below(31) 226 expect(videoDetails.files[1].fps).to.be.below(31)
216 expect(videoDetails.files[ 2 ].fps).to.be.below(31) 227 expect(videoDetails.files[2].fps).to.be.below(31)
217 expect(videoDetails.files[ 3 ].fps).to.be.below(31) 228 expect(videoDetails.files[3].fps).to.be.below(31)
218 229
219 for (const resolution of [ '240', '360', '480' ]) { 230 for (const resolution of [ '240', '360', '480' ]) {
220 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-' + resolution + '.mp4') 231 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-' + resolution + '.mp4')
@@ -240,11 +251,11 @@ describe('Test video transcoding', function () {
240 fixture: 'video_short1.webm', 251 fixture: 'video_short1.webm',
241 waitTranscoding: true 252 waitTranscoding: true
242 } 253 }
243 const resVideo = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributes) 254 const resVideo = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
244 const videoId = resVideo.body.video.uuid 255 const videoId = resVideo.body.video.uuid
245 256
246 // Should be in transcode state 257 // Should be in transcode state
247 const { body } = await getVideo(servers[ 1 ].url, videoId) 258 const { body } = await getVideo(servers[1].url, videoId)
248 expect(body.name).to.equal('waiting video') 259 expect(body.name).to.equal('waiting video')
249 expect(body.state.id).to.equal(VideoState.TO_TRANSCODE) 260 expect(body.state.id).to.equal(VideoState.TO_TRANSCODE)
250 expect(body.state.label).to.equal('To transcode') 261 expect(body.state.label).to.equal('To transcode')
@@ -310,7 +321,7 @@ describe('Test video transcoding', function () {
310 321
311 const video = res.body.data.find(v => v.name === videoAttributes.name) 322 const video = res.body.data.find(v => v.name === videoAttributes.name)
312 323
313 for (const resolution of ['240', '360', '480', '720', '1080']) { 324 for (const resolution of [ '240', '360', '480', '720', '1080' ]) {
314 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-' + resolution + '.mp4') 325 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-' + resolution + '.mp4')
315 const bitrate = await getVideoFileBitrate(path) 326 const bitrate = await getVideoFileBitrate(path)
316 const fps = await getVideoFileFPS(path) 327 const fps = await getVideoFileFPS(path)
@@ -340,7 +351,7 @@ describe('Test video transcoding', function () {
340 fixture 351 fixture
341 } 352 }
342 353
343 await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributes) 354 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
344 355
345 await waitJobs(servers) 356 await waitJobs(servers)
346 357
@@ -353,7 +364,7 @@ describe('Test video transcoding', function () {
353 364
354 expect(videoDetails.files).to.have.lengthOf(4) 365 expect(videoDetails.files).to.have.lengthOf(4)
355 366
356 const magnetUri = videoDetails.files[ 0 ].magnetUri 367 const magnetUri = videoDetails.files[0].magnetUri
357 expect(magnetUri).to.contain('.mp4') 368 expect(magnetUri).to.contain('.mp4')
358 } 369 }
359 } 370 }
@@ -370,7 +381,7 @@ describe('Test video transcoding', function () {
370 this.timeout(60000) 381 this.timeout(60000)
371 382
372 const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } 383 const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' }
373 await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributesArg) 384 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg)
374 385
375 await waitJobs(servers) 386 await waitJobs(servers)
376 387
@@ -386,7 +397,7 @@ describe('Test video transcoding', function () {
386 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: 200 }) 397 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: 200 })
387 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: 200 }) 398 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: 200 })
388 399
389 const magnetUri = videoDetails.files[ 0 ].magnetUri 400 const magnetUri = videoDetails.files[0].magnetUri
390 expect(magnetUri).to.contain('.mp4') 401 expect(magnetUri).to.contain('.mp4')
391 } 402 }
392 }) 403 })
@@ -395,7 +406,7 @@ describe('Test video transcoding', function () {
395 this.timeout(60000) 406 this.timeout(60000)
396 407
397 const videoAttributesArg = { name: 'audio_without_preview', fixture: 'sample.ogg' } 408 const videoAttributesArg = { name: 'audio_without_preview', fixture: 'sample.ogg' }
398 await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributesArg) 409 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg)
399 410
400 await waitJobs(servers) 411 await waitJobs(servers)
401 412
@@ -411,11 +422,109 @@ describe('Test video transcoding', function () {
411 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: 200 }) 422 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: 200 })
412 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: 200 }) 423 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: 200 })
413 424
414 const magnetUri = videoDetails.files[ 0 ].magnetUri 425 const magnetUri = videoDetails.files[0].magnetUri
415 expect(magnetUri).to.contain('.mp4') 426 expect(magnetUri).to.contain('.mp4')
416 } 427 }
417 }) 428 })
418 429
430 it('Should downscale to the closest divisor standard framerate', async function () {
431 this.timeout(160000)
432
433 let tempFixturePath: string
434
435 {
436 tempFixturePath = await generateVideoWithFramerate(59)
437
438 const fps = await getVideoFileFPS(tempFixturePath)
439 expect(fps).to.be.equal(59)
440 }
441
442 const videoAttributes = {
443 name: '59fps video',
444 description: '59fps video',
445 fixture: tempFixturePath
446 }
447
448 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
449
450 await waitJobs(servers)
451
452 for (const server of servers) {
453 const res = await getVideosList(server.url)
454
455 const video = res.body.data.find(v => v.name === videoAttributes.name)
456
457 {
458 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-240.mp4')
459 const fps = await getVideoFileFPS(path)
460 expect(fps).to.be.equal(25)
461 }
462
463 {
464 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-720.mp4')
465 const fps = await getVideoFileFPS(path)
466 expect(fps).to.be.equal(59)
467 }
468 }
469 })
470
471 it('Should provide valid ffprobe data', async function () {
472 this.timeout(160000)
473
474 const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'ffprobe data' })).uuid
475 await waitJobs(servers)
476
477 {
478 const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', videoUUID + '-240.mp4')
479 const metadata = await getMetadataFromFile<VideoFileMetadata>(path)
480
481 // expected format properties
482 for (const p of [
483 'tags.encoder',
484 'format_long_name',
485 'size',
486 'bit_rate'
487 ]) {
488 expect(metadata.format).to.have.nested.property(p)
489 }
490
491 // expected stream properties
492 for (const p of [
493 'codec_long_name',
494 'profile',
495 'width',
496 'height',
497 'display_aspect_ratio',
498 'avg_frame_rate',
499 'pix_fmt'
500 ]) {
501 expect(metadata.streams[0]).to.have.nested.property(p)
502 }
503
504 expect(metadata).to.not.have.nested.property('format.filename')
505 }
506
507 for (const server of servers) {
508 const res2 = await getVideo(server.url, videoUUID)
509 const videoDetails: VideoDetails = res2.body
510
511 const videoFiles = videoDetails.files
512 .concat(videoDetails.streamingPlaylists[0].files)
513 expect(videoFiles).to.have.lengthOf(8)
514
515 for (const file of videoFiles) {
516 expect(file.metadata).to.be.undefined
517 expect(file.metadataUrl).to.exist
518 expect(file.metadataUrl).to.contain(servers[1].url)
519 expect(file.metadataUrl).to.contain(videoUUID)
520
521 const res3 = await getVideoFileMetadataUrl(file.metadataUrl)
522 const metadata: FfprobeData = res3.body
523 expect(metadata).to.have.nested.property('format.size')
524 }
525 }
526 })
527
419 after(async function () { 528 after(async function () {
420 await cleanupTests(servers) 529 await cleanupTests(servers)
421 }) 530 })
diff --git a/server/tests/api/videos/videos-filter.ts b/server/tests/api/videos/videos-filter.ts
index e1e65260f..95e12e43c 100644
--- a/server/tests/api/videos/videos-filter.ts
+++ b/server/tests/api/videos/videos-filter.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
@@ -7,8 +7,6 @@ import {
7 createUser, 7 createUser,
8 doubleFollow, 8 doubleFollow,
9 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
10 flushTests,
11 killallServers,
12 makeGetRequest, 10 makeGetRequest,
13 ServerInfo, 11 ServerInfo,
14 setAccessTokensToServers, 12 setAccessTokensToServers,
@@ -98,7 +96,7 @@ describe('Test videos filter validator', function () {
98 const namesResults = await getVideosNames(server, server.accessToken, 'local') 96 const namesResults = await getVideosNames(server, server.accessToken, 'local')
99 for (const names of namesResults) { 97 for (const names of namesResults) {
100 expect(names).to.have.lengthOf(1) 98 expect(names).to.have.lengthOf(1)
101 expect(names[ 0 ]).to.equal('public ' + server.serverNumber) 99 expect(names[0]).to.equal('public ' + server.serverNumber)
102 } 100 }
103 } 101 }
104 }) 102 })
@@ -111,9 +109,9 @@ describe('Test videos filter validator', function () {
111 for (const names of namesResults) { 109 for (const names of namesResults) {
112 expect(names).to.have.lengthOf(3) 110 expect(names).to.have.lengthOf(3)
113 111
114 expect(names[ 0 ]).to.equal('public ' + server.serverNumber) 112 expect(names[0]).to.equal('public ' + server.serverNumber)
115 expect(names[ 1 ]).to.equal('unlisted ' + server.serverNumber) 113 expect(names[1]).to.equal('unlisted ' + server.serverNumber)
116 expect(names[ 2 ]).to.equal('private ' + server.serverNumber) 114 expect(names[2]).to.equal('private ' + server.serverNumber)
117 } 115 }
118 } 116 }
119 } 117 }
diff --git a/server/tests/api/videos/videos-history.ts b/server/tests/api/videos/videos-history.ts
index c7e55c1ab..6f90e9a57 100644
--- a/server/tests/api/videos/videos-history.ts
+++ b/server/tests/api/videos/videos-history.ts
@@ -1,4 +1,4 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
diff --git a/server/tests/api/videos/videos-overview.ts b/server/tests/api/videos/videos-overview.ts
index 975a5c87a..d38bcb6eb 100644
--- a/server/tests/api/videos/videos-overview.ts
+++ b/server/tests/api/videos/videos-overview.ts
@@ -1,8 +1,8 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { cleanupTests, flushAndRunServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../../../shared/extra-utils' 5import { cleanupTests, flushAndRunServer, ServerInfo, setAccessTokensToServers, uploadVideo, wait } from '../../../../shared/extra-utils'
6import { getVideosOverview } from '../../../../shared/extra-utils/overviews/overviews' 6import { getVideosOverview } from '../../../../shared/extra-utils/overviews/overviews'
7import { VideosOverview } from '../../../../shared/models/overviews' 7import { VideosOverview } from '../../../../shared/models/overviews'
8 8
@@ -20,7 +20,7 @@ describe('Test a videos overview', function () {
20 }) 20 })
21 21
22 it('Should send empty overview', async function () { 22 it('Should send empty overview', async function () {
23 const res = await getVideosOverview(server.url) 23 const res = await getVideosOverview(server.url, 1)
24 24
25 const overview: VideosOverview = res.body 25 const overview: VideosOverview = res.body
26 expect(overview.tags).to.have.lengthOf(0) 26 expect(overview.tags).to.have.lengthOf(0)
@@ -31,15 +31,15 @@ describe('Test a videos overview', function () {
31 it('Should upload 5 videos in a specific category, tag and channel but not include them in overview', async function () { 31 it('Should upload 5 videos in a specific category, tag and channel but not include them in overview', async function () {
32 this.timeout(15000) 32 this.timeout(15000)
33 33
34 for (let i = 0; i < 5; i++) { 34 await wait(3000)
35 await uploadVideo(server.url, server.accessToken, { 35
36 name: 'video ' + i, 36 await uploadVideo(server.url, server.accessToken, {
37 category: 3, 37 name: 'video 0',
38 tags: [ 'coucou1', 'coucou2' ] 38 category: 3,
39 }) 39 tags: [ 'coucou1', 'coucou2' ]
40 } 40 })
41 41
42 const res = await getVideosOverview(server.url) 42 const res = await getVideosOverview(server.url, 1)
43 43
44 const overview: VideosOverview = res.body 44 const overview: VideosOverview = res.body
45 expect(overview.tags).to.have.lengthOf(0) 45 expect(overview.tags).to.have.lengthOf(0)
@@ -48,27 +48,55 @@ describe('Test a videos overview', function () {
48 }) 48 })
49 49
50 it('Should upload another video and include all videos in the overview', async function () { 50 it('Should upload another video and include all videos in the overview', async function () {
51 await uploadVideo(server.url, server.accessToken, { 51 this.timeout(15000)
52 name: 'video 5',
53 category: 3,
54 tags: [ 'coucou1', 'coucou2' ]
55 })
56 52
57 const res = await getVideosOverview(server.url) 53 for (let i = 1; i < 6; i++) {
54 await uploadVideo(server.url, server.accessToken, {
55 name: 'video ' + i,
56 category: 3,
57 tags: [ 'coucou1', 'coucou2' ]
58 })
59 }
58 60
59 const overview: VideosOverview = res.body 61 await wait(3000)
60 expect(overview.tags).to.have.lengthOf(2) 62
61 expect(overview.categories).to.have.lengthOf(1) 63 {
62 expect(overview.channels).to.have.lengthOf(1) 64 const res = await getVideosOverview(server.url, 1)
65
66 const overview: VideosOverview = res.body
67 expect(overview.tags).to.have.lengthOf(1)
68 expect(overview.categories).to.have.lengthOf(1)
69 expect(overview.channels).to.have.lengthOf(1)
70 }
71
72 {
73 const res = await getVideosOverview(server.url, 2)
74
75 const overview: VideosOverview = res.body
76 expect(overview.tags).to.have.lengthOf(1)
77 expect(overview.categories).to.have.lengthOf(0)
78 expect(overview.channels).to.have.lengthOf(0)
79 }
63 }) 80 })
64 81
65 it('Should have the correct overview', async function () { 82 it('Should have the correct overview', async function () {
66 const res = await getVideosOverview(server.url) 83 const res1 = await getVideosOverview(server.url, 1)
84 const res2 = await getVideosOverview(server.url, 2)
67 85
68 const overview: VideosOverview = res.body 86 const overview1: VideosOverview = res1.body
87 const overview2: VideosOverview = res2.body
88
89 const tmp = [
90 overview1.tags,
91 overview1.categories,
92 overview1.channels,
93 overview2.tags
94 ]
95
96 for (const arr of tmp) {
97 expect(arr).to.have.lengthOf(1)
69 98
70 for (const attr of [ 'tags', 'categories', 'channels' ]) { 99 const obj = arr[0]
71 const obj = overview[attr][0]
72 100
73 expect(obj.videos).to.have.lengthOf(6) 101 expect(obj.videos).to.have.lengthOf(6)
74 expect(obj.videos[0].name).to.equal('video 5') 102 expect(obj.videos[0].name).to.equal('video 5')
@@ -79,12 +107,13 @@ describe('Test a videos overview', function () {
79 expect(obj.videos[5].name).to.equal('video 0') 107 expect(obj.videos[5].name).to.equal('video 0')
80 } 108 }
81 109
82 expect(overview.tags.find(t => t.tag === 'coucou1')).to.not.be.undefined 110 const tags = [ overview1.tags[0].tag, overview2.tags[0].tag ]
83 expect(overview.tags.find(t => t.tag === 'coucou2')).to.not.be.undefined 111 expect(tags.find(t => t === 'coucou1')).to.not.be.undefined
112 expect(tags.find(t => t === 'coucou2')).to.not.be.undefined
84 113
85 expect(overview.categories[0].category.id).to.equal(3) 114 expect(overview1.categories[0].category.id).to.equal(3)
86 115
87 expect(overview.channels[0].channel.name).to.equal('root_channel') 116 expect(overview1.channels[0].channel.name).to.equal('root_channel')
88 }) 117 })
89 118
90 after(async function () { 119 after(async function () {
diff --git a/server/tests/api/videos/videos-views-cleaner.ts b/server/tests/api/videos/videos-views-cleaner.ts
index fbddd40f4..d063d7973 100644
--- a/server/tests/api/videos/videos-views-cleaner.ts
+++ b/server/tests/api/videos/videos-views-cleaner.ts
@@ -1,20 +1,22 @@
1/* tslint:disable:no-unused-expression */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 cleanupTests,
7 closeAllSequelize,
8 countVideoViewsOf,
9 doubleFollow,
6 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
7 flushTests,
8 killallServers, 11 killallServers,
9 reRunServer, 12 reRunServer,
10 flushAndRunServer,
11 ServerInfo, 13 ServerInfo,
12 setAccessTokensToServers, 14 setAccessTokensToServers,
13 uploadVideo, uploadVideoAndGetId, viewVideo, wait, countVideoViewsOf, doubleFollow, waitJobs, cleanupTests, closeAllSequelize 15 uploadVideoAndGetId,
16 viewVideo,
17 wait,
18 waitJobs
14} from '../../../../shared/extra-utils' 19} from '../../../../shared/extra-utils'
15import { getVideosOverview } from '../../../../shared/extra-utils/overviews/overviews'
16import { VideosOverview } from '../../../../shared/models/overviews'
17import { listMyVideosHistory } from '../../../../shared/extra-utils/videos/video-history'
18 20
19const expect = chai.expect 21const expect = chai.expect
20 22