Skip to content

Commit

Permalink
166816223-feature(report, article): user can report article
Browse files Browse the repository at this point in the history
  - add report migration
  - add flagged column in article table
  - add Report Model
  - add report route
  - add report Controller
  - add tests
[Delivers #166816223]
  • Loading branch information
Obi chinedu Frank committed Jul 18, 2019
1 parent 8d026bd commit 35f1901
Show file tree
Hide file tree
Showing 13 changed files with 501 additions and 0 deletions.
81 changes: 81 additions & 0 deletions controllers/articles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,5 +428,86 @@ export default {
error: 'Something went wrong',
});
}
},

flagArticle: async (req, res) => {
const { params: { slug }, body: { flag } } = req;

const article = await db.Article.findOne({
where: { slug }
});
if (!article) {
return res.status(404).send({
message: 'Article does not exist'
});
}
const result = await article.update({
flagged: JSON.parse(flag)
});

return res.status(200).send({
article: result
});
},

showArticleReports: async (req, res) => {
const { params: { slug } } = req;

const article = await db.Article.findOne({
where: { slug },
include: [{
model: db.Report,
as: 'reports',
include: [{
model: db.User,
as: 'reporter',
attributes: ['id', 'firstName', 'lastName', 'email', 'image', 'username']
}]
}]
});

if (!article) {
return res.status(404).send({
message: 'Article does not exist'
});
}
return res.status(200).send({
article,
});
},

deleteReportedArticle: async (req, res) => {
const { params: { slug } } = req;

const article = await db.Article.findOne({
where: {
slug
}
});
if (!article) {
return res.status(404).send({
message: 'Article does not exist'
});
}
const wasReported = await db.Report.findAll({
where: {
articleId: article.id
}
});
if (!wasReported.length) {
return res.status(404).send({
message: 'sorry you can\'t delete an article that was not reported'
});
}

// await deleteImage(article.slug);
await db.Article.destroy({
where: {
id: article.id,
}
});
return res.status(200).send({
message: 'deleted successfully',
});
}
};
42 changes: 42 additions & 0 deletions controllers/reports/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import db from '../../db/models';

export default {
reportArticle: async (req, res) => {
const {
user, body: {
articleId, message
}
} = req;

await db.Report.create({
articleId,
userId: user.id,
message,
});

return res.status(200).send({
message: 'thank you for the report'
});
},

getReportedArticles: async (req, res) => {
const articles = await db.Report.findAll({
include: [
{
model: db.Article,
as: 'articles'
},
{
model: db.User,
as: 'reporter',
attributes: ['firstName', 'lastName', 'email', 'image', 'id', 'username']
},
],

});

return res.status(200).send({
articles
});
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface
.addColumn('Articles', 'flagged', {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false
}),
down: queryInterface => queryInterface.removeColumn('Articles', 'flagged'),
};
43 changes: 43 additions & 0 deletions db/migrations/20190716140622-create-reports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Reports', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
message: {
type: Sequelize.TEXT
},
userId: {
allowNull: false,
type: Sequelize.INTEGER,
required: true,
onDelete: 'CASCADE',
references: {
model: 'Users',
key: 'id',
as: 'user',
}
},
articleId: {
allowNull: false,
type: Sequelize.INTEGER,
onDelete: 'CASCADE',
references: {
model: 'Articles',
key: 'id',
as: 'article',
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('Reports'),
};
6 changes: 6 additions & 0 deletions db/models/Article.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = (sequelize, DataTypes) => {
image: DataTypes.STRING,
rating: DataTypes.FLOAT,
readTime: DataTypes.STRING,
flagged: DataTypes.BOOLEAN,
},
{}
);
Expand Down Expand Up @@ -44,6 +45,11 @@ module.exports = (sequelize, DataTypes) => {
as: 'bookmarks',
cascade: true,
});
Article.hasMany(models.Report, {
foreignKey: 'articleId',
as: 'reports',
cascade: true
});
};

return Article;
Expand Down
19 changes: 19 additions & 0 deletions db/models/Reports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = (sequelize, DataTypes) => {
const Report = sequelize.define('Report', {
message: DataTypes.TEXT,
userId: DataTypes.INTEGER,
articleId: DataTypes.INTEGER
}, {});
Report.associate = (models) => {
Report.belongsTo(models.Article, {
foreignKey: 'articleId',
as: 'articles'
});

Report.belongsTo(models.User, {
foreignKey: 'userId',
as: 'reporter'
});
};
return Report;
};
5 changes: 5 additions & 0 deletions db/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ module.exports = (sequelize, DataTypes) => {
as: 'bookmarks',
cascade: true,
});
User.hasMany(models.Report, {
foreignKey: 'userId',
as: 'reports',
cascade: true,
});
};

User.prototype.passwordsMatch = function match(password) {
Expand Down
24 changes: 24 additions & 0 deletions routes/v1/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,28 @@ router.get(
Validation.articleSlug,
Article.bookmarkArticle,
);

router.patch(
'/flag/:slug',
Middleware.authenticate,
Middleware.isblackListedToken,
Middleware.isAdmin,
Article.flagArticle
);

router.delete(
'/reported/:slug',
Middleware.authenticate,
Middleware.isblackListedToken,
Middleware.isAdmin,
Article.deleteReportedArticle
);

router.get(
'/reported/:slug',
Middleware.authenticate,
Middleware.isblackListedToken,
Middleware.isAdmin,
Article.showArticleReports
);
export default router;
2 changes: 2 additions & 0 deletions routes/v1/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import profiles from './profiles';
import notification from './notifications';
import members from './members';
import role from './role';
import report from './reports';

const router = express.Router();

Expand All @@ -17,5 +18,6 @@ router.use('/articles', article);
router.use('/notifications', notification);
router.use('/members', members);
router.use('/role', role);
router.use('/report', report);

export default router;
25 changes: 25 additions & 0 deletions routes/v1/reports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import express from 'express';
import Middleware from '../../middlewares';
import Report from '../../controllers/reports';
import Validation from '../../validators/articles';


const router = express.Router();

router.post(
'/',
Middleware.authenticate,
Middleware.isblackListedToken,
Validation.reportArticle,
Report.reportArticle
);

router.get(
'/articles',
Middleware.authenticate,
Middleware.isblackListedToken,
Middleware.isAdmin,
Report.getReportedArticles
);

export default router;
1 change: 1 addition & 0 deletions tests/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ export const createTestFakeUsers = () => {
await createUser(user);
});
};
export const createReport = async report => db.Report.create(report);
Loading

0 comments on commit 35f1901

Please sign in to comment.