Skip to content

Commit

Permalink
Merge pull request #94 from atlp-rwanda/187854543-ft-tests-profileCon…
Browse files Browse the repository at this point in the history
…troller-permissionController

Enable user role update, get all users, and get users by role
  • Loading branch information
niyontwali authored Jul 10, 2024
2 parents 97ba7e6 + bab117e commit 82d8331
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 33 deletions.
15 changes: 8 additions & 7 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const config = {
clearMocks: true,
collectCoverage: true,
coverageDirectory: 'coverage',
preset: 'ts-jest',
testEnvironment: 'node',
clearMocks: true,
collectCoverage: true,
coverageDirectory: 'coverage',
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/src/test/**/*.test.ts'],
};
exports.default = config;
75 changes: 53 additions & 22 deletions src/controllers/userController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { sendEmail } from '../helpers/send-email';
import { sendInternalErrorResponse, validateEmail, validateFields, validatePassword } from '../validations';
import { passwordEncrypt } from '../helpers/encrypt';
import getDefaultRole from '../helpers/defaultRoleGenerator';
import VendorRequest from '../database/models/sellerRequest';
import sequelize from '../database/models/index';
import { Transaction } from 'sequelize';

Expand Down Expand Up @@ -85,36 +84,65 @@ export const signupUser = async (req: Request, res: Response) => {
return;
}
};

// Function for get all users
export const getAllUser = async (req: Request, res: Response) => {
try {
const page = parseInt(req.params.page, 10);
const offset = Number.isNaN(page) ? 0 : page * 10;
const users = await User.findAll({
attributes: ['id', 'firstName', 'lastName', 'email', 'phoneNumber', 'photoUrl', 'gender'],
include: {
model: Role,
attributes: ['name'],
},
});
logger.info(`Fetched ${users.length} users`);
return res.status(200).json({ ok: true, message: users });
} catch (error) {
logger.error(`Error fetching all users: ${error}`);
sendInternalErrorResponse(res, error);
return;
}
};

// Function to get users by role name
export const getUsersByRoleName = async (req: Request, res: Response) => {
try {
const { roleName } = req.params;

const role = await Role.findOne({ where: { name: roleName } });

if (!role) {
return res.status(404).json({ ok: false, error: 'Role not found' });
}

const users = await User.findAll({
where: { RoleId: role.id },
attributes: ['id', 'firstName', 'lastName', 'email', 'phoneNumber', 'photoUrl', 'gender'],
limit: 10,
offset: offset,
include: {
model: Role,
attributes: ['name'],
},
});

if (users.length === 0) {
return res.status(404).json({ ok: false, error: 'No users found for this role' });
}

logger.info(`Fetched ${users.length} users with role ${roleName}`);
return res.status(200).json({ ok: true, message: users });
} catch (error) {
logger.error(`Error for fetch all user: ${error}`);
logger.error(`Error fetching users by role: ${error}`);
sendInternalErrorResponse(res, error);
return;
}
};
// Function to getOne user

