enable Hibernate validation

This commit is contained in:
2026-04-06 20:46:27 -06:00
parent e291a0e999
commit f646c18035
10 changed files with 36 additions and 1099 deletions

View File

@@ -11,7 +11,7 @@ final class RuntimeClasspathValidator {
if (!resourceExists("application.yml")) {
throw new IllegalStateException("Backend resources are missing from the runtime classpath. Reimport the Maven project in IntelliJ and run the shared Maven run configuration.");
}
if (!resourceExists("db/migration/V1__baseline_schema.sql")) {
if (!resourceExists("db/migration/V1__target_baseline.sql")) {
throw new IllegalStateException("Flyway migration files are missing from the runtime classpath. Reimport the Maven project in IntelliJ and run the shared Maven run configuration.");
}
}

View File

@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
public class AppointmentRequest {
@@ -25,7 +24,7 @@ public class AppointmentRequest {
@NotNull(message = "Appointment status is required")
private String appointmentStatus;
private List<Long> petIds;
private Long petId;
private Long employeeId;
@@ -77,12 +76,12 @@ public class AppointmentRequest {
this.appointmentStatus = appointmentStatus;
}
public List<Long> getPetIds() {
return petIds;
public Long getPetId() {
return petId;
}
public void setPetIds(List<Long> petIds) {
this.petIds = petIds;
public void setPetId(Long petId) {
this.petId = petId;
}
public Long getEmployeeId() {
@@ -104,13 +103,13 @@ public class AppointmentRequest {
Objects.equals(appointmentDate, that.appointmentDate) &&
Objects.equals(appointmentTime, that.appointmentTime) &&
Objects.equals(appointmentStatus, that.appointmentStatus) &&
Objects.equals(petIds, that.petIds) &&
Objects.equals(petId, that.petId) &&
Objects.equals(employeeId, that.employeeId);
}
@Override
public int hashCode() {
return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petIds, employeeId);
return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petId, employeeId);
}
@Override
@@ -122,7 +121,7 @@ public class AppointmentRequest {
", appointmentDate=" + appointmentDate +
", appointmentTime=" + appointmentTime +
", appointmentStatus='" + appointmentStatus + '\'' +
", petIds=" + petIds +
", petId=" + petId +
", employeeId=" + employeeId +
'}';
}

View File

@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
public class AppointmentResponse {
@@ -19,15 +18,15 @@ public class AppointmentResponse {
private String appointmentStatus;
private Long employeeId;
private String employeeName;
private List<String> petNames;
private List<Long> petIds;
private String petName;
private Long petId;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public AppointmentResponse() {
}
public AppointmentResponse(Long appointmentId, Long customerId, String customerName, Long storeId, String storeName, Long serviceId, String serviceName, LocalDate appointmentDate, LocalTime appointmentTime, String appointmentStatus, List<String> petNames, List<Long> petIds, LocalDateTime createdAt, LocalDateTime updatedAt) {
public AppointmentResponse(Long appointmentId, Long customerId, String customerName, Long storeId, String storeName, Long serviceId, String serviceName, LocalDate appointmentDate, LocalTime appointmentTime, String appointmentStatus, String petName, Long petId, LocalDateTime createdAt, LocalDateTime updatedAt) {
this.appointmentId = appointmentId;
this.customerId = customerId;
this.customerName = customerName;
@@ -38,8 +37,8 @@ public class AppointmentResponse {
this.appointmentDate = appointmentDate;
this.appointmentTime = appointmentTime;
this.appointmentStatus = appointmentStatus;
this.petNames = petNames;
this.petIds = petIds;
this.petName = petName;
this.petId = petId;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
@@ -140,20 +139,20 @@ public class AppointmentResponse {
this.employeeName = employeeName;
}
public List<String> getPetNames() {
return petNames;
public String getPetName() {
return petName;
}
public void setPetNames(List<String> petNames) {
this.petNames = petNames;
public void setPetName(String petName) {
this.petName = petName;
}
public List<Long> getPetIds() {
return petIds;
public Long getPetId() {
return petId;
}
public void setPetIds(List<Long> petIds) {
this.petIds = petIds;
public void setPetId(Long petId) {
this.petId = petId;
}
public LocalDateTime getCreatedAt() {
@@ -177,12 +176,12 @@ public class AppointmentResponse {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AppointmentResponse that = (AppointmentResponse) o;
return Objects.equals(appointmentId, that.appointmentId) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(appointmentDate, that.appointmentDate) && Objects.equals(appointmentTime, that.appointmentTime) && Objects.equals(appointmentStatus, that.appointmentStatus) && Objects.equals(petNames, that.petNames) && Objects.equals(petIds, that.petIds) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
return Objects.equals(appointmentId, that.appointmentId) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(appointmentDate, that.appointmentDate) && Objects.equals(appointmentTime, that.appointmentTime) && Objects.equals(appointmentStatus, that.appointmentStatus) && Objects.equals(petName, that.petName) && Objects.equals(petId, that.petId) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
}
@Override
public int hashCode() {
return Objects.hash(appointmentId, customerId, customerName, storeId, storeName, serviceId, serviceName, appointmentDate, appointmentTime, appointmentStatus, petNames, petIds, createdAt, updatedAt);
return Objects.hash(appointmentId, customerId, customerName, storeId, storeName, serviceId, serviceName, appointmentDate, appointmentTime, appointmentStatus, petName, petId, createdAt, updatedAt);
}
@Override
@@ -198,8 +197,8 @@ public class AppointmentResponse {
", appointmentDate=" + appointmentDate +
", appointmentTime=" + appointmentTime +
", appointmentStatus='" + appointmentStatus + '\'' +
", petNames=" + petNames +
", petIds=" + petIds +
", petName='" + petName + '\'' +
", petId=" + petId +
", createdAt=" + createdAt +
", updatedAt=" + updatedAt +
'}';

View File

@@ -7,9 +7,7 @@ import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "appointment")
@@ -44,13 +42,9 @@ public class Appointment {
@Column(nullable = false, length = 20)
private String appointmentStatus;
@ManyToMany
@JoinTable(
name = "appointmentPet",
joinColumns = @JoinColumn(name = "appointmentId"),
inverseJoinColumns = @JoinColumn(name = "petId")
)
private Set<Pet> pets = new HashSet<>();
@ManyToOne
@JoinColumn(name = "petId")
private Pet pet;
@CreationTimestamp
@Column(name = "created_at", updatable = false)
@@ -127,12 +121,12 @@ public class Appointment {
this.appointmentStatus = appointmentStatus;
}
public Set<Pet> getPets() {
return pets;
public Pet getPet() {
return pet;
}
public void setPets(Set<Pet> pets) {
this.pets = pets;
public void setPet(Pet pet) {
this.pet = pet;
}
public LocalDateTime getCreatedAt() {
@@ -175,7 +169,7 @@ public class Appointment {
", appointmentDate=" + appointmentDate +
", appointmentTime=" + appointmentTime +
", appointmentStatus='" + appointmentStatus + '\'' +
", pets=" + pets +
", pet=" + pet +
", createdAt=" + createdAt +
", updatedAt=" + updatedAt +
'}';

View File

@@ -20,7 +20,7 @@ spring:
jpa:
hibernate:
ddl-auto: none
ddl-auto: validate
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: ${JPA_SHOW_SQL:false}
@@ -32,7 +32,7 @@ spring:
flyway:
enabled: true
baseline-on-migrate: true
baseline-version: 0
baseline-version: 1
server:
port: ${SERVER_PORT:8080}

View File

@@ -1,201 +0,0 @@
package com.petshop.backend.controller;
import com.petshop.backend.entity.Employee;
import com.petshop.backend.entity.EmployeeStore;
import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.StoreLocation;
import com.petshop.backend.entity.User;
import com.petshop.backend.repository.CategoryRepository;
import com.petshop.backend.repository.CustomerPetRepository;
import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.EmployeeStoreRepository;
import com.petshop.backend.repository.PetRepository;
import com.petshop.backend.repository.ProductRepository;
import com.petshop.backend.repository.ServiceRepository;
import com.petshop.backend.repository.StoreRepository;
import com.petshop.backend.repository.SupplierRepository;
import com.petshop.backend.repository.UserRepository;
import com.petshop.backend.security.AppPrincipal;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class DropdownControllerTest {
private PetRepository petRepository;
private CustomerRepository customerRepository;
private CustomerPetRepository customerPetRepository;
private ServiceRepository serviceRepository;
private ProductRepository productRepository;
private CategoryRepository categoryRepository;
private StoreRepository storeRepository;
private SupplierRepository supplierRepository;
private EmployeeStoreRepository employeeStoreRepository;
private UserRepository userRepository;
private DropdownController controller;
@BeforeEach
void setUp() {
petRepository = mock(PetRepository.class);
customerRepository = mock(CustomerRepository.class);
customerPetRepository = mock(CustomerPetRepository.class);
serviceRepository = mock(ServiceRepository.class);
productRepository = mock(ProductRepository.class);
categoryRepository = mock(CategoryRepository.class);
storeRepository = mock(StoreRepository.class);
supplierRepository = mock(SupplierRepository.class);
employeeStoreRepository = mock(EmployeeStoreRepository.class);
userRepository = mock(UserRepository.class);
controller = new DropdownController(
petRepository,
customerRepository,
customerPetRepository,
serviceRepository,
productRepository,
categoryRepository,
storeRepository,
supplierRepository,
employeeStoreRepository,
userRepository
);
}
@AfterEach
void tearDown() {
SecurityContextHolder.clearContext();
}
private void setAuthentication(Long userId, User.Role role) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
new AppPrincipal(userId, "user", role, 0),
null,
List.of()
)
);
}
@Test
void getStoreEmployeesReturnsOnlyStaffLinkedEmployees() {
StoreLocation store = new StoreLocation();
store.setStoreId(1L);
Employee staffEmployee = new Employee();
staffEmployee.setEmployeeId(7L);
staffEmployee.setUserId(7L);
staffEmployee.setFirstName("Alex");
staffEmployee.setLastName("Jones");
staffEmployee.setIsActive(true);
Employee adminEmployee = new Employee();
adminEmployee.setEmployeeId(8L);
adminEmployee.setUserId(8L);
adminEmployee.setFirstName("Admin");
adminEmployee.setLastName("Helper");
adminEmployee.setIsActive(true);
User staffUser = new User();
staffUser.setId(7L);
staffUser.setRole(User.Role.STAFF);
staffUser.setActive(true);
User adminUser = new User();
adminUser.setId(8L);
adminUser.setRole(User.Role.ADMIN);
adminUser.setActive(true);
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(staffEmployee, store), new EmployeeStore(adminEmployee, store)));
when(userRepository.findById(7L)).thenReturn(Optional.of(staffUser));
when(userRepository.findById(8L)).thenReturn(Optional.of(adminUser));
var response = controller.getStoreEmployees(1L);
assertEquals(1, response.getBody().size());
assertEquals(Long.valueOf(7L), response.getBody().get(0).getId());
}
@Test
void getStoreEmployeesReturnsAllStaffWhenStoreIdIsNull() {
StoreLocation store = new StoreLocation();
store.setStoreId(1L);
Employee staffEmployee = new Employee();
staffEmployee.setEmployeeId(7L);
staffEmployee.setUserId(7L);
staffEmployee.setFirstName("Alex");
staffEmployee.setLastName("Jones");
staffEmployee.setIsActive(true);
User staffUser = new User();
staffUser.setId(7L);
staffUser.setRole(User.Role.STAFF);
staffUser.setActive(true);
when(employeeStoreRepository.findActiveAllOrderByEmployeeEmployeeIdAsc())
.thenReturn(List.of(new EmployeeStore(staffEmployee, store)));
when(userRepository.findById(7L)).thenReturn(Optional.of(staffUser));
var response = controller.getStoreEmployees(null);
assertEquals(1, response.getBody().size());
assertEquals(Long.valueOf(7L), response.getBody().get(0).getId());
}
@Test
void getStoreEmployeesExcludesInactiveStaffUsers() {
StoreLocation store = new StoreLocation();
store.setStoreId(1L);
Employee inactiveStaffEmployee = new Employee();
inactiveStaffEmployee.setEmployeeId(7L);
inactiveStaffEmployee.setUserId(7L);
inactiveStaffEmployee.setFirstName("Alex");
inactiveStaffEmployee.setLastName("Jones");
inactiveStaffEmployee.setIsActive(true);
User inactiveStaffUser = new User();
inactiveStaffUser.setId(7L);
inactiveStaffUser.setRole(User.Role.STAFF);
inactiveStaffUser.setActive(false);
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(inactiveStaffEmployee, store)));
when(userRepository.findById(7L)).thenReturn(Optional.of(inactiveStaffUser));
var response = controller.getStoreEmployees(1L);
assertEquals(0, response.getBody().size());
}
@Test
void getAppointmentCustomersReturnsOnlyCustomersWithPetsForStaff() {
User staffUser = new User();
staffUser.setId(99L);
staffUser.setRole(User.Role.STAFF);
when(userRepository.findById(99L)).thenReturn(Optional.of(staffUser));
setAuthentication(99L, User.Role.STAFF);
Customer one = new Customer();
one.setCustomerId(1L);
one.setFirstName("Alex");
one.setLastName("Brown");
when(customerRepository.findAllWithPets()).thenReturn(List.of(one));
var response = controller.getAppointmentCustomers();
assertEquals(1, response.getBody().size());
assertEquals(Long.valueOf(1L), response.getBody().get(0).getId());
}
}

View File

@@ -1,150 +0,0 @@
package com.petshop.backend.service;
import com.petshop.backend.dto.adoption.AdoptionRequest;
import com.petshop.backend.entity.Adoption;
import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.Employee;
import com.petshop.backend.entity.Pet;
import com.petshop.backend.entity.User;
import com.petshop.backend.repository.AdoptionRepository;
import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.EmployeeRepository;
import com.petshop.backend.repository.PetRepository;
import com.petshop.backend.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.quality.Strictness;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class AdoptionServiceTest {
@Mock private AdoptionRepository adoptionRepository;
@Mock private PetRepository petRepository;
@Mock private CustomerRepository customerRepository;
@Mock private EmployeeRepository employeeRepository;
@Mock private UserRepository userRepository;
@InjectMocks
private AdoptionService adoptionService;
private Pet pet;
private Customer customer;
private Employee staffEmployee;
private Employee adminEmployee;
@BeforeEach
void setUp() {
pet = new Pet();
pet.setPetId(1L);
pet.setPetName("Buddy");
pet.setPetStatus("Available");
customer = new Customer();
customer.setCustomerId(1L);
customer.setFirstName("Pat");
customer.setLastName("Owner");
staffEmployee = new Employee();
staffEmployee.setEmployeeId(7L);
staffEmployee.setUserId(7L);
staffEmployee.setFirstName("Alex");
staffEmployee.setLastName("Jones");
staffEmployee.setIsActive(true);
adminEmployee = new Employee();
adminEmployee.setEmployeeId(8L);
adminEmployee.setUserId(8L);
adminEmployee.setFirstName("Admin");
adminEmployee.setLastName("Helper");
adminEmployee.setIsActive(true);
User staffUser = new User();
staffUser.setId(7L);
staffUser.setRole(User.Role.STAFF);
staffUser.setActive(true);
when(userRepository.findById(7L)).thenReturn(Optional.of(staffUser));
User adminUser = new User();
adminUser.setId(8L);
adminUser.setRole(User.Role.ADMIN);
adminUser.setActive(true);
when(userRepository.findById(8L)).thenReturn(Optional.of(adminUser));
}
@Test
void createAdoptionAutoAssignsFirstStaffEmployee() {
when(petRepository.findById(1L)).thenReturn(Optional.of(pet));
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(employeeRepository.findAllByIsActiveTrueOrderByEmployeeIdAsc()).thenReturn(List.of(adminEmployee, staffEmployee));
when(adoptionRepository.save(any(Adoption.class))).thenAnswer(invocation -> {
Adoption adoption = invocation.getArgument(0);
adoption.setAdoptionId(10L);
return adoption;
});
AdoptionRequest request = new AdoptionRequest();
request.setPetId(1L);
request.setCustomerId(1L);
request.setAdoptionDate(LocalDate.now());
request.setAdoptionStatus("Pending");
var response = adoptionService.createAdoption(request);
assertEquals(7L, response.getEmployeeId());
assertEquals("Alex Jones", response.getEmployeeName());
}
@Test
void createAdoptionRejectsAdminEmployeeSelection() {
when(petRepository.findById(1L)).thenReturn(Optional.of(pet));
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(employeeRepository.findById(8L)).thenReturn(Optional.of(adminEmployee));
AdoptionRequest request = new AdoptionRequest();
request.setPetId(1L);
request.setCustomerId(1L);
request.setEmployeeId(8L);
request.setAdoptionDate(LocalDate.now());
request.setAdoptionStatus("Pending");
assertThrows(IllegalArgumentException.class, () -> adoptionService.createAdoption(request));
}
@Test
void createAdoptionRejectsInactiveStaffUserSelection() {
User inactiveStaffUser = new User();
inactiveStaffUser.setId(7L);
inactiveStaffUser.setRole(User.Role.STAFF);
inactiveStaffUser.setActive(false);
when(userRepository.findById(7L)).thenReturn(Optional.of(inactiveStaffUser));
when(petRepository.findById(1L)).thenReturn(Optional.of(pet));
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(employeeRepository.findById(7L)).thenReturn(Optional.of(staffEmployee));
AdoptionRequest request = new AdoptionRequest();
request.setPetId(1L);
request.setCustomerId(1L);
request.setEmployeeId(7L);
request.setAdoptionDate(LocalDate.now());
request.setAdoptionStatus("Pending");
assertThrows(IllegalArgumentException.class, () -> adoptionService.createAdoption(request));
}
}

View File

@@ -1,332 +0,0 @@
package com.petshop.backend.service;
import com.petshop.backend.entity.Appointment;
import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.CustomerPet;
import com.petshop.backend.entity.Employee;
import com.petshop.backend.entity.EmployeeStore;
import com.petshop.backend.entity.Pet;
import com.petshop.backend.entity.Service;
import com.petshop.backend.entity.StoreLocation;
import com.petshop.backend.entity.User;
import com.petshop.backend.repository.AppointmentRepository;
import com.petshop.backend.repository.CustomerPetRepository;
import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.EmployeeRepository;
import com.petshop.backend.repository.EmployeeStoreRepository;
import com.petshop.backend.repository.PetRepository;
import com.petshop.backend.repository.ServiceRepository;
import com.petshop.backend.repository.StoreRepository;
import com.petshop.backend.repository.UserRepository;
import com.petshop.backend.security.AppPrincipal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.quality.Strictness;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class AppointmentServiceTest {
@Mock private AppointmentRepository appointmentRepository;
@Mock private CustomerRepository customerRepository;
@Mock private CustomerPetRepository customerPetRepository;
@Mock private ServiceRepository serviceRepository;
@Mock private PetRepository petRepository;
@Mock private StoreRepository storeRepository;
@Mock private UserRepository userRepository;
@Mock private EmployeeRepository employeeRepository;
@Mock private EmployeeStoreRepository employeeStoreRepository;
@InjectMocks
private AppointmentService appointmentService;
private Customer customer;
private StoreLocation store;
private Service grooming;
private Service nailTrim;
private Pet pet;
private CustomerPet customerPet;
private Employee employee;
private LocalDate date;
@BeforeEach
void setUp() {
setAuthentication(99L, User.Role.ADMIN);
User adminUser = new User();
adminUser.setId(99L);
adminUser.setRole(User.Role.ADMIN);
adminUser.setActive(true);
when(userRepository.findById(99L)).thenReturn(Optional.of(adminUser));
customer = new Customer();
customer.setCustomerId(1L);
customer.setFirstName("Pat");
customer.setLastName("Owner");
store = new StoreLocation();
store.setStoreId(1L);
store.setStoreName("Main Store");
grooming = new Service();
grooming.setServiceId(1L);
grooming.setServiceName("Grooming");
grooming.setServiceDuration(30);
nailTrim = new Service();
nailTrim.setServiceId(2L);
nailTrim.setServiceName("Nail Trim");
nailTrim.setServiceDuration(30);
pet = new Pet();
pet.setPetId(1L);
pet.setPetName("Milo");
customerPet = new CustomerPet();
customerPet.setCustomerPetId(11L);
customerPet.setPetName("Milo Jr");
customerPet.setCustomer(customer);
employee = new Employee();
employee.setEmployeeId(7L);
employee.setUserId(7L);
employee.setFirstName("Alex");
employee.setLastName("Jones");
employee.setIsActive(true);
User staffUser = new User();
staffUser.setId(7L);
staffUser.setRole(User.Role.STAFF);
staffUser.setActive(true);
when(userRepository.findById(7L)).thenReturn(Optional.of(staffUser));
date = LocalDate.now().plusDays(1);
}
@AfterEach
void tearDown() {
SecurityContextHolder.clearContext();
}
@Test
void checkAvailabilityAllowsConcurrentAppointmentsIfAnotherEmployeeFree() {
Employee employee2 = new Employee();
employee2.setEmployeeId(8L);
employee2.setUserId(8L);
employee2.setFirstName("Bob");
employee2.setIsActive(true);
User staffUser2 = new User();
staffUser2.setId(8L);
staffUser2.setRole(User.Role.STAFF);
staffUser2.setActive(true);
when(userRepository.findById(8L)).thenReturn(Optional.of(staffUser2));
Appointment existing = appointment(1L, date, LocalTime.of(10, 0), grooming, store);
when(storeRepository.findById(1L)).thenReturn(Optional.of(store));
when(serviceRepository.findById(2L)).thenReturn(Optional.of(nailTrim));
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(employee, store), new EmployeeStore(employee2, store)));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(7L, date)).thenReturn(List.of(existing));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(8L, date)).thenReturn(List.of());
List<String> slots = appointmentService.checkAvailability(1L, 2L, date);
assertTrue(slots.contains("10:00"));
}
@Test
void createAppointmentRejectsCustomerPetOwnedByDifferentCustomerForStaff() {
setAuthentication(7L, User.Role.STAFF);
when(employeeRepository.findByUserId(7L)).thenReturn(Optional.of(employee));
when(employeeStoreRepository.findByEmployeeEmployeeId(7L)).thenReturn(Optional.of(new EmployeeStore(employee, store)));
Customer otherCustomer = new Customer();
otherCustomer.setCustomerId(2L);
CustomerPet otherCustomerPet = new CustomerPet();
otherCustomerPet.setCustomerPetId(22L);
otherCustomerPet.setCustomer(otherCustomer);
otherCustomerPet.setPetName("Not Yours");
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(storeRepository.findById(1L)).thenReturn(Optional.of(store));
when(serviceRepository.findById(1L)).thenReturn(Optional.of(grooming));
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(employee, store)));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(7L, date)).thenReturn(List.of());
when(customerPetRepository.findById(22L)).thenReturn(Optional.of(otherCustomerPet));
var request = new com.petshop.backend.dto.appointment.AppointmentRequest();
request.setCustomerId(1L);
request.setStoreId(1L);
request.setServiceId(1L);
request.setAppointmentDate(date);
request.setAppointmentTime(LocalTime.of(10, 0));
request.setAppointmentStatus("Booked");
request.setCustomerPetIds(List.of(22L));
assertThrows(IllegalArgumentException.class, () -> appointmentService.createAppointment(request));
}
@Test
void createAppointmentRejectsCustomerPetOwnedByDifferentCustomer() {
setAuthentication(99L, User.Role.ADMIN);
Customer otherCustomer = new Customer();
otherCustomer.setCustomerId(2L);
CustomerPet otherCustomerPet = new CustomerPet();
otherCustomerPet.setCustomerPetId(22L);
otherCustomerPet.setCustomer(otherCustomer);
otherCustomerPet.setPetName("Not Yours");
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(storeRepository.findById(1L)).thenReturn(Optional.of(store));
when(serviceRepository.findById(1L)).thenReturn(Optional.of(grooming));
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(employee, store)));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(7L, date)).thenReturn(List.of());
when(customerPetRepository.findById(22L)).thenReturn(Optional.of(otherCustomerPet));
var request = new com.petshop.backend.dto.appointment.AppointmentRequest();
request.setCustomerId(1L);
request.setStoreId(1L);
request.setServiceId(1L);
request.setAppointmentDate(date);
request.setAppointmentTime(LocalTime.of(10, 0));
request.setAppointmentStatus("Booked");
request.setCustomerPetIds(List.of(22L));
assertThrows(IllegalArgumentException.class, () -> appointmentService.createAppointment(request));
}
@Test
void createAppointmentRejectsAdminEmployeeSelection() {
setAuthentication(99L, User.Role.ADMIN);
User adminUser = new User();
adminUser.setId(99L);
adminUser.setRole(User.Role.ADMIN);
adminUser.setActive(true);
when(userRepository.findById(99L)).thenReturn(Optional.of(adminUser));
Employee adminEmployee = new Employee();
adminEmployee.setEmployeeId(8L);
adminEmployee.setUserId(8L);
adminEmployee.setFirstName("Admin");
adminEmployee.setLastName("Helper");
adminEmployee.setIsActive(true);
User adminLinkedUser = new User();
adminLinkedUser.setId(8L);
adminLinkedUser.setRole(User.Role.ADMIN);
adminLinkedUser.setActive(true);
when(userRepository.findById(8L)).thenReturn(Optional.of(adminLinkedUser));
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(storeRepository.findById(1L)).thenReturn(Optional.of(store));
when(serviceRepository.findById(1L)).thenReturn(Optional.of(grooming));
when(employeeRepository.findById(8L)).thenReturn(Optional.of(adminEmployee));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(7L, date)).thenReturn(List.of());
when(customerPetRepository.findById(11L)).thenReturn(Optional.of(customerPet));
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(adminEmployee, store), new EmployeeStore(employee, store)));
var request = new com.petshop.backend.dto.appointment.AppointmentRequest();
request.setCustomerId(1L);
request.setStoreId(1L);
request.setServiceId(1L);
request.setEmployeeId(8L);
request.setAppointmentDate(date);
request.setAppointmentTime(LocalTime.of(10, 0));
request.setAppointmentStatus("Booked");
request.setCustomerPetIds(List.of(11L));
assertThrows(IllegalArgumentException.class, () -> appointmentService.createAppointment(request));
}
@Test
void createAppointmentRejectsInactiveStaffUserSelection() {
setAuthentication(99L, User.Role.ADMIN);
User adminUser = new User();
adminUser.setId(99L);
adminUser.setRole(User.Role.ADMIN);
adminUser.setActive(true);
when(userRepository.findById(99L)).thenReturn(Optional.of(adminUser));
User inactiveStaffUser = new User();
inactiveStaffUser.setId(7L);
inactiveStaffUser.setRole(User.Role.STAFF);
inactiveStaffUser.setActive(false);
when(userRepository.findById(7L)).thenReturn(Optional.of(inactiveStaffUser));
when(customerRepository.findById(1L)).thenReturn(Optional.of(customer));
when(storeRepository.findById(1L)).thenReturn(Optional.of(store));
when(serviceRepository.findById(1L)).thenReturn(Optional.of(grooming));
when(employeeRepository.findById(7L)).thenReturn(Optional.of(employee));
when(appointmentRepository.findByEmployeeEmployeeIdAndAppointmentDate(7L, date)).thenReturn(List.of());
when(customerPetRepository.findById(11L)).thenReturn(Optional.of(customerPet));
when(employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(1L))
.thenReturn(List.of(new EmployeeStore(employee, store)));
var request = new com.petshop.backend.dto.appointment.AppointmentRequest();
request.setCustomerId(1L);
request.setStoreId(1L);
request.setServiceId(1L);
request.setEmployeeId(7L);
request.setAppointmentDate(date);
request.setAppointmentTime(LocalTime.of(10, 0));
request.setAppointmentStatus("Booked");
request.setCustomerPetIds(List.of(11L));
assertThrows(IllegalArgumentException.class, () -> appointmentService.createAppointment(request));
}
private Appointment appointment(Long id, LocalDate date, LocalTime time, Service service, StoreLocation storeLocation) {
Appointment appointment = new Appointment();
appointment.setAppointmentId(id);
appointment.setAppointmentDate(date);
appointment.setAppointmentTime(time);
appointment.setAppointmentStatus("Booked");
appointment.setService(service);
appointment.setStore(storeLocation);
appointment.setEmployee(employee);
appointment.setCustomer(customer);
appointment.setPets(Set.of());
appointment.setCustomerPets(Set.of());
return appointment;
}
private void setAuthentication(Long userId, User.Role role) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
new AppPrincipal(userId, "user", role, 0),
"n/a",
List.of(new SimpleGrantedAuthority("ROLE_" + role.name()))
)
);
}
}

