diff --git a/server/src/main/java/com/project/yozmcafe/controller/CafeController.java b/server/src/main/java/com/project/yozmcafe/controller/CafeController.java index 032193fd..2a34389d 100644 --- a/server/src/main/java/com/project/yozmcafe/controller/CafeController.java +++ b/server/src/main/java/com/project/yozmcafe/controller/CafeController.java @@ -4,7 +4,6 @@ import com.project.yozmcafe.controller.dto.cafe.CafeResponse; import com.project.yozmcafe.domain.member.Member; import com.project.yozmcafe.service.CafeService; -import com.project.yozmcafe.service.MemberService; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; @@ -22,11 +21,9 @@ public class CafeController { private static final int IGNORED_PAGE = 0; private final CafeService cafeService; - private final MemberService memberService; - public CafeController(final CafeService cafeService, final MemberService memberService) { + public CafeController(final CafeService cafeService) { this.cafeService = cafeService; - this.memberService = memberService; } @GetMapping @@ -43,14 +40,6 @@ public ResponseEntity> getCafes(@PageableDefault(size = PAGE_ return ResponseEntity.ok(cafeResponses); } - @PostMapping("/{cafeId}/likes") - public ResponseEntity updateLikes(final Member member, - @PathVariable("cafeId") final long cafeId, - @RequestParam("isLiked") final boolean isLiked) { - memberService.updateLike(member, cafeId, isLiked); - return ResponseEntity.ok().build(); - } - @PostMapping public ResponseEntity saveCafe(@RequestBody CafeRequest cafeRequest) { cafeService.saveCafe(cafeRequest); diff --git a/server/src/main/java/com/project/yozmcafe/controller/LikedCafeController.java b/server/src/main/java/com/project/yozmcafe/controller/LikedCafeController.java new file mode 100644 index 00000000..73648218 --- /dev/null +++ b/server/src/main/java/com/project/yozmcafe/controller/LikedCafeController.java @@ -0,0 +1,37 @@ +package com.project.yozmcafe.controller; + +import com.project.yozmcafe.controller.dto.LikedCafeResponse; +import com.project.yozmcafe.domain.member.Member; +import com.project.yozmcafe.service.LikedCafeService; +import jakarta.websocket.server.PathParam; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +public class LikedCafeController { + + private static final int PAGE_SIZE = 15; + + private final LikedCafeService likedCafeService; + + public LikedCafeController(final LikedCafeService likedCafeService) { + this.likedCafeService = likedCafeService; + } + + @GetMapping("/members/{memberId}/liked-cafes") + public ResponseEntity> getLikedCafes(@PathVariable("memberId") final String memberId, + @PathParam("page") final int page) { + final List likedCafes = likedCafeService.findLikedCafesById(memberId, page, PAGE_SIZE); + return ResponseEntity.ok(likedCafes); + } + + @PostMapping("/cafes/{cafeId}/likes") + public ResponseEntity updateLikes(final Member member, + @PathVariable("cafeId") final long cafeId, + @RequestParam("isLiked") final boolean isLiked) { + likedCafeService.updateLike(member, cafeId, isLiked); + return ResponseEntity.ok().build(); + } +} diff --git a/server/src/main/java/com/project/yozmcafe/controller/MemberController.java b/server/src/main/java/com/project/yozmcafe/controller/MemberController.java index a96d8d5b..94888c1d 100644 --- a/server/src/main/java/com/project/yozmcafe/controller/MemberController.java +++ b/server/src/main/java/com/project/yozmcafe/controller/MemberController.java @@ -1,18 +1,13 @@ package com.project.yozmcafe.controller; -import com.project.yozmcafe.controller.dto.LikedCafeResponse; import com.project.yozmcafe.controller.dto.MemberResponse; import com.project.yozmcafe.service.MemberService; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import java.util.List; - @Controller @RequestMapping("/members") public class MemberController { @@ -28,11 +23,4 @@ public ResponseEntity findById(@PathVariable("memberId") final S final MemberResponse member = memberService.findById(memberId); return ResponseEntity.ok(member); } - - @GetMapping("/{memberId}/liked-cafes") - public ResponseEntity> getLikedCafes(@PathVariable("memberId") final String memberId, - @PageableDefault(size = 15) final Pageable pageable) { - final List likedCafes = memberService.findLikedCafesById(memberId, pageable); - return ResponseEntity.ok(likedCafes); - } } diff --git a/server/src/main/java/com/project/yozmcafe/domain/member/Member.java b/server/src/main/java/com/project/yozmcafe/domain/member/Member.java index 35be3ef6..e0484409 100644 --- a/server/src/main/java/com/project/yozmcafe/domain/member/Member.java +++ b/server/src/main/java/com/project/yozmcafe/domain/member/Member.java @@ -1,11 +1,5 @@ package com.project.yozmcafe.domain.member; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_LIKED_CAFE; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_UN_VIEWED_CAFE; - -import java.util.ArrayList; -import java.util.List; - import com.project.yozmcafe.domain.cafe.Cafe; import com.project.yozmcafe.domain.cafe.LikedCafe; import com.project.yozmcafe.domain.cafe.UnViewedCafe; @@ -13,8 +7,12 @@ import jakarta.persistence.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_LIKED_CAFE; +import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_UN_VIEWED_CAFE; + @Entity public class Member { @@ -90,7 +88,6 @@ private void removeLikedCafe(final Cafe cafe) { cafe.subtractLikeCount(); } - public void addLikedCafe(Cafe cafe) { likedCafes.add(new LikedCafe(cafe, this)); cafe.addLikeCount(); @@ -120,4 +117,14 @@ public List getUnViewedCafes() { public List getLikedCafes() { return likedCafes; } + + public List getLikedCafesByPaging(int pageNum, int pageSize) { + List reverseLikedCafes = new ArrayList<>(likedCafes); + Collections.reverse(reverseLikedCafes); + + int startIndex = (pageNum - 1) * pageSize; + int endIndex = Math.min(startIndex + pageSize, reverseLikedCafes.size()); + + return reverseLikedCafes.subList(startIndex, endIndex); + } } diff --git a/server/src/main/java/com/project/yozmcafe/domain/member/MemberRepository.java b/server/src/main/java/com/project/yozmcafe/domain/member/MemberRepository.java index 4140b47d..8639e42b 100644 --- a/server/src/main/java/com/project/yozmcafe/domain/member/MemberRepository.java +++ b/server/src/main/java/com/project/yozmcafe/domain/member/MemberRepository.java @@ -1,11 +1,6 @@ package com.project.yozmcafe.domain.member; -import com.project.yozmcafe.domain.cafe.LikedCafe; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.Optional; @@ -13,7 +8,4 @@ @Repository public interface MemberRepository extends JpaRepository { Optional findById(String id); - - @Query("SELECT likedCafes FROM Member m JOIN m.likedCafes likedCafes WHERE m.id = :memberId") - Slice findLikedCafesByMemberId(@Param("memberId") final String memberId, final Pageable pageable); } diff --git a/server/src/main/java/com/project/yozmcafe/service/LikedCafeService.java b/server/src/main/java/com/project/yozmcafe/service/LikedCafeService.java new file mode 100644 index 00000000..e32dfd1e --- /dev/null +++ b/server/src/main/java/com/project/yozmcafe/service/LikedCafeService.java @@ -0,0 +1,43 @@ +package com.project.yozmcafe.service; + +import com.project.yozmcafe.controller.dto.LikedCafeResponse; +import com.project.yozmcafe.domain.cafe.Cafe; +import com.project.yozmcafe.domain.cafe.CafeRepository; +import com.project.yozmcafe.domain.cafe.LikedCafe; +import com.project.yozmcafe.domain.member.Member; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(readOnly = true) +public class LikedCafeService { + + private final CafeRepository cafeRepository; + private final MemberService memberService; + + public LikedCafeService(final CafeRepository cafeRepository, + final MemberService memberService) { + this.cafeRepository = cafeRepository; + this.memberService = memberService; + } + + public List findLikedCafesById(final String memberId, final int pageNum, final int pageSize) { + final Member member = memberService.findMemberByIdOrElseThrow(memberId); + + final List likedCafes = member.getLikedCafesByPaging(pageNum, pageSize); + + return likedCafes.stream() + .map(LikedCafeResponse::from) + .toList(); + } + + @Transactional + public void updateLike(final Member member, final long cafeId, final boolean isLiked) { + final Cafe cafe = cafeRepository.findById(cafeId) + .orElseThrow(() -> new IllegalArgumentException("해당하는 카페가 존재하지 않습니다.")); + + member.updateLikedCafesBy(cafe, isLiked); + } +} diff --git a/server/src/main/java/com/project/yozmcafe/service/MemberService.java b/server/src/main/java/com/project/yozmcafe/service/MemberService.java index e4b44dd6..ede7c885 100644 --- a/server/src/main/java/com/project/yozmcafe/service/MemberService.java +++ b/server/src/main/java/com/project/yozmcafe/service/MemberService.java @@ -1,34 +1,22 @@ package com.project.yozmcafe.service; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_CAFE; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_MEMBER; - -import java.util.List; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.project.yozmcafe.controller.dto.LikedCafeResponse; import com.project.yozmcafe.controller.dto.MemberResponse; -import com.project.yozmcafe.domain.cafe.Cafe; -import com.project.yozmcafe.domain.cafe.CafeRepository; -import com.project.yozmcafe.domain.cafe.LikedCafe; import com.project.yozmcafe.domain.member.Member; import com.project.yozmcafe.domain.member.MemberRepository; import com.project.yozmcafe.exception.BadRequestException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_MEMBER; @Transactional(readOnly = true) @Service public class MemberService { private final MemberRepository memberRepository; - private final CafeRepository cafeRepository; - public MemberService(final MemberRepository memberRepository, final CafeRepository cafeRepository) { + public MemberService(final MemberRepository memberRepository) { this.memberRepository = memberRepository; - this.cafeRepository = cafeRepository; } public MemberResponse findById(final String memberId) { @@ -37,25 +25,8 @@ public MemberResponse findById(final String memberId) { return MemberResponse.from(member); } - public List findLikedCafesById(final String memberId, final Pageable pageable) { - final Member member = findMemberByIdOrElseThrow(memberId); - - final Slice likedCafes = memberRepository.findLikedCafesByMemberId(member.getId(), pageable); - - return likedCafes.stream() - .map(LikedCafeResponse::from) - .toList(); - } - - private Member findMemberByIdOrElseThrow(final String memberId) { + public Member findMemberByIdOrElseThrow(final String memberId) { return memberRepository.findById(memberId) .orElseThrow(() -> new BadRequestException(NOT_EXISTED_MEMBER)); } - - @Transactional - public void updateLike(final Member member, final long cafeId, final boolean isLiked) { - final Cafe cafe = cafeRepository.findById(cafeId) - .orElseThrow(() -> new BadRequestException(NOT_EXISTED_CAFE)); - member.updateLikedCafesBy(cafe, isLiked); - } } diff --git a/server/src/test/java/com/project/yozmcafe/controller/MemberControllerTest.java b/server/src/test/java/com/project/yozmcafe/controller/MemberControllerTest.java index 597d3282..3551a135 100644 --- a/server/src/test/java/com/project/yozmcafe/controller/MemberControllerTest.java +++ b/server/src/test/java/com/project/yozmcafe/controller/MemberControllerTest.java @@ -1,25 +1,5 @@ package com.project.yozmcafe.controller; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doReturn; -import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD; - -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.test.context.jdbc.Sql; - import com.project.yozmcafe.controller.dto.LikedCafeResponse; import com.project.yozmcafe.controller.dto.MemberResponse; import com.project.yozmcafe.domain.cafe.Cafe; @@ -31,9 +11,27 @@ import com.project.yozmcafe.service.auth.JwtTokenProvider; import com.project.yozmcafe.service.auth.KakaoOAuthClient; import com.project.yozmcafe.util.AcceptanceContext; - import io.restassured.RestAssured; import io.restassured.response.Response; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.context.jdbc.Sql; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doReturn; +import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Sql(scripts = {"classpath:truncate.sql"}, executionPhase = AFTER_TEST_METHOD) @@ -93,15 +91,14 @@ void getLikedCafes() { memberRepository.save(member); //when - context.invokeHttpGet("/members/{memberId}/liked-cafes?size=1&page=1", member.getId()); + context.invokeHttpGet("/members/{memberId}/liked-cafes?page=1", member.getId()); Response response = context.response; - context.invokeHttpGet("/members/{memberId}/liked-cafes?size=1&page=2", member.getId()); - Response response2 = context.response; + //then assertAll( - () -> assertThat(response.jsonPath().getLong("[0].cafeId")).isEqualTo(savedCafe1.getId()), - () -> assertThat(response2.jsonPath().getLong("[0].cafeId")).isEqualTo(savedCafe2.getId()) + () -> assertThat(response.jsonPath().getLong("[0].cafeId")).isEqualTo(savedCafe2.getId()), + () -> assertThat(response.jsonPath().getLong("[1].cafeId")).isEqualTo(savedCafe1.getId()) ); } @@ -113,7 +110,7 @@ void getLikedCafes_empty() { memberRepository.save(member); //when - context.invokeHttpGet("/members/{memberId}/liked-cafes?size=1&page=1", member.getId()); + context.invokeHttpGet("/members/{memberId}/liked-cafes?page=1", member.getId()); Response response = context.response; //then @@ -135,7 +132,7 @@ void reLoginLikedListTest() { //when context.accessToken = "accessToken"; context.invokeHttpPostWithToken("/cafes/" + cafe.getId() + "/likes?isLiked=true"); - relogin(); + reLogin(); context.invokeHttpGet("/members/{memberId}/liked-cafes?size=1&page=1", member.getId()); final List result = context.response.jsonPath().getList(""); @@ -144,8 +141,8 @@ void reLoginLikedListTest() { assertThat(result).hasSize(1); } - private Response relogin() { - return RestAssured.given() + private void reLogin() { + RestAssured.given() .log().all() .queryParam("code", "googleCode") .when() diff --git a/server/src/test/java/com/project/yozmcafe/domain/member/MemberRepositoryTest.java b/server/src/test/java/com/project/yozmcafe/domain/member/MemberRepositoryTest.java index 68cdc42c..6fe78a0e 100644 --- a/server/src/test/java/com/project/yozmcafe/domain/member/MemberRepositoryTest.java +++ b/server/src/test/java/com/project/yozmcafe/domain/member/MemberRepositoryTest.java @@ -1,21 +1,14 @@ package com.project.yozmcafe.domain.member; -import com.project.yozmcafe.domain.cafe.Cafe; -import com.project.yozmcafe.domain.cafe.CafeRepository; -import com.project.yozmcafe.domain.cafe.LikedCafe; -import com.project.yozmcafe.fixture.Fixture; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Slice; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @DataJpaTest @@ -23,8 +16,6 @@ class MemberRepositoryTest { @Autowired private MemberRepository memberRepository; - @Autowired - private CafeRepository cafeRepository; @Test @DisplayName("회원 ID로 조회") @@ -53,28 +44,4 @@ void findById_fail() { //then assertThat(persisted).isEmpty(); } - - @Test - @DisplayName("멤버의 좋아요 목록을 반환한다.") - void findLikedCafesById() { - //given - PageRequest pageRequest = PageRequest.of(0, 2); - final Cafe save1 = cafeRepository.save(Fixture.getCafe("오션의 귀여운 카페", "인천 오션동", 5)); - final Cafe save2 = cafeRepository.save(Fixture.getCafe("오션의 멋진 카페", "서울 오션동", 5)); - final Member member = new Member("1234", "오션", "오션.img"); - member.addLikedCafe(save1); - member.addLikedCafe(save2); - final Member savedMember = memberRepository.save(member); - - //when - final Slice likedCafeByMemberId = memberRepository.findLikedCafesByMemberId(savedMember.getId(), pageRequest); - - //then - assertAll( - () -> assertThat(likedCafeByMemberId.getContent()).hasSize(2), - () -> assertThat(likedCafeByMemberId.hasNext()).isFalse(), - () -> assertThat(likedCafeByMemberId.isFirst()).isTrue(), - () -> assertThat(likedCafeByMemberId.isLast()).isTrue() - ); - } } diff --git a/server/src/test/java/com/project/yozmcafe/domain/member/MemberTest.java b/server/src/test/java/com/project/yozmcafe/domain/member/MemberTest.java index 79b1c334..c7988b85 100644 --- a/server/src/test/java/com/project/yozmcafe/domain/member/MemberTest.java +++ b/server/src/test/java/com/project/yozmcafe/domain/member/MemberTest.java @@ -1,24 +1,18 @@ package com.project.yozmcafe.domain.member; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.util.List; -import java.util.stream.Stream; - +import com.project.yozmcafe.domain.cafe.Cafe; +import com.project.yozmcafe.domain.cafe.LikedCafe; +import com.project.yozmcafe.domain.cafe.UnViewedCafe; +import com.project.yozmcafe.exception.BadRequestException; +import com.project.yozmcafe.exception.ErrorCode; +import com.project.yozmcafe.fixture.Fixture; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import com.project.yozmcafe.domain.cafe.Cafe; -import com.project.yozmcafe.domain.cafe.UnViewedCafe; -import com.project.yozmcafe.exception.BadRequestException; -import com.project.yozmcafe.exception.ErrorCode; -import com.project.yozmcafe.fixture.Fixture; -import java.util.Arrays; import java.util.List; import java.util.stream.Stream; @@ -188,4 +182,25 @@ public static Stream provideMemberAndIsLiked() { Arguments.of(member2, cafe, false, false) ); } + + @Test + @DisplayName("좋아요한 카페 목록을 페이지 처리한다") + void getLikedCafesByPaging() { + //given + final Member member = new Member("1234", "오션", "오션사진"); + final Cafe cafe1 = Fixture.getCafe(1L, "카페1", "주소1", 3); + final Cafe cafe2 = Fixture.getCafe(2L, "카페2", "주소2", 3); + final Cafe cafe3 = Fixture.getCafe(3L, "카페3", "주소2", 3); + final Cafe cafe4 = Fixture.getCafe(4L, "카페4", "주소2", 3); + member.addLikedCafe(cafe1); + member.addLikedCafe(cafe2); + member.addLikedCafe(cafe3); + member.addLikedCafe(cafe4); + + //when + final List likedCafes = member.getLikedCafesByPaging(1, 2); + + //then + assertThat(likedCafes).map(LikedCafe::getCafe).containsExactly(cafe4, cafe3); + } } diff --git a/server/src/test/java/com/project/yozmcafe/service/LikedCafeServiceTest.java b/server/src/test/java/com/project/yozmcafe/service/LikedCafeServiceTest.java new file mode 100644 index 00000000..14169a39 --- /dev/null +++ b/server/src/test/java/com/project/yozmcafe/service/LikedCafeServiceTest.java @@ -0,0 +1,132 @@ +package com.project.yozmcafe.service; + +import com.project.yozmcafe.controller.dto.LikedCafeResponse; +import com.project.yozmcafe.domain.cafe.Cafe; +import com.project.yozmcafe.domain.cafe.CafeRepository; +import com.project.yozmcafe.domain.member.Member; +import com.project.yozmcafe.domain.member.MemberRepository; +import com.project.yozmcafe.exception.BadRequestException; +import com.project.yozmcafe.fixture.Fixture; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_MEMBER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +@SpringBootTest +@Transactional +class LikedCafeServiceTest { + + @Autowired + private LikedCafeService likedCafeService; + @Autowired + private MemberRepository memberRepository; + @Autowired + private CafeRepository cafeRepository; + + @Test + @DisplayName("멤버가 좋아요한 카페 목록을 조회한다.") + void findLikedCafesById() { + //given + final Cafe savedCafe = cafeRepository.save(Fixture.getCafe("오션의 귀여운 카페", "인천 오션동", 5)); + final Member member = new Member("1234", "오션", "오션.img"); + member.addLikedCafe(savedCafe); + memberRepository.save(member); + + //when + final List likedCafes = likedCafeService.findLikedCafesById(member.getId(), 1, 15); + + //then + assertThat(likedCafes.get(0).cafeId()).isEqualTo(savedCafe.getId()); + } + + @Test + @DisplayName("좋아요 카페 목록을 조회할 멤버가 없을 경우 예외가 발생한다.") + void findLikedCafesById_fail() { + //given + //when + //then + assertThatThrownBy(() -> likedCafeService.findLikedCafesById("findLikedCafesById_fail", 1, 15)) + .isInstanceOf(BadRequestException.class) + .hasMessage(NOT_EXISTED_MEMBER.getMessage()); + } + + @Test + @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하지 않고, isLiked가 true인 경우 likedCafes에 카페를 추가한다.") + void updateLikeAdd() { + //given + final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); + final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); + + //when + likedCafeService.updateLike(member, cafe.getId(), true); + final Member updatedMember = memberRepository.findById(member.getId()).get(); + + //then + assertAll( + () -> assertThat(updatedMember.getLikedCafes()).hasSize(1), + () -> assertThat(updatedMember.isLike(cafe)).isTrue(), + () -> assertThat(cafe.getLikeCount()).isEqualTo(11) + ); + } + + @Test + @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하고, isLiked가 false 경우 likedCafes에서 카페를 삭제한다.") + void updateLikeRemove() { + //given + final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); + final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); + member.addLikedCafe(cafe); + + //when + likedCafeService.updateLike(member, cafe.getId(), false); + final Member updatedMember = memberRepository.findById(member.getId()).get(); + + //then + assertAll( + () -> assertThat(updatedMember.getLikedCafes()).isEmpty(), + () -> assertThat(updatedMember.isLike(cafe)).isFalse(), + () -> assertThat(cafe.getLikeCount()).isEqualTo(10) + ); + } + + @Test + @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하고, isLiked가 true인 경우 기존의 상태를 유지한다.") + void updateLikeAlreadySatisfied() { + //given + final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); + final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); + member.addLikedCafe(cafe); + + //when + likedCafeService.updateLike(member, cafe.getId(), true); + final Member updatedMember = memberRepository.findById(member.getId()).get(); + + //then + assertAll( + () -> assertThat(updatedMember.getLikedCafes()).hasSize(1), + () -> assertThat(updatedMember.isLike(cafe)).isTrue(), + () -> assertThat(cafe.getLikeCount()).isEqualTo(11) + ); + } + + @Test + @DisplayName("좋아요 상태를 변경하려는 카페가 존재하지 않는 경우 예외가 발생한다.") + void updateLikeFail() { + //given + final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); + final Cafe cafe = Fixture.getCafe(1L, "카페", "카페주소", 10); + + //when & then + assertThatThrownBy(() -> likedCafeService.updateLike(member, cafe.getId(), true)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("해당하는 카페가 존재하지 않습니다."); + } +} diff --git a/server/src/test/java/com/project/yozmcafe/service/MemberServiceTest.java b/server/src/test/java/com/project/yozmcafe/service/MemberServiceTest.java index 5b72bd44..39c6cc0a 100644 --- a/server/src/test/java/com/project/yozmcafe/service/MemberServiceTest.java +++ b/server/src/test/java/com/project/yozmcafe/service/MemberServiceTest.java @@ -1,28 +1,18 @@ package com.project.yozmcafe.service; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_CAFE; -import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_MEMBER; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.util.List; - +import com.project.yozmcafe.controller.dto.MemberResponse; +import com.project.yozmcafe.domain.member.Member; +import com.project.yozmcafe.domain.member.MemberRepository; +import com.project.yozmcafe.exception.BadRequestException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.domain.PageRequest; import org.springframework.transaction.annotation.Transactional; -import com.project.yozmcafe.controller.dto.LikedCafeResponse; -import com.project.yozmcafe.controller.dto.MemberResponse; -import com.project.yozmcafe.domain.cafe.Cafe; -import com.project.yozmcafe.domain.cafe.CafeRepository; -import com.project.yozmcafe.domain.member.Member; -import com.project.yozmcafe.domain.member.MemberRepository; -import com.project.yozmcafe.exception.BadRequestException; -import com.project.yozmcafe.fixture.Fixture; +import static com.project.yozmcafe.exception.ErrorCode.NOT_EXISTED_MEMBER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; @SpringBootTest @Transactional @@ -32,8 +22,6 @@ class MemberServiceTest { private MemberService memberService; @Autowired private MemberRepository memberRepository; - @Autowired - private CafeRepository cafeRepository; @Test @DisplayName("아이디로 회원을 조회할 수 있다") @@ -56,105 +44,4 @@ void findById_fail() { .isInstanceOf(BadRequestException.class) .hasMessage(NOT_EXISTED_MEMBER.getMessage()); } - - @Test - @DisplayName("멤버가 좋아요한 카페 목록을 조회한다.") - void findLikedCafesById() { - //given - final Cafe savedCafe = cafeRepository.save(Fixture.getCafe("오션의 귀여운 카페", "인천 오션동", 5)); - final Member member = new Member("1234", "오션", "오션.img"); - final PageRequest pageRequest = PageRequest.of(0, 1); - member.addLikedCafe(savedCafe); - memberRepository.save(member); - - //when - final List likedCafes = memberService.findLikedCafesById(member.getId(), pageRequest); - - //then - assertThat(likedCafes.get(0).cafeId()).isEqualTo(savedCafe.getId()); - } - - @Test - @DisplayName("좋아요 카페 목록을 조회할 멤버가 없을 경우 예외가 발생한다.") - void findLikedCafesById_fail() { - //given - final PageRequest pageRequest = PageRequest.of(0, 1); - - //when & then - assertThatThrownBy(() -> memberService.findLikedCafesById("findLikedCafesById_fail", pageRequest)) - .isInstanceOf(BadRequestException.class) - .hasMessage(NOT_EXISTED_MEMBER.getMessage()); - } - - @Test - @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하지 않고, isLiked가 true인 경우 likedCafes에 카페를 추가한다.") - void updateLikeAdd() { - //given - final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); - final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); - - //when - memberService.updateLike(member, cafe.getId(), true); - final Member updatedMember = memberRepository.findById(member.getId()).get(); - - //then - assertAll( - () -> assertThat(updatedMember.getLikedCafes()).hasSize(1), - () -> assertThat(updatedMember.isLike(cafe)).isTrue(), - () -> assertThat(cafe.getLikeCount()).isEqualTo(11) - ); - } - - @Test - @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하고, isLiked가 false 경우 likedCafes에서 카페를 삭제한다.") - void updateLikeRemove() { - //given - final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); - final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); - member.addLikedCafe(cafe); - - //when - memberService.updateLike(member, cafe.getId(), false); - final Member updatedMember = memberRepository.findById(member.getId()).get(); - - //then - assertAll( - () -> assertThat(updatedMember.getLikedCafes()).isEmpty(), - () -> assertThat(updatedMember.isLike(cafe)).isFalse(), - () -> assertThat(cafe.getLikeCount()).isEqualTo(10) - ); - } - - @Test - @DisplayName("member의 likedCafes에 cafeId에 해당하는 카페가 존재하고, isLiked가 true인 경우 기존의 상태를 유지한다.") - void updateLikeAlreadySatisfied() { - //given - final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); - final Cafe cafe = cafeRepository.save(Fixture.getCafe("카페", "카페주소", 10)); - member.addLikedCafe(cafe); - - //when - memberService.updateLike(member, cafe.getId(), true); - final Member updatedMember = memberRepository.findById(member.getId()).get(); - - //then - assertAll( - () -> assertThat(updatedMember.getLikedCafes()).hasSize(1), - () -> assertThat(updatedMember.isLike(cafe)).isTrue(), - () -> assertThat(cafe.getLikeCount()).isEqualTo(11) - ); - } - - @Test - @DisplayName("좋아요 상태를 변경하려는 카페가 존재하지 않는 경우 예외가 발생한다.") - void updateLikeFail() { - //given - final Member member = memberRepository.save(new Member("memberId", "폴로", "폴로사진")); - final Cafe cafe = Fixture.getCafe(1L, "카페", "카페주소", 10); - - //when & then - assertThatThrownBy(() -> memberService.updateLike(member, cafe.getId(), true)) - .isInstanceOf(BadRequestException.class) - .hasMessage(NOT_EXISTED_CAFE.getMessage()); - } }