Skip to content

Commit

Permalink
bug(fix-live-app): The live application should be running smoothly [F…
Browse files Browse the repository at this point in the history
…inishes #167938441]
  • Loading branch information
Noah Kalyesubula authored and Noah Kalyesubula committed Aug 16, 2019
2 parents 81045b0 + 7f0c6eb commit 172687f
Show file tree
Hide file tree
Showing 23 changed files with 1,045 additions and 581 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ TWITTER_SECRET='ggug'
CLOUDINARY_API_KEY=xxxxxxxxxxxxxxxxx
CLOUDINARY_SECRET_KEY=xxxxxxxxxxxxxxxx
CLOUDINARY_NAME=xxxxxxxxxxxxx
TWITTER_CALLBACK_URL='ghgfh'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ typings/

#ignore vscode settings file
.vscode/settings.json
#ignore DS_Store
.DS_Store

# End of https://www.gitignore.io/api/node

596 changes: 61 additions & 535 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 5 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"description": "A Social platform for the creative at heart",
"main": "./src/app.js",
"scripts": {
"start": "npm run undoseeds && npm run migration && npm run seeds && babel-node ./src/app.js",
"start": "npm run undoseeds && npm run undomigration && npm run migration && npm run seeds && babel-node ./src/app.js",
"seeds": "babel-node node_modules/.bin/sequelize db:seed:all --seeders-path src/seeders",
"undoseeds": "babel-node node_modules/.bin/sequelize db:seed:undo:all",
"migration": "babel-node node_modules/.bin/sequelize db:migrate",
"undomigration": "npm run undoseeds && babel-node node_modules/.bin/sequelize db:migrate:undo:all",
"undomigration": "babel-node node_modules/.bin/sequelize db:migrate:undo:all",
"runmigrations": "npm run undoseeds && npm run migration && npm run seeds",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"test": "export NODE_ENV=test && npm run undomigration && npm run migration && npm run seeds && nyc --reporter=html --reporter=text mocha ./test --no-timeout --exit --require @babel/register",
Expand All @@ -29,25 +29,20 @@
"bcrypt": "^3.0.6",
"body-parser": "^1.19.0",
"cloudinary": "^1.14.0",
"connect-multiparty": "^2.2.0",
"cors": "^2.8.5",
"coverage": "^0.4.1",
"dotenv": "^6.2.0",
"ejs": "^2.6.1",
"errorhandler": "^1.5.0",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-jwt": "^5.3.1",
"express-session": "^1.15.6",
"joi": "^14.3.1",
"jsonwebtoken": "^8.5.1",
"method-override": "^2.3.10",
"methods": "^1.1.2",
"multer": "^1.4.2",
"nyc": "^14.1.1",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-google-oauth": "^2.0.0",
"passport-local": "^1.0.0",
"passport-twitter": "^1.0.4",
"pg": "^7.12.0",
"pg-hstore": "^2.3.3",
Expand All @@ -57,14 +52,11 @@
"slug": "^1.1.0",
"swagger-jsdoc": "^3.3.0",
"swagger-ui-express": "^4.0.7",
"underscore": "^1.9.1",
"winston": "^3.2.1",
"zombie": "^6.1.4",
"uniqid": "^5.0.3"
"uniqid": "^5.0.3",
"winston": "^3.2.1"
},
"devDependencies": {
"coveralls": "^3.0.5",
"mocha-lcov-reporter": "^1.3.0",
"eslint": "^6.1.0",
"eslint-config-airbnb-base": "^13.2.0",
"eslint-plugin-import": "^2.18.2",
Expand Down
99 changes: 99 additions & 0 deletions src/controllers/profile.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import cloudinary from 'cloudinary';
import UserService from '../services/user.service';
import Util from '../helpers/util';

const util = new Util();

/**
* @description User profile
*/
class Profile {
/**
* @description get user profile
* @param {object} req
* @param {object} res
* @returns {object} return object containing user profile
*/
static async getProfile(req, res) {
const userName = req.params.username;

try {
let userfound;
if (userName) {
userfound = await UserService.findOne('', userName);
} else {
userfound = await UserService.findOne(req.auth.email, '');
}
if (!userfound) {
util.setError(404, 'Profile not found');
return util.send(res);
}
const data = {
username: userfound.username,
bio: userfound.bio,
image: userfound.image,
};
util.setSuccess(200, 'Successfully retrieved a user profile', data);
return util.send(res);
} catch (err) {
util.setError(400, 'we are facing some problemsin system, please contact administrator');
return util.send(res);
}
}

/**
* @description update user profile
* @param {object} req
* @param {object} res
* @returns {object} return object containing updated user profile
*/
static async updateProfile(req, res) {
let filename = '';
if (req.files.image) {
filename = req.files.image.path;
}
cloudinary.v2.uploader.upload(filename, { tags: 'CodepiratesAuthors-haven' }, async (err, image) => {
try {
const userName = req.auth.email;
const user = await UserService.findOne(userName, '');
const oldURL = user.image;
if (!user) {
util.setError(400, 'User not found');
return util.send(res);
}
const usernamefound = await UserService.getUserByUserName(req.body.username, userName);
if (usernamefound) {
util.setError(409, 'Sorry! The profile username taken, try another one');
return util.send(res);
}
let imgURL;
if (!err) {
imgURL = image.secure_url;
}
if (!imgURL) {
imgURL = oldURL;
}
const prof = {
email: req.auth.email,
username: req.body.username,
bio: req.body.bio,
image: imgURL,
};
const updateProfile = await UserService.updateProfile(prof);
const newProfile = {
userName: updateProfile[1].username,
email: updateProfile[1].email,
bio: updateProfile[1].bio,
image: updateProfile[1].image,
upadatedAt: updateProfile[1].upadatedAt,
};
util.setSuccess(200, 'Successfully Profile Updated.', newProfile);
return util.send(res);
} catch (error) {
util.setError(400, 'we are having some problems in system, please contact administrator');
return util.send(res);
}
});
}
}
export default Profile;
129 changes: 129 additions & 0 deletions src/controllers/rating.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import db from '../models/index';
import RateService from '../services/rate.service';
/**
*
*
* @class rateController
*/
class rateController {
/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} return rating information to user
* @memberof UserController
*/
static async setArticleRating(req, res) {
try {
// Initialize rating data
const userEmail = req.auth.email;
const { rate } = req.body;
const { articleSlug } = req.params;
const rateSchema = { userEmail, articleSlug, rate };

// check if user is trying to rate his/her own article
const article = await db.Article.findOne({
where: { slug: articleSlug }
});
const user = await db.user.findOne({
where: { id: article.authorId }
});
if (user.email === userEmail) {
return res.status(400).send({
status: 400,
message: 'You cannot rate your own article'
});
}

// create rating
const createdRate = await RateService.create(rateSchema);
return res.status(200).send({
status: 200,
message: 'Thank you for rating this article',
data: createdRate
});
} catch (error) {
return res.status(404).send({
status: 404,
message: error.message
});
}
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} return rating information to user
* @memberof UserController
*/
static async updateArticleRating(req, res) {
try {
// Initialize rating data
const userEmail = req.auth.email;
const { rate } = req.body;
const { articleSlug } = req.params;

// update article rate
const updatedRate = await RateService.update(articleSlug, userEmail, rate);
if (!updatedRate) {
return res.status(400).send({
status: 400,
error: `Rating for article with Slug: ${articleSlug} not found`
});
}
return res.status(200).send({
status: 200,
message: 'Thank you for rating this article',
newRating: updatedRate
});
} catch (error) {
return res.status(404).send({
status: 404,
message: error.message
});
}
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} return rating information to user
* @memberof rateController
*/
static async getArticleRating(req, res) {
try {
// Initialize rating data
const userEmail = req.auth.email;
const { articleSlug } = req.params;

// find particular rating
const userRate = await RateService.findOne(articleSlug, userEmail);
if (!userRate) {
return res.status(400).send({
status: 400,
error: `Rating for article with slug ${articleSlug} not found`,
});
}
return res.status(200).send({
status: 200,
message: `Rating for article with slug ${articleSlug} found`,
data: userRate
});
} catch (error) {
return res.status(404).send({
status: 404,
message: error.message
});
}
}
}

export default rateController;
21 changes: 21 additions & 0 deletions src/middlewares/validators/rate.validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Joi from 'joi';
import Util from '../../helpers/util';

const util = new Util();

export default (req, res, next) => {
const { rate } = req.body;

const schema = {
rate: Joi.number().integer().min(1).max(5),
};
const { error } = Joi.validate({
rate
}, schema);

if (!error) return next();
const errorMessageFromJoi = error.details[0].message;
const removeEscapeCharacters = errorMessageFromJoi.replace(/['"]+/g, '');
util.setError(400, removeEscapeCharacters);
return util.send(res);
};
38 changes: 38 additions & 0 deletions src/middlewares/validators/user.profile.validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Joi from 'joi';
import Util from '../../helpers/util';

const util = new Util();

export default (req, res, next) => {
const {
username, bio
} = req.body;

const schema = {
username: Joi.string()
.trim()
.regex(/^[a-zA-Z]+$/)
.min(3)
.max(20),
bio: Joi.string()
.trim()
.min(20)
};
const { error } = Joi.validate({
bio, username
}, schema);

if (!error) return next();
const errorMessageFromJoi = error.details[0].message;
switch (errorMessageFromJoi) {
case `"bio" with value "${String(bio)}" fails to match the required pattern: /^[a-zA-Z]+$/`:
util.setError(400, 'bio should contain only characters');
return util.send(res);
case `"username" with value "${String(username)}" fails to match the required pattern: /^[a-zA-Z]+$/`:
util.setError(400, 'username should contain only characters');
return util.send(res);
default:
util.setError(400, errorMessageFromJoi);
return util.send(res);
}
};
Loading

0 comments on commit 172687f

Please sign in to comment.