---
# (DD05) Business Logic — OwnerControllerTests.processUpdateOwnerFormHasErrors() [13 LOC]

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

## 1. Role

### OwnerControllerTests.processUpdateOwnerFormHasErrors()

This method is a controller test that verifies the business behavior of the owner update flow when submitted form data fails validation. In domain terms, it simulates a user attempting to save changes to an existing pet owner record with incomplete contact information, specifically an empty address and telephone number. The test confirms that the web layer does not persist the update, returns the owner maintenance form for correction, and exposes field-level validation errors for the invalid fields.

From a design perspective, the method implements a black-box web endpoint verification pattern using MockMvc. It acts as a regression safeguard for the update route `/owners/{ownerId}/edit`, ensuring that validation errors are surfaced in the same screen where the user entered the data. The method does not route by business type or branch across multiple service categories; instead, it asserts one negative-path behavior for the owner update transaction. In the larger system, it protects the controller contract that an invalid owner update must keep the user on the create/update form and preserve error feedback rather than performing a successful save and redirect.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["processUpdateOwnerFormHasErrors()"])
    POST(["HTTP POST /owners/{ownerId}/edit"])
    PARAMS(["Set form parameters firstName=Joe, lastName=Bloggs, address=empty, telephone=empty"])
    BIND(["Bind request parameters to Owner"])
    VALIDATE(["Validate Owner with JSR-303 rules"])
    HAS_ERRORS{"BindingResult has errors?"}
    ERROR_MODEL(["Assert model contains errors for owner"])
    ADDRESS_ERR(["Assert field error for address"])
    TELEPHONE_ERR(["Assert field error for telephone"])
    VIEW(["Assert view name owners/createOrUpdateOwnerForm"])
    END_NODE(["Test completes"])

    START --> POST
    POST --> PARAMS
    PARAMS --> BIND
    BIND --> VALIDATE
    VALIDATE --> HAS_ERRORS
    HAS_ERRORS -->|"Yes"| ERROR_MODEL
    ERROR_MODEL --> ADDRESS_ERR
    ADDRESS_ERR --> TELEPHONE_ERR
    TELEPHONE_ERR --> VIEW
    VIEW --> END_NODE
    HAS_ERRORS -->|"No"| END_NODE
```

## 3. Parameter Analysis

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

This test method has no parameters. Its behavior depends on the fixed request payload defined in the test body and on shared test fixture state, including `TEST_OWNER_ID`, the `MockMvc` instance, and the mocked `OwnerRepository` setup in `@BeforeEach`. The method uses these external test fields to drive the web request and verify the controller response.

## 4. CRUD Operations / Called Services

The method does not directly invoke application CRUD services or repositories. It only drives the controller through MockMvc and asserts the HTTP/model outcome. The effective CRUD semantics under test are an attempted **Update** operation on an owner record, but the invalid payload prevents persistence from occurring.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| U | `OwnerController.processUpdateOwnerForm` (via HTTP test target) | N/A | `Owner` | Verifies that an owner update submission with invalid address and telephone data is rejected before save/persist occurs |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen/Controller web test: `OwnerControllerTests` | `OwnerControllerTests.processUpdateOwnerFormHasErrors` | `OwnerController.processUpdateOwnerForm [U] Owner` |

This test is exercised from the controller test class itself and is indirectly tied to the owner edit endpoint used by the web UI. The terminal business effect under test is the controller's update path for `Owner`, with the invalid input branch stopping before repository save.

## 6. Per-Branch Detail Blocks

**Block 1** — [TEST SETUP] `(MockMvc POST request preparation)` (L203-L206)

> Prepares the owner update request with business data that intentionally violates validation rules.

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

**Block 2** — [ASSERTION CHAIN] `(controller response validation)` (L207-L214)

> Confirms that validation failure keeps the user on the edit form and surfaces field-level errors.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `.andExpect(status().isOk())` |
| 2 | EXEC | `.andExpect(model().attributeHasErrors("owner"))` |
| 3 | EXEC | `.andExpect(model().attributeHasFieldErrors("owner", "address"))` |
| 4 | EXEC | `.andExpect(model().attributeHasFieldErrors("owner", "telephone"))` |
| 5 | EXEC | `.andExpect(view().name("owners/createOrUpdateOwnerForm"));` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain object | Pet owner record managed by the application |
| `ownerId` | Field / Path variable | Unique identifier of the owner being edited |
| `firstName` | Field | Owner's given name |
| `lastName` | Field | Owner's family name |
| `address` | Field | Owner's mailing or street address |
| `telephone` | Field | Owner's contact phone number |
| `MockMvc` | Technical component | Spring test client used to simulate HTTP requests to the controller |
| `BindingResult` | Technical component | Container for validation and binding errors produced during request processing |
| `JSR-303` | Acronym | Bean Validation standard used to enforce field constraints |
| `POST /owners/{ownerId}/edit` | Web route | Owner update submission endpoint |
| `owners/createOrUpdateOwnerForm` | View | Owner maintenance form used for create and update operations |
| `CRUD` | Acronym | Create, Read, Update, Delete business operation categories |
| `Validation error` | Business term | Input that does not meet required rules and must be corrected before saving |
| `flash attribute` | Technical term | Temporary message stored for the next request in a redirect or redisplay flow |
| `Model` | Technical component | Web response data container used by the view layer |
