diff options
Diffstat (limited to 'server/tests')
27 files changed, 814 insertions, 116 deletions
diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts index 8bde54a40..364b53e0f 100644 --- a/server/tests/api/activitypub/security.ts +++ b/server/tests/api/activitypub/security.ts | |||
@@ -8,6 +8,8 @@ import { | |||
8 | cleanupTests, | 8 | cleanupTests, |
9 | closeAllSequelize, | 9 | closeAllSequelize, |
10 | flushAndRunMultipleServers, | 10 | flushAndRunMultipleServers, |
11 | killallServers, | ||
12 | reRunServer, | ||
11 | ServerInfo, | 13 | ServerInfo, |
12 | setActorField, | 14 | setActorField, |
13 | wait | 15 | wait |
@@ -20,21 +22,32 @@ import { buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activi | |||
20 | const expect = chai.expect | 22 | const expect = chai.expect |
21 | 23 | ||
22 | function setKeysOfServer (onServer: ServerInfo, ofServer: ServerInfo, publicKey: string, privateKey: string) { | 24 | function setKeysOfServer (onServer: ServerInfo, ofServer: ServerInfo, publicKey: string, privateKey: string) { |
25 | const url = 'http://localhost:' + ofServer.port + '/accounts/peertube' | ||
26 | |||
23 | return Promise.all([ | 27 | return Promise.all([ |
24 | setActorField(onServer.internalServerNumber, 'http://localhost:' + ofServer.port + '/accounts/peertube', 'publicKey', publicKey), | 28 | setActorField(onServer.internalServerNumber, url, 'publicKey', publicKey), |
25 | setActorField(onServer.internalServerNumber, 'http://localhost:' + ofServer.port + '/accounts/peertube', 'privateKey', privateKey) | 29 | setActorField(onServer.internalServerNumber, url, 'privateKey', privateKey) |
26 | ]) | 30 | ]) |
27 | } | 31 | } |
28 | 32 | ||
29 | function getAnnounceWithoutContext (server2: ServerInfo) { | 33 | function setUpdatedAtOfServer (onServer: ServerInfo, ofServer: ServerInfo, updatedAt: string) { |
34 | const url = 'http://localhost:' + ofServer.port + '/accounts/peertube' | ||
35 | |||
36 | return Promise.all([ | ||
37 | setActorField(onServer.internalServerNumber, url, 'createdAt', updatedAt), | ||
38 | setActorField(onServer.internalServerNumber, url, 'updatedAt', updatedAt) | ||
39 | ]) | ||
40 | } | ||
41 | |||
42 | function getAnnounceWithoutContext (server: ServerInfo) { | ||
30 | const json = require('./json/peertube/announce-without-context.json') | 43 | const json = require('./json/peertube/announce-without-context.json') |
31 | const result: typeof json = {} | 44 | const result: typeof json = {} |
32 | 45 | ||
33 | for (const key of Object.keys(json)) { | 46 | for (const key of Object.keys(json)) { |
34 | if (Array.isArray(json[key])) { | 47 | if (Array.isArray(json[key])) { |
35 | result[key] = json[key].map(v => v.replace(':9002', `:${server2.port}`)) | 48 | result[key] = json[key].map(v => v.replace(':9002', `:${server.port}`)) |
36 | } else { | 49 | } else { |
37 | result[key] = json[key].replace(':9002', `:${server2.port}`) | 50 | result[key] = json[key].replace(':9002', `:${server.port}`) |
38 | } | 51 | } |
39 | } | 52 | } |
40 | 53 | ||
@@ -64,7 +77,8 @@ describe('Test ActivityPub security', function () { | |||
64 | 77 | ||
65 | url = servers[0].url + '/inbox' | 78 | url = servers[0].url + '/inbox' |
66 | 79 | ||
67 | await setKeysOfServer(servers[0], servers[1], keys.publicKey, keys.privateKey) | 80 | await setKeysOfServer(servers[0], servers[1], keys.publicKey, null) |
81 | await setKeysOfServer(servers[1], servers[1], keys.publicKey, keys.privateKey) | ||
68 | 82 | ||
69 | const to = { url: 'http://localhost:' + servers[0].port + '/accounts/peertube' } | 83 | const to = { url: 'http://localhost:' + servers[0].port + '/accounts/peertube' } |
70 | const by = { url: 'http://localhost:' + servers[1].port + '/accounts/peertube', privateKey: keys.privateKey } | 84 | const by = { url: 'http://localhost:' + servers[1].port + '/accounts/peertube', privateKey: keys.privateKey } |
@@ -79,9 +93,12 @@ describe('Test ActivityPub security', function () { | |||
79 | Digest: buildDigest({ hello: 'coucou' }) | 93 | Digest: buildDigest({ hello: 'coucou' }) |
80 | } | 94 | } |
81 | 95 | ||
82 | const { response } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | 96 | try { |
83 | 97 | await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | |
84 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 98 | expect(true, 'Did not throw').to.be.false |
99 | } catch (err) { | ||
100 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
101 | } | ||
85 | }) | 102 | }) |
86 | 103 | ||
87 | it('Should fail with an invalid date', async function () { | 104 | it('Should fail with an invalid date', async function () { |
@@ -89,9 +106,12 @@ describe('Test ActivityPub security', function () { | |||
89 | const headers = buildGlobalHeaders(body) | 106 | const headers = buildGlobalHeaders(body) |
90 | headers['date'] = 'Wed, 21 Oct 2015 07:28:00 GMT' | 107 | headers['date'] = 'Wed, 21 Oct 2015 07:28:00 GMT' |
91 | 108 | ||
92 | const { response } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | 109 | try { |
93 | 110 | await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | |
94 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 111 | expect(true, 'Did not throw').to.be.false |
112 | } catch (err) { | ||
113 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
114 | } | ||
95 | }) | 115 | }) |
96 | 116 | ||
97 | it('Should fail with bad keys', async function () { | 117 | it('Should fail with bad keys', async function () { |
@@ -101,9 +121,12 @@ describe('Test ActivityPub security', function () { | |||
101 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) | 121 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) |
102 | const headers = buildGlobalHeaders(body) | 122 | const headers = buildGlobalHeaders(body) |
103 | 123 | ||
104 | const { response } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | 124 | try { |
105 | 125 | await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | |
106 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 126 | expect(true, 'Did not throw').to.be.false |
127 | } catch (err) { | ||
128 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
129 | } | ||
107 | }) | 130 | }) |
108 | 131 | ||
109 | it('Should reject requests without appropriate signed headers', async function () { | 132 | it('Should reject requests without appropriate signed headers', async function () { |
@@ -123,8 +146,12 @@ describe('Test ActivityPub security', function () { | |||
123 | for (const badHeaders of badHeadersMatrix) { | 146 | for (const badHeaders of badHeadersMatrix) { |
124 | signatureOptions.headers = badHeaders | 147 | signatureOptions.headers = badHeaders |
125 | 148 | ||
126 | const { response } = await makePOSTAPRequest(url, body, signatureOptions, headers) | 149 | try { |
127 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 150 | await makePOSTAPRequest(url, body, signatureOptions, headers) |
151 | expect(true, 'Did not throw').to.be.false | ||
152 | } catch (err) { | ||
153 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
154 | } | ||
128 | } | 155 | } |
129 | }) | 156 | }) |
130 | 157 | ||
@@ -132,27 +159,32 @@ describe('Test ActivityPub security', function () { | |||
132 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) | 159 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) |
133 | const headers = buildGlobalHeaders(body) | 160 | const headers = buildGlobalHeaders(body) |
134 | 161 | ||
135 | const { response } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | 162 | const { statusCode } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) |
136 | 163 | expect(statusCode).to.equal(HttpStatusCode.NO_CONTENT_204) | |
137 | expect(response.statusCode).to.equal(HttpStatusCode.NO_CONTENT_204) | ||
138 | }) | 164 | }) |
139 | 165 | ||
140 | it('Should refresh the actor keys', async function () { | 166 | it('Should refresh the actor keys', async function () { |
141 | this.timeout(20000) | 167 | this.timeout(20000) |
142 | 168 | ||
143 | // Wait refresh invalidation | ||
144 | await wait(10000) | ||
145 | |||
146 | // Update keys of server 2 to invalid keys | 169 | // Update keys of server 2 to invalid keys |
147 | // Server 1 should refresh the actor and fail | 170 | // Server 1 should refresh the actor and fail |
148 | await setKeysOfServer(servers[1], servers[1], invalidKeys.publicKey, invalidKeys.privateKey) | 171 | await setKeysOfServer(servers[1], servers[1], invalidKeys.publicKey, invalidKeys.privateKey) |
172 | await setUpdatedAtOfServer(servers[0], servers[1], '2015-07-17 22:00:00+00') | ||
173 | |||
174 | // Invalid peertube actor cache | ||
175 | killallServers([ servers[1] ]) | ||
176 | await reRunServer(servers[1]) | ||
149 | 177 | ||
150 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) | 178 | const body = activityPubContextify(getAnnounceWithoutContext(servers[1])) |
151 | const headers = buildGlobalHeaders(body) | 179 | const headers = buildGlobalHeaders(body) |
152 | 180 | ||
153 | const { response } = await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | 181 | try { |
154 | 182 | await makePOSTAPRequest(url, body, baseHttpSignature(), headers) | |
155 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 183 | expect(true, 'Did not throw').to.be.false |
184 | } catch (err) { | ||
185 | console.error(err) | ||
186 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
187 | } | ||
156 | }) | 188 | }) |
157 | }) | 189 | }) |
158 | 190 | ||
@@ -183,9 +215,12 @@ describe('Test ActivityPub security', function () { | |||
183 | 215 | ||
184 | const headers = buildGlobalHeaders(signedBody) | 216 | const headers = buildGlobalHeaders(signedBody) |
185 | 217 | ||
186 | const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | 218 | try { |
187 | 219 | await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | |
188 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 220 | expect(true, 'Did not throw').to.be.false |
221 | } catch (err) { | ||
222 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
223 | } | ||
189 | }) | 224 | }) |
190 | 225 | ||
191 | it('Should fail with an altered body', async function () { | 226 | it('Should fail with an altered body', async function () { |
@@ -204,9 +239,12 @@ describe('Test ActivityPub security', function () { | |||
204 | 239 | ||
205 | const headers = buildGlobalHeaders(signedBody) | 240 | const headers = buildGlobalHeaders(signedBody) |
206 | 241 | ||
207 | const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | 242 | try { |
208 | 243 | await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | |
209 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 244 | expect(true, 'Did not throw').to.be.false |
245 | } catch (err) { | ||
246 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
247 | } | ||
210 | }) | 248 | }) |
211 | 249 | ||
212 | it('Should succeed with a valid signature', async function () { | 250 | it('Should succeed with a valid signature', async function () { |
@@ -220,9 +258,8 @@ describe('Test ActivityPub security', function () { | |||
220 | 258 | ||
221 | const headers = buildGlobalHeaders(signedBody) | 259 | const headers = buildGlobalHeaders(signedBody) |
222 | 260 | ||
223 | const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | 261 | const { statusCode } = await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) |
224 | 262 | expect(statusCode).to.equal(HttpStatusCode.NO_CONTENT_204) | |
225 | expect(response.statusCode).to.equal(HttpStatusCode.NO_CONTENT_204) | ||
226 | }) | 263 | }) |
227 | 264 | ||
228 | it('Should refresh the actor keys', async function () { | 265 | it('Should refresh the actor keys', async function () { |
@@ -243,9 +280,12 @@ describe('Test ActivityPub security', function () { | |||
243 | 280 | ||
244 | const headers = buildGlobalHeaders(signedBody) | 281 | const headers = buildGlobalHeaders(signedBody) |
245 | 282 | ||
246 | const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | 283 | try { |
247 | 284 | await makePOSTAPRequest(url, signedBody, baseHttpSignature(), headers) | |
248 | expect(response.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | 285 | expect(true, 'Did not throw').to.be.false |
286 | } catch (err) { | ||
287 | expect(err.statusCode).to.equal(HttpStatusCode.FORBIDDEN_403) | ||
288 | } | ||
249 | }) | 289 | }) |
250 | }) | 290 | }) |
251 | 291 | ||
diff --git a/server/tests/api/check-params/user-notifications.ts b/server/tests/api/check-params/user-notifications.ts index 05a78b0ad..26d4423f9 100644 --- a/server/tests/api/check-params/user-notifications.ts +++ b/server/tests/api/check-params/user-notifications.ts | |||
@@ -176,7 +176,9 @@ describe('Test user notifications API validators', function () { | |||
176 | newInstanceFollower: UserNotificationSettingValue.WEB, | 176 | newInstanceFollower: UserNotificationSettingValue.WEB, |
177 | autoInstanceFollowing: UserNotificationSettingValue.WEB, | 177 | autoInstanceFollowing: UserNotificationSettingValue.WEB, |
178 | abuseNewMessage: UserNotificationSettingValue.WEB, | 178 | abuseNewMessage: UserNotificationSettingValue.WEB, |
179 | abuseStateChange: UserNotificationSettingValue.WEB | 179 | abuseStateChange: UserNotificationSettingValue.WEB, |
180 | newPeerTubeVersion: UserNotificationSettingValue.WEB, | ||
181 | newPluginVersion: UserNotificationSettingValue.WEB | ||
180 | } | 182 | } |
181 | 183 | ||
182 | it('Should fail with missing fields', async function () { | 184 | it('Should fail with missing fields', async function () { |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 0a13f5b67..2b03fde2d 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -241,7 +241,7 @@ describe('Test users API validators', function () { | |||
241 | }) | 241 | }) |
242 | 242 | ||
243 | it('Should succeed with no password on a server with smtp enabled', async function () { | 243 | it('Should succeed with no password on a server with smtp enabled', async function () { |
244 | this.timeout(10000) | 244 | this.timeout(20000) |
245 | 245 | ||
246 | killallServers([ server ]) | 246 | killallServers([ server ]) |
247 | 247 | ||
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts index 0dd436426..bc2e6192e 100644 --- a/server/tests/api/check-params/video-channels.ts +++ b/server/tests/api/check-params/video-channels.ts | |||
@@ -234,7 +234,8 @@ describe('Test video channels API validator', function () { | |||
234 | }) | 234 | }) |
235 | }) | 235 | }) |
236 | 236 | ||
237 | describe('When updating video channel avatar', function () { | 237 | describe('When updating video channel avatar/banner', function () { |
238 | const types = [ 'avatar', 'banner' ] | ||
238 | let path: string | 239 | let path: string |
239 | 240 | ||
240 | before(async function () { | 241 | before(async function () { |
@@ -242,48 +243,57 @@ describe('Test video channels API validator', function () { | |||
242 | }) | 243 | }) |
243 | 244 | ||
244 | it('Should fail with an incorrect input file', async function () { | 245 | it('Should fail with an incorrect input file', async function () { |
245 | const fields = {} | 246 | for (const type of types) { |
246 | const attaches = { | 247 | const fields = {} |
247 | avatarfile: join(__dirname, '..', '..', 'fixtures', 'video_short.mp4') | 248 | const attaches = { |
249 | [type + 'file']: join(__dirname, '..', '..', 'fixtures', 'video_short.mp4') | ||
250 | } | ||
251 | |||
252 | await makeUploadRequest({ url: server.url, path: `${path}/${type}/pick`, token: server.accessToken, fields, attaches }) | ||
248 | } | 253 | } |
249 | await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) | ||
250 | }) | 254 | }) |
251 | 255 | ||
252 | it('Should fail with a big file', async function () { | 256 | it('Should fail with a big file', async function () { |
253 | const fields = {} | 257 | for (const type of types) { |
254 | const attaches = { | 258 | const fields = {} |
255 | avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') | 259 | const attaches = { |
260 | [type + 'file']: join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') | ||
261 | } | ||
262 | await makeUploadRequest({ url: server.url, path: `${path}/${type}/pick`, token: server.accessToken, fields, attaches }) | ||
256 | } | 263 | } |
257 | await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) | ||
258 | }) | 264 | }) |
259 | 265 | ||
260 | it('Should fail with an unauthenticated user', async function () { | 266 | it('Should fail with an unauthenticated user', async function () { |
261 | const fields = {} | 267 | for (const type of types) { |
262 | const attaches = { | 268 | const fields = {} |
263 | avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png') | 269 | const attaches = { |
270 | [type + 'file']: join(__dirname, '..', '..', 'fixtures', 'avatar.png') | ||
271 | } | ||
272 | await makeUploadRequest({ | ||
273 | url: server.url, | ||
274 | path: `${path}/${type}/pick`, | ||
275 | fields, | ||
276 | attaches, | ||
277 | statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401 | ||
278 | }) | ||
264 | } | 279 | } |
265 | await makeUploadRequest({ | ||
266 | url: server.url, | ||
267 | path: path + '/avatar/pick', | ||
268 | fields, | ||
269 | attaches, | ||
270 | statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401 | ||
271 | }) | ||
272 | }) | 280 | }) |
273 | 281 | ||
274 | it('Should succeed with the correct params', async function () { | 282 | it('Should succeed with the correct params', async function () { |
275 | const fields = {} | 283 | for (const type of types) { |
276 | const attaches = { | 284 | const fields = {} |
277 | avatarfile: join(__dirname, '..', '..', 'fixtures', 'avatar.png') | 285 | const attaches = { |
286 | [type + 'file']: join(__dirname, '..', '..', 'fixtures', 'avatar.png') | ||
287 | } | ||
288 | await makeUploadRequest({ | ||
289 | url: server.url, | ||
290 | path: `${path}/${type}/pick`, | ||
291 | token: server.accessToken, | ||
292 | fields, | ||
293 | attaches, | ||
294 | statusCodeExpected: HttpStatusCode.OK_200 | ||
295 | }) | ||
278 | } | 296 | } |
279 | await makeUploadRequest({ | ||
280 | url: server.url, | ||
281 | path: path + '/avatar/pick', | ||
282 | token: server.accessToken, | ||
283 | fields, | ||
284 | attaches, | ||
285 | statusCodeExpected: HttpStatusCode.OK_200 | ||
286 | }) | ||
287 | }) | 297 | }) |
288 | }) | 298 | }) |
289 | 299 | ||
diff --git a/server/tests/api/notifications/admin-notifications.ts b/server/tests/api/notifications/admin-notifications.ts new file mode 100644 index 000000000..e07327d74 --- /dev/null +++ b/server/tests/api/notifications/admin-notifications.ts | |||
@@ -0,0 +1,165 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import { expect } from 'chai' | ||
5 | import { MockJoinPeerTubeVersions } from '@shared/extra-utils/mock-servers/joinpeertube-versions' | ||
6 | import { cleanupTests, installPlugin, setPluginLatestVersion, setPluginVersion, wait } from '../../../../shared/extra-utils' | ||
7 | import { ServerInfo } from '../../../../shared/extra-utils/index' | ||
8 | import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' | ||
9 | import { | ||
10 | CheckerBaseParams, | ||
11 | checkNewPeerTubeVersion, | ||
12 | checkNewPluginVersion, | ||
13 | prepareNotificationsTest | ||
14 | } from '../../../../shared/extra-utils/users/user-notifications' | ||
15 | import { UserNotification, UserNotificationType } from '../../../../shared/models/users' | ||
16 | import { PluginType } from '@shared/models' | ||
17 | |||
18 | describe('Test admin notifications', function () { | ||
19 | let server: ServerInfo | ||
20 | let userNotifications: UserNotification[] = [] | ||
21 | let adminNotifications: UserNotification[] = [] | ||
22 | let emails: object[] = [] | ||
23 | let baseParams: CheckerBaseParams | ||
24 | let joinPeerTubeServer: MockJoinPeerTubeVersions | ||
25 | |||
26 | before(async function () { | ||
27 | this.timeout(120000) | ||
28 | |||
29 | const config = { | ||
30 | peertube: { | ||
31 | check_latest_version: { | ||
32 | enabled: true, | ||
33 | url: 'http://localhost:42102/versions.json' | ||
34 | } | ||
35 | }, | ||
36 | plugins: { | ||
37 | index: { | ||
38 | enabled: true, | ||
39 | check_latest_versions_interval: '5 seconds' | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
44 | const res = await prepareNotificationsTest(1, config) | ||
45 | emails = res.emails | ||
46 | server = res.servers[0] | ||
47 | |||
48 | userNotifications = res.userNotifications | ||
49 | adminNotifications = res.adminNotifications | ||
50 | |||
51 | baseParams = { | ||
52 | server: server, | ||
53 | emails, | ||
54 | socketNotifications: adminNotifications, | ||
55 | token: server.accessToken | ||
56 | } | ||
57 | |||
58 | await installPlugin({ | ||
59 | url: server.url, | ||
60 | accessToken: server.accessToken, | ||
61 | npmName: 'peertube-plugin-hello-world' | ||
62 | }) | ||
63 | |||
64 | await installPlugin({ | ||
65 | url: server.url, | ||
66 | accessToken: server.accessToken, | ||
67 | npmName: 'peertube-theme-background-red' | ||
68 | }) | ||
69 | |||
70 | joinPeerTubeServer = new MockJoinPeerTubeVersions() | ||
71 | await joinPeerTubeServer.initialize() | ||
72 | }) | ||
73 | |||
74 | describe('Latest PeerTube version notification', function () { | ||
75 | |||
76 | it('Should not send a notification to admins if there is not a new version', async function () { | ||
77 | this.timeout(30000) | ||
78 | |||
79 | joinPeerTubeServer.setLatestVersion('1.4.2') | ||
80 | |||
81 | await wait(3000) | ||
82 | await checkNewPeerTubeVersion(baseParams, '1.4.2', 'absence') | ||
83 | }) | ||
84 | |||
85 | it('Should send a notification to admins on new plugin version', async function () { | ||
86 | this.timeout(30000) | ||
87 | |||
88 | joinPeerTubeServer.setLatestVersion('15.4.2') | ||
89 | |||
90 | await wait(3000) | ||
91 | await checkNewPeerTubeVersion(baseParams, '15.4.2', 'presence') | ||
92 | }) | ||
93 | |||
94 | it('Should not send the same notification to admins', async function () { | ||
95 | this.timeout(30000) | ||
96 | |||
97 | await wait(3000) | ||
98 | expect(adminNotifications.filter(n => n.type === UserNotificationType.NEW_PEERTUBE_VERSION)).to.have.lengthOf(1) | ||
99 | }) | ||
100 | |||
101 | it('Should not have sent a notification to users', async function () { | ||
102 | this.timeout(30000) | ||
103 | |||
104 | expect(userNotifications.filter(n => n.type === UserNotificationType.NEW_PEERTUBE_VERSION)).to.have.lengthOf(0) | ||
105 | }) | ||
106 | |||
107 | it('Should send a new notification after a new release', async function () { | ||
108 | this.timeout(30000) | ||
109 | |||
110 | joinPeerTubeServer.setLatestVersion('15.4.3') | ||
111 | |||
112 | await wait(3000) | ||
113 | await checkNewPeerTubeVersion(baseParams, '15.4.3', 'presence') | ||
114 | expect(adminNotifications.filter(n => n.type === UserNotificationType.NEW_PEERTUBE_VERSION)).to.have.lengthOf(2) | ||
115 | }) | ||
116 | }) | ||
117 | |||
118 | describe('Latest plugin version notification', function () { | ||
119 | |||
120 | it('Should not send a notification to admins if there is no new plugin version', async function () { | ||
121 | this.timeout(30000) | ||
122 | |||
123 | await wait(6000) | ||
124 | await checkNewPluginVersion(baseParams, PluginType.PLUGIN, 'hello-world', 'absence') | ||
125 | }) | ||
126 | |||
127 | it('Should send a notification to admins on new plugin version', async function () { | ||
128 | this.timeout(30000) | ||
129 | |||
130 | await setPluginVersion(server.internalServerNumber, 'hello-world', '0.0.1') | ||
131 | await setPluginLatestVersion(server.internalServerNumber, 'hello-world', '0.0.1') | ||
132 | await wait(6000) | ||
133 | |||
134 | await checkNewPluginVersion(baseParams, PluginType.PLUGIN, 'hello-world', 'presence') | ||
135 | }) | ||
136 | |||
137 | it('Should not send the same notification to admins', async function () { | ||
138 | this.timeout(30000) | ||
139 | |||
140 | await wait(6000) | ||
141 | |||
142 | expect(adminNotifications.filter(n => n.type === UserNotificationType.NEW_PLUGIN_VERSION)).to.have.lengthOf(1) | ||
143 | }) | ||
144 | |||
145 | it('Should not have sent a notification to users', async function () { | ||
146 | expect(userNotifications.filter(n => n.type === UserNotificationType.NEW_PLUGIN_VERSION)).to.have.lengthOf(0) | ||
147 | }) | ||
148 | |||
149 | it('Should send a new notification after a new plugin release', async function () { | ||
150 | this.timeout(30000) | ||
151 | |||
152 | await setPluginVersion(server.internalServerNumber, 'hello-world', '0.0.1') | ||
153 | await setPluginLatestVersion(server.internalServerNumber, 'hello-world', '0.0.1') | ||
154 | await wait(6000) | ||
155 | |||
156 | expect(adminNotifications.filter(n => n.type === UserNotificationType.NEW_PEERTUBE_VERSION)).to.have.lengthOf(2) | ||
157 | }) | ||
158 | }) | ||
159 | |||
160 | after(async function () { | ||
161 | MockSmtpServer.Instance.kill() | ||
162 | |||
163 | await cleanupTests([ server ]) | ||
164 | }) | ||
165 | }) | ||
diff --git a/server/tests/api/notifications/index.ts b/server/tests/api/notifications/index.ts index bd07a339e..8caa30a3d 100644 --- a/server/tests/api/notifications/index.ts +++ b/server/tests/api/notifications/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import './admin-notifications' | ||
1 | import './comments-notifications' | 2 | import './comments-notifications' |
2 | import './moderation-notifications' | 3 | import './moderation-notifications' |
3 | import './notifications-api' | 4 | import './notifications-api' |
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index 043754e70..f3ba11950 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts | |||
@@ -348,8 +348,8 @@ describe('Test handle downs', function () { | |||
348 | 348 | ||
349 | for (let i = 0; i < 3; i++) { | 349 | for (let i = 0; i < 3; i++) { |
350 | await getVideo(servers[1].url, videoIdsServer1[i]) | 350 | await getVideo(servers[1].url, videoIdsServer1[i]) |
351 | await wait(1000) | ||
352 | await waitJobs([ servers[1] ]) | 351 | await waitJobs([ servers[1] ]) |
352 | await wait(1500) | ||
353 | } | 353 | } |
354 | 354 | ||
355 | for (const id of videoIdsServer1) { | 355 | for (const id of videoIdsServer1) { |
diff --git a/server/tests/api/server/services.ts b/server/tests/api/server/services.ts index df910c111..f0fa91674 100644 --- a/server/tests/api/server/services.ts +++ b/server/tests/api/server/services.ts | |||
@@ -20,6 +20,7 @@ const expect = chai.expect | |||
20 | describe('Test services', function () { | 20 | describe('Test services', function () { |
21 | let server: ServerInfo = null | 21 | let server: ServerInfo = null |
22 | let playlistUUID: string | 22 | let playlistUUID: string |
23 | let playlistDisplayName: string | ||
23 | let video: Video | 24 | let video: Video |
24 | 25 | ||
25 | before(async function () { | 26 | before(async function () { |
@@ -52,6 +53,7 @@ describe('Test services', function () { | |||
52 | }) | 53 | }) |
53 | 54 | ||
54 | playlistUUID = res.body.videoPlaylist.uuid | 55 | playlistUUID = res.body.videoPlaylist.uuid |
56 | playlistDisplayName = 'The Life and Times of Scrooge McDuck' | ||
55 | 57 | ||
56 | await addVideoInPlaylist({ | 58 | await addVideoInPlaylist({ |
57 | url: server.url, | 59 | url: server.url, |
@@ -69,7 +71,7 @@ describe('Test services', function () { | |||
69 | 71 | ||
70 | const res = await getOEmbed(server.url, oembedUrl) | 72 | const res = await getOEmbed(server.url, oembedUrl) |
71 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 73 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + |
72 | `src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 74 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
73 | 'frameborder="0" allowfullscreen></iframe>' | 75 | 'frameborder="0" allowfullscreen></iframe>' |
74 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath | 76 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath |
75 | 77 | ||
@@ -88,7 +90,7 @@ describe('Test services', function () { | |||
88 | 90 | ||
89 | const res = await getOEmbed(server.url, oembedUrl) | 91 | const res = await getOEmbed(server.url, oembedUrl) |
90 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 92 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + |
91 | `src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + | 93 | `title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + |
92 | 'frameborder="0" allowfullscreen></iframe>' | 94 | 'frameborder="0" allowfullscreen></iframe>' |
93 | 95 | ||
94 | expect(res.body.html).to.equal(expectedHtml) | 96 | expect(res.body.html).to.equal(expectedHtml) |
@@ -97,8 +99,8 @@ describe('Test services', function () { | |||
97 | expect(res.body.width).to.equal(560) | 99 | expect(res.body.width).to.equal(560) |
98 | expect(res.body.height).to.equal(315) | 100 | expect(res.body.height).to.equal(315) |
99 | expect(res.body.thumbnail_url).exist | 101 | expect(res.body.thumbnail_url).exist |
100 | expect(res.body.thumbnail_width).to.equal(223) | 102 | expect(res.body.thumbnail_width).to.equal(280) |
101 | expect(res.body.thumbnail_height).to.equal(122) | 103 | expect(res.body.thumbnail_height).to.equal(157) |
102 | }) | 104 | }) |
103 | 105 | ||
104 | it('Should have a valid oEmbed response with small max height query', async function () { | 106 | it('Should have a valid oEmbed response with small max height query', async function () { |
@@ -109,7 +111,7 @@ describe('Test services', function () { | |||
109 | 111 | ||
110 | const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) | 112 | const res = await getOEmbed(server.url, oembedUrl, format, maxHeight, maxWidth) |
111 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + | 113 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + |
112 | `src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 114 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
113 | 'frameborder="0" allowfullscreen></iframe>' | 115 | 'frameborder="0" allowfullscreen></iframe>' |
114 | 116 | ||
115 | expect(res.body.html).to.equal(expectedHtml) | 117 | expect(res.body.html).to.equal(expectedHtml) |
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index 62a59033f..cea98aac7 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts | |||
@@ -4,10 +4,12 @@ import 'mocha' | |||
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { AbuseState, AbuseUpdate, MyUser, User, UserRole, Video, VideoPlaylistType } from '@shared/models' | 5 | import { AbuseState, AbuseUpdate, MyUser, User, UserRole, Video, VideoPlaylistType } from '@shared/models' |
6 | import { CustomConfig } from '@shared/models/server' | 6 | import { CustomConfig } from '@shared/models/server' |
7 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
7 | import { | 8 | import { |
8 | addVideoCommentThread, | 9 | addVideoCommentThread, |
9 | blockUser, | 10 | blockUser, |
10 | cleanupTests, | 11 | cleanupTests, |
12 | closeAllSequelize, | ||
11 | createUser, | 13 | createUser, |
12 | deleteMe, | 14 | deleteMe, |
13 | flushAndRunServer, | 15 | flushAndRunServer, |
@@ -24,6 +26,7 @@ import { | |||
24 | getVideoChannel, | 26 | getVideoChannel, |
25 | getVideosList, | 27 | getVideosList, |
26 | installPlugin, | 28 | installPlugin, |
29 | killallServers, | ||
27 | login, | 30 | login, |
28 | makePutBodyRequest, | 31 | makePutBodyRequest, |
29 | rateVideo, | 32 | rateVideo, |
@@ -31,7 +34,9 @@ import { | |||
31 | removeUser, | 34 | removeUser, |
32 | removeVideo, | 35 | removeVideo, |
33 | reportAbuse, | 36 | reportAbuse, |
37 | reRunServer, | ||
34 | ServerInfo, | 38 | ServerInfo, |
39 | setTokenField, | ||
35 | testImage, | 40 | testImage, |
36 | unblockUser, | 41 | unblockUser, |
37 | updateAbuse, | 42 | updateAbuse, |
@@ -44,10 +49,9 @@ import { | |||
44 | waitJobs | 49 | waitJobs |
45 | } from '../../../../shared/extra-utils' | 50 | } from '../../../../shared/extra-utils' |
46 | import { follow } from '../../../../shared/extra-utils/server/follows' | 51 | import { follow } from '../../../../shared/extra-utils/server/follows' |
47 | import { logout, serverLogin, setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' | 52 | import { logout, refreshToken, setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' |
48 | import { getMyVideos } from '../../../../shared/extra-utils/videos/videos' | 53 | import { getMyVideos } from '../../../../shared/extra-utils/videos/videos' |
49 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' | 54 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' |
50 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
51 | 55 | ||
52 | const expect = chai.expect | 56 | const expect = chai.expect |
53 | 57 | ||
@@ -89,6 +93,7 @@ describe('Test users', function () { | |||
89 | const client = { id: 'client', secret: server.client.secret } | 93 | const client = { id: 'client', secret: server.client.secret } |
90 | const res = await login(server.url, client, server.user, HttpStatusCode.BAD_REQUEST_400) | 94 | const res = await login(server.url, client, server.user, HttpStatusCode.BAD_REQUEST_400) |
91 | 95 | ||
96 | expect(res.body.code).to.equal('invalid_client') | ||
92 | expect(res.body.error).to.contain('client is invalid') | 97 | expect(res.body.error).to.contain('client is invalid') |
93 | }) | 98 | }) |
94 | 99 | ||
@@ -96,6 +101,7 @@ describe('Test users', function () { | |||
96 | const client = { id: server.client.id, secret: 'coucou' } | 101 | const client = { id: server.client.id, secret: 'coucou' } |
97 | const res = await login(server.url, client, server.user, HttpStatusCode.BAD_REQUEST_400) | 102 | const res = await login(server.url, client, server.user, HttpStatusCode.BAD_REQUEST_400) |
98 | 103 | ||
104 | expect(res.body.code).to.equal('invalid_client') | ||
99 | expect(res.body.error).to.contain('client is invalid') | 105 | expect(res.body.error).to.contain('client is invalid') |
100 | }) | 106 | }) |
101 | }) | 107 | }) |
@@ -106,6 +112,7 @@ describe('Test users', function () { | |||
106 | const user = { username: 'captain crochet', password: server.user.password } | 112 | const user = { username: 'captain crochet', password: server.user.password } |
107 | const res = await login(server.url, server.client, user, HttpStatusCode.BAD_REQUEST_400) | 113 | const res = await login(server.url, server.client, user, HttpStatusCode.BAD_REQUEST_400) |
108 | 114 | ||
115 | expect(res.body.code).to.equal('invalid_grant') | ||
109 | expect(res.body.error).to.contain('credentials are invalid') | 116 | expect(res.body.error).to.contain('credentials are invalid') |
110 | }) | 117 | }) |
111 | 118 | ||
@@ -113,6 +120,7 @@ describe('Test users', function () { | |||
113 | const user = { username: server.user.username, password: 'mew_three' } | 120 | const user = { username: server.user.username, password: 'mew_three' } |
114 | const res = await login(server.url, server.client, user, HttpStatusCode.BAD_REQUEST_400) | 121 | const res = await login(server.url, server.client, user, HttpStatusCode.BAD_REQUEST_400) |
115 | 122 | ||
123 | expect(res.body.code).to.equal('invalid_grant') | ||
116 | expect(res.body.error).to.contain('credentials are invalid') | 124 | expect(res.body.error).to.contain('credentials are invalid') |
117 | }) | 125 | }) |
118 | 126 | ||
@@ -245,12 +253,44 @@ describe('Test users', function () { | |||
245 | }) | 253 | }) |
246 | 254 | ||
247 | it('Should be able to login again', async function () { | 255 | it('Should be able to login again', async function () { |
248 | server.accessToken = await serverLogin(server) | 256 | const res = await login(server.url, server.client, server.user) |
257 | server.accessToken = res.body.access_token | ||
258 | server.refreshToken = res.body.refresh_token | ||
259 | }) | ||
260 | |||
261 | it('Should be able to get my user information again', async function () { | ||
262 | await getMyUserInformation(server.url, server.accessToken) | ||
263 | }) | ||
264 | |||
265 | it('Should have an expired access token', async function () { | ||
266 | this.timeout(15000) | ||
267 | |||
268 | await setTokenField(server.internalServerNumber, server.accessToken, 'accessTokenExpiresAt', new Date().toISOString()) | ||
269 | await setTokenField(server.internalServerNumber, server.accessToken, 'refreshTokenExpiresAt', new Date().toISOString()) | ||
270 | |||
271 | killallServers([ server ]) | ||
272 | await reRunServer(server) | ||
273 | |||
274 | await getMyUserInformation(server.url, server.accessToken, 401) | ||
275 | }) | ||
276 | |||
277 | it('Should not be able to refresh an access token with an expired refresh token', async function () { | ||
278 | await refreshToken(server, server.refreshToken, 400) | ||
249 | }) | 279 | }) |
250 | 280 | ||
251 | it('Should have an expired access token') | 281 | it('Should refresh the token', async function () { |
282 | this.timeout(15000) | ||
283 | |||
284 | const futureDate = new Date(new Date().getTime() + 1000 * 60).toISOString() | ||
285 | await setTokenField(server.internalServerNumber, server.accessToken, 'refreshTokenExpiresAt', futureDate) | ||
252 | 286 | ||
253 | it('Should refresh the token') | 287 | killallServers([ server ]) |
288 | await reRunServer(server) | ||
289 | |||
290 | const res = await refreshToken(server, server.refreshToken) | ||
291 | server.accessToken = res.body.access_token | ||
292 | server.refreshToken = res.body.refresh_token | ||
293 | }) | ||
254 | 294 | ||
255 | it('Should be able to get my user information again', async function () { | 295 | it('Should be able to get my user information again', async function () { |
256 | await getMyUserInformation(server.url, server.accessToken) | 296 | await getMyUserInformation(server.url, server.accessToken) |
@@ -976,6 +1016,7 @@ describe('Test users', function () { | |||
976 | }) | 1016 | }) |
977 | 1017 | ||
978 | after(async function () { | 1018 | after(async function () { |
1019 | await closeAllSequelize([ server ]) | ||
979 | await cleanupTests([ server ]) | 1020 | await cleanupTests([ server ]) |
980 | }) | 1021 | }) |
981 | }) | 1022 | }) |
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts index 367f99fdd..d12d58e75 100644 --- a/server/tests/api/videos/video-channels.ts +++ b/server/tests/api/videos/video-channels.ts | |||
@@ -2,16 +2,20 @@ | |||
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { basename } from 'path' | ||
5 | import { | 6 | import { |
6 | cleanupTests, | 7 | cleanupTests, |
7 | createUser, | 8 | createUser, |
9 | deleteVideoChannelImage, | ||
8 | doubleFollow, | 10 | doubleFollow, |
9 | flushAndRunMultipleServers, | 11 | flushAndRunMultipleServers, |
12 | getActorImage, | ||
10 | getVideo, | 13 | getVideo, |
14 | getVideoChannel, | ||
11 | getVideoChannelVideos, | 15 | getVideoChannelVideos, |
12 | testImage, | 16 | testImage, |
13 | updateVideo, | 17 | updateVideo, |
14 | updateVideoChannelAvatar, | 18 | updateVideoChannelImage, |
15 | uploadVideo, | 19 | uploadVideo, |
16 | userLogin, | 20 | userLogin, |
17 | wait | 21 | wait |
@@ -21,7 +25,6 @@ import { | |||
21 | deleteVideoChannel, | 25 | deleteVideoChannel, |
22 | getAccountVideoChannelsList, | 26 | getAccountVideoChannelsList, |
23 | getMyUserInformation, | 27 | getMyUserInformation, |
24 | getVideoChannel, | ||
25 | getVideoChannelsList, | 28 | getVideoChannelsList, |
26 | ServerInfo, | 29 | ServerInfo, |
27 | setAccessTokensToServers, | 30 | setAccessTokensToServers, |
@@ -30,9 +33,17 @@ import { | |||
30 | } from '../../../../shared/extra-utils/index' | 33 | } from '../../../../shared/extra-utils/index' |
31 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | 34 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' |
32 | import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index' | 35 | import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index' |
36 | import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants' | ||
33 | 37 | ||
34 | const expect = chai.expect | 38 | const expect = chai.expect |
35 | 39 | ||
40 | async function findChannel (server: ServerInfo, channelId: number) { | ||
41 | const res = await getVideoChannelsList(server.url, 0, 5, '-name') | ||
42 | const videoChannel = res.body.data.find(c => c.id === channelId) | ||
43 | |||
44 | return videoChannel as VideoChannel | ||
45 | } | ||
46 | |||
36 | describe('Test video channels', function () { | 47 | describe('Test video channels', function () { |
37 | let servers: ServerInfo[] | 48 | let servers: ServerInfo[] |
38 | let userInfo: User | 49 | let userInfo: User |
@@ -262,38 +273,94 @@ describe('Test video channels', function () { | |||
262 | }) | 273 | }) |
263 | 274 | ||
264 | it('Should update video channel avatar', async function () { | 275 | it('Should update video channel avatar', async function () { |
265 | this.timeout(5000) | 276 | this.timeout(15000) |
266 | 277 | ||
267 | const fixture = 'avatar.png' | 278 | const fixture = 'avatar.png' |
268 | 279 | ||
269 | await updateVideoChannelAvatar({ | 280 | await updateVideoChannelImage({ |
270 | url: servers[0].url, | 281 | url: servers[0].url, |
271 | accessToken: servers[0].accessToken, | 282 | accessToken: servers[0].accessToken, |
272 | videoChannelName: 'second_video_channel', | 283 | videoChannelName: 'second_video_channel', |
273 | fixture | 284 | fixture, |
285 | type: 'avatar' | ||
274 | }) | 286 | }) |
275 | 287 | ||
276 | await waitJobs(servers) | 288 | await waitJobs(servers) |
289 | |||
290 | for (const server of servers) { | ||
291 | const videoChannel = await findChannel(server, secondVideoChannelId) | ||
292 | |||
293 | await testImage(server.url, 'avatar-resized', videoChannel.avatar.path, '.png') | ||
294 | |||
295 | const row = await getActorImage(server.internalServerNumber, basename(videoChannel.avatar.path)) | ||
296 | expect(row.height).to.equal(ACTOR_IMAGES_SIZE.AVATARS.height) | ||
297 | expect(row.width).to.equal(ACTOR_IMAGES_SIZE.AVATARS.width) | ||
298 | } | ||
277 | }) | 299 | }) |
278 | 300 | ||
279 | it('Should have video channel avatar updated', async function () { | 301 | it('Should update video channel banner', async function () { |
302 | this.timeout(15000) | ||
303 | |||
304 | const fixture = 'banner.jpg' | ||
305 | |||
306 | await updateVideoChannelImage({ | ||
307 | url: servers[0].url, | ||
308 | accessToken: servers[0].accessToken, | ||
309 | videoChannelName: 'second_video_channel', | ||
310 | fixture, | ||
311 | type: 'banner' | ||
312 | }) | ||
313 | |||
314 | await waitJobs(servers) | ||
315 | |||
280 | for (const server of servers) { | 316 | for (const server of servers) { |
281 | const res = await getVideoChannelsList(server.url, 0, 1, '-name') | 317 | const res = await getVideoChannel(server.url, 'second_video_channel@' + servers[0].host) |
318 | const videoChannel = res.body | ||
282 | 319 | ||
283 | const videoChannel = res.body.data.find(c => c.id === secondVideoChannelId) | 320 | await testImage(server.url, 'banner-resized', videoChannel.banner.path) |
284 | 321 | ||
285 | await testImage(server.url, 'avatar-resized', videoChannel.avatar.path, '.png') | 322 | const row = await getActorImage(server.internalServerNumber, basename(videoChannel.banner.path)) |
323 | expect(row.height).to.equal(ACTOR_IMAGES_SIZE.BANNERS.height) | ||
324 | expect(row.width).to.equal(ACTOR_IMAGES_SIZE.BANNERS.width) | ||
325 | } | ||
326 | }) | ||
327 | |||
328 | it('Should delete the video channel avatar', async function () { | ||
329 | this.timeout(15000) | ||
330 | |||
331 | await deleteVideoChannelImage({ | ||
332 | url: servers[0].url, | ||
333 | accessToken: servers[0].accessToken, | ||
334 | videoChannelName: 'second_video_channel', | ||
335 | type: 'avatar' | ||
336 | }) | ||
337 | |||
338 | await waitJobs(servers) | ||
339 | |||
340 | for (const server of servers) { | ||
341 | const videoChannel = await findChannel(server, secondVideoChannelId) | ||
342 | |||
343 | expect(videoChannel.avatar).to.be.null | ||
286 | } | 344 | } |
287 | }) | 345 | }) |
288 | 346 | ||
289 | it('Should get video channel', async function () { | 347 | it('Should delete the video channel banner', async function () { |
290 | const res = await getVideoChannel(servers[0].url, 'second_video_channel') | 348 | this.timeout(15000) |
349 | |||
350 | await deleteVideoChannelImage({ | ||
351 | url: servers[0].url, | ||
352 | accessToken: servers[0].accessToken, | ||
353 | videoChannelName: 'second_video_channel', | ||
354 | type: 'banner' | ||
355 | }) | ||
356 | |||
357 | await waitJobs(servers) | ||
358 | |||
359 | for (const server of servers) { | ||
360 | const videoChannel = await findChannel(server, secondVideoChannelId) | ||
291 | 361 | ||
292 | const videoChannel = res.body | 362 | expect(videoChannel.banner).to.be.null |
293 | expect(videoChannel.name).to.equal('second_video_channel') | 363 | } |
294 | expect(videoChannel.displayName).to.equal('video channel updated') | ||
295 | expect(videoChannel.description).to.equal('video channel description updated') | ||
296 | expect(videoChannel.support).to.equal('video channel support text updated') | ||
297 | }) | 364 | }) |
298 | 365 | ||
299 | it('Should list the second video channel videos', async function () { | 366 | it('Should list the second video channel videos', async function () { |
diff --git a/server/tests/cli/index.ts b/server/tests/cli/index.ts index 242589010..7e6eebd17 100644 --- a/server/tests/cli/index.ts +++ b/server/tests/cli/index.ts | |||
@@ -6,5 +6,6 @@ import './peertube' | |||
6 | import './plugins' | 6 | import './plugins' |
7 | import './print-transcode-command' | 7 | import './print-transcode-command' |
8 | import './prune-storage' | 8 | import './prune-storage' |
9 | import './regenerate-thumbnails' | ||
9 | import './reset-password' | 10 | import './reset-password' |
10 | import './update-host' | 11 | import './update-host' |
diff --git a/server/tests/cli/regenerate-thumbnails.ts b/server/tests/cli/regenerate-thumbnails.ts new file mode 100644 index 000000000..8acb9f263 --- /dev/null +++ b/server/tests/cli/regenerate-thumbnails.ts | |||
@@ -0,0 +1,124 @@ | |||
1 | import 'mocha' | ||
2 | import { expect } from 'chai' | ||
3 | import { writeFile } from 'fs-extra' | ||
4 | import { basename, join } from 'path' | ||
5 | import { Video, VideoDetails } from '@shared/models' | ||
6 | import { | ||
7 | buildServerDirectory, | ||
8 | cleanupTests, | ||
9 | doubleFollow, | ||
10 | execCLI, | ||
11 | flushAndRunMultipleServers, | ||
12 | getEnvCli, | ||
13 | getVideo, | ||
14 | makeRawRequest, | ||
15 | ServerInfo, | ||
16 | setAccessTokensToServers, | ||
17 | uploadVideoAndGetId, | ||
18 | waitJobs | ||
19 | } from '../../../shared/extra-utils' | ||
20 | import { HttpStatusCode } from '@shared/core-utils' | ||
21 | |||
22 | async function testThumbnail (server: ServerInfo, videoId: number | string) { | ||
23 | const res = await getVideo(server.url, videoId) | ||
24 | const video: VideoDetails = res.body | ||
25 | |||
26 | const res1 = await makeRawRequest(join(server.url, video.thumbnailPath), HttpStatusCode.OK_200) | ||
27 | expect(res1.body).to.not.have.lengthOf(0) | ||
28 | |||
29 | const res2 = await makeRawRequest(join(server.url, video.thumbnailPath), HttpStatusCode.OK_200) | ||
30 | expect(res2.body).to.not.have.lengthOf(0) | ||
31 | } | ||
32 | |||
33 | describe('Test regenerate thumbnails script', function () { | ||
34 | let servers: ServerInfo[] | ||
35 | |||
36 | let video1: Video | ||
37 | let video2: Video | ||
38 | let remoteVideo: Video | ||
39 | |||
40 | let thumbnail1Path: string | ||
41 | let thumbnailRemotePath: string | ||
42 | |||
43 | before(async function () { | ||
44 | this.timeout(60000) | ||
45 | |||
46 | servers = await flushAndRunMultipleServers(2) | ||
47 | await setAccessTokensToServers(servers) | ||
48 | |||
49 | await doubleFollow(servers[0], servers[1]) | ||
50 | |||
51 | { | ||
52 | const videoUUID1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 1' })).uuid | ||
53 | video1 = await (getVideo(servers[0].url, videoUUID1).then(res => res.body)) | ||
54 | |||
55 | thumbnail1Path = join(buildServerDirectory(servers[0], 'thumbnails'), basename(video1.thumbnailPath)) | ||
56 | |||
57 | const videoUUID2 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 2' })).uuid | ||
58 | video2 = await (getVideo(servers[0].url, videoUUID2).then(res => res.body)) | ||
59 | } | ||
60 | |||
61 | { | ||
62 | const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3' })).uuid | ||
63 | await waitJobs(servers) | ||
64 | |||
65 | remoteVideo = await (getVideo(servers[0].url, videoUUID).then(res => res.body)) | ||
66 | |||
67 | thumbnailRemotePath = join(buildServerDirectory(servers[0], 'thumbnails'), basename(remoteVideo.thumbnailPath)) | ||
68 | } | ||
69 | |||
70 | await writeFile(thumbnail1Path, '') | ||
71 | await writeFile(thumbnailRemotePath, '') | ||
72 | }) | ||
73 | |||
74 | it('Should have empty thumbnails', async function () { | ||
75 | { | ||
76 | const res = await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.OK_200) | ||
77 | expect(res.body).to.have.lengthOf(0) | ||
78 | } | ||
79 | |||
80 | { | ||
81 | const res = await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.OK_200) | ||
82 | expect(res.body).to.not.have.lengthOf(0) | ||
83 | } | ||
84 | |||
85 | { | ||
86 | const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200) | ||
87 | expect(res.body).to.have.lengthOf(0) | ||
88 | } | ||
89 | }) | ||
90 | |||
91 | it('Should regenerate local thumbnails from the CLI', async function () { | ||
92 | this.timeout(15000) | ||
93 | |||
94 | const env = getEnvCli(servers[0]) | ||
95 | await execCLI(`${env} npm run regenerate-thumbnails`) | ||
96 | }) | ||
97 | |||
98 | it('Should have generated new thumbnail files', async function () { | ||
99 | await testThumbnail(servers[0], video1.uuid) | ||
100 | await testThumbnail(servers[0], video2.uuid) | ||
101 | |||
102 | const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200) | ||
103 | expect(res.body).to.have.lengthOf(0) | ||
104 | }) | ||
105 | |||
106 | it('Should have deleted old thumbnail files', async function () { | ||
107 | { | ||
108 | await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.NOT_FOUND_404) | ||
109 | } | ||
110 | |||
111 | { | ||
112 | await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.NOT_FOUND_404) | ||
113 | } | ||
114 | |||
115 | { | ||
116 | const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200) | ||
117 | expect(res.body).to.have.lengthOf(0) | ||
118 | } | ||
119 | }) | ||
120 | |||
121 | after(async function () { | ||
122 | await cleanupTests(servers) | ||
123 | }) | ||
124 | }) | ||
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts index f1055ea44..7bad81751 100644 --- a/server/tests/feeds/feeds.ts +++ b/server/tests/feeds/feeds.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import * as libxmljs from 'libxmljs' | 5 | import * as xmlParser from 'fast-xml-parser' |
6 | import { | 6 | import { |
7 | addAccountToAccountBlocklist, | 7 | addAccountToAccountBlocklist, |
8 | addAccountToServerBlocklist, | 8 | addAccountToServerBlocklist, |
@@ -139,12 +139,15 @@ describe('Test syndication feeds', () => { | |||
139 | it('Should contain a valid enclosure (covers RSS 2.0 endpoint)', async function () { | 139 | it('Should contain a valid enclosure (covers RSS 2.0 endpoint)', async function () { |
140 | for (const server of servers) { | 140 | for (const server of servers) { |
141 | const rss = await getXMLfeed(server.url, 'videos') | 141 | const rss = await getXMLfeed(server.url, 'videos') |
142 | const xmlDoc = libxmljs.parseXmlString(rss.text) | 142 | expect(xmlParser.validate(rss.text)).to.be.true |
143 | const xmlEnclosure = xmlDoc.get('/rss/channel/item/enclosure') | 143 | |
144 | expect(xmlEnclosure).to.exist | 144 | const xmlDoc = xmlParser.parse(rss.text, { parseAttributeValue: true, ignoreAttributes: false }) |
145 | expect(xmlEnclosure.attr('type').value()).to.be.equal('application/x-bittorrent') | 145 | |
146 | expect(xmlEnclosure.attr('length').value()).to.be.equal('218910') | 146 | const enclosure = xmlDoc.rss.channel.item[0].enclosure |
147 | expect(xmlEnclosure.attr('url').value()).to.contain('720.torrent') | 147 | expect(enclosure).to.exist |
148 | expect(enclosure['@_type']).to.equal('application/x-bittorrent') | ||
149 | expect(enclosure['@_length']).to.equal(218910) | ||
150 | expect(enclosure['@_url']).to.contain('720.torrent') | ||
148 | } | 151 | } |
149 | }) | 152 | }) |
150 | 153 | ||
diff --git a/server/tests/fixtures/banner-resized.jpg b/server/tests/fixtures/banner-resized.jpg new file mode 100644 index 000000000..13ea422cb --- /dev/null +++ b/server/tests/fixtures/banner-resized.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/banner.jpg b/server/tests/fixtures/banner.jpg new file mode 100644 index 000000000..e5f284f59 --- /dev/null +++ b/server/tests/fixtures/banner.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js index 305d92002..ee0bc39f3 100644 --- a/server/tests/fixtures/peertube-plugin-test/main.js +++ b/server/tests/fixtures/peertube-plugin-test/main.js | |||
@@ -184,6 +184,76 @@ async function register ({ registerHook, registerSetting, settingsManager, stora | |||
184 | return result | 184 | return result |
185 | } | 185 | } |
186 | }) | 186 | }) |
187 | |||
188 | registerHook({ | ||
189 | target: 'filter:api.download.torrent.allowed.result', | ||
190 | handler: (result, params) => { | ||
191 | if (params && params.downloadName.includes('bad torrent')) { | ||
192 | return { allowed: false, errorMessage: 'Liu Bei' } | ||
193 | } | ||
194 | |||
195 | return result | ||
196 | } | ||
197 | }) | ||
198 | |||
199 | registerHook({ | ||
200 | target: 'filter:api.download.video.allowed.result', | ||
201 | handler: (result, params) => { | ||
202 | if (params && !params.streamingPlaylist && params.video.name.includes('bad file')) { | ||
203 | return { allowed: false, errorMessage: 'Cao Cao' } | ||
204 | } | ||
205 | |||
206 | if (params && params.streamingPlaylist && params.video.name.includes('bad playlist file')) { | ||
207 | return { allowed: false, errorMessage: 'Sun Jian' } | ||
208 | } | ||
209 | |||
210 | return result | ||
211 | } | ||
212 | }) | ||
213 | |||
214 | registerHook({ | ||
215 | target: 'filter:html.embed.video.allowed.result', | ||
216 | handler: (result, params) => { | ||
217 | return { | ||
218 | allowed: false, | ||
219 | html: 'Lu Bu' | ||
220 | } | ||
221 | } | ||
222 | }) | ||
223 | |||
224 | registerHook({ | ||
225 | target: 'filter:html.embed.video-playlist.allowed.result', | ||
226 | handler: (result, params) => { | ||
227 | return { | ||
228 | allowed: false, | ||
229 | html: 'Diao Chan' | ||
230 | } | ||
231 | } | ||
232 | }) | ||
233 | |||
234 | { | ||
235 | const searchHooks = [ | ||
236 | 'filter:api.search.videos.local.list.params', | ||
237 | 'filter:api.search.videos.local.list.result', | ||
238 | 'filter:api.search.videos.index.list.params', | ||
239 | 'filter:api.search.videos.index.list.result', | ||
240 | 'filter:api.search.video-channels.local.list.params', | ||
241 | 'filter:api.search.video-channels.local.list.result', | ||
242 | 'filter:api.search.video-channels.index.list.params', | ||
243 | 'filter:api.search.video-channels.index.list.result', | ||
244 | ] | ||
245 | |||
246 | for (const h of searchHooks) { | ||
247 | registerHook({ | ||
248 | target: h, | ||
249 | handler: (obj) => { | ||
250 | peertubeHelpers.logger.debug('Run hook %s.', h) | ||
251 | |||
252 | return obj | ||
253 | } | ||
254 | }) | ||
255 | } | ||
256 | } | ||
187 | } | 257 | } |
188 | 258 | ||
189 | async function unregister () { | 259 | async function unregister () { |
diff --git a/server/tests/fixtures/thumbnail-playlist.jpg b/server/tests/fixtures/thumbnail-playlist.jpg index 19db4f18c..62cd77435 100644 --- a/server/tests/fixtures/thumbnail-playlist.jpg +++ b/server/tests/fixtures/thumbnail-playlist.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_import_thumbnail.jpg b/server/tests/fixtures/video_import_thumbnail.jpg index fcc50b75f..9ee1bc382 100644 --- a/server/tests/fixtures/video_import_thumbnail.jpg +++ b/server/tests/fixtures/video_import_thumbnail.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short.mp4.jpg b/server/tests/fixtures/video_short.mp4.jpg index 48790ffec..62cd77435 100644 --- a/server/tests/fixtures/video_short.mp4.jpg +++ b/server/tests/fixtures/video_short.mp4.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short.ogv.jpg b/server/tests/fixtures/video_short.ogv.jpg index c4c1d00e5..62cd77435 100644 --- a/server/tests/fixtures/video_short.ogv.jpg +++ b/server/tests/fixtures/video_short.ogv.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short.webm.jpg b/server/tests/fixtures/video_short.webm.jpg index 7f8047516..62cd77435 100644 --- a/server/tests/fixtures/video_short.webm.jpg +++ b/server/tests/fixtures/video_short.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short1.webm.jpg b/server/tests/fixtures/video_short1.webm.jpg index 582eb9ea3..615cb2a5d 100644 --- a/server/tests/fixtures/video_short1.webm.jpg +++ b/server/tests/fixtures/video_short1.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short2.webm.jpg b/server/tests/fixtures/video_short2.webm.jpg index b331aba3b..aa3126381 100644 --- a/server/tests/fixtures/video_short2.webm.jpg +++ b/server/tests/fixtures/video_short2.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/fixtures/video_short3.webm.jpg b/server/tests/fixtures/video_short3.webm.jpg index ec8652167..62cd77435 100644 --- a/server/tests/fixtures/video_short3.webm.jpg +++ b/server/tests/fixtures/video_short3.webm.jpg | |||
Binary files differ | |||
diff --git a/server/tests/helpers/request.ts b/server/tests/helpers/request.ts index f8b2d599b..5e77f129e 100644 --- a/server/tests/helpers/request.ts +++ b/server/tests/helpers/request.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import { doRequest, doRequestAndSaveToFile } from '../../helpers/requests' | ||
5 | import { get4KFileUrl, root, wait } from '../../../shared/extra-utils' | ||
6 | import { join } from 'path' | ||
7 | import { pathExists, remove } from 'fs-extra' | ||
8 | import { expect } from 'chai' | 4 | import { expect } from 'chai' |
5 | import { pathExists, remove } from 'fs-extra' | ||
6 | import { join } from 'path' | ||
7 | import { get4KFileUrl, root, wait } from '../../../shared/extra-utils' | ||
8 | import { doRequest, doRequestAndSaveToFile } from '../../helpers/requests' | ||
9 | 9 | ||
10 | describe('Request helpers', function () { | 10 | describe('Request helpers', function () { |
11 | const destPath1 = join(root(), 'test-output-1.txt') | 11 | const destPath1 = join(root(), 'test-output-1.txt') |
@@ -13,7 +13,7 @@ describe('Request helpers', function () { | |||
13 | 13 | ||
14 | it('Should throw an error when the bytes limit is exceeded for request', async function () { | 14 | it('Should throw an error when the bytes limit is exceeded for request', async function () { |
15 | try { | 15 | try { |
16 | await doRequest({ uri: get4KFileUrl() }, 3) | 16 | await doRequest(get4KFileUrl(), { bodyKBLimit: 3 }) |
17 | } catch { | 17 | } catch { |
18 | return | 18 | return |
19 | } | 19 | } |
@@ -23,7 +23,7 @@ describe('Request helpers', function () { | |||
23 | 23 | ||
24 | it('Should throw an error when the bytes limit is exceeded for request and save file', async function () { | 24 | it('Should throw an error when the bytes limit is exceeded for request and save file', async function () { |
25 | try { | 25 | try { |
26 | await doRequestAndSaveToFile({ uri: get4KFileUrl() }, destPath1, 3) | 26 | await doRequestAndSaveToFile(get4KFileUrl(), destPath1, { bodyKBLimit: 3 }) |
27 | } catch { | 27 | } catch { |
28 | 28 | ||
29 | await wait(500) | 29 | await wait(500) |
@@ -35,8 +35,8 @@ describe('Request helpers', function () { | |||
35 | }) | 35 | }) |
36 | 36 | ||
37 | it('Should succeed if the file is below the limit', async function () { | 37 | it('Should succeed if the file is below the limit', async function () { |
38 | await doRequest({ uri: get4KFileUrl() }, 5) | 38 | await doRequest(get4KFileUrl(), { bodyKBLimit: 5 }) |
39 | await doRequestAndSaveToFile({ uri: get4KFileUrl() }, destPath2, 5) | 39 | await doRequestAndSaveToFile(get4KFileUrl(), destPath2, { bodyKBLimit: 5 }) |
40 | 40 | ||
41 | expect(await pathExists(destPath2)).to.be.true | 41 | expect(await pathExists(destPath2)).to.be.true |
42 | }) | 42 | }) |
diff --git a/server/tests/plugins/external-auth.ts b/server/tests/plugins/external-auth.ts index a1b5e8f5d..5addb45c7 100644 --- a/server/tests/plugins/external-auth.ts +++ b/server/tests/plugins/external-auth.ts | |||
@@ -137,7 +137,7 @@ describe('Test external auth plugins', function () { | |||
137 | 137 | ||
138 | await loginUsingExternalToken(server, 'cyan', externalAuthToken, HttpStatusCode.BAD_REQUEST_400) | 138 | await loginUsingExternalToken(server, 'cyan', externalAuthToken, HttpStatusCode.BAD_REQUEST_400) |
139 | 139 | ||
140 | await waitUntilLog(server, 'expired external auth token') | 140 | await waitUntilLog(server, 'expired external auth token', 2) |
141 | }) | 141 | }) |
142 | 142 | ||
143 | it('Should auto login Cyan, create the user and use the token', async function () { | 143 | it('Should auto login Cyan, create the user and use the token', async function () { |
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index d88170201..ac958c5f5 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts | |||
@@ -2,11 +2,15 @@ | |||
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels' | ||
5 | import { ServerConfig } from '@shared/models' | 6 | import { ServerConfig } from '@shared/models' |
7 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
6 | import { | 8 | import { |
7 | addVideoCommentReply, | 9 | addVideoCommentReply, |
8 | addVideoCommentThread, | 10 | addVideoCommentThread, |
11 | advancedVideosSearch, | ||
9 | createLive, | 12 | createLive, |
13 | createVideoPlaylist, | ||
10 | doubleFollow, | 14 | doubleFollow, |
11 | getAccountVideos, | 15 | getAccountVideos, |
12 | getConfig, | 16 | getConfig, |
@@ -15,24 +19,33 @@ import { | |||
15 | getVideo, | 19 | getVideo, |
16 | getVideoChannelVideos, | 20 | getVideoChannelVideos, |
17 | getVideoCommentThreads, | 21 | getVideoCommentThreads, |
22 | getVideoPlaylist, | ||
18 | getVideosList, | 23 | getVideosList, |
19 | getVideosListPagination, | 24 | getVideosListPagination, |
20 | getVideoThreadComments, | 25 | getVideoThreadComments, |
21 | getVideoWithToken, | 26 | getVideoWithToken, |
22 | installPlugin, | 27 | installPlugin, |
28 | makeRawRequest, | ||
23 | registerUser, | 29 | registerUser, |
24 | setAccessTokensToServers, | 30 | setAccessTokensToServers, |
25 | setDefaultVideoChannel, | 31 | setDefaultVideoChannel, |
26 | updateCustomSubConfig, | 32 | updateCustomSubConfig, |
27 | updateVideo, | 33 | updateVideo, |
28 | uploadVideo, | 34 | uploadVideo, |
35 | uploadVideoAndGetId, | ||
29 | waitJobs | 36 | waitJobs |
30 | } from '../../../shared/extra-utils' | 37 | } from '../../../shared/extra-utils' |
31 | import { cleanupTests, flushAndRunMultipleServers, ServerInfo } from '../../../shared/extra-utils/server/servers' | 38 | import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers' |
32 | import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports' | 39 | import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports' |
33 | import { VideoDetails, VideoImport, VideoImportState, VideoPrivacy } from '../../../shared/models/videos' | 40 | import { |
41 | VideoDetails, | ||
42 | VideoImport, | ||
43 | VideoImportState, | ||
44 | VideoPlaylist, | ||
45 | VideoPlaylistPrivacy, | ||
46 | VideoPrivacy | ||
47 | } from '../../../shared/models/videos' | ||
34 | import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' | 48 | import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' |
35 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
36 | 49 | ||
37 | const expect = chai.expect | 50 | const expect = chai.expect |
38 | 51 | ||
@@ -355,6 +368,165 @@ describe('Test plugin filter hooks', function () { | |||
355 | }) | 368 | }) |
356 | }) | 369 | }) |
357 | 370 | ||
371 | describe('Download hooks', function () { | ||
372 | const downloadVideos: VideoDetails[] = [] | ||
373 | |||
374 | before(async function () { | ||
375 | this.timeout(60000) | ||
376 | |||
377 | await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { | ||
378 | transcoding: { | ||
379 | webtorrent: { | ||
380 | enabled: true | ||
381 | }, | ||
382 | hls: { | ||
383 | enabled: true | ||
384 | } | ||
385 | } | ||
386 | }) | ||
387 | |||
388 | const uuids: string[] = [] | ||
389 | |||
390 | for (const name of [ 'bad torrent', 'bad file', 'bad playlist file' ]) { | ||
391 | const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: name })).uuid | ||
392 | uuids.push(uuid) | ||
393 | } | ||
394 | |||
395 | await waitJobs(servers) | ||
396 | |||
397 | for (const uuid of uuids) { | ||
398 | const res = await getVideo(servers[0].url, uuid) | ||
399 | downloadVideos.push(res.body) | ||
400 | } | ||
401 | }) | ||
402 | |||
403 | it('Should run filter:api.download.torrent.allowed.result', async function () { | ||
404 | const res = await makeRawRequest(downloadVideos[0].files[0].torrentDownloadUrl, 403) | ||
405 | expect(res.body.error).to.equal('Liu Bei') | ||
406 | |||
407 | await makeRawRequest(downloadVideos[1].files[0].torrentDownloadUrl, 200) | ||
408 | await makeRawRequest(downloadVideos[2].files[0].torrentDownloadUrl, 200) | ||
409 | }) | ||
410 | |||
411 | it('Should run filter:api.download.video.allowed.result', async function () { | ||
412 | { | ||
413 | const res = await makeRawRequest(downloadVideos[1].files[0].fileDownloadUrl, 403) | ||
414 | expect(res.body.error).to.equal('Cao Cao') | ||
415 | |||
416 | await makeRawRequest(downloadVideos[0].files[0].fileDownloadUrl, 200) | ||
417 | await makeRawRequest(downloadVideos[2].files[0].fileDownloadUrl, 200) | ||
418 | } | ||
419 | |||
420 | { | ||
421 | const res = await makeRawRequest(downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl, 403) | ||
422 | expect(res.body.error).to.equal('Sun Jian') | ||
423 | |||
424 | await makeRawRequest(downloadVideos[2].files[0].fileDownloadUrl, 200) | ||
425 | |||
426 | await makeRawRequest(downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl, 200) | ||
427 | await makeRawRequest(downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl, 200) | ||
428 | } | ||
429 | }) | ||
430 | }) | ||
431 | |||
432 | describe('Embed filters', function () { | ||
433 | const embedVideos: VideoDetails[] = [] | ||
434 | const embedPlaylists: VideoPlaylist[] = [] | ||
435 | |||
436 | before(async function () { | ||
437 | this.timeout(60000) | ||
438 | |||
439 | await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { | ||
440 | transcoding: { | ||
441 | enabled: false | ||
442 | } | ||
443 | }) | ||
444 | |||
445 | for (const name of [ 'bad embed', 'good embed' ]) { | ||
446 | { | ||
447 | const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: name })).uuid | ||
448 | const res = await getVideo(servers[0].url, uuid) | ||
449 | embedVideos.push(res.body) | ||
450 | } | ||
451 | |||
452 | { | ||
453 | const playlistAttrs = { displayName: name, videoChannelId: servers[0].videoChannel.id, privacy: VideoPlaylistPrivacy.PUBLIC } | ||
454 | const res = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs }) | ||
455 | |||
456 | const resPlaylist = await getVideoPlaylist(servers[0].url, res.body.videoPlaylist.id) | ||
457 | embedPlaylists.push(resPlaylist.body) | ||
458 | } | ||
459 | } | ||
460 | }) | ||
461 | |||
462 | it('Should run filter:html.embed.video.allowed.result', async function () { | ||
463 | const res = await makeRawRequest(servers[0].url + embedVideos[0].embedPath, 200) | ||
464 | expect(res.text).to.equal('Lu Bu') | ||
465 | }) | ||
466 | |||
467 | it('Should run filter:html.embed.video-playlist.allowed.result', async function () { | ||
468 | const res = await makeRawRequest(servers[0].url + embedPlaylists[0].embedPath, 200) | ||
469 | expect(res.text).to.equal('Diao Chan') | ||
470 | }) | ||
471 | }) | ||
472 | |||
473 | describe('Search filters', function () { | ||
474 | |||
475 | before(async function () { | ||
476 | await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { | ||
477 | search: { | ||
478 | searchIndex: { | ||
479 | enabled: true, | ||
480 | isDefaultSearch: false, | ||
481 | disableLocalSearch: false | ||
482 | } | ||
483 | } | ||
484 | }) | ||
485 | }) | ||
486 | |||
487 | it('Should run filter:api.search.videos.local.list.{params,result}', async function () { | ||
488 | await advancedVideosSearch(servers[0].url, { | ||
489 | search: 'Sun Quan' | ||
490 | }) | ||
491 | |||
492 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.params', 1) | ||
493 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.result', 1) | ||
494 | }) | ||
495 | |||
496 | it('Should run filter:api.search.videos.index.list.{params,result}', async function () { | ||
497 | await advancedVideosSearch(servers[0].url, { | ||
498 | search: 'Sun Quan', | ||
499 | searchTarget: 'search-index' | ||
500 | }) | ||
501 | |||
502 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.params', 1) | ||
503 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.result', 1) | ||
504 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.index.list.params', 1) | ||
505 | await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.index.list.result', 1) | ||
506 | }) | ||
507 | |||
508 | it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () { | ||
509 | await advancedVideoChannelSearch(servers[0].url, { | ||
510 | search: 'Sun Ce' | ||
511 | }) | ||
512 | |||
513 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.params', 1) | ||
514 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.result', 1) | ||
515 | }) | ||
516 | |||
517 | it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () { | ||
518 | await advancedVideoChannelSearch(servers[0].url, { | ||
519 | search: 'Sun Ce', | ||
520 | searchTarget: 'search-index' | ||
521 | }) | ||
522 | |||
523 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.params', 1) | ||
524 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.result', 1) | ||
525 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.index.list.params', 1) | ||
526 | await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.index.list.result', 1) | ||
527 | }) | ||
528 | }) | ||
529 | |||
358 | after(async function () { | 530 | after(async function () { |
359 | await cleanupTests(servers) | 531 | await cleanupTests(servers) |
360 | }) | 532 | }) |