From f473504274cdad7572b2bab4ba586fce7d98145e Mon Sep 17 00:00:00 2001 From: Irina Yarutkina Date: Thu, 2 Jul 2026 23:55:58 +0300 Subject: [PATCH] YH-2101: add unit tests for CompanySelect component --- .../ui/CompanySelect/CompanySelect.test.tsx | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/entities/company/ui/CompanySelect/CompanySelect.test.tsx diff --git a/src/entities/company/ui/CompanySelect/CompanySelect.test.tsx b/src/entities/company/ui/CompanySelect/CompanySelect.test.tsx new file mode 100644 index 000000000..0cdd939d0 --- /dev/null +++ b/src/entities/company/ui/CompanySelect/CompanySelect.test.tsx @@ -0,0 +1,162 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; + +import { companiesMock } from '../../api/__mocks__/data/companiesMock'; +import { useGetCompaniesListQuery } from '../../api/companyApi'; + +import { CompanySelect } from './CompanySelect'; + +const mockCompanies = companiesMock; +const mockedQuery = useGetCompaniesListQuery as jest.Mock; + +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => { + const translations: Record = { + 'companies.select.choose': 'Выберите название компании', + 'companies.select.empty': 'Нет доступных компаний', + 'companies.select.selected': 'Выбранная компания', + }; + return translations[key] || key; + }, + i18n: { + changeLanguage: jest.fn(), + language: 'ru', + }, + }), + initReactI18next: { + type: '3rdParty', + init: jest.fn(), + }, +})); + +jest.mock('../../api/companyApi', () => { + return { + useGetCompaniesListQuery: jest.fn(() => ({ + data: mockCompanies, + isLoading: false, + isSuccess: true, + })), + }; +}); + +describe('CompanySelect component', () => { + const onChangeMock = jest.fn(); + + beforeEach(() => { + onChangeMock.mockClear(); + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + }); + + test('renders CompanySelect component', () => { + render(); + expect(screen.getByTestId('dropdown-select')).toBeInTheDocument(); + }); + + test('displays company list', async () => { + render(); + + const dropdown = screen.getByTestId('dropdown-select'); + + fireEvent.click(dropdown); + + const listbox = await screen.findByRole('listbox'); + + expect(listbox).toBeVisible(); + + await Promise.all( + companiesMock.data.map(async (company) => { + expect( + await screen.findByRole('option', { + name: company.title, + }), + ).toBeVisible(); + }), + ); + }); + + test('renders empty companies list', () => { + mockedQuery.mockReturnValueOnce({ + data: undefined, + isLoading: false, + isSuccess: true, + }); + + render(); + + expect(screen.getByTestId('dropdown-select')).toBeInTheDocument(); + }); + + test('select company', async () => { + render(); + + fireEvent.click(screen.getByTestId('dropdown-select')); + + const option = await screen.findByRole('option', { + name: 'YeaHub', + }); + + fireEvent.click(option); + + await waitFor(() => { + expect(onChangeMock).toHaveBeenCalledWith('1'); + }); + }); + + test('disabled select', () => { + render(); + + fireEvent.click(screen.getByTestId('dropdown-select')); + + expect(onChangeMock).not.toHaveBeenCalled(); + }); + + test('delete selected company', async () => { + render(); + + const chip = await screen.findByTestId('chip'); + + const deleteButton = chip.querySelector('.chip-delete-icon'); + + expect(deleteButton).toBeTruthy(); + + fireEvent.click(deleteButton!); + + await waitFor(() => { + expect(onChangeMock).toHaveBeenCalledWith(''); + }); + }); + + test('does not delete chip when disabled', async () => { + render(); + + const chip = await screen.findByTestId('chip'); + + const deleteButton = chip.querySelector('.chip-delete-icon'); + + expect(deleteButton).toBeTruthy(); + + fireEvent.click(deleteButton!); + + expect(onChangeMock).not.toHaveBeenCalled(); + }); + test('search input updates value', () => { + render(); + + const input = screen.getByRole('textbox'); + + fireEvent.change(input, { + target: { + value: 'Yea', + }, + }); + + expect(input).toHaveValue('Yea'); + + jest.advanceTimersByTime(500); + }); +});