fix: Duplicated numeric values in Select (#21480)

This commit is contained in:
Michael S. Molina 2022-09-16 08:39:27 -03:00 committed by GitHub
parent 7c3fc67315
commit b739e27f6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 5 deletions

View File

@ -98,6 +98,11 @@ const findSelectOption = (text: string) =>
within(getElementByClassName('.rc-virtual-list')).getByText(text),
);
const querySelectOption = (text: string) =>
waitFor(() =>
within(getElementByClassName('.rc-virtual-list')).queryByText(text),
);
const findAllSelectOptions = () =>
waitFor(() => getElementsByClassName('.ant-select-item-option-content'));
@ -736,6 +741,21 @@ test('renders a helper text when one is provided', async () => {
expect(screen.queryByText(helperText)).toBeInTheDocument();
});
test('finds an element with a numeric value and does not duplicate the options', async () => {
const options = jest.fn(async () => ({
data: [
{ label: 'a', value: 11 },
{ label: 'b', value: 12 },
],
totalCount: 2,
}));
render(<AsyncSelect {...defaultProps} options={options} allowNewOptions />);
await open();
await type('11');
expect(await findSelectOption('a')).toBeInTheDocument();
expect(await querySelectOption('11')).not.toBeInTheDocument();
});
/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available

View File

@ -77,6 +77,11 @@ const findSelectOption = (text: string) =>
within(getElementByClassName('.rc-virtual-list')).getByText(text),
);
const querySelectOption = (text: string) =>
waitFor(() =>
within(getElementByClassName('.rc-virtual-list')).queryByText(text),
);
const findAllSelectOptions = () =>
waitFor(() => getElementsByClassName('.ant-select-item-option-content'));
@ -549,6 +554,18 @@ test('renders a helper text when one is provided', async () => {
expect(screen.queryByText(helperText)).toBeInTheDocument();
});
test('finds an element with a numeric value and does not duplicate the options', async () => {
const options = [
{ label: 'a', value: 11 },
{ label: 'b', value: 12 },
];
render(<Select {...defaultProps} options={options} allowNewOptions />);
await open();
await type('11');
expect(await findSelectOption('a')).toBeInTheDocument();
expect(await querySelectOption('11')).not.toBeInTheDocument();
});
/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available

View File

@ -96,20 +96,26 @@ export function getValue(
return isLabeledValue(option) ? option.value : option;
}
type LabeledValue<V> = { label?: ReactNode; value?: V };
type V = string | number | null | undefined;
export function hasOption<V>(
type LabeledValue = { label?: ReactNode; value?: V };
export function hasOption(
value: V,
options?: V | LabeledValue<V> | (V | LabeledValue<V>)[],
options?: V | LabeledValue | (V | LabeledValue)[],
checkLabel = false,
): boolean {
const optionsArray = ensureIsArray(options);
// When comparing the values we use the equality
// operator to automatically convert different types
return (
optionsArray.find(
x =>
x === value ||
// eslint-disable-next-line eqeqeq
x == value ||
(isObject(x) &&
(('value' in x && x.value === value) ||
// eslint-disable-next-line eqeqeq
(('value' in x && x.value == value) ||
(checkLabel && 'label' in x && x.label === value))),
) !== undefined
);