Skip to content

Commit

Permalink
- Implement access level change by superadmin
Browse files Browse the repository at this point in the history
- Implement user delete feature
  • Loading branch information
Cavdy authored and codeBlock-1984 committed Jul 26, 2019
1 parent bdcb0a5 commit 5314b8e
Show file tree
Hide file tree
Showing 20 changed files with 633 additions and 28 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"build": "babel src -d lib",
"pretest": "npm run undo:migrate && npm run migrate && npm run seed",
"test": "NODE_ENV=test nyc mocha --timeout 50000 --require @babel/register --exit",
"tes": "NODE_ENV=test nyc mocha --timeout 50000 --require @babel/register ./test/userValidator.test.js --exit",
"generate-lcov": "nyc report --reporter=text-lcov > lcov.info",
"coveralls-coverage": "coveralls < lcov.info",
"coverage": "nyc npm test && npm run generate-lcov && npm run coveralls-coverage",
Expand Down
57 changes: 54 additions & 3 deletions src/controllers/articleController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Article, Tag, User, Category } from '../db/models';
import { Article, Tag, User, Category, highlightComment } from '../db/models';
import slugGen from '../helpers/slugGen';
import urlExtractor from '../helpers/urlExtractor';
import tagExtractor from '../helpers/tagExtractor';
Expand Down Expand Up @@ -155,7 +155,7 @@ class ArticleController {
}

/**
* @description - Get a single article
* @description - Get a single article with readtime
* @static
* @async
* @param {object} req - request
Expand Down Expand Up @@ -186,6 +186,12 @@ class ArticleController {
]
});

const { body } = getArticle.dataValues;

const wordCount = body.split(' ').filter(word => word !== ' ');

const readTime = Math.round(wordCount.length / 200);

const getTags = await Tag.findAll({
where: {
articleId: getArticle.id
Expand All @@ -198,9 +204,12 @@ class ArticleController {
const article = {};
article.article = getArticle;
article.tag = allTags;
article.readTime = readTime;

return res.status(200).json({
status: 200,
message: [article]
message: `This article's read time is ${readTime} mins`,
data: [article]
});
} catch (error) {
return res.status(500).json({
Expand All @@ -209,6 +218,48 @@ class ArticleController {
});
}
}

/**
* @description - Highlight and Comment an article
* @static
* @async
* @param {object} req - request
* @param {object} res - response
* @returns {object} highlighted comment
*/
static async highlightAndComment(req, res) {
try {
const { highlightedWord, comment } = req.body;
const userId = req.user;
const article = res.locals.articleObject;
const articleId = article.id

const isHighlightedWordFound = article.body.includes(highlightedWord)
if (isHighlightedWordFound) {
await highlightComment.create({
highlightedWord,
comment,
userId,
articleId
})

return res.status(201).json({
status: 201,
message: `${highlightedWord} has been highlighted`
});
}

return res.status(400).json({
status: 400,
message: 'invalid highlighted word'
});
} catch (error) {
return res.status(500).json({
status: 500,
message: error.message,
});
}
}
}

export default ArticleController;
64 changes: 62 additions & 2 deletions src/controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { User, Follow } from '../db/models';
import { User, Follow, UserArchive } from '../db/models';
import findItem from '../helpers/findItem';
/**
* @description This class handles user requests
Expand Down Expand Up @@ -187,6 +187,66 @@ class UserController {
});
}
}
}

/**
* @description - method for changing a user's access level
* @static
* @async
* @param {object} req - request object
* @param {object} res - response object
* @returns {object} - response object
* @memberof UserController
*/
static async changeAccessLevel(req, res) {
try {
const { userRole } = req.body;
const { userId } = req.params;

await User.update({ role: userRole }, { where: { id: userId } });

return res.status(200).json({
status: 200,
message: 'User access level successfully changed',
});
} catch (error) {
return res.status(500).json({
status: 500,
message: error.message
});
}
}

/**
* @description - method for deleting a user
* @static
* @async
* @param {object} req - request object
* @param {object} res - response object
* @returns {object} - response object
* @memberof UserController
*/
static async deleteUser(req, res) {
try {
const { userId } = req.params;
const { dataValues: userDetails } = req.userResponse;
const { id: oldId, createdAt: oldCreatedAt, updatedAt: oldUpdatedAt, ...otherDetails } = userDetails;
const archiveDetails = { oldId, oldCreatedAt, oldUpdatedAt, ...otherDetails };

await UserArchive.create(archiveDetails);

await User.destroy({ where: { id: userId } });

return res.status(200).json({
status: 200,
message: 'User successfully deleted',
});
} catch (error) {
return res.status(500).json({
status: 500,
message: error
});
}
}
}

