import { describe, it, expect, vi, beforeEach } from 'vitest'; import { apiClient } from '../../src/services/api-client'; import * as ShoppingListsService from '../../src/services/shopping-lists'; vi.mock('../../src/services/api-client', () => ({ apiClient: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), delete: vi.fn(), baseUrl: 'http://localhost:3001', }, })); describe('shopping-lists service', () => { beforeEach(() => { vi.clearAllMocks(); }); it('getShoppingLists', async () => { await ShoppingListsService.getShoppingLists('hh1'); expect(apiClient.get).toHaveBeenCalledWith('/households/hh1/shopping-lists'); }); it('getShoppingList', async () => { await ShoppingListsService.getShoppingList('hh1', 'list1'); expect(apiClient.get).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1'); }); it('createShoppingList', async () => { const data = { name: 'Test' } as any; await ShoppingListsService.createShoppingList('hh1', data); expect(apiClient.post).toHaveBeenCalledWith('/households/hh1/shopping-lists', data); }); it('updateShoppingList', async () => { const data = { name: 'Updated' } as any; await ShoppingListsService.updateShoppingList('hh1', 'list1', data); expect(apiClient.patch).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1', data); }); it('deleteShoppingList', async () => { await ShoppingListsService.deleteShoppingList('hh1', 'list1'); expect(apiClient.delete).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1'); }); it('addShoppingItem', async () => { const data = { productId: 'p1' } as any; await ShoppingListsService.addShoppingItem('hh1', 'list1', data); expect(apiClient.post).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1/items', data); }); it('updateShoppingItem', async () => { const data = { checked: true } as any; await ShoppingListsService.updateShoppingItem('hh1', 'list1', 'item1', data); expect(apiClient.patch).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1/items/item1', data); }); it('removeShoppingItem', async () => { await ShoppingListsService.removeShoppingItem('hh1', 'list1', 'item1'); expect(apiClient.delete).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1/items/item1'); }); it('generateFromMealPlan', async () => { await ShoppingListsService.generateFromMealPlan('hh1', 'mp1'); expect(apiClient.post).toHaveBeenCalledWith('/households/hh1/shopping-lists/from-meal-plan/mp1'); }); it('syncToPantry', async () => { await ShoppingListsService.syncToPantry('hh1', 'list1'); expect(apiClient.post).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1/sync-to-pantry'); }); it('getBasketStoreComparison', async () => { await ShoppingListsService.getBasketStoreComparison('hh1', 'list1'); expect(apiClient.get).toHaveBeenCalledWith('/households/hh1/shopping-lists/list1/stores'); }); it('getShoppingListSyncSocketUrl handles insecure and secure contexts', () => { const urlInsecure = ShoppingListsService.getShoppingListSyncSocketUrl('hh1', 'list1'); expect(urlInsecure).toBe('ws://localhost:3001/households/hh1/shopping-lists/list1/sync'); apiClient.baseUrl = 'https://api.meshitrack.com'; const urlSecure = ShoppingListsService.getShoppingListSyncSocketUrl('hh1', 'list1'); expect(urlSecure).toBe('wss://api.meshitrack.com/households/hh1/shopping-lists/list1/sync'); }); });