2026-05-19 10:13:40 +09:00
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
2026-05-19 11:06:03 +09:00
|
|
|
import { apiClient } from '../../src/services/api-client';
|
|
|
|
|
import * as ShoppingListsService from '../../src/services/shopping-lists';
|
2026-05-19 10:13:40 +09:00
|
|
|
|
2026-05-19 11:06:03 +09:00
|
|
|
vi.mock('../../src/services/api-client', () => ({
|
2026-05-19 10:13:40 +09:00
|
|
|
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');
|
|
|
|
|
|
2026-05-19 16:15:15 +09:00
|
|
|
(apiClient as any).baseUrl = 'https://api.meshitrack.com';
|
2026-05-19 10:13:40 +09:00
|
|
|
const urlSecure = ShoppingListsService.getShoppingListSyncSocketUrl('hh1', 'list1');
|
|
|
|
|
expect(urlSecure).toBe('wss://api.meshitrack.com/households/hh1/shopping-lists/list1/sync');
|
2026-05-19 14:09:03 +09:00
|
|
|
|
|
|
|
|
// Test falsy baseUrl fallback path
|
|
|
|
|
(apiClient as any).baseUrl = '';
|
|
|
|
|
const urlFalsy = ShoppingListsService.getShoppingListSyncSocketUrl('hh1', 'list1');
|
|
|
|
|
expect(urlFalsy).toBe('ws:///households/hh1/shopping-lists/list1/sync');
|
2026-05-19 10:13:40 +09:00
|
|
|
});
|
|
|
|
|
});
|