Files
interview-demo-code/frontend/spa/tests/unit/stores/CartStore.test.js
Nikita Kiselev 5439e8ef9a
Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
Squashed commit message
2026-03-11 22:08:52 +03:00

267 lines
7.9 KiB
JavaScript
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 { 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('');
});
});
});
});