# (DD01) Business Logic — OwnerControllerTests.processUpdateOwnerFormWithIdMismatch() [19 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.processUpdateOwnerFormWithIdMismatch()

This test verifies the controller’s defensive behavior when the owner identifier carried in the request path does not match the owner object submitted from the form. In business terms, it validates that an attempted owner profile update is rejected when the caller tries to submit a different record than the one addressed by the URL. This protects the owner maintenance flow from accidental or malicious record substitution during editing.

The method sets up a mismatched owner identity, configures the owner repository to return the owner associated with the path identifier, and then submits an update request through MockMvc. The expected outcome is a redirect back to the edit screen for the path owner and a flash-scoped error indicator. The pattern is a controller-level negative test using request simulation, repository stubbing, and response assertion. Its role in the larger system is to preserve data integrity and enforce safe edit semantics for owner maintenance screens.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
START(["processUpdateOwnerFormWithIdMismatch() test start"])
SET_ID(["Set pathOwnerId = 1"])
CREATE_OWNER(["Create Owner test fixture"])
SET_OWNER_ID(["Set owner.id = 2"])
SET_OWNER_FIELDS(["Set owner name, address, city, telephone"])
MOCK_FIND(["Stub owners.findById(pathOwnerId) -> Optional.of(owner)"])
PERFORM(["Perform POST /owners/{ownerId}/edit with flashAttr owner"])
ASSERT_REDIRECT(["Assert 3xx redirection"])
ASSERT_URL(["Assert redirectedUrl = /owners/1/edit"])
ASSERT_ERROR(["Assert flash attribute error exists"])
END_NODE(["Test completes"])
START --> SET_ID
SET_ID --> CREATE_OWNER
CREATE_OWNER --> SET_OWNER_ID
SET_OWNER_ID --> SET_OWNER_FIELDS
SET_OWNER_FIELDS --> MOCK_FIND
MOCK_FIND --> PERFORM
PERFORM --> ASSERT_REDIRECT
ASSERT_REDIRECT --> ASSERT_URL
ASSERT_URL --> ASSERT_ERROR
ASSERT_ERROR --> END_NODE
```

The method does not branch by business constant. It follows a single test path that intentionally sets up an identifier mismatch and then verifies the controller response.

## 3. Parameter Analysis

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

External state read by the method at runtime includes the mocked `owners` repository, the `mockMvc` test harness, and the request mapping `/owners/{ownerId}/edit`.

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `owners.findById(pathOwnerId)` | N/A | `Owner` aggregate / owner repository | Reads the owner record for the path identifier so the controller can compare it against the submitted form object. |
| R | `MockMvcRequestBuilders.post("/owners/{ownerId}/edit", pathOwnerId)` | N/A | Web request / controller endpoint | Issues the edit submission request to the owner controller. |
| R | `status().is3xxRedirection()` | N/A | HTTP response | Verifies that the controller rejects the mismatched update by redirecting. |
| R | `redirectedUrl("/owners/" + pathOwnerId + "/edit")` | N/A | HTTP response | Confirms the user is routed back to the same owner edit screen. |
| R | `flash().attributeExists("error")` | N/A | Flash scope | Confirms the controller exposes an error message for the rejected update attempt. |

This method is a test case, so it does not directly perform CRUD on a persistent database table. Its business value is to validate that the underlying update flow protects the owner record from inconsistent identity updates.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:owner edit submission | `HTTP POST /owners/{ownerId}/edit` -> `OwnerController.updateOwnerForm(...)` -> `OwnerControllerTests.processUpdateOwnerFormWithIdMismatch()` | `owners.findById(pathOwnerId) [R] Owner` |

The caller search located this method only in its own test class. From an execution perspective, the test is invoked by the test runner, and its target dependency chain validates the controller’s edit submission path rather than a downstream service or database write.

## 6. Per-Branch Detail Blocks

**Block 1** — [SEQUENTIAL] `(test setup)` (L232)

> Establishes the conflicting owner identifiers needed to simulate a rejected update.

| # | Type | Code |
|---|------|------|
| 1 | SET | `int pathOwnerId = 1;` |
| 2 | SET | `Owner owner = new Owner();` |
| 3 | EXEC | `owner.setId(2);` |
| 4 | EXEC | `owner.setFirstName("John");` |
| 5 | EXEC | `owner.setLastName("Doe");` |
| 6 | EXEC | `owner.setAddress("Center Street");` |
| 7 | EXEC | `owner.setCity("New York");` |
| 8 | EXEC | `owner.setTelephone("0123456789");` |

**Block 2** — [SEQUENTIAL] `(repository stub)` (L241)

> Makes the repository return the owner matching the path identifier so the controller can detect the mismatch against the form object.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `when(owners.findById(pathOwnerId)).thenReturn(Optional.of(owner));` |

**Block 3** — [SEQUENTIAL] `(request execution and verification)` (L243)

> Submits the edit request and verifies the controller response is a safe rejection with an error message.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mockMvc.perform(MockMvcRequestBuilders.post("/owners/{ownerId}/edit", pathOwnerId).flashAttr("owner", owner))` |
| 2 | CALL | `.andExpect(status().is3xxRedirection())` |
| 3 | CALL | `.andExpect(redirectedUrl("/owners/" + pathOwnerId + "/edit"))` |
| 4 | CALL | `.andExpect(flash().attributeExists("error"));` |
| 5 | RETURN | `void` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Pet clinic customer record representing a pet owner. |
| `ownerId` | Field / path variable | Identifier of the owner record being edited in the URL. |
| `flashAttr` | Technical term | Temporarily stores form data for a single redirect cycle. |
| `flash` | Technical term | Redirect-scoped response data, often used for validation errors and user messages. |
| `MockMvc` | Technical term | Spring test harness used to simulate HTTP requests against controllers. |
| `findById` | Repository operation | Reads an owner record by identifier. |
| `edit` | Business action | Opens or submits the owner maintenance screen for profile changes. |
| `mismatch` | Business condition | The submitted owner identity does not match the owner referenced by the URL. |
| `redirect` | Web behavior | Sends the user back to another page instead of completing the update on the current request. |
| `error` | User feedback | Validation or rejection message shown when the update request is not accepted. |
| `3xx redirection` | HTTP status family | Response class indicating the request was not completed in-place and the user must navigate elsewhere. |
