# (DD11) Business Logic — OwnerControllerTests.processFindFormByLastName() [8 LOC]

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

## 1. Role

### OwnerControllerTests.processFindFormByLastName()

This test method verifies the owner search-by-last-name flow exposed by the owner web controller. It configures the repository mock to return a single matching owner when the controller searches for the last name prefix `Franklin`, then drives a mock HTTP GET request to `/owners?page=1` with the search parameter `lastName=Franklin`. The business expectation is that a unique search result does not render a list page; instead, the application should redirect the user directly to that owner's detail page. In other words, the method validates the controller's one-result routing behavior for owner lookup.

The method is part of the controller test suite and supports the larger user journey of locating an owner record from a search form. It exercises the routing/dispatch branch in the controller that converts a search request into a direct owner-details redirect when exactly one owner is found. The test does not perform business persistence itself; rather, it confirms that the web layer correctly delegates to `OwnerRepository.findByLastNameStartingWith(...)` and returns the expected redirect target.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["processFindFormByLastName() test"])
    SETUP(["Create PageImpl with george() owner"])
    STUB(["Stub owners.findByLastNameStartingWith(\"Franklin\", any(Pageable.class))"])
    REQUEST(["Perform GET /owners?page=1 with lastName=Franklin"])
    CONTROLLER(["OwnerController.processFindForm(page=1, owner.lastName=Franklin)"])
    READ(["Call owners.findByLastNameStartingWith(lastName, pageable)"])
    ONE_RESULT{["Is totalElements == 1?"]}
    REDIRECT(["Return redirect:/owners/" + TEST_OWNER_ID])
    ASSERT(["Assert HTTP 3xx and redirect view name"])
    END_NODE(["Test passes"])

    START --> SETUP
    SETUP --> STUB
    STUB --> REQUEST
    REQUEST --> CONTROLLER
    CONTROLLER --> READ
    READ --> ONE_RESULT
    ONE_RESULT --> REDIRECT
    REDIRECT --> ASSERT
    ASSERT --> END_NODE
```

The tested business pattern is a search-and-route flow. The controller accepts a search criterion, queries the repository for owners whose last name starts with the supplied text, and if the result set contains exactly one owner it routes the user to the owner detail screen. This test specifically validates the single-result branch.

## 3. Parameter Analysis

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

Instance fields and external state used by the method:
- `mockMvc`: the Spring MVC test client used to simulate the browser request.
- `owners`: a Mockito repository double configured to return a search result.
- `TEST_OWNER_ID`: expected owner identifier used in the redirect assertion.
- `george()`: helper method that creates the owner record returned by the stubbed repository.

## 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` |
| - | `OwnerControllerTests.george` | OwnerControllerTests | - | Calls `george` in `OwnerControllerTests` |

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` | Searches owner records by last-name prefix for the controller search flow |
| - | `george` | `OwnerControllerTests` | - | Builds a test owner fixture containing the expected matching owner data |
| - | `mockMvc.perform` | `MockMvc` | - | Executes the HTTP GET request against the MVC layer |
| - | `status().is3xxRedirection` | `MockMvcResultMatchers` | - | Verifies that the controller returns a redirect response |
| - | `view().name` | `MockMvcResultMatchers` | - | Verifies the redirect target view string |

## 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 | Test: `OwnerControllerTests` | `OwnerControllerTests.processFindFormByLastName` | `OwnerRepository.findByLastNameStartingWith [R] Owner` |

This method is invoked only from the JUnit test runner through the test class itself. Its terminal dependency is the repository read operation that supplies the single owner result used to confirm the redirect behavior.

## 6. Per-Branch Detail Blocks

**Block 1** — SETUP `(test fixture creation)` (L150)

> Prepares a single-owner search result for the controller test.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Page<Owner> tasks = new PageImpl<>(List.of(george()));` |
| 2 | CALL | `george()` |

**Block 2** — STUB `(repository mock configuration)` (L151)

> Configures the repository mock to return the prepared owner page for the Franklin search criteria.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `when(this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))).thenReturn(tasks);` |
| 2 | CALL | `this.owners.findByLastNameStartingWith(eq("Franklin"), any(Pageable.class))` |
| 3 | CALL | `eq("Franklin")` |
| 4 | CALL | `any(Pageable.class)` |

**Block 3** — REQUEST `(MVC request execution)` (L152-L153)

> Sends the browser-equivalent request that triggers the controller's find-by-last-name flow.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mockMvc.perform(get("/owners?page=1").param("lastName", "Franklin"))` |
| 2 | CALL | `get("/owners?page=1")` |
| 3 | EXEC | `.param("lastName", "Franklin")` |

**Block 4** — ASSERT `(response verification)` (L153-L155)

> Validates that the controller routes a single match to the owner detail page via redirect.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.andExpect(status().is3xxRedirection())` |
| 2 | CALL | `status().is3xxRedirection()` |
| 3 | CALL | `.andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID))` |
| 4 | CALL | `view().name("redirect:/owners/" + TEST_OWNER_ID)` |
| 5 | SET | `"redirect:/owners/" + TEST_OWNER_ID` |

**Block 5** — END `(test completion)` (L156)

> The test ends after asserting the redirect target.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `void` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Customer record in the PetClinic owner module |
| `lastName` | Field | Owner surname used as the search criterion |
| `findByLastNameStartingWith` | Repository query method | Search for owners whose surname begins with the provided text |
| `Page` | Technical term | Paginated search result set returned by the repository |
| `Pageable` | Technical term | Pagination request describing page number and size |
| `MockMvc` | Test framework component | Spring MVC test client used to simulate HTTP requests |
| `redirect:/owners/{id}` | Web routing term | Redirect to the owner detail screen for a matched owner |
| `3xx` | HTTP status class | Redirect response family |
| `Franklin` | Test data value | Search input used to locate the sample owner George Franklin |
| `George Franklin` | Test fixture | Sample owner record returned by the repository mock |
| `TEST_OWNER_ID` | Test constant | Expected owner identifier used in the redirect assertion |
| `george()` | Test helper | Builds a reusable owner fixture with a pet and visit data |
