miinventario-mobile-v2/src/stores/__tests__/inventory.store.spec.ts
rckrdmrd eb718a95aa Sincronización desde miinventario/apps/mobile - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:29:24 -06:00

201 lines
5.7 KiB
TypeScript

import { useInventoryStore } from '../inventory.store';
import { inventoryService } from '@services/api/inventory.service';
jest.mock('@services/api/inventory.service');
const mockInventoryService = inventoryService as jest.Mocked<
typeof inventoryService
>;
describe('Inventory Store', () => {
beforeEach(() => {
useInventoryStore.setState({
items: [],
isLoading: false,
error: null,
currentPage: 1,
hasMore: true,
searchQuery: '',
categoryFilter: null,
});
jest.clearAllMocks();
});
describe('fetchItems', () => {
it('should load inventory items', async () => {
const mockItems = [
{ id: '1', name: 'Item 1', quantity: 10, storeId: 'store-1' },
{ id: '2', name: 'Item 2', quantity: 5, storeId: 'store-1' },
];
mockInventoryService.getItems.mockResolvedValue({
items: mockItems,
total: 2,
page: 1,
limit: 50,
hasMore: false,
});
await useInventoryStore.getState().fetchItems('store-1');
const state = useInventoryStore.getState();
expect(state.items).toHaveLength(2);
expect(state.hasMore).toBe(false);
expect(state.error).toBeNull();
});
it('should handle fetch errors', async () => {
mockInventoryService.getItems.mockRejectedValue(
new Error('Failed to fetch')
);
await useInventoryStore.getState().fetchItems('store-1');
expect(useInventoryStore.getState().error).toBe('Failed to fetch');
});
it('should set loading state during fetch', async () => {
mockInventoryService.getItems.mockImplementation(
() =>
new Promise((resolve) =>
setTimeout(
() =>
resolve({
items: [],
total: 0,
page: 1,
limit: 50,
hasMore: false,
}),
100
)
)
);
const fetchPromise = useInventoryStore.getState().fetchItems('store-1');
expect(useInventoryStore.getState().isLoading).toBe(true);
await fetchPromise;
expect(useInventoryStore.getState().isLoading).toBe(false);
});
});
describe('loadMore', () => {
it('should load next page and append items', async () => {
useInventoryStore.setState({
items: [{ id: '1', name: 'Item 1', quantity: 10, storeId: 'store-1' }],
currentPage: 1,
hasMore: true,
});
mockInventoryService.getItems.mockResolvedValue({
items: [{ id: '2', name: 'Item 2', quantity: 5, storeId: 'store-1' }],
total: 2,
page: 2,
limit: 50,
hasMore: false,
});
await useInventoryStore.getState().loadMore('store-1');
const state = useInventoryStore.getState();
expect(state.items).toHaveLength(2);
expect(state.currentPage).toBe(2);
});
it('should not load if hasMore is false', async () => {
useInventoryStore.setState({ hasMore: false });
await useInventoryStore.getState().loadMore('store-1');
expect(mockInventoryService.getItems).not.toHaveBeenCalled();
});
});
describe('updateItem', () => {
it('should update an item in the list', async () => {
useInventoryStore.setState({
items: [
{ id: '1', name: 'Item 1', quantity: 10, storeId: 'store-1' },
{ id: '2', name: 'Item 2', quantity: 5, storeId: 'store-1' },
],
});
const updatedItem = {
id: '1',
name: 'Updated Item',
quantity: 20,
storeId: 'store-1',
};
mockInventoryService.updateItem.mockResolvedValue(updatedItem);
await useInventoryStore
.getState()
.updateItem('store-1', '1', { name: 'Updated Item', quantity: 20 });
const items = useInventoryStore.getState().items;
expect(items[0].name).toBe('Updated Item');
expect(items[0].quantity).toBe(20);
});
});
describe('deleteItem', () => {
it('should remove item from the list', async () => {
useInventoryStore.setState({
items: [
{ id: '1', name: 'Item 1', quantity: 10, storeId: 'store-1' },
{ id: '2', name: 'Item 2', quantity: 5, storeId: 'store-1' },
],
});
mockInventoryService.deleteItem.mockResolvedValue(undefined);
await useInventoryStore.getState().deleteItem('store-1', '1');
const items = useInventoryStore.getState().items;
expect(items).toHaveLength(1);
expect(items[0].id).toBe('2');
});
});
describe('setSearchQuery', () => {
it('should update search query', () => {
useInventoryStore.getState().setSearchQuery('test search');
expect(useInventoryStore.getState().searchQuery).toBe('test search');
});
});
describe('setCategoryFilter', () => {
it('should update category filter', () => {
useInventoryStore.getState().setCategoryFilter('Electronics');
expect(useInventoryStore.getState().categoryFilter).toBe('Electronics');
});
it('should allow null filter', () => {
useInventoryStore.setState({ categoryFilter: 'Electronics' });
useInventoryStore.getState().setCategoryFilter(null);
expect(useInventoryStore.getState().categoryFilter).toBeNull();
});
});
describe('clearItems', () => {
it('should reset items and pagination', () => {
useInventoryStore.setState({
items: [{ id: '1', name: 'Item', quantity: 10, storeId: 'store-1' }],
currentPage: 5,
hasMore: false,
});
useInventoryStore.getState().clearItems();
const state = useInventoryStore.getState();
expect(state.items).toHaveLength(0);
expect(state.currentPage).toBe(1);
expect(state.hasMore).toBe(true);
});
});
});