aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/api/check-params/config.ts5
-rw-r--r--server/tests/api/check-params/video-source.ts148
-rw-r--r--server/tests/api/server/config.ts9
-rw-r--r--server/tests/api/videos/index.ts2
-rw-r--r--server/tests/api/videos/resumable-upload.ts8
-rw-r--r--server/tests/api/videos/video-source.ts447
-rw-r--r--server/tests/cli/prune-storage.ts22
-rw-r--r--server/tests/shared/videos.ts2
8 files changed, 587 insertions, 56 deletions
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index 80b616ccf..2f523d4ce 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -170,6 +170,11 @@ describe('Test config API validators', function () {
170 enabled: true 170 enabled: true
171 } 171 }
172 }, 172 },
173 videoFile: {
174 update: {
175 enabled: true
176 }
177 },
173 import: { 178 import: {
174 videos: { 179 videos: {
175 concurrency: 1, 180 concurrency: 1,
diff --git a/server/tests/api/check-params/video-source.ts b/server/tests/api/check-params/video-source.ts
index ca324bb9d..3c641ccd3 100644
--- a/server/tests/api/check-params/video-source.ts
+++ b/server/tests/api/check-params/video-source.ts
@@ -1,5 +1,12 @@
1import { HttpStatusCode } from '@shared/models' 1import { HttpStatusCode } from '@shared/models'
2import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' 2import {
3 cleanupTests,
4 createSingleServer,
5 PeerTubeServer,
6 setAccessTokensToServers,
7 setDefaultVideoChannel,
8 waitJobs
9} from '@shared/server-commands'
3 10
4describe('Test video sources API validator', function () { 11describe('Test video sources API validator', function () {
5 let server: PeerTubeServer = null 12 let server: PeerTubeServer = null
@@ -7,35 +14,138 @@ describe('Test video sources API validator', function () {
7 let userToken: string 14 let userToken: string
8 15
9 before(async function () { 16 before(async function () {
10 this.timeout(30000) 17 this.timeout(120000)
11 18
12 server = await createSingleServer(1) 19 server = await createSingleServer(1)
13 await setAccessTokensToServers([ server ]) 20 await setAccessTokensToServers([ server ])
21 await setDefaultVideoChannel([ server ])
14 22
15 const created = await server.videos.quickUpload({ name: 'video' }) 23 userToken = await server.users.generateUserAndToken('user1')
16 uuid = created.uuid
17
18 userToken = await server.users.generateUserAndToken('user')
19 }) 24 })
20 25
21 it('Should fail without a valid uuid', async function () { 26 describe('When getting latest source', function () {
22 await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df563d0b0', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
23 })
24 27
25 it('Should receive 404 when passing a non existing video id', async function () { 28 before(async function () {
26 await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df5630b06', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) 29 const created = await server.videos.quickUpload({ name: 'video' })
27 }) 30 uuid = created.uuid
31 })
28 32
29 it('Should not get the source as unauthenticated', async function () { 33 it('Should fail without a valid uuid', async function () {
30 await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401, token: null }) 34 await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df563d0b0', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
31 }) 35 })
36
37 it('Should receive 404 when passing a non existing video id', async function () {
38 await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df5630b06', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
39 })
40
41 it('Should not get the source as unauthenticated', async function () {
42 await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401, token: null })
43 })
44
45 it('Should not get the source with another user', async function () {
46 await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.FORBIDDEN_403, token: userToken })
47 })
32 48
33 it('Should not get the source with another user', async function () { 49 it('Should succeed with the correct parameters get the source as another user', async function () {
34 await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.FORBIDDEN_403, token: userToken }) 50 await server.videos.getSource({ id: uuid })
51 })
35 }) 52 })
36 53
37 it('Should succeed with the correct parameters get the source as another user', async function () { 54 describe('When updating source video file', function () {
38 await server.videos.getSource({ id: uuid }) 55 let userAccessToken: string
56 let userId: number
57
58 let videoId: string
59 let userVideoId: string
60
61 before(async function () {
62 const res = await server.users.generate('user2')
63 userAccessToken = res.token
64 userId = res.userId
65
66 const { uuid } = await server.videos.quickUpload({ name: 'video' })
67 videoId = uuid
68
69 await waitJobs([ server ])
70 })
71
72 it('Should fail if not enabled on the instance', async function () {
73 await server.config.disableFileUpdate()
74
75 await server.videos.replaceSourceFile({ videoId, fixture: 'video_short.mp4', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
76 })
77
78 it('Should fail on an unknown video', async function () {
79 await server.config.enableFileUpdate()
80
81 await server.videos.replaceSourceFile({ videoId: 404, fixture: 'video_short.mp4', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
82 })
83
84 it('Should fail with an invalid video', async function () {
85 await server.config.enableLive({ allowReplay: false })
86
87 const { video } = await server.live.quickCreate({ saveReplay: false, permanentLive: true })
88 await server.videos.replaceSourceFile({
89 videoId: video.uuid,
90 fixture: 'video_short.mp4',
91 expectedStatus: HttpStatusCode.BAD_REQUEST_400
92 })
93 })
94
95 it('Should fail without token', async function () {
96 await server.videos.replaceSourceFile({
97 token: null,
98 videoId,
99 fixture: 'video_short.mp4',
100 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
101 })
102 })
103
104 it('Should fail with another user', async function () {
105 await server.videos.replaceSourceFile({
106 token: userAccessToken,
107 videoId,
108 fixture: 'video_short.mp4',
109 expectedStatus: HttpStatusCode.FORBIDDEN_403
110 })
111 })
112
113 it('Should fail with an incorrect input file', async function () {
114 await server.videos.replaceSourceFile({
115 fixture: 'video_short_fake.webm',
116 videoId,
117 expectedStatus: HttpStatusCode.UNPROCESSABLE_ENTITY_422
118 })
119
120 await server.videos.replaceSourceFile({
121 fixture: 'video_short.mkv',
122 videoId,
123 expectedStatus: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415
124 })
125 })
126
127 it('Should fail if quota is exceeded', async function () {
128 this.timeout(60000)
129
130 const { uuid } = await server.videos.quickUpload({ name: 'user video' })
131 userVideoId = uuid
132 await waitJobs([ server ])
133
134 await server.users.update({ userId, videoQuota: 1 })
135 await server.videos.replaceSourceFile({
136 token: userAccessToken,
137 videoId: uuid,
138 fixture: 'video_short.mp4',
139 expectedStatus: HttpStatusCode.FORBIDDEN_403
140 })
141 })
142
143 it('Should succeed with the correct params', async function () {
144 this.timeout(60000)
145
146 await server.users.update({ userId, videoQuota: 1000 * 1000 * 1000 })
147 await server.videos.replaceSourceFile({ videoId: userVideoId, fixture: 'video_short.mp4' })
148 })
39 }) 149 })
40 150
41 after(async function () { 151 after(async function () {
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index 0e700eddb..a614d92d2 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -105,6 +105,8 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
105 expect(data.videoStudio.enabled).to.be.false 105 expect(data.videoStudio.enabled).to.be.false
106 expect(data.videoStudio.remoteRunners.enabled).to.be.false 106 expect(data.videoStudio.remoteRunners.enabled).to.be.false
107 107
108 expect(data.videoFile.update.enabled).to.be.false
109
108 expect(data.import.videos.concurrency).to.equal(2) 110 expect(data.import.videos.concurrency).to.equal(2)
109 expect(data.import.videos.http.enabled).to.be.true 111 expect(data.import.videos.http.enabled).to.be.true
110 expect(data.import.videos.torrent.enabled).to.be.true 112 expect(data.import.videos.torrent.enabled).to.be.true
@@ -216,6 +218,8 @@ function checkUpdatedConfig (data: CustomConfig) {
216 expect(data.videoStudio.enabled).to.be.true 218 expect(data.videoStudio.enabled).to.be.true
217 expect(data.videoStudio.remoteRunners.enabled).to.be.true 219 expect(data.videoStudio.remoteRunners.enabled).to.be.true
218 220
221 expect(data.videoFile.update.enabled).to.be.true
222
219 expect(data.import.videos.concurrency).to.equal(4) 223 expect(data.import.videos.concurrency).to.equal(4)
220 expect(data.import.videos.http.enabled).to.be.false 224 expect(data.import.videos.http.enabled).to.be.false
221 expect(data.import.videos.torrent.enabled).to.be.false 225 expect(data.import.videos.torrent.enabled).to.be.false
@@ -386,6 +390,11 @@ const newCustomConfig: CustomConfig = {
386 enabled: true 390 enabled: true
387 } 391 }
388 }, 392 },
393 videoFile: {
394 update: {
395 enabled: true
396 }
397 },
389 import: { 398 import: {
390 videos: { 399 videos: {
391 concurrency: 4, 400 concurrency: 4,
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts
index 9c79b3aa6..01d0c5852 100644
--- a/server/tests/api/videos/index.ts
+++ b/server/tests/api/videos/index.ts
@@ -13,11 +13,11 @@ import './video-imports'
13import './video-nsfw' 13import './video-nsfw'
14import './video-playlists' 14import './video-playlists'
15import './video-playlist-thumbnails' 15import './video-playlist-thumbnails'
16import './video-source'
16import './video-privacy' 17import './video-privacy'
17import './video-schedule-update' 18import './video-schedule-update'
18import './videos-common-filters' 19import './videos-common-filters'
19import './videos-history' 20import './videos-history'
20import './videos-overview' 21import './videos-overview'
21import './video-source'
22import './video-static-file-privacy' 22import './video-static-file-privacy'
23import './video-storyboard' 23import './video-storyboard'
diff --git a/server/tests/api/videos/resumable-upload.ts b/server/tests/api/videos/resumable-upload.ts
index 91eb61833..cac1201e9 100644
--- a/server/tests/api/videos/resumable-upload.ts
+++ b/server/tests/api/videos/resumable-upload.ts
@@ -11,6 +11,7 @@ import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServ
11// Most classic resumable upload tests are done in other test suites 11// Most classic resumable upload tests are done in other test suites
12 12
13describe('Test resumable upload', function () { 13describe('Test resumable upload', function () {
14 const path = '/api/v1/videos/upload-resumable'
14 const defaultFixture = 'video_short.mp4' 15 const defaultFixture = 'video_short.mp4'
15 let server: PeerTubeServer 16 let server: PeerTubeServer
16 let rootId: number 17 let rootId: number
@@ -44,7 +45,7 @@ describe('Test resumable upload', function () {
44 45
45 const mimetype = 'video/mp4' 46 const mimetype = 'video/mp4'
46 47
47 const res = await server.videos.prepareResumableUpload({ token, attributes, size, mimetype, originalName, lastModified }) 48 const res = await server.videos.prepareResumableUpload({ path, token, attributes, size, mimetype, originalName, lastModified })
48 49
49 return res.header['location'].split('?')[1] 50 return res.header['location'].split('?')[1]
50 } 51 }
@@ -66,6 +67,7 @@ describe('Test resumable upload', function () {
66 67
67 return server.videos.sendResumableChunks({ 68 return server.videos.sendResumableChunks({
68 token, 69 token,
70 path,
69 pathUploadId, 71 pathUploadId,
70 videoFilePath: absoluteFilePath, 72 videoFilePath: absoluteFilePath,
71 size, 73 size,
@@ -125,7 +127,7 @@ describe('Test resumable upload', function () {
125 it('Should correctly delete files after an upload', async function () { 127 it('Should correctly delete files after an upload', async function () {
126 const uploadId = await prepareUpload() 128 const uploadId = await prepareUpload()
127 await sendChunks({ pathUploadId: uploadId }) 129 await sendChunks({ pathUploadId: uploadId })
128 await server.videos.endResumableUpload({ pathUploadId: uploadId }) 130 await server.videos.endResumableUpload({ path, pathUploadId: uploadId })
129 131
130 expect(await countResumableUploads()).to.equal(0) 132 expect(await countResumableUploads()).to.equal(0)
131 }) 133 })
@@ -251,7 +253,7 @@ describe('Test resumable upload', function () {
251 const uploadId1 = await prepareUpload({ originalName, lastModified, token: server.accessToken }) 253 const uploadId1 = await prepareUpload({ originalName, lastModified, token: server.accessToken })
252 254
253 await sendChunks({ pathUploadId: uploadId1 }) 255 await sendChunks({ pathUploadId: uploadId1 })
254 await server.videos.endResumableUpload({ pathUploadId: uploadId1 }) 256 await server.videos.endResumableUpload({ path, pathUploadId: uploadId1 })
255 257
256 const uploadId2 = await prepareUpload({ originalName, lastModified, token: server.accessToken }) 258 const uploadId2 = await prepareUpload({ originalName, lastModified, token: server.accessToken })
257 expect(uploadId1).to.equal(uploadId2) 259 expect(uploadId1).to.equal(uploadId2)
diff --git a/server/tests/api/videos/video-source.ts b/server/tests/api/videos/video-source.ts
index 5ecf8316f..8669f342e 100644
--- a/server/tests/api/videos/video-source.ts
+++ b/server/tests/api/videos/video-source.ts
@@ -1,36 +1,447 @@
1import { expect } from 'chai' 1import { expect } from 'chai'
2import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' 2import { expectStartWith } from '@server/tests/shared'
3/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils'
5import { HttpStatusCode } from '@shared/models'
6import {
7 cleanupTests,
8 createMultipleServers,
9 doubleFollow,
10 makeGetRequest,
11 makeRawRequest,
12 ObjectStorageCommand,
13 PeerTubeServer,
14 setAccessTokensToServers,
15 setDefaultAccountAvatar,
16 setDefaultVideoChannel,
17 waitJobs
18} from '@shared/server-commands'
3 19
4describe('Test video source', () => { 20describe('Test a video file replacement', function () {
5 let server: PeerTubeServer = null 21 let servers: PeerTubeServer[] = []
6 const fixture = 'video_short.webm' 22
23 let replaceDate: Date
24 let userToken: string
25 let uuid: string
7 26
8 before(async function () { 27 before(async function () {
9 this.timeout(30000) 28 this.timeout(50000)
29
30 servers = await createMultipleServers(2)
31
32 // Get the access tokens
33 await setAccessTokensToServers(servers)
34 await setDefaultVideoChannel(servers)
35 await setDefaultAccountAvatar(servers)
36
37 await servers[0].config.enableFileUpdate()
10 38
11 server = await createSingleServer(1) 39 userToken = await servers[0].users.generateUserAndToken('user1')
12 await setAccessTokensToServers([ server ]) 40
41 // Server 1 and server 2 follow each other
42 await doubleFollow(servers[0], servers[1])
13 }) 43 })
14 44
15 it('Should get the source filename with legacy upload', async function () { 45 describe('Getting latest video source', () => {
16 this.timeout(30000) 46 const fixture = 'video_short.webm'
47 const uuids: string[] = []
48
49 it('Should get the source filename with legacy upload', async function () {
50 this.timeout(30000)
51
52 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' })
53 uuids.push(uuid)
17 54
18 const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' }) 55 const source = await servers[0].videos.getSource({ id: uuid })
56 expect(source.filename).to.equal(fixture)
57 })
19 58
20 const source = await server.videos.getSource({ id: uuid }) 59 it('Should get the source filename with resumable upload', async function () {
21 expect(source.filename).to.equal(fixture) 60 this.timeout(30000)
61
62 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' })
63 uuids.push(uuid)
64
65 const source = await servers[0].videos.getSource({ id: uuid })
66 expect(source.filename).to.equal(fixture)
67 })
68
69 after(async function () {
70 this.timeout(60000)
71
72 for (const uuid of uuids) {
73 await servers[0].videos.remove({ id: uuid })
74 }
75
76 await waitJobs(servers)
77 })
22 }) 78 })
23 79
24 it('Should get the source filename with resumable upload', async function () { 80 describe('Updating video source', function () {
25 this.timeout(30000) 81
82 describe('Filesystem', function () {
83
84 it('Should replace a video file with transcoding disabled', async function () {
85 this.timeout(120000)
86
87 await servers[0].config.disableTranscoding()
88
89 const { uuid } = await servers[0].videos.quickUpload({ name: 'fs without transcoding', fixture: 'video_short_720p.mp4' })
90 await waitJobs(servers)
91
92 for (const server of servers) {
93 const video = await server.videos.get({ id: uuid })
94
95 const files = getAllFiles(video)
96 expect(files).to.have.lengthOf(1)
97 expect(files[0].resolution.id).to.equal(720)
98 }
99
100 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
101 await waitJobs(servers)
102
103 for (const server of servers) {
104 const video = await server.videos.get({ id: uuid })
105
106 const files = getAllFiles(video)
107 expect(files).to.have.lengthOf(1)
108 expect(files[0].resolution.id).to.equal(360)
109 }
110 })
111
112 it('Should replace a video file with transcoding enabled', async function () {
113 this.timeout(120000)
114
115 const previousPaths: string[] = []
116
117 await servers[0].config.enableTranscoding(true, true, true)
118
119 const { uuid: videoUUID } = await servers[0].videos.quickUpload({ name: 'fs with transcoding', fixture: 'video_short_720p.mp4' })
120 uuid = videoUUID
121
122 await waitJobs(servers)
123
124 for (const server of servers) {
125 const video = await server.videos.get({ id: uuid })
126 expect(video.inputFileUpdatedAt).to.be.null
127
128 const files = getAllFiles(video)
129 expect(files).to.have.lengthOf(6 * 2)
130
131 // Grab old paths to ensure we'll regenerate
132
133 previousPaths.push(video.previewPath)
134 previousPaths.push(video.thumbnailPath)
135
136 for (const file of files) {
137 previousPaths.push(file.fileUrl)
138 previousPaths.push(file.torrentUrl)
139 previousPaths.push(file.metadataUrl)
140
141 const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl })
142 previousPaths.push(JSON.stringify(metadata))
143 }
144
145 const { storyboards } = await server.storyboard.list({ id: uuid })
146 for (const s of storyboards) {
147 previousPaths.push(s.storyboardPath)
148 }
149 }
150
151 replaceDate = new Date()
152
153 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
154 await waitJobs(servers)
155
156 for (const server of servers) {
157 const video = await server.videos.get({ id: uuid })
158
159 expect(video.inputFileUpdatedAt).to.not.be.null
160 expect(new Date(video.inputFileUpdatedAt)).to.be.above(replaceDate)
161
162 const files = getAllFiles(video)
163 expect(files).to.have.lengthOf(4 * 2)
164
165 expect(previousPaths).to.not.include(video.previewPath)
166 expect(previousPaths).to.not.include(video.thumbnailPath)
167
168 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
169 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
170
171 for (const file of files) {
172 expect(previousPaths).to.not.include(file.fileUrl)
173 expect(previousPaths).to.not.include(file.torrentUrl)
174 expect(previousPaths).to.not.include(file.metadataUrl)
175
176 await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 })
177 await makeRawRequest({ url: file.torrentUrl, expectedStatus: HttpStatusCode.OK_200 })
178
179 const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl })
180 expect(previousPaths).to.not.include(JSON.stringify(metadata))
181 }
182
183 const { storyboards } = await server.storyboard.list({ id: uuid })
184 for (const s of storyboards) {
185 expect(previousPaths).to.not.include(s.storyboardPath)
186
187 await makeGetRequest({ url: server.url, path: s.storyboardPath, expectedStatus: HttpStatusCode.OK_200 })
188 }
189 }
190
191 await servers[0].config.enableMinimumTranscoding()
192 })
193
194 it('Should have cleaned up old files', async function () {
195 {
196 const count = await servers[0].servers.countFiles('storyboards')
197 expect(count).to.equal(2)
198 }
199
200 {
201 const count = await servers[0].servers.countFiles('web-videos')
202 expect(count).to.equal(5 + 1) // +1 for private directory
203 }
204
205 {
206 const count = await servers[0].servers.countFiles('streaming-playlists/hls')
207 expect(count).to.equal(1 + 1) // +1 for private directory
208 }
209
210 {
211 const count = await servers[0].servers.countFiles('torrents')
212 expect(count).to.equal(9)
213 }
214 })
215
216 it('Should have the correct source input', async function () {
217 const source = await servers[0].videos.getSource({ id: uuid })
218
219 expect(source.filename).to.equal('video_short_360p.mp4')
220 expect(new Date(source.createdAt)).to.be.above(replaceDate)
221 })
222
223 it('Should not have regenerated miniatures that were previously uploaded', async function () {
224 this.timeout(120000)
225
226 const { uuid } = await servers[0].videos.upload({
227 attributes: {
228 name: 'custom miniatures',
229 thumbnailfile: 'custom-thumbnail.jpg',
230 previewfile: 'custom-preview.jpg'
231 }
232 })
233
234 await waitJobs(servers)
235
236 const previousPaths: string[] = []
237
238 for (const server of servers) {
239 const video = await server.videos.get({ id: uuid })
240
241 previousPaths.push(video.previewPath)
242 previousPaths.push(video.thumbnailPath)
243
244 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
245 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
246 }
247
248 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
249 await waitJobs(servers)
250
251 for (const server of servers) {
252 const video = await server.videos.get({ id: uuid })
253
254 expect(previousPaths).to.include(video.previewPath)
255 expect(previousPaths).to.include(video.thumbnailPath)
256
257 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
258 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
259 }
260 })
261 })
262
263 describe('Autoblacklist', function () {
264
265 function updateAutoBlacklist (enabled: boolean) {
266 return servers[0].config.updateExistingSubConfig({
267 newConfig: {
268 autoBlacklist: {
269 videos: {
270 ofUsers: {
271 enabled
272 }
273 }
274 }
275 }
276 })
277 }
278
279 async function expectBlacklist (uuid: string, value: boolean) {
280 const video = await servers[0].videos.getWithToken({ id: uuid })
281
282 expect(video.blacklisted).to.equal(value)
283 }
284
285 before(async function () {
286 await updateAutoBlacklist(true)
287 })
288
289 it('Should auto blacklist an unblacklisted video after file replacement', async function () {
290 this.timeout(120000)
291
292 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
293 await waitJobs(servers)
294 await expectBlacklist(uuid, true)
295
296 await servers[0].blacklist.remove({ videoId: uuid })
297 await expectBlacklist(uuid, false)
298
299 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' })
300 await waitJobs(servers)
301
302 await expectBlacklist(uuid, true)
303 })
304
305 it('Should auto blacklist an already blacklisted video after file replacement', async function () {
306 this.timeout(120000)
307
308 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
309 await waitJobs(servers)
310 await expectBlacklist(uuid, true)
311
312 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' })
313 await waitJobs(servers)
314
315 await expectBlacklist(uuid, true)
316 })
317
318 it('Should not auto blacklist if auto blacklist has been disabled between the upload and the replacement', async function () {
319 this.timeout(120000)
320
321 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
322 await waitJobs(servers)
323 await expectBlacklist(uuid, true)
324
325 await servers[0].blacklist.remove({ videoId: uuid })
326 await expectBlacklist(uuid, false)
327
328 await updateAutoBlacklist(false)
329
330 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short1.webm' })
331 await waitJobs(servers)
332
333 await expectBlacklist(uuid, false)
334 })
335 })
336
337 describe('With object storage enabled', function () {
338 if (areMockObjectStorageTestsDisabled()) return
339
340 const objectStorage = new ObjectStorageCommand()
341
342 before(async function () {
343 this.timeout(120000)
344
345 const configOverride = objectStorage.getDefaultMockConfig()
346 await objectStorage.prepareDefaultMockBuckets()
347
348 await servers[0].kill()
349 await servers[0].run(configOverride)
350 })
351
352 it('Should replace a video file with transcoding disabled', async function () {
353 this.timeout(120000)
354
355 await servers[0].config.disableTranscoding()
356
357 const { uuid } = await servers[0].videos.quickUpload({
358 name: 'object storage without transcoding',
359 fixture: 'video_short_720p.mp4'
360 })
361 await waitJobs(servers)
362
363 for (const server of servers) {
364 const video = await server.videos.get({ id: uuid })
365
366 const files = getAllFiles(video)
367 expect(files).to.have.lengthOf(1)
368 expect(files[0].resolution.id).to.equal(720)
369 expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl())
370 }
371
372 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
373 await waitJobs(servers)
374
375 for (const server of servers) {
376 const video = await server.videos.get({ id: uuid })
377
378 const files = getAllFiles(video)
379 expect(files).to.have.lengthOf(1)
380 expect(files[0].resolution.id).to.equal(360)
381 expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl())
382 }
383 })
384
385 it('Should replace a video file with transcoding enabled', async function () {
386 this.timeout(120000)
387
388 const previousPaths: string[] = []
389
390 await servers[0].config.enableTranscoding(true, true, true)
391
392 const { uuid: videoUUID } = await servers[0].videos.quickUpload({
393 name: 'object storage with transcoding',
394 fixture: 'video_short_360p.mp4'
395 })
396 uuid = videoUUID
397
398 await waitJobs(servers)
399
400 for (const server of servers) {
401 const video = await server.videos.get({ id: uuid })
402
403 const files = getAllFiles(video)
404 expect(files).to.have.lengthOf(4 * 2)
405
406 for (const file of files) {
407 previousPaths.push(file.fileUrl)
408 }
409
410 for (const file of video.files) {
411 expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl())
412 }
413
414 for (const file of video.streamingPlaylists[0].files) {
415 expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl())
416 }
417 }
418
419 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_240p.mp4' })
420 await waitJobs(servers)
421
422 for (const server of servers) {
423 const video = await server.videos.get({ id: uuid })
424
425 const files = getAllFiles(video)
426 expect(files).to.have.lengthOf(3 * 2)
427
428 for (const file of files) {
429 expect(previousPaths).to.not.include(file.fileUrl)
430 }
26 431
27 const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' }) 432 for (const file of video.files) {
433 expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl())
434 }
28 435
29 const source = await server.videos.getSource({ id: uuid }) 436 for (const file of video.streamingPlaylists[0].files) {
30 expect(source.filename).to.equal(fixture) 437 expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl())
438 }
439 }
440 })
441 })
31 }) 442 })
32 443
33 after(async function () { 444 after(async function () {
34 await cleanupTests([ server ]) 445 await cleanupTests(servers)
35 }) 446 })
36}) 447})
diff --git a/server/tests/cli/prune-storage.ts b/server/tests/cli/prune-storage.ts
index 00f63570f..72a4b1332 100644
--- a/server/tests/cli/prune-storage.ts
+++ b/server/tests/cli/prune-storage.ts
@@ -19,12 +19,6 @@ import {
19 waitJobs 19 waitJobs
20} from '@shared/server-commands' 20} from '@shared/server-commands'
21 21
22async function countFiles (server: PeerTubeServer, directory: string) {
23 const files = await readdir(server.servers.buildDirectory(directory))
24
25 return files.length
26}
27
28async function assertNotExists (server: PeerTubeServer, directory: string, substring: string) { 22async function assertNotExists (server: PeerTubeServer, directory: string, substring: string) {
29 const files = await readdir(server.servers.buildDirectory(directory)) 23 const files = await readdir(server.servers.buildDirectory(directory))
30 24
@@ -35,28 +29,28 @@ async function assertNotExists (server: PeerTubeServer, directory: string, subst
35 29
36async function assertCountAreOkay (servers: PeerTubeServer[]) { 30async function assertCountAreOkay (servers: PeerTubeServer[]) {
37 for (const server of servers) { 31 for (const server of servers) {
38 const videosCount = await countFiles(server, 'web-videos') 32 const videosCount = await server.servers.countFiles('web-videos')
39 expect(videosCount).to.equal(9) // 2 videos with 4 resolutions + private directory 33 expect(videosCount).to.equal(9) // 2 videos with 4 resolutions + private directory
40 34
41 const privateVideosCount = await countFiles(server, 'web-videos/private') 35 const privateVideosCount = await server.servers.countFiles('web-videos/private')
42 expect(privateVideosCount).to.equal(4) 36 expect(privateVideosCount).to.equal(4)
43 37
44 const torrentsCount = await countFiles(server, 'torrents') 38 const torrentsCount = await server.servers.countFiles('torrents')
45 expect(torrentsCount).to.equal(24) 39 expect(torrentsCount).to.equal(24)
46 40
47 const previewsCount = await countFiles(server, 'previews') 41 const previewsCount = await server.servers.countFiles('previews')
48 expect(previewsCount).to.equal(3) 42 expect(previewsCount).to.equal(3)
49 43
50 const thumbnailsCount = await countFiles(server, 'thumbnails') 44 const thumbnailsCount = await server.servers.countFiles('thumbnails')
51 expect(thumbnailsCount).to.equal(5) // 3 local videos, 1 local playlist, 2 remotes videos (lazy downloaded) and 1 remote playlist 45 expect(thumbnailsCount).to.equal(5) // 3 local videos, 1 local playlist, 2 remotes videos (lazy downloaded) and 1 remote playlist
52 46
53 const avatarsCount = await countFiles(server, 'avatars') 47 const avatarsCount = await server.servers.countFiles('avatars')
54 expect(avatarsCount).to.equal(4) 48 expect(avatarsCount).to.equal(4)
55 49
56 const hlsRootCount = await countFiles(server, join('streaming-playlists', 'hls')) 50 const hlsRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls'))
57 expect(hlsRootCount).to.equal(3) // 2 videos + private directory 51 expect(hlsRootCount).to.equal(3) // 2 videos + private directory
58 52
59 const hlsPrivateRootCount = await countFiles(server, join('streaming-playlists', 'hls', 'private')) 53 const hlsPrivateRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls', 'private'))
60 expect(hlsPrivateRootCount).to.equal(1) 54 expect(hlsPrivateRootCount).to.equal(1)
61 } 55 }
62} 56}
diff --git a/server/tests/shared/videos.ts b/server/tests/shared/videos.ts
index e09bd60b5..3f59c329f 100644
--- a/server/tests/shared/videos.ts
+++ b/server/tests/shared/videos.ts
@@ -277,7 +277,7 @@ function checkUploadVideoParam (
277) { 277) {
278 return mode === 'legacy' 278 return mode === 'legacy'
279 ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus }) 279 ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus })
280 : server.videos.buildResumeUpload({ token, attributes, expectedStatus }) 280 : server.videos.buildResumeUpload({ token, attributes, expectedStatus, path: '/api/v1/videos/upload-resumable' })
281} 281}
282 282
283// serverNumber starts from 1 283// serverNumber starts from 1