# (DD49) Business Logic — ProcessCreationFormHasErrors.processCreationFormWithInvalidBirthDate() [15 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `org.springframework.samples.petclinic.owner.ProcessCreationFormHasErrors` |
| Layer | Test |
| Module | `owner` (Package: `org.springframework.samples.petclinic.owner`) |

## 1. Role

### ProcessCreationFormHasErrors.processCreationFormWithInvalidBirthDate()

This test method verifies the pet creation flow when the submitted birth date cannot be parsed as a valid value for the form binding process. In business terms, it protects the owner/pet registration screen from accepting an invalid future-dated birth date and confirms that the controller returns the user to the same creation form with the field-level error preserved. The scenario is specifically focused on input validation behavior rather than persistence, so no database write is expected and the test validates only the request/response contract of the web layer.

The method acts as a negative-path regression test for the pet registration process. It constructs a future date, submits it through the `/owners/{ownerId}/pets/new` endpoint, and expects the binding/validation layer to reject the `birthDate` field while leaving the parent `owner` object error-free. This is a straightforward request-driven test pattern: arrange test input, invoke the MVC endpoint, then assert on model state, HTTP status, and the returned Thymeleaf view.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["processCreationFormWithInvalidBirthDate()"])
    NOW(["Get current date using LocalDate.now()"])
    FUTURE(["Create invalid future birth date by adding one month"])
    REQUEST(["Submit POST /owners/{ownerId}/pets/new with name and future birthDate"])
    ASSERT1(["Verify model attribute owner has no errors"])
    ASSERT2(["Verify model attribute pet has errors"])
    ASSERT3(["Verify pet.birthDate has a field error"])
    ASSERT4(["Verify field error code equals typeMismatch.birthDate"])
    ASSERT5(["Verify response status is 200 OK"])
    ASSERT6(["Verify returned view is pets/createOrUpdatePetForm"])
    END_NODE(["Test completes"])

    START --> NOW
    NOW --> FUTURE
    FUTURE --> REQUEST
    REQUEST --> ASSERT1
    ASSERT1 --> ASSERT2
    ASSERT2 --> ASSERT3
    ASSERT3 --> ASSERT4
    ASSERT4 --> ASSERT5
    ASSERT5 --> ASSERT6
    ASSERT6 --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | - |

External state read by the method:
- `TEST_OWNER_ID` — test owner identifier used in the request path.
- `mockMvc` — Spring MVC test harness used to submit the HTTP POST and assert the response.

## 4. CRUD Operations / Called Services

This method does not invoke any application CRUD service or repository methods. It performs only test-side object creation and HTTP assertions against the controller layer.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|-----------------------|
| - | - | - | - | No direct CRUD operation is executed; the method verifies validation failure on the pet creation form. |

## 5. Dependency Trace

The search for callers found only the test method itself in `PetControllerTests.java`, so this method is not called by other Java classes in the codebase. It is an endpoint-level test that directly exercises the pet creation controller path through MockMvc.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Test: `PetControllerTests` | `PetControllerTests.processCreationFormWithInvalidBirthDate` | `MockMvc POST /owners/{ownerId}/pets/new` [R] `pets/createOrUpdatePetForm` |

## 6. Per-Branch Detail Blocks

**Block 1** — Sequential setup and assertion chain `(no branching)` (L147-L159)

> This block covers the full negative-path validation scenario for an invalid birth date submission.

| # | Type | Code |
|---|------|------|
| 1 | SET | `LocalDate currentDate = LocalDate.now();` |
| 2 | SET | `String futureBirthDate = currentDate.plusMonths(1).toString();` |
| 3 | CALL | `mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate", futureBirthDate))` |
| 4 | CALL | `.andExpect(model().attributeHasNoErrors("owner"))` |
| 5 | CALL | `.andExpect(model().attributeHasErrors("pet"))` |
| 6 | CALL | `.andExpect(model().attributeHasFieldErrors("pet", "birthDate"))` |
| 7 | CALL | `.andExpect(model().attributeHasFieldErrorCode("pet", "birthDate", "typeMismatch.birthDate"))` |
| 8 | CALL | `.andExpect(status().isOk())` |
| 9 | CALL | `.andExpect(view().name("pets/createOrUpdatePetForm"))` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain concept | The pet owner whose record is being used to register a new pet. |
| `pet` | Domain concept | The animal being created through the owner’s pet registration flow. |
| `birthDate` | Field | Pet date of birth entered on the creation form; must bind to a valid date value. |
| `typeMismatch.birthDate` | Validation code | Binding error code used when the submitted value cannot be converted into the expected birth date type. |
| `MockMvc` | Technical component | Spring MVC testing framework used to simulate HTTP requests against controller endpoints. |
| `POST /owners/{ownerId}/pets/new` | Endpoint | Controller route used to submit a new pet creation form for a specific owner. |
| `pets/createOrUpdatePetForm` | View name | Thymeleaf page shown when the form must be redisplayed after validation failure. |
| `TEST_OWNER_ID` | Test constant | Predefined owner identifier used to target the request path during controller testing. |
| `LocalDate` | Java type | Java date type used to generate a future birth date for validation failure testing. |
| `typeMismatch` | Validation concept | Spring binding failure indicating a form field could not be converted to the target type. |
