Skip to content

Commit

Permalink
Write more test #164139773
Browse files Browse the repository at this point in the history
  • Loading branch information
mezlet committed Mar 9, 2019
1 parent 9d1757d commit a8b9190
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 101 deletions.
Empty file removed index.html
Empty file.
2 changes: 1 addition & 1 deletion server/controllers/auth-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
comparePassword
} from '../utils/helpers';
import db from '../models';
import registerSchema from '../utils/validators';
import { registerSchema } from '../utils/validators';

const { User } = db;

Expand Down
98 changes: 55 additions & 43 deletions server/controllers/user-controller.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,58 @@
import { successResponse, errorResponse, uploadImages } from '../utils/helpers';
import { User, Sequelize } from '../models';
import {
successResponse,
errorResponse,
validate,
validationErrorResponse,
checkUniqueUserName
} from '../utils/helpers';
import db from '../models';
import { profileSchema } from '../utils/validators';

const { User } = db;

/**
* The controllers for users route
*
* @class UsersController
*/
class UsersController {
/**
* @param {string} username
* @param {integer} id
* @returns {object} user
* update user profile
* @static
* @param {Request} req request object
* @param {Response} res response object
* @memberof {Users}
* @returns {undefined}
*/
static async checkUniqueUserName(username, id) {
const { Op } = Sequelize;
const user = await User.findOne({
where: {
username,
id: { [Op.ne]: id }
}
});
return user === null;
static async updateUser(req, res) {
validate(req.body, profileSchema)
.then(async () => {
const { ...auth } = req.authUser;
try {
const { username, bio } = req.body;
const user = await User.findOne({
where: { id: auth.id }
});
const isUnique = await checkUniqueUserName(username, auth.id);
if (!isUnique) {
return errorResponse(res, 'username already exist', 409);
}
const data = await user.update(
{ username, bio },
{ returning: true, where: { id: auth.id } }
);
successResponse(
res,
{ message: 'update successful', user: data },
200
);
} catch (error) {
errorResponse(res, error.message, 500);
}
})
.catch(({ details }) => {
validationErrorResponse(res, details, 400);
});
}

/**
Expand All @@ -30,37 +63,16 @@ class UsersController {
* @memberof {Users}
* @returns {undefined}
*/
static async updateUser(req, res) {
static async getProfile(req, res) {
try {
const { authUser } = req;
const { username, bio } = req.body;
const user = await User.findOne({ where: { id: authUser.id } });
if (authUser.id !== user.dataValues.id) {
return errorResponse(res, 'you cannot edit this entry', 401);
const { id } = req.authUser;
const user = await User.findOne({ where: { id } });
if (user) {
delete user.hash;
successResponse(res, { data: user }, 200);
}
const isUnique = await UsersController.checkUniqueUserName(
username,
authUser.id
);
if (!isUnique) {
return errorResponse(res, 'username already exist', 400);
}
let imagePath = '';
if (req.file) {
imagePath = await uploadImages(req.file);
}
const data = await user.update({
username,
bio,
imagePath
});
successResponse(
res,
{ status: 200, message: 'update successful', user: data },
200
);
} catch (error) {
errorResponse(res, error.message, 500);
} catch (err) {
errorResponse(res, err.message, 500);
}
}
}
Expand Down
33 changes: 0 additions & 33 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,13 @@ import morgan from 'morgan';
import debug from 'debug';
import passport from 'passport';
import session from 'express-session';
import multer from 'multer';
import cloudinary from 'cloudinary';
import cloudinaryStorage from 'multer-storage-cloudinary';
import env from './config/env-config';
import routes from './routes/index';
// import storage from './config/cloudinary';

const app = express();
const logger = debug('vale-ah::server: ');

// app.use(multer({ storage }).single('image'));
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
});

const storage = cloudinaryStorage({
cloudinary,
allowedFormats: [
'jpg',
'svg',
'png',
'jpeg',
'gif',
'avi',
'flv',
'mpeg',
'3gp',
'mp4',
'webm'
],
params: {
resource_type: 'auto',
folder: 'iReporter/media'
}
});

app.use(multer({ storage }).single('image'));

app.use(cors());
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
Expand Down
13 changes: 9 additions & 4 deletions server/middlewares/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import jwt from 'jsonwebtoken';
import { User } from '../models';
import db from '../models';

const { User } = db;
/**
*Users endpoint middlewares
*
Expand All @@ -25,15 +27,18 @@ export default class UsersMiddleware {
}
try {
const decoded = await jwt.verify(token, process.env.SECRET);
const rows = await User.findOne({
const data = await User.findOne({
where: { id: decoded.id }
});
if (!rows) {
if (!data) {
return res.status(400).send({
message: 'The token you provided is invalid'
});
}
req.authUser = rows.dataValues;
req.authUser = {
id: decoded.id,
username: decoded.username
};
return next();
} catch (error) {
return res.status(401).send(error);
Expand Down
2 changes: 1 addition & 1 deletion server/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { errorResponse } from '../utils/helpers';
const router = app => {
app.use('/api-docs', serve, setup(apiSpec));
app.use('/api/users', authRoutes);
app.use('/api/profiles', userRoutes);
app.use('/api/user', userRoutes);

app.use('*', (req, res) =>
errorResponse(res, 'The requested resource was not found', 404)
Expand Down
7 changes: 4 additions & 3 deletions server/routes/user-routes.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Router } from 'express';
// import multer from 'multer';
import User from '../middlewares/index';
import userController from '../controllers/user-controller';
// import userController from '../controllers/user-controller';
import UsersController from '../controllers/user-controller';

const router = new Router();

// const upload = multer({ dest: 'public/uploads/' });

router.post('/', User.verifyToken, userController.updateUser);

router.put('/', User.verifyToken, UsersController.updateUser);
router.get('/', User.verifyToken, UsersController.getProfile);
export default router;
26 changes: 13 additions & 13 deletions server/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import Joi from 'joi';
import env from '../config/env-config';
import db from '../models';

const { User, Sequelize } = db;

const { SECRET } = env;

Expand Down Expand Up @@ -93,20 +96,17 @@ export const validate = (value, schema) =>
Joi.validate(value, schema, { abortEarly: false, allowUnknown: true });

/**
* Validates a value using the given schema
* @param {*} value
* @param {*}
* @returns {Promise}
* @param {string} username
* @param {integer} id
* @returns {object} user
*/

export const uploadImages = async files => {
let imagePath = '';
const filePaths = files.secure_url;
imagePath = filePaths;
return new Promise(async (resolve, reject) => {
if (imagePath) {
return resolve(imagePath);
export const checkUniqueUserName = async (username, id) => {
const { Op } = Sequelize;
const user = await User.findOne({
where: {
username,
id: { [Op.ne]: id }
}
return reject(Error('Unable to upload media item'));
});
return user === null;
};
10 changes: 8 additions & 2 deletions server/utils/validators.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Joi from 'joi';

const registerSchema = Joi.object().keys({
export const registerSchema = Joi.object().keys({
email: Joi.string()
.email()
.required(),
Expand All @@ -14,4 +14,10 @@ const registerSchema = Joi.object().keys({
.required()
});

export default registerSchema;
export const profileSchema = Joi.object().keys({
bio: Joi.string(),
username: Joi.string()
.min(3)
.max(20)
.required()
});
87 changes: 86 additions & 1 deletion test/users.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const user1 = {
email: faker.internet.email(),
password: 'esiaguleticia12'
};

describe('Authentication', () => {
describe('POST /api/users', () => {
const baseUrl = '/api/users';
Expand Down Expand Up @@ -113,6 +112,17 @@ describe('Authentication', () => {
});

describe('POST /api/users/login', () => {
it('should rLogin user with right', done => {
chai
.request(server)
.post('/api/users/login')
.send(user1)
.end((err, res) => {
expect(res).to.have.status(200);
done(err);
});
});

it('should reject a credential with wrong password', done => {
chai
.request(server)
Expand Down Expand Up @@ -140,3 +150,78 @@ describe('Authentication', () => {
});
});
});

describe('User', () => {
let loggedInUser;

before(() => {
const { email, password } = user1;
return chai
.request(server)
.post('/api/users/login')
.send({ email, password })
.then(res => {
loggedInUser = res.body.user;
});
});
it('should update profile', done => {
chai
.request(server)
.put('/api/user')
.send(user1)
.set({ authorization: loggedInUser.token })
.end((err, res) => {
const { user } = res.body;
expect(res).to.have.status(200);
expect(user.id).to.be.a('number');
expect(user).to.have.property('verified');
expect(user).to.have.property('createdAt');
expect(user).to.have.property('updatedAt');
done(err);
});
});

it('should return an error if no username', done => {
chai
.request(server)
.put('/api/user')
.send({ bio: 'we are here' })
.set({ authorization: loggedInUser.token })
.end((err, res) => {
expect(res).to.have.status(400);
done(err);
});
});

it('should return an error if no token', done => {
chai
.request(server)
.put('/api/user')
.send(user1)
.end((err, res) => {
expect(res).to.have.status(400);
done(err);
});
});

it('should return a username', done => {
chai
.request(server)
.get('/api/user')
.set({ authorization: loggedInUser.token })
.end((err, res) => {
expect(res).to.have.status(200);
done(err);
});
});

it('should return an error if no username', done => {
chai
.request(server)
.get('/api/user')
.end((err, res) => {
expect(res).to.have.status(400);
done(err);
});
});
});

0 comments on commit a8b9190

Please sign in to comment.