Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions src/controllers/userProfileController.deleteUserProfile.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
jest.mock('../helpers/userHelper', () => () => ({}));
jest.mock('../models/timeentry', () => ({}));
jest.mock('../models/team', () => ({
updateMany: jest.fn(),
}));
jest.mock('../models/badge', () => ({}));
jest.mock('../utilities/nodeCache', () =>
jest.fn(() => ({
removeCache: jest.fn(),
getCache: jest.fn(() => null),
setCache: jest.fn(),
})),
);
jest.mock('../models/followUp', () => ({
findOneAndDelete: jest.fn(),
}));
jest.mock('../models/task', () => ({
updateMany: jest.fn(),
}));
jest.mock('../models/hgnFormResponse', () => ({}));
jest.mock('../services/userService', () => ({}));
jest.mock('../utilities/permissions', () => ({
hasPermission: jest.fn(),
canRequestorUpdateUser: jest.fn(),
}));
jest.mock('../utilities/emailSender', () => jest.fn());
jest.mock('../utilities/objectUtils', () => ({
deepCopyMongooseObjectWithLodash: jest.fn((value) => value),
}));
jest.mock('../startup/logger', () => ({
logInfo: jest.fn(),
logException: jest.fn(),
}));
jest.mock('./reportsController', () => () => ({}));

const mongoose = require('mongoose');
const Team = require('../models/team');
const Task = require('../models/task');
const followUp = require('../models/followUp');
const { hasPermission, canRequestorUpdateUser } = require('../utilities/permissions');
const { mockReq, mockRes } = require('../test');
const userProfileController = require('./userProfileController');

describe('userProfileController deleteUserProfile', () => {
const userId = '65cf6c3706d8ac105827bb2e';
const mockUserProfileModel = {
findById: jest.fn(),
deleteOne: jest.fn(),
};

const makeSut = () => userProfileController(mockUserProfileModel, {});

beforeEach(() => {
jest.clearAllMocks();
hasPermission.mockResolvedValue(true);
canRequestorUpdateUser.mockResolvedValue(true);
mockUserProfileModel.findById.mockResolvedValue({
_id: userId,
email: 'volunteer@example.org',
});
mockUserProfileModel.deleteOne.mockResolvedValue({ deletedCount: 1 });
followUp.findOneAndDelete.mockResolvedValue({});
Task.updateMany.mockResolvedValue({ modifiedCount: 1 });
Team.updateMany.mockResolvedValue({ modifiedCount: 1 });
mockRes.status.mockReturnThis();

mockReq.body = {
...mockReq.body,
userId,
option: 'delete',
role: 'Volunteer',
requestor: {
...mockReq.body.requestor,
requestorId: '507f1f77bcf86cd799439011',
},
};
});

test('removes deleted users from tasks and teams using both string and ObjectId matches', async () => {
const { deleteUserProfile } = makeSut();

await deleteUserProfile(mockReq, mockRes);

const expectedObjectId = new mongoose.Types.ObjectId(userId);
const expectedMatchedUserIds = [userId, expectedObjectId];

expect(mockUserProfileModel.deleteOne).toHaveBeenCalledWith({ _id: userId });
expect(followUp.findOneAndDelete).toHaveBeenCalledWith({ userId });
expect(Task.updateMany).toHaveBeenCalledWith(
{ 'resources.userID': { $in: expectedMatchedUserIds } },
{ $pull: { resources: { userID: { $in: expectedMatchedUserIds } } } },
);
expect(Team.updateMany).toHaveBeenCalledWith(
{ 'members.userId': { $in: expectedMatchedUserIds } },
{ $pull: { members: { userId: { $in: expectedMatchedUserIds } } } },
);
expect(mockRes.status).toHaveBeenCalledWith(200);
expect(mockRes.send).toHaveBeenCalledWith({ message: 'Executed Successfully' });
});
});
15 changes: 15 additions & 0 deletions src/controllers/userProfileController.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const Badge = require('../models/badge');
const yearMonthDayDateValidator = require('../utilities/yearMonthDayDateValidator');
const cacheClosure = require('../utilities/nodeCache');
const followUp = require('../models/followUp');
const Task = require('../models/task');
const HGNFormResponses = require('../models/hgnFormResponse');
const userService = require('../services/userService');
const { hasPermission, canRequestorUpdateUser } = require('../utilities/permissions');
Expand Down Expand Up @@ -1427,6 +1428,20 @@ const createControllerMethods = function (UserProfile, Project, cache) {
await UserProfile.deleteOne({ _id: userId });
// delete followUp for deleted user
await followUp.findOneAndDelete({ userId });
const matchedUserIds = [userId];
if (mongoose.Types.ObjectId.isValid(userId)) {
matchedUserIds.push(new mongoose.Types.ObjectId(userId));
}
// delete user from task-resources
await Task.updateMany(
{ 'resources.userID': { $in: matchedUserIds } },
{ $pull: { resources: { userID: { $in: matchedUserIds } } } },
);
// delete user from teams-members
await Team.updateMany(
{ 'members.userId': { $in: matchedUserIds } },
{ $pull: { members: { userId: { $in: matchedUserIds } } } },
);
res.status(200).send({ message: 'Executed Successfully' });
auditIfProtectedAccountUpdated({
requestorId: req.body.requestor.requestorId,
Expand Down
Loading