Skip to content

Commit

Permalink
WIP tests
Browse files Browse the repository at this point in the history
Co-authored-by: sirineJ <[email protected]>
  • Loading branch information
connor-baer and sirineJ committed Oct 18, 2024
1 parent b7f8cc9 commit 35dcf3a
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 17 deletions.
136 changes: 120 additions & 16 deletions packages/circuit-ui/components/DateInput/DateInput.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,11 @@
* limitations under the License.
*/

import { describe, expect, it, vi } from 'vitest';
import { beforeAll, describe, expect, it, vi } from 'vitest';
import { createRef } from 'react';
import MockDate from 'mockdate';

import {
render,
screen,
axe,
userEvent,
fireEvent,
} from '../../util/test-utils.js';
import { render, screen, axe, userEvent } from '../../util/test-utils.js';

import { DateInput } from './DateInput.js';

Expand All @@ -36,25 +31,43 @@ describe('DateInput', () => {
closeCalendarButtonLabel: 'Close',
applyDateButtonLabel: 'Apply',
clearDateButtonLabel: 'Clear',
yearInputLabel: 'Year',
monthInputLabel: 'Month',
dayInputLabel: 'Day',
};

beforeAll(() => {
MockDate.set('2000-01-01');
});

// TODO: Move ref to outermost div?
it('should forward a ref', () => {
const ref = createRef<HTMLInputElement>();
const ref = createRef<HTMLFieldSetElement>();
render(<DateInput {...baseProps} ref={ref} />);
const input = screen.getByRole('textbox');
expect(ref.current).toBe(input);
const fieldset = screen.getByRole('group');
expect(ref.current).toBe(fieldset);
});

it('should merge a custom class name with the default ones', () => {
const className = 'foo';
const { container } = render(
<DateInput {...baseProps} className={className} />,
);
// eslint-disable-next-line testing-library/no-container
const wrapper = container.querySelectorAll('div')[0];
expect(wrapper?.className).toContain(className);
});

it('should select a calendar date', async () => {
render(<DateInput {...baseProps} />);
const onChange = vi.fn();

render(<DateInput {...baseProps} onChange={onChange} />);

const input: HTMLInputElement = screen.getByRole('textbox');
const openCalendarButton = screen.getByRole('button', {
name: /change date/i,
});

// For some reason, userEvent doesn't work here.
fireEvent.click(openCalendarButton);
await userEvent.click(openCalendarButton);

const calendarDialog = screen.getByRole('dialog');

Expand All @@ -64,7 +77,98 @@ describe('DateInput', () => {

await userEvent.click(dateButton);

expect(input).toHaveValue('2024-10-12');
expect(onChange).toHaveBeenCalledWith('2000-01-12');
});

it('should display the initial value correctly', () => {
render(<DateInput {...baseProps} value="2000-01-12" />);

expect(screen.getByLabelText(/day/i)).toHaveValue(12);
expect(screen.getByLabelText(/month/i)).toHaveValue(1);
expect(screen.getByLabelText(/year/i)).toHaveValue(2000);
});

it('should render a disabled input', () => {
render(<DateInput {...baseProps} disabled />);
expect(screen.getByLabelText(/day/i)).toBeDisabled();
expect(screen.getByLabelText(/month/i)).toBeDisabled();
expect(screen.getByLabelText(/year/i)).toBeDisabled();
expect(
screen.getByRole('button', { name: baseProps.openCalendarButtonLabel }),
).toHaveAttribute('aria-disabled', 'true');
});

it('should handle min/max dates', () => {
render(<DateInput {...baseProps} min="2000-01-01" max="2001-01-01" />);
expect(screen.getByLabelText(/day/i)).toHaveAttribute('min', '1');
expect(screen.getByLabelText(/day/i)).toHaveAttribute('max', '31');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('min', '1');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('max', '12');
expect(screen.getByLabelText(/year/i)).toHaveAttribute('min', '2000');
expect(screen.getByLabelText(/year/i)).toHaveAttribute('max', '2001');
});

it('should handle min/max dates as the user types year', async () => {
render(<DateInput {...baseProps} min="2000-04-29" max="2001-02-15" />);

await userEvent.type(screen.getByLabelText(/year/i), '2001');
/* expect(screen.getByLabelText(/day/i)).toHaveAttribute('min', '1');
expect(screen.getByLabelText(/day/i)).toHaveAttribute('max', '1'); */
expect(screen.getByLabelText(/month/i)).toHaveAttribute('min', '1');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('max', '2');
});

it('should handle min/max dates as the user types year and month', async () => {
render(<DateInput {...baseProps} min="2000-04-29" max="2001-02-15" />);

await userEvent.type(screen.getByLabelText(/year/i), '2001');
await userEvent.type(screen.getByLabelText(/month/i), '02');

expect(screen.getByLabelText(/day/i)).toHaveAttribute('min', '1');
expect(screen.getByLabelText(/day/i)).toHaveAttribute('max', '15');
});

it('years field should be readonly if min/max dates have the same year', () => {
render(<DateInput {...baseProps} min="2000-04-29" max="2000-06-15" />);
expect(screen.getByLabelText(/year/i)).toHaveAttribute('readonly');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('min', '4');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('max', '6');
});

it('years and months fields should render as readonly if min/max dates have the same year and same month', () => {
render(<DateInput {...baseProps} min="2000-04-09" max="2000-04-27" />);
expect(screen.getByLabelText(/year/i)).toHaveAttribute('readonly');
expect(screen.getByLabelText(/month/i)).toHaveAttribute('readonly');

expect(screen.getByLabelText(/day/i)).toHaveAttribute('min', '9');
expect(screen.getByLabelText(/day/i)).toHaveAttribute('max', '27');
});

describe('Status messages', () => {
it('should render an empty live region on mount', () => {
render(<DateInput {...baseProps} />);
const liveRegionEl = screen.getByRole('status');

expect(liveRegionEl).toBeEmptyDOMElement();
});

it('should render status messages in a live region', () => {
const statusMessage = 'This field is required';
render(
<DateInput {...baseProps} invalid validationHint={statusMessage} />,
);
const liveRegionEl = screen.getByRole('status');

expect(liveRegionEl).toHaveTextContent(statusMessage);
});

it('should not render descriptions in a live region', () => {
const statusMessage = 'This field is required';
render(<DateInput {...baseProps} validationHint={statusMessage} />);
const liveRegionEl = screen.getByRole('status');

expect(liveRegionEl).toBeEmptyDOMElement();
});
});

it('should have no accessibility violations', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { getDateSegments } from './DateInputService.js';

describe('DateInputService', () => {
describe('getDateSegments', () => {
it('should', () => {
it.todo('should', () => {
const actual = getDateSegments();
expect(actual).toBe('TODO:');
});
Expand Down

0 comments on commit 35dcf3a

Please sign in to comment.