# (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 method verifies the owner registration flow at the persistence boundary by confirming that a newly constructed `Owner` entity can be inserted and subsequently retrieved through the owner repository search API. The business operation under test is the creation of a new pet clinic owner record with a complete set of core contact details: first name, last name, address, city, and telephone number.

The method follows a simple create-and-verify pattern. First, it measures the current number of owners whose last name begins with `Schultz`, then it inserts a new owner record with the same surname, and finally it re-queries the repository to confirm that the number of matching owners has increased by exactly one. This validates both persistence success and search visibility using the domain's last-name-prefix lookup behavior.

From a design perspective, the method acts as an integration test for the owner repository and the JPA save operation. It does not branch into multiple business variants, but it does depend on the repository's query-by-convention implementation and on generated identifier assignment after persistence. In the wider system, this test protects the owner onboarding capability used by the owner registration flow and ensures that newly added owners are discoverable through standard search screens.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["shouldInsertOwner()"])
    READ_EXISTING["Query owners by last name prefix 'Schultz'"]
    COUNT_EXISTING["Store current total owner count"]
    CREATE_OWNER["Instantiate new Owner"]
    SET_FIRST_NAME["Set firstName = 'Sam'"]
    SET_LAST_NAME["Set lastName = 'Schultz'"]
    SET_ADDRESS["Set address = '4, Evans Street'"]
    SET_CITY["Set city = 'Wollongong'"]
    SET_TELEPHONE["Set telephone = '4444444444'"]
    SAVE_OWNER["Call owners.save(owner)"]
    ASSERT_ID["Assert generated owner id is not zero"]
    REQUERY["Query owners by last name prefix 'Schultz' again"]
    ASSERT_COUNT["Assert total owner count increased by 1"]
    END_NODE(["Return"])

    START --> READ_EXISTING
    READ_EXISTING --> COUNT_EXISTING
    COUNT_EXISTING --> CREATE_OWNER
    CREATE_OWNER --> SET_FIRST_NAME
    SET_FIRST_NAME --> SET_LAST_NAME
    SET_LAST_NAME --> SET_ADDRESS
    SET_ADDRESS --> SET_CITY
    SET_CITY --> SET_TELEPHONE
    SET_TELEPHONE --> SAVE_OWNER
    SAVE_OWNER --> ASSERT_ID
    ASSERT_ID --> REQUERY
    REQUERY --> ASSERT_COUNT
    ASSERT_COUNT --> END_NODE
```

## 3. Parameter Analysis

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

This method has no parameters. It reads the injected `owners` repository field, uses the shared `pageable` test fixture for repository pagination, and relies on JPA-generated identifier state on the `Owner` entity after save.

## 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 | `findByLastNameStartingWith` | OwnerRepository | `Owner` | Reads owners whose last name starts with `Schultz` before and after the insert to measure the record count |
| C | `save` | OwnerRepository | `Owner` | Persists a new owner record and triggers identifier generation |

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

## 6. Per-Branch Detail Blocks

**Block 1** — [SEQUENCE] `(start and baseline read)` (L107-L110)

> Establishes the initial owner population size for the target surname before the insert operation.

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

**Block 2** — [SEQUENCE] `(construct new owner record)` (L112-L117)

> Creates the new owner entity and populates the required registration attributes.

| # | 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 3** — [SEQUENCE] `(persist and verify identity assignment)` (L118-L119)

> Saves the owner and confirms that the persistence layer assigned a database identifier.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `this.owners.save(owner);` |
| 2 | EXEC | `assertThat(owner.getId()).isNotZero();` |

**Block 4** — [SEQUENCE] `(requery and validate count growth)` (L121-L123)

> Repeats the surname search and verifies that the total result set increased by one after insertion.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `owners = this.owners.findByLastNameStartingWith("Schultz", pageable);` |
| 2 | EXEC | `assertThat(owners.getTotalElements()).isEqualTo(found + 1);` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Pet clinic customer record representing a person who owns one or more pets |
| `owners` | Repository field | Data access handle used to search and persist owner records |
| `findByLastNameStartingWith` | Repository query method | Lookup that returns owners whose last name begins with the supplied text |
| `save` | Repository method | Persists a new owner record and assigns a generated identifier when inserted |
| `Page` | Technical type | Paginated query result containing the matching owners and total count |
| `pageable` | Test fixture | Pagination/sorting request used to control repository query execution in the test |
| `lastName` | Field | Owner surname used as the search key in the repository query |
| `firstName` | Field | Owner given name stored on the new customer record |
| `address` | Field | Mailing street address for the owner |
| `city` | Field | Mailing city for the owner |
| `telephone` | Field | Contact phone number for the owner |
| `id` | Field | Generated primary key assigned after persistence |
| `Schultz` | Business value | Target surname used to validate before-and-after owner counts |
| `Sam` | Business value | Example first name for the newly inserted owner |
| `Wollongong` | Business value | Example city used to complete the owner profile |
| `4444444444` | Business value | Example telephone number used to complete the owner profile |
| CRUD | Acronym | Create, Read, Update, Delete — standard data operation categories |
| JUnit | Acronym | Java unit testing framework used to execute the test method |
| JPA | Acronym | Java Persistence API — object-relational persistence layer behind the repository |
| Pet Clinic | Business term | Sample veterinary clinic domain used by the application |
