diff options
Diffstat (limited to 'server/tests/api')
23 files changed, 733 insertions, 829 deletions
diff --git a/server/tests/api/check-params/accounts.ts b/server/tests/api/check-params/accounts.ts index 567fd072c..68f9519c6 100644 --- a/server/tests/api/check-params/accounts.ts +++ b/server/tests/api/check-params/accounts.ts | |||
@@ -10,7 +10,7 @@ import { | |||
10 | } from '../../../../shared/utils/requests/check-api-params' | 10 | } from '../../../../shared/utils/requests/check-api-params' |
11 | import { getAccount } from '../../../../shared/utils/users/accounts' | 11 | import { getAccount } from '../../../../shared/utils/users/accounts' |
12 | 12 | ||
13 | describe('Test users API validators', function () { | 13 | describe('Test accounts API validators', function () { |
14 | const path = '/api/v1/accounts/' | 14 | const path = '/api/v1/accounts/' |
15 | let server: ServerInfo | 15 | let server: ServerInfo |
16 | 16 | ||
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index 4038ecbf0..07de2b5a5 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -65,6 +65,9 @@ describe('Test config API validators', function () { | |||
65 | '480p': true, | 65 | '480p': true, |
66 | '720p': false, | 66 | '720p': false, |
67 | '1080p': false | 67 | '1080p': false |
68 | }, | ||
69 | hls: { | ||
70 | enabled: false | ||
68 | } | 71 | } |
69 | }, | 72 | }, |
70 | import: { | 73 | import: { |
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts index 2407ac0b5..c7e014b1f 100644 --- a/server/tests/api/check-params/contact-form.ts +++ b/server/tests/api/check-params/contact-form.ts | |||
@@ -46,6 +46,8 @@ describe('Test contact form API validators', function () { | |||
46 | }) | 46 | }) |
47 | 47 | ||
48 | it('Should not accept a contact form if it is disabled in the configuration', async function () { | 48 | it('Should not accept a contact form if it is disabled in the configuration', async function () { |
49 | this.timeout(10000) | ||
50 | |||
49 | killallServers([ server ]) | 51 | killallServers([ server ]) |
50 | 52 | ||
51 | // Contact form is disabled | 53 | // Contact form is disabled |
@@ -54,6 +56,8 @@ describe('Test contact form API validators', function () { | |||
54 | }) | 56 | }) |
55 | 57 | ||
56 | it('Should not accept a contact form if from email is invalid', async function () { | 58 | it('Should not accept a contact form if from email is invalid', async function () { |
59 | this.timeout(10000) | ||
60 | |||
57 | killallServers([ server ]) | 61 | killallServers([ server ]) |
58 | 62 | ||
59 | // Email & contact form enabled | 63 | // Email & contact form enabled |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index a3e8e2e9c..13be8b460 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -464,6 +464,24 @@ describe('Test users API validators', function () { | |||
464 | await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields }) | 464 | await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields }) |
465 | }) | 465 | }) |
466 | 466 | ||
467 | it('Should fail with a too small password', async function () { | ||
468 | const fields = { | ||
469 | currentPassword: 'my super password', | ||
470 | password: 'bla' | ||
471 | } | ||
472 | |||
473 | await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields }) | ||
474 | }) | ||
475 | |||
476 | it('Should fail with a too long password', async function () { | ||
477 | const fields = { | ||
478 | currentPassword: 'my super password', | ||
479 | password: 'super'.repeat(61) | ||
480 | } | ||
481 | |||
482 | await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields }) | ||
483 | }) | ||
484 | |||
467 | it('Should fail with an non authenticated user', async function () { | 485 | it('Should fail with an non authenticated user', async function () { |
468 | const fields = { | 486 | const fields = { |
469 | videoQuota: 42 | 487 | videoQuota: 42 |
diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts index a79ab4201..3b8f5f14d 100644 --- a/server/tests/api/check-params/video-abuses.ts +++ b/server/tests/api/check-params/video-abuses.ts | |||
@@ -113,8 +113,8 @@ describe('Test video abuses API validators', function () { | |||
113 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | 113 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) |
114 | }) | 114 | }) |
115 | 115 | ||
116 | it('Should fail with a reason too big', async function () { | 116 | it('Should fail with a too big reason', async function () { |
117 | const fields = { reason: 'super'.repeat(61) } | 117 | const fields = { reason: 'super'.repeat(605) } |
118 | 118 | ||
119 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | 119 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) |
120 | }) | 120 | }) |
@@ -154,7 +154,7 @@ describe('Test video abuses API validators', function () { | |||
154 | }) | 154 | }) |
155 | 155 | ||
156 | it('Should fail with a bad moderation comment', async function () { | 156 | it('Should fail with a bad moderation comment', async function () { |
157 | const body = { moderationComment: 'b'.repeat(305) } | 157 | const body = { moderationComment: 'b'.repeat(3001) } |
158 | await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400) | 158 | await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400) |
159 | }) | 159 | }) |
160 | 160 | ||
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts index 8e1206db3..6b82643f4 100644 --- a/server/tests/api/check-params/video-blacklist.ts +++ b/server/tests/api/check-params/video-blacklist.ts | |||
@@ -4,17 +4,20 @@ import 'mocha' | |||
4 | 4 | ||
5 | import { | 5 | import { |
6 | createUser, | 6 | createUser, |
7 | doubleFollow, | ||
8 | flushAndRunMultipleServers, | ||
7 | flushTests, | 9 | flushTests, |
8 | getBlacklistedVideosList, getVideo, getVideoWithToken, | 10 | getBlacklistedVideosList, |
11 | getVideo, | ||
12 | getVideoWithToken, | ||
9 | killallServers, | 13 | killallServers, |
10 | makePostBodyRequest, | 14 | makePostBodyRequest, |
11 | makePutBodyRequest, | 15 | makePutBodyRequest, |
12 | removeVideoFromBlacklist, | 16 | removeVideoFromBlacklist, |
13 | runServer, | ||
14 | ServerInfo, | 17 | ServerInfo, |
15 | setAccessTokensToServers, | 18 | setAccessTokensToServers, |
16 | uploadVideo, | 19 | uploadVideo, |
17 | userLogin | 20 | userLogin, waitJobs |
18 | } from '../../../../shared/utils' | 21 | } from '../../../../shared/utils' |
19 | import { | 22 | import { |
20 | checkBadCountPagination, | 23 | checkBadCountPagination, |
@@ -25,8 +28,9 @@ import { VideoDetails } from '../../../../shared/models/videos' | |||
25 | import { expect } from 'chai' | 28 | import { expect } from 'chai' |
26 | 29 | ||
27 | describe('Test video blacklist API validators', function () { | 30 | describe('Test video blacklist API validators', function () { |
28 | let server: ServerInfo | 31 | let servers: ServerInfo[] |
29 | let notBlacklistedVideoId: number | 32 | let notBlacklistedVideoId: number |
33 | let remoteVideoUUID: string | ||
30 | let userAccessToken1 = '' | 34 | let userAccessToken1 = '' |
31 | let userAccessToken2 = '' | 35 | let userAccessToken2 = '' |
32 | 36 | ||
@@ -36,75 +40,89 @@ describe('Test video blacklist API validators', function () { | |||
36 | this.timeout(120000) | 40 | this.timeout(120000) |
37 | 41 | ||
38 | await flushTests() | 42 | await flushTests() |
43 | servers = await flushAndRunMultipleServers(2) | ||
39 | 44 | ||
40 | server = await runServer(1) | 45 | await setAccessTokensToServers(servers) |
41 | 46 | await doubleFollow(servers[0], servers[1]) | |
42 | await setAccessTokensToServers([ server ]) | ||
43 | 47 | ||
44 | { | 48 | { |
45 | const username = 'user1' | 49 | const username = 'user1' |
46 | const password = 'my super password' | 50 | const password = 'my super password' |
47 | await createUser(server.url, server.accessToken, username, password) | 51 | await createUser(servers[0].url, servers[0].accessToken, username, password) |
48 | userAccessToken1 = await userLogin(server, { username, password }) | 52 | userAccessToken1 = await userLogin(servers[0], { username, password }) |
49 | } | 53 | } |
50 | 54 | ||
51 | { | 55 | { |
52 | const username = 'user2' | 56 | const username = 'user2' |
53 | const password = 'my super password' | 57 | const password = 'my super password' |
54 | await createUser(server.url, server.accessToken, username, password) | 58 | await createUser(servers[0].url, servers[0].accessToken, username, password) |
55 | userAccessToken2 = await userLogin(server, { username, password }) | 59 | userAccessToken2 = await userLogin(servers[0], { username, password }) |
56 | } | 60 | } |
57 | 61 | ||
58 | { | 62 | { |
59 | const res = await uploadVideo(server.url, userAccessToken1, {}) | 63 | const res = await uploadVideo(servers[0].url, userAccessToken1, {}) |
60 | server.video = res.body.video | 64 | servers[0].video = res.body.video |
61 | } | 65 | } |
62 | 66 | ||
63 | { | 67 | { |
64 | const res = await uploadVideo(server.url, server.accessToken, {}) | 68 | const res = await uploadVideo(servers[0].url, servers[0].accessToken, {}) |
65 | notBlacklistedVideoId = res.body.video.uuid | 69 | notBlacklistedVideoId = res.body.video.uuid |
66 | } | 70 | } |
71 | |||
72 | { | ||
73 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, {}) | ||
74 | remoteVideoUUID = res.body.video.uuid | ||
75 | } | ||
76 | |||
77 | await waitJobs(servers) | ||
67 | }) | 78 | }) |
68 | 79 | ||
69 | describe('When adding a video in blacklist', function () { | 80 | describe('When adding a video in blacklist', function () { |
70 | const basePath = '/api/v1/videos/' | 81 | const basePath = '/api/v1/videos/' |
71 | 82 | ||
72 | it('Should fail with nothing', async function () { | 83 | it('Should fail with nothing', async function () { |
73 | const path = basePath + server.video + '/blacklist' | 84 | const path = basePath + servers[0].video + '/blacklist' |
74 | const fields = {} | 85 | const fields = {} |
75 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | 86 | await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields }) |
76 | }) | 87 | }) |
77 | 88 | ||
78 | it('Should fail with a wrong video', async function () { | 89 | it('Should fail with a wrong video', async function () { |
79 | const wrongPath = '/api/v1/videos/blabla/blacklist' | 90 | const wrongPath = '/api/v1/videos/blabla/blacklist' |
80 | const fields = {} | 91 | const fields = {} |
81 | await makePostBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) | 92 | await makePostBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields }) |
82 | }) | 93 | }) |
83 | 94 | ||
84 | it('Should fail with a non authenticated user', async function () { | 95 | it('Should fail with a non authenticated user', async function () { |
85 | const path = basePath + server.video + '/blacklist' | 96 | const path = basePath + servers[0].video + '/blacklist' |
86 | const fields = {} | 97 | const fields = {} |
87 | await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) | 98 | await makePostBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 }) |
88 | }) | 99 | }) |
89 | 100 | ||
90 | it('Should fail with a non admin user', async function () { | 101 | it('Should fail with a non admin user', async function () { |
91 | const path = basePath + server.video + '/blacklist' | 102 | const path = basePath + servers[0].video + '/blacklist' |
92 | const fields = {} | 103 | const fields = {} |
93 | await makePostBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) | 104 | await makePostBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) |
94 | }) | 105 | }) |
95 | 106 | ||
96 | it('Should fail with an invalid reason', async function () { | 107 | it('Should fail with an invalid reason', async function () { |
97 | const path = basePath + server.video.uuid + '/blacklist' | 108 | const path = basePath + servers[0].video.uuid + '/blacklist' |
98 | const fields = { reason: 'a'.repeat(305) } | 109 | const fields = { reason: 'a'.repeat(305) } |
99 | 110 | ||
100 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | 111 | await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields }) |
112 | }) | ||
113 | |||
114 | it('Should fail to unfederate a remote video', async function () { | ||
115 | const path = basePath + remoteVideoUUID + '/blacklist' | ||
116 | const fields = { unfederate: true } | ||
117 | |||
118 | await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 409 }) | ||
101 | }) | 119 | }) |
102 | 120 | ||
103 | it('Should succeed with the correct params', async function () { | 121 | it('Should succeed with the correct params', async function () { |
104 | const path = basePath + server.video.uuid + '/blacklist' | 122 | const path = basePath + servers[0].video.uuid + '/blacklist' |
105 | const fields = { } | 123 | const fields = { } |
106 | 124 | ||
107 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) | 125 | await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 }) |
108 | }) | 126 | }) |
109 | }) | 127 | }) |
110 | 128 | ||
@@ -114,61 +132,61 @@ describe('Test video blacklist API validators', function () { | |||
114 | it('Should fail with a wrong video', async function () { | 132 | it('Should fail with a wrong video', async function () { |
115 | const wrongPath = '/api/v1/videos/blabla/blacklist' | 133 | const wrongPath = '/api/v1/videos/blabla/blacklist' |
116 | const fields = {} | 134 | const fields = {} |
117 | await makePutBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) | 135 | await makePutBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields }) |
118 | }) | 136 | }) |
119 | 137 | ||
120 | it('Should fail with a video not blacklisted', async function () { | 138 | it('Should fail with a video not blacklisted', async function () { |
121 | const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist' | 139 | const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist' |
122 | const fields = {} | 140 | const fields = {} |
123 | await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 404 }) | 141 | await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 404 }) |
124 | }) | 142 | }) |
125 | 143 | ||
126 | it('Should fail with a non authenticated user', async function () { | 144 | it('Should fail with a non authenticated user', async function () { |
127 | const path = basePath + server.video + '/blacklist' | 145 | const path = basePath + servers[0].video + '/blacklist' |
128 | const fields = {} | 146 | const fields = {} |
129 | await makePutBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) | 147 | await makePutBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 }) |
130 | }) | 148 | }) |
131 | 149 | ||
132 | it('Should fail with a non admin user', async function () { | 150 | it('Should fail with a non admin user', async function () { |
133 | const path = basePath + server.video + '/blacklist' | 151 | const path = basePath + servers[0].video + '/blacklist' |
134 | const fields = {} | 152 | const fields = {} |
135 | await makePutBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) | 153 | await makePutBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) |
136 | }) | 154 | }) |
137 | 155 | ||
138 | it('Should fail with an invalid reason', async function () { | 156 | it('Should fail with an invalid reason', async function () { |
139 | const path = basePath + server.video.uuid + '/blacklist' | 157 | const path = basePath + servers[0].video.uuid + '/blacklist' |
140 | const fields = { reason: 'a'.repeat(305) } | 158 | const fields = { reason: 'a'.repeat(305) } |
141 | 159 | ||
142 | await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | 160 | await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields }) |
143 | }) | 161 | }) |
144 | 162 | ||
145 | it('Should succeed with the correct params', async function () { | 163 | it('Should succeed with the correct params', async function () { |
146 | const path = basePath + server.video.uuid + '/blacklist' | 164 | const path = basePath + servers[0].video.uuid + '/blacklist' |
147 | const fields = { reason: 'hello' } | 165 | const fields = { reason: 'hello' } |
148 | 166 | ||
149 | await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) | 167 | await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 }) |
150 | }) | 168 | }) |
151 | }) | 169 | }) |
152 | 170 | ||
153 | describe('When getting blacklisted video', function () { | 171 | describe('When getting blacklisted video', function () { |
154 | 172 | ||
155 | it('Should fail with a non authenticated user', async function () { | 173 | it('Should fail with a non authenticated user', async function () { |
156 | await getVideo(server.url, server.video.uuid, 401) | 174 | await getVideo(servers[0].url, servers[0].video.uuid, 401) |
157 | }) | 175 | }) |
158 | 176 | ||
159 | it('Should fail with another user', async function () { | 177 | it('Should fail with another user', async function () { |
160 | await getVideoWithToken(server.url, userAccessToken2, server.video.uuid, 403) | 178 | await getVideoWithToken(servers[0].url, userAccessToken2, servers[0].video.uuid, 403) |
161 | }) | 179 | }) |
162 | 180 | ||
163 | it('Should succeed with the owner authenticated user', async function () { | 181 | it('Should succeed with the owner authenticated user', async function () { |
164 | const res = await getVideoWithToken(server.url, userAccessToken1, server.video.uuid, 200) | 182 | const res = await getVideoWithToken(servers[0].url, userAccessToken1, servers[0].video.uuid, 200) |
165 | const video: VideoDetails = res.body | 183 | const video: VideoDetails = res.body |
166 | 184 | ||
167 | expect(video.blacklisted).to.be.true | 185 | expect(video.blacklisted).to.be.true |
168 | }) | 186 | }) |
169 | 187 | ||
170 | it('Should succeed with an admin', async function () { | 188 | it('Should succeed with an admin', async function () { |
171 | const res = await getVideoWithToken(server.url, server.accessToken, server.video.uuid, 200) | 189 | const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 200) |
172 | const video: VideoDetails = res.body | 190 | const video: VideoDetails = res.body |
173 | 191 | ||
174 | expect(video.blacklisted).to.be.true | 192 | expect(video.blacklisted).to.be.true |
@@ -177,24 +195,24 @@ describe('Test video blacklist API validators', function () { | |||
177 | 195 | ||
178 | describe('When removing a video in blacklist', function () { | 196 | describe('When removing a video in blacklist', function () { |
179 | it('Should fail with a non authenticated user', async function () { | 197 | it('Should fail with a non authenticated user', async function () { |
180 | await removeVideoFromBlacklist(server.url, 'fake token', server.video.uuid, 401) | 198 | await removeVideoFromBlacklist(servers[0].url, 'fake token', servers[0].video.uuid, 401) |
181 | }) | 199 | }) |
182 | 200 | ||
183 | it('Should fail with a non admin user', async function () { | 201 | it('Should fail with a non admin user', async function () { |
184 | await removeVideoFromBlacklist(server.url, userAccessToken2, server.video.uuid, 403) | 202 | await removeVideoFromBlacklist(servers[0].url, userAccessToken2, servers[0].video.uuid, 403) |
185 | }) | 203 | }) |
186 | 204 | ||
187 | it('Should fail with an incorrect id', async function () { | 205 | it('Should fail with an incorrect id', async function () { |
188 | await removeVideoFromBlacklist(server.url, server.accessToken, 'hello', 400) | 206 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, 'hello', 400) |
189 | }) | 207 | }) |
190 | 208 | ||
191 | it('Should fail with a not blacklisted video', async function () { | 209 | it('Should fail with a not blacklisted video', async function () { |
192 | // The video was not added to the blacklist so it should fail | 210 | // The video was not added to the blacklist so it should fail |
193 | await removeVideoFromBlacklist(server.url, server.accessToken, notBlacklistedVideoId, 404) | 211 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, notBlacklistedVideoId, 404) |
194 | }) | 212 | }) |
195 | 213 | ||
196 | it('Should succeed with the correct params', async function () { | 214 | it('Should succeed with the correct params', async function () { |
197 | await removeVideoFromBlacklist(server.url, server.accessToken, server.video.uuid, 204) | 215 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 204) |
198 | }) | 216 | }) |
199 | }) | 217 | }) |
200 | 218 | ||
@@ -202,28 +220,28 @@ describe('Test video blacklist API validators', function () { | |||
202 | const basePath = '/api/v1/videos/blacklist/' | 220 | const basePath = '/api/v1/videos/blacklist/' |
203 | 221 | ||
204 | it('Should fail with a non authenticated user', async function () { | 222 | it('Should fail with a non authenticated user', async function () { |
205 | await getBlacklistedVideosList(server.url, 'fake token', 401) | 223 | await getBlacklistedVideosList(servers[0].url, 'fake token', 401) |
206 | }) | 224 | }) |
207 | 225 | ||
208 | it('Should fail with a non admin user', async function () { | 226 | it('Should fail with a non admin user', async function () { |
209 | await getBlacklistedVideosList(server.url, userAccessToken2, 403) | 227 | await getBlacklistedVideosList(servers[0].url, userAccessToken2, 403) |
210 | }) | 228 | }) |
211 | 229 | ||
212 | it('Should fail with a bad start pagination', async function () { | 230 | it('Should fail with a bad start pagination', async function () { |
213 | await checkBadStartPagination(server.url, basePath, server.accessToken) | 231 | await checkBadStartPagination(servers[0].url, basePath, servers[0].accessToken) |
214 | }) | 232 | }) |
215 | 233 | ||
216 | it('Should fail with a bad count pagination', async function () { | 234 | it('Should fail with a bad count pagination', async function () { |
217 | await checkBadCountPagination(server.url, basePath, server.accessToken) | 235 | await checkBadCountPagination(servers[0].url, basePath, servers[0].accessToken) |
218 | }) | 236 | }) |
219 | 237 | ||
220 | it('Should fail with an incorrect sort', async function () { | 238 | it('Should fail with an incorrect sort', async function () { |
221 | await checkBadSortPagination(server.url, basePath, server.accessToken) | 239 | await checkBadSortPagination(servers[0].url, basePath, servers[0].accessToken) |
222 | }) | 240 | }) |
223 | }) | 241 | }) |
224 | 242 | ||
225 | after(async function () { | 243 | after(async function () { |
226 | killallServers([ server ]) | 244 | killallServers(servers) |
227 | 245 | ||
228 | // Keep the logs if the test failed | 246 | // Keep the logs if the test failed |
229 | if (this['ok']) { | 247 | if (this['ok']) { |
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts index 7bf187007..6dd9f15f7 100644 --- a/server/tests/api/check-params/video-imports.ts +++ b/server/tests/api/check-params/video-imports.ts | |||
@@ -88,6 +88,7 @@ describe('Test video imports API validator', function () { | |||
88 | language: 'pt', | 88 | language: 'pt', |
89 | nsfw: false, | 89 | nsfw: false, |
90 | commentsEnabled: true, | 90 | commentsEnabled: true, |
91 | downloadEnabled: true, | ||
91 | waitTranscoding: true, | 92 | waitTranscoding: true, |
92 | description: 'my super description', | 93 | description: 'my super description', |
93 | support: 'my super support text', | 94 | support: 'my super support text', |
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index f26b91435..878ffe025 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts | |||
@@ -179,6 +179,7 @@ describe('Test videos API validator', function () { | |||
179 | language: 'pt', | 179 | language: 'pt', |
180 | nsfw: false, | 180 | nsfw: false, |
181 | commentsEnabled: true, | 181 | commentsEnabled: true, |
182 | downloadEnabled: true, | ||
182 | waitTranscoding: true, | 183 | waitTranscoding: true, |
183 | description: 'my super description', | 184 | description: 'my super description', |
184 | support: 'my super support text', | 185 | support: 'my super support text', |
@@ -428,6 +429,7 @@ describe('Test videos API validator', function () { | |||
428 | language: 'pt', | 429 | language: 'pt', |
429 | nsfw: false, | 430 | nsfw: false, |
430 | commentsEnabled: false, | 431 | commentsEnabled: false, |
432 | downloadEnabled: false, | ||
431 | description: 'my super description', | 433 | description: 'my super description', |
432 | privacy: VideoPrivacy.PUBLIC, | 434 | privacy: VideoPrivacy.PUBLIC, |
433 | tags: [ 'tag1', 'tag2' ] | 435 | tags: [ 'tag1', 'tag2' ] |
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts index 9d3ce8153..778611fff 100644 --- a/server/tests/api/redundancy/redundancy.ts +++ b/server/tests/api/redundancy/redundancy.ts | |||
@@ -17,7 +17,7 @@ import { | |||
17 | viewVideo, | 17 | viewVideo, |
18 | wait, | 18 | wait, |
19 | waitUntilLog, | 19 | waitUntilLog, |
20 | checkVideoFilesWereRemoved, removeVideo, getVideoWithToken | 20 | checkVideoFilesWereRemoved, removeVideo, getVideoWithToken, reRunServer, checkSegmentHash |
21 | } from '../../../../shared/utils' | 21 | } from '../../../../shared/utils' |
22 | import { waitJobs } from '../../../../shared/utils/server/jobs' | 22 | import { waitJobs } from '../../../../shared/utils/server/jobs' |
23 | 23 | ||
@@ -48,6 +48,11 @@ function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: numbe | |||
48 | 48 | ||
49 | async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { | 49 | async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { |
50 | const config = { | 50 | const config = { |
51 | transcoding: { | ||
52 | hls: { | ||
53 | enabled: true | ||
54 | } | ||
55 | }, | ||
51 | redundancy: { | 56 | redundancy: { |
52 | videos: { | 57 | videos: { |
53 | check_interval: '5 seconds', | 58 | check_interval: '5 seconds', |
@@ -85,7 +90,7 @@ async function runServers (strategy: VideoRedundancyStrategy, additionalParams: | |||
85 | await waitJobs(servers) | 90 | await waitJobs(servers) |
86 | } | 91 | } |
87 | 92 | ||
88 | async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: string) { | 93 | async function check1WebSeed (videoUUID?: string) { |
89 | if (!videoUUID) videoUUID = video1Server2UUID | 94 | if (!videoUUID) videoUUID = video1Server2UUID |
90 | 95 | ||
91 | const webseeds = [ | 96 | const webseeds = [ |
@@ -93,47 +98,17 @@ async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: str | |||
93 | ] | 98 | ] |
94 | 99 | ||
95 | for (const server of servers) { | 100 | for (const server of servers) { |
96 | { | 101 | // With token to avoid issues with video follow constraints |
97 | // With token to avoid issues with video follow constraints | 102 | const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) |
98 | const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) | ||
99 | 103 | ||
100 | const video: VideoDetails = res.body | 104 | const video: VideoDetails = res.body |
101 | for (const f of video.files) { | 105 | for (const f of video.files) { |
102 | checkMagnetWebseeds(f, webseeds, server) | 106 | checkMagnetWebseeds(f, webseeds, server) |
103 | } | ||
104 | } | 107 | } |
105 | } | 108 | } |
106 | } | 109 | } |
107 | 110 | ||
108 | async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) { | 111 | async function check2Webseeds (videoUUID?: string) { |
109 | const res = await getStats(servers[0].url) | ||
110 | const data: ServerStats = res.body | ||
111 | |||
112 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
113 | const stat = data.videosRedundancy[0] | ||
114 | |||
115 | expect(stat.strategy).to.equal(strategy) | ||
116 | expect(stat.totalSize).to.equal(204800) | ||
117 | expect(stat.totalUsed).to.be.at.least(1).and.below(204801) | ||
118 | expect(stat.totalVideoFiles).to.equal(4) | ||
119 | expect(stat.totalVideos).to.equal(1) | ||
120 | } | ||
121 | |||
122 | async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) { | ||
123 | const res = await getStats(servers[0].url) | ||
124 | const data: ServerStats = res.body | ||
125 | |||
126 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
127 | |||
128 | const stat = data.videosRedundancy[0] | ||
129 | expect(stat.strategy).to.equal(strategy) | ||
130 | expect(stat.totalSize).to.equal(204800) | ||
131 | expect(stat.totalUsed).to.equal(0) | ||
132 | expect(stat.totalVideoFiles).to.equal(0) | ||
133 | expect(stat.totalVideos).to.equal(0) | ||
134 | } | ||
135 | |||
136 | async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: string) { | ||
137 | if (!videoUUID) videoUUID = video1Server2UUID | 112 | if (!videoUUID) videoUUID = video1Server2UUID |
138 | 113 | ||
139 | const webseeds = [ | 114 | const webseeds = [ |
@@ -158,7 +133,7 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st | |||
158 | await makeGetRequest({ | 133 | await makeGetRequest({ |
159 | url: servers[1].url, | 134 | url: servers[1].url, |
160 | statusCodeExpected: 200, | 135 | statusCodeExpected: 200, |
161 | path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, | 136 | path: `/static/webseed/${videoUUID}-${file.resolution.id}.mp4`, |
162 | contentType: null | 137 | contentType: null |
163 | }) | 138 | }) |
164 | } | 139 | } |
@@ -174,6 +149,85 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st | |||
174 | } | 149 | } |
175 | } | 150 | } |
176 | 151 | ||
152 | async function check0PlaylistRedundancies (videoUUID?: string) { | ||
153 | if (!videoUUID) videoUUID = video1Server2UUID | ||
154 | |||
155 | for (const server of servers) { | ||
156 | // With token to avoid issues with video follow constraints | ||
157 | const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) | ||
158 | const video: VideoDetails = res.body | ||
159 | |||
160 | expect(video.streamingPlaylists).to.be.an('array') | ||
161 | expect(video.streamingPlaylists).to.have.lengthOf(1) | ||
162 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0) | ||
163 | } | ||
164 | } | ||
165 | |||
166 | async function check1PlaylistRedundancies (videoUUID?: string) { | ||
167 | if (!videoUUID) videoUUID = video1Server2UUID | ||
168 | |||
169 | for (const server of servers) { | ||
170 | const res = await getVideo(server.url, videoUUID) | ||
171 | const video: VideoDetails = res.body | ||
172 | |||
173 | expect(video.streamingPlaylists).to.have.lengthOf(1) | ||
174 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1) | ||
175 | |||
176 | const redundancy = video.streamingPlaylists[0].redundancies[0] | ||
177 | |||
178 | expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID) | ||
179 | } | ||
180 | |||
181 | const baseUrlPlaylist = servers[1].url + '/static/playlists/hls' | ||
182 | const baseUrlSegment = servers[0].url + '/static/redundancy/hls' | ||
183 | |||
184 | const res = await getVideo(servers[0].url, videoUUID) | ||
185 | const hlsPlaylist = (res.body as VideoDetails).streamingPlaylists[0] | ||
186 | |||
187 | for (const resolution of [ 240, 360, 480, 720 ]) { | ||
188 | await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist) | ||
189 | } | ||
190 | |||
191 | for (const directory of [ 'test1/redundancy/hls', 'test2/playlists/hls' ]) { | ||
192 | const files = await readdir(join(root(), directory, videoUUID)) | ||
193 | expect(files).to.have.length.at.least(4) | ||
194 | |||
195 | for (const resolution of [ 240, 360, 480, 720 ]) { | ||
196 | const filename = `${videoUUID}-${resolution}-fragmented.mp4` | ||
197 | |||
198 | expect(files.find(f => f === filename)).to.not.be.undefined | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | |||
203 | async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) { | ||
204 | const res = await getStats(servers[0].url) | ||
205 | const data: ServerStats = res.body | ||
206 | |||
207 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
208 | const stat = data.videosRedundancy[0] | ||
209 | |||
210 | expect(stat.strategy).to.equal(strategy) | ||
211 | expect(stat.totalSize).to.equal(204800) | ||
212 | expect(stat.totalUsed).to.be.at.least(1).and.below(204801) | ||
213 | expect(stat.totalVideoFiles).to.equal(4) | ||
214 | expect(stat.totalVideos).to.equal(1) | ||
215 | } | ||
216 | |||
217 | async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) { | ||
218 | const res = await getStats(servers[0].url) | ||
219 | const data: ServerStats = res.body | ||
220 | |||
221 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
222 | |||
223 | const stat = data.videosRedundancy[0] | ||
224 | expect(stat.strategy).to.equal(strategy) | ||
225 | expect(stat.totalSize).to.equal(204800) | ||
226 | expect(stat.totalUsed).to.equal(0) | ||
227 | expect(stat.totalVideoFiles).to.equal(0) | ||
228 | expect(stat.totalVideos).to.equal(0) | ||
229 | } | ||
230 | |||
177 | async function enableRedundancyOnServer1 () { | 231 | async function enableRedundancyOnServer1 () { |
178 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) | 232 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) |
179 | 233 | ||
@@ -220,7 +274,8 @@ describe('Test videos redundancy', function () { | |||
220 | }) | 274 | }) |
221 | 275 | ||
222 | it('Should have 1 webseed on the first video', async function () { | 276 | it('Should have 1 webseed on the first video', async function () { |
223 | await check1WebSeed(strategy) | 277 | await check1WebSeed() |
278 | await check0PlaylistRedundancies() | ||
224 | await checkStatsWith1Webseed(strategy) | 279 | await checkStatsWith1Webseed(strategy) |
225 | }) | 280 | }) |
226 | 281 | ||
@@ -229,27 +284,29 @@ describe('Test videos redundancy', function () { | |||
229 | }) | 284 | }) |
230 | 285 | ||
231 | it('Should have 2 webseeds on the first video', async function () { | 286 | it('Should have 2 webseeds on the first video', async function () { |
232 | this.timeout(40000) | 287 | this.timeout(80000) |
233 | 288 | ||
234 | await waitJobs(servers) | 289 | await waitJobs(servers) |
235 | await waitUntilLog(servers[0], 'Duplicated ', 4) | 290 | await waitUntilLog(servers[0], 'Duplicated ', 5) |
236 | await waitJobs(servers) | 291 | await waitJobs(servers) |
237 | 292 | ||
238 | await check2Webseeds(strategy) | 293 | await check2Webseeds() |
294 | await check1PlaylistRedundancies() | ||
239 | await checkStatsWith2Webseed(strategy) | 295 | await checkStatsWith2Webseed(strategy) |
240 | }) | 296 | }) |
241 | 297 | ||
242 | it('Should undo redundancy on server 1 and remove duplicated videos', async function () { | 298 | it('Should undo redundancy on server 1 and remove duplicated videos', async function () { |
243 | this.timeout(40000) | 299 | this.timeout(80000) |
244 | 300 | ||
245 | await disableRedundancyOnServer1() | 301 | await disableRedundancyOnServer1() |
246 | 302 | ||
247 | await waitJobs(servers) | 303 | await waitJobs(servers) |
248 | await wait(5000) | 304 | await wait(5000) |
249 | 305 | ||
250 | await check1WebSeed(strategy) | 306 | await check1WebSeed() |
307 | await check0PlaylistRedundancies() | ||
251 | 308 | ||
252 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) | 309 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos', join('playlists', 'hls') ]) |
253 | }) | 310 | }) |
254 | 311 | ||
255 | after(function () { | 312 | after(function () { |
@@ -267,7 +324,8 @@ describe('Test videos redundancy', function () { | |||
267 | }) | 324 | }) |
268 | 325 | ||
269 | it('Should have 1 webseed on the first video', async function () { | 326 | it('Should have 1 webseed on the first video', async function () { |
270 | await check1WebSeed(strategy) | 327 | await check1WebSeed() |
328 | await check0PlaylistRedundancies() | ||
271 | await checkStatsWith1Webseed(strategy) | 329 | await checkStatsWith1Webseed(strategy) |
272 | }) | 330 | }) |
273 | 331 | ||
@@ -276,25 +334,27 @@ describe('Test videos redundancy', function () { | |||
276 | }) | 334 | }) |
277 | 335 | ||
278 | it('Should have 2 webseeds on the first video', async function () { | 336 | it('Should have 2 webseeds on the first video', async function () { |
279 | this.timeout(40000) | 337 | this.timeout(80000) |
280 | 338 | ||
281 | await waitJobs(servers) | 339 | await waitJobs(servers) |
282 | await waitUntilLog(servers[0], 'Duplicated ', 4) | 340 | await waitUntilLog(servers[0], 'Duplicated ', 5) |
283 | await waitJobs(servers) | 341 | await waitJobs(servers) |
284 | 342 | ||
285 | await check2Webseeds(strategy) | 343 | await check2Webseeds() |
344 | await check1PlaylistRedundancies() | ||
286 | await checkStatsWith2Webseed(strategy) | 345 | await checkStatsWith2Webseed(strategy) |
287 | }) | 346 | }) |
288 | 347 | ||
289 | it('Should unfollow on server 1 and remove duplicated videos', async function () { | 348 | it('Should unfollow on server 1 and remove duplicated videos', async function () { |
290 | this.timeout(40000) | 349 | this.timeout(80000) |
291 | 350 | ||
292 | await unfollow(servers[0].url, servers[0].accessToken, servers[1]) | 351 | await unfollow(servers[0].url, servers[0].accessToken, servers[1]) |
293 | 352 | ||
294 | await waitJobs(servers) | 353 | await waitJobs(servers) |
295 | await wait(5000) | 354 | await wait(5000) |
296 | 355 | ||
297 | await check1WebSeed(strategy) | 356 | await check1WebSeed() |
357 | await check0PlaylistRedundancies() | ||
298 | 358 | ||
299 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) | 359 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) |
300 | }) | 360 | }) |
@@ -314,7 +374,8 @@ describe('Test videos redundancy', function () { | |||
314 | }) | 374 | }) |
315 | 375 | ||
316 | it('Should have 1 webseed on the first video', async function () { | 376 | it('Should have 1 webseed on the first video', async function () { |
317 | await check1WebSeed(strategy) | 377 | await check1WebSeed() |
378 | await check0PlaylistRedundancies() | ||
318 | await checkStatsWith1Webseed(strategy) | 379 | await checkStatsWith1Webseed(strategy) |
319 | }) | 380 | }) |
320 | 381 | ||
@@ -323,18 +384,19 @@ describe('Test videos redundancy', function () { | |||
323 | }) | 384 | }) |
324 | 385 | ||
325 | it('Should still have 1 webseed on the first video', async function () { | 386 | it('Should still have 1 webseed on the first video', async function () { |
326 | this.timeout(40000) | 387 | this.timeout(80000) |
327 | 388 | ||
328 | await waitJobs(servers) | 389 | await waitJobs(servers) |
329 | await wait(15000) | 390 | await wait(15000) |
330 | await waitJobs(servers) | 391 | await waitJobs(servers) |
331 | 392 | ||
332 | await check1WebSeed(strategy) | 393 | await check1WebSeed() |
394 | await check0PlaylistRedundancies() | ||
333 | await checkStatsWith1Webseed(strategy) | 395 | await checkStatsWith1Webseed(strategy) |
334 | }) | 396 | }) |
335 | 397 | ||
336 | it('Should view 2 times the first video to have > min_views config', async function () { | 398 | it('Should view 2 times the first video to have > min_views config', async function () { |
337 | this.timeout(40000) | 399 | this.timeout(80000) |
338 | 400 | ||
339 | await viewVideo(servers[ 0 ].url, video1Server2UUID) | 401 | await viewVideo(servers[ 0 ].url, video1Server2UUID) |
340 | await viewVideo(servers[ 2 ].url, video1Server2UUID) | 402 | await viewVideo(servers[ 2 ].url, video1Server2UUID) |
@@ -344,13 +406,14 @@ describe('Test videos redundancy', function () { | |||
344 | }) | 406 | }) |
345 | 407 | ||
346 | it('Should have 2 webseeds on the first video', async function () { | 408 | it('Should have 2 webseeds on the first video', async function () { |
347 | this.timeout(40000) | 409 | this.timeout(80000) |
348 | 410 | ||
349 | await waitJobs(servers) | 411 | await waitJobs(servers) |
350 | await waitUntilLog(servers[0], 'Duplicated ', 4) | 412 | await waitUntilLog(servers[0], 'Duplicated ', 5) |
351 | await waitJobs(servers) | 413 | await waitJobs(servers) |
352 | 414 | ||
353 | await check2Webseeds(strategy) | 415 | await check2Webseeds() |
416 | await check1PlaylistRedundancies() | ||
354 | await checkStatsWith2Webseed(strategy) | 417 | await checkStatsWith2Webseed(strategy) |
355 | }) | 418 | }) |
356 | 419 | ||
@@ -405,7 +468,7 @@ describe('Test videos redundancy', function () { | |||
405 | }) | 468 | }) |
406 | 469 | ||
407 | it('Should still have 2 webseeds after 10 seconds', async function () { | 470 | it('Should still have 2 webseeds after 10 seconds', async function () { |
408 | this.timeout(40000) | 471 | this.timeout(80000) |
409 | 472 | ||
410 | await wait(10000) | 473 | await wait(10000) |
411 | 474 | ||
@@ -420,7 +483,7 @@ describe('Test videos redundancy', function () { | |||
420 | }) | 483 | }) |
421 | 484 | ||
422 | it('Should stop server 1 and expire video redundancy', async function () { | 485 | it('Should stop server 1 and expire video redundancy', async function () { |
423 | this.timeout(40000) | 486 | this.timeout(80000) |
424 | 487 | ||
425 | killallServers([ servers[0] ]) | 488 | killallServers([ servers[0] ]) |
426 | 489 | ||
@@ -446,10 +509,11 @@ describe('Test videos redundancy', function () { | |||
446 | await enableRedundancyOnServer1() | 509 | await enableRedundancyOnServer1() |
447 | 510 | ||
448 | await waitJobs(servers) | 511 | await waitJobs(servers) |
449 | await waitUntilLog(servers[0], 'Duplicated ', 4) | 512 | await waitUntilLog(servers[0], 'Duplicated ', 5) |
450 | await waitJobs(servers) | 513 | await waitJobs(servers) |
451 | 514 | ||
452 | await check2Webseeds(strategy) | 515 | await check2Webseeds() |
516 | await check1PlaylistRedundancies() | ||
453 | await checkStatsWith2Webseed(strategy) | 517 | await checkStatsWith2Webseed(strategy) |
454 | 518 | ||
455 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) | 519 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) |
@@ -467,8 +531,10 @@ describe('Test videos redundancy', function () { | |||
467 | await wait(1000) | 531 | await wait(1000) |
468 | 532 | ||
469 | try { | 533 | try { |
470 | await check1WebSeed(strategy, video1Server2UUID) | 534 | await check1WebSeed(video1Server2UUID) |
471 | await check2Webseeds(strategy, video2Server2UUID) | 535 | await check0PlaylistRedundancies(video1Server2UUID) |
536 | await check2Webseeds(video2Server2UUID) | ||
537 | await check1PlaylistRedundancies(video2Server2UUID) | ||
472 | 538 | ||
473 | checked = true | 539 | checked = true |
474 | } catch { | 540 | } catch { |
@@ -477,6 +543,26 @@ describe('Test videos redundancy', function () { | |||
477 | } | 543 | } |
478 | }) | 544 | }) |
479 | 545 | ||
546 | it('Should disable strategy and remove redundancies', async function () { | ||
547 | this.timeout(80000) | ||
548 | |||
549 | await waitJobs(servers) | ||
550 | |||
551 | killallServers([ servers[ 0 ] ]) | ||
552 | await reRunServer(servers[ 0 ], { | ||
553 | redundancy: { | ||
554 | videos: { | ||
555 | check_interval: '1 second', | ||
556 | strategies: [] | ||
557 | } | ||
558 | } | ||
559 | }) | ||
560 | |||
561 | await waitJobs(servers) | ||
562 | |||
563 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ join('redundancy', 'hls') ]) | ||
564 | }) | ||
565 | |||
480 | after(function () { | 566 | after(function () { |
481 | return cleanServers() | 567 | return cleanServers() |
482 | }) | 568 | }) |
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index bebfc7398..0dfe6e4fe 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts | |||
@@ -57,6 +57,8 @@ function checkInitialConfig (data: CustomConfig) { | |||
57 | expect(data.transcoding.resolutions['480p']).to.be.true | 57 | expect(data.transcoding.resolutions['480p']).to.be.true |
58 | expect(data.transcoding.resolutions['720p']).to.be.true | 58 | expect(data.transcoding.resolutions['720p']).to.be.true |
59 | expect(data.transcoding.resolutions['1080p']).to.be.true | 59 | expect(data.transcoding.resolutions['1080p']).to.be.true |
60 | expect(data.transcoding.hls.enabled).to.be.true | ||
61 | |||
60 | expect(data.import.videos.http.enabled).to.be.true | 62 | expect(data.import.videos.http.enabled).to.be.true |
61 | expect(data.import.videos.torrent.enabled).to.be.true | 63 | expect(data.import.videos.torrent.enabled).to.be.true |
62 | } | 64 | } |
@@ -95,6 +97,7 @@ function checkUpdatedConfig (data: CustomConfig) { | |||
95 | expect(data.transcoding.resolutions['480p']).to.be.true | 97 | expect(data.transcoding.resolutions['480p']).to.be.true |
96 | expect(data.transcoding.resolutions['720p']).to.be.false | 98 | expect(data.transcoding.resolutions['720p']).to.be.false |
97 | expect(data.transcoding.resolutions['1080p']).to.be.false | 99 | expect(data.transcoding.resolutions['1080p']).to.be.false |
100 | expect(data.transcoding.hls.enabled).to.be.false | ||
98 | 101 | ||
99 | expect(data.import.videos.http.enabled).to.be.false | 102 | expect(data.import.videos.http.enabled).to.be.false |
100 | expect(data.import.videos.torrent.enabled).to.be.false | 103 | expect(data.import.videos.torrent.enabled).to.be.false |
@@ -205,6 +208,9 @@ describe('Test config', function () { | |||
205 | '480p': true, | 208 | '480p': true, |
206 | '720p': false, | 209 | '720p': false, |
207 | '1080p': false | 210 | '1080p': false |
211 | }, | ||
212 | hls: { | ||
213 | enabled: false | ||
208 | } | 214 | } |
209 | }, | 215 | }, |
210 | import: { | 216 | import: { |
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index b0fc5d293..ad4c87c73 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts | |||
@@ -348,6 +348,7 @@ describe('Test follows', function () { | |||
348 | }, | 348 | }, |
349 | isLocal, | 349 | isLocal, |
350 | commentsEnabled: true, | 350 | commentsEnabled: true, |
351 | downloadEnabled: true, | ||
351 | duration: 5, | 352 | duration: 5, |
352 | tags: [ 'tag1', 'tag2', 'tag3' ], | 353 | tags: [ 'tag1', 'tag2', 'tag3' ], |
353 | privacy: VideoPrivacy.PUBLIC, | 354 | privacy: VideoPrivacy.PUBLIC, |
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index cd7baadad..cd5acbe16 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts | |||
@@ -76,6 +76,7 @@ describe('Test handle downs', function () { | |||
76 | tags: [ 'tag1p1', 'tag2p1' ], | 76 | tags: [ 'tag1p1', 'tag2p1' ], |
77 | privacy: VideoPrivacy.PUBLIC, | 77 | privacy: VideoPrivacy.PUBLIC, |
78 | commentsEnabled: true, | 78 | commentsEnabled: true, |
79 | downloadEnabled: true, | ||
79 | channel: { | 80 | channel: { |
80 | name: 'root_channel', | 81 | name: 'root_channel', |
81 | displayName: 'Main root channel', | 82 | displayName: 'Main root channel', |
diff --git a/server/tests/api/server/redundancy.ts b/server/tests/api/server/redundancy.ts deleted file mode 100644 index 8053d0491..000000000 --- a/server/tests/api/server/redundancy.ts +++ /dev/null | |||
@@ -1,479 +0,0 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import 'mocha' | ||
5 | import { VideoDetails } from '../../../../shared/models/videos' | ||
6 | import { | ||
7 | doubleFollow, | ||
8 | flushAndRunMultipleServers, | ||
9 | getFollowingListPaginationAndSort, | ||
10 | getVideo, | ||
11 | immutableAssign, | ||
12 | killallServers, makeGetRequest, | ||
13 | root, | ||
14 | ServerInfo, | ||
15 | setAccessTokensToServers, unfollow, | ||
16 | uploadVideo, | ||
17 | viewVideo, | ||
18 | wait, | ||
19 | waitUntilLog, | ||
20 | checkVideoFilesWereRemoved, removeVideo | ||
21 | } from '../../../../shared/utils' | ||
22 | import { waitJobs } from '../../../../shared/utils/server/jobs' | ||
23 | import * as magnetUtil from 'magnet-uri' | ||
24 | import { updateRedundancy } from '../../../../shared/utils/server/redundancy' | ||
25 | import { ActorFollow } from '../../../../shared/models/actors' | ||
26 | import { readdir } from 'fs-extra' | ||
27 | import { join } from 'path' | ||
28 | import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy' | ||
29 | import { getStats } from '../../../../shared/utils/server/stats' | ||
30 | import { ServerStats } from '../../../../shared/models/server/server-stats.model' | ||
31 | |||
32 | const expect = chai.expect | ||
33 | |||
34 | let servers: ServerInfo[] = [] | ||
35 | let video1Server2UUID: string | ||
36 | |||
37 | function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) { | ||
38 | const parsed = magnetUtil.decode(file.magnetUri) | ||
39 | |||
40 | for (const ws of baseWebseeds) { | ||
41 | const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) | ||
42 | expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined | ||
43 | } | ||
44 | |||
45 | expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length) | ||
46 | } | ||
47 | |||
48 | async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { | ||
49 | const config = { | ||
50 | redundancy: { | ||
51 | videos: { | ||
52 | check_interval: '5 seconds', | ||
53 | strategies: [ | ||
54 | immutableAssign({ | ||
55 | min_lifetime: '1 hour', | ||
56 | strategy: strategy, | ||
57 | size: '100KB' | ||
58 | }, additionalParams) | ||
59 | ] | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | servers = await flushAndRunMultipleServers(3, config) | ||
64 | |||
65 | // Get the access tokens | ||
66 | await setAccessTokensToServers(servers) | ||
67 | |||
68 | { | ||
69 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 1 server 2' }) | ||
70 | video1Server2UUID = res.body.video.uuid | ||
71 | |||
72 | await viewVideo(servers[ 1 ].url, video1Server2UUID) | ||
73 | } | ||
74 | |||
75 | await waitJobs(servers) | ||
76 | |||
77 | // Server 1 and server 2 follow each other | ||
78 | await doubleFollow(servers[ 0 ], servers[ 1 ]) | ||
79 | // Server 1 and server 3 follow each other | ||
80 | await doubleFollow(servers[ 0 ], servers[ 2 ]) | ||
81 | // Server 2 and server 3 follow each other | ||
82 | await doubleFollow(servers[ 1 ], servers[ 2 ]) | ||
83 | |||
84 | await waitJobs(servers) | ||
85 | } | ||
86 | |||
87 | async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: string) { | ||
88 | if (!videoUUID) videoUUID = video1Server2UUID | ||
89 | |||
90 | const webseeds = [ | ||
91 | 'http://localhost:9002/static/webseed/' + videoUUID | ||
92 | ] | ||
93 | |||
94 | for (const server of servers) { | ||
95 | { | ||
96 | const res = await getVideo(server.url, videoUUID) | ||
97 | |||
98 | const video: VideoDetails = res.body | ||
99 | for (const f of video.files) { | ||
100 | checkMagnetWebseeds(f, webseeds, server) | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) { | ||
107 | const res = await getStats(servers[0].url) | ||
108 | const data: ServerStats = res.body | ||
109 | |||
110 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
111 | const stat = data.videosRedundancy[0] | ||
112 | |||
113 | expect(stat.strategy).to.equal(strategy) | ||
114 | expect(stat.totalSize).to.equal(102400) | ||
115 | expect(stat.totalUsed).to.be.at.least(1).and.below(102401) | ||
116 | expect(stat.totalVideoFiles).to.equal(4) | ||
117 | expect(stat.totalVideos).to.equal(1) | ||
118 | } | ||
119 | |||
120 | async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) { | ||
121 | const res = await getStats(servers[0].url) | ||
122 | const data: ServerStats = res.body | ||
123 | |||
124 | expect(data.videosRedundancy).to.have.lengthOf(1) | ||
125 | |||
126 | const stat = data.videosRedundancy[0] | ||
127 | expect(stat.strategy).to.equal(strategy) | ||
128 | expect(stat.totalSize).to.equal(102400) | ||
129 | expect(stat.totalUsed).to.equal(0) | ||
130 | expect(stat.totalVideoFiles).to.equal(0) | ||
131 | expect(stat.totalVideos).to.equal(0) | ||
132 | } | ||
133 | |||
134 | async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: string) { | ||
135 | if (!videoUUID) videoUUID = video1Server2UUID | ||
136 | |||
137 | const webseeds = [ | ||
138 | 'http://localhost:9001/static/webseed/' + videoUUID, | ||
139 | 'http://localhost:9002/static/webseed/' + videoUUID | ||
140 | ] | ||
141 | |||
142 | for (const server of servers) { | ||
143 | const res = await getVideo(server.url, videoUUID) | ||
144 | |||
145 | const video: VideoDetails = res.body | ||
146 | |||
147 | for (const file of video.files) { | ||
148 | checkMagnetWebseeds(file, webseeds, server) | ||
149 | |||
150 | // Only servers 1 and 2 have the video | ||
151 | if (server.serverNumber !== 3) { | ||
152 | await makeGetRequest({ | ||
153 | url: server.url, | ||
154 | statusCodeExpected: 200, | ||
155 | path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, | ||
156 | contentType: null | ||
157 | }) | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | |||
162 | for (const directory of [ 'test1', 'test2' ]) { | ||
163 | const files = await readdir(join(root(), directory, 'videos')) | ||
164 | expect(files).to.have.length.at.least(4) | ||
165 | |||
166 | for (const resolution of [ 240, 360, 480, 720 ]) { | ||
167 | expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | async function enableRedundancyOnServer1 () { | ||
173 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) | ||
174 | |||
175 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') | ||
176 | const follows: ActorFollow[] = res.body.data | ||
177 | const server2 = follows.find(f => f.following.host === 'localhost:9002') | ||
178 | const server3 = follows.find(f => f.following.host === 'localhost:9003') | ||
179 | |||
180 | expect(server3).to.not.be.undefined | ||
181 | expect(server3.following.hostRedundancyAllowed).to.be.false | ||
182 | |||
183 | expect(server2).to.not.be.undefined | ||
184 | expect(server2.following.hostRedundancyAllowed).to.be.true | ||
185 | } | ||
186 | |||
187 | async function disableRedundancyOnServer1 () { | ||
188 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false) | ||
189 | |||
190 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') | ||
191 | const follows: ActorFollow[] = res.body.data | ||
192 | const server2 = follows.find(f => f.following.host === 'localhost:9002') | ||
193 | const server3 = follows.find(f => f.following.host === 'localhost:9003') | ||
194 | |||
195 | expect(server3).to.not.be.undefined | ||
196 | expect(server3.following.hostRedundancyAllowed).to.be.false | ||
197 | |||
198 | expect(server2).to.not.be.undefined | ||
199 | expect(server2.following.hostRedundancyAllowed).to.be.false | ||
200 | } | ||
201 | |||
202 | async function cleanServers () { | ||
203 | killallServers(servers) | ||
204 | } | ||
205 | |||
206 | describe('Test videos redundancy', function () { | ||
207 | |||
208 | describe('With most-views strategy', function () { | ||
209 | const strategy = 'most-views' | ||
210 | |||
211 | before(function () { | ||
212 | this.timeout(120000) | ||
213 | |||
214 | return runServers(strategy) | ||
215 | }) | ||
216 | |||
217 | it('Should have 1 webseed on the first video', async function () { | ||
218 | await check1WebSeed(strategy) | ||
219 | await checkStatsWith1Webseed(strategy) | ||
220 | }) | ||
221 | |||
222 | it('Should enable redundancy on server 1', function () { | ||
223 | return enableRedundancyOnServer1() | ||
224 | }) | ||
225 | |||
226 | it('Should have 2 webseed on the first video', async function () { | ||
227 | this.timeout(40000) | ||
228 | |||
229 | await waitJobs(servers) | ||
230 | await waitUntilLog(servers[0], 'Duplicated ', 4) | ||
231 | await waitJobs(servers) | ||
232 | |||
233 | await check2Webseeds(strategy) | ||
234 | await checkStatsWith2Webseed(strategy) | ||
235 | }) | ||
236 | |||
237 | it('Should undo redundancy on server 1 and remove duplicated videos', async function () { | ||
238 | this.timeout(40000) | ||
239 | |||
240 | await disableRedundancyOnServer1() | ||
241 | |||
242 | await waitJobs(servers) | ||
243 | await wait(5000) | ||
244 | |||
245 | await check1WebSeed(strategy) | ||
246 | |||
247 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) | ||
248 | }) | ||
249 | |||
250 | after(function () { | ||
251 | return cleanServers() | ||
252 | }) | ||
253 | }) | ||
254 | |||
255 | describe('With trending strategy', function () { | ||
256 | const strategy = 'trending' | ||
257 | |||
258 | before(function () { | ||
259 | this.timeout(120000) | ||
260 | |||
261 | return runServers(strategy) | ||
262 | }) | ||
263 | |||
264 | it('Should have 1 webseed on the first video', async function () { | ||
265 | await check1WebSeed(strategy) | ||
266 | await checkStatsWith1Webseed(strategy) | ||
267 | }) | ||
268 | |||
269 | it('Should enable redundancy on server 1', function () { | ||
270 | return enableRedundancyOnServer1() | ||
271 | }) | ||
272 | |||
273 | it('Should have 2 webseed on the first video', async function () { | ||
274 | this.timeout(40000) | ||
275 | |||
276 | await waitJobs(servers) | ||
277 | await waitUntilLog(servers[0], 'Duplicated ', 4) | ||
278 | await waitJobs(servers) | ||
279 | |||
280 | await check2Webseeds(strategy) | ||
281 | await checkStatsWith2Webseed(strategy) | ||
282 | }) | ||
283 | |||
284 | it('Should unfollow on server 1 and remove duplicated videos', async function () { | ||
285 | this.timeout(40000) | ||
286 | |||
287 | await unfollow(servers[0].url, servers[0].accessToken, servers[1]) | ||
288 | |||
289 | await waitJobs(servers) | ||
290 | await wait(5000) | ||
291 | |||
292 | await check1WebSeed(strategy) | ||
293 | |||
294 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) | ||
295 | }) | ||
296 | |||
297 | after(function () { | ||
298 | return cleanServers() | ||
299 | }) | ||
300 | }) | ||
301 | |||
302 | describe('With recently added strategy', function () { | ||
303 | const strategy = 'recently-added' | ||
304 | |||
305 | before(function () { | ||
306 | this.timeout(120000) | ||
307 | |||
308 | return runServers(strategy, { min_views: 3 }) | ||
309 | }) | ||
310 | |||
311 | it('Should have 1 webseed on the first video', async function () { | ||
312 | await check1WebSeed(strategy) | ||
313 | await checkStatsWith1Webseed(strategy) | ||
314 | }) | ||
315 | |||
316 | it('Should enable redundancy on server 1', function () { | ||
317 | return enableRedundancyOnServer1() | ||
318 | }) | ||
319 | |||
320 | it('Should still have 1 webseed on the first video', async function () { | ||
321 | this.timeout(40000) | ||
322 | |||
323 | await waitJobs(servers) | ||
324 | await wait(15000) | ||
325 | await waitJobs(servers) | ||
326 | |||
327 | await check1WebSeed(strategy) | ||
328 | await checkStatsWith1Webseed(strategy) | ||
329 | }) | ||
330 | |||
331 | it('Should view 2 times the first video to have > min_views config', async function () { | ||
332 | this.timeout(40000) | ||
333 | |||
334 | await viewVideo(servers[ 0 ].url, video1Server2UUID) | ||
335 | await viewVideo(servers[ 2 ].url, video1Server2UUID) | ||
336 | |||
337 | await wait(10000) | ||
338 | await waitJobs(servers) | ||
339 | }) | ||
340 | |||
341 | it('Should have 2 webseed on the first video', async function () { | ||
342 | this.timeout(40000) | ||
343 | |||
344 | await waitJobs(servers) | ||
345 | await waitUntilLog(servers[0], 'Duplicated ', 4) | ||
346 | await waitJobs(servers) | ||
347 | |||
348 | await check2Webseeds(strategy) | ||
349 | await checkStatsWith2Webseed(strategy) | ||
350 | }) | ||
351 | |||
352 | it('Should remove the video and the redundancy files', async function () { | ||
353 | this.timeout(20000) | ||
354 | |||
355 | await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID) | ||
356 | |||
357 | await waitJobs(servers) | ||
358 | |||
359 | for (const server of servers) { | ||
360 | await checkVideoFilesWereRemoved(video1Server2UUID, server.serverNumber) | ||
361 | } | ||
362 | }) | ||
363 | |||
364 | after(function () { | ||
365 | return cleanServers() | ||
366 | }) | ||
367 | }) | ||
368 | |||
369 | describe('Test expiration', function () { | ||
370 | const strategy = 'recently-added' | ||
371 | |||
372 | async function checkContains (servers: ServerInfo[], str: string) { | ||
373 | for (const server of servers) { | ||
374 | const res = await getVideo(server.url, video1Server2UUID) | ||
375 | const video: VideoDetails = res.body | ||
376 | |||
377 | for (const f of video.files) { | ||
378 | expect(f.magnetUri).to.contain(str) | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | async function checkNotContains (servers: ServerInfo[], str: string) { | ||
384 | for (const server of servers) { | ||
385 | const res = await getVideo(server.url, video1Server2UUID) | ||
386 | const video: VideoDetails = res.body | ||
387 | |||
388 | for (const f of video.files) { | ||
389 | expect(f.magnetUri).to.not.contain(str) | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
394 | before(async function () { | ||
395 | this.timeout(120000) | ||
396 | |||
397 | await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) | ||
398 | |||
399 | await enableRedundancyOnServer1() | ||
400 | }) | ||
401 | |||
402 | it('Should still have 2 webseeds after 10 seconds', async function () { | ||
403 | this.timeout(40000) | ||
404 | |||
405 | await wait(10000) | ||
406 | |||
407 | try { | ||
408 | await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001') | ||
409 | } catch { | ||
410 | // Maybe a server deleted a redundancy in the scheduler | ||
411 | await wait(2000) | ||
412 | |||
413 | await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001') | ||
414 | } | ||
415 | }) | ||
416 | |||
417 | it('Should stop server 1 and expire video redundancy', async function () { | ||
418 | this.timeout(40000) | ||
419 | |||
420 | killallServers([ servers[0] ]) | ||
421 | |||
422 | await wait(15000) | ||
423 | |||
424 | await checkNotContains([ servers[1], servers[2] ], 'http%3A%2F%2Flocalhost%3A9001') | ||
425 | }) | ||
426 | |||
427 | after(function () { | ||
428 | return killallServers([ servers[1], servers[2] ]) | ||
429 | }) | ||
430 | }) | ||
431 | |||
432 | describe('Test file replacement', function () { | ||
433 | let video2Server2UUID: string | ||
434 | const strategy = 'recently-added' | ||
435 | |||
436 | before(async function () { | ||
437 | this.timeout(120000) | ||
438 | |||
439 | await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) | ||
440 | |||
441 | await enableRedundancyOnServer1() | ||
442 | |||
443 | await waitJobs(servers) | ||
444 | await waitUntilLog(servers[0], 'Duplicated ', 4) | ||
445 | await waitJobs(servers) | ||
446 | |||
447 | await check2Webseeds(strategy) | ||
448 | await checkStatsWith2Webseed(strategy) | ||
449 | |||
450 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) | ||
451 | video2Server2UUID = res.body.video.uuid | ||
452 | }) | ||
453 | |||
454 | it('Should cache video 2 webseed on the first video', async function () { | ||
455 | this.timeout(120000) | ||
456 | |||
457 | await waitJobs(servers) | ||
458 | |||
459 | let checked = false | ||
460 | |||
461 | while (checked === false) { | ||
462 | await wait(1000) | ||
463 | |||
464 | try { | ||
465 | await check1WebSeed(strategy, video1Server2UUID) | ||
466 | await check2Webseeds(strategy, video2Server2UUID) | ||
467 | |||
468 | checked = true | ||
469 | } catch { | ||
470 | checked = false | ||
471 | } | ||
472 | } | ||
473 | }) | ||
474 | |||
475 | after(function () { | ||
476 | return cleanServers() | ||
477 | }) | ||
478 | }) | ||
479 | }) | ||
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts index d4c08c346..ee0fffd5a 100644 --- a/server/tests/api/server/reverse-proxy.ts +++ b/server/tests/api/server/reverse-proxy.ts | |||
@@ -95,7 +95,7 @@ describe('Test application behind a reverse proxy', function () { | |||
95 | it('Should rate limit logins', async function () { | 95 | it('Should rate limit logins', async function () { |
96 | const user = { username: 'root', password: 'fail' } | 96 | const user = { username: 'root', password: 'fail' } |
97 | 97 | ||
98 | for (let i = 0; i < 14; i++) { | 98 | for (let i = 0; i < 19; i++) { |
99 | await userLogin(server, user, 400) | 99 | await userLogin(server, user, 400) |
100 | } | 100 | } |
101 | 101 | ||
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts index 517b4e542..aaa6c62f7 100644 --- a/server/tests/api/server/stats.ts +++ b/server/tests/api/server/stats.ts | |||
@@ -39,7 +39,7 @@ describe('Test stats (excluding redundancy)', function () { | |||
39 | } | 39 | } |
40 | await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) | 40 | await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) |
41 | 41 | ||
42 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, {}) | 42 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' }) |
43 | const videoUUID = resVideo.body.video.uuid | 43 | const videoUUID = resVideo.body.video.uuid |
44 | 44 | ||
45 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') | 45 | await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') |
@@ -60,6 +60,7 @@ describe('Test stats (excluding redundancy)', function () { | |||
60 | expect(data.totalLocalVideoComments).to.equal(1) | 60 | expect(data.totalLocalVideoComments).to.equal(1) |
61 | expect(data.totalLocalVideos).to.equal(1) | 61 | expect(data.totalLocalVideos).to.equal(1) |
62 | expect(data.totalLocalVideoViews).to.equal(1) | 62 | expect(data.totalLocalVideoViews).to.equal(1) |
63 | expect(data.totalLocalVideoFilesSize).to.equal(218910) | ||
63 | expect(data.totalUsers).to.equal(2) | 64 | expect(data.totalUsers).to.equal(2) |
64 | expect(data.totalVideoComments).to.equal(1) | 65 | expect(data.totalVideoComments).to.equal(1) |
65 | expect(data.totalVideos).to.equal(1) | 66 | expect(data.totalVideos).to.equal(1) |
@@ -74,6 +75,7 @@ describe('Test stats (excluding redundancy)', function () { | |||
74 | expect(data.totalLocalVideoComments).to.equal(0) | 75 | expect(data.totalLocalVideoComments).to.equal(0) |
75 | expect(data.totalLocalVideos).to.equal(0) | 76 | expect(data.totalLocalVideos).to.equal(0) |
76 | expect(data.totalLocalVideoViews).to.equal(0) | 77 | expect(data.totalLocalVideoViews).to.equal(0) |
78 | expect(data.totalLocalVideoFilesSize).to.equal(0) | ||
77 | expect(data.totalUsers).to.equal(1) | 79 | expect(data.totalUsers).to.equal(1) |
78 | expect(data.totalVideoComments).to.equal(1) | 80 | expect(data.totalVideoComments).to.equal(1) |
79 | expect(data.totalVideos).to.equal(1) | 81 | expect(data.totalVideos).to.equal(1) |
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts index 5260d64cc..69e51677e 100644 --- a/server/tests/api/users/user-notifications.ts +++ b/server/tests/api/users/user-notifications.ts | |||
@@ -165,6 +165,8 @@ describe('Test users notifications', function () { | |||
165 | }) | 165 | }) |
166 | 166 | ||
167 | it('Should not send notifications if the user does not follow the video publisher', async function () { | 167 | it('Should not send notifications if the user does not follow the video publisher', async function () { |
168 | this.timeout(10000) | ||
169 | |||
168 | await uploadVideoByLocalAccount(servers) | 170 | await uploadVideoByLocalAccount(servers) |
169 | 171 | ||
170 | const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) | 172 | const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) |
@@ -644,6 +646,8 @@ describe('Test users notifications', function () { | |||
644 | }) | 646 | }) |
645 | 647 | ||
646 | it('Should not send a notification if transcoding is not enabled', async function () { | 648 | it('Should not send a notification if transcoding is not enabled', async function () { |
649 | this.timeout(10000) | ||
650 | |||
647 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | 651 | const { name, uuid } = await uploadVideoByLocalAccount(servers) |
648 | await waitJobs(servers) | 652 | await waitJobs(servers) |
649 | 653 | ||
@@ -717,6 +721,24 @@ describe('Test users notifications', function () { | |||
717 | await wait(6000) | 721 | await wait(6000) |
718 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') | 722 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') |
719 | }) | 723 | }) |
724 | |||
725 | it('Should not send a notification before the video is published', async function () { | ||
726 | this.timeout(20000) | ||
727 | |||
728 | let updateAt = new Date(new Date().getTime() + 100000) | ||
729 | |||
730 | const data = { | ||
731 | privacy: VideoPrivacy.PRIVATE, | ||
732 | scheduleUpdate: { | ||
733 | updateAt: updateAt.toISOString(), | ||
734 | privacy: VideoPrivacy.PUBLIC | ||
735 | } | ||
736 | } | ||
737 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
738 | |||
739 | await wait(6000) | ||
740 | await checkVideoIsPublished(baseParams, name, uuid, 'absence') | ||
741 | }) | ||
720 | }) | 742 | }) |
721 | 743 | ||
722 | describe('My video is imported', function () { | 744 | describe('My video is imported', function () { |
@@ -781,6 +803,8 @@ describe('Test users notifications', function () { | |||
781 | }) | 803 | }) |
782 | 804 | ||
783 | it('Should send a notification only to moderators when a user registers on the instance', async function () { | 805 | it('Should send a notification only to moderators when a user registers on the instance', async function () { |
806 | this.timeout(10000) | ||
807 | |||
784 | await registerUser(servers[0].url, 'user_45', 'password') | 808 | await registerUser(servers[0].url, 'user_45', 'password') |
785 | 809 | ||
786 | await waitJobs(servers) | 810 | await waitJobs(servers) |
@@ -849,6 +873,8 @@ describe('Test users notifications', function () { | |||
849 | }) | 873 | }) |
850 | 874 | ||
851 | it('Should notify when a local account is following one of our channel', async function () { | 875 | it('Should notify when a local account is following one of our channel', async function () { |
876 | this.timeout(10000) | ||
877 | |||
852 | await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001') | 878 | await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001') |
853 | 879 | ||
854 | await waitJobs(servers) | 880 | await waitJobs(servers) |
@@ -857,6 +883,8 @@ describe('Test users notifications', function () { | |||
857 | }) | 883 | }) |
858 | 884 | ||
859 | it('Should notify when a remote account is following one of our channel', async function () { | 885 | it('Should notify when a remote account is following one of our channel', async function () { |
886 | this.timeout(10000) | ||
887 | |||
860 | await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001') | 888 | await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001') |
861 | 889 | ||
862 | await waitJobs(servers) | 890 | await waitJobs(servers) |
@@ -926,6 +954,8 @@ describe('Test users notifications', function () { | |||
926 | }) | 954 | }) |
927 | 955 | ||
928 | it('Should not have notifications', async function () { | 956 | it('Should not have notifications', async function () { |
957 | this.timeout(10000) | ||
958 | |||
929 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | 959 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { |
930 | newVideoFromSubscription: UserNotificationSettingValue.NONE | 960 | newVideoFromSubscription: UserNotificationSettingValue.NONE |
931 | })) | 961 | })) |
@@ -943,6 +973,8 @@ describe('Test users notifications', function () { | |||
943 | }) | 973 | }) |
944 | 974 | ||
945 | it('Should only have web notifications', async function () { | 975 | it('Should only have web notifications', async function () { |
976 | this.timeout(10000) | ||
977 | |||
946 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | 978 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { |
947 | newVideoFromSubscription: UserNotificationSettingValue.WEB | 979 | newVideoFromSubscription: UserNotificationSettingValue.WEB |
948 | })) | 980 | })) |
@@ -967,6 +999,8 @@ describe('Test users notifications', function () { | |||
967 | }) | 999 | }) |
968 | 1000 | ||
969 | it('Should only have mail notifications', async function () { | 1001 | it('Should only have mail notifications', async function () { |
1002 | this.timeout(10000) | ||
1003 | |||
970 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | 1004 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { |
971 | newVideoFromSubscription: UserNotificationSettingValue.EMAIL | 1005 | newVideoFromSubscription: UserNotificationSettingValue.EMAIL |
972 | })) | 1006 | })) |
@@ -991,6 +1025,8 @@ describe('Test users notifications', function () { | |||
991 | }) | 1025 | }) |
992 | 1026 | ||
993 | it('Should have email and web notifications', async function () { | 1027 | it('Should have email and web notifications', async function () { |
1028 | this.timeout(10000) | ||
1029 | |||
994 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | 1030 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { |
995 | newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | 1031 | newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL |
996 | })) | 1032 | })) |
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index ad98ab1c7..c4465d541 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts | |||
@@ -501,6 +501,22 @@ describe('Test users', function () { | |||
501 | accessTokenUser = await userLogin(server, user) | 501 | accessTokenUser = await userLogin(server, user) |
502 | }) | 502 | }) |
503 | 503 | ||
504 | it('Should be able to update another user password', async function () { | ||
505 | await updateUser({ | ||
506 | url: server.url, | ||
507 | userId, | ||
508 | accessToken, | ||
509 | password: 'password updated' | ||
510 | }) | ||
511 | |||
512 | await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401) | ||
513 | |||
514 | await userLogin(server, user, 400) | ||
515 | |||
516 | user.password = 'password updated' | ||
517 | accessTokenUser = await userLogin(server, user) | ||
518 | }) | ||
519 | |||
504 | it('Should be able to list video blacklist by a moderator', async function () { | 520 | it('Should be able to list video blacklist by a moderator', async function () { |
505 | await getBlacklistedVideosList(server.url, accessTokenUser) | 521 | await getBlacklistedVideosList(server.url, accessTokenUser) |
506 | }) | 522 | }) |
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts index 9bdb78491..a501a80b2 100644 --- a/server/tests/api/videos/index.ts +++ b/server/tests/api/videos/index.ts | |||
@@ -3,12 +3,12 @@ import './services' | |||
3 | import './single-server' | 3 | import './single-server' |
4 | import './video-abuse' | 4 | import './video-abuse' |
5 | import './video-blacklist' | 5 | import './video-blacklist' |
6 | import './video-blacklist-management' | ||
7 | import './video-captions' | 6 | import './video-captions' |
8 | import './video-change-ownership' | 7 | import './video-change-ownership' |
9 | import './video-channels' | 8 | import './video-channels' |
10 | import './video-comments' | 9 | import './video-comments' |
11 | import './video-description' | 10 | import './video-description' |
11 | import './video-hls' | ||
12 | import './video-imports' | 12 | import './video-imports' |
13 | import './video-nsfw' | 13 | import './video-nsfw' |
14 | import './video-privacy' | 14 | import './video-privacy' |
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index 6c281e49e..1b471ba79 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts | |||
@@ -128,6 +128,7 @@ describe('Test multiple servers', function () { | |||
128 | tags: [ 'tag1p1', 'tag2p1' ], | 128 | tags: [ 'tag1p1', 'tag2p1' ], |
129 | privacy: VideoPrivacy.PUBLIC, | 129 | privacy: VideoPrivacy.PUBLIC, |
130 | commentsEnabled: true, | 130 | commentsEnabled: true, |
131 | downloadEnabled: true, | ||
131 | channel: { | 132 | channel: { |
132 | displayName: 'my channel', | 133 | displayName: 'my channel', |
133 | name: 'super_channel_name', | 134 | name: 'super_channel_name', |
@@ -199,6 +200,7 @@ describe('Test multiple servers', function () { | |||
199 | }, | 200 | }, |
200 | isLocal, | 201 | isLocal, |
201 | commentsEnabled: true, | 202 | commentsEnabled: true, |
203 | downloadEnabled: true, | ||
202 | duration: 5, | 204 | duration: 5, |
203 | tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], | 205 | tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ], |
204 | privacy: VideoPrivacy.PUBLIC, | 206 | privacy: VideoPrivacy.PUBLIC, |
@@ -307,6 +309,7 @@ describe('Test multiple servers', function () { | |||
307 | isLocal, | 309 | isLocal, |
308 | duration: 5, | 310 | duration: 5, |
309 | commentsEnabled: true, | 311 | commentsEnabled: true, |
312 | downloadEnabled: true, | ||
310 | tags: [ 'tag1p3' ], | 313 | tags: [ 'tag1p3' ], |
311 | privacy: VideoPrivacy.PUBLIC, | 314 | privacy: VideoPrivacy.PUBLIC, |
312 | channel: { | 315 | channel: { |
@@ -338,6 +341,7 @@ describe('Test multiple servers', function () { | |||
338 | host: 'localhost:9003' | 341 | host: 'localhost:9003' |
339 | }, | 342 | }, |
340 | commentsEnabled: true, | 343 | commentsEnabled: true, |
344 | downloadEnabled: true, | ||
341 | isLocal, | 345 | isLocal, |
342 | duration: 5, | 346 | duration: 5, |
343 | tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ], | 347 | tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ], |
@@ -655,6 +659,7 @@ describe('Test multiple servers', function () { | |||
655 | isLocal, | 659 | isLocal, |
656 | duration: 5, | 660 | duration: 5, |
657 | commentsEnabled: true, | 661 | commentsEnabled: true, |
662 | downloadEnabled: true, | ||
658 | tags: [ 'tag_up_1', 'tag_up_2' ], | 663 | tags: [ 'tag_up_1', 'tag_up_2' ], |
659 | privacy: VideoPrivacy.PUBLIC, | 664 | privacy: VideoPrivacy.PUBLIC, |
660 | channel: { | 665 | channel: { |
@@ -914,11 +919,12 @@ describe('Test multiple servers', function () { | |||
914 | } | 919 | } |
915 | }) | 920 | }) |
916 | 921 | ||
917 | it('Should disable comments', async function () { | 922 | it('Should disable comments and download', async function () { |
918 | this.timeout(20000) | 923 | this.timeout(20000) |
919 | 924 | ||
920 | const attributes = { | 925 | const attributes = { |
921 | commentsEnabled: false | 926 | commentsEnabled: false, |
927 | downloadEnabled: false | ||
922 | } | 928 | } |
923 | 929 | ||
924 | await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, attributes) | 930 | await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, attributes) |
@@ -928,6 +934,7 @@ describe('Test multiple servers', function () { | |||
928 | for (const server of servers) { | 934 | for (const server of servers) { |
929 | const res = await getVideo(server.url, videoUUID) | 935 | const res = await getVideo(server.url, videoUUID) |
930 | expect(res.body.commentsEnabled).to.be.false | 936 | expect(res.body.commentsEnabled).to.be.false |
937 | expect(res.body.downloadEnabled).to.be.false | ||
931 | 938 | ||
932 | const text = 'my super forbidden comment' | 939 | const text = 'my super forbidden comment' |
933 | await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409) | 940 | await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409) |
@@ -976,6 +983,7 @@ describe('Test multiple servers', function () { | |||
976 | isLocal, | 983 | isLocal, |
977 | duration: 5, | 984 | duration: 5, |
978 | commentsEnabled: false, | 985 | commentsEnabled: false, |
986 | downloadEnabled: false, | ||
979 | tags: [ ], | 987 | tags: [ ], |
980 | privacy: VideoPrivacy.PUBLIC, | 988 | privacy: VideoPrivacy.PUBLIC, |
981 | channel: { | 989 | channel: { |
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts index 069dec67c..cfdcbaf3f 100644 --- a/server/tests/api/videos/single-server.ts +++ b/server/tests/api/videos/single-server.ts | |||
@@ -55,6 +55,7 @@ describe('Test a single server', function () { | |||
55 | tags: [ 'tag1', 'tag2', 'tag3' ], | 55 | tags: [ 'tag1', 'tag2', 'tag3' ], |
56 | privacy: VideoPrivacy.PUBLIC, | 56 | privacy: VideoPrivacy.PUBLIC, |
57 | commentsEnabled: true, | 57 | commentsEnabled: true, |
58 | downloadEnabled: true, | ||
58 | channel: { | 59 | channel: { |
59 | displayName: 'Main root channel', | 60 | displayName: 'Main root channel', |
60 | name: 'root_channel', | 61 | name: 'root_channel', |
@@ -87,6 +88,7 @@ describe('Test a single server', function () { | |||
87 | privacy: VideoPrivacy.PUBLIC, | 88 | privacy: VideoPrivacy.PUBLIC, |
88 | duration: 5, | 89 | duration: 5, |
89 | commentsEnabled: false, | 90 | commentsEnabled: false, |
91 | downloadEnabled: false, | ||
90 | channel: { | 92 | channel: { |
91 | name: 'root_channel', | 93 | name: 'root_channel', |
92 | displayName: 'Main root channel', | 94 | displayName: 'Main root channel', |
@@ -356,6 +358,7 @@ describe('Test a single server', function () { | |||
356 | nsfw: false, | 358 | nsfw: false, |
357 | description: 'my super description updated', | 359 | description: 'my super description updated', |
358 | commentsEnabled: false, | 360 | commentsEnabled: false, |
361 | downloadEnabled: false, | ||
359 | tags: [ 'tagup1', 'tagup2' ] | 362 | tags: [ 'tagup1', 'tagup2' ] |
360 | } | 363 | } |
361 | await updateVideo(server.url, server.accessToken, videoId, attributes) | 364 | await updateVideo(server.url, server.accessToken, videoId, attributes) |
diff --git a/server/tests/api/videos/video-blacklist-management.ts b/server/tests/api/videos/video-blacklist-management.ts deleted file mode 100644 index 61411e30d..000000000 --- a/server/tests/api/videos/video-blacklist-management.ts +++ /dev/null | |||
@@ -1,192 +0,0 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import { orderBy } from 'lodash' | ||
5 | import 'mocha' | ||
6 | import { | ||
7 | addVideoToBlacklist, | ||
8 | flushAndRunMultipleServers, | ||
9 | getBlacklistedVideosList, | ||
10 | getMyVideos, | ||
11 | getSortedBlacklistedVideosList, | ||
12 | getVideosList, | ||
13 | killallServers, | ||
14 | removeVideoFromBlacklist, | ||
15 | ServerInfo, | ||
16 | setAccessTokensToServers, | ||
17 | updateVideoBlacklist, | ||
18 | uploadVideo | ||
19 | } from '../../../../shared/utils/index' | ||
20 | import { doubleFollow } from '../../../../shared/utils/server/follows' | ||
21 | import { waitJobs } from '../../../../shared/utils/server/jobs' | ||
22 | import { VideoAbuse } from '../../../../shared/models/videos' | ||
23 | |||
24 | const expect = chai.expect | ||
25 | |||
26 | describe('Test video blacklist management', function () { | ||
27 | let servers: ServerInfo[] = [] | ||
28 | let videoId: number | ||
29 | |||
30 | async function blacklistVideosOnServer (server: ServerInfo) { | ||
31 | const res = await getVideosList(server.url) | ||
32 | |||
33 | const videos = res.body.data | ||
34 | for (let video of videos) { | ||
35 | await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason') | ||
36 | } | ||
37 | } | ||
38 | |||
39 | before(async function () { | ||
40 | this.timeout(50000) | ||
41 | |||
42 | // Run servers | ||
43 | servers = await flushAndRunMultipleServers(2) | ||
44 | |||
45 | // Get the access tokens | ||
46 | await setAccessTokensToServers(servers) | ||
47 | |||
48 | // Server 1 and server 2 follow each other | ||
49 | await doubleFollow(servers[0], servers[1]) | ||
50 | |||
51 | // Upload 2 videos on server 2 | ||
52 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' }) | ||
53 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' }) | ||
54 | |||
55 | // Wait videos propagation, server 2 has transcoding enabled | ||
56 | await waitJobs(servers) | ||
57 | |||
58 | // Blacklist the two videos on server 1 | ||
59 | await blacklistVideosOnServer(servers[0]) | ||
60 | }) | ||
61 | |||
62 | describe('When listing blacklisted videos', function () { | ||
63 | it('Should display all the blacklisted videos', async function () { | ||
64 | const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken) | ||
65 | |||
66 | expect(res.body.total).to.equal(2) | ||
67 | |||
68 | const blacklistedVideos = res.body.data | ||
69 | expect(blacklistedVideos).to.be.an('array') | ||
70 | expect(blacklistedVideos.length).to.equal(2) | ||
71 | |||
72 | for (const blacklistedVideo of blacklistedVideos) { | ||
73 | expect(blacklistedVideo.reason).to.equal('super reason') | ||
74 | videoId = blacklistedVideo.video.id | ||
75 | } | ||
76 | }) | ||
77 | |||
78 | it('Should get the correct sort when sorting by descending id', async function () { | ||
79 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id') | ||
80 | expect(res.body.total).to.equal(2) | ||
81 | |||
82 | const blacklistedVideos = res.body.data | ||
83 | expect(blacklistedVideos).to.be.an('array') | ||
84 | expect(blacklistedVideos.length).to.equal(2) | ||
85 | |||
86 | const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ]) | ||
87 | |||
88 | expect(blacklistedVideos).to.deep.equal(result) | ||
89 | }) | ||
90 | |||
91 | it('Should get the correct sort when sorting by descending video name', async function () { | ||
92 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
93 | expect(res.body.total).to.equal(2) | ||
94 | |||
95 | const blacklistedVideos = res.body.data | ||
96 | expect(blacklistedVideos).to.be.an('array') | ||
97 | expect(blacklistedVideos.length).to.equal(2) | ||
98 | |||
99 | const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ]) | ||
100 | |||
101 | expect(blacklistedVideos).to.deep.equal(result) | ||
102 | }) | ||
103 | |||
104 | it('Should get the correct sort when sorting by ascending creation date', async function () { | ||
105 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') | ||
106 | expect(res.body.total).to.equal(2) | ||
107 | |||
108 | const blacklistedVideos = res.body.data | ||
109 | expect(blacklistedVideos).to.be.an('array') | ||
110 | expect(blacklistedVideos.length).to.equal(2) | ||
111 | |||
112 | const result = orderBy(res.body.data, [ 'createdAt' ]) | ||
113 | |||
114 | expect(blacklistedVideos).to.deep.equal(result) | ||
115 | }) | ||
116 | }) | ||
117 | |||
118 | describe('When updating blacklisted videos', function () { | ||
119 | it('Should change the reason', async function () { | ||
120 | await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated') | ||
121 | |||
122 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
123 | const video = res.body.data.find(b => b.video.id === videoId) | ||
124 | |||
125 | expect(video.reason).to.equal('my super reason updated') | ||
126 | }) | ||
127 | }) | ||
128 | |||
129 | describe('When listing my videos', function () { | ||
130 | it('Should display blacklisted videos', async function () { | ||
131 | await blacklistVideosOnServer(servers[1]) | ||
132 | |||
133 | const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5) | ||
134 | |||
135 | expect(res.body.total).to.equal(2) | ||
136 | expect(res.body.data).to.have.lengthOf(2) | ||
137 | |||
138 | for (const video of res.body.data) { | ||
139 | expect(video.blacklisted).to.be.true | ||
140 | expect(video.blacklistedReason).to.equal('super reason') | ||
141 | } | ||
142 | }) | ||
143 | }) | ||
144 | |||
145 | describe('When removing a blacklisted video', function () { | ||
146 | let videoToRemove: VideoAbuse | ||
147 | let blacklist = [] | ||
148 | |||
149 | it('Should not have any video in videos list on server 1', async function () { | ||
150 | const res = await getVideosList(servers[0].url) | ||
151 | expect(res.body.total).to.equal(0) | ||
152 | expect(res.body.data).to.be.an('array') | ||
153 | expect(res.body.data.length).to.equal(0) | ||
154 | }) | ||
155 | |||
156 | it('Should remove a video from the blacklist on server 1', async function () { | ||
157 | // Get one video in the blacklist | ||
158 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
159 | videoToRemove = res.body.data[0] | ||
160 | blacklist = res.body.data.slice(1) | ||
161 | |||
162 | // Remove it | ||
163 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id) | ||
164 | }) | ||
165 | |||
166 | it('Should have the ex-blacklisted video in videos list on server 1', async function () { | ||
167 | const res = await getVideosList(servers[0].url) | ||
168 | expect(res.body.total).to.equal(1) | ||
169 | |||
170 | const videos = res.body.data | ||
171 | expect(videos).to.be.an('array') | ||
172 | expect(videos.length).to.equal(1) | ||
173 | |||
174 | expect(videos[0].name).to.equal(videoToRemove.video.name) | ||
175 | expect(videos[0].id).to.equal(videoToRemove.video.id) | ||
176 | }) | ||
177 | |||
178 | it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { | ||
179 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
180 | expect(res.body.total).to.equal(1) | ||
181 | |||
182 | const videos = res.body.data | ||
183 | expect(videos).to.be.an('array') | ||
184 | expect(videos.length).to.equal(1) | ||
185 | expect(videos).to.deep.equal(blacklist) | ||
186 | }) | ||
187 | }) | ||
188 | |||
189 | after(async function () { | ||
190 | killallServers(servers) | ||
191 | }) | ||
192 | }) | ||
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts index 1cce82d2a..d39ad63b4 100644 --- a/server/tests/api/videos/video-blacklist.ts +++ b/server/tests/api/videos/video-blacklist.ts | |||
@@ -1,24 +1,43 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | 1 | /* tslint:disable:no-unused-expression */ |
2 | 2 | ||
3 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
4 | import { orderBy } from 'lodash' | ||
4 | import 'mocha' | 5 | import 'mocha' |
5 | import { | 6 | import { |
6 | addVideoToBlacklist, | 7 | addVideoToBlacklist, |
7 | flushAndRunMultipleServers, | 8 | flushAndRunMultipleServers, |
9 | getBlacklistedVideosList, | ||
10 | getMyVideos, | ||
11 | getSortedBlacklistedVideosList, | ||
8 | getVideosList, | 12 | getVideosList, |
9 | killallServers, | 13 | killallServers, |
14 | removeVideoFromBlacklist, | ||
10 | searchVideo, | 15 | searchVideo, |
11 | ServerInfo, | 16 | ServerInfo, |
12 | setAccessTokensToServers, | 17 | setAccessTokensToServers, |
13 | uploadVideo | 18 | updateVideo, |
19 | updateVideoBlacklist, | ||
20 | uploadVideo, | ||
21 | viewVideo | ||
14 | } from '../../../../shared/utils/index' | 22 | } from '../../../../shared/utils/index' |
15 | import { doubleFollow } from '../../../../shared/utils/server/follows' | 23 | import { doubleFollow } from '../../../../shared/utils/server/follows' |
16 | import { waitJobs } from '../../../../shared/utils/server/jobs' | 24 | import { waitJobs } from '../../../../shared/utils/server/jobs' |
25 | import { VideoBlacklist } from '../../../../shared/models/videos' | ||
17 | 26 | ||
18 | const expect = chai.expect | 27 | const expect = chai.expect |
19 | 28 | ||
20 | describe('Test video blacklists', function () { | 29 | describe('Test video blacklist management', function () { |
21 | let servers: ServerInfo[] = [] | 30 | let servers: ServerInfo[] = [] |
31 | let videoId: number | ||
32 | |||
33 | async function blacklistVideosOnServer (server: ServerInfo) { | ||
34 | const res = await getVideosList(server.url) | ||
35 | |||
36 | const videos = res.body.data | ||
37 | for (let video of videos) { | ||
38 | await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason') | ||
39 | } | ||
40 | } | ||
22 | 41 | ||
23 | before(async function () { | 42 | before(async function () { |
24 | this.timeout(50000) | 43 | this.timeout(50000) |
@@ -32,58 +51,270 @@ describe('Test video blacklists', function () { | |||
32 | // Server 1 and server 2 follow each other | 51 | // Server 1 and server 2 follow each other |
33 | await doubleFollow(servers[0], servers[1]) | 52 | await doubleFollow(servers[0], servers[1]) |
34 | 53 | ||
35 | // Upload a video on server 2 | 54 | // Upload 2 videos on server 2 |
36 | const videoAttributes = { | 55 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' }) |
37 | name: 'my super name for server 2', | 56 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' }) |
38 | description: 'my super description for server 2' | ||
39 | } | ||
40 | await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) | ||
41 | 57 | ||
42 | // Wait videos propagation, server 2 has transcoding enabled | 58 | // Wait videos propagation, server 2 has transcoding enabled |
43 | await waitJobs(servers) | 59 | await waitJobs(servers) |
44 | 60 | ||
45 | const res = await getVideosList(servers[0].url) | 61 | // Blacklist the two videos on server 1 |
46 | const videos = res.body.data | 62 | await blacklistVideosOnServer(servers[0]) |
63 | }) | ||
64 | |||
65 | describe('When listing/searching videos', function () { | ||
47 | 66 | ||
48 | expect(videos.length).to.equal(1) | 67 | it('Should not have the video blacklisted in videos list/search on server 1', async function () { |
68 | { | ||
69 | const res = await getVideosList(servers[ 0 ].url) | ||
49 | 70 | ||
50 | servers[0].remoteVideo = videos.find(video => video.name === 'my super name for server 2') | 71 | expect(res.body.total).to.equal(0) |
72 | expect(res.body.data).to.be.an('array') | ||
73 | expect(res.body.data.length).to.equal(0) | ||
74 | } | ||
75 | |||
76 | { | ||
77 | const res = await searchVideo(servers[ 0 ].url, 'name') | ||
78 | |||
79 | expect(res.body.total).to.equal(0) | ||
80 | expect(res.body.data).to.be.an('array') | ||
81 | expect(res.body.data.length).to.equal(0) | ||
82 | } | ||
83 | }) | ||
84 | |||
85 | it('Should have the blacklisted video in videos list/search on server 2', async function () { | ||
86 | { | ||
87 | const res = await getVideosList(servers[ 1 ].url) | ||
88 | |||
89 | expect(res.body.total).to.equal(2) | ||
90 | expect(res.body.data).to.be.an('array') | ||
91 | expect(res.body.data.length).to.equal(2) | ||
92 | } | ||
93 | |||
94 | { | ||
95 | const res = await searchVideo(servers[ 1 ].url, 'video') | ||
96 | |||
97 | expect(res.body.total).to.equal(2) | ||
98 | expect(res.body.data).to.be.an('array') | ||
99 | expect(res.body.data.length).to.equal(2) | ||
100 | } | ||
101 | }) | ||
51 | }) | 102 | }) |
52 | 103 | ||
53 | it('Should blacklist a remote video on server 1', async function () { | 104 | describe('When listing blacklisted videos', function () { |
54 | await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id) | 105 | it('Should display all the blacklisted videos', async function () { |
106 | const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken) | ||
107 | |||
108 | expect(res.body.total).to.equal(2) | ||
109 | |||
110 | const blacklistedVideos = res.body.data | ||
111 | expect(blacklistedVideos).to.be.an('array') | ||
112 | expect(blacklistedVideos.length).to.equal(2) | ||
113 | |||
114 | for (const blacklistedVideo of blacklistedVideos) { | ||
115 | expect(blacklistedVideo.reason).to.equal('super reason') | ||
116 | videoId = blacklistedVideo.video.id | ||
117 | } | ||
118 | }) | ||
119 | |||
120 | it('Should get the correct sort when sorting by descending id', async function () { | ||
121 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id') | ||
122 | expect(res.body.total).to.equal(2) | ||
123 | |||
124 | const blacklistedVideos = res.body.data | ||
125 | expect(blacklistedVideos).to.be.an('array') | ||
126 | expect(blacklistedVideos.length).to.equal(2) | ||
127 | |||
128 | const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ]) | ||
129 | |||
130 | expect(blacklistedVideos).to.deep.equal(result) | ||
131 | }) | ||
132 | |||
133 | it('Should get the correct sort when sorting by descending video name', async function () { | ||
134 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
135 | expect(res.body.total).to.equal(2) | ||
136 | |||
137 | const blacklistedVideos = res.body.data | ||
138 | expect(blacklistedVideos).to.be.an('array') | ||
139 | expect(blacklistedVideos.length).to.equal(2) | ||
140 | |||
141 | const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ]) | ||
142 | |||
143 | expect(blacklistedVideos).to.deep.equal(result) | ||
144 | }) | ||
145 | |||
146 | it('Should get the correct sort when sorting by ascending creation date', async function () { | ||
147 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') | ||
148 | expect(res.body.total).to.equal(2) | ||
149 | |||
150 | const blacklistedVideos = res.body.data | ||
151 | expect(blacklistedVideos).to.be.an('array') | ||
152 | expect(blacklistedVideos.length).to.equal(2) | ||
153 | |||
154 | const result = orderBy(res.body.data, [ 'createdAt' ]) | ||
155 | |||
156 | expect(blacklistedVideos).to.deep.equal(result) | ||
157 | }) | ||
55 | }) | 158 | }) |
56 | 159 | ||
57 | it('Should not have the video blacklisted in videos list on server 1', async function () { | 160 | describe('When updating blacklisted videos', function () { |
58 | const res = await getVideosList(servers[0].url) | 161 | it('Should change the reason', async function () { |
162 | await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated') | ||
163 | |||
164 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
165 | const video = res.body.data.find(b => b.video.id === videoId) | ||
59 | 166 | ||
60 | expect(res.body.total).to.equal(0) | 167 | expect(video.reason).to.equal('my super reason updated') |
61 | expect(res.body.data).to.be.an('array') | 168 | }) |
62 | expect(res.body.data.length).to.equal(0) | ||
63 | }) | 169 | }) |
64 | 170 | ||
65 | it('Should not have the video blacklisted in videos search on server 1', async function () { | 171 | describe('When listing my videos', function () { |
66 | const res = await searchVideo(servers[0].url, 'name') | 172 | it('Should display blacklisted videos', async function () { |
173 | await blacklistVideosOnServer(servers[1]) | ||
174 | |||
175 | const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5) | ||
67 | 176 | ||
68 | expect(res.body.total).to.equal(0) | 177 | expect(res.body.total).to.equal(2) |
69 | expect(res.body.data).to.be.an('array') | 178 | expect(res.body.data).to.have.lengthOf(2) |
70 | expect(res.body.data.length).to.equal(0) | 179 | |
180 | for (const video of res.body.data) { | ||
181 | expect(video.blacklisted).to.be.true | ||
182 | expect(video.blacklistedReason).to.equal('super reason') | ||
183 | } | ||
184 | }) | ||
71 | }) | 185 | }) |
72 | 186 | ||
73 | it('Should have the blacklisted video in videos list on server 2', async function () { | 187 | describe('When removing a blacklisted video', function () { |
74 | const res = await getVideosList(servers[1].url) | 188 | let videoToRemove: VideoBlacklist |
189 | let blacklist = [] | ||
190 | |||
191 | it('Should not have any video in videos list on server 1', async function () { | ||
192 | const res = await getVideosList(servers[0].url) | ||
193 | expect(res.body.total).to.equal(0) | ||
194 | expect(res.body.data).to.be.an('array') | ||
195 | expect(res.body.data.length).to.equal(0) | ||
196 | }) | ||
197 | |||
198 | it('Should remove a video from the blacklist on server 1', async function () { | ||
199 | // Get one video in the blacklist | ||
200 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
201 | videoToRemove = res.body.data[0] | ||
202 | blacklist = res.body.data.slice(1) | ||
203 | |||
204 | // Remove it | ||
205 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id) | ||
206 | }) | ||
207 | |||
208 | it('Should have the ex-blacklisted video in videos list on server 1', async function () { | ||
209 | const res = await getVideosList(servers[0].url) | ||
210 | expect(res.body.total).to.equal(1) | ||
211 | |||
212 | const videos = res.body.data | ||
213 | expect(videos).to.be.an('array') | ||
214 | expect(videos.length).to.equal(1) | ||
215 | |||
216 | expect(videos[0].name).to.equal(videoToRemove.video.name) | ||
217 | expect(videos[0].id).to.equal(videoToRemove.video.id) | ||
218 | }) | ||
219 | |||
220 | it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { | ||
221 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') | ||
222 | expect(res.body.total).to.equal(1) | ||
75 | 223 | ||
76 | expect(res.body.total).to.equal(1) | 224 | const videos = res.body.data |
77 | expect(res.body.data).to.be.an('array') | 225 | expect(videos).to.be.an('array') |
78 | expect(res.body.data.length).to.equal(1) | 226 | expect(videos.length).to.equal(1) |
227 | expect(videos).to.deep.equal(blacklist) | ||
228 | }) | ||
79 | }) | 229 | }) |
80 | 230 | ||
81 | it('Should have the video blacklisted in videos search on server 2', async function () { | 231 | describe('When blacklisting local videos', function () { |
82 | const res = await searchVideo(servers[1].url, 'name') | 232 | let video3UUID: string |
233 | let video4UUID: string | ||
234 | |||
235 | before(async function () { | ||
236 | this.timeout(10000) | ||
237 | |||
238 | { | ||
239 | const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'Video 3' }) | ||
240 | video3UUID = res.body.video.uuid | ||
241 | } | ||
242 | { | ||
243 | const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'Video 4' }) | ||
244 | video4UUID = res.body.video.uuid | ||
245 | } | ||
246 | |||
247 | await waitJobs(servers) | ||
248 | }) | ||
249 | |||
250 | it('Should blacklist video 3 and keep it federated', async function () { | ||
251 | this.timeout(10000) | ||
252 | |||
253 | await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video3UUID, 'super reason', false) | ||
254 | |||
255 | await waitJobs(servers) | ||
256 | |||
257 | { | ||
258 | const res = await getVideosList(servers[ 0 ].url) | ||
259 | expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined | ||
260 | } | ||
261 | |||
262 | { | ||
263 | const res = await getVideosList(servers[ 1 ].url) | ||
264 | expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined | ||
265 | } | ||
266 | }) | ||
267 | |||
268 | it('Should unfederate the video', async function () { | ||
269 | this.timeout(10000) | ||
270 | |||
271 | await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, 'super reason', true) | ||
272 | |||
273 | await waitJobs(servers) | ||
274 | |||
275 | for (const server of servers) { | ||
276 | const res = await getVideosList(server.url) | ||
277 | expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined | ||
278 | } | ||
279 | }) | ||
280 | |||
281 | it('Should have the video unfederated even after an Update AP message', async function () { | ||
282 | this.timeout(10000) | ||
283 | |||
284 | await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, { description: 'super description' }) | ||
285 | |||
286 | await waitJobs(servers) | ||
287 | |||
288 | for (const server of servers) { | ||
289 | const res = await getVideosList(server.url) | ||
290 | expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined | ||
291 | } | ||
292 | }) | ||
293 | |||
294 | it('Should have the correct video blacklist unfederate attribute', async function () { | ||
295 | const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') | ||
296 | |||
297 | const blacklistedVideos: VideoBlacklist[] = res.body.data | ||
298 | const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID) | ||
299 | const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID) | ||
300 | |||
301 | expect(video3Blacklisted.unfederated).to.be.false | ||
302 | expect(video4Blacklisted.unfederated).to.be.true | ||
303 | }) | ||
304 | |||
305 | it('Should remove the video from blacklist and refederate the video', async function () { | ||
306 | this.timeout(10000) | ||
307 | |||
308 | await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID) | ||
309 | |||
310 | await waitJobs(servers) | ||
311 | |||
312 | for (const server of servers) { | ||
313 | const res = await getVideosList(server.url) | ||
314 | expect(res.body.data.find(v => v.uuid === video4UUID)).to.not.be.undefined | ||
315 | } | ||
316 | }) | ||
83 | 317 | ||
84 | expect(res.body.total).to.equal(1) | ||
85 | expect(res.body.data).to.be.an('array') | ||
86 | expect(res.body.data.length).to.equal(1) | ||
87 | }) | 318 | }) |
88 | 319 | ||
89 | after(async function () { | 320 | after(async function () { |
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts new file mode 100644 index 000000000..a1214bad1 --- /dev/null +++ b/server/tests/api/videos/video-hls.ts | |||
@@ -0,0 +1,139 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import 'mocha' | ||
5 | import { | ||
6 | checkDirectoryIsEmpty, | ||
7 | checkSegmentHash, | ||
8 | checkTmpIsEmpty, | ||
9 | doubleFollow, | ||
10 | flushAndRunMultipleServers, | ||
11 | flushTests, | ||
12 | getPlaylist, | ||
13 | getVideo, | ||
14 | killallServers, | ||
15 | removeVideo, | ||
16 | ServerInfo, | ||
17 | setAccessTokensToServers, | ||
18 | updateVideo, | ||
19 | uploadVideo, | ||
20 | waitJobs | ||
21 | } from '../../../../shared/utils' | ||
22 | import { VideoDetails } from '../../../../shared/models/videos' | ||
23 | import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type' | ||
24 | import { join } from 'path' | ||
25 | |||
26 | const expect = chai.expect | ||
27 | |||
28 | async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) { | ||
29 | const resolutions = [ 240, 360, 480, 720 ] | ||
30 | |||
31 | for (const server of servers) { | ||
32 | const res = await getVideo(server.url, videoUUID) | ||
33 | const videoDetails: VideoDetails = res.body | ||
34 | |||
35 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(1) | ||
36 | |||
37 | const hlsPlaylist = videoDetails.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) | ||
38 | expect(hlsPlaylist).to.not.be.undefined | ||
39 | |||
40 | { | ||
41 | const res2 = await getPlaylist(hlsPlaylist.playlistUrl) | ||
42 | |||
43 | const masterPlaylist = res2.text | ||
44 | |||
45 | expect(masterPlaylist).to.contain('#EXT-X-STREAM-INF:BANDWIDTH=55472,RESOLUTION=640x360,FRAME-RATE=25') | ||
46 | |||
47 | for (const resolution of resolutions) { | ||
48 | expect(masterPlaylist).to.contain(`${resolution}.m3u8`) | ||
49 | } | ||
50 | } | ||
51 | |||
52 | { | ||
53 | for (const resolution of resolutions) { | ||
54 | const res2 = await getPlaylist(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}.m3u8`) | ||
55 | |||
56 | const subPlaylist = res2.text | ||
57 | expect(subPlaylist).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | { | ||
62 | const baseUrl = 'http://localhost:9001/static/playlists/hls' | ||
63 | |||
64 | for (const resolution of resolutions) { | ||
65 | await checkSegmentHash(baseUrl, baseUrl, videoUUID, resolution, hlsPlaylist) | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | describe('Test HLS videos', function () { | ||
72 | let servers: ServerInfo[] = [] | ||
73 | let videoUUID = '' | ||
74 | |||
75 | before(async function () { | ||
76 | this.timeout(120000) | ||
77 | |||
78 | servers = await flushAndRunMultipleServers(2, { transcoding: { enabled: true, hls: { enabled: true } } }) | ||
79 | |||
80 | // Get the access tokens | ||
81 | await setAccessTokensToServers(servers) | ||
82 | |||
83 | // Server 1 and server 2 follow each other | ||
84 | await doubleFollow(servers[0], servers[1]) | ||
85 | }) | ||
86 | |||
87 | it('Should upload a video and transcode it to HLS', async function () { | ||
88 | this.timeout(120000) | ||
89 | |||
90 | { | ||
91 | const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video 1', fixture: 'video_short.webm' }) | ||
92 | videoUUID = res.body.video.uuid | ||
93 | } | ||
94 | |||
95 | await waitJobs(servers) | ||
96 | |||
97 | await checkHlsPlaylist(servers, videoUUID) | ||
98 | }) | ||
99 | |||
100 | it('Should update the video', async function () { | ||
101 | await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { name: 'video 1 updated' }) | ||
102 | |||
103 | await waitJobs(servers) | ||
104 | |||
105 | await checkHlsPlaylist(servers, videoUUID) | ||
106 | }) | ||
107 | |||
108 | it('Should delete the video', async function () { | ||
109 | await removeVideo(servers[0].url, servers[0].accessToken, videoUUID) | ||
110 | |||
111 | await waitJobs(servers) | ||
112 | |||
113 | for (const server of servers) { | ||
114 | await getVideo(server.url, videoUUID, 404) | ||
115 | } | ||
116 | }) | ||
117 | |||
118 | it('Should have the playlists/segment deleted from the disk', async function () { | ||
119 | for (const server of servers) { | ||
120 | await checkDirectoryIsEmpty(server, 'videos') | ||
121 | await checkDirectoryIsEmpty(server, join('playlists', 'hls')) | ||
122 | } | ||
123 | }) | ||
124 | |||
125 | it('Should have an empty tmp directory', async function () { | ||
126 | for (const server of servers) { | ||
127 | await checkTmpIsEmpty(server) | ||
128 | } | ||
129 | }) | ||
130 | |||
131 | after(async function () { | ||
132 | killallServers(servers) | ||
133 | |||
134 | // Keep the logs if the test failed | ||
135 | if (this['ok']) { | ||
136 | await flushTests() | ||
137 | } | ||
138 | }) | ||
139 | }) | ||