Skip to content

Commit

Permalink
Merge d9fb40e into 67c9ddf
Browse files Browse the repository at this point in the history
  • Loading branch information
tolumide-ng committed Jul 21, 2019
2 parents 67c9ddf + d9fb40e commit b3e5bd9
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 47 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"*.js": [
"npm run lint:fix",
"npm run prettier",
"git add ."
"git add .",
"npm test"
]
},
"author": "Andela Simulations Programme",
Expand Down
37 changes: 26 additions & 11 deletions src/controllers/article.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,36 @@ class ArticleController {
static async getBookMarks(req, res) {
const { id: userId } = req.currentUser;

const allBookMarks = await BaseRepository.findAndInclude(
db.Bookmark,
{ userId },
db.Article,
'article'
);
const { page } = req.query;
const paginate = new Pagination(page, req.query.limit);
const { limit, offset } = paginate.getQueryMetadata();

if (allBookMarks.length < 1) {
return responseGenerator.sendError(
const {
count,
rows: allBookMarks
} = await BaseRepository.findCountAndInclude({
model: db.Bookmark,
options: { userId },
limit,
offset,
alias: 'article',
associatedModel: db.Article,
attributes: ['id', 'title', 'authorId', 'description']
});
if (count > 0) {
return responseGenerator.sendSuccess(
res,
400,
`You currently do not have any article in your bookmark`
200,
null,
allBookMarks,
paginate.getPageMetadata(count, '/api/v1/articles')
);
}
return responseGenerator.sendSuccess(res, 200, null, allBookMarks);
return responseGenerator.sendError(
res,
400,
`You currently do not have any article in your bookmark`
);
}

/**
Expand Down
76 changes: 56 additions & 20 deletions src/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Sequelize from 'sequelize';
import BaseRepository from '../repository/base.repository';
import responseGenerator from '../helpers/responseGenerator';
import utility from '../helpers/utils';
Expand Down Expand Up @@ -278,7 +279,6 @@ class UserController {
*/
static async followUser(req, res) {
try {
// Please inform team to change the id of the decrypted user to id when been parsed with req object
const { followeeId } = req.body;
const { id: followerId } = req.currentUser;
const details = { followeeId, followerId };
Expand Down Expand Up @@ -354,20 +354,38 @@ class UserController {
* @memberof UserController
*/
static async getFollowers(req, res) {
console.log('this is here for now');
const { id: followeeId } = req.currentUser;
// const followers = await BaseRepository.findAll(db.Follower, { followeeId });
const followers = await BaseRepository.findAndInclude(
db.Follower,
{ followeeId },
db.User,
'followed'
);
if (followers.length > 1) {
return responseGenerator.sendSuccess(res, 200, followers);

const { page } = req.query;
const paginate = new Pagination(page, req.query.limit);
const { limit, offset } = paginate.getQueryMetadata();

const {
count,
rows: followings
} = await BaseRepository.findCountAndInclude({
model: db.Follower,
options: { followeeId },
limit,
offset,
alias: 'followee',
associatedModel: db.User,
attributes: ['id', 'username', 'email']
});
if (count > 0) {
return responseGenerator.sendSuccess(
res,
200,
null,
followings,
paginate.getPageMetadata(count, '/api/v1/users')
);
}
return responseGenerator.sendError(
return responseGenerator.sendSuccess(
res,
200,
null,
`You do not have any followers at the moment`
);
}
Expand All @@ -381,18 +399,36 @@ class UserController {
*/
static async getFollowings(req, res) {
const { id: followerId } = req.currentUser;
const followings = await BaseRepository.findAndInclude(
db.Follower,
{ followerId },
db.User,
'followed'
);
if (followings.length > 1) {
return responseGenerator.sendSuccess(res, 200, followings);

const { page } = req.query;
const paginate = new Pagination(page, req.query.limit);
const { limit, offset } = paginate.getQueryMetadata();

const {
count,
rows: followings
} = await BaseRepository.findCountAndInclude({
model: db.Follower,
options: { followerId },
limit,
offset,
alias: 'followee',
associatedModel: db.User,
attributes: ['id', 'username', 'email']
});
if (count > 0) {
return responseGenerator.sendSuccess(
res,
200,
null,
followings,
paginate.getPageMetadata(count, '/api/v1/users')
);
}
return responseGenerator.sendError(
return responseGenerator.sendSuccess(
res,
200,
null,
`You are not following anyone at the moment`
);
}
Expand Down
1 change: 1 addition & 0 deletions src/database/models/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default (sequelize, DataTypes) => {
},
{}
);

Article.associate = models => {
Article.belongsTo(models.User, {
through: 'Articles',
Expand Down
1 change: 1 addition & 0 deletions src/database/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ module.exports = (sequelize, DataTypes) => {
as: 'articleId'
});
};

return User;
};
49 changes: 45 additions & 4 deletions src/repository/base.repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,64 @@ class BaseRepository {
* @returns {object} - returns a database object
* @memberof BaseRepository
*/
static async findAndInclude(
static async findAndInclude({
model,
options,
limit,
offset,
associatedModel,
alias,
associatedOptions
) {
attributes
}) {
return model.findAll({
raw: true,
where: options,
limit,
offset,
include: {
model: associatedModel,
as: alias,
where: associatedOptions
attributes
}
});
}

/**
*
*
* @static
* @param {object} model - database model
* @param {object} options - column options
* @param {object} associatedModel - associated database model
* @param {string} alias - title of the alias
* @param {array} attributes - array of required attributes from associated model
* @param {integer} limit - maximum reponse objects
* @param {integer} offset - page number
* @returns {object} returns a database object
* @memberof BaseRepository
*/
static async findCountAndInclude({
model,
options,
associatedModel,
alias,
attributes,
limit,
offset
}) {
return model.findAndCountAll({
raw: true,
where: { ...options },
include: {
model: associatedModel,
as: alias,
attributes
},
limit,
offset
});
}

/**
* @static
* @param {*} model
Expand Down
14 changes: 14 additions & 0 deletions src/routes/v1/user.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ router.put(
UserController.updateProfile
);

router.get(
'/followers',
authMiddleware,
paginationValidations,
UserController.getFollowers
);

router.get(
'/following',
authMiddleware,
paginationValidations,
UserController.getFollowings
);

router.patch(
'/verify/:token',
validateRequest,
Expand Down
34 changes: 24 additions & 10 deletions src/test/article.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,42 @@ describe('PATCH api/v1/articles/bookmark', () => {
const theArticle = await createArticle(
await generateArticle({ authorId: secondUser.id })
);
const numberOfBookmarks = await BaseRepository.findAll(db.Bookmark, {
userId: firstUser.id
});
expect(numberOfBookmarks.length).to.equal(0);
const numberOfBookmarks = await BaseRepository.findAndCountAll(
db.Bookmark,
{
userId: firstUser.id
}
);
expect(numberOfBookmarks.count).to.equal(0);
await BaseRepository.create(db.Bookmark, {
userId: firstUser.id,
articleId: theArticle.id
});
const newNumberOfBookmarks = await BaseRepository.findAll(db.Bookmark, {
userId: firstUser.id
});
expect(newNumberOfBookmarks.length).to.equal(1);
const newNumberOfBookmarks = await BaseRepository.findAndCountAll(
db.Bookmark,
{
userId: firstUser.id
}
);
expect(newNumberOfBookmarks.count).to.equal(1);

const token = helper.jwtSigner(firstUser);
const page = 1;
const limit = 1;

const res = await server()
.get(`${ARTICLES_API}/bookmark`)
.get(`${ARTICLES_API}/bookmark?page=${page}&limit=${limit}`)
.set('token', token);
expect(res.status).to.equal(200);

expect(res.body.message[0].articleId).to.equal(theArticle.id);
expect(res.body.message[0].secondUser).to.equal(theArticle.userId);
expect(res.body.message[0]['article.title']).to.equal(theArticle.title);
expect(res.body.message[0]['article.authorId']).to.equal(secondUser.id);

expect(res.status).to.equal(200);
expect(res.body.metadata.next).to.equal(null);
expect(res.body.metadata.currentPage).to.equal(page);
expect(res.body.metadata.totalItems).to.equal(newNumberOfBookmarks.count);
});

it('should get no bookmarks for the user', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/test/oauth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('SOCIAL LOGIN', () => {

it('should hit the github URL for social login', async () => {
nock('https://api.github.com/')
.get('/auth/twitter')
.get('/auth/github')
.reply(200, 'hit the route');

const res = await chai.request(app).get('/auth/github');
Expand Down
Loading

0 comments on commit b3e5bd9

Please sign in to comment.