mock mock mock !
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m50s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m50s
This commit is contained in:
@@ -6,8 +6,9 @@ import { useApi } from './useApi';
|
||||
import { useAuth } from '../hooks/useAuth';
|
||||
import { useUserData } from '../hooks/useUserData';
|
||||
import * as apiClient from '../services/apiClient';
|
||||
import type { ShoppingList, ShoppingListItem, User } from '../types';
|
||||
import React from 'react'; // Required for Dispatch/SetStateAction types
|
||||
import { createMockShoppingList, createMockShoppingListItem, createMockUserProfile } from '../tests/utils/mockFactories';
|
||||
import React from 'react';
|
||||
import type { ShoppingList, User } from '../types'; // Import ShoppingList and User types
|
||||
|
||||
// Define a type for the mock return value of useApi to ensure type safety in tests
|
||||
type MockApiResult = {
|
||||
@@ -30,7 +31,9 @@ const mockedUseApi = vi.mocked(useApi);
|
||||
const mockedUseAuth = vi.mocked(useAuth);
|
||||
const mockedUseUserData = vi.mocked(useUserData);
|
||||
|
||||
const mockUser: User = { user_id: 'user-123', email: 'test@example.com' };
|
||||
// Create a mock User object by extracting it from a mock UserProfile
|
||||
const mockUserProfile = createMockUserProfile({ user_id: 'user-123', user: { user_id: 'user-123', email: 'test@example.com' } });
|
||||
const mockUser: User = mockUserProfile.user;
|
||||
|
||||
describe('useShoppingLists Hook', () => {
|
||||
// Create a mock setter function that we can spy on
|
||||
@@ -96,9 +99,9 @@ describe('useShoppingLists Hook', () => {
|
||||
});
|
||||
|
||||
it('should set the first list as active on initial load if lists exist', async () => {
|
||||
const mockLists: ShoppingList[] = [
|
||||
{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] },
|
||||
{ shopping_list_id: 2, name: 'Hardware Store', user_id: 'user-123', created_at: '', items: [] },
|
||||
const mockLists = [
|
||||
createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' }),
|
||||
createMockShoppingList({ shopping_list_id: 2, name: 'Hardware Store', user_id: 'user-123' }),
|
||||
];
|
||||
|
||||
mockedUseUserData.mockReturnValue({
|
||||
@@ -125,9 +128,7 @@ describe('useShoppingLists Hook', () => {
|
||||
logout: vi.fn(),
|
||||
updateProfile: vi.fn(),
|
||||
});
|
||||
const mockLists: ShoppingList[] = [
|
||||
{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] },
|
||||
];
|
||||
const mockLists = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' })];
|
||||
mockedUseUserData.mockReturnValue({
|
||||
shoppingLists: mockLists,
|
||||
setShoppingLists: mockSetShoppingLists,
|
||||
@@ -143,7 +144,7 @@ describe('useShoppingLists Hook', () => {
|
||||
});
|
||||
|
||||
it('should set activeListId to null when lists become empty', async () => {
|
||||
const mockLists: ShoppingList[] = [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] }];
|
||||
const mockLists = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' })];
|
||||
|
||||
// Initial render with a list
|
||||
mockedUseUserData.mockReturnValue({
|
||||
@@ -221,7 +222,7 @@ describe('useShoppingLists Hook', () => {
|
||||
|
||||
describe('createList', () => {
|
||||
it('should call the API and update state on successful creation', async () => {
|
||||
const newList: ShoppingList = { shopping_list_id: 99, name: 'New List', user_id: 'user-123', created_at: '', items: [] };
|
||||
const newList = createMockShoppingList({ shopping_list_id: 99, name: 'New List', user_id: 'user-123' });
|
||||
let currentLists: ShoppingList[] = [];
|
||||
|
||||
// Mock the implementation of the setter to simulate a real state update.
|
||||
@@ -257,10 +258,10 @@ describe('useShoppingLists Hook', () => {
|
||||
|
||||
describe('deleteList', () => {
|
||||
// Use a function to get a fresh copy for each test run
|
||||
const getMockLists = (): ShoppingList[] => ([
|
||||
{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] },
|
||||
{ shopping_list_id: 2, name: 'Hardware Store', user_id: 'user-123', created_at: '', items: [] },
|
||||
]);
|
||||
const getMockLists = () => [
|
||||
createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' }),
|
||||
createMockShoppingList({ shopping_list_id: 2, name: 'Hardware Store', user_id: 'user-123' }),
|
||||
];
|
||||
|
||||
let currentLists: ShoppingList[] = [];
|
||||
|
||||
@@ -347,7 +348,7 @@ describe('useShoppingLists Hook', () => {
|
||||
|
||||
it('should set activeListId to null when the last list is deleted', async () => {
|
||||
console.log('TEST: should set activeListId to null when the last list is deleted');
|
||||
const singleList: ShoppingList[] = [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] }];
|
||||
const singleList = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' })];
|
||||
// Override the state for this specific test
|
||||
currentLists = singleList;
|
||||
mockDeleteListApi.mockResolvedValue(null);
|
||||
@@ -371,7 +372,7 @@ describe('useShoppingLists Hook', () => {
|
||||
|
||||
describe('addItemToList', () => {
|
||||
let currentLists: ShoppingList[] = [];
|
||||
const getMockLists = () => [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [] }];
|
||||
const getMockLists = () => [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123' })];
|
||||
|
||||
beforeEach(() => {
|
||||
currentLists = getMockLists();
|
||||
@@ -389,7 +390,7 @@ describe('useShoppingLists Hook', () => {
|
||||
});
|
||||
|
||||
it('should call API and add item to the correct list', async () => {
|
||||
const newItem: ShoppingListItem = { shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk', is_purchased: false, quantity: 1, added_at: new Date().toISOString() };
|
||||
const newItem = createMockShoppingListItem({ shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk' });
|
||||
mockAddItemApi.mockResolvedValue(newItem);
|
||||
|
||||
const { result, rerender } = renderHook(() => useShoppingLists());
|
||||
@@ -406,11 +407,11 @@ describe('useShoppingLists Hook', () => {
|
||||
|
||||
it('should not add a duplicate item (by master_item_id) to a list', async () => {
|
||||
console.log('TEST: should not add a duplicate item (by master_item_id) to a list');
|
||||
const existingItem: ShoppingListItem = { shopping_list_item_id: 100, shopping_list_id: 1, master_item_id: 5, custom_item_name: 'Milk', is_purchased: false, quantity: 1, added_at: '' };
|
||||
const existingItem = createMockShoppingListItem({ shopping_list_item_id: 100, shopping_list_id: 1, master_item_id: 5, custom_item_name: 'Milk' });
|
||||
// Override state for this specific test
|
||||
currentLists = [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [existingItem] }];
|
||||
currentLists = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', items: [existingItem] })];
|
||||
// This is what the API would return for adding master_item_id 5 again. It has a new shopping_list_item_id.
|
||||
const newItemFromApi: ShoppingListItem = { shopping_list_item_id: 101, shopping_list_id: 1, master_item_id: 5, custom_item_name: 'Milk', is_purchased: false, quantity: 1, added_at: '' };
|
||||
const newItemFromApi = createMockShoppingListItem({ shopping_list_item_id: 101, shopping_list_id: 1, master_item_id: 5, custom_item_name: 'Milk' });
|
||||
|
||||
mockAddItemApi.mockResolvedValue(newItemFromApi);
|
||||
|
||||
@@ -433,17 +434,15 @@ describe('useShoppingLists Hook', () => {
|
||||
});
|
||||
|
||||
describe('updateItemInList', () => {
|
||||
const initialItem: ShoppingListItem = { shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk', is_purchased: false, quantity: 1, added_at: new Date().toISOString() };
|
||||
const mockLists: ShoppingList[] = [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [initialItem] }];
|
||||
const otherList: ShoppingList = { shopping_list_id: 2, name: 'Other', user_id: 'user-123', created_at: '', items: [] };
|
||||
const multiLists = [mockLists[0], otherList];
|
||||
const initialItem = createMockShoppingListItem({ shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk', is_purchased: false, quantity: 1 });
|
||||
const multiLists = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', items: [initialItem] }), createMockShoppingList({ shopping_list_id: 2, name: 'Other' })];
|
||||
|
||||
beforeEach(() => {
|
||||
mockedUseUserData.mockReturnValue({ shoppingLists: multiLists, setShoppingLists: mockSetShoppingLists, watchedItems: [], setWatchedItems: vi.fn(), isLoading: false, error: null });
|
||||
});
|
||||
|
||||
it('should call API and update the correct item, leaving other lists unchanged', async () => {
|
||||
const updatedItem: ShoppingListItem = { ...initialItem, is_purchased: true };
|
||||
const updatedItem = { ...initialItem, is_purchased: true };
|
||||
mockUpdateItemApi.mockResolvedValue(updatedItem);
|
||||
|
||||
const { result } = renderHook(() => useShoppingLists());
|
||||
@@ -457,7 +456,7 @@ describe('useShoppingLists Hook', () => {
|
||||
const updater = (mockSetShoppingLists as Mock).mock.calls[0][0];
|
||||
const newState = updater(multiLists);
|
||||
expect(newState[0].items[0].is_purchased).toBe(true);
|
||||
expect(newState[1]).toBe(otherList); // Verify other list is unchanged
|
||||
expect(newState[1]).toBe(multiLists[1]); // Verify other list is unchanged
|
||||
});
|
||||
|
||||
it('should not call update API if no list is active', async () => {
|
||||
@@ -482,10 +481,8 @@ describe('useShoppingLists Hook', () => {
|
||||
});
|
||||
|
||||
describe('removeItemFromList', () => {
|
||||
const initialItem: ShoppingListItem = { shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk', is_purchased: false, quantity: 1, added_at: new Date().toISOString() };
|
||||
const mockLists: ShoppingList[] = [{ shopping_list_id: 1, name: 'Groceries', user_id: 'user-123', created_at: '', items: [initialItem] }];
|
||||
const otherList: ShoppingList = { shopping_list_id: 2, name: 'Other', user_id: 'user-123', created_at: '', items: [] };
|
||||
const multiLists = [mockLists[0], otherList];
|
||||
const initialItem = createMockShoppingListItem({ shopping_list_item_id: 101, shopping_list_id: 1, custom_item_name: 'Milk' });
|
||||
const multiLists = [createMockShoppingList({ shopping_list_id: 1, name: 'Groceries', items: [initialItem] }), createMockShoppingList({ shopping_list_id: 2, name: 'Other' })];
|
||||
|
||||
beforeEach(() => {
|
||||
mockedUseUserData.mockReturnValue({
|
||||
@@ -511,7 +508,7 @@ describe('useShoppingLists Hook', () => {
|
||||
const updater = (mockSetShoppingLists as Mock).mock.calls[0][0];
|
||||
const newState = updater(multiLists);
|
||||
expect(newState[0].items).toHaveLength(0);
|
||||
expect(newState[1]).toBe(otherList); // Verify other list is unchanged
|
||||
expect(newState[1]).toBe(multiLists[1]); // Verify other list is unchanged
|
||||
});
|
||||
|
||||
it('should not call remove API if no list is active', async () => {
|
||||
|
||||
Reference in New Issue
Block a user