From 429dec8a040da979f9e19f70b9f5d2ec60322410 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 20 Dec 2021 14:48:14 +0100 Subject: [PATCH 1/4] add describedby to styledradiogroup description Signed-off-by: Kerry Archibald --- .../views/elements/StyledRadioGroup.tsx | 3 +- .../views/elements/StyledRadioGroup-test.tsx | 115 +++++++++++++ .../StyledRadioGroup-test.tsx.snap | 152 ++++++++++++++++++ 3 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 test/components/views/elements/StyledRadioGroup-test.tsx create mode 100644 test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap diff --git a/src/components/views/elements/StyledRadioGroup.tsx b/src/components/views/elements/StyledRadioGroup.tsx index 1c3f5c10cd0..0571c64206d 100644 --- a/src/components/views/elements/StyledRadioGroup.tsx +++ b/src/components/views/elements/StyledRadioGroup.tsx @@ -61,10 +61,11 @@ function StyledRadioGroup({ value={d.value} disabled={d.disabled ?? disabled} outlined={outlined} + aria-describedby={d.description ? `${name}-${d.value}` : undefined} > { d.label } - { d.description ? { d.description } : null } + { d.description ? { d.description } : null } ) } ; } diff --git a/test/components/views/elements/StyledRadioGroup-test.tsx b/test/components/views/elements/StyledRadioGroup-test.tsx new file mode 100644 index 00000000000..b82920b92b9 --- /dev/null +++ b/test/components/views/elements/StyledRadioGroup-test.tsx @@ -0,0 +1,115 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +import "../../../skinned-sdk"; + +import React from 'react'; +import { mount } from 'enzyme'; +import { act } from "react-dom/test-utils"; + +import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup"; + +describe('', () => { + const optionA = { + value: 'Anteater', + label: Anteater label, + description: 'anteater description', + className: 'a-class', + }; + const optionB = { + value: 'Badger', + label: Badger label, + }; + const optionC = { + value: 'Canary', + label: Canary label, + description: Canary description, + }; + const defaultDefinitions = [optionA, optionB, optionC]; + const defaultProps = { + name: 'test', + className: 'test-class', + definitions: defaultDefinitions, + onChange: jest.fn(), + }; + const getComponent = (props = {}) => mount(); + + const getInputByValue = (component, value) => component.find(`input[value="${value}"]`); + const getCheckedInput = component => component.find('input[checked=true]'); + + it('renders radios correctly when no value is provided', () => { + const component = getComponent(); + + expect(component).toMatchSnapshot(); + expect(getCheckedInput(component).length).toBeFalsy(); + }); + + it('selects correct button when value is provided', () => { + const component = getComponent({ + value: optionC.value, + }); + + expect(getCheckedInput(component).at(0).props().value).toEqual(optionC.value); + }); + + it('selects correct buttons when definitions have checked prop', () => { + const definitions = [ + { ...optionA, checked: true }, + optionB, + { ...optionC, checked: false }, + ]; + const component = getComponent({ + value: optionC.value, definitions, + }); + + expect(getInputByValue(component, optionA.value).props().checked).toBeTruthy(); + expect(getInputByValue(component, optionB.value).props().checked).toBeFalsy(); + // optionC.checked = false overrides value matching + expect(getInputByValue(component, optionC.value).props().checked).toBeFalsy(); + }); + + it('disables individual buttons based on definition.disabled', () => { + const definitions = [ + optionA, + { ...optionB, disabled: true }, + { ...optionC, disabled: true }, + ]; + const component = getComponent({ definitions }); + expect(getInputByValue(component, optionA.value).props().disabled).toBeFalsy(); + expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); + expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); + }); + + it('disables all buttons with disabled prop', () => { + const component = getComponent({ disabled: true }); + expect(getInputByValue(component, optionA.value).props().disabled).toBeTruthy(); + expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); + expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); + }); + + it('calls onChange on click', () => { + const onChange = jest.fn(); + const component = getComponent({ + value: optionC.value, + onChange, + }); + + act(() => { + getInputByValue(component, optionB.value).simulate('change'); + }); + + expect(onChange).toHaveBeenCalledWith(optionB.value); + }); +}); diff --git a/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap b/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap new file mode 100644 index 00000000000..d5d47648cca --- /dev/null +++ b/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap @@ -0,0 +1,152 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders radios correctly when no value is provided 1`] = ` + + Anteater label + , + "value": "Anteater", + }, + Object { + "label": + Badger label + , + "value": "Badger", + }, + Object { + "description": + Canary description + , + "label": + Canary label + , + "value": "Canary", + }, + ] + } + name="test" + onChange={[MockFunction]} +> + +