enable Hibernate validation
This commit is contained in:
@@ -11,7 +11,7 @@ final class RuntimeClasspathValidator {
|
|||||||
if (!resourceExists("application.yml")) {
|
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.");
|
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.");
|
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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
|
|||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class AppointmentRequest {
|
public class AppointmentRequest {
|
||||||
@@ -25,7 +24,7 @@ public class AppointmentRequest {
|
|||||||
@NotNull(message = "Appointment status is required")
|
@NotNull(message = "Appointment status is required")
|
||||||
private String appointmentStatus;
|
private String appointmentStatus;
|
||||||
|
|
||||||
private List<Long> petIds;
|
private Long petId;
|
||||||
|
|
||||||
private Long employeeId;
|
private Long employeeId;
|
||||||
|
|
||||||
@@ -77,12 +76,12 @@ public class AppointmentRequest {
|
|||||||
this.appointmentStatus = appointmentStatus;
|
this.appointmentStatus = appointmentStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getPetIds() {
|
public Long getPetId() {
|
||||||
return petIds;
|
return petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPetIds(List<Long> petIds) {
|
public void setPetId(Long petId) {
|
||||||
this.petIds = petIds;
|
this.petId = petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getEmployeeId() {
|
public Long getEmployeeId() {
|
||||||
@@ -104,13 +103,13 @@ public class AppointmentRequest {
|
|||||||
Objects.equals(appointmentDate, that.appointmentDate) &&
|
Objects.equals(appointmentDate, that.appointmentDate) &&
|
||||||
Objects.equals(appointmentTime, that.appointmentTime) &&
|
Objects.equals(appointmentTime, that.appointmentTime) &&
|
||||||
Objects.equals(appointmentStatus, that.appointmentStatus) &&
|
Objects.equals(appointmentStatus, that.appointmentStatus) &&
|
||||||
Objects.equals(petIds, that.petIds) &&
|
Objects.equals(petId, that.petId) &&
|
||||||
Objects.equals(employeeId, that.employeeId);
|
Objects.equals(employeeId, that.employeeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
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
|
@Override
|
||||||
@@ -122,7 +121,7 @@ public class AppointmentRequest {
|
|||||||
", appointmentDate=" + appointmentDate +
|
", appointmentDate=" + appointmentDate +
|
||||||
", appointmentTime=" + appointmentTime +
|
", appointmentTime=" + appointmentTime +
|
||||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||||
", petIds=" + petIds +
|
", petId=" + petId +
|
||||||
", employeeId=" + employeeId +
|
", employeeId=" + employeeId +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class AppointmentResponse {
|
public class AppointmentResponse {
|
||||||
@@ -19,15 +18,15 @@ public class AppointmentResponse {
|
|||||||
private String appointmentStatus;
|
private String appointmentStatus;
|
||||||
private Long employeeId;
|
private Long employeeId;
|
||||||
private String employeeName;
|
private String employeeName;
|
||||||
private List<String> petNames;
|
private String petName;
|
||||||
private List<Long> petIds;
|
private Long petId;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
public AppointmentResponse() {
|
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.appointmentId = appointmentId;
|
||||||
this.customerId = customerId;
|
this.customerId = customerId;
|
||||||
this.customerName = customerName;
|
this.customerName = customerName;
|
||||||
@@ -38,8 +37,8 @@ public class AppointmentResponse {
|
|||||||
this.appointmentDate = appointmentDate;
|
this.appointmentDate = appointmentDate;
|
||||||
this.appointmentTime = appointmentTime;
|
this.appointmentTime = appointmentTime;
|
||||||
this.appointmentStatus = appointmentStatus;
|
this.appointmentStatus = appointmentStatus;
|
||||||
this.petNames = petNames;
|
this.petName = petName;
|
||||||
this.petIds = petIds;
|
this.petId = petId;
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
this.updatedAt = updatedAt;
|
this.updatedAt = updatedAt;
|
||||||
}
|
}
|
||||||
@@ -140,20 +139,20 @@ public class AppointmentResponse {
|
|||||||
this.employeeName = employeeName;
|
this.employeeName = employeeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getPetNames() {
|
public String getPetName() {
|
||||||
return petNames;
|
return petName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPetNames(List<String> petNames) {
|
public void setPetName(String petName) {
|
||||||
this.petNames = petNames;
|
this.petName = petName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getPetIds() {
|
public Long getPetId() {
|
||||||
return petIds;
|
return petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPetIds(List<Long> petIds) {
|
public void setPetId(Long petId) {
|
||||||
this.petIds = petIds;
|
this.petId = petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
@@ -177,12 +176,12 @@ public class AppointmentResponse {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
AppointmentResponse that = (AppointmentResponse) o;
|
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
|
@Override
|
||||||
public int hashCode() {
|
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
|
@Override
|
||||||
@@ -198,8 +197,8 @@ public class AppointmentResponse {
|
|||||||
", appointmentDate=" + appointmentDate +
|
", appointmentDate=" + appointmentDate +
|
||||||
", appointmentTime=" + appointmentTime +
|
", appointmentTime=" + appointmentTime +
|
||||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||||
", petNames=" + petNames +
|
", petName='" + petName + '\'' +
|
||||||
", petIds=" + petIds +
|
", petId=" + petId +
|
||||||
", createdAt=" + createdAt +
|
", createdAt=" + createdAt +
|
||||||
", updatedAt=" + updatedAt +
|
", updatedAt=" + updatedAt +
|
||||||
'}';
|
'}';
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ import org.hibernate.annotations.UpdateTimestamp;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "appointment")
|
@Table(name = "appointment")
|
||||||
@@ -44,13 +42,9 @@ public class Appointment {
|
|||||||
@Column(nullable = false, length = 20)
|
@Column(nullable = false, length = 20)
|
||||||
private String appointmentStatus;
|
private String appointmentStatus;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToOne
|
||||||
@JoinTable(
|
@JoinColumn(name = "petId")
|
||||||
name = "appointmentPet",
|
private Pet pet;
|
||||||
joinColumns = @JoinColumn(name = "appointmentId"),
|
|
||||||
inverseJoinColumns = @JoinColumn(name = "petId")
|
|
||||||
)
|
|
||||||
private Set<Pet> pets = new HashSet<>();
|
|
||||||
|
|
||||||
@CreationTimestamp
|
@CreationTimestamp
|
||||||
@Column(name = "created_at", updatable = false)
|
@Column(name = "created_at", updatable = false)
|
||||||
@@ -127,12 +121,12 @@ public class Appointment {
|
|||||||
this.appointmentStatus = appointmentStatus;
|
this.appointmentStatus = appointmentStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Pet> getPets() {
|
public Pet getPet() {
|
||||||
return pets;
|
return pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPets(Set<Pet> pets) {
|
public void setPet(Pet pet) {
|
||||||
this.pets = pets;
|
this.pet = pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
@@ -175,7 +169,7 @@ public class Appointment {
|
|||||||
", appointmentDate=" + appointmentDate +
|
", appointmentDate=" + appointmentDate +
|
||||||
", appointmentTime=" + appointmentTime +
|
", appointmentTime=" + appointmentTime +
|
||||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||||
", pets=" + pets +
|
", pet=" + pet +
|
||||||
", createdAt=" + createdAt +
|
", createdAt=" + createdAt +
|
||||||
", updatedAt=" + updatedAt +
|
", updatedAt=" + updatedAt +
|
||||||
'}';
|
'}';
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ spring:
|
|||||||
|
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: none
|
ddl-auto: validate
|
||||||
naming:
|
naming:
|
||||||
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
||||||
show-sql: ${JPA_SHOW_SQL:false}
|
show-sql: ${JPA_SHOW_SQL:false}
|
||||||
@@ -32,7 +32,7 @@ spring:
|
|||||||
flyway:
|
flyway:
|
||||||
enabled: true
|
enabled: true
|
||||||
baseline-on-migrate: true
|
baseline-on-migrate: true
|
||||||
baseline-version: 0
|
baseline-version: 1
|
||||||
|
|
||||||
server:
|
server:
|
||||||
port: ${SERVER_PORT:8080}
|
port: ${SERVER_PORT:8080}
|
||||||
|
|||||||
@@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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()))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user