General enquries feature

This commit is contained in:
2026-05-04 20:32:24 +12:00
parent bf9331bb5b
commit fa1bc1a615
27 changed files with 657 additions and 164 deletions
+69 -3
View File
@@ -16,6 +16,8 @@ describe('BookingSection', () => {
booking: homepageContent.booking
});
expect(screen.queryByLabelText(/General enquiry/i)).not.toBeInTheDocument();
await fireEvent.click(container.querySelector('.booking-next-button')!);
expect(screen.getByText("Please enter your dog's name")).toBeInTheDocument();
@@ -27,7 +29,7 @@ describe('BookingSection', () => {
booking: homepageContent.booking
});
await fireEvent.input(screen.getByLabelText(/Pet's Name/i), {
await fireEvent.input(screen.getByLabelText(/Dog's Name/i), {
target: { value: 'Maya' }
});
await fireEvent.input(screen.getByLabelText(/Location/i), {
@@ -56,7 +58,7 @@ describe('BookingSection', () => {
await fireEvent.click(screen.getByLabelText('Pack Walks'));
await fireEvent.click(screen.getByLabelText('Other Services'));
await fireEvent.input(screen.getByLabelText(/Pet's Name/i), {
await fireEvent.input(screen.getByLabelText(/Dog's Name/i), {
target: { value: 'Maya' }
});
await fireEvent.input(screen.getByLabelText(/Location/i), {
@@ -91,6 +93,7 @@ describe('BookingSection', () => {
const payload = JSON.parse(fetchMock.mock.calls[0][1].body as string);
expect(payload).toMatchObject({
enquiryType: 'booking',
fullName: 'Alex Walker',
email: 'alex@example.com',
phone: '021 123 4567',
@@ -113,6 +116,69 @@ describe('BookingSection', () => {
);
});
it('allows general enquiries without dog or service details', async () => {
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
json: vi.fn().mockResolvedValue({})
});
vi.stubGlobal('fetch', fetchMock);
const { container } = render(BookingSection, {
booking: homepageContent.booking,
allowGeneralEnquiry: true
});
await fireEvent.input(screen.getByLabelText(/Dog's Name/i), {
target: { value: 'Maya' }
});
await fireEvent.input(screen.getByLabelText(/Location/i), {
target: { value: 'Grey Lynn' }
});
await fireEvent.click(screen.getByLabelText('Pack Walks'));
await fireEvent.click(screen.getByLabelText(/General enquiry/i));
expect(screen.queryByLabelText(/Dog's Name/i)).not.toBeInTheDocument();
expect(screen.queryByText('Pack Walks')).not.toBeInTheDocument();
await fireEvent.click(container.querySelector('.booking-next-button')!);
expect(screen.getByText('Please tell us how we can help')).toBeInTheDocument();
await fireEvent.input(screen.getByLabelText(/Your Message/i), {
target: { value: 'I would like to discuss a business partnership.' }
});
await fireEvent.click(container.querySelector('.booking-next-button')!);
await fireEvent.input(screen.getByLabelText(/Full Name/i), {
target: { value: 'Alex Walker' }
});
await fireEvent.input(screen.getByLabelText(/^Email/i), {
target: { value: 'alex@example.com' }
});
await fireEvent.input(screen.getByLabelText(/Contact #/i), {
target: { value: '021 123 4567' }
});
await fireEvent.click(container.querySelector('.booking-submit-button')!);
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1));
const payload = JSON.parse(fetchMock.mock.calls[0][1].body as string);
expect(payload).toMatchObject({
enquiryType: 'general',
fullName: 'Alex Walker',
email: 'alex@example.com',
phone: '021 123 4567',
petName: '',
location: '',
message: 'I would like to discuss a business partnership.',
services: []
});
expect(screen.getByRole('dialog', { name: /Enquiry confirmed/i })).toBeInTheDocument();
expect(screen.getByText(/Your message is with us!/i)).toBeInTheDocument();
});
it('shows the API error message when submission fails', async () => {
vi.stubGlobal(
'fetch',
@@ -126,7 +192,7 @@ describe('BookingSection', () => {
booking: homepageContent.booking
});
await fireEvent.input(screen.getByLabelText(/Pet's Name/i), {
await fireEvent.input(screen.getByLabelText(/Dog's Name/i), {
target: { value: 'Maya' }
});
await fireEvent.input(screen.getByLabelText(/Location/i), {