Skip to content

Commit

Permalink
create article model manager
Browse files Browse the repository at this point in the history
  • Loading branch information
kabiribraheem committed Jan 23, 2019
1 parent 5f34e63 commit 8d6574d
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 52 deletions.
6 changes: 5 additions & 1 deletion database/migrations/20190121213602-articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,24 @@ module.exports = {
readTime: {
type: Sequelize.INTEGER,
},
numberOfReviews: {
type: Sequelize.INTEGER,
},
slug: {
type: Sequelize.STRING,
allowNull: false
},
authorId: {
type: Sequelize.UUID,
allowNull: false,
onDelete: 'CASCADE',
foreignKey: true,
references: {
model: 'Users',
key: 'id'
}
},
ispublished: {
isPublished: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
Expand Down
15 changes: 11 additions & 4 deletions database/models/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module.exports = (sequelize, DataTypes) => {
primaryKey: true,
defaultValue: DataTypes.UUIDV4
},
authorId: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
title: {
type: DataTypes.STRING,
allowNull: false,
Expand All @@ -23,7 +27,7 @@ module.exports = (sequelize, DataTypes) => {
validate: {
len: {
args: [5, 200],
msg: 'Title must be between 5 and 200 characters'
msg: 'Description must be between 5 and 200 characters'
}
}
},
Expand Down Expand Up @@ -52,6 +56,10 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.INTEGER,
defaultValue: 0
},
numberOfReviews: {
type: DataTypes.INTEGER,
defaultValue: 0
},
isPublished: {
type: DataTypes.BOOLEAN,
defaultValue: false,
Expand All @@ -66,12 +74,11 @@ module.exports = (sequelize, DataTypes) => {
);
Articles.associate = (models) => {
Articles.belongsTo(models.User, {
foreignKey: 'id',
as: 'authorsId'
foreignKey: 'authorId',
as: 'articleAuthor'
});
Articles.hasMany(models.articlesComment, {
foreignKey: 'articleId',
as: 'authorId',
});
};
return Articles;
Expand Down
91 changes: 48 additions & 43 deletions lib/modelManagers/articlemodel.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { article, userprofile } = require('../../database/models');
const { Articles, User, userprofile } = require('../../database/models');

/**
*
*
Expand All @@ -9,29 +10,20 @@ class articleModelManager {
*
*
* @static
* @param {*} title
* @param {*} description
* @param {*} content
* @param {*} featuredImageUrl
* @param {*} Slug
* @param {*} readTime
* @param {*} averageRating
* @param {*} id
* @param {*} req
* @returns {*} createdArticle
* @memberof articleModelManager
*/
static async createArticle(title, description,
content, featuredImageUrl,
Slug, readTime, averageRating, id) {
const createdArticle = await article.create({
Title: title,
Description: description,
Content: content,
featuredImageUrl,
averageRating,
Slug,
readTime,
authorId: id
static async createArticle(req) {
const createdArticle = await Articles.create({
title: req.title,
description: req.description,
content: req.content,
featuredImageUrl: req.featuredImageUrl,
averageRating: req.averageRating,
slug: req.Slug,
readTime: req.readTime,
authorId: req.authorId
});
return createdArticle;
}
Expand All @@ -46,19 +38,21 @@ class articleModelManager {
* @memberof articleModelManager
*/
static async updateArticle(req, id) {
const updatedArticle = await article.update(
const updatedArticle = await Articles.update(
{
Title: req.title || article.Title,
Description: req.Description || article.Description,
Slug: req.Slug || article.Slug,
Content: req.content || article.Content,
readTime: req.readTime || article.readTime,
featuredImageUrl: req.featuredImageUrl || article.featuredImageUrl,
averageRating: req.averageRating || article.averageRating,
title: req.title,
description: req.description,
content: req.content,
featuredImageUrl: req.featuredImageUrl,
averageRating: req.averageRating,
slug: req.Slug,
readTime: req.readTime,
},
{
where: { id }
}
where: { id },
returning: true
},

);
return updatedArticle;
}
Expand All @@ -72,7 +66,7 @@ class articleModelManager {
* @memberof articleModelManager
*/
static async deleteArticle(id) {
const deletedArticle = article.destroy({
const deletedArticle = Articles.destroy({
where: {
id
}
Expand All @@ -86,23 +80,34 @@ class articleModelManager {
* @static
* @param {columnName} columnName to be returned
* @param {value} value
* @param {limit} limit
* @param {offset} offset
* @memberof articleModelManager
* @returns {*} authorsArticle
*/
static async getArticle(columnName, value) {
const authorsArticle = article.findAll(
{
where: { [columnName]: value },
static async getallArticlesby(columnName, value, limit, offset) {
const options = {
where: { [columnName]: value },
include: [{
model: User,
as: 'articleAuthor',
include: [{
model: userprofile,
as: 'author',
attributes: ['username', 'avatar', 'bio']
}]
}
);

return authorsArticle;
attributes: ['avatar']
}],
attributes: ['firstname', 'lastname']
}],
limit,
offset
};
if (columnName) {
const returnedArticles = await Articles.findAll(options);
return returnedArticles;
}
const returnedArticles = await Articles.findAll({ options });
return returnedArticles;
}
}


module.exports = articleModelManager;
8 changes: 7 additions & 1 deletion lib/modelManagers/usermodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,13 @@ class UserModelManager {
* @returns {object} The parameters from the query
*/
static async update(id, newData) {
const updatedRecord = await user.update(newData, { where: { id } });
const updatedRecord = await user.update(
newData,
{
where: { id },
returning: true,
}
);
return updatedRecord;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/utils/pagination/paginationHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const paginate = (query) => {

return { limit, offset };
}
const page = parseInt(query.offset, 10) || OFFSET;
const limit = parseInt(query.limit, 10) || LIMIT;
const page = parseInt(query.offset, 10);
const limit = parseInt(query.limit, 10);
const offset = limit * (page - 1);

return { limit, offset };
Expand Down
24 changes: 24 additions & 0 deletions test/mockData.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,32 @@ const userprofile3 = {
updatedAt: faker.date.recent()
};

const article = authorid => ({
title: 'This is a test title',
description: faker.lorem.sentence(10, 20),
content: faker.lorem.paragraph(30),
featuredImageUrl: 'https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.jpg',
averageRating: faker.random.number(5),
Slug: faker.helpers.slugify('title'),
readTime: faker.random.number(),
authorId: authorid
});

const updatearticle = authorid => ({
title: faker.lorem.sentence(10, 20),
description: faker.lorem.sentence(10, 20),
content: faker.lorem.paragraph(30),
featuredImageUrl: 'https://farm4.staticflickr.com/3894/15008518202_c265dfa55f_h.jpg',
averageRating: faker.random.number(5),
Slug: faker.helpers.slugify('title'),
readTime: faker.random.number(),
authorId: authorid
});

module.exports = {
token,
article,
updatearticle,
defaultquery,
validquery,
NaNquery,
Expand Down
84 changes: 84 additions & 0 deletions test/modelmanagers/articlemodel.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const { expect } = require('chai');
const user = require('../../database/models').User;
const { userprofile } = require('../../database/models');
const article = require('../../lib/modelManagers/articlemodel');
const constants = require('../mockData');


let id;
let res;
let articleid, article2id;
let testArticle, testArticle2;
describe('Unit test article model manager functions', () => {
before(async () => {
res = await user.create(constants.userdata).then(async (newUser) => {
await userprofile.create(constants.userprofile);
return newUser;
});
({ id } = res.dataValues);
testArticle = constants.article(id);
testArticle2 = constants.article(id);
article2id = testArticle2.id;
});

it('should create a new article when all necesary fields are provided', async () => {
const res = await article.createArticle(testArticle);
articleid = res.dataValues.id;
expect(res).to.be.an('object');
expect(res.dataValues.isPublished).to.be.equals(false);
expect(res.dataValues.title).to.be.equals(testArticle.title);
expect(res.dataValues.description).to.be.equals(testArticle.description);
expect(res.dataValues.content).to.be.equals(testArticle.content);
expect(res.dataValues.featuredImageUrl).to.be.equals(testArticle.featuredImageUrl);
expect(res.dataValues.averageRating).to.be.equals(testArticle.averageRating);
expect(res.dataValues.authorId).to.be.equals(testArticle.authorId);
expect(res.dataValues.slug).to.be.equals(testArticle.Slug);
expect(res.dataValues.readTime).to.be.equals(testArticle.readTime);
});

it('should update an article when update fields are provided and article exists', async () => {
const updatedArticle = constants.updatearticle(id);
const res = await article.updateArticle(updatedArticle, articleid);
const updatedDetails = await article.getallArticlesby('id', articleid);
expect(res).to.be.an('array');
expect(res[0]).to.be.equals(1);
expect(updatedDetails[0].dataValues.title).to.be.equals(updatedArticle.title);
expect(updatedDetails[0].dataValues.content).to.be.equals(updatedArticle.content);
expect(updatedDetails[0].dataValues.description).to.be.equals(updatedArticle.description);
expect(updatedDetails[0].dataValues.featuredImageUrl)
.to.be.equals(updatedArticle.featuredImageUrl);
expect(updatedDetails[0].dataValues.averageRating).to.be.equals(updatedArticle.averageRating);
expect(updatedDetails[0].dataValues.authorId).to.be.equals(updatedArticle.authorId);
expect(updatedDetails[0].dataValues.slug).to.be.equals(updatedArticle.Slug);
expect(updatedDetails[0].dataValues.readTime).to.be.equals(updatedArticle.readTime);
});

it('should get all articles filter by a specific field', async () => {
await article.createArticle(testArticle2);
const res = await article.getallArticlesby('authorId', id);
expect(res.length).to.be.equals(2);
expect(res[0].dataValues.authorId).to.be.equals(id);
});

it('should display all articles when no column name is passed', async () => {
const res = await article.getallArticlesby();
expect(res.length).to.be.equals(2);
});

it('should get all articles present in the database with 1 article page pagination', async () => {
const res = await article.getallArticlesby('authorId', id, 1, 0);
expect(res.length).to.be.equals(1);
expect(res[0].dataValues.articleid).to.be.equals(testArticle.articleid);
});

it('should display the second article on the second of pagination', async () => {
const res = await article.getallArticlesby('authorId', id, 1, 1);
expect(res.length).to.be.equals(1);
expect(res[0].dataValues.articleid).to.be.equals(article2id);
});

it('should delete an article when a valid id is provided', async () => {
const res = await article.deleteArticle(articleid);
expect(res).to.be.equals(1);
});
});
2 changes: 1 addition & 1 deletion test/modelmanagers/usermodel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ describe('Unit test usermodel allusers', () => {
});
({ id } = res.dataValues);
});

it('should list all users in the database', async () => {
const res = await User.listAllUsers();
expect(res).to.be.a('array');
expect(res[0]).to.be.a('object');
expect(res.length).to.be.equals(1);
expect(res[0].dataValues).contains.a.property('userprofile');
expect(res[0].dataValues.userprofile.length).is.not.equals('0');
expect(res[0].dataValues.userprofile).contains.a.property('UserId');
Expand Down

0 comments on commit 8d6574d

Please sign in to comment.