Skip to content

Commit

Permalink
Merge 6c02ea9 into 25383ff
Browse files Browse the repository at this point in the history
  • Loading branch information
julietezekwe committed Jan 22, 2019
2 parents 25383ff + 6c02ea9 commit dbea0fc
Show file tree
Hide file tree
Showing 16 changed files with 293 additions and 22 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
},
"nyc": {
"exclude": [
"src/helpers/EmailNotificationAPI.js"
"src/helpers/EmailNotificationAPI.js",
"test"
]
},
"author": "Andela Simulations Programme",
Expand Down
58 changes: 54 additions & 4 deletions src/controllers/UsersController.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class UsersController {
const response = new Response(
'Bad request',
400,
'There was a problem sending',
'There was a problem sending mail',
);
return res.status(response.code).json(response);
}
Expand Down Expand Up @@ -191,7 +191,7 @@ class UsersController {
const response = new Response(
'Bad request',
400,
'There was a problem sending',
'There was a problem sending mail',
);
return res.status(response.code).json(response);
}
Expand Down Expand Up @@ -250,13 +250,63 @@ class UsersController {
return res.status(response.code).json(response);
}


/**
* @static
* @desc POST /api/v1/auth/verify
* @desc PUT /api/v1/users/profile
* @param {object} req
* @param {object} res
* @memberof UsersController
* @returns successful pasword reset
* @returns successful profile update
*/
static async updateProfile(req, res) {
try {
const { id } = req.verifyUser;
const { bio, imgURL, userType } = req.body;

const updateProfile = await Profile.update(
{
bio,
imgURL,
userType
},
{
where: {
userId: id,
}
}
);
if (updateProfile[0]) {
const response = new Response(
'Ok',
200,
'Profile updated successfully',
);
return res.status(response.code).json(response);
}
const response = new Response(
'Bad Request',
400,
'Unable to update profile',
);
return res.status(response.code).json(response);
} catch (err) {
const response = new Response(
'Internal server error',
500,
`${err}`,
);
return res.status(response.code).json(response);
}
}

