Skip to content

Commit

Permalink
[Feature #165412912] signup validation error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
rwajon committed May 16, 2019
1 parent 3892b33 commit 1503305
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 54 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "A Social platform for the creative at heart",
"main": "src/index.js",
"scripts": {
"test": "NODE_ENV=test npm run db:migrate && NODE_ENV=test nyc mocha --require @babel/register --timeout 30000 src/tests/index.js",
"test": "NODE_ENV=test sequelize db:migrate:undo:all && NODE_ENV=test npm run db:migrate && NODE_ENV=test nyc mocha --require @babel/register --timeout 30000 src/tests/index.js",
"cover": "npm test && nyc report --reporter=text-lcov | coveralls",
"coveralls": "cat coverage/lcov.info | coveralls",
"start": "babel-node src/index.js",
Expand Down
6 changes: 3 additions & 3 deletions src/helpers/validation/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export default (input, required = '') => {

let errors = [];
const re = /[A-Z0-9]+@[A-Z0-9-]+\.[A-Z]{2,4}/gim;
const reUsername = /[\\ ,;:"!#$%&'*+/=?^`{|}~]/g;
const reDomainSLD = /[ \\,;:"!#$%&'*+/=?^`{|}~]/g;
const reDomainTLD = /[\d+ \\,;:"!#$%&'*+-/=?^_`{|}~]/g;
const reUsername = /[\\ ,;:"!#$%&'*+/=?^`{|}~([\])]/g;
const reDomainSLD = /[ \\,;:"!#$%&'*+/=?^`{|}~([\])]/g;
const reDomainTLD = /[\d+ \\,;:"!#$%&'*+-/=?^_`{|}~([\])]/g;

const emailUsername = input.substring(0, input.lastIndexOf('@'));
const emailDomainSLD = input.substring(input.lastIndexOf('@') + 1, input.lastIndexOf('.'));
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/validation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import email from './email';
import password from './password';
import createArticle from './createArticle';
import updateArticle from './updateArticle';
import newUser from './newUser';

export {
isUser, email, password, createArticle, updateArticle
isUser, email, password, createArticle, updateArticle, newUser
};
37 changes: 37 additions & 0 deletions src/helpers/validation/newUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Joi from 'joi';

export default (input) => {
const schema = Joi.object().keys({
firstName: Joi.string()
.min(2)
.max(45)
.required()
.label('First name'),
lastName: Joi.string()
.min(2)
.max(45)
.required()
.label('Last name'),
username: Joi.string()
.min(4)
.max(45)
.required(),
email: Joi.string()
.min(5)
.max(100)
.required(),
password: Joi.string()
.min(5)
.max(100)
.required(),
role: Joi.string()
.min(2)
.max(100)
.optional(),
permissions: Joi.array()
.items(Joi.string().min(1))
.optional()
});

return Joi.validate(input, schema, { abortEarly: false });
};
2 changes: 1 addition & 1 deletion src/helpers/validation/password.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default (input, required = '') => {
}
if (
input.match(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,25}$/)
&& input.match(/[ \\,;:"!#$%&'+-/=?^_`{|}~]/)
&& input.match(/[ \\,;:"!#$@*%&'+-/=?^_`{|}~]/)
) {
return [];
}
Expand Down
38 changes: 23 additions & 15 deletions src/middlewares/validateNewUser.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import * as validate from '../helpers/validation';
import status from '../config/status';

export default async (req, res, next) => {
if (Object.keys(req.body).length <= 0) {
return res.status(400).json({ errors: { body: ['body can not be empty'] } });
}
const errors = {};
const { error } = validate.newUser(req.body);

// check errors in email or password
const errors = {
email: [...validate.email(req.body.email, 'required')],
password: [...validate.password(req.body.password, 'required')]
};
if (error && typeof error === 'object' && Object.keys(error).length) {
error.details.forEach((err) => {
if (errors[err.path[0]] && errors[err.path[0]].length) {
errors[err.path[0]] = [...[err.message]];
} else {
errors[err.path[0]] = [err.message];
}
});
}

const isUser = await validate.isUser({ email: req.body.email });
if (errors && !Object.keys(errors).length) {
const checkEmail = validate.email(req.body.email, 'required');
const checkPassword = validate.password(req.body.password, 'required');

if (isUser) {
errors.email = [...['sorry, this email is already used']];
if (checkEmail.length) {
errors.email = checkEmail;
}
if (checkPassword.length) {
errors.password = checkPassword;
}
}

Object.keys(errors).forEach(error => errors[error].length > 0 || delete errors[error]);

if (Object.keys(errors).length > 0) {
return res.status(400).json({ errors });
if (Object.keys(errors).length) {
return res.status(status.BAD_REQUEST).json({ errors });
}

next();
Expand Down
12 changes: 7 additions & 5 deletions src/tests/controllers/users.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@ import chaiHttp from 'chai-http';
import app from '../../app';
import status from '../../config/status';
import db from '../../models';
import { factory } from '../../helpers';
import * as Factory from '../../helpers/factory';

chai.should();
chai.use(chaiHttp);
const user = Factory.user.build();
delete user.id;

// user test
describe('user tests', () => {
const user = factory.user.build();

// test signup;
before(async () => {
try {
await db.User.destroy({
where: { email: user.email }
truncate: true,
cascade: true,
logging: false
});
} catch (error) {
throw error;
}
});
// test signup;
describe('user signup', () => {
it('Should register new user', (done) => {
chai
Expand Down
42 changes: 14 additions & 28 deletions src/tests/middlewares/validateNewUser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import chai from 'chai';
import chaiHttp from 'chai-http';
import express from 'express';
import * as Factory from '../../helpers/factory';
import db from '../../models';
import validateNewUser from '../../middlewares/validateNewUser';

const { expect } = chai;
Expand All @@ -25,20 +24,7 @@ app.use('/api/users', router.post('/', validateNewUser));
const newUser = Factory.user.build();
delete newUser.id;

describe('Check Existing user', () => {
before(async () => {
try {
await db.User.destroy({
truncate: true,
cascade: true,
logging: false
});
await db.User.create(newUser, { logging: false });
} catch (error) {
throw error;
}
});

describe('validate user inputs when on registration', () => {
it('should return an error message if the body is empty', (done) => {
chai
.request(app)
Expand All @@ -47,12 +33,13 @@ describe('Check Existing user', () => {
.end((err, res) => {
const { errors } = res.body;
expect(res.status).to.equal(400);
expect(errors.body.length).to.be.above(0);
expect(Object.keys(errors).length).to.be.above(0);
done();
});
});

it('should return an error message if there is an existing user email', (done) => {
it('should return an error message if the email is not valid', (done) => {
newUser.email = 'abcdz@gma/il.com';
chai
.request(app)
.post('/api/users')
Expand All @@ -65,44 +52,43 @@ describe('Check Existing user', () => {
});
});

it('should return an error message if the email is not valid', (done) => {
newUser.email = 'abcdz@gma/il.com';
it("should return an error message if the password doesn't meet the requirements", (done) => {
newUser.password = 'baaa1234';
newUser.email = Factory.user.build().email;
chai
.request(app)
.post('/api/users')
.send(newUser)
.end((err, res) => {
const { errors } = res.body;
expect(res.status).to.equal(400);
expect(errors.email.length).to.be.above(0);
expect(errors.password.length).to.be.above(0);
done();
});
});

it("should return an error message if the password doesn't meet the requirements", (done) => {
newUser.password = 'baaa1234';
newUser.email = Factory.user.build().email;
it('should not return any error', (done) => {
newUser.email = 'aaabbbccc@gmail.com';
newUser.password = 'Baaa1234!';
chai
.request(app)
.post('/api/users')
.send(newUser)
.end((err, res) => {
const { errors } = res.body;
expect(res.status).to.equal(400);
expect(errors.password.length).to.be.above(0);
expect(res.status).to.not.equal(400);
done();
});
});

it('should not return any error', (done) => {
newUser.email = 'aaabbbccc@gmail.com';
newUser.email = '';
newUser.password = 'Baaa1234!';
chai
.request(app)
.post('/api/users')
.send(newUser)
.end((err, res) => {
expect(res.status).to.not.equal(400);
expect(res.status).to.equal(400);
done();
});
});
Expand Down

0 comments on commit 1503305

Please sign in to comment.