267 lines
7.9 KiB
JavaScript
267 lines
7.9 KiB
JavaScript
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||
import { setActivePinia, createPinia } from 'pinia';
|
||
import { useCartStore } from '@/stores/CartStore.js';
|
||
import * as ftch from '@/utils/ftch.js';
|
||
|
||
// Мокаем API функции
|
||
vi.mock('@/utils/ftch.js', () => ({
|
||
getCart: vi.fn(),
|
||
addToCart: vi.fn(),
|
||
cartRemoveItem: vi.fn(),
|
||
cartEditItem: vi.fn(),
|
||
setCoupon: vi.fn(),
|
||
setVoucher: vi.fn(),
|
||
}));
|
||
|
||
// Мокаем другие stores
|
||
vi.mock('@/stores/yaMetrikaStore.js', () => ({
|
||
useYaMetrikaStore: () => ({
|
||
dataLayerPush: vi.fn(),
|
||
}),
|
||
}));
|
||
|
||
vi.mock('@/stores/SettingsStore.js', () => ({
|
||
useSettingsStore: () => ({
|
||
currency_code: 'RUB',
|
||
}),
|
||
}));
|
||
|
||
describe('CartStore', () => {
|
||
beforeEach(() => {
|
||
setActivePinia(createPinia());
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
describe('state', () => {
|
||
it('должен инициализироваться с пустыми значениями', () => {
|
||
const store = useCartStore();
|
||
|
||
expect(store.items).toEqual([]);
|
||
expect(store.productsCount).toBe(0);
|
||
expect(store.total).toBe(0);
|
||
expect(store.isLoading).toBe(false);
|
||
expect(store.coupon).toBe('');
|
||
expect(store.voucher).toBe('');
|
||
});
|
||
});
|
||
|
||
describe('getters', () => {
|
||
it('canCheckout должен возвращать false при загрузке', () => {
|
||
const store = useCartStore();
|
||
store.isLoading = true;
|
||
|
||
expect(store.canCheckout).toBe(false);
|
||
});
|
||
|
||
it('canCheckout должен возвращать false при наличии ошибки', () => {
|
||
const store = useCartStore();
|
||
store.error_warning = 'Ошибка';
|
||
|
||
expect(store.canCheckout).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('actions', () => {
|
||
describe('getProducts', () => {
|
||
it('должен загружать продукты из API', async () => {
|
||
const mockData = {
|
||
data: {
|
||
products: [{ id: 1, name: 'Product 1' }],
|
||
total_products_count: 1,
|
||
totals: { total: 1000 },
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
};
|
||
|
||
ftch.getCart.mockResolvedValue(mockData);
|
||
|
||
const store = useCartStore();
|
||
await store.getProducts();
|
||
|
||
expect(store.items).toEqual(mockData.data.products);
|
||
expect(store.productsCount).toBe(1);
|
||
expect(store.isLoading).toBe(false);
|
||
});
|
||
|
||
it('должен обрабатывать ошибки', async () => {
|
||
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||
ftch.getCart.mockRejectedValue(new Error('Network error'));
|
||
|
||
const store = useCartStore();
|
||
await store.getProducts();
|
||
|
||
expect(store.isLoading).toBe(false);
|
||
expect(consoleErrorSpy).toHaveBeenCalled();
|
||
|
||
consoleErrorSpy.mockRestore();
|
||
});
|
||
});
|
||
|
||
describe('addProduct', () => {
|
||
it('должен добавлять продукт в корзину', async () => {
|
||
const mockResponse = { error: null };
|
||
ftch.addToCart.mockResolvedValue(mockResponse);
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [{ id: 1, name: 'Product 1' }],
|
||
total_products_count: 1,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const store = useCartStore();
|
||
await store.addProduct(1, 'Product 1', 100, 2, []);
|
||
|
||
expect(ftch.addToCart).toHaveBeenCalled();
|
||
expect(store.isLoading).toBe(false);
|
||
});
|
||
|
||
it('должен обрабатывать опции продукта', async () => {
|
||
const mockResponse = { error: null };
|
||
ftch.addToCart.mockResolvedValue(mockResponse);
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [],
|
||
total_products_count: 0,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const options = [
|
||
{ type: 'checkbox', product_option_id: 1, value: [{ product_option_value_id: 10 }] },
|
||
{ type: 'radio', product_option_id: 2, value: { product_option_value_id: 20 } },
|
||
{ type: 'text', product_option_id: 3, value: 'test text' },
|
||
];
|
||
|
||
const store = useCartStore();
|
||
await store.addProduct(1, 'Product', 100, 1, options);
|
||
|
||
expect(ftch.addToCart).toHaveBeenCalled();
|
||
});
|
||
|
||
it('должен выбрасывать ошибку при ошибке API', async () => {
|
||
const mockResponse = { error: 'Product not found' };
|
||
ftch.addToCart.mockResolvedValue(mockResponse);
|
||
|
||
const store = useCartStore();
|
||
|
||
await expect(store.addProduct(1, 'Product', 100)).rejects.toThrow();
|
||
});
|
||
});
|
||
|
||
describe('removeItem', () => {
|
||
it('должен удалять товар из корзины', async () => {
|
||
ftch.cartRemoveItem.mockResolvedValue({});
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [],
|
||
total_products_count: 0,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const store = useCartStore();
|
||
const cartItem = { product_id: 1, name: 'Product', quantity: 1 };
|
||
|
||
await store.removeItem(cartItem, 'row123', 0);
|
||
|
||
expect(ftch.cartRemoveItem).toHaveBeenCalled();
|
||
expect(store.isLoading).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('setQuantity', () => {
|
||
it('должен изменять количество товара', async () => {
|
||
ftch.cartEditItem.mockResolvedValue({});
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [],
|
||
total_products_count: 0,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const store = useCartStore();
|
||
await store.setQuantity('cart123', 5);
|
||
|
||
expect(ftch.cartEditItem).toHaveBeenCalled();
|
||
expect(store.isLoading).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('applyCoupon', () => {
|
||
it('должен применять купон успешно', async () => {
|
||
ftch.setCoupon.mockResolvedValue({ error: null });
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [],
|
||
total_products_count: 0,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const store = useCartStore();
|
||
store.coupon = 'DISCOUNT10';
|
||
|
||
await store.applyCoupon();
|
||
|
||
expect(ftch.setCoupon).toHaveBeenCalledWith('DISCOUNT10');
|
||
expect(store.error_warning).toBe('');
|
||
});
|
||
|
||
it('должен обрабатывать ошибку при применении купона', async () => {
|
||
ftch.setCoupon.mockResolvedValue({ error: 'Invalid coupon' });
|
||
|
||
const store = useCartStore();
|
||
store.coupon = 'INVALID';
|
||
|
||
await store.applyCoupon();
|
||
|
||
expect(store.error_coupon).toBe('Invalid coupon');
|
||
});
|
||
});
|
||
|
||
describe('applyVoucher', () => {
|
||
it('должен применять ваучер успешно', async () => {
|
||
ftch.setVoucher.mockResolvedValue({ error: null });
|
||
ftch.getCart.mockResolvedValue({
|
||
data: {
|
||
products: [],
|
||
total_products_count: 0,
|
||
totals: {},
|
||
error_warning: '',
|
||
attention: '',
|
||
success: '',
|
||
},
|
||
});
|
||
|
||
const store = useCartStore();
|
||
store.voucher = 'VOUCHER123';
|
||
|
||
await store.applyVoucher();
|
||
|
||
expect(ftch.setVoucher).toHaveBeenCalledWith('VOUCHER123');
|
||
expect(store.error_warning).toBe('');
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|