diff options
author | kontrollanten <6680299+kontrollanten@users.noreply.github.com> | 2021-05-10 11:13:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-10 11:13:41 +0200 |
commit | f6d6e7f861189a4446f406efb775a29688764b48 (patch) | |
tree | c3dda9958c3f189d4c39e8743c738d8c1fef4c2d /server/tests/api/check-params/users.ts | |
parent | d29ced1a8582d99b776f664475a157adcf555d98 (diff) | |
download | PeerTube-f6d6e7f861189a4446f406efb775a29688764b48.tar.gz PeerTube-f6d6e7f861189a4446f406efb775a29688764b48.tar.zst PeerTube-f6d6e7f861189a4446f406efb775a29688764b48.zip |
Resumable video uploads (#3933)
* WIP: resumable video uploads
relates to #324
* fix review comments
* video upload: error handling
* fix audio upload
* fixes after self review
* Update server/controllers/api/videos/index.ts
Co-authored-by: Rigel Kent <par@rigelk.eu>
* Update server/middlewares/validators/videos/videos.ts
Co-authored-by: Rigel Kent <par@rigelk.eu>
* Update server/controllers/api/videos/index.ts
Co-authored-by: Rigel Kent <par@rigelk.eu>
* update after code review
* refactor upload route
- restore multipart upload route
- move resumable to dedicated upload-resumable route
- move checks to middleware
- do not leak internal fs structure in response
* fix yarn.lock upon rebase
* factorize addVideo for reuse in both endpoints
* add resumable upload API to openapi spec
* add initial test and test helper for resumable upload
* typings for videoAddResumable middleware
* avoid including aws and google packages via node-uploadx, by only including uploadx/core
* rename ex-isAudioBg to more explicit name mentioning it is a preview file for audio
* add video-upload-tmp-folder-cleaner job
* stronger typing of video upload middleware
* reduce dependency to @uploadx/core
* add audio upload test
* refactor resumable uploads cleanup from job to scheduler
* refactor resumable uploads scheduler to compare to last execution time
* make resumable upload validator to always cleanup on failure
* move legacy upload request building outside of uploadVideo test helper
* filter upload-resumable middlewares down to POST, PUT, DELETE
also begin to type metadata
* merge add duration functions
* stronger typings and documentation for uploadx behaviour, move init validator up
* refactor(client/video-edit): options > uploadxOptions
* refactor(client/video-edit): remove obsolete else
* scheduler/remove-dangling-resum: rename tag
* refactor(server/video): add UploadVideoFiles type
* refactor(mw/validators): restructure eslint disable
* refactor(mw/validators/videos): rename import
* refactor(client/vid-upload): rename html elem id
* refactor(sched/remove-dangl): move fn to method
* refactor(mw/async): add method typing
* refactor(mw/vali/video): double quote > single
* refactor(server/upload-resum): express use > all
* proper http methud enum server/middlewares/async.ts
* properly type http methods
* factorize common video upload validation steps
* add check for maximum partially uploaded file size
* fix audioBg use
* fix extname(filename) in addVideo
* document parameters for uploadx's resumable protocol
* clear META files in scheduler
* last audio refactor before cramming preview in the initial POST form data
* refactor as mulitpart/form-data initial post request
this allows preview/thumbnail uploads alongside the initial request,
and cleans up the upload form
* Add more tests for resumable uploads
* Refactor remove dangling resumable uploads
* Prepare changelog
* Add more resumable upload tests
* Remove user quota check for resumable uploads
* Fix upload error handler
* Update nginx template for upload-resumable
* Cleanup comment
* Remove unused express methods
* Prefer to use got instead of raw http
* Don't retry on error 500
Co-authored-by: Rigel Kent <par@rigelk.eu>
Co-authored-by: Rigel Kent <sendmemail@rigelk.eu>
Co-authored-by: Chocobozzz <me@florianbigard.com>
Diffstat (limited to 'server/tests/api/check-params/users.ts')
-rw-r--r-- | server/tests/api/check-params/users.ts | 105 |
1 files changed, 2 insertions, 103 deletions
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 2b03fde2d..dcff0d52b 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -1,10 +1,10 @@ | |||
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 { expect } from 'chai' | ||
5 | import { omit } from 'lodash' | 4 | import { omit } from 'lodash' |
6 | import { join } from 'path' | 5 | import { join } from 'path' |
7 | import { User, UserRole, VideoImport, VideoImportState } from '../../../../shared' | 6 | import { User, UserRole } from '../../../../shared' |
7 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
8 | import { | 8 | import { |
9 | addVideoChannel, | 9 | addVideoChannel, |
10 | blockUser, | 10 | blockUser, |
@@ -29,7 +29,6 @@ import { | |||
29 | ServerInfo, | 29 | ServerInfo, |
30 | setAccessTokensToServers, | 30 | setAccessTokensToServers, |
31 | unblockUser, | 31 | unblockUser, |
32 | updateUser, | ||
33 | uploadVideo, | 32 | uploadVideo, |
34 | userLogin | 33 | userLogin |
35 | } from '../../../../shared/extra-utils' | 34 | } from '../../../../shared/extra-utils' |
@@ -39,11 +38,7 @@ import { | |||
39 | checkBadSortPagination, | 38 | checkBadSortPagination, |
40 | checkBadStartPagination | 39 | checkBadStartPagination |
41 | } from '../../../../shared/extra-utils/requests/check-api-params' | 40 | } from '../../../../shared/extra-utils/requests/check-api-params' |
42 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
43 | import { getGoodVideoUrl, getMagnetURI, getMyVideoImports, importVideo } from '../../../../shared/extra-utils/videos/video-imports' | ||
44 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' | 41 | import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' |
45 | import { VideoPrivacy } from '../../../../shared/models/videos' | ||
46 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
47 | 42 | ||
48 | describe('Test users API validators', function () { | 43 | describe('Test users API validators', function () { |
49 | const path = '/api/v1/users/' | 44 | const path = '/api/v1/users/' |
@@ -1093,102 +1088,6 @@ describe('Test users API validators', function () { | |||
1093 | }) | 1088 | }) |
1094 | }) | 1089 | }) |
1095 | 1090 | ||
1096 | describe('When having a video quota', function () { | ||
1097 | it('Should fail with a user having too many videos', async function () { | ||
1098 | await updateUser({ | ||
1099 | url: server.url, | ||
1100 | userId: rootId, | ||
1101 | accessToken: server.accessToken, | ||
1102 | videoQuota: 42 | ||
1103 | }) | ||
1104 | |||
1105 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
1106 | }) | ||
1107 | |||
1108 | it('Should fail with a registered user having too many videos', async function () { | ||
1109 | this.timeout(30000) | ||
1110 | |||
1111 | const user = { | ||
1112 | username: 'user3', | ||
1113 | password: 'my super password' | ||
1114 | } | ||
1115 | userAccessToken = await userLogin(server, user) | ||
1116 | |||
1117 | const videoAttributes = { fixture: 'video_short2.webm' } | ||
1118 | await uploadVideo(server.url, userAccessToken, videoAttributes) | ||
1119 | await uploadVideo(server.url, userAccessToken, videoAttributes) | ||
1120 | await uploadVideo(server.url, userAccessToken, videoAttributes) | ||
1121 | await uploadVideo(server.url, userAccessToken, videoAttributes) | ||
1122 | await uploadVideo(server.url, userAccessToken, videoAttributes) | ||
1123 | await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
1124 | }) | ||
1125 | |||
1126 | it('Should fail to import with HTTP/Torrent/magnet', async function () { | ||
1127 | this.timeout(120000) | ||
1128 | |||
1129 | const baseAttributes = { | ||
1130 | channelId: 1, | ||
1131 | privacy: VideoPrivacy.PUBLIC | ||
1132 | } | ||
1133 | await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getGoodVideoUrl() })) | ||
1134 | await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() })) | ||
1135 | await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' as any })) | ||
1136 | |||
1137 | await waitJobs([ server ]) | ||
1138 | |||
1139 | const res = await getMyVideoImports(server.url, server.accessToken) | ||
1140 | |||
1141 | expect(res.body.total).to.equal(3) | ||
1142 | const videoImports: VideoImport[] = res.body.data | ||
1143 | expect(videoImports).to.have.lengthOf(3) | ||
1144 | |||
1145 | for (const videoImport of videoImports) { | ||
1146 | expect(videoImport.state.id).to.equal(VideoImportState.FAILED) | ||
1147 | expect(videoImport.error).not.to.be.undefined | ||
1148 | expect(videoImport.error).to.contain('user video quota is exceeded') | ||
1149 | } | ||
1150 | }) | ||
1151 | }) | ||
1152 | |||
1153 | describe('When having a daily video quota', function () { | ||
1154 | it('Should fail with a user having too many videos daily', async function () { | ||
1155 | await updateUser({ | ||
1156 | url: server.url, | ||
1157 | userId: rootId, | ||
1158 | accessToken: server.accessToken, | ||
1159 | videoQuotaDaily: 42 | ||
1160 | }) | ||
1161 | |||
1162 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
1163 | }) | ||
1164 | }) | ||
1165 | |||
1166 | describe('When having an absolute and daily video quota', function () { | ||
1167 | it('Should fail if exceeding total quota', async function () { | ||
1168 | await updateUser({ | ||
1169 | url: server.url, | ||
1170 | userId: rootId, | ||
1171 | accessToken: server.accessToken, | ||
1172 | videoQuota: 42, | ||
1173 | videoQuotaDaily: 1024 * 1024 * 1024 | ||
1174 | }) | ||
1175 | |||
1176 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
1177 | }) | ||
1178 | |||
1179 | it('Should fail if exceeding daily quota', async function () { | ||
1180 | await updateUser({ | ||
1181 | url: server.url, | ||
1182 | userId: rootId, | ||
1183 | accessToken: server.accessToken, | ||
1184 | videoQuota: 1024 * 1024 * 1024, | ||
1185 | videoQuotaDaily: 42 | ||
1186 | }) | ||
1187 | |||
1188 | await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) | ||
1189 | }) | ||
1190 | }) | ||
1191 | |||
1192 | describe('When asking a password reset', function () { | 1091 | describe('When asking a password reset', function () { |
1193 | const path = '/api/v1/users/ask-reset-password' | 1092 | const path = '/api/v1/users/ask-reset-password' |
1194 | 1093 | ||