Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/components/Form/Form.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,41 @@ export const WithDynamicInitialValues: StoryObj<typeof Form> = {
]
};

export const WithResetButton: StoryObj<typeof Form> = {
args: {
content: {
name: {
kind: 'string',
label: 'Name',
variant: 'input'
},
contactMethod: {
kind: 'string',
label: 'Preferred Contact Method',
options: {
email: 'Email',
phone: 'Phone',
mail: 'Mail'
},
variant: 'radio'
},
comments: {
kind: 'string',
label: 'Comments',
variant: 'textarea'
}
},
resetBtn: true,
onSubmit: (data) => {
alert(JSON.stringify(data, null, 2));
},
validationSchema: $SimpleExampleFormData.extend({
contactMethod: z.enum(['email', 'phone', 'mail']).optional(),
comments: z.string().optional()
})
}
};

export const WithPreventReset: StoryObj<typeof Form<SimpleExampleFormSchemaType>> = {
args: {
content: {
Expand Down
95 changes: 95 additions & 0 deletions src/components/Form/Form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,99 @@ describe('Form', () => {
await waitFor(() => expect(onSubmit).toHaveBeenCalledOnce());
});
});
describe('reset button', () => {
const renderForm = (props?: { preventResetValuesOnReset?: boolean; resetBtn?: boolean }) => {
render(
<Form
content={{
name: {
kind: 'string',
label: 'Name',
variant: 'input'
}
}}
data-testid={testid}
validationSchema={z.object({
name: z.string().min(3, 'Too short')
})}
onError={onError}
onSubmit={onSubmit}
{...props}
/>
);
return screen.getByLabelText<HTMLInputElement>('Name');
};

// The button is identified by its aria-label, so the query does not depend on the resolved
// translation for the visible text.
const getResetButton = () => screen.getByRole('button', { name: 'Reset' });

afterEach(() => {
vi.clearAllMocks();
});

it('should not render the reset button unless resetBtn is set', () => {
renderForm();
expect(screen.queryByRole('button', { name: 'Reset' })).not.toBeInTheDocument();
});

it('should render the reset button when resetBtn is set', () => {
renderForm({ resetBtn: true });
expect(getResetButton()).toBeInTheDocument();
});

it('should clear the values when the reset button is clicked', async () => {
const name = renderForm({ resetBtn: true });
await userEvent.type(name, 'Winston');
expect(name.value).toBe('Winston');
await userEvent.click(getResetButton());
expect(name.value).toBe('');
});

it('should not submit the form when the reset button is clicked', async () => {
const name = renderForm({ resetBtn: true });
await userEvent.type(name, 'Winston');
await userEvent.click(getResetButton());
expect(onSubmit).not.toHaveBeenCalled();
});

it('should clear the errors when the reset button is clicked', async () => {
const name = renderForm({ resetBtn: true });
await userEvent.type(name, 'ab');
fireEvent.submit(screen.getByTestId(testid));
await waitFor(() =>
expect(screen.getAllByTestId('error-message-text').map((e) => e.innerHTML)).toMatchObject(['Too short'])
);
await userEvent.click(getResetButton());
expect(screen.queryAllByTestId('error-message-text')).toHaveLength(0);
});

it('should keep the values, but still clear the errors, when preventResetValuesOnReset is set', async () => {
const name = renderForm({ preventResetValuesOnReset: true, resetBtn: true });
await userEvent.type(name, 'ab');
fireEvent.submit(screen.getByTestId(testid));
await waitFor(() =>
expect(screen.getAllByTestId('error-message-text').map((e) => e.innerHTML)).toMatchObject(['Too short'])
);
await userEvent.click(getResetButton());
expect(screen.queryAllByTestId('error-message-text')).toHaveLength(0);
expect(name.value).toBe('ab');
});

it('should clear the values after a successful submit, even without the reset button', async () => {
const name = renderForm();
await userEvent.type(name, 'Winston');
fireEvent.submit(screen.getByTestId(testid));
await waitFor(() => expect(onSubmit).toHaveBeenCalledOnce());
await waitFor(() => expect(name.value).toBe(''));
});

it('should keep the values after a successful submit when preventResetValuesOnReset is set', async () => {
const name = renderForm({ preventResetValuesOnReset: true });
await userEvent.type(name, 'Winston');
fireEvent.submit(screen.getByTestId(testid));
await waitFor(() => expect(onSubmit).toHaveBeenCalledOnce());
expect(name.value).toBe('Winston');
});
});
});
Loading