// Function to get one user
export const getOneUser = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const user: User | null = await User.findOne({
where: {
id,
},
where: { id },
attributes: ['id', 'firstName', 'lastName', 'email', 'phoneNumber', 'photoUrl', 'gender'],
include: {
model: Role,
Expand All @@ -130,13 +158,12 @@ export const getOneUser = async (req: Request, res: Response) => {
return;
}
};
// Function for delete a user

// Function to delete a user
export const deleteUser = async (req: Request, res: Response) => {
try {
const deleteUserAccount = await User.destroy({
where: {
id: req.params.id,
},
where: { id: req.params.id },
});
if (deleteUserAccount === 0) {
return res.status(404).json({ ok: false, message: 'User with this ID does not exist' });
Expand All @@ -148,6 +175,7 @@ export const deleteUser = async (req: Request, res: Response) => {
return;
}
};

// Function to edit user role
export const editUserRole = async (req: Request, res: Response) => {
const transaction: Transaction = await sequelize.transaction();
Expand All @@ -165,16 +193,15 @@ export const editUserRole = async (req: Request, res: Response) => {
res.status(404).json({ ok: false, error: 'User not found' });
return;
}
const requestedUser = await VendorRequest.findOne({ where: { vendorId: userId }, transaction });
if (!requestedUser) {
logger.error('Error User request Not Found');
res.status(404).json({ ok: false, error: 'User request not found' });

const role = await Role.findByPk(roleId);
if (!role) {
res.status(404).json({ ok: false, message: `There is no Role with this id: ${roleId}` });
return;
}
const role = await Role.findByPk(roleId);
if (!role) return res.status(404).json({ ok: false, message: `There is no Role with this id: ${roleId}` });
await user.update({ RoleId: roleId });
await requestedUser.update({ status: 'approved' });

await user.update({ RoleId: roleId }, { transaction });
await transaction.commit();

res.status(200).json({ ok: true, message: 'Role assigned successfully.' });
} catch (error) {
Expand All @@ -183,6 +210,7 @@ export const editUserRole = async (req: Request, res: Response) => {
sendInternalErrorResponse(res, error);
}
};

// Function to update user profile
export const editUser = async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -220,6 +248,7 @@ export const editUser = async (req: Request, res: Response) => {
sendInternalErrorResponse(res, error);
}
};

// Function for verifying a user
export const userVerify = async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -249,6 +278,7 @@ export const userVerify = async (req: Request, res: Response) => {
}
}
};

// Function for resend verification link
export const resendVerifyLink = async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -284,6 +314,7 @@ export const resendVerifyLink = async (req: Request, res: Response) => {
sendInternalErrorResponse(res, error);
}
};

// Function to enable two factor authentication(2FA)
export const enable2FA = async (req: Request, res: Response) => {
try {
Expand Down
21 changes: 18 additions & 3 deletions src/docs/users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,36 @@ paths:
description: Internal Server Error
400:
description: Email is already used, Login to continuue
/api/users/{page}:
/api/users:
get:
summary: Get all users
security:
- bearerAuth: []
tags:
- User
responses:
200:
description: Successfull get all users
500:
description: Internal Server Error
/api/users/role/{roleName}:
get:
summary: Get users by role name
security:
- bearerAuth: []
tags:
- User
- Role
parameters:
- in: path
name: page
required: false
name: roleName
required: true
type: string
responses:
200:
description: Successfull get all users
401:
description: Authentication required - Unauthorized
500:
description: Internal Server Error
/api/users/edit/{id}:
Expand Down
4 changes: 3 additions & 1 deletion src/routes/userRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
editUserRole,
enable2FA,
getAllUser,
getUsersByRoleName,
getOneUser,
resendVerifyLink,
signupUser,
Expand All @@ -18,11 +19,12 @@ import { checkUserRoles, isAuthenticated } from '../middlewares/authMiddlewares'
const router = Router();

router.post('/signup', signupUser);
router.get('/:page?', isAuthenticated, checkUserRoles('admin'), getAllUser);
router.get('/', isAuthenticated, checkUserRoles('admin'), getAllUser);
router.get('/user/:id', isAuthenticated, getOneUser);
router.delete('/:id', isAuthenticated, checkUserRoles('admin'), deleteUser);
router.patch('/edit/:id', isAuthenticated, multerUpload.single('profileImage'), editUser);
router.put('/role/:userId', isAuthenticated, checkUserRoles('admin'), editUserRole);
router.get('/role/:roleName', isAuthenticated, checkUserRoles('admin'), getUsersByRoleName);
router.get('/:token/verify-email', userVerify);
router.post('/resend-verify', resendVerifyLink);
router.put('/deactivate/:userId', isAuthenticated, deactivateUserAccount);
Expand Down

0 comments on commit 82d8331

Please sign in to comment.