diff --git a/src/main/java/org/kakaoshare/backend/domain/funding/controller/FundingController.java b/src/main/java/org/kakaoshare/backend/domain/funding/controller/FundingController.java index 12c85a3b..b949433d 100644 --- a/src/main/java/org/kakaoshare/backend/domain/funding/controller/FundingController.java +++ b/src/main/java/org/kakaoshare/backend/domain/funding/controller/FundingController.java @@ -73,7 +73,7 @@ public ResponseEntity getFriendsActiveFundingItems(@LoggedInMember String pro @GetMapping("/members/funding/products") public ResponseEntity getMyAllFundingProducts(@LoggedInMember String providerId, - @RequestParam(name = "status", required = false, defaultValue = "PROGRESS") FundingStatus status, + @RequestParam(name = "status", required = false) FundingStatus status, @PageableDefault(size = FUNDING_DEFAULT_SIZE) final Pageable pageable) { PageResponse response = fundingService.getMyFilteredFundingProducts(providerId, status, pageable); return ResponseEntity.ok(response); diff --git a/src/main/java/org/kakaoshare/backend/domain/funding/repository/query/FundingRepositoryCustomImpl.java b/src/main/java/org/kakaoshare/backend/domain/funding/repository/query/FundingRepositoryCustomImpl.java index 41743a93..7291ad56 100644 --- a/src/main/java/org/kakaoshare/backend/domain/funding/repository/query/FundingRepositoryCustomImpl.java +++ b/src/main/java/org/kakaoshare/backend/domain/funding/repository/query/FundingRepositoryCustomImpl.java @@ -69,7 +69,19 @@ public List findAllByMemberId(Long memberId) { @Override public Page findFundingByMemberIdAndStatusWithPage(Long memberId, FundingStatus status, Pageable pageable) { - JPAQuery contentQuery = queryFactory + JPAQuery contentQuery = createFundingQuery(memberId, status, pageable); + JPAQuery countQuery = createCountQuery(memberId, status); + + return RepositoryUtils.toPage(pageable, contentQuery, countQuery); + } + + private JPAQuery createFundingQuery(Long memberId, FundingStatus status, Pageable pageable) { + BooleanExpression condition = QFunding.funding.member.memberId.eq(memberId); + if (status != null) { + condition = condition.and(QFunding.funding.status.eq(status)); + } + + return queryFactory .select(Projections.constructor( FundingResponse.class, QFunding.funding.fundingId, @@ -86,19 +98,22 @@ public Page findFundingByMemberIdAndStatusWithPage(Long memberI .from(QFunding.funding) .leftJoin(QFunding.funding.product) .on(QFunding.funding.product.productId.eq(QProduct.product.productId)) - .where(QFunding.funding.member.memberId.eq(memberId) - .and(QFunding.funding.status.eq(status))) + .where(condition) .orderBy(SortUtil.from(pageable)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()); + } + + private JPAQuery createCountQuery(Long memberId, FundingStatus status) { + BooleanExpression condition = QFunding.funding.member.memberId.eq(memberId); + if (status != null) { + condition = condition.and(QFunding.funding.status.eq(status)); + } - JPAQuery countQuery = queryFactory + return queryFactory .select(QFunding.funding.count()) .from(QFunding.funding) - .where(QFunding.funding.member.memberId.eq(memberId) - .and(QFunding.funding.status.eq(status))); - - return RepositoryUtils.toPage(pageable, contentQuery, countQuery); + .where(condition); } diff --git a/src/test/java/org/kakaoshare/backend/domain/funding/service/FundingServiceTest.java b/src/test/java/org/kakaoshare/backend/domain/funding/service/FundingServiceTest.java index 6688d153..c91a6b39 100644 --- a/src/test/java/org/kakaoshare/backend/domain/funding/service/FundingServiceTest.java +++ b/src/test/java/org/kakaoshare/backend/domain/funding/service/FundingServiceTest.java @@ -1,9 +1,13 @@ package org.kakaoshare.backend.domain.funding.service; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.kakaoshare.backend.common.dto.PageResponse; import org.kakaoshare.backend.domain.brand.entity.Brand; +import org.kakaoshare.backend.domain.funding.dto.FundingResponse; import org.kakaoshare.backend.domain.funding.dto.ProgressResponse; import org.kakaoshare.backend.domain.funding.dto.RegisterRequest; import org.kakaoshare.backend.domain.funding.dto.RegisterResponse; @@ -24,6 +28,11 @@ import java.time.LocalDate; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -76,14 +85,17 @@ void getFundingProgress_Success() { Funding funding = FundingFixture.SAMPLE_FUNDING.생성(1L, member, product); given(memberRepository.findMemberByProviderId(member.getProviderId())).willReturn(Optional.of(member)); - given(fundingRepository.findByIdAndMemberId(funding.getFundingId(), member.getMemberId())).willReturn(Optional.of(funding)); + given(fundingRepository.findByIdAndMemberId(funding.getFundingId(), member.getMemberId())).willReturn( + Optional.of(funding)); - ProgressResponse response = fundingService.getFundingItemProgress(funding.getFundingId(), member.getProviderId()); + ProgressResponse response = fundingService.getFundingItemProgress(funding.getFundingId(), + member.getProviderId()); assertThat(response).isNotNull(); verify(memberRepository).findMemberByProviderId(member.getProviderId()); } + @Test @DisplayName("나의 등록된 펀딩아이템 조회") public void testGetMyFundingProgress_WithValidData() { @@ -93,10 +105,76 @@ public void testGetMyFundingProgress_WithValidData() { Funding funding = FundingFixture.SAMPLE_FUNDING.생성(1L, member, product); when(memberRepository.findMemberByProviderId(member.getProviderId())).thenReturn(Optional.of(member)); - when(fundingRepository.findByMemberIdAndStatus(member.getMemberId(), FundingStatus.PROGRESS)).thenReturn(Optional.of(funding)); - when(fundingRepository.findByIdAndMemberId(funding.getFundingId(),member.getMemberId())).thenReturn(Optional.of(funding)); + when(fundingRepository.findByMemberIdAndStatus(member.getMemberId(), FundingStatus.PROGRESS)).thenReturn( + Optional.of(funding)); + when(fundingRepository.findByIdAndMemberId(funding.getFundingId(), member.getMemberId())).thenReturn( + Optional.of(funding)); ProgressResponse response = fundingService.getMyFundingProgress(member.getProviderId()); assertNotNull(response, "ProgressResponse should not be null"); } + + @Test + @DisplayName("내가 등록했던 펀딩아이템 목록 조회") + public void testGetMyAllFundingItems() { + Pageable pageable = PageRequest.of(0, 5); + Brand brand = BrandFixture.EDIYA.생성(1L); + Member member = MemberFixture.KAKAO.생성(); + Product product1 = ProductFixture.TEST_PRODUCT.생성(1L, brand); + Product product2 = ProductFixture.TEST_PRODUCT.생성(2L, brand); + Product product3 = ProductFixture.TEST_PRODUCT.생성(3L, brand); + Funding funding1 = FundingFixture.SAMPLE_FUNDING.생성(1L, member, product1, FundingStatus.COMPLETE); + Funding funding2 = FundingFixture.SAMPLE_FUNDING.생성(2L, member, product2, FundingStatus.PROGRESS); + Funding funding3 = FundingFixture.SAMPLE_FUNDING.생성(3L, member, product3, FundingStatus.CANCEL); + + List fundingResponses = Arrays.asList( + FundingResponse.from(funding1), + FundingResponse.from(funding2), + FundingResponse.from(funding3) + ); + Page fundingPage = new PageImpl<>(fundingResponses, pageable, fundingResponses.size()); + + when(memberRepository.findMemberByProviderId(member.getProviderId())).thenReturn(Optional.of(member)); + when(fundingRepository.findFundingByMemberIdAndStatusWithPage( + eq(member.getMemberId()), nullable(FundingStatus.class), eq(pageable))) + .thenReturn(fundingPage); + + PageResponse response = fundingService.getMyFilteredFundingProducts(member.getProviderId(), null, pageable); + + assertThat(response.getItems()).hasSize(3); + verify(fundingRepository).findFundingByMemberIdAndStatusWithPage(member.getMemberId(), null, pageable); + } + + @Test + @DisplayName("내가 등록했던 펀딩아이템 목록 조회 - CANCEL 상태만") + public void testGetMyFilteredFundingItemsForCancelStatus() { + Pageable pageable = PageRequest.of(0, 5); + Brand brand = BrandFixture.EDIYA.생성(1L); + Member member = MemberFixture.KAKAO.생성(); + Product product = ProductFixture.TEST_PRODUCT.생성(1L, brand); + Funding funding1 = FundingFixture.SAMPLE_FUNDING.생성(1L, member, product, FundingStatus.CANCEL); + Funding funding2 = FundingFixture.SAMPLE_FUNDING.생성(2L, member, product, FundingStatus.COMPLETE); + Funding funding3 = FundingFixture.SAMPLE_FUNDING.생성(3L, member, product, FundingStatus.PROGRESS); + + List fundingResponses = Arrays.asList( + FundingResponse.from(funding1), + FundingResponse.from(funding2), + FundingResponse.from(funding3) + ); + Page allFundingsPage = new PageImpl<>(fundingResponses, pageable, fundingResponses.size()); + Page cancelFundingsPage = new PageImpl<>(List.of(FundingResponse.from(funding1)), pageable, 1); + + when(memberRepository.findMemberByProviderId(member.getProviderId())).thenReturn(Optional.of(member)); + when(fundingRepository.findFundingByMemberIdAndStatusWithPage( + eq(member.getMemberId()), eq(FundingStatus.CANCEL), eq(pageable))) + .thenReturn(cancelFundingsPage); + + PageResponse response = fundingService.getMyFilteredFundingProducts(member.getProviderId(), FundingStatus.CANCEL, pageable); + + assertThat(response.getItems()).hasSize(1); + verify(fundingRepository).findFundingByMemberIdAndStatusWithPage(member.getMemberId(), FundingStatus.CANCEL, pageable); + } + + } +