export default UserController;
1 change: 0 additions & 1 deletion src/db/migrations/20190716060554-create-report.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Reports', {
Expand Down
1 change: 0 additions & 1 deletion src/db/migrations/20190716062433-create-user-report.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('UserReports', {
Expand Down
82 changes: 82 additions & 0 deletions src/db/migrations/20190724101932-create-user-archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('UserArchives', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
oldId: {
type: Sequelize.INTEGER,
required: true,
},
firstName: {
type: Sequelize.STRING,
required: false,
},
lastName: {
type: Sequelize.STRING,
required: false,
},
userName: {
type: Sequelize.STRING,
required: true,
unique: true,
},
email: {
type: Sequelize.STRING,
required: true,
unique: true,
},
password: {
type: Sequelize.STRING,
required: true,
},
isVerified: {
type: Sequelize.BOOLEAN,
required: false,
defaultValue: false,
},
role: {
type: Sequelize.ENUM(['superAdmin', 'admin', 'user']),
required: true,
allowNull: false,
defaultValue: 'user',
},
imageUrl: {
type: Sequelize.STRING,
required: false,
},
bio: {
type: Sequelize.STRING,
required: false,
},
verificationToken: {
type: Sequelize.STRING,
required: false,
},
oldCreatedAt: {
type: Sequelize.DATE,
required: true,
},
oldUpdatedAt: {
type: Sequelize.DATE,
required: true,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('UserArchives');
}
};
5 changes: 5 additions & 0 deletions src/db/models/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ module.exports = (sequelize, DataTypes) => {
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
Article.hasMany(models.highlightComment, {
foreignKey: 'articleId',
onDelete: 'CASCADE',
onUpdate: 'CASCADE'
});
Article.hasMany(models.Rating, {
foreignKey: 'articleId',
onDelete: 'CASCADE',
Expand Down
1 change: 0 additions & 1 deletion src/db/models/commentHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@ module.exports = (sequelize, DataTypes) => {
};
return CommentHistory;
};

3 changes: 1 addition & 2 deletions src/db/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.js')[env];
const db = {};

let sequelize;
sequelize = new Sequelize(
let sequelize = new Sequelize(
config.database,
config.username,
config.password,
Expand Down
8 changes: 4 additions & 4 deletions src/db/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'reporterId',
as: 'userReports',
});
User.hasMany(models.highlightComment, {
foreignKey: 'userId',
as: 'highlightComment'
});
User.hasMany(models.Rating, {
foreignKey: 'userId',
as: 'userRatings'
Expand All @@ -89,6 +85,10 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'userId',
as: 'userBookmarks'
});
User.hasMany(models.highlightComment, {
foreignKey: 'userId',
as: 'highlightComment'
});
};
return User;
};
60 changes: 60 additions & 0 deletions src/db/models/userarchive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

module.exports = (sequelize, DataTypes) => {
const UserArchive = sequelize.define('UserArchive', {
oldId: {
type: DataTypes.INTEGER,
required: true,
},
firstName: {
type: DataTypes.STRING,
required: false,
},
lastName: {
type: DataTypes.STRING,
required: false,
},
userName: {
type: DataTypes.STRING,
required: true,
unique: true,
},
email: {
type: DataTypes.STRING,
required: true,
unique: true,
},
password: {
type: DataTypes.STRING,
required: true,
},
isVerified: {
type: DataTypes.BOOLEAN,
},
bio: {
type: DataTypes.STRING,
},
role: {
type: DataTypes.ENUM(['superAdmin', 'admin', 'user']),
},
imageUrl: {
type: DataTypes.STRING,
required: false,
},
verificationToken: {
type: DataTypes.STRING,
required: false,
},
oldCreatedAt: {
type: DataTypes.DATE,
required: true,
},
oldUpdatedAt: {
type: DataTypes.DATE,
required: true,
}
}, {});
UserArchive.associate = function(models) {
// associations can be defined here
};
return UserArchive;
};
1 change: 1 addition & 0 deletions src/helpers/helperData/roles.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const roles = {
allRoles: ['superAdmin', 'admin', 'user'],
superAdmin: ['superAdmin']
};

export default roles;
Loading

0 comments on commit 5314b8e

Please sign in to comment.