diff options
Diffstat (limited to 'server/tests')
-rw-r--r-- | server/tests/api/check-params/config.ts | 5 | ||||
-rw-r--r-- | server/tests/api/check-params/video-source.ts | 148 | ||||
-rw-r--r-- | server/tests/api/server/config.ts | 9 | ||||
-rw-r--r-- | server/tests/api/videos/index.ts | 2 | ||||
-rw-r--r-- | server/tests/api/videos/resumable-upload.ts | 8 | ||||
-rw-r--r-- | server/tests/api/videos/video-source.ts | 447 | ||||
-rw-r--r-- | server/tests/cli/prune-storage.ts | 22 | ||||
-rw-r--r-- | server/tests/shared/videos.ts | 2 |
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 @@ | |||
1 | import { HttpStatusCode } from '@shared/models' | 1 | import { HttpStatusCode } from '@shared/models' |
2 | import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' | 2 | import { |
3 | cleanupTests, | ||
4 | createSingleServer, | ||
5 | PeerTubeServer, | ||
6 | setAccessTokensToServers, | ||
7 | setDefaultVideoChannel, | ||
8 | waitJobs | ||
9 | } from '@shared/server-commands' | ||
3 | 10 | ||
4 | describe('Test video sources API validator', function () { | 11 | describe('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' | |||
13 | import './video-nsfw' | 13 | import './video-nsfw' |
14 | import './video-playlists' | 14 | import './video-playlists' |
15 | import './video-playlist-thumbnails' | 15 | import './video-playlist-thumbnails' |
16 | import './video-source' | ||
16 | import './video-privacy' | 17 | import './video-privacy' |
17 | import './video-schedule-update' | 18 | import './video-schedule-update' |
18 | import './videos-common-filters' | 19 | import './videos-common-filters' |
19 | import './videos-history' | 20 | import './videos-history' |
20 | import './videos-overview' | 21 | import './videos-overview' |
21 | import './video-source' | ||
22 | import './video-static-file-privacy' | 22 | import './video-static-file-privacy' |
23 | import './video-storyboard' | 23 | import './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 | ||
13 | describe('Test resumable upload', function () { | 13 | describe('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 @@ | |||
1 | import { expect } from 'chai' | 1 | import { expect } from 'chai' |
2 | import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' | 2 | import { expectStartWith } from '@server/tests/shared' |
3 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
4 | import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils' | ||
5 | import { HttpStatusCode } from '@shared/models' | ||
6 | import { | ||
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 | ||
4 | describe('Test video source', () => { | 20 | describe('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 | ||
22 | async function countFiles (server: PeerTubeServer, directory: string) { | ||
23 | const files = await readdir(server.servers.buildDirectory(directory)) | ||
24 | |||
25 | return files.length | ||
26 | } | ||
27 | |||
28 | async function assertNotExists (server: PeerTubeServer, directory: string, substring: string) { | 22 | async 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 | ||
36 | async function assertCountAreOkay (servers: PeerTubeServer[]) { | 30 | async 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 |