Skip to content

Commit

Permalink
Save user's locale to database (API) (#962)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkvon committed Dec 15, 2018
1 parent f689363 commit ffca3ec
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Expand Up @@ -105,7 +105,8 @@ module.exports = {
files: [
'testutils/data.server.testutils.js',
'modules/references/server/**',
'modules/references/tests/server/**'
'modules/references/tests/server/**',
'modules/users/tests/server/user-change-locale.server.routes.tests.js'
],
parserOptions: {
ecmaVersion: 2018
Expand Down
@@ -1,5 +1,8 @@
'use strict';

var path = require('path'),
languages = require(path.resolve('./config/languages/languages'));

/**
* Module dependencies.
*/
Expand Down Expand Up @@ -300,6 +303,14 @@ exports.update = function (req, res) {
});
}

// validate locale
// @TODO validation framework
if (req.body.locale && (typeof req.body.locale !== 'string' || !Object.keys(languages).includes(req.body.locale))) {
return res.status(400).send({
message: errorService.getErrorMessageByKey('bad-request')
});
}

async.waterfall([

function (done) {
Expand Down
5 changes: 5 additions & 0 deletions modules/users/server/models/user.server.model.js
Expand Up @@ -249,6 +249,11 @@ var UserSchema = new Schema({
type: Boolean,
default: false
},
/* Preferred interface language (client, emails, ...) */
locale: {
type: String,
default: ''
},
passwordUpdated: {
type: Date
},
Expand Down
151 changes: 151 additions & 0 deletions modules/users/tests/server/user-change-locale.server.routes.tests.js
@@ -0,0 +1,151 @@
'use strict';

const mongoose = require('mongoose'),
path = require('path'),
request = require('supertest'),
should = require('should'),
utils = require(path.resolve('./testutils/data.server.testutils')),
express = require(path.resolve('./config/lib/express')),
User = mongoose.model('User');

const app = express.init(mongoose.connection);
const agent = request.agent(app);

describe('User account: change locale', () => {

const publicUsers = utils.generateUsers(1, { public: true });
const nonpublicUsers = utils.generateUsers(1, { public: false, username: 'nonpublic', email: 'nonpublic@example.com' });
let users;

// save users
beforeEach(async () => {
users = await utils.saveUsers([...publicUsers, ...nonpublicUsers]);
});

afterEach(utils.clearDatabase);

context('logged in', () => {

beforeEach(async () => {
await utils.signIn(publicUsers[0], agent);
});

afterEach(async () => {
await utils.signOut(agent);
});

context('valid value', () => {
it('200 and save the new locale to user model', async () => {

const { username } = users[0];

const userBefore = await User.findOne({ username }).lean();
should(userBefore).have.property('locale', '');

const { body } = await agent
.put('/api/users')
.send({ locale: 'cze' })
.expect(200);

should(body).have.property('locale', 'cze');

const userAfter = await User.findOne({ username }).lean();
should(userAfter).have.property('locale', 'cze');
});
});

context('invalid value', () => {
it('[number] 400', async () => {
await agent
.put('/api/users')
.send({ locale: 1111 })
.expect(400);
});

it('[invalid string] 400', async () => {
await agent
.put('/api/users')
.send({ locale: 'invalid string' })
.expect(400);
});
});
});

context('logged in as nonpublic user', () => {
beforeEach(async () => {
await utils.signIn(nonpublicUsers[0], agent);
});

afterEach(async () => {
await utils.signOut(agent);
});

it('can update, too', async () => {

const { username } = nonpublicUsers[0];

const userBefore = await User.findOne({ username }).lean();
should(userBefore).have.property('locale', '');

await agent
.put('/api/users')
.send({ locale: 'eng' })
.expect(200);

const userAfter = await User.findOne({ username }).lean();
should(userAfter).have.property('locale', 'eng');
});
});

context('not logged in', () => {
it('403', async () => {
await agent
.put('/api/users')
.send({ locale: 'eng' })
.expect(403);
});
});
});

describe('User account: read locale', () => {
const publicUsers = utils.generateUsers(2, { public: true, locale: 'eng' });

// save users
beforeEach(async () => {
await utils.saveUsers(publicUsers);
});

afterEach(utils.clearDatabase);

context('logged in', () => {

beforeEach(async () => {
await utils.signIn(publicUsers[0], agent);
});

afterEach(async () => {
await utils.signOut(agent);
});

it('[self] response body of /api/auth/signin should include locale', async () => {
const { username, password } = publicUsers[0];

const { body } = await agent
.post('/api/auth/signin')
.send({ username, password })
.expect(200);

should(body).have.property('locale', 'eng');
});

it('response body of /api/users/:username shouldn\'t include locale', async () => {
const otherUser = publicUsers[1];

const { body } = await agent
.get(`/api/users/${otherUser.username}`)
.expect(200);

should(body).not.have.property('locale');
});
});
});
4 changes: 3 additions & 1 deletion testutils/data.server.testutils.js
Expand Up @@ -27,11 +27,12 @@ function getRandInt(exclusiveMaximum) {
* @param {string} [defs.firstName=GivenName] - first name (will have a number appended)
* @param {string} [defs.lastName=FamilyName] - last name (will have a number appended)
* @param {string} [defs.email=user(at)example.com] - email (will have a number prepended)
* @param {string} [defs.locale=] - locale (preferred language)
* @param {boolean} [defs.publ] - is the user public? (defaults to a random boolean)
* @param {string} [defs.password] - password (defaults to a random password)
* @returns {object[]} array of user data
*/
function generateUsers(count, { username='username', firstName='GivenName', lastName='FamilyName', email='user@example.com', public: pub, password }={ }) {
function generateUsers(count, { username='username', firstName='GivenName', lastName='FamilyName', email='user@example.com', locale='', public: pub, password }={ }) {

return _.range(count).map(i => ({
public: (typeof pub === 'boolean') ? pub : !getRandInt(2),
Expand All @@ -40,6 +41,7 @@ function generateUsers(count, { username='username', firstName='GivenName', last
email: i + email,
username: username + i,
displayUsername: username + i,
locale,
password: password || crypto.randomBytes(24).toString('base64')
}));
}
Expand Down

0 comments on commit ffca3ec

Please sign in to comment.