# (DD05) 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 negative-path behavior of the owner update workflow when mandatory address data is missing from the submitted form. In business terms, it simulates a user attempting to update an existing pet owner record but leaving the address and telephone fields blank, which should trigger validation failures instead of persisting the change.

The method does not implement domain logic itself; instead, it validates that the controller correctly routes an invalid update request back to the owner edit form and preserves field-level error feedback. This is a form-validation regression test for the owner maintenance screen, ensuring that incomplete customer master data cannot be accepted silently.

From a larger system perspective, this method protects the owner registration/update use case by asserting that the MVC layer enforces required-field rules before any repository update is attempted. It follows a simple request/response verification pattern: submit form data, observe validation errors, and confirm the same form view is returned for correction. The only branch represented here is the error outcome for missing address and telephone values.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["processUpdateOwnerFormHasErrors()"]
    SUBMIT["MockMvc POST /owners/{ownerId}/edit with ownerId=1 and form fields"]
    SET_FIRST_NAME["Set firstName = Joe"]
    SET_LAST_NAME["Set lastName = Bloggs"]
    SET_ADDRESS_EMPTY["Set address = empty string"]
    SET_TELEPHONE_EMPTY["Set telephone = empty string"]
    VALIDATE["Controller validates owner form input"]
    HAS_ERRORS{"Validation errors exist?"}
    ADDRESS_ERROR{"address field has error?"}
    TELEPHONE_ERROR{"telephone field has error?"}
    VIEW_FORM["Return view owners/createOrUpdateOwnerForm"]
    END_NODE["Test assertions complete"]

    START --> SUBMIT
    SUBMIT --> SET_FIRST_NAME
    SET_FIRST_NAME --> SET_LAST_NAME
    SET_LAST_NAME --> SET_ADDRESS_EMPTY
    SET_ADDRESS_EMPTY --> SET_TELEPHONE_EMPTY
    SET_TELEPHONE_EMPTY --> VALIDATE
    VALIDATE --> HAS_ERRORS
    HAS_ERRORS --> ADDRESS_ERROR
    ADDRESS_ERROR --> TELEPHONE_ERROR
    TELEPHONE_ERROR --> VIEW_FORM
    VIEW_FORM --> END_NODE
```

The method submits an HTTP POST request to the owner edit endpoint with the target owner identifier and a partially completed form. It intentionally supplies empty values for `address` and `telephone` to exercise validation rules on the update screen. The assertions then confirm that validation errors are present on the model, that the errors are attached to the expected fields, and that the UI returns the owner form rather than redirecting to the detail page.

## 3. Parameter Analysis

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

This test method has no parameters of its own. The observable inputs are external test fixtures and request state: `TEST_OWNER_ID` is used as the target owner identifier, `mockMvc` executes the HTTP request against the controller under test, and the preconfigured `owners` repository stub supplies the existing owner record used by the MVC flow.

## 4. CRUD Operations / Called Services

This method is a test harness and does not directly invoke application CRUD service methods. Its primary interaction is a simulated HTTP POST that exercises controller-side update validation. The table below lists the framework-level call used to drive the business scenario.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `mockMvc.perform(...)` | N/A | Owner form submission | Executes a simulated web request to read and validate an existing owner update form without persisting changes |

No repository write occurs in this method because the invalid form data should stop the update workflow before any save operation is reached.

## 5. Dependency Trace

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

This method is invoked only by the JUnit test runner as part of the `OwnerControllerTests` class. It does not have application callers from screens, batches, or CBS components. The terminal business effect is a read/validation path through the MVC stack, ending with a form redisplay and validation errors rather than a data update.

## 6. Per-Branch Detail Blocks

**Block 1** — [SEQUENCE] `(test setup and request submission)` (L202-L214)

> This block covers the full test scenario: posting invalid owner data, checking validation errors, and verifying that the edit form is shown again.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `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", "")` |
| 6 | CALL | `.andExpect(status().isOk())` |
| 7 | CALL | `.andExpect(model().attributeHasErrors("owner"))` |
| 8 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "address"))` |
| 9 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "telephone"))` |
| 10 | CALL | `.andExpect(view().name("owners/createOrUpdateOwnerForm"))` |
| 11 | RETURN | `void` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain object | Pet owner master record being maintained in the clinic system |
| `ownerId` | Field | Identifier of the owner record being edited |
| `firstName` | Field | Owner given name captured on the form |
| `lastName` | Field | Owner family name captured on the form |
| `address` | Field | Owner street address; required update field in this scenario |
| `telephone` | Field | Owner phone number; required update field in this scenario |
| `owners/createOrUpdateOwnerForm` | View | MVC form used to create or edit an owner record |
| `MockMvc` | Test framework | Spring MVC test harness used to simulate HTTP requests without starting a full server |
| validation error | Technical term | Binding or field-level failure caused by missing or invalid submitted data |
| owner update workflow | Business term | Screen flow used to modify an existing owner profile |
| pet owner | Business term | Customer who owns one or more pets in the PetClinic domain |
