From 0cc4a2bedd5f843d2580f531932e172baa821483 Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Mon, 6 Apr 2026 15:50:45 -0600 Subject: [PATCH] Pet owner and store --- backend/petshop-api.postman_collection.json | 29 +++++-- .../backend/controller/PetController.java | 3 +- .../petshop/backend/dto/pet/PetRequest.java | 20 +++++ .../petshop/backend/dto/pet/PetResponse.java | 50 +++++++++++- .../java/com/petshop/backend/entity/Pet.java | 24 ++++++ .../backend/repository/PetRepository.java | 12 +-- .../petshop/backend/service/PetService.java | 80 +++++++++++++++++-- .../db/migration/V19__pet_owner_and_store.sql | 23 ++++++ .../backend/service/PetServiceTest.java | 28 ++++--- 9 files changed, 236 insertions(+), 33 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V19__pet_owner_and_store.sql diff --git a/backend/petshop-api.postman_collection.json b/backend/petshop-api.postman_collection.json index 73fed551..1068f4e0 100644 --- a/backend/petshop-api.postman_collection.json +++ b/backend/petshop-api.postman_collection.json @@ -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; });" ] } } diff --git a/backend/src/main/java/com/petshop/backend/controller/PetController.java b/backend/src/main/java/com/petshop/backend/controller/PetController.java index 9fb93f0b..60f9a5e4 100644 --- a/backend/src/main/java/com/petshop/backend/controller/PetController.java +++ b/backend/src/main/java/com/petshop/backend/controller/PetController.java @@ -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}") diff --git a/backend/src/main/java/com/petshop/backend/dto/pet/PetRequest.java b/backend/src/main/java/com/petshop/backend/dto/pet/PetRequest.java index db3f71c9..9a92581a 100644 --- a/backend/src/main/java/com/petshop/backend/dto/pet/PetRequest.java +++ b/backend/src/main/java/com/petshop/backend/dto/pet/PetRequest.java @@ -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; diff --git a/backend/src/main/java/com/petshop/backend/dto/pet/PetResponse.java b/backend/src/main/java/com/petshop/backend/dto/pet/PetResponse.java index e3213653..b7113bb1 100644 --- a/backend/src/main/java/com/petshop/backend/dto/pet/PetResponse.java +++ b/backend/src/main/java/com/petshop/backend/dto/pet/PetResponse.java @@ -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 + '\'' + '}'; } } diff --git a/backend/src/main/java/com/petshop/backend/entity/Pet.java b/backend/src/main/java/com/petshop/backend/entity/Pet.java index 8f6a6020..d0b3b3fc 100644 --- a/backend/src/main/java/com/petshop/backend/entity/Pet.java +++ b/backend/src/main/java/com/petshop/backend/entity/Pet.java @@ -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; diff --git a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java index 468c0c9d..d01c2d85 100644 --- a/backend/src/main/java/com/petshop/backend/repository/PetRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/PetRepository.java @@ -18,16 +18,18 @@ public interface PetRepository extends JpaRepository { @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 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 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 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 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))") diff --git a/backend/src/main/java/com/petshop/backend/service/PetService.java b/backend/src/main/java/com/petshop/backend/service/PetService.java index dc5fa61e..7d038ed4 100644 --- a/backend/src/main/java/com/petshop/backend/service/PetService.java +++ b/backend/src/main/java/com/petshop/backend/service/PetService.java @@ -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 getAllPets(String query, String species, String status, Pageable pageable) { + @Transactional(readOnly = true) + public Page 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) { } diff --git a/backend/src/main/resources/db/migration/V19__pet_owner_and_store.sql b/backend/src/main/resources/db/migration/V19__pet_owner_and_store.sql new file mode 100644 index 00000000..918ed375 --- /dev/null +++ b/backend/src/main/resources/db/migration/V19__pet_owner_and_store.sql @@ -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'; diff --git a/backend/src/test/java/com/petshop/backend/service/PetServiceTest.java b/backend/src/test/java/com/petshop/backend/service/PetServiceTest.java index 9107ebd9..6a80e9ca 100644 --- a/backend/src/test/java/com/petshop/backend/service/PetServiceTest.java +++ b/backend/src/test/java/com/petshop/backend/service/PetServiceTest.java @@ -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