Skip to content

Commit

Permalink
#2823 merge with #3074-GetUnreadAnnouncements to have announcement se…
Browse files Browse the repository at this point in the history
…rvice funcs
  • Loading branch information
chpy04 committed Dec 20, 2024
2 parents e80337e + 66f5837 commit acbb022
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 40 deletions.
21 changes: 11 additions & 10 deletions src/backend/src/controllers/users.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,9 @@ export default class UsersController {

static async getUserUnreadNotifications(req: Request, res: Response, next: NextFunction) {
try {
const { userId } = req.params;
const { organization } = req;
const { organization, currentUser } = req;

const unreadNotifications = await UsersService.getUserUnreadNotifications(userId, organization);
const unreadNotifications = await UsersService.getUserUnreadNotifications(currentUser.userId, organization);
res.status(200).json(unreadNotifications);
} catch (error: unknown) {
next(error);
Expand All @@ -206,11 +205,14 @@ export default class UsersController {

static async removeUserNotification(req: Request, res: Response, next: NextFunction) {
try {
const { userId } = req.params;
const { notificationId } = req.body;
const { organization } = req;
const { notificationId } = req.params;
const { organization, currentUser } = req;

const unreadNotifications = await UsersService.removeUserNotification(userId, notificationId, organization);
const unreadNotifications = await UsersService.removeUserNotification(
currentUser.userId,
notificationId,
organization
);
res.status(200).json(unreadNotifications);
} catch (error: unknown) {
next(error);
Expand All @@ -219,10 +221,9 @@ export default class UsersController {

static async getUserUnreadAnnouncements(req: Request, res: Response, next: NextFunction) {
try {
const { userId } = req.params;
const { organization } = req;
const { organization, currentUser } = req;

const unreadAnnouncements = await UsersService.getUserUnreadAnnouncements(userId, organization);
const unreadAnnouncements = await UsersService.getUserUnreadAnnouncements(currentUser.userId, organization);
res.status(200).json(unreadAnnouncements);
} catch (error: unknown) {
next(error);
Expand Down
12 changes: 11 additions & 1 deletion src/backend/src/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { writeFileSync } from 'fs';
import WorkPackageTemplatesService from '../services/work-package-template.services';
import RecruitmentServices from '../services/recruitment.services';
import OrganizationsService from '../services/organizations.services';
import NotificationsService from '../services/notifications.services';
import AnnouncementService from '../services/announcement.service';

const prisma = new PrismaClient();

Expand Down Expand Up @@ -1894,6 +1894,16 @@ const performSeed: () => Promise<void> = async () => {
await RecruitmentServices.createFaq(batman, 'When was FinishLine created?', 'FinishLine was created in 2019', ner);

await RecruitmentServices.createFaq(batman, 'How many developers are working on FinishLine?', '178 as of 2024', ner);

await AnnouncementService.createAnnouncement(
'Welcome to Finishline!',
[regina.userId],
new Date(),
'Thomas Emrax',
'1',
'software',
ner.organizationId
);
};

performSeed()
Expand Down
10 changes: 3 additions & 7 deletions src/backend/src/routes/users.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,8 @@ userRouter.post(
validateInputs,
UsersController.getManyUserTasks
);
userRouter.get('/:userId/notifications', UsersController.getUserUnreadNotifications);
userRouter.get('/:userId/announcements', UsersController.getUserUnreadAnnouncements);
userRouter.post(
'/:userId/notifications/remove',
nonEmptyString(body('notificationId')),
UsersController.removeUserNotification
);
userRouter.get('/notifications/current-user', UsersController.getUserUnreadNotifications);
userRouter.get('/announcements/current-user', UsersController.getUserUnreadAnnouncements);
userRouter.post('/notifications/:notificationId/remove', UsersController.removeUserNotification);

export default userRouter;
12 changes: 12 additions & 0 deletions src/backend/src/services/announcement.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ import announcementTransformer from '../transformers/announcements.transformer';
import { NotFoundException } from '../utils/errors.utils';

export default class AnnouncementService {
/**
* Creates an announcement that is sent to users
* this data is populated from slack events
* @param text slack message text
* @param usersReceivedIds users to send announcements to
* @param dateCreated date created of slack message
* @param senderName name of user who sent slack message
* @param slackEventId id of slack event (provided by slack api)
* @param slackChannelName name of channel message was sent in
* @param organizationId id of organization of users
* @returns the created announcement
*/
static async createAnnouncement(
text: string,
usersReceivedIds: string[],
Expand Down
15 changes: 10 additions & 5 deletions src/backend/src/services/users.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,13 +578,18 @@ export default class UsersService {
* @returns the unread notifications of the user
*/
static async getUserUnreadNotifications(userId: string, organization: Organization) {
const requestedUser = await prisma.user.findUnique({
where: { userId },
include: { unreadNotifications: getNotificationQueryArgs(organization.organizationId) }
const unreadNotifications = await prisma.notification.findMany({
where: {
users: {
some: { userId }
}
},
...getNotificationQueryArgs(organization.organizationId)
});
if (!requestedUser) throw new NotFoundException('User', userId);

return requestedUser.unreadNotifications.map(notificationTransformer);
if (!unreadNotifications) throw new HttpException(404, 'User Unread Notifications Not Found');

return unreadNotifications.map(notificationTransformer);
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/backend/tests/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const resetUsers = async () => {
await prisma.organization.deleteMany();
await prisma.announcement.deleteMany();
await prisma.user.deleteMany();
await prisma.announcement.deleteMany();
};

export const createFinanceTeamAndLead = async (organization?: Organization) => {
Expand Down
49 changes: 32 additions & 17 deletions src/backend/tests/unmocked/users.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { batmanAppAdmin } from '../test-data/users.test-data';
import UsersService from '../../src/services/users.services';
import { NotFoundException } from '../../src/utils/errors.utils';
import NotificationsService from '../../src/services/notifications.services';
import AnnouncementService from '../../src/services/announcement.service';

describe('User Tests', () => {
let orgId: string;
Expand Down Expand Up @@ -51,12 +52,6 @@ describe('User Tests', () => {
});

describe('Get Notifications', () => {
it('fails on invalid user id', async () => {
await expect(async () => await UsersService.getUserUnreadNotifications('1', organization)).rejects.toThrow(
new NotFoundException('User', '1')
);
});

it('Succeeds and gets user notifications', async () => {
const testBatman = await createTestUser(batmanAppAdmin, orgId);
await NotificationsService.sendNotifcationToUsers('test1', 'test1', [testBatman.userId], orgId);
Expand All @@ -71,17 +66,7 @@ describe('User Tests', () => {
});

describe('Remove Notifications', () => {
it('Fails with invalid user', async () => {
const testBatman = await createTestUser(batmanAppAdmin, orgId);
await NotificationsService.sendNotifcationToUsers('test1', 'test1', [testBatman.userId], orgId);
const notifications = await UsersService.getUserUnreadNotifications(testBatman.userId, organization);

await expect(
async () => await UsersService.removeUserNotification('1', notifications[0].notificationId, organization)
).rejects.toThrow(new NotFoundException('User', '1'));
});

it('Succeeds and gets user notifications', async () => {
it('Succeeds and removes user notification', async () => {
const testBatman = await createTestUser(batmanAppAdmin, orgId);
await NotificationsService.sendNotifcationToUsers('test1', 'test1', [testBatman.userId], orgId);
await NotificationsService.sendNotifcationToUsers('test2', 'test2', [testBatman.userId], orgId);
Expand All @@ -102,4 +87,34 @@ describe('User Tests', () => {
expect(updatedNotifications[0].text).toBe('test2');
});
});

describe('Get Announcements', () => {
it('Succeeds and gets user announcements', async () => {
const testBatman = await createTestUser(batmanAppAdmin, orgId);
await AnnouncementService.createAnnouncement(
'test1',
[testBatman.userId],
new Date(),
'Thomas Emrax',
'1',
'software',
organization.organizationId
);
await AnnouncementService.createAnnouncement(
'test2',
[testBatman.userId],
new Date(),
'Superman',
'50',
'mechanical',
organization.organizationId
);

const announcements = await UsersService.getUserUnreadAnnouncements(testBatman.userId, organization);

expect(announcements).toHaveLength(2);
expect(announcements[0].text).toBe('test1');
expect(announcements[1].text).toBe('test2');
});
});
});

0 comments on commit acbb022

Please sign in to comment.