From 1a9448bfd6ecba29ee55e17343a67e458f54d7bc Mon Sep 17 00:00:00 2001 From: DenisPopkov06 Date: Tue, 21 Apr 2026 00:48:00 +0300 Subject: [PATCH 1/2] YH-1875: add tests for OrderFilter component --- .../ui/OrderFilter/OrderFilter.test.tsx | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/shared/ui/OrderFilter/OrderFilter.test.tsx diff --git a/src/shared/ui/OrderFilter/OrderFilter.test.tsx b/src/shared/ui/OrderFilter/OrderFilter.test.tsx new file mode 100644 index 000000000..9b86736ea --- /dev/null +++ b/src/shared/ui/OrderFilter/OrderFilter.test.tsx @@ -0,0 +1,146 @@ +import { fireEvent, render, screen } from '@testing-library/react'; + +import { OrderFilter } from './OrderFilter'; + +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => { + const translations: Record = { + 'sort.title': 'Сортировать по', + 'sort.ascending': 'Возрастанию', + 'sort.descending': 'Убыванию', + }; + return translations[key] || key; + }, + }), +})); + +jest.mock('@/shared/config', () => ({ + i18Namespace: { + translation: 'translation', + }, + Translation: { + SORT_TITLE: 'sort.title', + SORT_ASCENDING: 'sort.ascending', + SORT_DESCENDING: 'sort.descending', + }, +})); + +jest.mock('@/shared/ui/BaseFilterSection', () => ({ + BaseFilterSection: ({ + data, + title, + onClick, + }: { + title: string; + data: Array<{ id: T; title: string; active?: boolean }>; + onClick?: (id: T) => void; + }) => ( +
+
{title}
+ {data.map((item) => ( + + ))} +
+ ), +})); + +const mockChangeOrder = jest.fn(); + +const renderOrderFilter = (props = {}) => { + const defaultProps = { + changeOrder: mockChangeOrder, + selectedOrder: undefined, + }; + + return render(); +}; + +describe('OrderFilter', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Rendering', () => { + test('renders BaseFilterSection', () => { + renderOrderFilter(); + expect(screen.getByTestId('base-filter-section')).toBeInTheDocument(); + }); + + test('renders both ASC and DESC options', () => { + renderOrderFilter(); + expect(screen.getByTestId('filter-ASC')).toBeInTheDocument(); + expect(screen.getByTestId('filter-DESC')).toBeInTheDocument(); + }); + + test('renders correct titles from translations', () => { + renderOrderFilter(); + expect(screen.getByTestId('filter-ASC')).toHaveTextContent('Возрастанию'); + expect(screen.getByTestId('filter-DESC')).toHaveTextContent('Убыванию'); + expect(screen.getByTestId('filter-title')).toHaveTextContent('Сортировать по'); + }); + + test('sets active correctly when no order selected', () => { + renderOrderFilter({ selectedOrder: undefined }); + expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'false'); + expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'false'); + }); + + test('sets active correctly when ASC is selected', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'true'); + expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'false'); + }); + + test('sets active correctly when DESC is selected', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'false'); + expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'true'); + }); + }); + + describe('Interactions', () => { + test('calls changeOrder with ASC when clicking on ASC option', () => { + renderOrderFilter({ selectedOrder: undefined }); + fireEvent.click(screen.getByTestId('filter-ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); + }); + + test('calls changeOrder with DESC when clicking on DESC option', () => { + renderOrderFilter({ selectedOrder: undefined }); + fireEvent.click(screen.getByTestId('filter-DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); + }); + + test('calls changeOrder with undefined when clicking on already selected ASC', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + fireEvent.click(screen.getByTestId('filter-ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith(undefined); + }); + + test('calls changeOrder with undefined when clicking on already selected DESC', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + fireEvent.click(screen.getByTestId('filter-DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith(undefined); + }); + + test('switches from ASC to DESC correctly', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + fireEvent.click(screen.getByTestId('filter-DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); + }); + + test('switches from DESC to ASC correctly', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + fireEvent.click(screen.getByTestId('filter-ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); + }); + }); +}); From 4b8f48da7637f0194ba9f2d39e2312d3da0ccc92 Mon Sep 17 00:00:00 2001 From: DenisPopkov06 Date: Mon, 27 Apr 2026 01:21:05 +0300 Subject: [PATCH 2/2] YH-1875: added OrderFilter unit tests --- .../ui/OrderFilter/OrderFilter.test.tsx | 247 ++++++++---------- 1 file changed, 113 insertions(+), 134 deletions(-) diff --git a/src/shared/ui/OrderFilter/OrderFilter.test.tsx b/src/shared/ui/OrderFilter/OrderFilter.test.tsx index 9b86736ea..5724569d4 100644 --- a/src/shared/ui/OrderFilter/OrderFilter.test.tsx +++ b/src/shared/ui/OrderFilter/OrderFilter.test.tsx @@ -1,146 +1,125 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { fireEvent, screen } from '@testing-library/react'; +import { renderComponent } from '@/shared/libs/jest/renderComponent'; import { OrderFilter } from './OrderFilter'; -jest.mock('react-i18next', () => ({ - useTranslation: () => ({ - t: (key: string) => { - const translations: Record = { - 'sort.title': 'Сортировать по', - 'sort.ascending': 'Возрастанию', - 'sort.descending': 'Убыванию', - }; - return translations[key] || key; - }, - }), -})); - -jest.mock('@/shared/config', () => ({ - i18Namespace: { - translation: 'translation', - }, - Translation: { - SORT_TITLE: 'sort.title', - SORT_ASCENDING: 'sort.ascending', - SORT_DESCENDING: 'sort.descending', - }, -})); - jest.mock('@/shared/ui/BaseFilterSection', () => ({ - BaseFilterSection: ({ - data, - title, - onClick, - }: { - title: string; - data: Array<{ id: T; title: string; active?: boolean }>; - onClick?: (id: T) => void; - }) => ( -
-
{title}
- {data.map((item) => ( - - ))} -
- ), + BaseFilterSection: ({ + data, + title, + onClick, + }: { + title: string; + data: Array<{ id: T; title: string; active?: boolean }>; + onClick?: (id: T) => void; + }) => ( +
+
{title}
+ {data.map((item) => ( + + ))} +
+ ), })); const mockChangeOrder = jest.fn(); const renderOrderFilter = (props = {}) => { - const defaultProps = { - changeOrder: mockChangeOrder, - selectedOrder: undefined, - }; - - return render(); + const defaultProps = { + changeOrder: mockChangeOrder, + selectedOrder: undefined, + }; + + return renderComponent( + + ); }; describe('OrderFilter', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('Rendering', () => { - test('renders BaseFilterSection', () => { - renderOrderFilter(); - expect(screen.getByTestId('base-filter-section')).toBeInTheDocument(); - }); - - test('renders both ASC and DESC options', () => { - renderOrderFilter(); - expect(screen.getByTestId('filter-ASC')).toBeInTheDocument(); - expect(screen.getByTestId('filter-DESC')).toBeInTheDocument(); - }); - - test('renders correct titles from translations', () => { - renderOrderFilter(); - expect(screen.getByTestId('filter-ASC')).toHaveTextContent('Возрастанию'); - expect(screen.getByTestId('filter-DESC')).toHaveTextContent('Убыванию'); - expect(screen.getByTestId('filter-title')).toHaveTextContent('Сортировать по'); - }); - - test('sets active correctly when no order selected', () => { - renderOrderFilter({ selectedOrder: undefined }); - expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'false'); - expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'false'); - }); - - test('sets active correctly when ASC is selected', () => { - renderOrderFilter({ selectedOrder: 'ASC' }); - expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'true'); - expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'false'); - }); - - test('sets active correctly when DESC is selected', () => { - renderOrderFilter({ selectedOrder: 'DESC' }); - expect(screen.getByTestId('filter-ASC')).toHaveAttribute('data-active', 'false'); - expect(screen.getByTestId('filter-DESC')).toHaveAttribute('data-active', 'true'); - }); - }); - - describe('Interactions', () => { - test('calls changeOrder with ASC when clicking on ASC option', () => { - renderOrderFilter({ selectedOrder: undefined }); - fireEvent.click(screen.getByTestId('filter-ASC')); - expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); - }); - - test('calls changeOrder with DESC when clicking on DESC option', () => { - renderOrderFilter({ selectedOrder: undefined }); - fireEvent.click(screen.getByTestId('filter-DESC')); - expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); - }); - - test('calls changeOrder with undefined when clicking on already selected ASC', () => { - renderOrderFilter({ selectedOrder: 'ASC' }); - fireEvent.click(screen.getByTestId('filter-ASC')); - expect(mockChangeOrder).toHaveBeenCalledWith(undefined); - }); - - test('calls changeOrder with undefined when clicking on already selected DESC', () => { - renderOrderFilter({ selectedOrder: 'DESC' }); - fireEvent.click(screen.getByTestId('filter-DESC')); - expect(mockChangeOrder).toHaveBeenCalledWith(undefined); - }); - - test('switches from ASC to DESC correctly', () => { - renderOrderFilter({ selectedOrder: 'ASC' }); - fireEvent.click(screen.getByTestId('filter-DESC')); - expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); - }); - - test('switches from DESC to ASC correctly', () => { - renderOrderFilter({ selectedOrder: 'DESC' }); - fireEvent.click(screen.getByTestId('filter-ASC')); - expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); - }); - }); -}); + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Rendering', () => { + test('renders BaseFilterSection', () => { + renderOrderFilter(); + expect(screen.getByTestId('OrderFilter_Section')).toBeInTheDocument(); + }); + + test('renders both ASC and DESC options', () => { + renderOrderFilter(); + expect(screen.getByTestId('OrderFilter_ASC')).toBeInTheDocument(); + expect(screen.getByTestId('OrderFilter_DESC')).toBeInTheDocument(); + }); + + test('renders correct titles from translations', () => { + renderOrderFilter(); + expect(screen.getByTestId('OrderFilter_ASC')).toHaveTextContent('sort.ascending'); + expect(screen.getByTestId('OrderFilter_DESC')).toHaveTextContent('sort.descending'); + expect(screen.getByTestId('OrderFilter_Title')).toHaveTextContent('sort.title'); + }); + + test('sets active correctly when no order selected', () => { + renderOrderFilter({ selectedOrder: undefined }); + expect(screen.getByTestId('OrderFilter_ASC')).toHaveAttribute('data-active', 'false'); + expect(screen.getByTestId('OrderFilter_DESC')).toHaveAttribute('data-active', 'false'); + }); + + test('sets active correctly when ASC is selected', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + expect(screen.getByTestId('OrderFilter_ASC')).toHaveAttribute('data-active', 'true'); + expect(screen.getByTestId('OrderFilter_DESC')).toHaveAttribute('data-active', 'false'); + }); + + test('sets active correctly when DESC is selected', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + expect(screen.getByTestId('OrderFilter_ASC')).toHaveAttribute('data-active', 'false'); + expect(screen.getByTestId('OrderFilter_DESC')).toHaveAttribute('data-active', 'true'); + }); + }); + + describe('Interactions', () => { + test('calls changeOrder with ASC when clicking on ASC option', () => { + renderOrderFilter({ selectedOrder: undefined }); + fireEvent.click(screen.getByTestId('OrderFilter_ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); + }); + + test('calls changeOrder with DESC when clicking on DESC option', () => { + renderOrderFilter({ selectedOrder: undefined }); + fireEvent.click(screen.getByTestId('OrderFilter_DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); + }); + + test('calls changeOrder with undefined when clicking on already selected ASC', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + fireEvent.click(screen.getByTestId('OrderFilter_ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith(undefined); + }); + + test('calls changeOrder with undefined when clicking on already selected DESC', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + fireEvent.click(screen.getByTestId('OrderFilter_DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith(undefined); + }); + + test('switches from ASC to DESC correctly', () => { + renderOrderFilter({ selectedOrder: 'ASC' }); + fireEvent.click(screen.getByTestId('OrderFilter_DESC')); + expect(mockChangeOrder).toHaveBeenCalledWith('DESC'); + }); + + test('switches from DESC to ASC correctly', () => { + renderOrderFilter({ selectedOrder: 'DESC' }); + fireEvent.click(screen.getByTestId('OrderFilter_ASC')); + expect(mockChangeOrder).toHaveBeenCalledWith('ASC'); + }); + }); +}); \ No newline at end of file