diff options
author | Andréas Livet <andreas.livet@gmail.com> | 2017-12-19 10:45:49 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2017-12-19 10:45:49 +0100 |
commit | 7efe153b0bc23e596d5019b9fb3e3e32b6cfeccd (patch) | |
tree | 56116e7e9f8467b78ed6dfc81827288915d31c8c /server | |
parent | 228077efd73485a2832bb6211c9fa923158c2112 (diff) | |
download | PeerTube-7efe153b0bc23e596d5019b9fb3e3e32b6cfeccd.tar.gz PeerTube-7efe153b0bc23e596d5019b9fb3e3e32b6cfeccd.tar.zst PeerTube-7efe153b0bc23e596d5019b9fb3e3e32b6cfeccd.zip |
Enh #106 : Add an autoPlayVideo user attribute (#159)
Warning : I was not able to run the tests on my machine. It uses a different approach to handle databse connexion and didn't find where to configure it...
- create a migration file to add a boolean column in user table
- add autoPlayVideo attribute everywhere it is needed (both on client and server side)
- add tests
- add a way to configure this attribute in account-settings
- use the attribute in video-watch component to actually autoplay or not the video
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users.ts | 3 | ||||
-rw-r--r-- | server/helpers/custom-validators/users.ts | 13 | ||||
-rw-r--r-- | server/initializers/constants.ts | 2 | ||||
-rw-r--r-- | server/initializers/migrations/0130-user-autoplay-video.ts | 27 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 2 | ||||
-rw-r--r-- | server/models/account/user.ts | 9 | ||||
-rw-r--r-- | server/tests/api/check-params/users.ts | 9 | ||||
-rw-r--r-- | server/tests/api/users.ts | 9 | ||||
-rw-r--r-- | server/tests/utils/users.ts | 4 |
9 files changed, 73 insertions, 5 deletions
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index d6c0e67f9..995542604 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -134,6 +134,7 @@ async function createUser (req: express.Request) { | |||
134 | password: body.password, | 134 | password: body.password, |
135 | email: body.email, | 135 | email: body.email, |
136 | displayNSFW: false, | 136 | displayNSFW: false, |
137 | autoPlayVideo: true, | ||
137 | role: body.role, | 138 | role: body.role, |
138 | videoQuota: body.videoQuota | 139 | videoQuota: body.videoQuota |
139 | }) | 140 | }) |
@@ -162,6 +163,7 @@ async function registerUser (req: express.Request) { | |||
162 | password: body.password, | 163 | password: body.password, |
163 | email: body.email, | 164 | email: body.email, |
164 | displayNSFW: false, | 165 | displayNSFW: false, |
166 | autoPlayVideo: true, | ||
165 | role: UserRole.USER, | 167 | role: UserRole.USER, |
166 | videoQuota: CONFIG.USER.VIDEO_QUOTA | 168 | videoQuota: CONFIG.USER.VIDEO_QUOTA |
167 | }) | 169 | }) |
@@ -219,6 +221,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr | |||
219 | if (body.password !== undefined) user.password = body.password | 221 | if (body.password !== undefined) user.password = body.password |
220 | if (body.email !== undefined) user.email = body.email | 222 | if (body.email !== undefined) user.email = body.email |
221 | if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW | 223 | if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW |
224 | if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo | ||
222 | 225 | ||
223 | await user.save() | 226 | await user.save() |
224 | 227 | ||
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index b5b5642d6..159c2a700 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts | |||
@@ -21,10 +21,18 @@ function isUserUsernameValid (value: string) { | |||
21 | return exists(value) && validator.matches(value, new RegExp(`^[a-z0-9._]{${min},${max}}$`)) | 21 | return exists(value) && validator.matches(value, new RegExp(`^[a-z0-9._]{${min},${max}}$`)) |
22 | } | 22 | } |
23 | 23 | ||
24 | function isUserDisplayNSFWValid (value: any) { | 24 | function isBoolean (value: any) { |
25 | return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) | 25 | return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) |
26 | } | 26 | } |
27 | 27 | ||
28 | function isUserDisplayNSFWValid (value: any) { | ||
29 | return isBoolean(value) | ||
30 | } | ||
31 | |||
32 | function isUserAutoPlayVideoValid (value: any) { | ||
33 | return isBoolean(value) | ||
34 | } | ||
35 | |||
28 | function isUserRoleValid (value: any) { | 36 | function isUserRoleValid (value: any) { |
29 | return exists(value) && validator.isInt('' + value) && UserRole[value] !== undefined | 37 | return exists(value) && validator.isInt('' + value) && UserRole[value] !== undefined |
30 | } | 38 | } |
@@ -36,5 +44,6 @@ export { | |||
36 | isUserRoleValid, | 44 | isUserRoleValid, |
37 | isUserVideoQuotaValid, | 45 | isUserVideoQuotaValid, |
38 | isUserUsernameValid, | 46 | isUserUsernameValid, |
39 | isUserDisplayNSFWValid | 47 | isUserDisplayNSFWValid, |
48 | isUserAutoPlayVideoValid | ||
40 | } | 49 | } |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 341086bd6..ff322730f 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -8,7 +8,7 @@ import { isTestInstance, root } from '../helpers/core-utils' | |||
8 | 8 | ||
9 | // --------------------------------------------------------------------------- | 9 | // --------------------------------------------------------------------------- |
10 | 10 | ||
11 | const LAST_MIGRATION_VERSION = 125 | 11 | const LAST_MIGRATION_VERSION = 130 |
12 | 12 | ||
13 | // --------------------------------------------------------------------------- | 13 | // --------------------------------------------------------------------------- |
14 | 14 | ||
diff --git a/server/initializers/migrations/0130-user-autoplay-video.ts b/server/initializers/migrations/0130-user-autoplay-video.ts new file mode 100644 index 000000000..9f6878e39 --- /dev/null +++ b/server/initializers/migrations/0130-user-autoplay-video.ts | |||
@@ -0,0 +1,27 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import * as Promise from 'bluebird' | ||
3 | |||
4 | function up (utils: { | ||
5 | transaction: Sequelize.Transaction, | ||
6 | queryInterface: Sequelize.QueryInterface, | ||
7 | sequelize: Sequelize.Sequelize | ||
8 | }): Promise<void> { | ||
9 | const q = utils.queryInterface | ||
10 | |||
11 | const data = { | ||
12 | type: Sequelize.BOOLEAN, | ||
13 | allowNull: false, | ||
14 | defaultValue: true | ||
15 | } | ||
16 | |||
17 | return q.addColumn('user', 'autoPlayVideo', data) | ||
18 | } | ||
19 | |||
20 | function down (options) { | ||
21 | throw new Error('Not implemented.') | ||
22 | } | ||
23 | |||
24 | export { | ||
25 | up, | ||
26 | down | ||
27 | } | ||
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 920176d07..a6fdbe268 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -5,6 +5,7 @@ import { isSignupAllowed, logger } from '../../helpers' | |||
5 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' | 5 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' |
6 | import { | 6 | import { |
7 | isUserDisplayNSFWValid, | 7 | isUserDisplayNSFWValid, |
8 | isUserAutoPlayVideoValid, | ||
8 | isUserPasswordValid, | 9 | isUserPasswordValid, |
9 | isUserRoleValid, | 10 | isUserRoleValid, |
10 | isUserUsernameValid, | 11 | isUserUsernameValid, |
@@ -86,6 +87,7 @@ const usersUpdateMeValidator = [ | |||
86 | body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'), | 87 | body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'), |
87 | body('email').optional().isEmail().withMessage('Should have a valid email attribute'), | 88 | body('email').optional().isEmail().withMessage('Should have a valid email attribute'), |
88 | body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'), | 89 | body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'), |
90 | body('autoPlayVideo').optional().custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video attribute'), | ||
89 | 91 | ||
90 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 92 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
91 | // TODO: Add old password verification | 93 | // TODO: Add old password verification |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 26f04dcb5..70ed61e07 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -20,7 +20,7 @@ import { | |||
20 | } from '../../helpers' | 20 | } from '../../helpers' |
21 | import { | 21 | import { |
22 | isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, | 22 | isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, |
23 | isUserVideoQuotaValid | 23 | isUserVideoQuotaValid, isUserAutoPlayVideoValid |
24 | } from '../../helpers/custom-validators/users' | 24 | } from '../../helpers/custom-validators/users' |
25 | import { OAuthTokenModel } from '../oauth/oauth-token' | 25 | import { OAuthTokenModel } from '../oauth/oauth-token' |
26 | import { getSort, throwIfNotValid } from '../utils' | 26 | import { getSort, throwIfNotValid } from '../utils' |
@@ -83,6 +83,12 @@ export class UserModel extends Model<UserModel> { | |||
83 | displayNSFW: boolean | 83 | displayNSFW: boolean |
84 | 84 | ||
85 | @AllowNull(false) | 85 | @AllowNull(false) |
86 | @Default(true) | ||
87 | @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) | ||
88 | @Column | ||
89 | autoPlayVideo: boolean | ||
90 | |||
91 | @AllowNull(false) | ||
86 | @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) | 92 | @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) |
87 | @Column | 93 | @Column |
88 | role: number | 94 | role: number |
@@ -223,6 +229,7 @@ export class UserModel extends Model<UserModel> { | |||
223 | username: this.username, | 229 | username: this.username, |
224 | email: this.email, | 230 | email: this.email, |
225 | displayNSFW: this.displayNSFW, | 231 | displayNSFW: this.displayNSFW, |
232 | autoPlayVideo: this.autoPlayVideo, | ||
226 | role: this.role, | 233 | role: this.role, |
227 | roleLabel: USER_ROLE_LABELS[ this.role ], | 234 | roleLabel: USER_ROLE_LABELS[ this.role ], |
228 | videoQuota: this.videoQuota, | 235 | videoQuota: this.videoQuota, |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 1e3533bf3..72488e5c4 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -350,6 +350,14 @@ describe('Test users API validators', function () { | |||
350 | await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) | 350 | await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) |
351 | }) | 351 | }) |
352 | 352 | ||
353 | it('Should fail with an invalid autoPlayVideo attribute', async function () { | ||
354 | const fields = { | ||
355 | autoPlayVideo: -1 | ||
356 | } | ||
357 | |||
358 | await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) | ||
359 | }) | ||
360 | |||
353 | it('Should fail with an non authenticated user', async function () { | 361 | it('Should fail with an non authenticated user', async function () { |
354 | const fields = { | 362 | const fields = { |
355 | password: 'my super password' | 363 | password: 'my super password' |
@@ -362,6 +370,7 @@ describe('Test users API validators', function () { | |||
362 | const fields = { | 370 | const fields = { |
363 | password: 'my super password', | 371 | password: 'my super password', |
364 | displayNSFW: true, | 372 | displayNSFW: true, |
373 | autoPlayVideo: false, | ||
365 | email: 'super_email@example.com' | 374 | email: 'super_email@example.com' |
366 | } | 375 | } |
367 | 376 | ||
diff --git a/server/tests/api/users.ts b/server/tests/api/users.ts index b3163b1e1..67e4cc8c6 100644 --- a/server/tests/api/users.ts +++ b/server/tests/api/users.ts | |||
@@ -415,6 +415,15 @@ describe('Test users', function () { | |||
415 | .a('number') | 415 | .a('number') |
416 | }) | 416 | }) |
417 | 417 | ||
418 | it('Should be able to change the autoPlayVideo attribute', async function () { | ||
419 | await updateMyUser(server.url, accessTokenUser, undefined, undefined, undefined, false) | ||
420 | |||
421 | const res = await getMyUserInformation(server.url, accessTokenUser) | ||
422 | const user = res.body | ||
423 | |||
424 | expect(user.autoPlayVideo).to.be.false | ||
425 | }) | ||
426 | |||
418 | it('Should be able to change the email display attribute', async function () { | 427 | it('Should be able to change the email display attribute', async function () { |
419 | await updateMyUser(server.url, accessTokenUser, undefined, undefined, 'updated@example.com') | 428 | await updateMyUser(server.url, accessTokenUser, undefined, undefined, 'updated@example.com') |
420 | 429 | ||
diff --git a/server/tests/utils/users.ts b/server/tests/utils/users.ts index ce04b9d96..a37d84ab4 100644 --- a/server/tests/utils/users.ts +++ b/server/tests/utils/users.ts | |||
@@ -111,12 +111,14 @@ function removeUser (url: string, userId: number, accessToken: string, expectedS | |||
111 | .expect(expectedStatus) | 111 | .expect(expectedStatus) |
112 | } | 112 | } |
113 | 113 | ||
114 | function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, email?: string) { | 114 | function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, |
115 | email?: string, autoPlayVideo?: boolean) { | ||
115 | const path = '/api/v1/users/me' | 116 | const path = '/api/v1/users/me' |
116 | 117 | ||
117 | const toSend = {} | 118 | const toSend = {} |
118 | if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword | 119 | if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword |
119 | if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW | 120 | if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW |
121 | if (autoPlayVideo !== undefined && autoPlayVideo !== null) toSend['autoPlayVideo'] = autoPlayVideo | ||
120 | if (email !== undefined && email !== null) toSend['email'] = email | 122 | if (email !== undefined && email !== null) toSend['email'] = email |
121 | 123 | ||
122 | return request(url) | 124 | return request(url) |