201 lines
5.7 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|