View File

@@ -1,199 +0,0 @@
package com.petshop.backend.service;
import com.petshop.backend.dto.chat.MessageRequest;
import com.petshop.backend.dto.chat.UpdateConversationRequest;
import com.petshop.backend.entity.Conversation;
import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.Message;
import com.petshop.backend.entity.User;
import com.petshop.backend.repository.ConversationRepository;
import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.MessageRepository;
import com.petshop.backend.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.access.AccessDeniedException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class ChatServiceTest {
@Mock
private ConversationRepository conversationRepository;
@Mock
private MessageRepository messageRepository;
@Mock
private UserRepository userRepository;
@Mock
private CustomerRepository customerRepository;
@InjectMocks
private ChatService chatService;
private Customer customer;
@BeforeEach
void setUp() {
customer = new Customer();
customer.setCustomerId(1L);
customer.setUserId(10L);
customer.setFirstName("Pat");
customer.setLastName("Owner");
customer.setEmail("pat@example.com");
}
@Test
void updateConversationMarksConversationClosed() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(customerRepository.findByUserId(10L)).thenReturn(Optional.of(customer));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L))
.thenReturn(List.of(message("hello")));
var response = chatService.updateConversation(99L, 10L, User.Role.CUSTOMER, new UpdateConversationRequest("CLOSED"));
assertEquals("CLOSED", response.getStatus());
assertEquals("hello", response.getLastMessage());
verify(conversationRepository).save(conversation);
}
@Test
void updateConversationRejectsOtherCustomer() {
Conversation conversation = conversation(99L, 2L, null, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(customerRepository.findByUserId(10L)).thenReturn(Optional.of(customer));
assertThrows(AccessDeniedException.class,
() -> chatService.updateConversation(99L, 10L, User.Role.CUSTOMER, new UpdateConversationRequest("CLOSED")));
}
@Test
void updateConversationIsIdempotent() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.CLOSED);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(customerRepository.findByUserId(10L)).thenReturn(Optional.of(customer));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L)).thenReturn(List.of());
var response = chatService.updateConversation(99L, 10L, User.Role.CUSTOMER, new UpdateConversationRequest("CLOSED"));
assertEquals("CLOSED", response.getStatus());
}
@Test
void staffCanCloseAssignedConversation() {
Conversation conversation = conversation(99L, 1L, 77L, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L)).thenReturn(List.of());
var response = chatService.updateConversation(99L, 77L, User.Role.STAFF, new UpdateConversationRequest("CLOSED"));
assertEquals("CLOSED", response.getStatus());
}
@Test
void staffCanCloseUnassignedConversation() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L)).thenReturn(List.of());
var response = chatService.updateConversation(99L, 77L, User.Role.STAFF, new UpdateConversationRequest("CLOSED"));
assertEquals("CLOSED", response.getStatus());
}
@Test
void adminCanCloseAnyConversation() {
Conversation conversation = conversation(99L, 2L, 88L, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L)).thenReturn(List.of());
var response = chatService.updateConversation(99L, 1L, User.Role.ADMIN, new UpdateConversationRequest("CLOSED"));
assertEquals("CLOSED", response.getStatus());
}
@Test
void updateConversationCanReopenClosedConversation() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.CLOSED);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(customerRepository.findByUserId(10L)).thenReturn(Optional.of(customer));
when(conversationRepository.save(any(Conversation.class))).thenAnswer(invocation -> invocation.getArgument(0));
when(messageRepository.findByConversationIdOrderByTimestampAsc(99L)).thenReturn(List.of());
var response = chatService.updateConversation(99L, 10L, User.Role.CUSTOMER, new UpdateConversationRequest("OPEN"));
assertEquals("OPEN", response.getStatus());
}
@Test
void updateConversationRejectsInvalidStatus() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.OPEN);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
when(customerRepository.findByUserId(10L)).thenReturn(Optional.of(customer));
assertThrows(IllegalArgumentException.class,
() -> chatService.updateConversation(99L, 10L, User.Role.CUSTOMER, new UpdateConversationRequest("INVALID")));
}
@Test
void sendMessageRejectsClosedConversation() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.CLOSED);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
assertThrows(AccessDeniedException.class,
() -> chatService.sendMessage(99L, 10L, User.Role.CUSTOMER, new MessageRequest("hello")));
verify(messageRepository, never()).save(any());
}
@Test
void requestHumanTakeoverRejectsClosedConversation() {
Conversation conversation = conversation(99L, 1L, null, Conversation.ConversationStatus.CLOSED);
when(conversationRepository.findById(99L)).thenReturn(Optional.of(conversation));
assertThrows(AccessDeniedException.class,
() -> chatService.requestHumanTakeover(99L, 10L, User.Role.CUSTOMER));
}
private Conversation conversation(Long id, Long customerId, Long staffId, Conversation.ConversationStatus status) {
Conversation conversation = new Conversation();
conversation.setId(id);
conversation.setCustomerId(customerId);
conversation.setStaffId(staffId);
conversation.setStatus(status);
conversation.setMode(Conversation.ConversationMode.AUTOMATED);
conversation.setHumanRequestedAt(LocalDateTime.now());
return conversation;
}
private Message message(String content) {
Message message = new Message();
message.setConversationId(99L);
message.setSenderId(10L);
message.setContent(content);
message.setIsRead(false);
return message;
}
}

