Skip to content

Commit

Permalink
Merge 8affbb3 into a6a610f
Browse files Browse the repository at this point in the history
  • Loading branch information
ngireric123 committed Oct 22, 2019
2 parents a6a610f + 8affbb3 commit dce11cb
Show file tree
Hide file tree
Showing 15 changed files with 297 additions and 28 deletions.
67 changes: 67 additions & 0 deletions src/controllers/profileController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import responseUtil from '../utils/responseUtil';
import responseError from '../utils/responseError';
import string from '../utils/stringsUtil';
import models from '../database/models';

const { users } = models;

export default class profile {
static async updateProfile(req, res) {
if (req.user.payload.email !== req.params.email) {
return responseError(res, 400, string.users.error.USER_SAME_EMAIL);
}
try {
const newUser = await users.update(
req.body,
{
where: { email: req.params.email },
returning: true,
plain: true
}
);
const {
password,
createdAt,
updatedAt,
isVerified,
...data
} = newUser[1].dataValues;
return responseUtil(res, 200, string.users.success.SUCCESS_UPDATE, data);
} catch (error) {
return responseError(res, 500, string.users.error.SOMETHING_WRONG);
}
}

static async getProfile(req, res) {
if (req.user.payload.email !== req.params.email) {
return responseError(res, 400, string.users.error.USER_SAME_EMAIL);
}
try {
const { email } = req.params;
const user = await users.findOne({
where: { email },
raw: true
});
if (!user) {
return res.status(404).json({
error: 'user does not exist'
});
}
const {
password,
isVerified,
createdAt,
updatedAt,
...data
} = user;
return res.status(200).json({
message: 'User Profile',
profile: data,
});
} catch (error) {
return res.status(500).json({
error: 'Something wrong',
});
}
}
}
32 changes: 32 additions & 0 deletions src/database/migrations/20190930143254-User.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,38 @@ module.exports = {
}
}
},
phone: {
type: Sequelize.STRING,
unique: false
},
gender: {
type: Sequelize.STRING,
allowNull: true
},
dob: {
type: Sequelize.DATE,
allowNull: true
},
country: {
type: Sequelize.STRING,
allowNull: true
},
language:{
type: Sequelize.STRING,
allowNull: true
},
currency:{
type: Sequelize.STRING,
allowNull: true
},
company:{
type: Sequelize.STRING,
allowNull: true
},
department:{
type: Sequelize.STRING,
allowNull: true
},
email: {
type: Sequelize.STRING,
allowNull: false,
Expand Down
8 changes: 8 additions & 0 deletions src/database/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ module.exports = (sequelize, Datatypes) => {
googleId: Datatypes.STRING,
facebookId: Datatypes.STRING,
password: Datatypes.STRING,
phone: Datatypes.STRING,
gender: Datatypes.STRING,
dob: Datatypes.DATE,
country: Datatypes.STRING,
language: Datatypes.STRING,
currency: Datatypes.STRING,
company: Datatypes.STRING,
department: Datatypes.STRING,
isVerified: {
type: Datatypes.BOOLEAN,
defaultValue: false,
Expand Down
11 changes: 9 additions & 2 deletions src/database/seeders/20191002153158-usersTableSeeder.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ module.exports = {
username: 'johndoe',
email: 'johndoe@test.com',
password: '$2b$10$vQp2ahUwAnRS.HHxNLK0pOQ/E41TRnxtlDJL.5vVRHsvL7DC9svNm',
isVerified: false,
role: 'requester',
isVerified: true,
phone: '+250788716711',
gender: 'M',
country: 'Rwanda',
language:'french',
currency: 'frw',
company: 'Andela',
department: 'IT',
role: 'supplier',
createdAt: new Date(),
updatedAt: new Date()
},
Expand Down
15 changes: 15 additions & 0 deletions src/middlewares/inputValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ const validation = (req, res, schema, next) => {
};

export default class InputValidation {
static validateProfile(req, res, next) {
const schema = Joi.object({
username: Joi.string().trim().min(10).max(100),
phone: Joi.string().trim().regex(/^[0-9]{3,10}$/),
gender: Joi.string().valid('female', 'male'),
language: Joi.string().min(2).max(15).regex(/^[a-zA-Z]/),
dob: Joi.date(),
country: Joi.string(),
company: Joi.string(),
department: Joi.string(),
lineManager: Joi.string(),
});
validation(req, res, schema, next);
}

static validateAddNew(req, res, next) {
const schema = Joi.object({
name: Joi.string().trim().min(10).max(100)
Expand Down
61 changes: 57 additions & 4 deletions src/routes/api/users.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import express from 'express';
import UserController from '../../controllers/userController';
import profile from '../../controllers/profileController';
import EmailToken from '../../utils/EmailToken';
import validateResetpassword from '../../middlewares/checkResetpassword';
import verifyExist from '../../middlewares/verifyExist';
import validateToken from '../../middlewares/auth/validateToken';
import InputValidation from '../../middlewares/inputValidation';
import confirmPassword from '../../middlewares/confirmPassword';
import inputValidation from '../../middlewares/inputValidation';

const { signup, signIn } = UserController;
const { validateLogin, validateSignup } = inputValidation;
const { updateProfile, getProfile } = profile;
const { validateProfile, validateLogin, validateSignup } = InputValidation;


const router = express.Router();
/**
Expand Down Expand Up @@ -128,7 +132,7 @@ const router = express.Router();
*/
/**
* @swagger
* users/forgotpassword:
* /users/forgotpassword:
* post:
* tags:
* - Authentication
Expand Down Expand Up @@ -169,7 +173,7 @@ const router = express.Router();
*/
/**
* @swagger
* users/resetpassword/{token}:
* /users/resetpassword/{token}:
* patch:
* tags:
* - Authentication
Expand Down Expand Up @@ -198,11 +202,60 @@ const router = express.Router();
* '400':
* description: Token expired request a new one
*/
/**
* @swagger
* definitions:
* updateprofile:
* type: object
* properties:
* language:
* type: string
* example: kinyarwanda
* newpassword:
* type: string
* format: string
* example: Pa55W0rd
* confirmpassword:
* type: string
* format: string
* example: Pa55W0rd
*/
/**
* @swagger
* /users/{email}:
* patch:
* tags:
* - Authentication
* name: profile
* summary: user profile page setting
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: email
* in: path
* - name: body
* in: body
* schema:
* $ref: '#/definitions/updateprofile'
* responses:
* '200':
* description: profile successfully updated
* '404':
* description: can not find that user
* '500':
* description: interrnal server error
* '400':
* description: invalid data
*/

router.post('/register', validateSignup, verifyExist, confirmPassword, signup);
router.get('/verify/:token', UserController.userVerify);
router.post('/forgotpassword', validateResetpassword.checkEmail, UserController.Providelink);
router.patch('/resetpassword/:token', EmailToken.UseraccessRequired, validateResetpassword.checkReset, UserController.Changepassword);
router.patch('/profile/:email', validateToken, validateProfile, updateProfile);
router.post('/login', validateLogin, signIn);
router.get('/profile/:email', validateToken, getProfile);

export default router;
3 changes: 3 additions & 0 deletions src/tests/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import authTests from './socialAuthTests.spec'
import defaultTests from './defaultTests.spec'
import signupTests from './signupTest.spec'
import profileTests from './profile.spec'
import loginTest from './loginTest.spec';
import requestTest from './requestTests.spec'
import accommodationTest from './accommodationTest.spec';
Expand All @@ -12,4 +13,6 @@ describe('Signup Tests', signupTests);
describe('Login Tests', loginTest);
describe('Request Test', requestTest);
describe('Accommodation Tests', accommodationTest);
describe('Setting Profile Test',profileTests);
describe('Social Authentication Tests', loginTest);
describe('Edit-Delete Accommodations Tests', editDeleteAccommodationsTests);
2 changes: 2 additions & 0 deletions src/tests/mockData/mockData.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ const mockData = {
missingData:{name: '', location: ''},
requester:{email: 'mateso@caretbn.com', password: 'Pa55w0rd' },
admin:{email: 'alain@caretbn.com', password: 'Pa55w0rd' },
fakeGender: { gender: 'xxxx' },
missingFields: { email: '', password: '' }
};
export default mockData;
9 changes: 9 additions & 0 deletions src/tests/mockData/signupMockdata.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ const testdata = {
password: 'Pa$5W0rd',
confirmPassword: 'Pa$5W0rd',
},
userProfile: {
id: '11',
username: 'caretdevs',
email: 'team11@gmail.com',
password: 'Pa$5W0rd',
confirmPassword: 'Pa$5W0rd',
language: 'lingala',
isVerified: true,
},

missingEmail: {
username: 'caretdevs1',
Expand Down
85 changes: 85 additions & 0 deletions src/tests/profile.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import chai from 'chai';
import chaiHttp from 'chai-http';
import { describe, it } from 'mocha';
import app from '../index';
import mockdata from './mockData/mockData';
import generateToken from '../utils/generateToken';
import string from '../utils/stringsUtil';

const token = generateToken(mockdata.verifiedUser);

chai.should();
chai.use(chaiHttp);

const email = mockdata.verifiedUser.email;
let newEmail;
let malformedToken;

const newProfile = {
language: 'Spanish',
};

describe('Profile Test Suite', () => {
it('Should edit Profile Page Settings', (done) => {
chai.request(app)
.patch(`/api/v1/users/profile/${email}`)
.set('Authorization', `Bearer ${token}`)
.send(newProfile)
.end((err, res) => {
res.should.have.status(200);
res.body.should.be.a('object');
res.body.should.have.property('message').eql(`${string.users.success.SUCCESS_UPDATE}`);
done();
});
});
it('Should return 400 when gender is not female or male', (done) => {
chai.request(app)
.patch(`/api/v1/users/profile/${email}`)
.set('Authorization', `Bearer ${token}`)
.send(mockdata.fakeGender)
.end((err, res) => {
res.should.have.status(400);
res.body.should.be.a('object');
done();
});
});
it('should return 400 if email is not the some of token', (done) => {
chai.request(app)
.patch(`/api/v1/users/profile/${newEmail}`)
.set('Authorization', `Bearer ${token}`)
.send(newProfile)
.end((err, res) => {
res.should.have.status(400);
done();
});
});
it('should not accept malformed', (done) => {
chai.request(app)
.patch(`/api/v1/users/profile/${email}`)
.set('Authorization', `Bearer ${malformedToken}`)
.send(newProfile)
.end((err, res) => {
res.should.have.status(400);
done();
});
});
it('should get a specific user', (done) => {
chai.request(app)
.get(`/api/v1/users/profile/${email}`)
.set('Authorization', `Bearer ${token}`)
.end((err, res) => {
res.should.have.status(200);
done();
});
});
it('should return 400 if email is not the some of token', (done) => {
chai.request(app)
.get(`/api/v1/users/profile/${newEmail}`)
.set('Authorization', `Bearer ${token}`)
.end((err, res) => {
console.log(res.body)
res.should.have.status(400);
done();
});
});
});
2 changes: 1 addition & 1 deletion src/tests/requestTests.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('Request Tests', () => {
.end((err, res) => {
const { status, body } = res;
expect(status).to.be.eql(400, 'Incorrect Status Code Returned.');
expect(body.message).to.be.eql('Unable to validate token, please sign in again', 'Wrong message returned');
expect(body.message).to.be.eql('Invalid token please sign again', 'Wrong message returned');
done();
});
})
Expand Down
Loading

0 comments on commit dce11cb

Please sign in to comment.