diff --git a/client/src/features/cart/add-to-cart/ui/__tests__/AddToCartButton.test.tsx b/client/src/features/cart/add-to-cart/ui/__tests__/AddToCartButton.test.tsx new file mode 100644 index 0000000..5d95186 --- /dev/null +++ b/client/src/features/cart/add-to-cart/ui/__tests__/AddToCartButton.test.tsx @@ -0,0 +1,38 @@ +import { render, screen, fireEvent } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import * as notifications from '@/shared/model/cart-notifications' +import { AddToCartButton } from '../AddToCartButton' + +vi.mock('@/entities/cart/api/cart-api', () => ({ + addToCart: vi.fn(() => Promise.resolve()), +})) + +vi.mock('effector-react', async () => { + const actual = await vi.importActual('effector-react') + return { ...actual, useUnit: () => ({ id: '1', email: 'test@test.com' }) } +}) + +describe('AddToCartButton', () => { + const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } }) + + beforeEach(() => { + vi.clearAllMocks() + qc.clear() + }) + + it('calls cartAdded after successful add', async () => { + const spy = vi.spyOn(notifications, 'cartAdded') + render( + + + , + ) + + fireEvent.click(screen.getByRole('button', { name: /в корзину/i })) + + await vi.waitFor(() => { + expect(spy).toHaveBeenCalled() + }) + }) +}) diff --git a/client/src/features/cart/toggle-cart-icon/ui/__tests__/ToggleCartIcon.test.tsx b/client/src/features/cart/toggle-cart-icon/ui/__tests__/ToggleCartIcon.test.tsx new file mode 100644 index 0000000..4ed67bb --- /dev/null +++ b/client/src/features/cart/toggle-cart-icon/ui/__tests__/ToggleCartIcon.test.tsx @@ -0,0 +1,69 @@ +import { render, screen, fireEvent } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { MemoryRouter } from 'react-router-dom' +import * as notifications from '@/shared/model/cart-notifications' +import * as api from '@/entities/cart/api/cart-api' +import { ToggleCartIcon } from '../ToggleCartIcon' + +vi.mock('@/entities/cart/api/cart-api', () => ({ + addToCart: vi.fn(() => Promise.resolve()), + fetchMyCart: vi.fn(() => Promise.resolve({ items: [] })), + removeCartItem: vi.fn(() => Promise.resolve()), +})) + +vi.mock('effector-react', async () => { + const actual = await vi.importActual('effector-react') + return { ...actual, useUnit: () => ({ id: '1', email: 'test@test.com' }) } +}) + +describe('ToggleCartIcon', () => { + const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } }) + + beforeEach(() => { + vi.clearAllMocks() + qc.clear() + }) + + it('calls cartAdded after successful add', async () => { + const spy = vi.spyOn(notifications, 'cartAdded') + render( + + + + + , + ) + + fireEvent.click(screen.getByRole('button', { name: /в корзину/i })) + + await vi.waitFor(() => { + expect(spy).toHaveBeenCalled() + }) + }) + + it('does not call cartAdded on remove', async () => { + vi.mocked(api.fetchMyCart).mockResolvedValueOnce({ + items: [{ id: 'cart-1', qty: 1, product: { id: 'test-product' } as never }], + }) + const spy = vi.spyOn(notifications, 'cartAdded') + + render( + + + + + , + ) + + await vi.waitFor(() => { + expect(screen.getByRole('button', { name: /убрать из корзины/i })).toBeInTheDocument() + }) + + fireEvent.click(screen.getByRole('button', { name: /убрать из корзины/i })) + + await vi.waitFor(() => { + expect(spy).not.toHaveBeenCalled() + }) + }) +}) diff --git a/client/src/shared/ui/__tests__/CartSnackbar.test.tsx b/client/src/shared/ui/__tests__/CartSnackbar.test.tsx index cf6a3e3..b163e27 100644 --- a/client/src/shared/ui/__tests__/CartSnackbar.test.tsx +++ b/client/src/shared/ui/__tests__/CartSnackbar.test.tsx @@ -1,6 +1,6 @@ import { render, screen, fireEvent, act } from '@testing-library/react' import { MemoryRouter } from 'react-router-dom' -import { describe, it, expect, vi, beforeEach } from 'vitest' +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { cartAdded, cartDismissed } from '@/shared/model/cart-notifications' import { CartSnackbar } from '@/shared/ui/CartSnackbar' @@ -15,6 +15,10 @@ beforeEach(() => { navigateMock.mockClear() }) +afterEach(() => { + vi.useRealTimers() +}) + function renderWithRouter() { render( @@ -53,7 +57,6 @@ describe('CartSnackbar', () => { vi.advanceTimersByTime(4000) }) expect(screen.queryByText(/товар добавлен/i)).not.toBeInTheDocument() - vi.useRealTimers() }) it('navigates to /cart and closes on "Перейти в корзину" click', () => { diff --git a/server/prisma/prisma/dev.db b/server/prisma/prisma/dev.db index 7d9b45c..18b8cec 100644 Binary files a/server/prisma/prisma/dev.db and b/server/prisma/prisma/dev.db differ