consolidate some testing functions

This commit is contained in:
2025-12-23 23:50:03 -08:00
parent f173f805ea
commit 03b5af39e1
24 changed files with 723 additions and 126 deletions

View File

@@ -32,7 +32,7 @@ describe('Notification DB Service', () => {
});
describe('getNotificationsForUser', () => {
it('should execute the correct query with limit and offset and return notifications', async () => {
it('should only return unread notifications by default', async () => {
const mockNotifications: Notification[] = [
createMockNotification({
notification_id: 1,
@@ -43,30 +43,59 @@ describe('Notification DB Service', () => {
];
mockPoolInstance.query.mockResolvedValue({ rows: mockNotifications });
const result = await notificationRepo.getNotificationsForUser('user-123', 10, 5, mockLogger);
const result = await notificationRepo.getNotificationsForUser(
'user-123',
10,
5,
false,
mockLogger,
);
expect(mockPoolInstance.query).toHaveBeenCalledWith(
expect.stringContaining('SELECT * FROM public.notifications'),
expect.stringContaining('is_read = false'),
['user-123', 10, 5],
);
expect(result).toEqual(mockNotifications);
});
it('should return all notifications when includeRead is true', async () => {
const mockNotifications: Notification[] = [
createMockNotification({ is_read: true }),
createMockNotification({ is_read: false }),
];
mockPoolInstance.query.mockResolvedValue({ rows: mockNotifications });
await notificationRepo.getNotificationsForUser('user-123', 10, 0, true, mockLogger);
// The query should NOT contain the is_read filter
expect(mockPoolInstance.query.mock.calls[0][0]).not.toContain('is_read = false');
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.any(String), ['user-123', 10, 0]);
});
it('should return an empty array if the user has no notifications', async () => {
mockPoolInstance.query.mockResolvedValue({ rows: [] });
const result = await notificationRepo.getNotificationsForUser('user-456', 10, 0, mockLogger);
const result = await notificationRepo.getNotificationsForUser(
'user-456',
10,
0,
false,
mockLogger,
);
expect(result).toEqual([]);
expect(mockPoolInstance.query).toHaveBeenCalledWith(expect.any(String), ['user-456', 10, 0]);
expect(mockPoolInstance.query).toHaveBeenCalledWith(
expect.stringContaining('is_read = false'),
['user-456', 10, 0],
);
});
it('should throw an error if the database query fails', async () => {
const dbError = new Error('DB Error');
mockPoolInstance.query.mockRejectedValue(dbError);
await expect(
notificationRepo.getNotificationsForUser('user-123', 10, 5, mockLogger),
notificationRepo.getNotificationsForUser('user-123', 10, 5, false, mockLogger),
).rejects.toThrow('Failed to retrieve notifications.');
expect(mockLogger.error).toHaveBeenCalledWith(
{ err: dbError, userId: 'user-123', limit: 10, offset: 5 },
{ err: dbError, userId: 'user-123', limit: 10, offset: 5, includeRead: false },
'Database error in getNotificationsForUser',
);
});

View File

@@ -95,20 +95,24 @@ export class NotificationRepository {
userId: string,
limit: number,
offset: number,
includeRead: boolean,
logger: Logger,
): Promise<Notification[]> {
try {
const res = await this.db.query<Notification>(
`SELECT * FROM public.notifications
WHERE user_id = $1
ORDER BY created_at DESC
LIMIT $2 OFFSET $3`,
[userId, limit, offset],
);
const params: (string | number)[] = [userId, limit, offset];
let query = `SELECT * FROM public.notifications WHERE user_id = $1`;
if (!includeRead) {
query += ` AND is_read = false`;
}
query += ` ORDER BY created_at DESC LIMIT $2 OFFSET $3`;
const res = await this.db.query<Notification>(query, params);
return res.rows;
} catch (error) {
logger.error(
{ err: error, userId, limit, offset },
{ err: error, userId, limit, offset, includeRead },
'Database error in getNotificationsForUser',
);
throw new Error('Failed to retrieve notifications.');