From 7efe153b0bc23e596d5019b9fb3e3e32b6cfeccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as=20Livet?= Date: Tue, 19 Dec 2017 10:45:49 +0100 Subject: 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 --- server/controllers/api/users.ts | 3 +++ server/helpers/custom-validators/users.ts | 13 +++++++++-- server/initializers/constants.ts | 2 +- .../migrations/0130-user-autoplay-video.ts | 27 ++++++++++++++++++++++ server/middlewares/validators/users.ts | 2 ++ server/models/account/user.ts | 9 +++++++- server/tests/api/check-params/users.ts | 9 ++++++++ server/tests/api/users.ts | 9 ++++++++ server/tests/utils/users.ts | 4 +++- 9 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 server/initializers/migrations/0130-user-autoplay-video.ts (limited to 'server') 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) { password: body.password, email: body.email, displayNSFW: false, + autoPlayVideo: true, role: body.role, videoQuota: body.videoQuota }) @@ -162,6 +163,7 @@ async function registerUser (req: express.Request) { password: body.password, email: body.email, displayNSFW: false, + autoPlayVideo: true, role: UserRole.USER, videoQuota: CONFIG.USER.VIDEO_QUOTA }) @@ -219,6 +221,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr if (body.password !== undefined) user.password = body.password if (body.email !== undefined) user.email = body.email if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW + if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo await user.save() 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) { return exists(value) && validator.matches(value, new RegExp(`^[a-z0-9._]{${min},${max}}$`)) } -function isUserDisplayNSFWValid (value: any) { +function isBoolean (value: any) { return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) } +function isUserDisplayNSFWValid (value: any) { + return isBoolean(value) +} + +function isUserAutoPlayVideoValid (value: any) { + return isBoolean(value) +} + function isUserRoleValid (value: any) { return exists(value) && validator.isInt('' + value) && UserRole[value] !== undefined } @@ -36,5 +44,6 @@ export { isUserRoleValid, isUserVideoQuotaValid, isUserUsernameValid, - isUserDisplayNSFWValid + isUserDisplayNSFWValid, + isUserAutoPlayVideoValid } 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' // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 125 +const LAST_MIGRATION_VERSION = 130 // --------------------------------------------------------------------------- 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 @@ +import * as Sequelize from 'sequelize' +import * as Promise from 'bluebird' + +function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize +}): Promise { + const q = utils.queryInterface + + const data = { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: true + } + + return q.addColumn('user', 'autoPlayVideo', data) +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} 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' import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' import { isUserDisplayNSFWValid, + isUserAutoPlayVideoValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, @@ -86,6 +87,7 @@ const usersUpdateMeValidator = [ body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'), body('email').optional().isEmail().withMessage('Should have a valid email attribute'), body('displayNSFW').optional().custom(isUserDisplayNSFWValid).withMessage('Should have a valid display Not Safe For Work attribute'), + body('autoPlayVideo').optional().custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video attribute'), (req: express.Request, res: express.Response, next: express.NextFunction) => { // 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 { } from '../../helpers' import { isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, - isUserVideoQuotaValid + isUserVideoQuotaValid, isUserAutoPlayVideoValid } from '../../helpers/custom-validators/users' import { OAuthTokenModel } from '../oauth/oauth-token' import { getSort, throwIfNotValid } from '../utils' @@ -82,6 +82,12 @@ export class UserModel extends Model { @Column displayNSFW: boolean + @AllowNull(false) + @Default(true) + @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) + @Column + autoPlayVideo: boolean + @AllowNull(false) @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) @Column @@ -223,6 +229,7 @@ export class UserModel extends Model { username: this.username, email: this.email, displayNSFW: this.displayNSFW, + autoPlayVideo: this.autoPlayVideo, role: this.role, roleLabel: USER_ROLE_LABELS[ this.role ], 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 () { await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) }) + it('Should fail with an invalid autoPlayVideo attribute', async function () { + const fields = { + autoPlayVideo: -1 + } + + await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) + }) + it('Should fail with an non authenticated user', async function () { const fields = { password: 'my super password' @@ -362,6 +370,7 @@ describe('Test users API validators', function () { const fields = { password: 'my super password', displayNSFW: true, + autoPlayVideo: false, email: 'super_email@example.com' } 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 () { .a('number') }) + it('Should be able to change the autoPlayVideo attribute', async function () { + await updateMyUser(server.url, accessTokenUser, undefined, undefined, undefined, false) + + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.autoPlayVideo).to.be.false + }) + it('Should be able to change the email display attribute', async function () { await updateMyUser(server.url, accessTokenUser, undefined, undefined, 'updated@example.com') 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 .expect(expectedStatus) } -function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, email?: string) { +function updateMyUser (url: string, accessToken: string, newPassword: string, displayNSFW?: boolean, + email?: string, autoPlayVideo?: boolean) { const path = '/api/v1/users/me' const toSend = {} if (newPassword !== undefined && newPassword !== null) toSend['password'] = newPassword if (displayNSFW !== undefined && displayNSFW !== null) toSend['displayNSFW'] = displayNSFW + if (autoPlayVideo !== undefined && autoPlayVideo !== null) toSend['autoPlayVideo'] = autoPlayVideo if (email !== undefined && email !== null) toSend['email'] = email return request(url) -- cgit v1.2.3