Pet owner store #139
@@ -564,7 +564,7 @@
|
||||
"name": "Get All Pets",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "{{baseUrl}}/api/v1/pets",
|
||||
"url": "{{baseUrl}}/api/v1/pets?status=available&storeId=1",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
@@ -585,7 +585,10 @@
|
||||
"exec": [
|
||||
"pm.test('Status code is 200', function () {",
|
||||
" pm.response.to.have.status(200);",
|
||||
"});"
|
||||
"});",
|
||||
"var json = pm.response.json();",
|
||||
"pm.test('is page response', function () { pm.expect(json.content).to.be.an('array'); });",
|
||||
"pm.test('all pets have storeName', function () { json.content.forEach(function(p) { pm.expect(p).to.have.property('storeName'); }); });"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -616,7 +619,10 @@
|
||||
"exec": [
|
||||
"pm.test('Status code is 200', function () {",
|
||||
" pm.response.to.have.status(200);",
|
||||
"});"
|
||||
"});",
|
||||
"var json = pm.response.json();",
|
||||
"pm.test('has petId', function () { pm.expect(json.petId).to.be.a('number'); });",
|
||||
"pm.test('has owner fields', function () { pm.expect(json).to.have.all.keys('petId','petName','petSpecies','petBreed','petAge','petStatus','petPrice','imageUrl','createdAt','updatedAt','customerId','customerName','storeId','storeName'); });"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -671,7 +677,7 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"petName\": \"Postman Pet\",\n \"petSpecies\": \"Dog\",\n \"petBreed\": \"Mixed\",\n \"petAge\": 2,\n \"petStatus\": \"Available\",\n \"petPrice\": 350.00\n}",
|
||||
"raw": "{\n \"petName\": \"Postman Pet\",\n \"petSpecies\": \"Dog\",\n \"petBreed\": \"Mixed\",\n \"petAge\": 2,\n \"petStatus\": \"Available\",\n \"petPrice\": 350.00,\n \"storeId\": 1\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
@@ -689,7 +695,11 @@
|
||||
" pm.response.to.have.status(201);",
|
||||
"});",
|
||||
"var jsonData = pm.response.json();",
|
||||
"if (jsonData.petId !== undefined) pm.collectionVariables.set('petId', jsonData.petId);"
|
||||
"if (jsonData.petId !== undefined) pm.collectionVariables.set('petId', jsonData.petId);",
|
||||
"pm.test('has petId', function () { pm.expect(jsonData.petId).to.be.a('number'); });",
|
||||
"pm.test('has storeId', function () { pm.expect(jsonData.storeId).to.equal(1); });",
|
||||
"pm.test('has storeName', function () { pm.expect(jsonData.storeName).to.be.a('string'); });",
|
||||
"pm.test('customerId is null', function () { pm.expect(jsonData.customerId).to.be.null; });"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -713,7 +723,7 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"petName\": \"Postman Pet Updated\",\n \"petSpecies\": \"Dog\",\n \"petBreed\": \"Mixed\",\n \"petAge\": 3,\n \"petStatus\": \"Available\",\n \"petPrice\": 375.00\n}",
|
||||
"raw": "{\n \"petName\": \"Postman Pet Updated\",\n \"petSpecies\": \"Dog\",\n \"petBreed\": \"Mixed\",\n \"petAge\": 3,\n \"petStatus\": \"Owned\",\n \"petPrice\": 375.00,\n \"customerId\": 1\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
@@ -729,7 +739,12 @@
|
||||
"exec": [
|
||||
"pm.test('Status code is 200', function () {",
|
||||
" pm.response.to.have.status(200);",
|
||||
"});"
|
||||
"});",
|
||||
"var json = pm.response.json();",
|
||||
"pm.test('status is Owned', function () { pm.expect(json.petStatus).to.equal('Owned'); });",
|
||||
"pm.test('has customerId', function () { pm.expect(json.customerId).to.be.a('number'); });",
|
||||
"pm.test('has customerName', function () { pm.expect(json.customerName).to.be.a('string'); });",
|
||||
"pm.test('storeId is null', function () { pm.expect(json.storeId).to.be.null; });"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@ public class PetController {
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) String species,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(petService.getAllPets(q, species, status, pageable));
|
||||
return ResponseEntity.ok(petService.getAllPets(q, species, status, storeId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -23,6 +23,10 @@ public class PetRequest {
|
||||
|
||||
private BigDecimal petPrice;
|
||||
|
||||
private Long customerId;
|
||||
|
||||
private Long storeId;
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
@@ -71,6 +75,22 @@ public class PetRequest {
|
||||
this.petPrice = petPrice;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -15,11 +15,15 @@ public class PetResponse {
|
||||
private String imageUrl;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
private Long customerId;
|
||||
private String customerName;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
|
||||
public PetResponse() {
|
||||
}
|
||||
|
||||
public PetResponse(Long petId, String petName, String petSpecies, String petBreed, Integer petAge, String petStatus, BigDecimal petPrice, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public PetResponse(Long petId, String petName, String petSpecies, String petBreed, Integer petAge, String petStatus, BigDecimal petPrice, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt, Long customerId, String customerName, Long storeId, String storeName) {
|
||||
this.petId = petId;
|
||||
this.petName = petName;
|
||||
this.petSpecies = petSpecies;
|
||||
@@ -30,6 +34,10 @@ public class PetResponse {
|
||||
this.imageUrl = imageUrl;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
public Long getPetId() {
|
||||
@@ -112,17 +120,49 @@ public class PetResponse {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PetResponse that = (PetResponse) o;
|
||||
return Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(petSpecies, that.petSpecies) && Objects.equals(petBreed, that.petBreed) && Objects.equals(petAge, that.petAge) && Objects.equals(petStatus, that.petStatus) && Objects.equals(petPrice, that.petPrice) && Objects.equals(imageUrl, that.imageUrl) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(petSpecies, that.petSpecies) && Objects.equals(petBreed, that.petBreed) && Objects.equals(petAge, that.petAge) && Objects.equals(petStatus, that.petStatus) && Objects.equals(petPrice, that.petPrice) && Objects.equals(imageUrl, that.imageUrl) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(petId, petName, petSpecies, petBreed, petAge, petStatus, petPrice, imageUrl, createdAt, updatedAt);
|
||||
return Objects.hash(petId, petName, petSpecies, petBreed, petAge, petStatus, petPrice, imageUrl, createdAt, updatedAt, customerId, customerName, storeId, storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,6 +178,10 @@ public class PetResponse {
|
||||
", imageUrl='" + imageUrl + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
", customerId=" + customerId +
|
||||
", customerName='" + customerName + '\'' +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,14 @@ public class Pet {
|
||||
@Column(length = 255)
|
||||
private String imageUrl;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "customerId")
|
||||
private Customer customer;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@@ -142,6 +150,22 @@ public class Pet {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public StoreLocation getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(StoreLocation store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -18,16 +18,18 @@ public interface PetRepository extends JpaRepository<Pet, Long> {
|
||||
@Query("SELECT p FROM Pet p WHERE " +
|
||||
"(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " +
|
||||
"(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status))")
|
||||
Page<Pet> searchPets(@Param("q") String query, @Param("species") String species, @Param("status") String status, Pageable pageable);
|
||||
"(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status)) AND " +
|
||||
"(:storeId IS NULL OR p.store.storeId = :storeId)")
|
||||
Page<Pet> searchPets(@Param("q") String query, @Param("species") String species, @Param("status") String status, @Param("storeId") Long storeId, Pageable pageable);
|
||||
|
||||
@Query("SELECT p FROM Pet p WHERE LOWER(p.petStatus) = 'available' AND " +
|
||||
"(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species))")
|
||||
Page<Pet> searchPublicPets(@Param("q") String query, @Param("species") String species, Pageable pageable);
|
||||
"(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " +
|
||||
"(:storeId IS NULL OR p.store.storeId = :storeId)")
|
||||
Page<Pet> searchPublicPets(@Param("q") String query, @Param("species") String species, @Param("storeId") Long storeId, Pageable pageable);
|
||||
|
||||
@Query("SELECT DISTINCT p FROM Pet p LEFT JOIN Adoption a ON a.pet = p AND LOWER(a.adoptionStatus) = 'completed' WHERE " +
|
||||
"(LOWER(p.petStatus) = 'available' OR a.customer.userId = :userId) AND " +
|
||||
"(LOWER(p.petStatus) = 'available' OR a.customer.userId = :userId OR (LOWER(p.petStatus) = 'owned' AND p.customer.userId = :userId)) AND " +
|
||||
"(:q IS NULL OR LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:species IS NULL OR LOWER(p.petSpecies) = LOWER(:species)) AND " +
|
||||
"(:status IS NULL OR LOWER(p.petStatus) = LOWER(:status))")
|
||||
|
||||
@@ -4,12 +4,16 @@ import com.petshop.backend.dto.common.BulkDeleteRequest;
|
||||
import com.petshop.backend.dto.pet.PetRequest;
|
||||
import com.petshop.backend.dto.pet.PetResponse;
|
||||
import com.petshop.backend.entity.Adoption;
|
||||
import com.petshop.backend.entity.Customer;
|
||||
import com.petshop.backend.entity.Pet;
|
||||
import com.petshop.backend.entity.StoreLocation;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.security.AppPrincipal;
|
||||
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 org.springframework.core.io.Resource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -29,15 +33,20 @@ public class PetService {
|
||||
|
||||
private final PetRepository petRepository;
|
||||
private final AdoptionRepository adoptionRepository;
|
||||
private final CustomerRepository customerRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
private final CatalogImageStorageService catalogImageStorageService;
|
||||
|
||||
public PetService(PetRepository petRepository, AdoptionRepository adoptionRepository, CatalogImageStorageService catalogImageStorageService) {
|
||||
public PetService(PetRepository petRepository, AdoptionRepository adoptionRepository, CustomerRepository customerRepository, StoreRepository storeRepository, CatalogImageStorageService catalogImageStorageService) {
|
||||
this.petRepository = petRepository;
|
||||
this.adoptionRepository = adoptionRepository;
|
||||
this.customerRepository = customerRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
this.catalogImageStorageService = catalogImageStorageService;
|
||||
}
|
||||
|
||||
public Page<PetResponse> getAllPets(String query, String species, String status, Pageable pageable) {
|
||||
@Transactional(readOnly = true)
|
||||
public Page<PetResponse> getAllPets(String query, String species, String status, Long storeId, Pageable pageable) {
|
||||
String normalizedQuery = normalizeFilter(query);
|
||||
String normalizedSpecies = normalizeFilter(species);
|
||||
String normalizedStatus = normalizeFilter(status);
|
||||
@@ -48,22 +57,23 @@ public class PetService {
|
||||
if (!isAllowedPublicStatus(normalizedStatus)) {
|
||||
return new PageImpl<>(java.util.List.of(), pageable, 0);
|
||||
}
|
||||
pets = petRepository.searchPublicPets(normalizedQuery, normalizedSpecies, pageable);
|
||||
pets = petRepository.searchPublicPets(normalizedQuery, normalizedSpecies, storeId, pageable);
|
||||
} else if (viewer.role() == User.Role.STAFF || viewer.role() == User.Role.ADMIN) {
|
||||
pets = petRepository.searchPets(normalizedQuery, normalizedSpecies, normalizedStatus, pageable);
|
||||
pets = petRepository.searchPets(normalizedQuery, normalizedSpecies, normalizedStatus, storeId, pageable);
|
||||
} else if (viewer.role() == User.Role.CUSTOMER) {
|
||||
if (!isAllowedCustomerStatus(normalizedStatus)) {
|
||||
return new PageImpl<>(java.util.List.of(), pageable, 0);
|
||||
}
|
||||
pets = petRepository.searchCustomerVisiblePets(viewer.userId(), normalizedQuery, normalizedSpecies, normalizedStatus, pageable);
|
||||
} else {
|
||||
pets = petRepository.searchPublicPets(normalizedQuery, normalizedSpecies, pageable);
|
||||
pets = petRepository.searchPublicPets(normalizedQuery, normalizedSpecies, storeId, pageable);
|
||||
}
|
||||
|
||||
return pets
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PetResponse getPetById(Long id) {
|
||||
Pet pet = petRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + id));
|
||||
@@ -82,6 +92,7 @@ public class PetService {
|
||||
pet.setPetAge(request.getPetAge());
|
||||
pet.setPetStatus(request.getPetStatus());
|
||||
pet.setPetPrice(request.getPetPrice());
|
||||
applyOwnerAndStore(pet, request);
|
||||
|
||||
pet = petRepository.save(pet);
|
||||
return mapToResponse(pet);
|
||||
@@ -98,6 +109,7 @@ public class PetService {
|
||||
pet.setPetAge(request.getPetAge());
|
||||
pet.setPetStatus(request.getPetStatus());
|
||||
pet.setPetPrice(request.getPetPrice());
|
||||
applyOwnerAndStore(pet, request);
|
||||
|
||||
pet = petRepository.save(pet);
|
||||
return mapToResponse(pet);
|
||||
@@ -161,6 +173,9 @@ public class PetService {
|
||||
if (viewer == null || viewer.userId() == null) {
|
||||
return false;
|
||||
}
|
||||
if (isOwnedByUser(pet, viewer.userId())) {
|
||||
return true;
|
||||
}
|
||||
return isAdoptedByUser(pet, viewer.userId());
|
||||
}
|
||||
|
||||
@@ -230,7 +245,7 @@ public class PetService {
|
||||
}
|
||||
|
||||
private boolean isAllowedCustomerStatus(String status) {
|
||||
return status == null || "available".equalsIgnoreCase(status) || "adopted".equalsIgnoreCase(status);
|
||||
return status == null || "available".equalsIgnoreCase(status) || "adopted".equalsIgnoreCase(status) || "owned".equalsIgnoreCase(status);
|
||||
}
|
||||
|
||||
private String normalizeFilter(String value) {
|
||||
@@ -242,6 +257,8 @@ public class PetService {
|
||||
}
|
||||
|
||||
private PetResponse mapToResponse(Pet pet) {
|
||||
Customer customer = pet.getCustomer();
|
||||
StoreLocation store = pet.getStore();
|
||||
return new PetResponse(
|
||||
pet.getPetId(),
|
||||
pet.getPetName(),
|
||||
@@ -252,10 +269,59 @@ public class PetService {
|
||||
pet.getPetPrice(),
|
||||
pet.getImageUrl() != null && !pet.getImageUrl().isBlank() ? "/api/v1/pets/" + pet.getPetId() + "/image" : null,
|
||||
pet.getCreatedAt(),
|
||||
pet.getUpdatedAt()
|
||||
pet.getUpdatedAt(),
|
||||
customer != null ? customer.getCustomerId() : null,
|
||||
customer != null ? customer.getFirstName() + " " + customer.getLastName() : null,
|
||||
store != null ? store.getStoreId() : null,
|
||||
store != null ? store.getStoreName() : null
|
||||
);
|
||||
}
|
||||
|
||||
private void applyOwnerAndStore(Pet pet, PetRequest request) {
|
||||
if ("owned".equalsIgnoreCase(request.getPetStatus())) {
|
||||
if (request.getCustomerId() != null) {
|
||||
Customer customer = customerRepository.findById(request.getCustomerId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId()));
|
||||
pet.setCustomer(customer);
|
||||
} else {
|
||||
pet.setCustomer(null);
|
||||
}
|
||||
pet.setStore(null);
|
||||
} else if ("available".equalsIgnoreCase(request.getPetStatus()) || "unadopted".equalsIgnoreCase(request.getPetStatus())) {
|
||||
if (request.getStoreId() != null) {
|
||||
StoreLocation store = storeRepository.findById(request.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId()));
|
||||
pet.setStore(store);
|
||||
} else {
|
||||
pet.setStore(null);
|
||||
}
|
||||
pet.setCustomer(null);
|
||||
} else {
|
||||
if (request.getCustomerId() != null) {
|
||||
Customer customer = customerRepository.findById(request.getCustomerId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId()));
|
||||
pet.setCustomer(customer);
|
||||
} else {
|
||||
pet.setCustomer(null);
|
||||
}
|
||||
if (request.getStoreId() != null) {
|
||||
StoreLocation store = storeRepository.findById(request.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId()));
|
||||
pet.setStore(store);
|
||||
} else {
|
||||
pet.setStore(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOwnedByUser(Pet pet, Long userId) {
|
||||
if (!"owned".equalsIgnoreCase(normalizeStatus(pet.getPetStatus()))) {
|
||||
return false;
|
||||
}
|
||||
Customer customer = pet.getCustomer();
|
||||
return customer != null && userId.equals(customer.getUserId());
|
||||
}
|
||||
|
||||
public record ImagePayload(Resource resource, MediaType mediaType) {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
ALTER TABLE pet ADD COLUMN customerId BIGINT NULL;
|
||||
ALTER TABLE pet ADD COLUMN storeId BIGINT NULL;
|
||||
|
||||
ALTER TABLE pet ADD CONSTRAINT fk_pet_customer
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId);
|
||||
ALTER TABLE pet ADD CONSTRAINT fk_pet_store
|
||||
FOREIGN KEY (storeId) REFERENCES storeLocation(storeId);
|
||||
|
||||
CREATE INDEX idx_pet_customerId ON pet(customerId);
|
||||
CREATE INDEX idx_pet_storeId ON pet(storeId);
|
||||
|
||||
UPDATE pet
|
||||
SET storeId = (SELECT storeId FROM storeLocation ORDER BY storeId ASC LIMIT 1)
|
||||
WHERE LOWER(petStatus) IN ('available', 'unadopted');
|
||||
|
||||
UPDATE pet p
|
||||
JOIN (
|
||||
SELECT a.petId, a.customerId
|
||||
FROM adoption a
|
||||
WHERE LOWER(a.adoptionStatus) = 'completed'
|
||||
) latest ON latest.petId = p.petId
|
||||
SET p.customerId = latest.customerId
|
||||
WHERE LOWER(p.petStatus) = 'adopted';
|
||||
@@ -6,7 +6,9 @@ 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;
|
||||
@@ -39,6 +41,12 @@ class PetServiceTest {
|
||||
@Mock
|
||||
private AdoptionRepository adoptionRepository;
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@Mock
|
||||
private StoreRepository storeRepository;
|
||||
|
||||
@Mock
|
||||
private CatalogImageStorageService catalogImageStorageService;
|
||||
|
||||
@@ -54,24 +62,24 @@ class PetServiceTest {
|
||||
void getAllPetsAnonymousReturnsOnlyPublicPets() {
|
||||
Pageable pageable = PageRequest.of(0, 10);
|
||||
Pet availablePet = pet(1L, "Buddy", "Available");
|
||||
when(petRepository.searchPublicPets(null, null, pageable)).thenReturn(new PageImpl<>(List.of(availablePet), pageable, 1));
|
||||
when(petRepository.searchPublicPets(null, null, null, pageable)).thenReturn(new PageImpl<>(List.of(availablePet), pageable, 1));
|
||||
|
||||
var result = petService.getAllPets(null, null, null, pageable);
|
||||
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, pageable);
|
||||
verify(petRepository, never()).searchPets(null, null, null, pageable);
|
||||
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", pageable);
|
||||
var result = petService.getAllPets(null, null, "Adopted", null, pageable);
|
||||
|
||||
assertEquals(0, result.getTotalElements());
|
||||
verify(petRepository, never()).searchPublicPets(null, null, pageable);
|
||||
verify(petRepository, never()).searchPublicPets(null, null, null, pageable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,7 +91,7 @@ class PetServiceTest {
|
||||
when(petRepository.searchCustomerVisiblePets(25L, null, null, null, pageable))
|
||||
.thenReturn(new PageImpl<>(List.of(availablePet, adoptedPet), pageable, 2));
|
||||
|
||||
var result = petService.getAllPets(null, null, null, pageable);
|
||||
var result = petService.getAllPets(null, null, null, null, pageable);
|
||||
|
||||
assertEquals(2, result.getTotalElements());
|
||||
verify(petRepository).searchCustomerVisiblePets(25L, null, null, null, pageable);
|
||||
@@ -95,13 +103,13 @@ class PetServiceTest {
|
||||
setAuthentication(99L, User.Role.ADMIN);
|
||||
Pet availablePet = pet(1L, "Buddy", "Available");
|
||||
Pet adoptedPet = pet(2L, "Luna", "Adopted");
|
||||
when(petRepository.searchPets(null, null, null, pageable))
|
||||
when(petRepository.searchPets(null, null, null, null, pageable))
|
||||
.thenReturn(new PageImpl<>(List.of(availablePet, adoptedPet), pageable, 2));
|
||||
|
||||
var result = petService.getAllPets(null, null, null, pageable);
|
||||
var result = petService.getAllPets(null, null, null, null, pageable);
|
||||
|
||||
assertEquals(2, result.getTotalElements());
|
||||
verify(petRepository).searchPets(null, null, null, pageable);
|
||||
verify(petRepository).searchPets(null, null, null, null, pageable);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user