import { server } from '@mocks/jest/server'; import { createReactQueryWrapper } from '@mocks/jest/wrappers'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; import type { AddExpenseItemBody, AddExpenseItemPath, AddExpenseItemSuccessResponse } from '@/entity/expenses/item'; import AddExpenseItemButton from './AddExpenseItemButton.ui'; const renderButton = () => { render( , { wrapper: createReactQueryWrapper() }, ); const buttonElem = screen.getByTestId('test-button'); return { buttonElem, }; }; const openModal = async () => { const { buttonElem } = renderButton(); await userEvent.click(buttonElem); const modalElem = screen.getByRole('dialog'); return { modalElem, }; }; const fillForm = async (data: { amount: string; count: string; date: string; description: string; title: string }) => { await userEvent.type(screen.getByLabelText('Название'), data.title); await userEvent.type(screen.getByLabelText('Описание'), data.description); await userEvent.type(screen.getByLabelText('Дата'), data.date); await userEvent.type(screen.getByLabelText('Сумма'), data.amount); await userEvent.type(screen.getByLabelText('Количество'), data.count); }; const submitHandler = (requestSpy: jest.Mock) => http.post< AddExpenseItemPath, AddExpenseItemBody, AddExpenseItemSuccessResponse >( '/expenses/list/123/items', async ({ request }) => { const body = await request.json(); requestSpy(body); return HttpResponse.json({ amount: 12, count: 12, createdAt: '2025-08-29T07:57:40.503Z', currency: 'RUB', date: '2025-08-22T00:00:03.000Z', description: 'Mock description', expenseListId: '10cc093c-3875-4d33-a40a-df526266e262', id: '51a44dc0-597b-49b9-85bb-e0bcd42db3f6', title: 'Mock item', updatedAt: '2025-08-29T07:57:40.503Z', }); }, ); describe('Test AddExpenseItemButton', () => { test('should correct render button', () => { const { buttonElem } = renderButton(); expect(buttonElem).toBeInTheDocument(); expect(buttonElem).toBeVisible(); expect(buttonElem).toBeEnabled(); expect(buttonElem).toHaveTextContent('Добавить элемент'); const modal = screen.queryByRole('dialog'); expect(modal).not.toBeInTheDocument(); }); test('should open modal after click', async () => { const { modalElem } = await openModal(); expect(modalElem).toBeInTheDocument(); expect(modalElem).toBeVisible(); }); describe('should close modal after submit and send request', () => { let modalElem: HTMLElement; let submitButtonElem: HTMLElement; const requestSpy = jest.fn(); beforeEach(async () => { server.use(submitHandler(requestSpy)); modalElem = (await openModal()).modalElem; submitButtonElem = screen.getByText('Добавить'); await fillForm({ amount: '12', count: '1', date: '2025-08-29', description: 'Описание элемента', title: 'Название элемента', }); }); test('should send correct request', async () => { await userEvent.click(submitButtonElem); expect(requestSpy).toHaveBeenCalledTimes(1); expect(requestSpy).toHaveBeenCalledWith({ amount: 12, count: 1, currency: 'RUB', date: '2025-08-29T00:00:00.000Z', description: 'Описание элемента', title: 'Название элемента', }); }); test('should close modal after submit', async () => { expect(submitButtonElem).toBeEnabled(); await userEvent.click(submitButtonElem); expect(modalElem).not.toBeInTheDocument(); }); }); });