import { describe, expect, it } from '@jest/globals'; import { userEvent } from '@testing-library/user-event'; import { render, screen as rtlScreen } from '../../../../../tests/utils'; import { ContactForm, type ContactFormData } from './contact-form'; describe('ContactForm', () => { const user = userEvent.setup(); it('renders the form fields with a submit button', () => { const label = 'Contact form'; render(); expect(rtlScreen.getByRole('form')).toHaveAccessibleName(label); expect( rtlScreen.getByRole('textbox', { name: /^Name:/ }) ).toBeInTheDocument(); expect( rtlScreen.getByRole('textbox', { name: /^Email:/ }) ).toBeInTheDocument(); expect( rtlScreen.getByRole('textbox', { name: /^Object:/ }) ).toBeInTheDocument(); expect( rtlScreen.getByRole('textbox', { name: /^Message:/ }) ).toBeInTheDocument(); expect( rtlScreen.getByRole('button', { name: /^Send/ }) ).toBeInTheDocument(); }); /* eslint-disable max-statements */ it('can submit the form', async () => { const onSubmit = jest.fn((_data: ContactFormData) => undefined); const values: ContactFormData = { email: 'Camryn.Hegmann23@gmail.com', message: 'Nulla eveniet tempora aliquid.', name: 'Erick82', object: 'sequi nobis unde', }; render(); // eslint-disable-next-line @typescript-eslint/no-magic-numbers expect.assertions(3); expect(onSubmit).not.toHaveBeenCalled(); await user.type( rtlScreen.getByRole('textbox', { name: /^Name:/ }), values.name ); await user.type( rtlScreen.getByRole('textbox', { name: /^Email:/ }), values.email ); await user.type( rtlScreen.getByRole('textbox', { name: /^Object:/ }), values.object ); await user.type( rtlScreen.getByRole('textbox', { name: /^Message:/ }), values.message ); await user.click(rtlScreen.getByRole('button', { name: /^Send/ })); expect(onSubmit).toHaveBeenCalledTimes(1); expect(onSubmit).toHaveBeenCalledWith(values); }); /* eslint-enable max-statements */ /* eslint-disable max-statements */ it('can submit the form and inform user on success', async () => { const successMsg = 'Mail has been sent.'; const onSubmit = jest.fn((_data: ContactFormData) => { return { messages: { success: successMsg }, validator: () => true, }; }); const values: ContactFormData = { email: 'Camryn.Hegmann23@gmail.com', message: 'Nulla eveniet tempora aliquid.', name: 'Erick82', object: 'sequi nobis unde', }; render(); // eslint-disable-next-line @typescript-eslint/no-magic-numbers expect.assertions(4); expect(onSubmit).not.toHaveBeenCalled(); await user.type( rtlScreen.getByRole('textbox', { name: /^Name:/ }), values.name ); await user.type( rtlScreen.getByRole('textbox', { name: /^Email:/ }), values.email ); await user.type( rtlScreen.getByRole('textbox', { name: /^Object:/ }), values.object ); await user.type( rtlScreen.getByRole('textbox', { name: /^Message:/ }), values.message ); await user.click(rtlScreen.getByRole('button', { name: /^Send/ })); expect(onSubmit).toHaveBeenCalledTimes(1); expect(onSubmit).toHaveBeenCalledWith(values); expect(rtlScreen.getByText(successMsg)).toBeInTheDocument(); }); /* eslint-enable max-statements */ /* eslint-disable max-statements */ it('can abort submit and inform user on failure', async () => { const errorMsg = 'An error occurred.'; const onSubmit = jest.fn((_data: ContactFormData) => { return { messages: { error: errorMsg }, validator: () => false, }; }); const values: ContactFormData = { email: 'Camryn.Hegmann23@gmail.com', message: 'Nulla eveniet tempora aliquid.', name: 'Erick82', object: 'sequi nobis unde', }; render(); // eslint-disable-next-line @typescript-eslint/no-magic-numbers expect.assertions(4); expect(onSubmit).not.toHaveBeenCalled(); await user.type( rtlScreen.getByRole('textbox', { name: /^Name:/ }), values.name ); await user.type( rtlScreen.getByRole('textbox', { name: /^Email:/ }), values.email ); await user.type( rtlScreen.getByRole('textbox', { name: /^Object:/ }), values.object ); await user.type( rtlScreen.getByRole('textbox', { name: /^Message:/ }), values.message ); await user.click(rtlScreen.getByRole('button', { name: /^Send/ })); expect(onSubmit).toHaveBeenCalledTimes(1); expect(onSubmit).toHaveBeenCalledWith(values); expect(rtlScreen.getByText(errorMsg)).toBeInTheDocument(); }); /* eslint-enable max-statements */ });