# (DD09) Business Logic — OwnerControllerTests.processCreationFormHasErrors() [10 LOC]

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

## 1. Role

### OwnerControllerTests.processCreationFormHasErrors()

This test verifies the controller’s negative-path behavior when an owner creation request fails validation. In business terms, it simulates a user submitting the “New Owner” registration form with incomplete address data and confirms that the application keeps the user on the owner form instead of creating a record. The method validates the user experience for data quality enforcement: the system must reject the submission, surface field-level validation errors, and preserve the create/update view so the user can correct the missing information.

The test specifically checks the validation outcome for two mandatory business fields, `address` and `telephone`, while the submitted data includes `firstName`, `lastName`, and `city`. This indicates that the controller is expected to accept partial input, bind it into an `Owner` model, and let the validation layer determine whether the business object is complete enough for persistence. The method follows a scenario-driven testing pattern: arrange a form submission, act through `MockMvc`, and assert that the response remains on the owner creation form with model errors attached.

In the larger system, this method acts as a regression guard for the owner registration flow. It does not perform business processing itself; instead, it proves that the controller endpoint correctly handles invalid input and does not advance to persistence or redirect behavior when required data is missing.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["processCreationFormHasErrors()"])
    REQ["Build POST request to /owners/new"]
    PARAMS["Set request parameters firstName=Joe, lastName=Bloggs, city=London"]
    CALL["Invoke MockMvc.perform(post(...))"]
    VALIDATE["Spring MVC binds and validates the Owner form"]
    HAS_ERRORS{"Validation errors exist?"}
    ASSERT1["Assert HTTP status is 200 OK"]
    ASSERT2["Assert model has errors for owner"]
    ASSERT3["Assert owner.address has field errors"]
    ASSERT4["Assert owner.telephone has field errors"]
    ASSERT5["Assert view is owners/createOrUpdateOwnerForm"]
    END_NODE(["Test completes"])

    START --> REQ
    REQ --> PARAMS
    PARAMS --> CALL
    CALL --> VALIDATE
    VALIDATE --> HAS_ERRORS
    HAS_ERRORS --> ASSERT1
    ASSERT1 --> ASSERT2
    ASSERT2 --> ASSERT3
    ASSERT3 --> ASSERT4
    ASSERT4 --> ASSERT5
    ASSERT5 --> END_NODE
```

## 3. Parameter Analysis

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

This method declares no parameters. It operates entirely through test fixture state and framework-provided behavior. External state read by the method includes the Spring `MockMvc` instance and the controller endpoint `/owners/new`, which together define the request scenario being verified.

## 4. CRUD Operations / Called Services

This method does not directly invoke application CRUD services. It exercises the MVC controller path through the test framework and asserts the validation result, but it does not persist, query, update, or delete any domain entity itself.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `MockMvc.perform(...)` | N/A | HTTP request/response handling | Executes the controller request path for the owner creation form submission so the validation outcome can be observed. |
| R | `status().isOk()` | N/A | HTTP status | Reads the response status and verifies that the invalid submission stays on the form page. |
| R | `model().attributeHasErrors("owner")` | N/A | MVC model | Reads the model state to confirm that validation errors are attached to the owner object. |
| R | `model().attributeHasFieldErrors("owner", "address")` | N/A | MVC model | Reads field-level validation state for the owner address business field. |
| R | `model().attributeHasFieldErrors("owner", "telephone")` | N/A | MVC model | Reads field-level validation state for the owner telephone business field. |
| R | `view().name("owners/createOrUpdateOwnerForm")` | N/A | View name | Reads the resolved view to confirm that the user remains on the owner create/update form. |

## 5. Dependency Trace

This test is a JUnit/MVC regression check and is not called by application runtime screens or CBS components. It is typically invoked by the test runner during the build lifecycle.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch/Test Runner: JUnit Platform | `JUnit test execution -> OwnerControllerTests.processCreationFormHasErrors()` | `MockMvc.perform [R] HTTP validation response` |

## 6. Per-Branch Detail Blocks

**Block 1** — [SEQUENTIAL TEST EXECUTION] (L124-L131)

> This block covers the full negative-path verification for an invalid owner creation request.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London"))` // submit a form with missing address and telephone data |
| 2 | CALL | `.andExpect(status().isOk())` // confirm the controller returns the form page instead of redirecting |
| 3 | CALL | `.andExpect(model().attributeHasErrors("owner"))` // confirm the model contains validation errors for the owner object |
| 4 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "address"))` // confirm the address field is flagged as invalid |
| 5 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "telephone"))` // confirm the telephone field is flagged as invalid |
| 6 | CALL | `.andExpect(view().name("owners/createOrUpdateOwnerForm"))` // confirm the user remains on the owner create/update form |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain object | Pet owner registration record submitted through the owner creation form |
| `firstName` | Field | Owner given name used as part of the registration identity |
| `lastName` | Field | Owner family name used to identify the registration record |
| `city` | Field | Owner city information supplied in the address section |
| `address` | Field | Owner street address information required for a valid registration |
| `telephone` | Field | Owner contact number required for a valid registration |
| `MockMvc` | Test framework | Spring MVC testing utility used to simulate HTTP requests against controller endpoints |
| `BindingResult` | Technical term | Captures validation and binding errors generated during request processing |
| `owners/createOrUpdateOwnerForm` | View | Owner form used for both creating and updating owner records |
| `HTTP POST /owners/new` | Endpoint | Controller route for submitting a new owner registration request |
| `validation` | Business term | Rule set that checks whether required owner information has been provided |
| `regression test` | Test term | Automated check that protects the owner creation failure behavior from accidental change |
