# (DD31) Business Logic — ClinicServiceTests.shouldInsertOwner() [18 LOC]

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

## 1. Role

### ClinicServiceTests.shouldInsertOwner()

This test verifies the owner registration flow in the PetClinic domain by proving that a new `Owner` record can be inserted and then discovered through the repository’s last-name search. Business-wise, it models the normal lifecycle of a customer master record: read the current population, create a new owner profile, persist it, and confirm that the repository now exposes one additional matching owner. The method uses a repository-driven persistence pattern rather than direct SQL, so the business rule under validation is that the owner registry accepts a new person record and immediately makes it available to search by surname.

The method covers a single business scenario with two read checks around one create operation. First, it queries for owners whose last name starts with `Schultz` and records the baseline count. Next, it constructs a complete owner profile with first name, last name, address, city, and telephone, then saves it through the repository. Finally, it re-queries the same search criteria to ensure the repository count increased by one and that the persisted entity received a generated identifier. In the larger system, this method acts as a regression test for the owner onboarding path used by the service layer and any UI or API flow that depends on owner creation and search visibility.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["shouldInsertOwner()"]
    READ1["Read existing owners by last name 'Schultz'"]
    COUNT1["Store current owner count in found"]
    NEW_OWNER["Create Owner and set first name, last name, address, city, telephone"]
    SAVE1["Persist Owner via this.owners.save(owner)"]
    ASSERT_ID["Assert inserted owner has a generated id"]
    READ2["Read owners by last name 'Schultz' again"]
    ASSERT_COUNT["Assert owner count increased by 1"]
    END_NODE["Return / Next"]

    START --> READ1
    READ1 --> COUNT1
    COUNT1 --> NEW_OWNER
    NEW_OWNER --> SAVE1
    SAVE1 --> ASSERT_ID
    ASSERT_ID --> READ2
    READ2 --> ASSERT_COUNT
    ASSERT_COUNT --> END_NODE
```

## 3. Parameter Analysis

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

This method has no explicit parameters. It operates entirely on test fixtures, injected repository state, and local variables. The external state it reads is the `owners` repository and the `pageable` paging object used for repository queries.

## 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 | `findByLastNameStartingWith` | OwnerRepository | Owner | Reads owners whose last name begins with the specified search key to establish the baseline count and verify post-insert visibility. |
| C | `save` | OwnerRepository | Owner | Persists a new owner master record so the repository assigns an identifier and stores the customer data. |
| R | `findByLastNameStartingWith` | OwnerRepository | Owner | Reads owners again after insertion to confirm that the total number of matching owners increased by one. |

## 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 | Test runner / JUnit | `ClinicServiceTests.shouldInsertOwner` | `findByLastNameStartingWith [R] Owner` |
| 2 | Test runner / JUnit | `ClinicServiceTests.shouldInsertOwner` | `save [C] Owner` |
| 3 | Test runner / JUnit | `ClinicServiceTests.shouldInsertOwner` | `findByLastNameStartingWith [R] Owner` |

## 6. Per-Branch Detail Blocks

**Block 1** — [STATEMENT] `(initialize baseline search)` (L109)

> Establishes the initial population of owners matching the target surname so the test can compare pre- and post-insert counts.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Page<Owner> owners = this.owners.findByLastNameStartingWith("Schultz", pageable);` |

**Block 2** — [STATEMENT] `(capture baseline count)` (L110)

> Stores the number of matching owners before the insert operation.

| # | Type | Code |
|---|------|------|
| 1 | SET | `int found = (int) owners.getTotalElements();` |

**Block 3** — [STATEMENT] `(create new owner master record)` (L112-L117)

> Builds a new owner profile with the business identity and contact fields required for persistence.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Owner owner = new Owner();` |
| 2 | EXEC | `owner.setFirstName("Sam");` |
| 3 | EXEC | `owner.setLastName("Schultz");` |
| 4 | EXEC | `owner.setAddress("4, Evans Street");` |
| 5 | EXEC | `owner.setCity("Wollongong");` |
| 6 | EXEC | `owner.setTelephone("4444444444");` |

**Block 4** — [STATEMENT] `(persist the new owner)` (L118)

> Saves the new owner through the repository so the data becomes part of the persistent owner registry.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `this.owners.save(owner);` |

**Block 5** — [STATEMENT] `(verify generated identifier)` (L119)

> Confirms that persistence assigned a non-zero identifier to the new owner record.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `assertThat(owner.getId()).isNotZero();` |

**Block 6** — [STATEMENT] `(repeat surname search after insert)` (L121)

> Re-reads the same owner population after the insert to verify that the registry now contains one additional match.

| # | Type | Code |
|---|------|------|
| 1 | SET | `owners = this.owners.findByLastNameStartingWith("Schultz", pageable);` |

**Block 7** — [STATEMENT] `(validate increased count)` (L122)

> Confirms the repository now returns one more matching owner than it did before the insert.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `assertThat(owners.getTotalElements()).isEqualTo(found + 1);` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain Entity | Pet owner master record containing identity and contact details for clinic customers. |
| `owners` | Repository field | Data access gateway used to search and persist owner records. |
| `findByLastNameStartingWith` | Repository method | Searches for owners whose last name begins with a given prefix. |
| `save` | Repository method | Persists a new or changed owner record to the database. |
| `pageable` | Technical term | Pagination request used to limit and structure repository search results. |
| `getTotalElements` | Technical term | Returns the total number of matching records across all pages. |
| `id` | Field | Generated database identifier for a persisted owner record. |
| `firstName` | Field | Owner’s given name used in customer identity details. |
| `lastName` | Field | Owner’s family name used for lookup and search matching. |
| `address` | Field | Owner’s street address used for contact and correspondence. |
| `city` | Field | Owner’s city used for geographic contact information. |
| `telephone` | Field | Owner’s phone number used for direct contact. |
| JUnit | Framework | Unit test framework that executes the method as part of the automated test suite. |
| transactional | Technical term | Test runs inside a transaction so database changes are rolled back after execution. |
