Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: select an option when there are several radio-group #882

6 changes: 3 additions & 3 deletions projects/ion/src/lib/radio-group/radio-group.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<div class="ion-input-radio" *ngFor="let option of options; let i = index">
<input
type="radio"
[attr.data-testid]="'radio-' + i"
[attr.data-testid]="name + '-radio-' + i"
[class.radio]="value !== option.value"
[class.radio-checked]="value === option.value"
[id]="'radio-' + i"
[id]="name + '-radio-' + i"
[name]="name"
[value]="option.value"
[checked]="value === option.value"
Expand All @@ -15,7 +15,7 @@
<label
[class.labelDisabled]="!option.disabled"
[class.labelDisabled-checked]="option.disabled"
[for]="'radio-' + i"
[for]="name + '-radio-' + i"
>{{ option.label }}</label
>
</div>
Expand Down
133 changes: 123 additions & 10 deletions projects/ion/src/lib/radio-group/radio-group.component.spec.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that make sense create a new case with two radio groups with differents names and check select one radio item.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well thought!

Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { render, screen } from '@testing-library/angular';
import { render, screen, fireEvent } from '@testing-library/angular';
import { IonRadioGroupComponent } from './radio-group.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import userEvent from '@testing-library/user-event';
import { ComponentFixture } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RadioOptions } from '../core/types/radio-group';
import { NgModule, Component } from '@angular/core';
import { IonRadioGroupModule } from './radio-group.module';

const radioGroupName = 'group';
const radioGroupValue = '';
Expand Down Expand Up @@ -55,18 +57,18 @@ describe('IonRadioGroup', () => {
)('radio option $index', ({ label, value, index }) => {
let radio: HTMLElement;
beforeEach(() => {
radio = document.getElementById(`radio-${index}`);
radio = document.getElementById(`${radioGroupName}-radio-${index}`);
});
it(`should render a radio with id as radio-${index}`, () => {
it(`should render a radio with id as ${radioGroupName}-radio-${index}`, () => {
expect(radio).toBeInTheDocument();
});
it(`should render a radio with label ${label}`, () => {
expect(screen.getByLabelText(label)).toBeInTheDocument();
});
it(`should render radio-${index} with radio group name`, () => {
it(`should render ${radioGroupName}-radio-${index} with radio group name`, () => {
expect(radio).toHaveAttribute('name', radioGroupName);
});
it(`should render radio-${index} with value '${value}'`, () => {
it(`should render ${radioGroupName}-radio-${index} with value '${value}'`, () => {
expect(radio).toHaveAttribute('value', value.toString());
});
it('should be unchecked by default', () => {
Expand All @@ -78,8 +80,8 @@ describe('IonRadioGroup', () => {
});
});
it('only one radio in the group should be checked', () => {
const firstOption = document.getElementById('radio-0');
const secondOption = document.getElementById('radio-1');
const firstOption = document.getElementById(`${radioGroupName}-radio-0`);
const secondOption = document.getElementById(`${radioGroupName}-radio-1`);

userEvent.click(firstOption);
expect(firstOption).toBeChecked();
Expand All @@ -91,14 +93,125 @@ describe('IonRadioGroup', () => {
});
it('should change value', () => {
const spyEmit = jest.spyOn(fixture.componentInstance.valueChange, 'emit');
const firstOption = document.getElementById('radio-0');
const firstOption = document.getElementById(`${radioGroupName}-radio-0`);

userEvent.click(firstOption);
expect(spyEmit).toHaveBeenCalled();
expect(spyEmit).toHaveBeenCalledWith(options[0].value);
});
it('should render option disabled', () => {
rerender({ options: [{ ...options[0], disabled: true }] });
expect(document.getElementById('radio-0')).toBeDisabled();
expect(document.getElementById(`${radioGroupName}-radio-0`)).toBeDisabled();
});
});

@Component({
template: `
<section style="display: flex; gap: 16px; flex-direction: column">
<div>
<h3>Please select your preferred contact method:</h3>
<ion-radio-group
[name]="contactMethod.name"
[options]="contactMethod.options"
></ion-radio-group>
</div>

<div>
<h3>Please select your favorite Web language:</h3>
<ion-radio-group
[name]="languages.name"
[options]="languages.options"
></ion-radio-group>
</div>
</section>
`,
})
class RadioGroupTestComponent {
contactMethod = {
name: 'contact-mathod',
options: [
{
label: 'Email',
value: 'email',
},
{
label: 'Phone',
value: 'phone',
},
{
label: 'Mail',
value: 'mail',
},
],
};
languages = {
name: 'language',
options: [
{
label: 'HTML',
value: 'html',
},
{
label: 'CSS',
value: 'css',
},
{
label: 'Javascript',
value: 'javascript',
},
],
};
}

@NgModule({
declarations: [RadioGroupTestComponent],
imports: [CommonModule, IonRadioGroupModule],
})
class RadioGroupTestModule {}

describe('IonRadioGroup - selecting an option when there are several ion-radio-group', () => {
let component: RadioGroupTestComponent;
let fixture: ComponentFixture<RadioGroupTestComponent>;

beforeEach(async () => {
TestBed.configureTestingModule({
imports: [RadioGroupTestModule],
}).compileComponents();
fixture = TestBed.createComponent(RadioGroupTestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

afterEach(async () => {
fixture.destroy();
});

it('should select the option by clicking on the HTML text and should not select any other option', () => {
const languageOptions = [
document.getElementById(`${component.languages.name}-radio-0`),
document.getElementById(`${component.languages.name}-radio-1`),
document.getElementById(`${component.languages.name}-radio-2`),
];

const contactMethodOptions = [
document.getElementById(`${component.contactMethod.name}-radio-0`),
document.getElementById(`${component.contactMethod.name}-radio-1`),
document.getElementById(`${component.contactMethod.name}-radio-2`),
];

const optionToSelect = languageOptions[0];
const htmlOption = screen.getByLabelText(
component.languages.options[0].label
);
fireEvent.click(htmlOption);
expect(optionToSelect).toBeChecked();

languageOptions.slice(1).forEach((option) => {
expect(option).not.toBeChecked();
});

contactMethodOptions.forEach((option) => {
expect(option).not.toBeChecked();
});
});
});
Loading