integration test fixes
This commit is contained in:
@@ -190,13 +190,14 @@ describe('Shopping DB Service', () => {
|
||||
|
||||
const result = await shoppingRepo.addShoppingListItem(
|
||||
1,
|
||||
'user-1',
|
||||
{ customItemName: 'Custom Item' },
|
||||
mockLogger,
|
||||
);
|
||||
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('INSERT INTO public.shopping_list_items'),
|
||||
[1, null, 'Custom Item'],
|
||||
[1, null, 'Custom Item', 'user-1'],
|
||||
);
|
||||
expect(result).toEqual(mockItem);
|
||||
});
|
||||
@@ -205,11 +206,11 @@ describe('Shopping DB Service', () => {
|
||||
const mockItem = createMockShoppingListItem({ master_item_id: 123 });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [mockItem] });
|
||||
|
||||
const result = await shoppingRepo.addShoppingListItem(1, { masterItemId: 123 }, mockLogger);
|
||||
const result = await shoppingRepo.addShoppingListItem(1, 'user-1', { masterItemId: 123 }, mockLogger);
|
||||
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('INSERT INTO public.shopping_list_items'),
|
||||
[1, 123, null],
|
||||
[1, 123, null, 'user-1'],
|
||||
);
|
||||
expect(result).toEqual(mockItem);
|
||||
});
|
||||
@@ -223,19 +224,20 @@ describe('Shopping DB Service', () => {
|
||||
|
||||
const result = await shoppingRepo.addShoppingListItem(
|
||||
1,
|
||||
'user-1',
|
||||
{ masterItemId: 123, customItemName: 'Organic Apples' },
|
||||
mockLogger,
|
||||
);
|
||||
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('INSERT INTO public.shopping_list_items'),
|
||||
[1, 123, 'Organic Apples'],
|
||||
[1, 123, 'Organic Apples', 'user-1'],
|
||||
);
|
||||
expect(result).toEqual(mockItem);
|
||||
});
|
||||
|
||||
it('should throw an error if both masterItemId and customItemName are missing', async () => {
|
||||
await expect(shoppingRepo.addShoppingListItem(1, {}, mockLogger)).rejects.toThrow(
|
||||
await expect(shoppingRepo.addShoppingListItem(1, 'user-1', {}, mockLogger)).rejects.toThrow(
|
||||
'Either masterItemId or customItemName must be provided.',
|
||||
);
|
||||
});
|
||||
@@ -244,19 +246,19 @@ describe('Shopping DB Service', () => {
|
||||
const dbError = new Error('violates foreign key constraint');
|
||||
(dbError as Error & { code: string }).code = '23503';
|
||||
mockPoolInstance.query.mockRejectedValue(dbError);
|
||||
await expect(
|
||||
shoppingRepo.addShoppingListItem(999, { masterItemId: 999 }, mockLogger),
|
||||
).rejects.toThrow('Referenced list or item does not exist.');
|
||||
await expect(shoppingRepo.addShoppingListItem(999, 'user-1', { masterItemId: 999 }, mockLogger)).rejects.toThrow(
|
||||
'Referenced list or item does not exist.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw a generic error if the database query fails', async () => {
|
||||
const dbError = new Error('DB Connection Error');
|
||||
mockPoolInstance.query.mockRejectedValue(dbError);
|
||||
await expect(
|
||||
shoppingRepo.addShoppingListItem(1, { customItemName: 'Test' }, mockLogger),
|
||||
shoppingRepo.addShoppingListItem(1, 'user-1', { customItemName: 'Test' }, mockLogger),
|
||||
).rejects.toThrow('Failed to add item to shopping list.');
|
||||
expect(mockLogger.error).toHaveBeenCalledWith(
|
||||
{ err: dbError, listId: 1, item: { customItemName: 'Test' } },
|
||||
{ err: dbError, listId: 1, userId: 'user-1', item: { customItemName: 'Test' } },
|
||||
'Database error in addShoppingListItem',
|
||||
);
|
||||
});
|
||||
@@ -269,13 +271,14 @@ describe('Shopping DB Service', () => {
|
||||
|
||||
const result = await shoppingRepo.updateShoppingListItem(
|
||||
1,
|
||||
'user-1',
|
||||
{ is_purchased: true },
|
||||
mockLogger,
|
||||
);
|
||||
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
'UPDATE public.shopping_list_items SET is_purchased = $1 WHERE shopping_list_item_id = $2 RETURNING *',
|
||||
[true, 1],
|
||||
expect.stringContaining('UPDATE public.shopping_list_items sli'),
|
||||
[true, 1, 'user-1'],
|
||||
);
|
||||
expect(result).toEqual(mockItem);
|
||||
});
|
||||
@@ -285,11 +288,11 @@ describe('Shopping DB Service', () => {
|
||||
const mockItem = createMockShoppingListItem({ shopping_list_item_id: 1, ...updates });
|
||||
mockPoolInstance.query.mockResolvedValue({ rows: [mockItem], rowCount: 1 });
|
||||
|
||||
const result = await shoppingRepo.updateShoppingListItem(1, updates, mockLogger);
|
||||
const result = await shoppingRepo.updateShoppingListItem(1, 'user-1', updates, mockLogger);
|
||||
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
'UPDATE public.shopping_list_items SET quantity = $1, is_purchased = $2, notes = $3 WHERE shopping_list_item_id = $4 RETURNING *',
|
||||
[updates.quantity, updates.is_purchased, updates.notes, 1],
|
||||
expect.stringContaining('UPDATE public.shopping_list_items sli'),
|
||||
[updates.quantity, updates.is_purchased, updates.notes, 1, 'user-1'],
|
||||
);
|
||||
expect(result).toEqual(mockItem);
|
||||
});
|
||||
@@ -297,13 +300,13 @@ describe('Shopping DB Service', () => {
|
||||
it('should throw an error if the item to update is not found', async () => {
|
||||
mockPoolInstance.query.mockResolvedValue({ rowCount: 0, rows: [], command: 'UPDATE' });
|
||||
await expect(
|
||||
shoppingRepo.updateShoppingListItem(999, { quantity: 5 }, mockLogger),
|
||||
shoppingRepo.updateShoppingListItem(999, 'user-1', { quantity: 5 }, mockLogger),
|
||||
).rejects.toThrow('Shopping list item not found.');
|
||||
});
|
||||
|
||||
it('should throw an error if no valid fields are provided to update', async () => {
|
||||
// The function should throw before even querying the database.
|
||||
await expect(shoppingRepo.updateShoppingListItem(1, {}, mockLogger)).rejects.toThrow(
|
||||
await expect(shoppingRepo.updateShoppingListItem(1, 'user-1', {}, mockLogger)).rejects.toThrow(
|
||||
'No valid fields to update.',
|
||||
);
|
||||
});
|
||||
@@ -312,28 +315,39 @@ describe('Shopping DB Service', () => {
|
||||
const dbError = new Error('DB Connection Error');
|
||||
mockPoolInstance.query.mockRejectedValue(dbError);
|
||||
await expect(
|
||||
shoppingRepo.updateShoppingListItem(1, { is_purchased: true }, mockLogger),
|
||||
shoppingRepo.updateShoppingListItem(1, 'user-1', { is_purchased: true }, mockLogger),
|
||||
).rejects.toThrow('Failed to update shopping list item.');
|
||||
expect(mockLogger.error).toHaveBeenCalledWith(
|
||||
{ err: dbError, itemId: 1, updates: { is_purchased: true } },
|
||||
{ err: dbError, itemId: 1, userId: 'user-1', updates: { is_purchased: true } },
|
||||
'Database error in updateShoppingListItem',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateShoppingListItem - Ownership Check', () => {
|
||||
it('should not update an item if the user does not own the shopping list', async () => {
|
||||
mockDb.query.mockResolvedValue({ rowCount: 0 });
|
||||
|
||||
await expect(
|
||||
shoppingRepo.updateShoppingListItem(1, 'wrong-user', { is_purchased: true }, mockLogger),
|
||||
).rejects.toThrow('Shopping list item not found.');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('removeShoppingListItem', () => {
|
||||
it('should delete an item if rowCount is 1', async () => {
|
||||
mockPoolInstance.query.mockResolvedValue({ rowCount: 1, rows: [], command: 'DELETE' });
|
||||
await expect(shoppingRepo.removeShoppingListItem(1, mockLogger)).resolves.toBeUndefined();
|
||||
await expect(shoppingRepo.removeShoppingListItem(1, 'user-1', mockLogger)).resolves.toBeUndefined();
|
||||
expect(mockPoolInstance.query).toHaveBeenCalledWith(
|
||||
'DELETE FROM public.shopping_list_items WHERE shopping_list_item_id = $1',
|
||||
[1],
|
||||
expect.stringContaining('DELETE FROM public.shopping_list_items sli'),
|
||||
[1, 'user-1'],
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if no rows are deleted (item not found)', async () => {
|
||||
mockPoolInstance.query.mockResolvedValue({ rowCount: 0, rows: [], command: 'DELETE' });
|
||||
await expect(shoppingRepo.removeShoppingListItem(999, mockLogger)).rejects.toThrow(
|
||||
await expect(shoppingRepo.removeShoppingListItem(999, 'user-1', mockLogger)).rejects.toThrow(
|
||||
'Shopping list item not found.',
|
||||
);
|
||||
});
|
||||
@@ -341,15 +355,25 @@ describe('Shopping DB Service', () => {
|
||||
it('should throw a generic error if the database query fails', async () => {
|
||||
const dbError = new Error('DB Connection Error');
|
||||
mockPoolInstance.query.mockRejectedValue(dbError);
|
||||
await expect(shoppingRepo.removeShoppingListItem(1, mockLogger)).rejects.toThrow(
|
||||
await expect(shoppingRepo.removeShoppingListItem(1, 'user-1', mockLogger)).rejects.toThrow(
|
||||
'Failed to remove item from shopping list.',
|
||||
);
|
||||
expect(mockLogger.error).toHaveBeenCalledWith(
|
||||
{ err: dbError, itemId: 1 },
|
||||
{ err: dbError, itemId: 1, userId: 'user-1' },
|
||||
'Database error in removeShoppingListItem',
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('removeShoppingListItem - Ownership Check', () => {
|
||||
it('should not remove an item if the user does not own the shopping list', async () => {
|
||||
mockPoolInstance.query.mockResolvedValue({ rowCount: 0 });
|
||||
|
||||
await expect(shoppingRepo.removeShoppingListItem(1, 'wrong-user', mockLogger)).rejects.toThrow(
|
||||
'Shopping list item not found.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('completeShoppingList', () => {
|
||||
it('should call the complete_shopping_list database function', async () => {
|
||||
|
||||
Reference in New Issue
Block a user