test: add AddToCartButton and ToggleCartIcon integration tests, fix timer cleanup

This commit is contained in:
Kirill
2026-05-25 18:14:27 +05:00
parent c9e3917129
commit bedf98245b
4 changed files with 112 additions and 2 deletions
@@ -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(
<QueryClientProvider client={qc}>
<AddToCartButton productId="test-product" />
</QueryClientProvider>,
)
fireEvent.click(screen.getByRole('button', { name: /в корзину/i }))
await vi.waitFor(() => {
expect(spy).toHaveBeenCalled()
})
})
})
@@ -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(
<QueryClientProvider client={qc}>
<MemoryRouter>
<ToggleCartIcon productId="test-product" />
</MemoryRouter>
</QueryClientProvider>,
)
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(
<QueryClientProvider client={qc}>
<MemoryRouter>
<ToggleCartIcon productId="test-product" />
</MemoryRouter>
</QueryClientProvider>,
)
await vi.waitFor(() => {
expect(screen.getByRole('button', { name: /убрать из корзины/i })).toBeInTheDocument()
})
fireEvent.click(screen.getByRole('button', { name: /убрать из корзины/i }))
await vi.waitFor(() => {
expect(spy).not.toHaveBeenCalled()
})
})
})
@@ -1,6 +1,6 @@
import { render, screen, fireEvent, act } from '@testing-library/react' import { render, screen, fireEvent, act } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom' 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 { cartAdded, cartDismissed } from '@/shared/model/cart-notifications'
import { CartSnackbar } from '@/shared/ui/CartSnackbar' import { CartSnackbar } from '@/shared/ui/CartSnackbar'
@@ -15,6 +15,10 @@ beforeEach(() => {
navigateMock.mockClear() navigateMock.mockClear()
}) })
afterEach(() => {
vi.useRealTimers()
})
function renderWithRouter() { function renderWithRouter() {
render( render(
<MemoryRouter initialEntries={['/']}> <MemoryRouter initialEntries={['/']}>
@@ -53,7 +57,6 @@ describe('CartSnackbar', () => {
vi.advanceTimersByTime(4000) vi.advanceTimersByTime(4000)
}) })
expect(screen.queryByText(/товар добавлен/i)).not.toBeInTheDocument() expect(screen.queryByText(/товар добавлен/i)).not.toBeInTheDocument()
vi.useRealTimers()
}) })
it('navigates to /cart and closes on "Перейти в корзину" click', () => { it('navigates to /cart and closes on "Перейти в корзину" click', () => {
Binary file not shown.