View File

@@ -1,173 +0,0 @@
package com.petshop.backend.service;
import com.petshop.backend.entity.Adoption;
import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.Pet;
import com.petshop.backend.entity.User;
import com.petshop.backend.exception.ResourceNotFoundException;
import com.petshop.backend.repository.AdoptionRepository;
import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.PetRepository;
import com.petshop.backend.repository.StoreRepository;
import com.petshop.backend.security.AppPrincipal;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PetServiceTest {
@Mock
private PetRepository petRepository;
@Mock
private AdoptionRepository adoptionRepository;
@Mock
private CustomerRepository customerRepository;
@Mock
private StoreRepository storeRepository;
@Mock
private CatalogImageStorageService catalogImageStorageService;
@InjectMocks
private PetService petService;
@AfterEach
void tearDown() {
SecurityContextHolder.clearContext();
}
@Test
void getAllPetsAnonymousReturnsOnlyPublicPets() {
Pageable pageable = PageRequest.of(0, 10);
Pet availablePet = pet(1L, "Buddy", "Available");
when(petRepository.searchPublicPets(null, null, null, pageable)).thenReturn(new PageImpl<>(List.of(availablePet), pageable, 1));
var result = petService.getAllPets(null, null, null, null, pageable);
assertEquals(1, result.getTotalElements());
assertEquals("Buddy", result.getContent().get(0).getPetName());
verify(petRepository).searchPublicPets(null, null, null, pageable);
verify(petRepository, never()).searchPets(null, null, null, null, pageable);
}
@Test
void getAllPetsAnonymousWithAdoptedStatusReturnsEmptyPage() {
Pageable pageable = PageRequest.of(0, 10);
var result = petService.getAllPets(null, null, "Adopted", null, pageable);
assertEquals(0, result.getTotalElements());
verify(petRepository, never()).searchPublicPets(null, null, null, pageable);
}
@Test
void getAllPetsCustomerReturnsVisiblePetsOnly() {
Pageable pageable = PageRequest.of(0, 10);
setAuthentication(25L, User.Role.CUSTOMER);
Pet availablePet = pet(1L, "Buddy", "Available");
Pet adoptedPet = pet(2L, "Luna", "Adopted");
when(petRepository.searchCustomerVisiblePets(25L, null, null, null, pageable))
.thenReturn(new PageImpl<>(List.of(availablePet, adoptedPet), pageable, 2));
var result = petService.getAllPets(null, null, null, null, pageable);
assertEquals(2, result.getTotalElements());
verify(petRepository).searchCustomerVisiblePets(25L, null, null, null, pageable);
}
@Test
void getAllPetsAdminReturnsAllPets() {
Pageable pageable = PageRequest.of(0, 10);
setAuthentication(99L, User.Role.ADMIN);
Pet availablePet = pet(1L, "Buddy", "Available");
Pet adoptedPet = pet(2L, "Luna", "Adopted");
when(petRepository.searchPets(null, null, null, null, pageable))
.thenReturn(new PageImpl<>(List.of(availablePet, adoptedPet), pageable, 2));
var result = petService.getAllPets(null, null, null, null, pageable);
assertEquals(2, result.getTotalElements());
verify(petRepository).searchPets(null, null, null, null, pageable);
}
@Test
void getPetByIdHidesAdoptedPetFromUnrelatedCustomer() {
setAuthentication(50L, User.Role.CUSTOMER);
Pet adoptedPet = pet(2L, "Luna", "Adopted");
when(petRepository.findById(2L)).thenReturn(Optional.of(adoptedPet));
when(adoptionRepository.findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(2L, "Completed"))
.thenReturn(Optional.of(adoption(2L, 25L)));
assertThrows(ResourceNotFoundException.class, () -> petService.getPetById(2L));
}
@Test
void getPetByIdAllowsOwnerToSeeAdoptedPet() {
setAuthentication(25L, User.Role.CUSTOMER);
Pet adoptedPet = pet(2L, "Luna", "Adopted");
when(petRepository.findById(2L)).thenReturn(Optional.of(adoptedPet));
when(adoptionRepository.findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(2L, "Completed"))
.thenReturn(Optional.of(adoption(2L, 25L)));
var result = petService.getPetById(2L);
assertEquals(2L, result.getPetId());
}
private void setAuthentication(Long userId, User.Role role) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(
new AppPrincipal(userId, "user", role, 0),
"n/a",
List.of(new SimpleGrantedAuthority("ROLE_" + role.name()))
)
);
}
private Pet pet(Long id, String name, String status) {
Pet pet = new Pet();
pet.setPetId(id);
pet.setPetName(name);
pet.setPetSpecies("Cat");
pet.setPetBreed("Mixed");
pet.setPetAge(2);
pet.setPetStatus(status);
pet.setPetPrice(java.math.BigDecimal.TEN);
return pet;
}
private Adoption adoption(Long petId, Long userId) {
Adoption adoption = new Adoption();
Pet pet = new Pet();
pet.setPetId(petId);
adoption.setPet(pet);
Customer customer = new Customer();
customer.setCustomerId(1L);
customer.setUserId(userId);
adoption.setCustomer(customer);
adoption.setAdoptionStatus("Completed");
return adoption;
}
}