-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #52 from andela/ft-update-article-endpoint-166720110
[166720110] User should be able to update an article
- Loading branch information
Showing
23 changed files
with
581 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,3 +19,6 @@ src/api/migrations | |
|
||
# Seeders | ||
src/api/seeders | ||
|
||
# models | ||
src/api/models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,4 +46,4 @@ package-lock.json | |
.vscode | ||
|
||
# Eslint cache | ||
.eslintcache | ||
.eslintcache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import cloudinary from 'cloudinary'; | ||
import model from '../models'; | ||
import slugHelper from '../../helpers/slug.maker'; | ||
import statuses from '../../helpers/constants/status.codes'; | ||
|
||
const { Article } = model; | ||
|
||
/** | ||
* this is the article controller | ||
* | ||
* @export | ||
* @class ArticleController | ||
*/ | ||
class ArticleController { | ||
/** | ||
* allow an author to update his/her article | ||
* | ||
* @author Frank Mutabazi | ||
* @static | ||
* @param {object} req the request | ||
* @param {object} res the response to be sent | ||
* @memberof ArticleController | ||
* @returns {Object} res | ||
*/ | ||
static async updateArticle(req, res) { | ||
const { slug } = req.params; | ||
const { | ||
title, description, body, tagList, category | ||
} = req.body; | ||
|
||
let { coverImage } = req.Existing; | ||
|
||
const slugCreation = slugHelper(title || req.Existing.title); | ||
|
||
if (req.file) { | ||
const image = await cloudinary.v2.uploader.upload(req.file.path); | ||
coverImage = image.secure_url; | ||
} | ||
const updateContent = { | ||
slug: slugCreation, | ||
title: title || req.Existing.title, | ||
description: description || req.Existing.description, | ||
body: body || req.Existing.body, | ||
tagList: tagList || req.Existing.tagList, | ||
category: category || req.Existing.category, | ||
}; | ||
await Article.update({ | ||
slug: updateContent.slug, | ||
title: updateContent.title, | ||
description: updateContent.description, | ||
body: updateContent.body, | ||
coverImage, | ||
tagList: updateContent.tagList, | ||
category: updateContent.category, | ||
}, | ||
{ | ||
where: { | ||
slug | ||
} | ||
}); | ||
return res.status(statuses.OK).json({ | ||
status: statuses.OK, | ||
message: 'Your Article is up-to-date now, Thanks' | ||
}); | ||
} | ||
} | ||
|
||
export default ArticleController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
export default { | ||
up: (queryInterface, Sequelize) => queryInterface.createTable('Articles', { | ||
id: { | ||
allowNull: false, | ||
unique: true, | ||
primaryKey: true, | ||
type: Sequelize.UUID, | ||
defaultValue: Sequelize.UUIDV4 | ||
}, | ||
title: { | ||
type: Sequelize.STRING, | ||
allowNull: false | ||
}, | ||
slug: { | ||
type: Sequelize.STRING, | ||
allowNull: false, | ||
unique: true | ||
}, | ||
category: { | ||
type: Sequelize.STRING, | ||
allowNull: false, | ||
}, | ||
description: { | ||
type: Sequelize.STRING, | ||
allowNull: false | ||
}, | ||
body: { | ||
type: Sequelize.TEXT, | ||
allowNull: false | ||
}, | ||
coverImage: { | ||
type: Sequelize.TEXT, | ||
allowNull: true | ||
}, | ||
tagList: { | ||
type: Sequelize.ARRAY(Sequelize.TEXT), | ||
allowNull: false | ||
}, | ||
createdAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE | ||
}, | ||
updatedAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE | ||
}, | ||
userId: { | ||
type: Sequelize.INTEGER, | ||
references: { | ||
model: 'Users', | ||
key: 'id' | ||
}, | ||
onDelete: 'CASCADE', | ||
onUpdate: 'CASCADE', | ||
allowNull: false | ||
} | ||
}), | ||
down: (queryInterface, Sequelize) => queryInterface.dropTable('Articles') | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,4 +19,4 @@ export default { | |
} | ||
}), | ||
down: (queryInterface, Sequelize) => queryInterface.dropTable('Tokens') | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const Article = (sequelize, DataTypes) => { | ||
const article = sequelize.define('Articles', | ||
{ | ||
id: { | ||
allowNull: false, | ||
unique: true, | ||
primaryKey: true, | ||
type: DataTypes.UUID, | ||
defaultValue: DataTypes.UUIDV4 | ||
}, | ||
title: { | ||
type: DataTypes.STRING, | ||
allowNull: false | ||
}, | ||
description: { | ||
type: DataTypes.STRING, | ||
allowNull: false | ||
}, | ||
slug: { | ||
type: DataTypes.STRING, | ||
allowNull: false, | ||
unique: true | ||
}, | ||
category: { | ||
type: DataTypes.STRING, | ||
allowNull: false, | ||
}, | ||
body: { | ||
type: DataTypes.TEXT, | ||
allowNull: false | ||
}, | ||
coverImage: { | ||
type: DataTypes.TEXT, | ||
allowNull: true | ||
}, | ||
tagList: { | ||
type: DataTypes.ARRAY(DataTypes.TEXT), | ||
allowNull: false | ||
}, | ||
userId: { | ||
type: DataTypes.INTEGER, | ||
references: { | ||
model: 'Users', | ||
key: 'id' | ||
}, | ||
onDelete: 'CASCADE', | ||
onUpdate: 'CASCADE', | ||
allowNull: false | ||
} | ||
}, | ||
{}); | ||
|
||
Article.associate = (models) => { | ||
Article.belongsTo(models.User, { foreignKey: 'userId' }); | ||
}; | ||
return article; | ||
}; | ||
|
||
export default Article; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Router } from 'express'; | ||
import articleController from '../controllers/articleController'; | ||
import checkArticleOwner from '../../middlewares/checkArticleOwnership'; | ||
import checkValidToken from '../../middlewares/checkValidToken'; | ||
import bodyVerifier from '../../middlewares/validations/body.verifier'; | ||
import checkArticle from '../../middlewares/getOneArticle'; | ||
import uploadImage from '../../middlewares/upload'; | ||
|
||
const articleRouter = new Router(); | ||
|
||
articleRouter.patch('/:slug', | ||
uploadImage.single('coverImage'), | ||
checkValidToken, | ||
bodyVerifier, | ||
checkArticle.getArticle, | ||
checkArticleOwner.checkOwner, | ||
articleController.updateArticle); | ||
|
||
export default articleRouter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import express from 'express'; | ||
import authRouter from './authRouter'; | ||
import resetRouter from './password.reset'; | ||
import articleRouter from './articleRouter'; | ||
|
||
const router = express(); | ||
|
||
router.use('/users', authRouter); | ||
router.use('/password-reset', resetRouter); | ||
router.use('/articles', articleRouter); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
export default { | ||
up: (queryInterface, Sequelize) => queryInterface.bulkInsert('Articles', | ||
[ | ||
{ | ||
id: 'e6db9e0b-ebdf-468a-9e66-db314b7586c0', | ||
title: 'How to create sequalize seeds', | ||
slug: 'How-to-create-sequalize-seeds', | ||
description: 'How to set dummy data automatically', | ||
body: 'Suppose we want to insert some data.', | ||
coverImage: 'default.jpeg', | ||
category: 'Tech', | ||
userId: 1, | ||
tagList: ['postgres', 'express', 'sequelize'], | ||
createdAt: new Date(), | ||
updatedAt: new Date() | ||
}, | ||
{ | ||
id: '263920cd-c7ad-45b0-a5d9-d12f7fe237c3', | ||
title: 'What is a Version 1 UUID', | ||
slug: 'What-is-a-Version-1-UUID', | ||
description: 'Velit non sit culpa pariatur proident', | ||
body:'A Version 1 UUID is a universall', | ||
coverImage: 'default.jpeg', | ||
category: 'Tech', | ||
userId: 1, | ||
tagList: ['UUID', 'express', 'sequelize'], | ||
createdAt: new Date(), | ||
updatedAt: new Date() | ||
}, | ||
], | ||
{}), | ||
|
||
down: (queryInterface, Sequelize) => queryInterface.bulkDelete('Articles', null, {}) | ||
}; |
Oops, something went wrong.