# (DD07) Business Logic — OwnerControllerTests.processFindFormNoOwnersFound() [11 LOC]

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

## 1. Role

### OwnerControllerTests.processFindFormNoOwnersFound()

This test method verifies the business behavior of the owner search form when the user searches by last name and no matching owners are found. In the PetClinic owner management flow, the controller is expected to validate the search request, reject the result as non-successful, and return the user to the owner search view with a field-level validation error on `owner.lastName`. The test simulates the repository returning an empty `Page<Owner>` for the search term `Unknown Surname`, which represents a no-match scenario in the owner lookup process.

From a business perspective, the method confirms the controller's exception-free handling of an empty search result and ensures that the user receives actionable feedback instead of being redirected to an owner detail page. It is not a production transaction method; rather, it is a controller-level verification of routing, validation, and user experience behavior. The method exercises a single negative branch of the owner lookup workflow: when the underlying owner search service returns no data, the controller must keep the user on the search page and raise the `notFound` validation code for the last-name field.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
START(["processFindFormNoOwnersFound()"])
MOCK(["Stub owners.findByLastNameStartingWith('Unknown Surname', pageable)"])
REQ(["Perform GET /owners?page=1 with lastName=Unknown Surname"])
STATUS(["Expect HTTP 200 OK"])
ERR1(["Expect model field error on owner.lastName"])
ERR2(["Expect notFound validation code"])
VIEW(["Expect view owners/findOwners"])
END_NODE(["Return / Next"])
START --> MOCK
MOCK --> REQ
REQ --> STATUS
STATUS --> ERR1
ERR1 --> ERR2
ERR2 --> VIEW
VIEW --> END_NODE
```

The test follows a simple negative-path validation pattern. First, it arranges a mocked repository response with no owners in the result page. Next, it performs the HTTP request that submits the owner search form with the last name `Unknown Surname`. Finally, it asserts that the controller responds with a successful HTTP status, retains the search view, and records a `notFound` field error for the `owner.lastName` input.

## 3. Parameter Analysis

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

External state read by this method:
- `this.owners` - mocked owner repository used to simulate the search result.
- `mockMvc` - Spring MVC test harness used to execute the controller request.
- `TEST_OWNER_ID` - not used in this method.

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `OwnerRepository.findByLastNameStartingWith` | OwnerRepository | Owner | Calls `findByLastNameStartingWith` in `OwnerRepository` |

Analyze all method calls within this method and classify each as a CRUD operation.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `OwnerRepository.findByLastNameStartingWith` | OwnerRepository | Owner | Reads owner records matching the supplied last-name prefix to simulate a search returning no results |
| R | `MockMvc.perform` | MockMvc | HTTP Request / Controller | Executes the controller endpoint request for the owner search form |
| R | `ResultActions.andExpect` | ResultActions | Controller Response | Validates the returned HTTP status, model state, and view name |

## 5. Dependency Trace

Trace who calls this method and what this method ultimately calls.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Controller test execution | `OwnerControllerTests.processFindFormNoOwnersFound` | `OwnerRepository.findByLastNameStartingWith [R] Owner` |

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] (test fixture setup) (L159)

> Prepares an empty owner search result to drive the controller into the no-match branch.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Page<Owner> tasks = new PageImpl<>(List.of());` // Create an empty page to represent no owners found |

**Block 2** — [CALL] (repository stub setup) (L160)

> Configures the repository mock to return no search results for the requested last name.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `when(this.owners.findByLastNameStartingWith(eq("Unknown Surname"), any(Pageable.class))).thenReturn(tasks);` // Stub owner search to return an empty result page |

**Block 3** — [CALL] (controller request execution) (L161)

> Sends the owner search request with a last name that is expected to produce no matches.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname"))` // Execute the search form submission against the controller |

**Block 4** — [CALL] (HTTP status assertion) (L162)

> Confirms that the controller returns a successful response instead of redirecting.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.andExpect(status().isOk())` // Expect HTTP 200 OK |

**Block 5** — [CALL] (model validation assertion) (L163-L164)

> Verifies that the controller attaches a field-level validation error to the owner's last name.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "lastName"))` // Expect a validation error on owner.lastName |
| 2 | CALL | `.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))` // Expect the notFound validation code |

**Block 6** — [CALL] (view assertion) (L165)

> Confirms that the user remains on the owner search page after no matches are found.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.andExpect(view().name("owners/findOwners"));` // Return the owner search view |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Entity | Pet owner record in the clinic system |
| `lastName` | Field | Owner surname used as the search key |
| `Unknown Surname` | Business value | Test input that represents a search term with no matching owner records |
| `findByLastNameStartingWith` | Repository method | Searches owners by the beginning of their last name |
| `Page<Owner>` | Technical type | Paginated owner search result set |
| `PageImpl` | Technical type | Concrete Spring Data implementation used to construct a paginated result |
| `MockMvc` | Technical component | Spring test framework component for exercising controller endpoints |
| `notFound` | Validation code | Error code used when a searched owner cannot be found |
| `owners/findOwners` | View name | Owner search page shown when the lookup returns no matches |
| `GET /owners?page=1` | HTTP request | Owner search request with pagination enabled |
