diff --git a/app/create-group-page/page.test.tsx b/app/create-group-page/page.test.tsx index c1370528..f6e6a429 100644 --- a/app/create-group-page/page.test.tsx +++ b/app/create-group-page/page.test.tsx @@ -4,6 +4,9 @@ import { render, screen } from '@testing-library/react'; import CreateGroupPage from './page'; import { Calendar } from '@/components/Calendar/calendar'; +import userEvent from '@testing-library/user-event'; + +window.HTMLElement.prototype.scrollIntoView = jest.fn(); jest.mock('next/navigation', () => ({ useRouter: () => ({ @@ -21,6 +24,29 @@ class MockResizeObserver { global.ResizeObserver = MockResizeObserver; describe('Create Group Page', () => { + const setupFormWithValidData = async (user: ReturnType) => { + await user.type(screen.getByLabelText(/group name/i), 'Test Group'); + await user.type( + screen.getByLabelText(/group description/i), + 'Test Description', + ); + await user.click(screen.getAllByRole('radio')[0]); + + // Budget selection + await user.click(screen.getByLabelText(/price range/i)); + await user.click(screen.getAllByRole('option')[0]); + + // Drawing date selection + await user.click(screen.getByLabelText(/drawing date/i)); + const drawingCalendarDays = screen.getAllByRole('gridcell'); + await user.click(drawingCalendarDays[drawingCalendarDays.length - 2]); + + // Exchange date selection + await user.click(screen.getByLabelText(/exchange date/i)); + const exchangeCalendarDays = screen.getAllByRole('gridcell'); + await user.click(exchangeCalendarDays[exchangeCalendarDays.length - 1]); + }; + it('has the first group image selected by default', () => { render(); @@ -86,4 +112,41 @@ describe('Create Group Page', () => { expect(tomorrow).not.toBeDisabled(); }); }); + + describe('Form submission', () => { + let mockFetch: jest.Mock; + let resolvePromise: (value: any) => void; + + beforeEach(() => { + resolvePromise = jest.fn(); + const pendingPromise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + mockFetch = jest.fn().mockReturnValue(pendingPromise); + global.fetch = mockFetch; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('disables submit button and shows loading state while submitting form', async () => { + render(); + const user = userEvent.setup(); + + await setupFormWithValidData(user); + + const submitButton = screen.getByRole('button', {name: /create group/i}); + await user.click(submitButton); + + expect(submitButton).toBeDisabled(); + expect(submitButton).toHaveTextContent(/creating/i); + + resolvePromise({ + ok: true, + json: () => Promise.resolve({ id: '1' }), + }); + }); + }); }); diff --git a/app/create-group-page/page.tsx b/app/create-group-page/page.tsx index 6a543c5f..a40d7e1a 100644 --- a/app/create-group-page/page.tsx +++ b/app/create-group-page/page.tsx @@ -40,6 +40,8 @@ import { import { useRouter } from 'next/navigation'; import LinkCustom from '@/components/LinkCustom/LinkCustom'; import Link from 'next/link'; +import { useState } from 'react'; +import { LoadingSpinner } from '@/components/LoadingSpinner/LoadingSpinner'; const priceRanges = [ { label: '$10 - $20', value: '10-20' }, @@ -79,6 +81,7 @@ const formSchema = z export default function CreateGroupPage() { const router = useRouter(); + const [isLoading, setLoading] = useState(false); const form = useForm>({ resolver: zodResolver(formSchema), @@ -94,6 +97,7 @@ export default function CreateGroupPage() { async function onSubmit(values: z.infer) { try { + setLoading(true); console.log(values); const response = await fetch('/api/gift-exchanges', { method: 'POST', @@ -107,6 +111,8 @@ export default function CreateGroupPage() { router.push(`/gift-exchanges/${data.id}`); } catch (error) { console.error(error); + } finally { + setLoading(false); } } @@ -281,7 +287,7 @@ export default function CreateGroupPage() { mode="single" selected={field.value} onSelect={field.onChange} - disabled={[{ before: new Date() }]} + disabled={[{ before: new Date() }]} initialFocus /> @@ -325,7 +331,9 @@ export default function CreateGroupPage() { mode="single" selected={field.value} onSelect={field.onChange} - disabled={[{ before: addDays(new Date(giftDrawingDate), 1) }]} + disabled={[ + { before: addDays(new Date(giftDrawingDate), 1) }, + ]} initialFocus /> @@ -341,7 +349,16 @@ export default function CreateGroupPage() { - + @@ -349,4 +366,4 @@ export default function CreateGroupPage() { ); -} +} \ No newline at end of file