diff options
author | Chocobozzz <me@florianbigard.com> | 2018-06-29 11:29:23 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-06-29 11:29:23 +0200 |
commit | 4bbfc6c606c8d3794bae25c64c516120af41f4eb (patch) | |
tree | 8d6012f3c04e55e7325e3f00eb9061776cc7a953 /server | |
parent | 3ff5a19b4c988d6c712b7ce63c4cf04f99d047ce (diff) | |
download | PeerTube-4bbfc6c606c8d3794bae25c64c516120af41f4eb.tar.gz PeerTube-4bbfc6c606c8d3794bae25c64c516120af41f4eb.tar.zst PeerTube-4bbfc6c606c8d3794bae25c64c516120af41f4eb.zip |
API: Add ability to update video channel avatar
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users.ts | 34 | ||||
-rw-r--r-- | server/controllers/api/video-channel.ts | 30 | ||||
-rw-r--r-- | server/lib/avatar.ts | 34 | ||||
-rw-r--r-- | server/middlewares/validators/avatar.ts | 25 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 21 | ||||
-rw-r--r-- | server/middlewares/validators/video-channels.ts | 2 | ||||
-rw-r--r-- | server/tests/api/check-params/users.ts | 14 | ||||
-rw-r--r-- | server/tests/api/check-params/video-channels.ts | 56 | ||||
-rw-r--r-- | server/tests/api/videos/video-channels.ts | 34 | ||||
-rw-r--r-- | server/tests/utils/requests/requests.ts | 29 | ||||
-rw-r--r-- | server/tests/utils/users/users.ts | 18 | ||||
-rw-r--r-- | server/tests/utils/videos/video-channels.ts | 14 |
12 files changed, 243 insertions, 68 deletions
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 891056912..c80f27a23 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -1,14 +1,10 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import 'multer' | 2 | import 'multer' |
3 | import { extname, join } from 'path' | ||
4 | import * as uuidv4 from 'uuid/v4' | ||
5 | import * as RateLimit from 'express-rate-limit' | 3 | import * as RateLimit from 'express-rate-limit' |
6 | import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared' | 4 | import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared' |
7 | import { processImage } from '../../helpers/image-utils' | ||
8 | import { logger } from '../../helpers/logger' | 5 | import { logger } from '../../helpers/logger' |
9 | import { getFormattedObjects } from '../../helpers/utils' | 6 | import { getFormattedObjects } from '../../helpers/utils' |
10 | import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, RATES_LIMIT, sequelizeTypescript } from '../../initializers' | 7 | import { CONFIG, IMAGE_MIMETYPE_EXT, RATES_LIMIT, sequelizeTypescript } from '../../initializers' |
11 | import { updateActorAvatarInstance } from '../../lib/activitypub' | ||
12 | import { sendUpdateActor } from '../../lib/activitypub/send' | 8 | import { sendUpdateActor } from '../../lib/activitypub/send' |
13 | import { Emailer } from '../../lib/emailer' | 9 | import { Emailer } from '../../lib/emailer' |
14 | import { Redis } from '../../lib/redis' | 10 | import { Redis } from '../../lib/redis' |
@@ -33,12 +29,7 @@ import { | |||
33 | usersUpdateValidator, | 29 | usersUpdateValidator, |
34 | usersVideoRatingValidator | 30 | usersVideoRatingValidator |
35 | } from '../../middlewares' | 31 | } from '../../middlewares' |
36 | import { | 32 | import { usersAskResetPasswordValidator, usersResetPasswordValidator, videosSortValidator } from '../../middlewares/validators' |
37 | usersAskResetPasswordValidator, | ||
38 | usersResetPasswordValidator, | ||
39 | usersUpdateMyAvatarValidator, | ||
40 | videosSortValidator | ||
41 | } from '../../middlewares/validators' | ||
42 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' | 33 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' |
43 | import { UserModel } from '../../models/account/user' | 34 | import { UserModel } from '../../models/account/user' |
44 | import { OAuthTokenModel } from '../../models/oauth/oauth-token' | 35 | import { OAuthTokenModel } from '../../models/oauth/oauth-token' |
@@ -46,6 +37,8 @@ import { VideoModel } from '../../models/video/video' | |||
46 | import { VideoSortField } from '../../../client/src/app/shared/video/sort-field.type' | 37 | import { VideoSortField } from '../../../client/src/app/shared/video/sort-field.type' |
47 | import { createReqFiles } from '../../helpers/express-utils' | 38 | import { createReqFiles } from '../../helpers/express-utils' |
48 | import { UserVideoQuota } from '../../../shared/models/users/user-video-quota.model' | 39 | import { UserVideoQuota } from '../../../shared/models/users/user-video-quota.model' |
40 | import { updateAvatarValidator } from '../../middlewares/validators/avatar' | ||
41 | import { updateActorAvatarFile } from '../../lib/avatar' | ||
49 | 42 | ||
50 | const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR }) | 43 | const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR }) |
51 | const loginRateLimiter = new RateLimit({ | 44 | const loginRateLimiter = new RateLimit({ |
@@ -121,7 +114,7 @@ usersRouter.put('/me', | |||
121 | usersRouter.post('/me/avatar/pick', | 114 | usersRouter.post('/me/avatar/pick', |
122 | authenticate, | 115 | authenticate, |
123 | reqAvatarFile, | 116 | reqAvatarFile, |
124 | usersUpdateMyAvatarValidator, | 117 | updateAvatarValidator, |
125 | asyncMiddleware(updateMyAvatar) | 118 | asyncMiddleware(updateMyAvatar) |
126 | ) | 119 | ) |
127 | 120 | ||
@@ -304,22 +297,9 @@ async function updateMe (req: express.Request, res: express.Response, next: expr | |||
304 | 297 | ||
305 | async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { | 298 | async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { |
306 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] | 299 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] |
307 | const user = res.locals.oauth.token.user | 300 | const account = res.locals.oauth.token.user.Account |
308 | const actor = user.Account.Actor | ||
309 | |||
310 | const extension = extname(avatarPhysicalFile.filename) | ||
311 | const avatarName = uuidv4() + extension | ||
312 | const destination = join(CONFIG.STORAGE.AVATARS_DIR, avatarName) | ||
313 | await processImage(avatarPhysicalFile, destination, AVATARS_SIZE) | ||
314 | |||
315 | const avatar = await sequelizeTypescript.transaction(async t => { | ||
316 | const updatedActor = await updateActorAvatarInstance(actor, avatarName, t) | ||
317 | await updatedActor.save({ transaction: t }) | ||
318 | 301 | ||
319 | await sendUpdateActor(user.Account, t) | 302 | const avatar = await updateActorAvatarFile(avatarPhysicalFile, account.Actor, account) |
320 | |||
321 | return updatedActor.Avatar | ||
322 | }) | ||
323 | 303 | ||
324 | return res | 304 | return res |
325 | .json({ | 305 | .json({ |
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index 61e72125f..1707732ee 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts | |||
@@ -19,12 +19,16 @@ import { videosSortValidator } from '../../middlewares/validators' | |||
19 | import { sendUpdateActor } from '../../lib/activitypub/send' | 19 | import { sendUpdateActor } from '../../lib/activitypub/send' |
20 | import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' | 20 | import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' |
21 | import { createVideoChannel } from '../../lib/video-channel' | 21 | import { createVideoChannel } from '../../lib/video-channel' |
22 | import { isNSFWHidden } from '../../helpers/express-utils' | 22 | import { createReqFiles, isNSFWHidden } from '../../helpers/express-utils' |
23 | import { setAsyncActorKeys } from '../../lib/activitypub' | 23 | import { setAsyncActorKeys } from '../../lib/activitypub' |
24 | import { AccountModel } from '../../models/account/account' | 24 | import { AccountModel } from '../../models/account/account' |
25 | import { sequelizeTypescript } from '../../initializers' | 25 | import { CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers' |
26 | import { logger } from '../../helpers/logger' | 26 | import { logger } from '../../helpers/logger' |
27 | import { VideoModel } from '../../models/video/video' | 27 | import { VideoModel } from '../../models/video/video' |
28 | import { updateAvatarValidator } from '../../middlewares/validators/avatar' | ||
29 | import { updateActorAvatarFile } from '../../lib/avatar' | ||
30 | |||
31 | const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR }) | ||
28 | 32 | ||
29 | const videoChannelRouter = express.Router() | 33 | const videoChannelRouter = express.Router() |
30 | 34 | ||
@@ -42,6 +46,15 @@ videoChannelRouter.post('/', | |||
42 | asyncRetryTransactionMiddleware(addVideoChannel) | 46 | asyncRetryTransactionMiddleware(addVideoChannel) |
43 | ) | 47 | ) |
44 | 48 | ||
49 | videoChannelRouter.post('/:id/avatar/pick', | ||
50 | authenticate, | ||
51 | reqAvatarFile, | ||
52 | // Check the rights | ||
53 | asyncMiddleware(videoChannelsUpdateValidator), | ||
54 | updateAvatarValidator, | ||
55 | asyncMiddleware(updateVideoChannelAvatar) | ||
56 | ) | ||
57 | |||
45 | videoChannelRouter.put('/:id', | 58 | videoChannelRouter.put('/:id', |
46 | authenticate, | 59 | authenticate, |
47 | asyncMiddleware(videoChannelsUpdateValidator), | 60 | asyncMiddleware(videoChannelsUpdateValidator), |
@@ -83,6 +96,19 @@ async function listVideoChannels (req: express.Request, res: express.Response, n | |||
83 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 96 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
84 | } | 97 | } |
85 | 98 | ||
99 | async function updateVideoChannelAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
100 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] | ||
101 | const videoChannel = res.locals.videoChannel | ||
102 | |||
103 | const avatar = await updateActorAvatarFile(avatarPhysicalFile, videoChannel.Actor, videoChannel) | ||
104 | |||
105 | return res | ||
106 | .json({ | ||
107 | avatar: avatar.toFormattedJSON() | ||
108 | }) | ||
109 | .end() | ||
110 | } | ||
111 | |||
86 | async function addVideoChannel (req: express.Request, res: express.Response) { | 112 | async function addVideoChannel (req: express.Request, res: express.Response) { |
87 | const videoChannelInfo: VideoChannelCreate = req.body | 113 | const videoChannelInfo: VideoChannelCreate = req.body |
88 | const account: AccountModel = res.locals.oauth.token.User.Account | 114 | const account: AccountModel = res.locals.oauth.token.User.Account |
diff --git a/server/lib/avatar.ts b/server/lib/avatar.ts new file mode 100644 index 000000000..7fdef008c --- /dev/null +++ b/server/lib/avatar.ts | |||
@@ -0,0 +1,34 @@ | |||
1 | import 'multer' | ||
2 | import * as uuidv4 from 'uuid' | ||
3 | import { sendUpdateActor } from './activitypub/send' | ||
4 | import { AVATARS_SIZE, CONFIG, sequelizeTypescript } from '../initializers' | ||
5 | import { updateActorAvatarInstance } from './activitypub' | ||
6 | import { processImage } from '../helpers/image-utils' | ||
7 | import { ActorModel } from '../models/activitypub/actor' | ||
8 | import { AccountModel } from '../models/account/account' | ||
9 | import { VideoChannelModel } from '../models/video/video-channel' | ||
10 | import { extname, join } from 'path' | ||
11 | |||
12 | async function updateActorAvatarFile ( | ||
13 | avatarPhysicalFile: Express.Multer.File, | ||
14 | actor: ActorModel, | ||
15 | accountOrChannel: AccountModel | VideoChannelModel | ||
16 | ) { | ||
17 | const extension = extname(avatarPhysicalFile.filename) | ||
18 | const avatarName = uuidv4() + extension | ||
19 | const destination = join(CONFIG.STORAGE.AVATARS_DIR, avatarName) | ||
20 | await processImage(avatarPhysicalFile, destination, AVATARS_SIZE) | ||
21 | |||
22 | return sequelizeTypescript.transaction(async t => { | ||
23 | const updatedActor = await updateActorAvatarInstance(actor, avatarName, t) | ||
24 | await updatedActor.save({ transaction: t }) | ||
25 | |||
26 | await sendUpdateActor(accountOrChannel, t) | ||
27 | |||
28 | return updatedActor.Avatar | ||
29 | }) | ||
30 | } | ||
31 | |||
32 | export { | ||
33 | updateActorAvatarFile | ||
34 | } | ||
diff --git a/server/middlewares/validators/avatar.ts b/server/middlewares/validators/avatar.ts new file mode 100644 index 000000000..f346ea92f --- /dev/null +++ b/server/middlewares/validators/avatar.ts | |||
@@ -0,0 +1,25 @@ | |||
1 | import * as express from 'express' | ||
2 | import { body } from 'express-validator/check' | ||
3 | import { isAvatarFile } from '../../helpers/custom-validators/users' | ||
4 | import { areValidationErrors } from './utils' | ||
5 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
6 | import { logger } from '../../helpers/logger' | ||
7 | |||
8 | const updateAvatarValidator = [ | ||
9 | body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage( | ||
10 | 'This file is not supported or too large. Please, make sure it is of the following type : ' | ||
11 | + CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ') | ||
12 | ), | ||
13 | |||
14 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
15 | logger.debug('Checking updateAvatarValidator parameters', { files: req.files }) | ||
16 | |||
17 | if (areValidationErrors(req, res)) return | ||
18 | |||
19 | return next() | ||
20 | } | ||
21 | ] | ||
22 | |||
23 | export { | ||
24 | updateAvatarValidator | ||
25 | } | ||
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 55a08a648..8ca9763a1 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -5,9 +5,9 @@ import { body, param } from 'express-validator/check' | |||
5 | import { omit } from 'lodash' | 5 | import { omit } from 'lodash' |
6 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' | 6 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' |
7 | import { | 7 | import { |
8 | isAvatarFile, | ||
9 | isUserAutoPlayVideoValid, | 8 | isUserAutoPlayVideoValid, |
10 | isUserDescriptionValid, isUserDisplayNameValid, | 9 | isUserDescriptionValid, |
10 | isUserDisplayNameValid, | ||
11 | isUserNSFWPolicyValid, | 11 | isUserNSFWPolicyValid, |
12 | isUserPasswordValid, | 12 | isUserPasswordValid, |
13 | isUserRoleValid, | 13 | isUserRoleValid, |
@@ -17,7 +17,6 @@ import { | |||
17 | import { isVideoExist } from '../../helpers/custom-validators/videos' | 17 | import { isVideoExist } from '../../helpers/custom-validators/videos' |
18 | import { logger } from '../../helpers/logger' | 18 | import { logger } from '../../helpers/logger' |
19 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/utils' | 19 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/utils' |
20 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers' | ||
21 | import { Redis } from '../../lib/redis' | 20 | import { Redis } from '../../lib/redis' |
22 | import { UserModel } from '../../models/account/user' | 21 | import { UserModel } from '../../models/account/user' |
23 | import { areValidationErrors } from './utils' | 22 | import { areValidationErrors } from './utils' |
@@ -116,21 +115,6 @@ const usersUpdateMeValidator = [ | |||
116 | } | 115 | } |
117 | ] | 116 | ] |
118 | 117 | ||
119 | const usersUpdateMyAvatarValidator = [ | ||
120 | body('avatarfile').custom((value, { req }) => isAvatarFile(req.files)).withMessage( | ||
121 | 'This file is not supported or too large. Please, make sure it is of the following type : ' | ||
122 | + CONSTRAINTS_FIELDS.ACTORS.AVATAR.EXTNAME.join(', ') | ||
123 | ), | ||
124 | |||
125 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
126 | logger.debug('Checking usersUpdateMyAvatarValidator parameters', { files: req.files }) | ||
127 | |||
128 | if (areValidationErrors(req, res)) return | ||
129 | |||
130 | return next() | ||
131 | } | ||
132 | ] | ||
133 | |||
134 | const usersGetValidator = [ | 118 | const usersGetValidator = [ |
135 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), | 119 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), |
136 | 120 | ||
@@ -239,7 +223,6 @@ export { | |||
239 | ensureUserRegistrationAllowed, | 223 | ensureUserRegistrationAllowed, |
240 | ensureUserRegistrationAllowedForIP, | 224 | ensureUserRegistrationAllowedForIP, |
241 | usersGetValidator, | 225 | usersGetValidator, |
242 | usersUpdateMyAvatarValidator, | ||
243 | usersAskResetPasswordValidator, | 226 | usersAskResetPasswordValidator, |
244 | usersResetPasswordValidator | 227 | usersResetPasswordValidator |
245 | } | 228 | } |
diff --git a/server/middlewares/validators/video-channels.ts b/server/middlewares/validators/video-channels.ts index a5be5f114..7f65f7290 100644 --- a/server/middlewares/validators/video-channels.ts +++ b/server/middlewares/validators/video-channels.ts | |||
@@ -13,6 +13,8 @@ import { logger } from '../../helpers/logger' | |||
13 | import { UserModel } from '../../models/account/user' | 13 | import { UserModel } from '../../models/account/user' |
14 | import { VideoChannelModel } from '../../models/video/video-channel' | 14 | import { VideoChannelModel } from '../../models/video/video-channel' |
15 | import { areValidationErrors } from './utils' | 15 | import { areValidationErrors } from './utils' |
16 | import { isAvatarFile } from '../../helpers/custom-validators/users' | ||
17 | import { CONSTRAINTS_FIELDS } from '../../initializers' | ||
16 | 18 | ||
17 | const listVideoAccountChannelsValidator = [ | 19 | const listVideoAccountChannelsValidator = [ |
18 | param('accountName').exists().withMessage('Should have a valid account name'), | 20 | param('accountName').exists().withMessage('Should have a valid account name'), |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 28537315e..e1954c64f 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -304,6 +304,20 @@ describe('Test users API validators', function () { | |||
304 | await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) | 304 | await makeUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches }) |
305 | }) | 305 | }) |
306 | 306 | ||
307 | it('Should fail with an unauthenticated user', async function () { | ||
308 | const fields = {} | ||
309 | const attaches = { | ||
310 | 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') | ||
311 | } | ||
312 | await makeUploadRequest({ | ||
313 | url: server.url, | ||
314 | path: path + '/me/avatar/pick', | ||
315 | fields, | ||
316 | attaches, | ||
317 | statusCodeExpected: 401 | ||
318 | }) | ||
319 | }) | ||
320 | |||
307 | it('Should succeed with the correct params', async function () { | 321 | it('Should succeed with the correct params', async function () { |
308 | const fields = {} | 322 | const fields = {} |
309 | const attaches = { | 323 | const attaches = { |
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts index 5080af2c9..7b05e5882 100644 --- a/server/tests/api/check-params/video-channels.ts +++ b/server/tests/api/check-params/video-channels.ts | |||
@@ -14,7 +14,7 @@ import { | |||
14 | killallServers, | 14 | killallServers, |
15 | makeGetRequest, | 15 | makeGetRequest, |
16 | makePostBodyRequest, | 16 | makePostBodyRequest, |
17 | makePutBodyRequest, | 17 | makePutBodyRequest, makeUploadRequest, |
18 | runServer, | 18 | runServer, |
19 | ServerInfo, | 19 | ServerInfo, |
20 | setAccessTokensToServers, | 20 | setAccessTokensToServers, |
@@ -22,6 +22,7 @@ import { | |||
22 | } from '../../utils' | 22 | } from '../../utils' |
23 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' | 23 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' |
24 | import { User } from '../../../../shared/models/users' | 24 | import { User } from '../../../../shared/models/users' |
25 | import { join } from "path" | ||
25 | 26 | ||
26 | const expect = chai.expect | 27 | const expect = chai.expect |
27 | 28 | ||
@@ -189,6 +190,59 @@ describe('Test video channels API validator', function () { | |||
189 | }) | 190 | }) |
190 | }) | 191 | }) |
191 | 192 | ||
193 | describe('When updating video channel avatar', function () { | ||
194 | let path: string | ||
195 | |||
196 | before(async function () { | ||
197 | path = videoChannelPath + '/' + videoChannelUUID | ||
198 | }) | ||
199 | |||
200 | it('Should fail with an incorrect input file', async function () { | ||
201 | const fields = {} | ||
202 | const attaches = { | ||
203 | 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'video_short.mp4') | ||
204 | } | ||
205 | await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) | ||
206 | }) | ||
207 | |||
208 | it('Should fail with a big file', async function () { | ||
209 | const fields = {} | ||
210 | const attaches = { | ||
211 | 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar-big.png') | ||
212 | } | ||
213 | await makeUploadRequest({ url: server.url, path: path + '/avatar/pick', token: server.accessToken, fields, attaches }) | ||
214 | }) | ||
215 | |||
216 | it('Should fail with an unauthenticated user', async function () { | ||
217 | const fields = {} | ||
218 | const attaches = { | ||
219 | 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') | ||
220 | } | ||
221 | await makeUploadRequest({ | ||
222 | url: server.url, | ||
223 | path: path + '/avatar/pick', | ||
224 | fields, | ||
225 | attaches, | ||
226 | statusCodeExpected: 401 | ||
227 | }) | ||
228 | }) | ||
229 | |||
230 | it('Should succeed with the correct params', async function () { | ||
231 | const fields = {} | ||
232 | const attaches = { | ||
233 | 'avatarfile': join(__dirname, '..', '..', 'fixtures', 'avatar.png') | ||
234 | } | ||
235 | await makeUploadRequest({ | ||
236 | url: server.url, | ||
237 | path: path + '/avatar/pick', | ||
238 | token: server.accessToken, | ||
239 | fields, | ||
240 | attaches, | ||
241 | statusCodeExpected: 200 | ||
242 | }) | ||
243 | }) | ||
244 | }) | ||
245 | |||
192 | describe('When getting a video channel', function () { | 246 | describe('When getting a video channel', function () { |
193 | it('Should return the list of the video channels with nothing', async function () { | 247 | it('Should return the list of the video channels with nothing', async function () { |
194 | const res = await makeGetRequest({ | 248 | const res = await makeGetRequest({ |
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts index ad543e2d6..e4e3ce9d9 100644 --- a/server/tests/api/videos/video-channels.ts +++ b/server/tests/api/videos/video-channels.ts | |||
@@ -3,7 +3,14 @@ | |||
3 | import * as chai from 'chai' | 3 | import * as chai from 'chai' |
4 | import 'mocha' | 4 | import 'mocha' |
5 | import { User, Video } from '../../../../shared/index' | 5 | import { User, Video } from '../../../../shared/index' |
6 | import { doubleFollow, flushAndRunMultipleServers, getVideoChannelVideos, updateVideo, uploadVideo } from '../../utils' | 6 | import { |
7 | doubleFollow, | ||
8 | flushAndRunMultipleServers, | ||
9 | getVideoChannelVideos, testImage, | ||
10 | updateVideo, | ||
11 | updateVideoChannelAvatar, | ||
12 | uploadVideo, wait | ||
13 | } from '../../utils' | ||
7 | import { | 14 | import { |
8 | addVideoChannel, | 15 | addVideoChannel, |
9 | deleteVideoChannel, | 16 | deleteVideoChannel, |
@@ -159,6 +166,31 @@ describe('Test video channels', function () { | |||
159 | } | 166 | } |
160 | }) | 167 | }) |
161 | 168 | ||
169 | it('Should update video channel avatar', async function () { | ||
170 | this.timeout(5000) | ||
171 | |||
172 | const fixture = 'avatar.png' | ||
173 | |||
174 | await updateVideoChannelAvatar({ | ||
175 | url: servers[0].url, | ||
176 | accessToken: servers[0].accessToken, | ||
177 | videoChannelId: secondVideoChannelId, | ||
178 | fixture | ||
179 | }) | ||
180 | |||
181 | await waitJobs(servers) | ||
182 | }) | ||
183 | |||
184 | it('Should have video channel avatar updated', async function () { | ||
185 | for (const server of servers) { | ||
186 | const res = await getVideoChannelsList(server.url, 0, 1, '-name') | ||
187 | |||
188 | const videoChannel = res.body.data.find(c => c.id === secondVideoChannelId) | ||
189 | |||
190 | await testImage(server.url, 'avatar-resized', videoChannel.avatar.path, '.png') | ||
191 | } | ||
192 | }) | ||
193 | |||
162 | it('Should get video channel', async function () { | 194 | it('Should get video channel', async function () { |
163 | const res = await getVideoChannel(servers[0].url, secondVideoChannelId) | 195 | const res = await getVideoChannel(servers[0].url, secondVideoChannelId) |
164 | 196 | ||
diff --git a/server/tests/utils/requests/requests.ts b/server/tests/utils/requests/requests.ts index b6195089d..ebde692cd 100644 --- a/server/tests/utils/requests/requests.ts +++ b/server/tests/utils/requests/requests.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { buildAbsoluteFixturePath } from '../miscs/miscs' | 2 | import { buildAbsoluteFixturePath } from '../miscs/miscs' |
3 | import { isAbsolute, join } from 'path' | ||
3 | 4 | ||
4 | function makeGetRequest (options: { | 5 | function makeGetRequest (options: { |
5 | url: string, | 6 | url: string, |
@@ -45,7 +46,7 @@ function makeUploadRequest (options: { | |||
45 | url: string, | 46 | url: string, |
46 | method?: 'POST' | 'PUT', | 47 | method?: 'POST' | 'PUT', |
47 | path: string, | 48 | path: string, |
48 | token: string, | 49 | token?: string, |
49 | fields: { [ fieldName: string ]: any }, | 50 | fields: { [ fieldName: string ]: any }, |
50 | attaches: { [ attachName: string ]: any }, | 51 | attaches: { [ attachName: string ]: any }, |
51 | statusCodeExpected?: number | 52 | statusCodeExpected?: number |
@@ -122,6 +123,29 @@ function makePutBodyRequest (options: { | |||
122 | .expect(options.statusCodeExpected) | 123 | .expect(options.statusCodeExpected) |
123 | } | 124 | } |
124 | 125 | ||
126 | function updateAvatarRequest (options: { | ||
127 | url: string, | ||
128 | path: string, | ||
129 | accessToken: string, | ||
130 | fixture: string | ||
131 | }) { | ||
132 | let filePath = '' | ||
133 | if (isAbsolute(options.fixture)) { | ||
134 | filePath = options.fixture | ||
135 | } else { | ||
136 | filePath = join(__dirname, '..', '..', 'fixtures', options.fixture) | ||
137 | } | ||
138 | |||
139 | return makeUploadRequest({ | ||
140 | url: options.url, | ||
141 | path: options.path, | ||
142 | token: options.accessToken, | ||
143 | fields: {}, | ||
144 | attaches: { avatarfile: filePath }, | ||
145 | statusCodeExpected: 200 | ||
146 | }) | ||
147 | } | ||
148 | |||
125 | // --------------------------------------------------------------------------- | 149 | // --------------------------------------------------------------------------- |
126 | 150 | ||
127 | export { | 151 | export { |
@@ -129,5 +153,6 @@ export { | |||
129 | makeUploadRequest, | 153 | makeUploadRequest, |
130 | makePostBodyRequest, | 154 | makePostBodyRequest, |
131 | makePutBodyRequest, | 155 | makePutBodyRequest, |
132 | makeDeleteRequest | 156 | makeDeleteRequest, |
157 | updateAvatarRequest | ||
133 | } | 158 | } |
diff --git a/server/tests/utils/users/users.ts b/server/tests/utils/users/users.ts index 34d50f7ad..37b15f64a 100644 --- a/server/tests/utils/users/users.ts +++ b/server/tests/utils/users/users.ts | |||
@@ -1,6 +1,5 @@ | |||
1 | import { isAbsolute, join } from 'path' | ||
2 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
3 | import { makePostBodyRequest, makeUploadRequest, makePutBodyRequest } from '../' | 2 | import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../' |
4 | 3 | ||
5 | import { UserRole } from '../../../../shared/index' | 4 | import { UserRole } from '../../../../shared/index' |
6 | import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type' | 5 | import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type' |
@@ -160,21 +159,8 @@ function updateMyAvatar (options: { | |||
160 | fixture: string | 159 | fixture: string |
161 | }) { | 160 | }) { |
162 | const path = '/api/v1/users/me/avatar/pick' | 161 | const path = '/api/v1/users/me/avatar/pick' |
163 | let filePath = '' | ||
164 | if (isAbsolute(options.fixture)) { | ||
165 | filePath = options.fixture | ||
166 | } else { | ||
167 | filePath = join(__dirname, '..', '..', 'fixtures', options.fixture) | ||
168 | } | ||
169 | 162 | ||
170 | return makeUploadRequest({ | 163 | return updateAvatarRequest(Object.assign(options, { path })) |
171 | url: options.url, | ||
172 | path, | ||
173 | token: options.accessToken, | ||
174 | fields: {}, | ||
175 | attaches: { avatarfile: filePath }, | ||
176 | statusCodeExpected: 200 | ||
177 | }) | ||
178 | } | 164 | } |
179 | 165 | ||
180 | function updateUser (options: { | 166 | function updateUser (options: { |
diff --git a/server/tests/utils/videos/video-channels.ts b/server/tests/utils/videos/video-channels.ts index a064598f4..3ca39469c 100644 --- a/server/tests/utils/videos/video-channels.ts +++ b/server/tests/utils/videos/video-channels.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import * as request from 'supertest' | 1 | import * as request from 'supertest' |
2 | import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos' | 2 | import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos' |
3 | import { updateAvatarRequest } from '../index' | ||
3 | 4 | ||
4 | function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { | 5 | function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { |
5 | const path = '/api/v1/video-channels' | 6 | const path = '/api/v1/video-channels' |
@@ -92,9 +93,22 @@ function getVideoChannel (url: string, channelId: number | string) { | |||
92 | .expect('Content-Type', /json/) | 93 | .expect('Content-Type', /json/) |
93 | } | 94 | } |
94 | 95 | ||
96 | function updateVideoChannelAvatar (options: { | ||
97 | url: string, | ||
98 | accessToken: string, | ||
99 | fixture: string, | ||
100 | videoChannelId: string | number | ||
101 | }) { | ||
102 | |||
103 | const path = '/api/v1/video-channels/' + options.videoChannelId + '/avatar/pick' | ||
104 | |||
105 | return updateAvatarRequest(Object.assign(options, { path })) | ||
106 | } | ||
107 | |||
95 | // --------------------------------------------------------------------------- | 108 | // --------------------------------------------------------------------------- |
96 | 109 | ||
97 | export { | 110 | export { |
111 | updateVideoChannelAvatar, | ||
98 | getVideoChannelsList, | 112 | getVideoChannelsList, |
99 | getAccountVideoChannelsList, | 113 | getAccountVideoChannelsList, |
100 | addVideoChannel, | 114 | addVideoChannel, |