# (DD04) Business Logic — OwnerControllerTests.processUpdateOwnerFormHasErrors() [13 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.processUpdateOwnerFormHasErrors()

This test verifies the validation failure path of the owner update flow in the Petclinic owner management screen. It submits an HTTP POST to `/owners/{ownerId}/edit` with a valid first name and last name, but with empty `address` and `telephone` fields, then confirms that the controller keeps the user on the owner form instead of proceeding with a successful update. The business purpose is to ensure that mandatory contact information is enforced during owner maintenance and that invalid form input is surfaced back to the user as field-level validation errors.

The method is not a production service routine; it is a controller-level integration test that exercises the MVC request handling, model validation, and view selection behavior together. Its role in the larger system is to protect the owner update use case from regressions by proving that the update endpoint rejects incomplete data and redisplays the maintenance form. There are no business branches inside the test itself, but the asserted business path is the “has validation errors” branch of the update workflow: the submitted form is invalid, the model contains errors for `address` and `telephone`, and the response renders `owners/createOrUpdateOwnerForm`.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["processUpdateOwnerFormHasErrors()"])
    POST(["perform POST /owners/{ownerId}/edit"])
    PARAMS(["Set form parameters - firstName=Joe, lastName=Bloggs, address blank, telephone blank"])
    STATUS(["Expect HTTP 200 OK"])
    MODEL_ERRORS(["Expect model attribute 'owner' has validation errors"])
    ADDRESS_ERROR(["Expect field error on 'address'"])
    TELEPHONE_ERROR(["Expect field error on 'telephone'"])
    VIEW(["Expect view owners/createOrUpdateOwnerForm"])
    END_NODE(["Return / Next"])

    START --> POST
    POST --> PARAMS
    PARAMS --> STATUS
    STATUS --> MODEL_ERRORS
    MODEL_ERRORS --> ADDRESS_ERROR
    ADDRESS_ERROR --> TELEPHONE_ERROR
    TELEPHONE_ERROR --> VIEW
    VIEW --> END_NODE
```

## 3. Parameter Analysis

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

This method has no explicit parameters. It relies on instance fields and test fixtures from the surrounding test class, including the mock MVC test harness and the fixed owner identifier used in the request path.

## 4. CRUD Operations / Called Services

This method does not directly invoke application CRUD services. It exercises the web layer through a mocked HTTP request and validates the controller response path.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `mockMvc.perform(...)` | N/A | HTTP request / MVC layer | Submits the owner edit form request so the controller can perform validation and redisplay the form on errors |
| R | `status().isOk()` | N/A | HTTP response | Verifies that the invalid submission returns the normal OK page status rather than a redirect |
| R | `model().attributeHasErrors("owner")` | N/A | MVC model attribute `owner` | Confirms that the bound owner object carries validation errors |
| R | `model().attributeHasFieldErrors("owner", "address")` | N/A | MVC model field `address` | Confirms that the address field is rejected as invalid |
| R | `model().attributeHasFieldErrors("owner", "telephone")` | N/A | MVC model field `telephone` | Confirms that the telephone field is rejected as invalid |
| R | `view().name("owners/createOrUpdateOwnerForm")` | N/A | View template `owners/createOrUpdateOwnerForm` | Verifies that the controller returns the owner maintenance form for correction |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:OwnerControllerTests | `OwnerControllerTests.processUpdateOwnerFormHasErrors` | `controller POST /owners/{ownerId}/edit [R] MVC validation result` |

## 6. Per-Branch Detail Blocks

**Block 1** — [TEST SETUP] (L202-L205)

> Builds the invalid owner update request with missing required contact fields.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID)` |
| 2 | EXEC | `.param("firstName", "Joe")` |
| 3 | EXEC | `.param("lastName", "Bloggs")` |
| 4 | EXEC | `.param("address", "")` |
| 5 | EXEC | `.param("telephone", ""))` |

**Block 2** — [ASSERT RESPONSE STATUS] (L206)

> Confirms the controller stays on the form page instead of redirecting away.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `status().isOk()` |

**Block 3** — [ASSERT MODEL ERRORS] (L207-L209)

> Verifies that validation errors are attached to the owner model and specifically to the missing fields.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `model().attributeHasErrors("owner")` |
| 2 | CALL | `model().attributeHasFieldErrors("owner", "address")` |
| 3 | CALL | `model().attributeHasFieldErrors("owner", "telephone")` |

**Block 4** — [ASSERT VIEW] (L210)

> Ensures the invalid submission redisplays the owner maintenance form for correction.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `view().name("owners/createOrUpdateOwnerForm")` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain object | Pet owner record being maintained through the UI |
| `ownerId` | Identifier | Unique identifier for the owner being edited |
| `address` | Field | Owner mailing address; required contact information in the edit form |
| `telephone` | Field | Owner phone number; required contact information in the edit form |
| `firstName` | Field | Owner given name submitted in the form |
| `lastName` | Field | Owner family name submitted in the form |
| `mockMvc` | Test harness | Spring MVC test client used to simulate an HTTP request to the controller |
| `model` | MVC concept | Data container passed from controller to view, including validation errors |
| `view` | MVC concept | Server-side page or template rendered back to the user |
| `createOrUpdateOwnerForm` | View name | Owner maintenance form used for both creating and updating owner data |
| `HTTP 200 OK` | HTTP status | Successful page response returned when validation fails and the form is redisplayed |
| validation error | Business rule | Input rejection that prevents an owner update from completing until required fields are provided |
