Skip to content

Commit 6ab2d39

Browse files
evanyan13Evan Yan
andauthored
[CDX-232] Bugfix: Filter selection for facets with duplicate option values (#180)
* Update selectedOptionMap to use facet.name:option.value * Update tests for Filters * Update implementation * Update implementation * Lint --------- Co-authored-by: Evan Yan <evan.yan@constructor.io>
1 parent 9f0eacd commit 6ab2d39

File tree

4 files changed

+98
-7
lines changed

4 files changed

+98
-7
lines changed

spec/components/Filters/Filters.test.jsx

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,55 @@ import { getStateFromUrl } from '../../../src/utils';
1010

1111
const filterProps = { facets: mockTransformedFacets };
1212

13+
const mockFacetsWithDuplicateValues = [
14+
{
15+
displayName: 'Size',
16+
name: 'size',
17+
type: 'multiple',
18+
data: {},
19+
hidden: false,
20+
options: [
21+
{
22+
status: '',
23+
count: 28,
24+
displayName: '0',
25+
value: '0',
26+
data: {},
27+
},
28+
{
29+
status: '',
30+
count: 229,
31+
displayName: '1',
32+
value: '1',
33+
data: {},
34+
},
35+
],
36+
},
37+
{
38+
displayName: 'Rating',
39+
name: 'rating',
40+
type: 'multiple',
41+
data: {},
42+
hidden: false,
43+
options: [
44+
{
45+
status: '',
46+
count: 7,
47+
displayName: '0',
48+
value: '0',
49+
data: {},
50+
},
51+
{
52+
status: '',
53+
count: 29,
54+
displayName: '1',
55+
value: '1',
56+
data: {},
57+
},
58+
],
59+
},
60+
];
61+
1362
describe('Testing Component: Filters', () => {
1463
const originalWindowLocation = window.location;
1564

@@ -90,14 +139,19 @@ describe('Testing Component: Filters', () => {
90139
const colorFacetData = mockTransformedFacets.find(
91140
(facetGroup) => facetGroup.displayName === 'Color',
92141
);
142+
93143
const selectedOption = colorFacetData.options.find((option) => option.status === 'selected');
94-
expect(container.querySelector(`#${selectedOption.value}:checked`)).not.toBeNull();
144+
expect(
145+
container.querySelector(`input[id=${colorFacetData.name}-${selectedOption.value}]`),
146+
).toBeChecked();
95147

96148
const newSelectedOption = colorFacetData.options.find(
97149
(option) => option.status !== 'selected',
98150
);
99151
fireEvent.click(getByText(newSelectedOption.value));
100-
expect(container.querySelector(`#${newSelectedOption.value}:checked`)).not.toBeNull();
152+
expect(
153+
container.querySelector(`input[id=${colorFacetData.name}-${newSelectedOption.value}]`),
154+
).toBeChecked();
101155
});
102156

103157
it('Should render correctly with render props', () => {
@@ -416,6 +470,32 @@ describe('Testing Component: Filters', () => {
416470
expect(updatedFiltersWithTwoSelected.color.includes(newSelectedOption.value)).toBe(true);
417471
});
418472

473+
it('OptionsList: Should handle duplicate option values between different facets correctly', async () => {
474+
const { container } = render(
475+
<CioPlp apiKey={DEMO_API_KEY}>
476+
<Filters facets={mockFacetsWithDuplicateValues} />
477+
</CioPlp>,
478+
);
479+
480+
const sizeZeroCheckbox = container.querySelector('input[id="size-0"]');
481+
const ratingZeroCheckbox = container.querySelector('input[id="rating-0"]');
482+
483+
// Select "0" option in Size facet
484+
fireEvent.click(sizeZeroCheckbox);
485+
expect(sizeZeroCheckbox).toBeChecked();
486+
expect(ratingZeroCheckbox).not.toBeChecked();
487+
488+
// Select "0" option in Rating facet
489+
fireEvent.click(ratingZeroCheckbox);
490+
expect(sizeZeroCheckbox).toBeChecked();
491+
expect(ratingZeroCheckbox).toBeChecked();
492+
493+
// Deselect "0" option in Size facet
494+
fireEvent.click(sizeZeroCheckbox);
495+
expect(sizeZeroCheckbox).not.toBeChecked();
496+
expect(ratingZeroCheckbox).toBeChecked();
497+
});
498+
419499
it('SliderRange: Upon updating the input, requestFilters should not be updated if not blurred', async () => {
420500
const { container } = render(<TestFiltersApplied />);
421501

src/components/Filters/FilterOptionListRow.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,34 @@ import React from 'react';
22

33
export interface FilterOptionListRowProps {
44
id: string;
5+
optionValue: string;
56
displayValue: string;
67
displayCountValue: string;
78
isChecked: boolean;
8-
onChange: (id: string) => void;
9+
onChange: (value: string) => void;
910
showCheckbox?: boolean;
1011
}
1112

1213
export default function FilterOptionListRow(props: FilterOptionListRowProps) {
13-
const { id, displayValue, displayCountValue, isChecked, onChange, showCheckbox = true } = props;
14+
const {
15+
id,
16+
optionValue,
17+
displayValue,
18+
displayCountValue,
19+
isChecked,
20+
onChange,
21+
showCheckbox = true,
22+
} = props;
1423

1524
return (
1625
<li className='cio-filter-multiple-option' key={id}>
1726
<label htmlFor={id}>
1827
<input
1928
type='checkbox'
2029
id={id}
21-
value={displayValue}
30+
value={optionValue}
2231
checked={isChecked}
23-
onChange={() => onChange(id)}
32+
onChange={() => onChange(optionValue)}
2433
/>
2534
{showCheckbox && (
2635
<div className='cio-checkbox'>

src/components/Filters/FilterOptionsList.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export default function FilterOptionsList(props: UseFilterOptionsListProps) {
2525
<ul className='cio-filter-multiple-options-list cio-collapsible-inner'>
2626
{optionsToRender.map((option) => (
2727
<FilterOptionListRow
28-
id={option.value}
28+
id={`${facet.name}-${option.value}`}
29+
optionValue={option.value}
2930
displayValue={option.displayName}
3031
displayCountValue={option.count.toString()}
3132
isChecked={selectedOptionMap[option.value] || false}

src/components/Groups/Groups.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export default function Groups(props: GroupsWithRenderProps) {
6767
showCheckbox={false}
6868
key={option.groupId}
6969
id={option.groupId}
70+
optionValue={option.groupId}
7071
displayValue={option.displayName}
7172
displayCountValue={option.count.toString()}
7273
isChecked={selectedGroupId === option.groupId}

0 commit comments

Comments
 (0)