canina/src/store/__tests__/cartStore.test.ts

143 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { useCartStore } from '../cartStore';
import { orderService } from '../../services/orderService';
vi.mock('../../services/orderService', () => ({
orderService: {
createOrder: vi.fn(),
},
}));
const mockProduct = {
id: 'prod-1',
artNo: 'art-1',
name: 'Canhydrox GAG',
scientificTagline: 'Joint helper',
description: 'Joints',
price: '۱,۰۰۰ تومان',
priceValue: 1000,
category: 'joints',
unit: 'tablet',
packageSize: 100,
main_ingredients: [],
dosage_logic: '1',
benefits: '',
symptoms: [],
suitableFor: 'سگ' as any,
calculateDosage: () => ({ quantity: 1, unit: 'tablet', description: '' }),
analysis: {},
feedingAdvice: '',
specialist: null as any,
image: '',
};
describe('cartStore', () => {
beforeEach(() => {
vi.clearAllMocks();
useCartStore.setState({
items: [],
isSubscribed: false,
charityDonation: 0,
coupon: null,
orders: [],
});
});
it('should add item to cart', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
const state = useCartStore.getState();
expect(state.items).toHaveLength(1);
expect(state.items[0].product.id).toBe('prod-1');
expect(state.items[0].quantity).toBe(2);
});
it('should increment quantity if item already in cart', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
store.addItem(mockProduct, 3);
const state = useCartStore.getState();
expect(state.items).toHaveLength(1);
expect(state.items[0].quantity).toBe(5);
});
it('should remove item from cart', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
store.removeItem('prod-1');
const state = useCartStore.getState();
expect(state.items).toHaveLength(0);
});
it('should update quantity', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
store.updateQuantity('prod-1', 4);
const state = useCartStore.getState();
expect(state.items[0].quantity).toBe(4);
});
it('should remove item if update quantity is <= 0', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
store.updateQuantity('prod-1', 0);
const state = useCartStore.getState();
expect(state.items).toHaveLength(0);
});
it('should apply discount coupon', () => {
const store = useCartStore.getState();
const success = store.applyCoupon('CANINA2024');
expect(success).toBe(true);
const state = useCartStore.getState();
expect(state.coupon).toEqual({ code: 'CANINA2024', discount: 0.1 });
});
it('should calculate subtotal, discount and total', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2); // 2 * 1000 = 2000
store.applyCoupon('CANINA2024'); // 10% discount
expect(useCartStore.getState().getSubtotal()).toBe(2000);
expect(useCartStore.getState().getDiscount()).toBe(200);
expect(useCartStore.getState().getTotal()).toBe(1800);
});
it('should create order successfully via orderService', async () => {
const mockBackendOrder = {
id: 'backend-order-id',
createdAt: '2026-05-26T18:00:00.000Z',
totalAmount: '2000.00',
charityDonation: '0.00',
status: 'processing',
trackingNumber: 'TRK-12345',
};
vi.mocked(orderService.createOrder).mockResolvedValue(mockBackendOrder);
const store = useCartStore.getState();
store.addItem(mockProduct, 2);
const orderId = await store.addOrder({
items: store.items,
total: 2000,
charityDonation: 0,
petId: 'pet-id',
});
expect(orderService.createOrder).toHaveBeenCalled();
expect(orderId).toBe('backend-order-id');
const state = useCartStore.getState();
expect(state.orders).toHaveLength(1);
expect(state.orders[0].id).toBe('backend-order-id');
expect(state.orders[0].total).toBe(2000);
});
});