import React from 'react';
import { act, fireEvent, render } from '@testing-library/react';
import { axe } from 'jest-axe';
import { getTestUtils } from '../utils/getTestUtils';
import Checkbox from '..';
const className = 'test-classname';
const onChange = jest.fn();
const onClick = jest.fn();
function renderCheckbox(props = {}) {
const renderUtils = render(
,
);
const utils = getTestUtils();
const wrapper = renderUtils.container.firstElementChild;
const checkbox = utils.getInput();
const label = utils.getLabel();
return { ...renderUtils, ...utils, wrapper, checkbox, label };
}
describe('packages/checkbox', () => {
describe('a11y', () => {
test('does not have basic accessibility violations', async () => {
const { container, checkbox } = renderCheckbox();
const results = await axe(container);
expect(results).toHaveNoViolations();
let newResults = null as any;
act(() => void fireEvent.click(checkbox));
await act(async () => {
newResults = await axe(container);
});
expect(newResults).toHaveNoViolations();
});
});
test('uses the aria-label prop when supplied', () => {
const { checkbox } = renderCheckbox({ 'aria-label': 'test string' });
expect(checkbox.getAttribute('aria-label')).toBe('test string');
});
test(`passes \`className\` through to checkbox parent`, () => {
const { wrapper } = renderCheckbox({ className });
expect(wrapper?.classList).toContain(className);
});
test('renders as unchecked by default', () => {
const { checkbox, getInputValue } = renderCheckbox();
expect(getInputValue()).toBe(false);
expect(checkbox.getAttribute('aria-checked')).toBe('false');
});
test('renders as checked when defaultChecked prop is set', () => {
const { checkbox, getInputValue } = renderCheckbox({
defaultChecked: true,
});
expect(getInputValue()).toBe(true);
expect(checkbox.getAttribute('aria-checked')).toBe('true');
});
test('renders as checked when the prop is set', () => {
const { checkbox, getInputValue } = renderCheckbox({ checked: true });
expect(getInputValue()).toBe(true);
expect(checkbox.getAttribute('aria-checked')).toBe('true');
});
test('renders with aria-disabled attribute but not disabled attribute when disabled prop is set', () => {
const { checkbox, isDisabled } = renderCheckbox({ disabled: true });
expect(isDisabled).toBeTruthy();
expect(checkbox.getAttribute('disabled')).toBeFalsy();
});
test('does not fire onClick events when disabled', () => {
const onClick = jest.fn();
const { getInput } = renderCheckbox({ onClick, disabled: true });
const input = getInput();
fireEvent.click(input);
expect(onClick).not.toHaveBeenCalled();
});
test('does not fire onChange events when disabled', () => {
const onChange = jest.fn();
const { getInput } = renderCheckbox({ onChange, disabled: true });
const input = getInput();
fireEvent.click(input);
expect(onChange).not.toHaveBeenCalled();
});
test('renders as indeterminate when the prop is set', () => {
const { checkbox } = renderCheckbox({ indeterminate: true });
expect(checkbox.getAttribute('aria-checked')).toBe('mixed');
});
test('renders as indeterminate when prop is set and checkbox is true', () => {
const { checkbox, getInputValue, rerender } = renderCheckbox({
indeterminate: true,
checked: true,
});
expect(checkbox.getAttribute('aria-checked')).toBe('mixed');
rerender(
,
);
expect(checkbox.getAttribute('aria-checked')).toBe('true');
expect(getInputValue()).toBe(true);
});
describe('when controlled', () => {
test('onClick fires once when the label is clicked', () => {
const { label } = renderCheckbox({ onClick, checked: false });
fireEvent.click(label!);
expect(onClick).toHaveBeenCalledTimes(1);
});
test('onChange fires once when the label is clicked', () => {
const { label } = renderCheckbox({ onChange, checked: false });
fireEvent.click(label!);
expect(onChange).toHaveBeenCalledTimes(1);
});
test('checkbox does not become checked when clicked', () => {
const { checkbox, getInputValue } = renderCheckbox({ checked: false });
fireEvent.click(checkbox);
expect(getInputValue()).toBe(false);
});
});
describe('when uncontrolled', () => {
const uncontrolledOnClick = jest.fn();
const uncontrolledOnChange = jest.fn();
test('onClick fires once when the label is clicked', () => {
const { label } = renderCheckbox({ onClick: uncontrolledOnClick });
fireEvent.click(label!);
expect(uncontrolledOnClick).toHaveBeenCalledTimes(1);
});
test('onChange fires once when the label is clicked', () => {
const { label } = renderCheckbox({ onChange: uncontrolledOnChange });
fireEvent.click(label!);
expect(uncontrolledOnChange).toHaveBeenCalledTimes(1);
});
test('checkbox becomes checked when clicked', () => {
const { checkbox, getInputValue } = renderCheckbox({});
fireEvent.click(checkbox);
expect(getInputValue()).toBe(true);
});
test('checkbox becomes unchecked when clicked if defaultChecked is set', () => {
const { checkbox, getInputValue } = renderCheckbox({
defaultChecked: true,
});
fireEvent.click(checkbox);
expect(getInputValue()).toBe(false);
});
});
});