|
2 | 2 | // SPDX-License-Identifier: Apache-2.0 |
3 | 3 |
|
4 | 4 | import React from 'react'; |
5 | | -import { act, fireEvent, render } from '@testing-library/react'; |
| 5 | +import { act, fireEvent, render as reactRender } from '@testing-library/react'; |
6 | 6 |
|
7 | 7 | import TestI18nProvider from '../../../lib/components/i18n/testing'; |
8 | 8 | import { useMobile } from '../../../lib/components/internal/hooks/use-mobile'; |
9 | | -import { FilteringOption, FilteringProperty, Ref } from '../../../lib/components/property-filter/interfaces'; |
| 9 | +import { FilteringOption, FilteringProperty } from '../../../lib/components/property-filter/interfaces'; |
10 | 10 | import PropertyFilterInternal, { PropertyFilterInternalProps } from '../../../lib/components/property-filter/internal'; |
11 | 11 | import createWrapper from '../../../lib/components/test-utils/dom'; |
12 | 12 | import { PropertyFilterWrapperInternal } from '../../../lib/components/test-utils/dom/property-filter'; |
13 | | -import { createDefaultProps, i18nStrings, i18nStringsTokenGroups, providedI18nStrings } from './common'; |
| 13 | +import { |
| 14 | + createDefaultProps, |
| 15 | + i18nStrings, |
| 16 | + i18nStringsTokenGroups, |
| 17 | + providedI18nStrings, |
| 18 | + StatefulInternalPropertyFilter, |
| 19 | +} from './common'; |
14 | 20 |
|
15 | 21 | jest.mock('../../../lib/components/internal/hooks/use-mobile', () => ({ |
16 | 22 | ...jest.requireActual('../../../lib/components/internal/hooks/use-mobile'), |
@@ -65,25 +71,22 @@ const filteringOptions: readonly FilteringOption[] = [ |
65 | 71 | { propertyKey: 'default-operator', value: 'value' }, |
66 | 72 | ]; |
67 | 73 |
|
68 | | -const defaultProps = { |
| 74 | +const defaultProps: PropertyFilterInternalProps = { |
69 | 75 | filteringOptions: [], |
70 | 76 | customGroupsText: [], |
71 | 77 | disableFreeTextFiltering: false, |
72 | 78 | i18nStringsTokenGroups, |
73 | 79 | ...createDefaultProps(filteringProperties, filteringOptions), |
74 | 80 | }; |
75 | 81 |
|
76 | | -function renderComponent( |
77 | | - props?: Partial<PropertyFilterInternalProps & { ref: React.Ref<Ref> }>, |
78 | | - withI18nProvider = false |
79 | | -) { |
| 82 | +function renderComponent(props?: Partial<PropertyFilterInternalProps>, withI18nProvider = false) { |
80 | 83 | return withI18nProvider |
81 | | - ? render( |
| 84 | + ? reactRender( |
82 | 85 | <TestI18nProvider messages={providedI18nStrings}> |
83 | 86 | <PropertyFilterInternal {...defaultProps} {...props} /> |
84 | 87 | </TestI18nProvider> |
85 | 88 | ) |
86 | | - : render(<PropertyFilterInternal {...defaultProps} {...props} />); |
| 89 | + : reactRender(<PropertyFilterInternal {...defaultProps} {...props} />); |
87 | 90 | } |
88 | 91 |
|
89 | 92 | function openEditor(tokenIndex: number, options: { expandToViewport?: boolean; isMobile?: boolean }) { |
@@ -438,6 +441,10 @@ describe('token editor with groups', () => { |
438 | 441 | return renderComponent({ enableTokenGroups: true, ...props }); |
439 | 442 | } |
440 | 443 |
|
| 444 | + function renderStateful(props?: Partial<PropertyFilterInternalProps>) { |
| 445 | + return reactRender(<StatefulInternalPropertyFilter {...defaultProps} {...props} enableTokenGroups={true} />); |
| 446 | + } |
| 447 | + |
441 | 448 | test('changes property name', () => { |
442 | 449 | const onChange = jest.fn(); |
443 | 450 | render({ |
@@ -735,6 +742,55 @@ describe('token editor with groups', () => { |
735 | 742 | } |
736 | 743 | ); |
737 | 744 |
|
| 745 | + test('moves focus to adjacent property when a filter is removed', () => { |
| 746 | + renderStateful({ |
| 747 | + query: { |
| 748 | + operation: 'and', |
| 749 | + tokenGroups: [{ operation: 'or', tokens: [tokenJohn, tokenJane, tokenJack] }], |
| 750 | + tokens: [], |
| 751 | + }, |
| 752 | + }); |
| 753 | + const editor = openEditor(0, { expandToViewport: false }); |
| 754 | + |
| 755 | + // Removing 2nd filter (Jane) |
| 756 | + editor.removeActions(2).actionsMenu.openDropdown(); |
| 757 | + editor.removeActions(2).removeAction().click(); |
| 758 | + |
| 759 | + // Focus is on new second filter (Jack) |
| 760 | + expect(editor.propertySelect(2).find('button')!.getElement()).toHaveFocus(); |
| 761 | + |
| 762 | + // Removing 2nd filter (Jack) |
| 763 | + editor.removeActions(2).actionsMenu.openDropdown(); |
| 764 | + editor.removeActions(2).removeFromGroupAction().click(); |
| 765 | + |
| 766 | + // Focus is on new first filter (John) |
| 767 | + expect(editor.propertySelect(1).find('button')!.getElement()).toHaveFocus(); |
| 768 | + }); |
| 769 | + |
| 770 | + test('moves focus to the new filter when it is added', () => { |
| 771 | + renderStateful({ |
| 772 | + query: { |
| 773 | + operation: 'and', |
| 774 | + tokenGroups: [{ operation: 'or', tokens: [tokenJohn] }, tokenJane], |
| 775 | + tokens: [], |
| 776 | + }, |
| 777 | + }); |
| 778 | + const editor = openEditor(0, { expandToViewport: false }); |
| 779 | + |
| 780 | + // Adding new filter |
| 781 | + editor.addActions!.findMainAction()!.click(); |
| 782 | + |
| 783 | + // Focus is on newly added 2nd filter |
| 784 | + expect(editor.propertySelect(2).find('button')!.getElement()).toHaveFocus(); |
| 785 | + |
| 786 | + // Adding standalone token (Jane) |
| 787 | + editor.addActions!.openDropdown(); |
| 788 | + editor.addActions!.findItems()[0].click(); |
| 789 | + |
| 790 | + // Focus is on newly added 3rd filter |
| 791 | + expect(editor.propertySelect(3).find('button')!.getElement()).toHaveFocus(); |
| 792 | + }); |
| 793 | + |
738 | 794 | test('standalone property menu items have indices as IDs', () => { |
739 | 795 | const onChange = jest.fn(); |
740 | 796 | render({ |
|
0 commit comments