/**
* @static
* @desc POST /api/v1/auth/verify Email
* @param {object} req
* @param {object} res
* @memberof UsersController
* @returns successful email verification
*/
static async verifyEmail(req, res) {
const { id } = req.verifyUser;
Expand Down
1 change: 1 addition & 0 deletions src/db/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const genericOptions = {

let sequelize;
if (process.env.DATABASE_URL) {
/* istanbul ignore next */
sequelize = new Sequelize(process.env.DATABASE_URL, genericOptions);
} else {
sequelize = new Sequelize(
Expand Down
13 changes: 13 additions & 0 deletions src/db/seeders/d_profileSeeder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
up: queryInterface => queryInterface.bulkInsert('Profiles', [{
firstName: 'abejide-femi',
lastName: 'artist',
bio: null,
imgURL: null,
userId: 1,
createdAt: new Date(),
updatedAt: new Date()
}], {}),

down: queryInterface => queryInterface.bulkDelete('Users', null, {})
};
1 change: 0 additions & 1 deletion src/helpers/TokenAuthenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class TokenAuthenticate {
static async tokenVerify(req, res, next) {
const token = req.headers.authorization
|| req.headers['x-access-token'] || req.query.token || req.body.token;

if (!token) {
return res.status(401).send({
status: 'error',
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import requestId from 'express-request-id';
import expressValidator from 'express-validator';
import routes from './routes/index';
import Response from './helpers/response';
import imageValidator from './middlewares/imageValidator';

dotenv.config();
const app = express();
Expand All @@ -35,7 +36,7 @@ app.use(cors());

app.use(requestId());

app.use(expressValidator());
app.use(expressValidator(imageValidator));

morgan.token('id', req => req.id);

Expand Down
4 changes: 2 additions & 2 deletions src/middlewares/ParamsChecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class ParamsChecker {
}
return next();
};
if (userId) checkParam(userId);
if (artId) checkParam(artId);
/* istanbul ignore next */if (userId) checkParam(userId);
/* istanbul ignore next */if (artId) checkParam(artId);
}
}

Expand Down
45 changes: 44 additions & 1 deletion src/middlewares/UsersValidator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Response from '../helpers/response';

const minPassLen = 5;
const minBioLen = 25;
let response;
const userTypeOptions = ['user', 'artist'];
/**
Expand All @@ -17,7 +18,7 @@ class UserValidator {
* @static
* @memberof UserValidator
*/
static UserSignUpValidator(req, res, next) {
static userSignUpValidator(req, res, next) {
req.check('firstName', 'First Name is required').trim().notEmpty();
req.check('lastName', 'Last Name is required').trim().notEmpty();
req.check('username', 'Username is required').trim().notEmpty();
Expand Down Expand Up @@ -53,6 +54,48 @@ class UserValidator {
req.body.email = email.replace(/\s{1,}/g, '').trim().toLowerCase();
return next();
}

/**
* @description - Checks the request parameters for user reg
* @param {Object} req - request
* @param {object} res - response
* @param {Object} next - Call back function
* @return {object} - status code and error message or next()
* @static
* @memberof UserValidator
*/
static userProfileValidator(req, res, next) {
req.check('bio', 'Biography cannot be empty').trim().notEmpty();
req.check('bio', 'Biography should be more than 5 words')
.isLength({ min: minBioLen });
req.check('imgURL', 'imgURL is cannot be empty').trim().notEmpty();
req.check('imgURL', 'Only Jpeg, Png or Gif is accepted image format')
.isImage(req.body.imgURL);
req.check('userType', 'userType cannot be empty').trim().notEmpty();
const errors = req.validationErrors();
const validationErrors = [];
if (errors) {
errors.map(err => validationErrors.push(err.msg));
response = new Response(
'Bad Request',
400,
'Invalid credentials',
validationErrors
);
return res.status(response.code).json(response);
}
const { userType } = req.body;
const userTypes = userTypeOptions.includes(userType);
if (!userTypes) {
response = new Response(
'Not found',
404,
'This user type does not exist'
);
return res.status(response.code).json(response);
}
return next();
}
}

export default UserValidator;
2 changes: 1 addition & 1 deletion src/middlewares/emailCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const emailCheck = async (req, res, next) => {
);
return res.status(response.code).json(response);
}
if (!emailExist) next();
/* istanbul ignore next */ if (!emailExist) next();
};

export default emailCheck;
24 changes: 24 additions & 0 deletions src/middlewares/imageValidator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import path from 'path';

export default {
customValidators: {
isImage(imageName) {
if (imageName) {
const imageExtension = (path.extname(imageName)).toLowerCase();
switch (imageExtension) {
case '.jpg':
return '.jpg';
case '.jpeg':
return '.jpeg';
case '.png':
return '.png';
case '.gif':
return '.gif';
default:
return false;
}
}
return false;
},
},
};
2 changes: 1 addition & 1 deletion src/routes/authRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const authRouter = express.Router();
*/
authRouter
.post('/signup',
UserValidator.UserSignUpValidator,
UserValidator.userSignUpValidator,
emailCheck,
UserController.signUp);
/**
Expand Down
3 changes: 3 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import express from 'express';
import swaggerJSDoc from 'swagger-jsdoc';
import swaggerUi from 'swagger-ui-express';
import authRouter from './authRouter';
import userRouter from './userRouter';

import commentRouter from './commentRouter';
import socialRouter from './socialRouter';

Expand All @@ -10,6 +12,7 @@ const swaggerSpec = swaggerJSDoc(require('../utils/swaggerConfig')
.options);

router.use('/auth', authRouter);
router.use('/users', userRouter);
router.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
router.use('/arts/comments/', commentRouter);
router.use('/auth', socialRouter);
Expand Down
16 changes: 16 additions & 0 deletions src/routes/userRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import express from 'express';
import TokenAuthenticate from '../helpers/TokenAuthenticate';
import UserValidator from '../middlewares/UsersValidator';
import UsersController from '../controllers/UsersController';

const userRouter = express.Router();

userRouter
.put(
'/profile',
TokenAuthenticate.tokenVerify,
UserValidator.userProfileValidator,
UsersController.updateProfile
);

export default userRouter;
4 changes: 2 additions & 2 deletions test/controllers/commentControllerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Comments Endpoint API Test', () => {
});
});
describe('Comments POST REQUESTS', () => {
it('it should add a product that exists', (done) => {
it('it should comment add comment for a product that exists', (done) => {
chai.request(app)
.post('/api/v1/arts/comments/1')
.set('Authorization', userToken)
Expand All @@ -34,7 +34,7 @@ describe('Comments Endpoint API Test', () => {
done(err);
});
});
it('it should submit comment for an art that does not exit', (done) => {
it('it should not submit comment for an art that does not exit', (done) => {
chai.request(app)
.post('/api/v1/arts/comments/100')
.set('Authorization', userToken)
Expand Down
Loading

0 comments on commit dbea0fc

Please sign in to comment.