# (DD37) Business Logic — OwnerControllerTests.processFindFormNoOwnersFound() [11 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.processFindFormNoOwnersFound()

This test method verifies the negative-path behavior of the owner search workflow when a user searches for an owner by last name and no matching owners exist. In business terms, it simulates a customer service or clinic staff lookup request where the entered surname produces an empty result set, and the application must respond by keeping the user on the search screen and showing a validation-style “not found” error on the `lastName` field.

The method does not implement production business logic itself; instead, it acts as an executable specification for the controller’s search-and-validate pattern. It confirms that the owner search operation delegates to the repository with paging, receives an empty page, and then routes the user experience into the form error state rather than an empty listing state. This is a routing/dispatch test for the controller’s behavior under a no-match condition.

The larger system role is to protect the user experience of the owner lookup screen by ensuring that a failed search is communicated as a field-level business validation issue. The assertion set confirms three outcomes at once: HTTP success, model validation error presence, and correct view resolution back to the search form. That combination ensures the controller’s negative branch remains stable for regression coverage.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["processFindFormNoOwnersFound()"]
    A["Prepare empty Page<Owner> result"]
    B["Stub owners.findByLastNameStartingWith('Unknown Surname', Pageable) to return empty page"]
    C["Send GET /owners?page=1 with lastName = Unknown Surname"]
    D["Controller invokes findPaginatedForOwnersLastName(page=1, lastname='Unknown Surname')"]
    E["Repository call owners.findByLastNameStartingWith(lastname, pageable)"]
    F{"Are any owners found?"}
    G["Add field error on owner.lastName with code notFound"]
    H["Return view owners/findOwners"]
    I["Assert HTTP 200, model field error, error code, and view name"]
    START --> A
    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    G --> H
    H --> I
```

**CRITICAL — Constant Resolution:**
The method does not branch on application constants in the test body. The only business value-driven branch is the empty-result condition triggered by the `Unknown Surname` input and the controller’s `notFound` model error code.

## 3. Parameter Analysis

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

This test method has no parameters. Its behavior is driven by local test fixtures, a stubbed repository response, and the mock HTTP request sent through `MockMvc`. External state read by the method includes the mocked `owners` repository, the `MockMvc` test harness, and the controller’s search endpoint mapping.

## 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.
Use the pre-computed evidence above. If SC Code or Entity/DB is missing, try to infer from:
- The **SC Code** (Service Component code, e.g., `EKK0361A010SC`, `EKK1081D010CBS`) — look at the class name of the called method or its containing class.
- The **Entity/DB tables** — search for table name constants (often `KK_T_*` pattern), SQL references, or entity names in the called method’s source code.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `owners.findByLastNameStartingWith` | `OwnerRepository` | `Owner` | Reads owners by last-name prefix to support the search form lookup path. |
| R | `mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname"))` | `MockMvc` | HTTP request / controller endpoint | Executes the owner search request through the web layer to verify the controller’s no-result handling. |

## 5. Dependency Trace

Trace who calls this method and what this method ultimately calls.
Use the pre-computed evidence and caller search results from Step 2 above.

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

**Instructions:**
- This method is a JUnit test method and is not invoked by application screens or batches.
- The effective runtime path under test is the controller search flow: `MockMvc.perform(get("/owners?page=1"))` -> `OwnerController.processFindForm` -> `findPaginatedForOwnersLastName` -> `OwnerRepository.findByLastNameStartingWith`.
- The method itself validates the negative branch where the repository returns no owners and the controller responds with a field error and the `owners/findOwners` view.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] `(test fixture setup)` (L158-L161)

> Prepares an empty result page and configures the repository mock to simulate a no-match surname search.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Page<Owner> tasks = new PageImpl<>(List.of());` |
| 2 | CALL | `when(this.owners.findByLastNameStartingWith(eq("Unknown Surname"), any(Pageable.class))).thenReturn(tasks);` |

**Block 2** — [CALL] `(execute controller search request)` (L162-L164)

> Sends a GET request to the owner search endpoint with the test surname and paging parameter.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mockMvc.perform(get("/owners?page=1").param("lastName", "Unknown Surname"))` |

**Block 3** — [ASSERT] `(verify response and validation outcome)` (L163-L166)

> Confirms the controller returned the expected business validation outcome for an empty search result.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.andExpect(status().isOk())` |
| 2 | CALL | `.andExpect(model().attributeHasFieldErrors("owner", "lastName"))` |
| 3 | CALL | `.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))` |
| 4 | CALL | `.andExpect(view().name("owners/findOwners"));` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `owner` | Domain object | Pet owner record used by the clinic application for customer and pet relationship management. |
| `lastName` | Field | Owner surname used as the primary search key in the lookup form. |
| `Unknown Surname` | Test data | A deliberately unmatched surname used to force the no-results business path. |
| `notFound` | Validation code | Model error code indicating that no matching owner records were found for the search criteria. |
| `owners/findOwners` | View name | Search form screen for locating owners by surname. |
| `MockMvc` | Test framework | Spring web test harness used to simulate HTTP requests against the controller. |
| `Page` | Technical term | Paged result wrapper used to model searchable collections with pagination metadata. |
| `Pageable` | Technical term | Pagination request descriptor containing page number and page size. |
| `OwnerRepository` | Repository | Data-access component that retrieves owner records from the persistence layer. |
| `findByLastNameStartingWith` | Repository method | Search operation that returns owners whose last name begins with the supplied prefix. |
| `HTTP 200` | Protocol status | Successful web response indicating the controller handled the request without transport-level failure. |
| `prefix search` | Business term | A search pattern that matches records starting with the provided text, useful for partial surname lookup. |
| `validation error` | Business term | User-facing indication that the search criteria did not produce a valid result set. |
