diff --git a/build.gradle b/build.gradle index 675ac1bd8..0e7da291b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { plugins { id 'java' + id 'jacoco' id 'org.springframework.boot' version '3.1.5' id 'io.spring.dependency-management' version '1.1.3' id 'com.epages.restdocs-api-spec' version "${restdocsApiSpecVersion}" @@ -121,5 +122,10 @@ dependencies { } tasks.named('test') { + finalizedBy jacocoTestReport useJUnitPlatform() } + +tasks.named('jacocoTestReport') { + dependsOn test +} diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/controller/AcademyController.java b/src/main/java/org/guzzing/studayserver/domain/academy/controller/AcademyController.java index 513cf0aa3..642322751 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/controller/AcademyController.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/controller/AcademyController.java @@ -47,7 +47,8 @@ public ResponseEntity getAcademy( @PathVariable Long academyId, @MemberId Long memberId ) { - AcademyDetailFacadeResult detailAcademy = academyFacade.getDetailAcademy(AcademyDetailFacadeParam.of(memberId, academyId)); + AcademyDetailFacadeResult detailAcademy = academyFacade.getDetailAcademy( + AcademyDetailFacadeParam.of(memberId, academyId)); return ResponseEntity.status(HttpStatus.OK) .body(AcademyGetResponse.from(detailAcademy)); diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/controller/dto/response/AcademyGetResponse.java b/src/main/java/org/guzzing/studayserver/domain/academy/controller/dto/response/AcademyGetResponse.java index 6bec68cea..604dd6815 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/controller/dto/response/AcademyGetResponse.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/controller/dto/response/AcademyGetResponse.java @@ -1,9 +1,7 @@ package org.guzzing.studayserver.domain.academy.controller.dto.response; import java.util.List; - import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeResult; -import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult; public record AcademyGetResponse( String academyName, diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacade.java b/src/main/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacade.java index a90891bfa..9bf9ea52c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacade.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacade.java @@ -8,7 +8,7 @@ import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesByLocationWithScrollResults; import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult; import org.guzzing.studayserver.domain.academy.util.GeometryUtil; -import org.guzzing.studayserver.domain.like.service.LikeService; +import org.guzzing.studayserver.domain.like.service.LikeFacade; import org.guzzing.studayserver.domain.region.service.RegionService; import org.guzzing.studayserver.domain.region.service.dto.location.RegionResult; import org.springframework.stereotype.Service; @@ -19,16 +19,17 @@ public class AcademyFacade { private final RegionService regionService; private final AcademyService academyService; - private final LikeService likeService; + private final LikeFacade likeFacade; - public AcademyFacade(RegionService regionService, AcademyService academyService, LikeService likeService) { + public AcademyFacade(RegionService regionService, AcademyService academyService, LikeFacade likeFacade) { this.regionService = regionService; this.academyService = academyService; - this.likeService = likeService; + this.likeFacade = likeFacade; } @Transactional(readOnly = true) - public AcademiesByLocationWithScrollFacadeResult findByLocationWithScroll(AcademiesByLocationWithScrollFacadeParam param) { + public AcademiesByLocationWithScrollFacadeResult findByLocationWithScroll( + AcademiesByLocationWithScrollFacadeParam param) { AcademiesByLocationWithScrollResults academiesByLocationWithScroll = academyService.findAcademiesByLocationWithScroll( AcademiesByLocationWithScrollFacadeParam.to(param)); @@ -45,7 +46,7 @@ public AcademiesByLocationWithScrollFacadeResult findByLocationWithScroll(Academ @Transactional(readOnly = true) public AcademyDetailFacadeResult getDetailAcademy(AcademyDetailFacadeParam param) { AcademyGetResult academyGetResult = academyService.getAcademy(param.academyId()); - boolean liked = likeService.isLiked(param.academyId(), param.memberId()); + boolean liked = likeFacade.isLiked(param.memberId(), param.academyId()); return AcademyDetailFacadeResult.of(academyGetResult, liked); } diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/facade/dto/AcademyDetailFacadeResult.java b/src/main/java/org/guzzing/studayserver/domain/academy/facade/dto/AcademyDetailFacadeResult.java index 6b1168780..a8d6d1aeb 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/facade/dto/AcademyDetailFacadeResult.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/facade/dto/AcademyDetailFacadeResult.java @@ -1,11 +1,10 @@ package org.guzzing.studayserver.domain.academy.facade.dto; +import java.util.List; import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult; import org.guzzing.studayserver.domain.academy.service.dto.result.LessonGetResults; import org.guzzing.studayserver.domain.academy.service.dto.result.ReviewPercentGetResult; -import java.util.List; - public record AcademyDetailFacadeResult( String academyName, String contact, diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewListener.java b/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewListener.java deleted file mode 100644 index 7c57a7d2e..000000000 --- a/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.guzzing.studayserver.domain.academy.listener; - -import static org.springframework.transaction.event.TransactionPhase.BEFORE_COMMIT; - -import java.util.Map; -import org.guzzing.studayserver.domain.academy.repository.review.ReviewCountRepository; -import org.guzzing.studayserver.domain.review.event.NewReviewEvent; -import org.springframework.stereotype.Component; -import org.springframework.transaction.event.TransactionalEventListener; - -@Component -public class NewReviewListener { - - private final ReviewCountRepository reviewCountRepository; - - public NewReviewListener(final ReviewCountRepository reviewCountRepository) { - this.reviewCountRepository = reviewCountRepository; - } - - @TransactionalEventListener(phase = BEFORE_COMMIT) - public void updateReviewCount(final NewReviewEvent event) { - final long academyId = event.getAcademyId(); - final Map reviews = event.getReviewType(); - final Map newReview = NewReviewType.newReviewCountOf(reviews); - - reviewCountRepository.getByAcademyId(academyId) - .updateSelectedReviewCount(newReview); - } - -} diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewType.java b/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewType.java deleted file mode 100644 index d3726c44f..000000000 --- a/src/main/java/org/guzzing/studayserver/domain/academy/listener/NewReviewType.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.guzzing.studayserver.domain.academy.listener; - -import java.util.Arrays; -import java.util.Map; -import java.util.stream.Collectors; - -public enum NewReviewType { - KINDNESS, - GOOD_FACILITY, - CHEAP_FEE, - GOOD_MANAGEMENT, - LOVELY_TEACHING, - SHUTTLE_AVAILABILITY; - - public static Map newReviewCountOf(final Map map) { - return Arrays.stream(NewReviewType.values()) - .collect(Collectors.toMap( - reviewType -> reviewType, - reviewType -> map.get(reviewType.name()) ? 1 : 0 - )); - } -} diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/model/ReviewCount.java b/src/main/java/org/guzzing/studayserver/domain/academy/model/ReviewCount.java index fc209457e..4706fd329 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/model/ReviewCount.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/model/ReviewCount.java @@ -1,11 +1,11 @@ package org.guzzing.studayserver.domain.academy.model; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.CHEAP_FEE; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.GOOD_FACILITY; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.GOOD_MANAGEMENT; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.KINDNESS; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.LOVELY_TEACHING; -import static org.guzzing.studayserver.domain.academy.listener.NewReviewType.SHUTTLE_AVAILABILITY; +import static org.guzzing.studayserver.domain.review.model.ReviewType.CHEAP_FEE; +import static org.guzzing.studayserver.domain.review.model.ReviewType.GOOD_FACILITY; +import static org.guzzing.studayserver.domain.review.model.ReviewType.GOOD_MANAGEMENT; +import static org.guzzing.studayserver.domain.review.model.ReviewType.KINDNESS; +import static org.guzzing.studayserver.domain.review.model.ReviewType.LOVELY_TEACHING; +import static org.guzzing.studayserver.domain.review.model.ReviewType.SHUTTLE_AVAILABILITY; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -17,7 +17,7 @@ import jakarta.persistence.Table; import java.util.Map; import lombok.Getter; -import org.guzzing.studayserver.domain.academy.listener.NewReviewType; +import org.guzzing.studayserver.domain.review.model.ReviewType; @Getter @Entity @@ -84,12 +84,14 @@ public static ReviewCount makeDefaultReviewCount(Academy academy) { academy); } - public void updateSelectedReviewCount(final Map newReview) { - this.kindnessCount += newReview.get(KINDNESS); - this.goodFacilityCount += newReview.get(GOOD_FACILITY); - this.cheapFeeCount += newReview.get(CHEAP_FEE); - this.goodManagementCount += newReview.get(GOOD_MANAGEMENT); - this.lovelyTeachingCount += newReview.get(LOVELY_TEACHING); - this.shuttleAvailabilityCount += newReview.get(SHUTTLE_AVAILABILITY); + public void updateSelectedReviewCount(final Map newReview) { + final Map reviewCountMap = ReviewType.convertToReviewTypeCountMap(newReview); + + this.kindnessCount += reviewCountMap.get(KINDNESS); + this.goodFacilityCount += reviewCountMap.get(GOOD_FACILITY); + this.cheapFeeCount += reviewCountMap.get(CHEAP_FEE); + this.goodManagementCount += reviewCountMap.get(GOOD_MANAGEMENT); + this.lovelyTeachingCount += reviewCountMap.get(LOVELY_TEACHING); + this.shuttleAvailabilityCount += reviewCountMap.get(SHUTTLE_AVAILABILITY); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/repository/academy/AcademyQueryRepositoryImpl.java b/src/main/java/org/guzzing/studayserver/domain/academy/repository/academy/AcademyQueryRepositoryImpl.java index 6a8160860..7f1992180 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/repository/academy/AcademyQueryRepositoryImpl.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/repository/academy/AcademyQueryRepositoryImpl.java @@ -2,9 +2,7 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.Query; - import java.util.List; - import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByFilterWithScroll; import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByLocationWithScroll; import org.guzzing.studayserver.domain.academy.repository.dto.AcademyByFilterWithScroll; @@ -67,7 +65,7 @@ public AcademiesByLocationWithScroll findAcademiesByLocation( .addScalar("longitude", StandardBasicTypes.DOUBLE) .addScalar("shuttleAvailable", StandardBasicTypes.STRING) .addScalar("isLiked", StandardBasicTypes.BOOLEAN) - .addScalar("categoryId",StandardBasicTypes.LONG) + .addScalar("categoryId", StandardBasicTypes.LONG) .setResultTransformer((tuple, aliases) -> new AcademyByLocationWithScroll( (Long) tuple[0], (String) tuple[1], @@ -81,7 +79,6 @@ public AcademiesByLocationWithScroll findAcademiesByLocation( )) .getResultList(); - return AcademiesByLocationWithScroll.of( academiesByLocation, isHasNest(academiesByLocation.size(), pageSize) diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademiesByLocationWithScroll.java b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademiesByLocationWithScroll.java index e83c672ce..1fa6b3c98 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademiesByLocationWithScroll.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademiesByLocationWithScroll.java @@ -3,11 +3,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public record AcademiesByLocationWithScroll( - Map> academiesByLocation, + Map> academiesByLocation, boolean hasNext ) { @@ -18,7 +17,8 @@ public static AcademiesByLocationWithScroll of( Map> academyIdWithCategories = new ConcurrentHashMap<>(); academiesByLocation.forEach(academyByLocationWithScroll -> { - academyIdWithCategories.computeIfAbsent(AcademyByLocation.of(academyByLocationWithScroll), k -> new ArrayList<>()) + academyIdWithCategories.computeIfAbsent(AcademyByLocation.of(academyByLocationWithScroll), + k -> new ArrayList<>()) .add(academyByLocationWithScroll.categoryId()); }); @@ -27,6 +27,7 @@ public static AcademiesByLocationWithScroll of( hasNext ); } + public record AcademyByLocation( Long academyId, String academyName, @@ -37,6 +38,7 @@ public record AcademyByLocation( String shuttleAvailable, boolean isLiked ) { + public static AcademyByLocation of(AcademyByLocationWithScroll academyByLocationWithScroll) { return new AcademyByLocation( academyByLocationWithScroll.academyId(), diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyByLocationWithScroll.java b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyByLocationWithScroll.java index fc948a9df..5db346689 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyByLocationWithScroll.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyByLocationWithScroll.java @@ -1,7 +1,5 @@ package org.guzzing.studayserver.domain.academy.repository.dto; -import java.util.Objects; - public record AcademyByLocationWithScroll( Long academyId, String academyName, @@ -13,4 +11,5 @@ public record AcademyByLocationWithScroll( boolean isLiked, Long categoryId ) { + } diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyFee.java b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyFee.java index 2155f86df..2df42f7c6 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyFee.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/repository/dto/AcademyFee.java @@ -2,7 +2,7 @@ public interface AcademyFee { - long getMaxEducationFee(); + Long getMaxEducationFee(); String getAcademyName(); diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/service/AcademyService.java b/src/main/java/org/guzzing/studayserver/domain/academy/service/AcademyService.java index de54f716e..1c0881069 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/service/AcademyService.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/service/AcademyService.java @@ -3,8 +3,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - +import org.guzzing.studayserver.domain.academy.model.Academy; import org.guzzing.studayserver.domain.academy.model.Lesson; +import org.guzzing.studayserver.domain.academy.model.ReviewCount; import org.guzzing.studayserver.domain.academy.repository.academy.AcademyRepository; import org.guzzing.studayserver.domain.academy.repository.academycategory.AcademyCategoryRepository; import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByFilterWithScroll; @@ -19,6 +20,7 @@ import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesByNameResults; import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesFilterWithScrollResults; import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyAndLessonDetailResult; +import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyFeeInfo; import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult; import org.guzzing.studayserver.domain.academy.service.dto.result.LessonInfoToCreateDashboardResults; import org.guzzing.studayserver.domain.academy.util.GeometryUtil; @@ -38,14 +40,29 @@ public class AcademyService { private final AcademyCategoryRepository academyCategoryRepository; public AcademyService(AcademyRepository academyRepository, LessonRepository lessonRepository, - ReviewCountRepository reviewCountRepository, - AcademyCategoryRepository academyCategoryRepository) { + ReviewCountRepository reviewCountRepository, + AcademyCategoryRepository academyCategoryRepository) { this.academyRepository = academyRepository; this.lessonRepository = lessonRepository; this.reviewCountRepository = reviewCountRepository; this.academyCategoryRepository = academyCategoryRepository; } + @Transactional(readOnly = true) + public Academy getAcademy(final long academyId) { + return academyRepository.getById(academyId); + } + + @Transactional(readOnly = true) + public ReviewCount getReviewCountOfAcademy(final long academyId) { + return reviewCountRepository.getByAcademyId(academyId); + } + + @Transactional(readOnly = true) + public AcademyFeeInfo findAcademyFeeInfo(final long academyId) { + return AcademyFeeInfo.from(academyRepository.findAcademyFeeInfo(academyId)); + } + @Transactional(readOnly = true) public AcademyGetResult getAcademy(Long academyId) { return AcademyGetResult.from( @@ -56,7 +73,8 @@ public AcademyGetResult getAcademy(Long academyId) { } @Transactional(readOnly = true) - public AcademiesByLocationWithScrollResults findAcademiesByLocationWithScroll(AcademiesByLocationWithScrollParam param) { + public AcademiesByLocationWithScrollResults findAcademiesByLocationWithScroll( + AcademiesByLocationWithScrollParam param) { String diagonal = GeometryUtil.makeDiagonal(param.baseLatitude(), param.baseLongitude(), DISTANCE); AcademiesByLocationWithScroll academiesByLocation = academyRepository.findAcademiesByLocation( diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademiesByLocationWithScrollResults.java b/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademiesByLocationWithScrollResults.java index 05b9981ac..678a0ad14 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademiesByLocationWithScrollResults.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademiesByLocationWithScrollResults.java @@ -1,9 +1,7 @@ package org.guzzing.studayserver.domain.academy.service.dto.result; import java.util.List; -import java.util.Map; import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByLocationWithScroll; -import org.guzzing.studayserver.domain.academy.repository.dto.AcademyByLocationWithScroll; import org.guzzing.studayserver.domain.academy.util.CategoryInfo; public record AcademiesByLocationWithScrollResults( @@ -17,13 +15,13 @@ public static AcademiesByLocationWithScrollResults to( academiesByLocationWithScroll .academiesByLocation() .keySet() - .stream() - .map(academyByLocation-> - AcademiesByLocationResultWithScroll.from( - academyByLocation, - academiesByLocationWithScroll.academiesByLocation(). - get(academyByLocation))) - .toList(), + .stream() + .map(academyByLocation -> + AcademiesByLocationResultWithScroll.from( + academyByLocation, + academiesByLocationWithScroll.academiesByLocation(). + get(academyByLocation))) + .toList(), academiesByLocationWithScroll.hasNext()); } @@ -39,8 +37,9 @@ public record AcademiesByLocationResultWithScroll( boolean isLiked ) { - public static AcademiesByLocationResultWithScroll from(AcademiesByLocationWithScroll.AcademyByLocation academyByLocationWithScroll, - List categories) { + public static AcademiesByLocationResultWithScroll from( + AcademiesByLocationWithScroll.AcademyByLocation academyByLocationWithScroll, + List categories) { return new AcademiesByLocationResultWithScroll( academyByLocationWithScroll.academyId(), academyByLocationWithScroll.academyName(), diff --git a/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademyFeeInfo.java b/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademyFeeInfo.java index 0210741e1..97dcc9b4c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademyFeeInfo.java +++ b/src/main/java/org/guzzing/studayserver/domain/academy/service/dto/result/AcademyFeeInfo.java @@ -4,7 +4,7 @@ public record AcademyFeeInfo( String academyName, - long expectedFee + Long expectedFee ) { public static AcademyFeeInfo from(AcademyFee academyFee) { diff --git a/src/main/java/org/guzzing/studayserver/domain/like/controller/LikeRestController.java b/src/main/java/org/guzzing/studayserver/domain/like/controller/LikeRestController.java index 289e92c66..04ea9c22f 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/controller/LikeRestController.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/controller/LikeRestController.java @@ -8,7 +8,7 @@ import org.guzzing.studayserver.domain.like.controller.dto.request.LikePostRequest; import org.guzzing.studayserver.domain.like.controller.dto.response.LikeGetResponses; import org.guzzing.studayserver.domain.like.controller.dto.response.LikePostResponse; -import org.guzzing.studayserver.domain.like.service.LikeService; +import org.guzzing.studayserver.domain.like.service.LikeFacade; import org.guzzing.studayserver.domain.like.service.dto.response.LikeGetResult; import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; import org.springframework.http.ResponseEntity; @@ -26,42 +26,63 @@ @RequestMapping(path = "/likes") public class LikeRestController { - private final LikeService likeService; + private final LikeFacade likeFacade; - public LikeRestController(final LikeService likeService) { - this.likeService = likeService; + public LikeRestController(final LikeFacade likeFacade) { + this.likeFacade = likeFacade; } + /** + * 좋아요 등록 + * + * @param request + * @param memberId + * @return LikePostResponse + */ @PostMapping(consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) public ResponseEntity createLike( @Validated @RequestBody final LikePostRequest request, @MemberId final Long memberId ) { - final LikePostResult result = likeService.createLikeOfAcademy(LikePostRequest.to(request, memberId)); + final LikePostResult result = likeFacade.createLikeOfAcademy(LikePostRequest.to(request, memberId)); return ResponseEntity .status(CREATED) .body(LikePostResponse.from(result)); } + /** + * 좋아요 단건 삭제 + * + * @param likeId + * @param memberId + * @return void + */ @DeleteMapping(path = "/{likeId}") public ResponseEntity removeLike( @PathVariable final Long likeId, @MemberId final Long memberId ) { - likeService.removeLike(likeId, memberId); + likeFacade.removeLike(likeId, memberId); return ResponseEntity .noContent() .build(); } + /** + * 멤버의 좋아요 삭제 - 회원 탈퇴 시 사용 + * + * @param academyId + * @param memberId + * @return void + */ @DeleteMapping public ResponseEntity removeLikeOfAcademy( @RequestParam final Long academyId, @MemberId final Long memberId ) { - likeService.deleteLikeOfAcademy(academyId, memberId); + likeFacade.deleteLikeOfAcademy(memberId, academyId); return ResponseEntity .noContent() @@ -72,7 +93,7 @@ public ResponseEntity removeLikeOfAcademy( public ResponseEntity getAllLikes( @MemberId final Long memberId ) { - final LikeGetResult allLikedAcademyInfo = likeService.findAllLikesOfMember(memberId); + final LikeGetResult allLikedAcademyInfo = likeFacade.getAllLikesOfMember(memberId); final LikeGetResponses response = LikeGetResponses.from(allLikedAcademyInfo); diff --git a/src/main/java/org/guzzing/studayserver/domain/like/model/Like.java b/src/main/java/org/guzzing/studayserver/domain/like/model/Like.java index 17d149e3b..4c9f7258e 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/model/Like.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/model/Like.java @@ -1,39 +1,54 @@ package org.guzzing.studayserver.domain.like.model; +import static jakarta.persistence.FetchType.LAZY; import static lombok.AccessLevel.PROTECTED; -import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import lombok.Getter; import lombok.NoArgsConstructor; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.member.model.Member; @Getter @NoArgsConstructor(access = PROTECTED) @Entity -@Table(name = "likes") +@Table(name = "likes", uniqueConstraints = @UniqueConstraint(columnNames = {"member_id", "academy_id"})) public class Like { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "member_id") - private Long memberId; + @ManyToOne(fetch = LAZY) + @JoinColumn(name = "member_id", nullable = false) + private Member member; - @Column(name = "academy_id") - private Long academyId; + @ManyToOne(fetch = LAZY) + @JoinColumn(name = "academy_id", nullable = false) + private Academy academy; - protected Like(final Long memberId, final Long academyId) { - this.memberId = memberId; - this.academyId = academyId; + protected Like(final Member member, final Academy academy) { + this.member = member; + this.academy = academy; } - public static Like of(final Long memberId, final Long academyId) { - return new Like(memberId, academyId); + public static Like of(final Member member, final Academy academy) { + return new Like(member, academy); + } + + public long getMemberId() { + return this.member.getId(); + } + + public long getAcademyId() { + return this.academy.getId(); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeJpaRepository.java b/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeJpaRepository.java index 53c0fa7e3..091833c3c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeJpaRepository.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeJpaRepository.java @@ -1,17 +1,19 @@ package org.guzzing.studayserver.domain.like.repository; import java.util.List; +import org.guzzing.studayserver.domain.academy.model.Academy; import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.member.model.Member; import org.springframework.data.jpa.repository.JpaRepository; public interface LikeJpaRepository extends JpaRepository, LikeRepository { - List findByMemberId(final Long memberId); + List findByMember(final Member member); - long countByMemberId(final Long memberId); + long countByMember(final Member member); - boolean existsByMemberIdAndAcademyId(final Long memberId, final Long academyId); + boolean existsByMemberAndAcademy(final Member member, final Academy academy); - void deleteByAcademyIdAndMemberId(final long academyId, final long memberId); + void deleteByMemberAndAcademy(final Member member, final Academy academy); } diff --git a/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeRepository.java b/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeRepository.java index 656d9e08e..47fe9ef68 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeRepository.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/repository/LikeRepository.java @@ -1,24 +1,26 @@ package org.guzzing.studayserver.domain.like.repository; import java.util.List; +import org.guzzing.studayserver.domain.academy.model.Academy; import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.member.model.Member; public interface LikeRepository { Like save(final Like like); - void deleteById(final Long likeId); + void deleteById(final long likeId); - void deleteByMemberId(final long memberId); + void deleteByMember(final Member member); - boolean existsById(final Long id); + boolean existsById(final long id); - List findByMemberId(final Long memberId); + List findByMember(final Member member); - long countByMemberId(final Long memberId); + long countByMember(final Member member); - boolean existsByMemberIdAndAcademyId(final Long memberId, final Long academyId); + boolean existsByMemberAndAcademy(final Member member, final Academy academy); - void deleteByAcademyIdAndMemberId(final long academyId, final long memberId); + void deleteByMemberAndAcademy(final Member member, final Academy academy); } diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/LikeCommandService.java b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeCommandService.java new file mode 100644 index 000000000..4be4ec522 --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeCommandService.java @@ -0,0 +1,37 @@ +package org.guzzing.studayserver.domain.like.service; + +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.like.repository.LikeRepository; +import org.guzzing.studayserver.domain.member.model.Member; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class LikeCommandService { + + private final LikeRepository likeRepository; + + public LikeCommandService(final LikeRepository likeRepository) { + this.likeRepository = likeRepository; + } + + public Like saveLike(final Member member, final Academy academy) { + final Like like = Like.of(member, academy); + return likeRepository.save(like); + } + + public void deleteLike(final long likeId) { + likeRepository.deleteById(likeId); + } + + public void deleteLikesOfMember(final Member member) { + likeRepository.deleteByMember(member); + } + + public void deleteLikesOfAcademyAndMember(final Member member, final Academy academy) { + likeRepository.deleteByMemberAndAcademy(member, academy); + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/LikeFacade.java b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeFacade.java new file mode 100644 index 000000000..ec2404ad5 --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeFacade.java @@ -0,0 +1,104 @@ +package org.guzzing.studayserver.domain.like.service; + +import java.util.List; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.academy.service.AcademyService; +import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyFeeInfo; +import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.like.service.dto.request.LikePostParam; +import org.guzzing.studayserver.domain.like.service.dto.response.LikeGetResult; +import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; +import org.guzzing.studayserver.domain.like.service.dto.response.LikedAcademyFeeInfo; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.member.service.MemberService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class LikeFacade { + + private final LikeReadService likeReadService; + private final LikeCommandService likeCommandService; + private final MemberService memberService; + private final AcademyService academyService; + + public LikeFacade( + final LikeReadService likeReadService, + final LikeCommandService likeCommandService, + final MemberService memberService, + final AcademyService academyService + ) { + this.likeReadService = likeReadService; + this.likeCommandService = likeCommandService; + this.memberService = memberService; + this.academyService = academyService; + } + + @Transactional + public LikePostResult createLikeOfAcademy(final LikePostParam param) { + final Member member = getValidMember(param.memberId()); + final Academy academy = getValidAcademy(param.academyId(), member); + + final Like savedLike = likeCommandService.saveLike(member, academy); + + return LikePostResult.from(savedLike); + } + + @Transactional + public void removeLike(final long likeId, final long memberId) { + getValidMember(memberId); + + likeCommandService.deleteLike(likeId); + } + + @Transactional + public void deleteLikeOfAcademy(final long memberId, final long academyId) { + final Member member = getValidMember(memberId); + final Academy academy = academyService.getAcademy(academyId); + + likeCommandService.deleteLikesOfAcademyAndMember(member, academy); + } + + @Transactional(readOnly = true) + public boolean isLiked(final long memberId, final long academyId) { + final Member member = memberService.getMember(memberId); + final Academy academy = academyService.getAcademy(academyId); + + return likeReadService.isLikedAcademy(member, academy); + } + + @Transactional(readOnly = true) + public LikeGetResult getAllLikesOfMember(final long memberId) { + final Member member = getValidMember(memberId); + + final List likedAcademyFeeInfos = likeReadService.findAllLikesOfMember(member) + .stream() + .map(like -> { + final long academyId = like.getAcademyId(); + + final AcademyFeeInfo academyFeeInfo = academyService.findAcademyFeeInfo(academyId); + + return new LikedAcademyFeeInfo( + like.getId(), + academyId, + academyFeeInfo.academyName(), + academyFeeInfo.expectedFee()); + }) + .toList(); + + return LikeGetResult.of(likedAcademyFeeInfos); + } + + private Member getValidMember(final long memberId) { + final Member member = memberService.getMember(memberId); + likeReadService.validateLikeLimit(member); + return member; + } + + private Academy getValidAcademy(final long academyId, final Member member) { + final Academy academy = academyService.getAcademy(academyId); + likeReadService.validateExistsLike(member, academy); + return academy; + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/LikeReadService.java b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeReadService.java new file mode 100644 index 000000000..a22e5c52f --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeReadService.java @@ -0,0 +1,46 @@ +package org.guzzing.studayserver.domain.like.service; + +import java.util.List; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.like.repository.LikeRepository; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.global.exception.LikeException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class LikeReadService { + + private final LikeRepository likeRepository; + + public LikeReadService(final LikeRepository likeRepository) { + this.likeRepository = likeRepository; + } + + public boolean isLikedAcademy(final Member member, final Academy academy) { + return likeRepository.existsByMemberAndAcademy(member, academy); + } + + public List findAllLikesOfMember(final Member member) { + return likeRepository.findByMember(member); + } + + protected void validateLikeLimit(final Member member) { + final long likeCount = likeRepository.countByMember(member); + + if (likeCount >= 10) { + throw new LikeException("좋아요 개수는 10개를 넘을 수 없습니다."); + } + } + + protected void validateExistsLike(final Member member, final Academy academy) { + final boolean existsLike = likeRepository.existsByMemberAndAcademy(member, academy); + + if (existsLike) { + throw new LikeException("이미 좋아요한 학원입니다."); + } + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/LikeService.java b/src/main/java/org/guzzing/studayserver/domain/like/service/LikeService.java deleted file mode 100644 index 75e091256..000000000 --- a/src/main/java/org/guzzing/studayserver/domain/like/service/LikeService.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.guzzing.studayserver.domain.like.service; - -import java.util.List; - -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyFeeInfo; -import org.guzzing.studayserver.domain.like.model.Like; -import org.guzzing.studayserver.domain.like.repository.LikeRepository; -import org.guzzing.studayserver.domain.like.service.dto.request.LikePostParam; -import org.guzzing.studayserver.domain.like.service.dto.response.LikeGetResult; -import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; -import org.guzzing.studayserver.domain.like.service.dto.response.LikedAcademyFeeInfo; -import org.guzzing.studayserver.domain.member.annotation.ValidMember; -import org.guzzing.studayserver.domain.member.annotation.ValidatedMemberId; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; -import org.guzzing.studayserver.global.exception.LikeException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class LikeService { - - private final LikeRepository likeRepository; - private final AcademyAccessService academyAccessService; - private final MemberAccessService memberAccessService; - - public LikeService( - final LikeRepository likeRepository, - final AcademyAccessService academyAccessService, - final MemberAccessService memberAccessService - ) { - this.likeRepository = likeRepository; - this.academyAccessService = academyAccessService; - this.memberAccessService = memberAccessService; - } - - @Transactional - public LikePostResult createLikeOfAcademy(final LikePostParam param) { - memberAccessService.validateMember(param.memberId()); - academyAccessService.validateAcademy(param.academyId()); - - validateLikeLimit(param); - validateExistsLike(param); - - final Like savedLike = likeRepository.save( - Like.of(param.memberId(), param.academyId())); - - return LikePostResult.from(savedLike); - } - - @Transactional - public void removeLike(final Long likeId, final Long memberId) { - memberAccessService.validateMember(memberId); - - likeRepository.deleteById(likeId); - } - - @Transactional - public void removeLike(final long memberId) { - likeRepository.deleteByMemberId(memberId); - } - - @ValidMember - @Transactional - public void deleteLikeOfAcademy(final Long academyId, @ValidatedMemberId final Long memberId) { - academyAccessService.validateAcademy(academyId); - - likeRepository.deleteByAcademyIdAndMemberId(academyId, memberId); - } - - @ValidMember - public boolean isLiked(final Long academyId, @ValidatedMemberId final Long memberId) { - return likeRepository.existsByMemberIdAndAcademyId(memberId, academyId); - } - - public LikeGetResult findAllLikesOfMember(Long memberId) { - memberAccessService.validateMember(memberId); - - final List likes = likeRepository.findByMemberId(memberId); - - final List likeAcademyFeeInfos = likes.stream() - .map(like -> { - AcademyFeeInfo academyFeeInfo = academyAccessService.findAcademyFeeInfo(like.getAcademyId()); - - return new LikedAcademyFeeInfo( - like.getId(), - like.getAcademyId(), - academyFeeInfo.academyName(), - academyFeeInfo.expectedFee()); - }) - .toList(); - - final long totalFee = likeAcademyFeeInfos.stream() - .mapToLong(LikedAcademyFeeInfo::expectedFee) - .sum(); - - return LikeGetResult.of(likeAcademyFeeInfos, totalFee); - } - - private void validateLikeLimit(LikePostParam param) { - final long likeCount = likeRepository.countByMemberId(param.memberId()); - - if (likeCount >= 10) { - throw new LikeException("좋아요 개수는 10개를 넘을 수 없습니다."); - } - } - - private void validateExistsLike(LikePostParam param) { - boolean existsLike = likeRepository.existsByMemberIdAndAcademyId(param.memberId(), param.academyId()); - - if (existsLike) { - throw new LikeException("이미 좋아요한 학원입니다."); - } - } - -} diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/request/LikePostParam.java b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/request/LikePostParam.java index d89e4ddb1..6824da68e 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/request/LikePostParam.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/request/LikePostParam.java @@ -1,8 +1,8 @@ package org.guzzing.studayserver.domain.like.service.dto.request; public record LikePostParam( - Long memberId, - Long academyId + long memberId, + long academyId ) { } diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikeGetResult.java b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikeGetResult.java index 08884ecee..20686f6ab 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikeGetResult.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikeGetResult.java @@ -7,8 +7,21 @@ public record LikeGetResult( long totalFee ) { - public static LikeGetResult of(final List likeAcademyInfos, final long totalFee) { - return new LikeGetResult(likeAcademyInfos, totalFee); + private static final long DEFAULT_TOTAL_FEE = 0L; + + public static LikeGetResult of(final List likedAcademyFeeInfos) { + return new LikeGetResult(likedAcademyFeeInfos, getTotalFee(likedAcademyFeeInfos)); + } + + private static long getTotalFee(final List likeAcademyFeeInfos) { + try { + return likeAcademyFeeInfos.stream() + .filter(likedAcademyFeeInfo -> likedAcademyFeeInfo.expectedFee() != null) + .mapToLong(LikedAcademyFeeInfo::expectedFee) + .sum(); + } catch (NullPointerException e) { + return DEFAULT_TOTAL_FEE; + } } } diff --git a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikedAcademyFeeInfo.java b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikedAcademyFeeInfo.java index c79147160..6dfca4b7b 100644 --- a/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikedAcademyFeeInfo.java +++ b/src/main/java/org/guzzing/studayserver/domain/like/service/dto/response/LikedAcademyFeeInfo.java @@ -4,7 +4,7 @@ public record LikedAcademyFeeInfo( long likeId, long academyId, String academyName, - long expectedFee + Long expectedFee ) { } diff --git a/src/main/java/org/guzzing/studayserver/domain/member/model/Member.java b/src/main/java/org/guzzing/studayserver/domain/member/model/Member.java index ef25074c4..f74b5406d 100644 --- a/src/main/java/org/guzzing/studayserver/domain/member/model/Member.java +++ b/src/main/java/org/guzzing/studayserver/domain/member/model/Member.java @@ -15,6 +15,7 @@ import jakarta.persistence.UniqueConstraint; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import lombok.Getter; import org.guzzing.studayserver.domain.child.model.Child; @@ -117,4 +118,24 @@ public List getChildren() { public String getNickname() { return nickName.getValue(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Member member = (Member) o; + return Objects.equals(id, member.id) && Objects.equals(nickName, member.nickName) + && Objects.equals(email, member.email) && Objects.equals(socialId, member.socialId) + && memberProvider == member.memberProvider && roleType == member.roleType && Objects.equals( + children, member.children); + } + + @Override + public int hashCode() { + return Objects.hash(id, nickName, email, socialId, memberProvider, roleType, children); + } } diff --git a/src/main/java/org/guzzing/studayserver/domain/member/service/MemberFacade.java b/src/main/java/org/guzzing/studayserver/domain/member/service/MemberFacade.java index 4a1d55a21..c6d86f2cc 100644 --- a/src/main/java/org/guzzing/studayserver/domain/member/service/MemberFacade.java +++ b/src/main/java/org/guzzing/studayserver/domain/member/service/MemberFacade.java @@ -6,8 +6,9 @@ import org.guzzing.studayserver.domain.child.service.ChildService; import org.guzzing.studayserver.domain.child.service.result.ChildrenFindResult.ChildFindResult; import org.guzzing.studayserver.domain.dashboard.service.DashboardService; -import org.guzzing.studayserver.domain.like.service.LikeService; -import org.guzzing.studayserver.domain.review.service.ReviewService; +import org.guzzing.studayserver.domain.like.service.LikeCommandService; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.review.service.ReviewFacade; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -19,34 +20,37 @@ public class MemberFacade { private final ChildService childService; private final AcademyCalendarService calendarService; private final DashboardService dashboardService; - private final LikeService likeService; - private final ReviewService reviewService; + private final LikeCommandService likeCommandService; + private final ReviewFacade reviewFacade; public MemberFacade( final MemberService memberService, final ChildService childService, final AcademyCalendarService calendarService, final DashboardService dashboardService, - final LikeService likeService, - final ReviewService reviewService + final LikeCommandService likeCommandService, + final ReviewFacade reviewFacade ) { this.memberService = memberService; this.childService = childService; this.calendarService = calendarService; this.dashboardService = dashboardService; - this.likeService = likeService; - this.reviewService = reviewService; + this.likeCommandService = likeCommandService; + this.reviewFacade = reviewFacade; } @Transactional public void removeMember(final long memberId) { - List childIds = childService.findByMemberId(memberId).children() + final Member member = memberService.getMember(memberId); + + final List childIds = childService.findByMemberId(member.getId()) + .children() .stream() .map(ChildFindResult::childId) .toList(); - reviewService.removeReview(memberId); - likeService.removeLike(memberId); + reviewFacade.removeReview(member); + likeCommandService.deleteLikesOfMember(member); calendarService.removeCalendar(childIds); dashboardService.removeDashboard(childIds); childService.removeChild(memberId); diff --git a/src/main/java/org/guzzing/studayserver/domain/member/service/MemberService.java b/src/main/java/org/guzzing/studayserver/domain/member/service/MemberService.java index 07e13361c..6212ee19c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/member/service/MemberService.java +++ b/src/main/java/org/guzzing/studayserver/domain/member/service/MemberService.java @@ -54,7 +54,7 @@ public MemberInformationResult getById(Long memberId) { return new MemberInformationResult(member.getNickName(), member.getEmail(), childInformationResults); } - private Member getMember(Long memberId) { + public Member getMember(final long memberId) { return memberRepository.findById(memberId) .orElseThrow(() -> new IllegalStateException("존재하지 않는 아이디입니다.")); } diff --git a/src/main/java/org/guzzing/studayserver/domain/review/controller/ReviewRestController.java b/src/main/java/org/guzzing/studayserver/domain/review/controller/ReviewRestController.java index 4a2715391..4952a849b 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/controller/ReviewRestController.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/controller/ReviewRestController.java @@ -8,7 +8,7 @@ import org.guzzing.studayserver.domain.review.controller.dto.request.ReviewPostRequest; import org.guzzing.studayserver.domain.review.controller.dto.response.ReviewPostResponse; import org.guzzing.studayserver.domain.review.controller.dto.response.ReviewableResponse; -import org.guzzing.studayserver.domain.review.service.ReviewService; +import org.guzzing.studayserver.domain.review.service.ReviewFacade; import org.guzzing.studayserver.domain.review.service.dto.request.ReviewPostParam; import org.guzzing.studayserver.domain.review.service.dto.response.ReviewPostResult; import org.guzzing.studayserver.domain.review.service.dto.response.ReviewableResult; @@ -25,10 +25,10 @@ @RequestMapping(path = "/reviews") public class ReviewRestController { - private final ReviewService reviewService; + private final ReviewFacade reviewFacade; - public ReviewRestController(ReviewService reviewService) { - this.reviewService = reviewService; + public ReviewRestController(ReviewFacade reviewFacade) { + this.reviewFacade = reviewFacade; } @PostMapping(consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) @@ -37,7 +37,7 @@ public ResponseEntity registerReview( @Validated @RequestBody ReviewPostRequest request ) { ReviewPostParam param = ReviewPostRequest.to(memberId, request); - ReviewPostResult result = reviewService.createReviewOfAcademy(param); + ReviewPostResult result = reviewFacade.createReviewOfAcademy(param); ReviewPostResponse response = ReviewPostResponse.from(result); return ResponseEntity @@ -50,7 +50,7 @@ public ResponseEntity getReviewable( @MemberId Long memberId, @RequestParam Long academyId ) { - ReviewableResult result = reviewService.getReviewableToAcademy(memberId, academyId); + ReviewableResult result = reviewFacade.getReviewableToAcademy(memberId, academyId); ReviewableResponse response = ReviewableResponse.from(result); return ResponseEntity diff --git a/src/main/java/org/guzzing/studayserver/domain/review/event/NewReviewEvent.java b/src/main/java/org/guzzing/studayserver/domain/review/event/NewReviewEvent.java deleted file mode 100644 index 763ec6148..000000000 --- a/src/main/java/org/guzzing/studayserver/domain/review/event/NewReviewEvent.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.guzzing.studayserver.domain.review.event; - -import java.util.Map; -import org.guzzing.studayserver.domain.review.model.Review; - -public class NewReviewEvent { - - private final Review review; - - private NewReviewEvent(final Review review) { - this.review = review; - } - - public static NewReviewEvent of(final Review review) { - return new NewReviewEvent(review); - } - - public long getAcademyId() { - return this.review.getAcademyId(); - } - - public Map getReviewType() { - return this.review.getReviewType(); - } - -} diff --git a/src/main/java/org/guzzing/studayserver/domain/review/model/Review.java b/src/main/java/org/guzzing/studayserver/domain/review/model/Review.java index e55324677..8e02fb548 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/model/Review.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/model/Review.java @@ -1,53 +1,62 @@ package org.guzzing.studayserver.domain.review.model; +import static jakarta.persistence.FetchType.LAZY; + import io.hypersistence.utils.hibernate.type.json.JsonType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.member.model.Member; import org.hibernate.annotations.Type; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity -@Table(name = "reviews") +@Table(name = "reviews", uniqueConstraints = @UniqueConstraint(columnNames = {"member_id", "academy_id"})) public class Review { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "member_id", nullable = false) - private Long memberId; + @ManyToOne(fetch = LAZY) + @JoinColumn(name = "member_id") + private Member member; - @Column(name = "academy_id", nullable = false) - private Long academyId; + @ManyToOne(fetch = LAZY) + @JoinColumn(name = "academy_id") + private Academy academy; @Type(JsonType.class) @Column(name = "reviewed_type", nullable = false, columnDefinition = "LONGTEXT") private Map reviewType; public Review( - final Long memberId, - final Long academyId, + final Member member, + final Academy academy, final Map reviewType ) { - this.memberId = memberId; - this.academyId = academyId; + this.member = member; + this.academy = academy; this.reviewType = reviewType; } public static Review of( - final Long memberId, - final Long academyId, + final Member member, + final Academy academy, final Map reviewType ) { final Map selectedRevieType = reviewType.entrySet() @@ -57,7 +66,15 @@ public static Review of( Entry::getValue )); - return new Review(memberId, academyId, selectedRevieType); + return new Review(member, academy, selectedRevieType); + } + + public long getMemberId() { + return this.member.getId(); + } + + public long getAcademyId() { + return this.academy.getId(); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/review/model/ReviewType.java b/src/main/java/org/guzzing/studayserver/domain/review/model/ReviewType.java index cf3058231..dc460065c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/model/ReviewType.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/model/ReviewType.java @@ -5,7 +5,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.guzzing.studayserver.domain.review.service.dto.request.ReviewPostParam; -import org.guzzing.studayserver.global.exception.ReviewException; public enum ReviewType { KINDNESS, @@ -32,7 +31,7 @@ public static Map getSelectedReviewMap(final ReviewPostPara return selectedReviewMap; } - public static Map convertReviewListToReviewMap(final Map map) { + public static Map convertToReviewTypeMap(final Map map) { return Arrays.stream(ReviewType.values()) .collect(Collectors.toMap( reviewType -> reviewType, @@ -40,13 +39,21 @@ public static Map convertReviewListToReviewMap(final Map convertToReviewTypeCountMap(final Map map) { + return Arrays.stream(ReviewType.values()) + .collect(Collectors.toMap( + reviewType -> reviewType, + reviewType -> Boolean.TRUE.equals(map.get(reviewType)) ? 1 : 0 + )); + } + private static void validateThreeReviewLimit(final Map map) { long count = map.values().stream() .filter(value -> value) .count(); if (count > MAX_REVIEW_COUNT) { - throw new ReviewException("리뷰는 3개 까지 가능합니다."); + throw new IllegalArgumentException("리뷰는 3개 까지 가능합니다."); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewJpaRepository.java b/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewJpaRepository.java index 5ec4398d9..597c44711 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewJpaRepository.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewJpaRepository.java @@ -1,12 +1,14 @@ package org.guzzing.studayserver.domain.review.repository; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.member.model.Member; import org.guzzing.studayserver.domain.review.model.Review; import org.springframework.data.jpa.repository.JpaRepository; public interface ReviewJpaRepository extends JpaRepository, ReviewRepository { - boolean existsByMemberIdAndAcademyId(final Long memberId, final Long academyId); + boolean existsByMemberAndAcademy(final Member member, final Academy academy); - void deleteByMemberId(final long memberId); + void deleteByMember(final Member member); } diff --git a/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewRepository.java b/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewRepository.java index 5c8aa9447..0e5678fdf 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewRepository.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/repository/ReviewRepository.java @@ -1,15 +1,15 @@ package org.guzzing.studayserver.domain.review.repository; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.member.model.Member; import org.guzzing.studayserver.domain.review.model.Review; public interface ReviewRepository { Review save(final Review review); - boolean existsByMemberIdAndAcademyId(final Long memberId, final Long academyId); + boolean existsByMemberAndAcademy(final Member member, final Academy academy); - void deleteByMemberId(final long memberId); - - void deleteAll(); + void deleteByMember(final Member member); } diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewCommandService.java b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewCommandService.java new file mode 100644 index 000000000..9147b659a --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewCommandService.java @@ -0,0 +1,29 @@ +package org.guzzing.studayserver.domain.review.service; + +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.review.model.Review; +import org.guzzing.studayserver.domain.review.repository.ReviewRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class ReviewCommandService { + + private final ReviewRepository reviewRepository; + + public ReviewCommandService( + final ReviewRepository reviewRepository + ) { + this.reviewRepository = reviewRepository; + } + + public Review saveReview(final Review review) { + return reviewRepository.save(review); + } + + public void deleteReviewOfMember(final Member member) { + reviewRepository.deleteByMember(member); + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewFacade.java b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewFacade.java new file mode 100644 index 000000000..6f1ed3348 --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewFacade.java @@ -0,0 +1,73 @@ +package org.guzzing.studayserver.domain.review.service; + +import jakarta.persistence.EntityExistsException; +import java.util.Map; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.academy.service.AcademyService; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.member.service.MemberService; +import org.guzzing.studayserver.domain.review.model.Review; +import org.guzzing.studayserver.domain.review.model.ReviewType; +import org.guzzing.studayserver.domain.review.service.dto.request.ReviewPostParam; +import org.guzzing.studayserver.domain.review.service.dto.response.ReviewPostResult; +import org.guzzing.studayserver.domain.review.service.dto.response.ReviewableResult; +import org.springframework.stereotype.Service; + +@Service +public class ReviewFacade { + + private final ReviewCommandService reviewCommandService; + private final ReviewReadService reviewReadService; + private final MemberService memberService; + private final AcademyService academyService; + + public ReviewFacade( + final ReviewCommandService reviewCommandService, + final ReviewReadService reviewReadService, + final MemberService memberService, + final AcademyService academyService + ) { + this.reviewCommandService = reviewCommandService; + this.reviewReadService = reviewReadService; + this.memberService = memberService; + this.academyService = academyService; + } + + public ReviewPostResult createReviewOfAcademy(final ReviewPostParam param) { + final Member member = memberService.getMember(param.memberId()); + final Academy academy = academyService.getAcademy(param.academyId()); + + checkReviewExists(member, academy); + + final Map selectedReviewMap = ReviewType.getSelectedReviewMap(param); + + final Review savedReview = reviewCommandService.saveReview( + Review.of(member, academy, selectedReviewMap)); + academyService.getReviewCountOfAcademy(academy.getId()) + .updateSelectedReviewCount(selectedReviewMap); + + return ReviewPostResult.from(savedReview); + } + + public void removeReview(final Member member) { + reviewCommandService.deleteReviewOfMember(member); + } + + public ReviewableResult getReviewableToAcademy(final long memberId, final long academyId) { + final Member member = memberService.getMember(memberId); + final Academy academy = academyService.getAcademy(academyId); + + final boolean existsReview = reviewReadService.existsReview(member, academy); + + return ReviewableResult.of(member.getId(), academy.getId(), !existsReview); + } + + private void checkReviewExists(Member member, Academy academy) { + final boolean existsReview = reviewReadService.existsReview(member, academy); + + if (existsReview) { + throw new EntityExistsException("이미 리뷰를 남겼습니다."); + } + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewReadService.java b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewReadService.java new file mode 100644 index 000000000..0865a6937 --- /dev/null +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewReadService.java @@ -0,0 +1,23 @@ +package org.guzzing.studayserver.domain.review.service; + +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.review.repository.ReviewRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class ReviewReadService { + + private final ReviewRepository reviewRepository; + + public ReviewReadService(final ReviewRepository reviewRepository) { + this.reviewRepository = reviewRepository; + } + + public boolean existsReview(final Member member, final Academy academy) { + return reviewRepository.existsByMemberAndAcademy(member, academy); + } + +} diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewService.java b/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewService.java deleted file mode 100644 index 391bdcbf9..000000000 --- a/src/main/java/org/guzzing/studayserver/domain/review/service/ReviewService.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.guzzing.studayserver.domain.review.service; - -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; -import org.guzzing.studayserver.domain.review.event.NewReviewEvent; -import org.guzzing.studayserver.domain.review.model.Review; -import org.guzzing.studayserver.domain.review.model.ReviewType; -import org.guzzing.studayserver.domain.review.repository.ReviewRepository; -import org.guzzing.studayserver.domain.review.service.dto.request.ReviewPostParam; -import org.guzzing.studayserver.domain.review.service.dto.response.ReviewPostResult; -import org.guzzing.studayserver.domain.review.service.dto.response.ReviewableResult; -import org.guzzing.studayserver.global.exception.ReviewException; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class ReviewService { - - private final ApplicationEventPublisher eventPublisher; - private final ReviewRepository reviewRepository; - private final AcademyAccessService academyAccessService; - private final MemberAccessService memberAccessService; - - public ReviewService( - final ApplicationEventPublisher eventPublisher, - final ReviewRepository reviewRepository, - final AcademyAccessService academyAccessService, - final MemberAccessService memberAccessService - ) { - this.eventPublisher = eventPublisher; - this.reviewRepository = reviewRepository; - this.academyAccessService = academyAccessService; - this.memberAccessService = memberAccessService; - } - - @Transactional - public ReviewPostResult createReviewOfAcademy(final ReviewPostParam param) { - memberAccessService.validateMember(param.memberId()); - academyAccessService.validateAcademy(param.academyId()); - - final ReviewableResult reviewableResult = getReviewableToAcademy( - param.memberId(), - param.academyId()); - - if (!reviewableResult.reviewable()) { - throw new ReviewException("이미 리뷰를 남겼습니다."); - } - - final Review review = Review.of( - param.memberId(), - param.academyId(), - ReviewType.getSelectedReviewMap(param)); - - final Review savedReview = reviewRepository.save(review); - - eventPublisher.publishEvent(NewReviewEvent.of(savedReview)); - - return ReviewPostResult.from(savedReview); - } - - @Transactional - public void removeReview(final long memberId) { - reviewRepository.deleteByMemberId(memberId); - } - - public ReviewableResult getReviewableToAcademy(final Long memberId, final Long academyId) { - memberAccessService.validateMember(memberId); - academyAccessService.validateAcademy(academyId); - - final boolean existsReview = reviewRepository.existsByMemberIdAndAcademyId(memberId, academyId); - - return ReviewableResult.of(memberId, academyId, !existsReview); - } - -} diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/request/ReviewPostParam.java b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/request/ReviewPostParam.java index 404ddbdbc..87a1836be 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/request/ReviewPostParam.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/request/ReviewPostParam.java @@ -1,8 +1,8 @@ package org.guzzing.studayserver.domain.review.service.dto.request; public record ReviewPostParam( - Long memberId, - Long academyId, + long memberId, + long academyId, boolean kindness, boolean cheapFee, boolean goodFacility, diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewPostResult.java b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewPostResult.java index dee48ad16..37ad3a88d 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewPostResult.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewPostResult.java @@ -11,9 +11,9 @@ import org.guzzing.studayserver.domain.review.model.ReviewType; public record ReviewPostResult( - Long reviewId, - Long memberId, - Long academyId, + long reviewId, + long memberId, + long academyId, boolean kindness, boolean cheapFee, boolean goodFacility, @@ -22,7 +22,7 @@ public record ReviewPostResult( ) { public static ReviewPostResult from(final Review entity) { - final Map reviewType = ReviewType.convertReviewListToReviewMap(entity.getReviewType()); + final Map reviewType = ReviewType.convertToReviewTypeMap(entity.getReviewType()); return new ReviewPostResult( entity.getId(), diff --git a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewableResult.java b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewableResult.java index 134088a2b..409b82f85 100644 --- a/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewableResult.java +++ b/src/main/java/org/guzzing/studayserver/domain/review/service/dto/response/ReviewableResult.java @@ -1,12 +1,12 @@ package org.guzzing.studayserver.domain.review.service.dto.response; public record ReviewableResult( - Long memberId, - Long academyId, + long memberId, + long academyId, boolean reviewable ) { - public static ReviewableResult of(final Long memberId, final Long academyId, final boolean reviewable) { + public static ReviewableResult of(final long memberId, final long academyId, final boolean reviewable) { return new ReviewableResult(memberId, academyId, reviewable); } diff --git a/src/test/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacadeTest.java b/src/test/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacadeTest.java index 5d64b3fd0..b8e9aedd2 100644 --- a/src/test/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacadeTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/academy/facade/AcademyFacadeTest.java @@ -1,5 +1,9 @@ package org.guzzing.studayserver.domain.academy.facade; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + import jakarta.transaction.Transactional; import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeParam; import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeResult; @@ -24,14 +28,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; - @Transactional @SpringBootTest(webEnvironment = NONE) @Import(TestDatabaseConfig.class) -public class AcademyFacadeTest { +class AcademyFacadeTest { @Autowired private AcademyFacade academyFacade; @@ -63,7 +63,7 @@ public class AcademyFacadeTest { @BeforeEach void setUp() { - Member member = MemberFixture.member(); + Member member = MemberFixture.makeMemberEntity(); savedMember = memberRepository.save(member); Academy academyAboutSungnam = AcademyFixture.academySungnam(); @@ -81,7 +81,7 @@ void setUp() { savedReviewCountAboutSungnam = reviewCountRepository.save( AcademyFixture.reviewCountDefault(savedAcademyAboutSungnam)); - likeRepository.save(Like.of(savedMember.getId(),savedAcademyAboutSungnam.getId())); + likeRepository.save(Like.of(savedMember, savedAcademyAboutSungnam)); } @Test @@ -99,11 +99,12 @@ void getDetailAcademy() { //Then assertAll("Academy Details", () -> assertThat(detailAcademy.academyName()).isEqualTo(savedAcademyAboutSungnam.getAcademyName()), - () -> assertThat(detailAcademy.isLiked()).isEqualTo(true), + () -> assertThat(detailAcademy.isLiked()).isTrue(), () -> assertThat(detailAcademy.contact()).isEqualTo(savedAcademyAboutSungnam.getContact()), () -> assertThat(detailAcademy.expectedFee()).isEqualTo(savedAcademyAboutSungnam.getMaxEducationFee()), () -> assertThat(detailAcademy.fullAddress()).isEqualTo(savedAcademyAboutSungnam.getFullAddress()), - () -> assertThat(detailAcademy.shuttleAvailability()).isEqualTo(savedAcademyAboutSungnam.getShuttleAvailability()) + () -> assertThat(detailAcademy.shuttleAvailability()).isEqualTo( + savedAcademyAboutSungnam.getShuttleAvailability()) ); } diff --git a/src/test/java/org/guzzing/studayserver/domain/academy/service/AcademyServiceTest.java b/src/test/java/org/guzzing/studayserver/domain/academy/service/AcademyServiceTest.java index 455350794..173c8bc7a 100644 --- a/src/test/java/org/guzzing/studayserver/domain/academy/service/AcademyServiceTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/academy/service/AcademyServiceTest.java @@ -79,7 +79,7 @@ class AcademyServiceTest { @BeforeEach void setUp() { - Member member = MemberFixture.member(); + Member member = MemberFixture.makeMemberEntity(); savedMember = memberRepository.save(member); Academy academyAboutSungnam = AcademyFixture.academySungnam(); diff --git a/src/test/java/org/guzzing/studayserver/domain/dashboard/controller/DashboardRestControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/dashboard/controller/DashboardRestControllerTest.java index 607327b2d..895b5852a 100644 --- a/src/test/java/org/guzzing/studayserver/domain/dashboard/controller/DashboardRestControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/dashboard/controller/DashboardRestControllerTest.java @@ -2,9 +2,9 @@ import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.guzzing.studayserver.domain.dashboard.fixture.DashboardFixture.childId; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.AUTHORIZATION_HEADER; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.BEARER; +import static com.nimbusds.oauth2.sdk.token.AccessTokenType.BEARER; +import static org.guzzing.studayserver.testutil.JwtTestConfig.AUTHORIZATION_HEADER; +import static org.guzzing.studayserver.testutil.fixture.dashboard.DashboardFixture.childId; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -34,11 +34,11 @@ import org.guzzing.studayserver.domain.child.service.ChildAccessService; import org.guzzing.studayserver.domain.dashboard.controller.dto.request.DashboardPostRequest; import org.guzzing.studayserver.domain.dashboard.controller.dto.request.DashboardPutRequest; -import org.guzzing.studayserver.domain.dashboard.fixture.DashboardFixture; import org.guzzing.studayserver.domain.dashboard.model.Dashboard; import org.guzzing.studayserver.domain.member.service.MemberAccessService; +import org.guzzing.studayserver.testutil.JwtTestConfig; import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser; -import org.guzzing.studayserver.testutil.fixture.TestConfig; +import org.guzzing.studayserver.testutil.fixture.dashboard.DashboardFixture; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -66,7 +66,7 @@ class DashboardRestControllerTest { @Autowired private ObjectMapper objectMapper; @Autowired - private TestConfig testConfig; + private JwtTestConfig jwtTestConfig; @MockBean private MemberAccessService memberAccessService; @@ -84,7 +84,7 @@ void registerDashboard_ReturnCreated() throws Exception { // When final ResultActions perform = mockMvc.perform(post("/dashboards") - .header(AUTHORIZATION_HEADER, TestConfig.BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) .content(objectMapper.writeValueAsBytes(request)) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -158,7 +158,7 @@ void updateDashboard_EditDashboard() throws Exception { // When final ResultActions perform = mockMvc.perform(put("/dashboards/{dashboardId}", dashboard.getId()) - .header(AUTHORIZATION_HEADER, TestConfig.BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) .content(objectMapper.writeValueAsBytes(request)) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -240,7 +240,7 @@ void getDashboard() throws Exception { // When final ResultActions perform = mockMvc.perform(get("/dashboards/{dashboardId}", dashboard.getId()) - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -336,7 +336,7 @@ void getDashboards_ByActiveOnlyBoolean_AllDashboardOfChild() throws Exception { // When final ResultActions perform = mockMvc.perform(get("/dashboards") - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(String.valueOf(AUTHORIZATION_HEADER), BEARER) .param("childId", String.valueOf(childId)) .param("active-only", String.valueOf(activeOnly)) .accept(APPLICATION_JSON_VALUE) @@ -367,7 +367,7 @@ void getDashboards_ByActiveOnlyBoolean_AllDashboardOfChild() throws Exception { .tag(TAG) .summary("아이 대시보드 전체 조회") .requestHeaders( - headerWithName(AUTHORIZATION_HEADER).description("JWT 토큰") + headerWithName(String.valueOf(AUTHORIZATION_HEADER)).description("JWT 토큰") ) .queryParameters( parameterWithName("childId").description("아이 아이디"), @@ -462,7 +462,7 @@ void removeDashboard_InActiveDashboard_Success() throws Exception { // When final ResultActions perform = mockMvc.perform(patch("/dashboards/{dashboardId}", dashboard.getId()) - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(String.valueOf(AUTHORIZATION_HEADER), BEARER) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -496,7 +496,7 @@ void revertToggleActive_Dashboard() throws Exception { // When final ResultActions perform = mockMvc.perform(patch("/dashboards/{dashboardId}/toggle", dashboard.getId()) - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(String.valueOf(AUTHORIZATION_HEADER), BEARER) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -513,7 +513,7 @@ void revertToggleActive_Dashboard() throws Exception { .tag(TAG) .summary("대시보드 활성화 반전") .requestHeaders( - headerWithName(AUTHORIZATION_HEADER).description("JWT 토큰") + headerWithName(String.valueOf(AUTHORIZATION_HEADER)).description("JWT 토큰") ) .pathParameters( parameterWithName("dashboardId").description("대시보드 아이디") diff --git a/src/test/java/org/guzzing/studayserver/domain/dashboard/facade/DashboardFacadeTest.java b/src/test/java/org/guzzing/studayserver/domain/dashboard/facade/DashboardFacadeTest.java index 1e0653764..339bf1540 100644 --- a/src/test/java/org/guzzing/studayserver/domain/dashboard/facade/DashboardFacadeTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/dashboard/facade/DashboardFacadeTest.java @@ -13,12 +13,12 @@ import org.guzzing.studayserver.domain.dashboard.facade.dto.DashboardPatchResult; import org.guzzing.studayserver.domain.dashboard.facade.dto.DashboardPostResult; import org.guzzing.studayserver.domain.dashboard.facade.dto.DashboardPutResult; -import org.guzzing.studayserver.domain.dashboard.fixture.DashboardFixture; import org.guzzing.studayserver.domain.dashboard.model.Dashboard; import org.guzzing.studayserver.domain.dashboard.service.dto.request.DashboardPostParam; import org.guzzing.studayserver.domain.dashboard.service.dto.request.DashboardPutParam; import org.guzzing.studayserver.domain.member.service.MemberAccessService; import org.guzzing.studayserver.global.exception.DashboardException; +import org.guzzing.studayserver.testutil.fixture.dashboard.DashboardFixture; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/test/java/org/guzzing/studayserver/domain/dashboard/service/DashboardServiceTest.java b/src/test/java/org/guzzing/studayserver/domain/dashboard/service/DashboardServiceTest.java index 0e02a60ac..13d8b6fa9 100644 --- a/src/test/java/org/guzzing/studayserver/domain/dashboard/service/DashboardServiceTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/dashboard/service/DashboardServiceTest.java @@ -6,12 +6,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; -import org.guzzing.studayserver.domain.dashboard.fixture.DashboardFixture; import org.guzzing.studayserver.domain.dashboard.model.Dashboard; import org.guzzing.studayserver.domain.dashboard.service.dto.request.DashboardPostParam; import org.guzzing.studayserver.domain.dashboard.service.dto.request.DashboardPutParam; import org.guzzing.studayserver.domain.dashboard.service.dto.response.DashboardResult; import org.guzzing.studayserver.global.exception.DashboardException; +import org.guzzing.studayserver.testutil.fixture.dashboard.DashboardFixture; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/test/java/org/guzzing/studayserver/domain/like/controller/LikeRestControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/like/controller/LikeRestControllerTest.java index 8fda2d797..4f1e13d35 100644 --- a/src/test/java/org/guzzing/studayserver/domain/like/controller/LikeRestControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/like/controller/LikeRestControllerTest.java @@ -2,10 +2,7 @@ import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.AUTHORIZATION_HEADER; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.BEARER; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; +import static org.guzzing.studayserver.testutil.JwtTestConfig.AUTHORIZATION_HEADER; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; @@ -26,30 +23,34 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyFeeInfo; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.academy.repository.academy.AcademyRepository; import org.guzzing.studayserver.domain.like.controller.dto.request.LikePostRequest; -import org.guzzing.studayserver.domain.like.service.LikeService; -import org.guzzing.studayserver.domain.like.service.dto.request.LikePostParam; -import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; -import org.guzzing.studayserver.domain.member.annotation.ValidMemberAspect; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; +import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.like.repository.LikeRepository; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.member.repository.MemberRepository; +import org.guzzing.studayserver.testutil.JwtTestConfig; import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser; -import org.guzzing.studayserver.testutil.fixture.TestConfig; +import org.guzzing.studayserver.testutil.fixture.academy.AcademyFixture; +import org.guzzing.studayserver.testutil.fixture.member.MemberFixture; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.transaction.annotation.Transactional; @AutoConfigureRestDocs @AutoConfigureMockMvc +@TestMethodOrder(value = OrderAnnotation.class) @SpringBootTest @Transactional class LikeRestControllerTest { @@ -61,41 +62,40 @@ class LikeRestControllerTest { @Autowired private ObjectMapper objectMapper; - @Autowired - private TestConfig testConfig; + private JwtTestConfig jwtTestConfig; @Autowired - private LikeService likeService; - - @MockBean - private AcademyAccessService academyAccessService; - @MockBean - private MemberAccessService memberAccessService; - @MockBean - private ValidMemberAspect validMemberAspect; + private LikeRepository likeRepository; + @Autowired + private MemberRepository memberRepository; + @Autowired + private AcademyRepository academyRepository; - private final Long academyId = 1L; - private LikePostParam param; + private Member savedMember; + private Academy savedAcademy; + private Like like; @BeforeEach void setUp() { - Long memberId = 1L; - LikePostRequest request = new LikePostRequest(academyId); - param = LikePostRequest.to(request, memberId); + savedMember = memberRepository.save(MemberFixture.makeMemberEntity()); + savedAcademy = academyRepository.save(AcademyFixture.academySungnam()); + like = Like.of(savedMember, savedAcademy); } @Test + @Order(1) @DisplayName("헤더에 JWT 로 들어오는 멤버 아이디와 바디로 전달되는 학원 아이디를 이용해서 좋아요를 등록한다.") - @WithMockCustomOAuth2LoginUser + @WithMockCustomOAuth2LoginUser(memberId = 1) void createLike_MemberIdAndAcademyId_RegisterLike() throws Exception { // Given - LikePostRequest request = new LikePostRequest(academyId); + LikePostRequest request = new LikePostRequest(like.getAcademyId()); String jsonBody = objectMapper.writeValueAsString(request); // When ResultActions perform = mockMvc.perform(post("/likes") - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) + .param("memberId", String.valueOf(savedMember.getId())) .content(jsonBody) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -105,8 +105,8 @@ void createLike_MemberIdAndAcademyId_RegisterLike() throws Exception { .andExpect(status().isCreated()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.likeId").isNumber()) - .andExpect(jsonPath("$.memberId").isNumber()) - .andExpect(jsonPath("$.academyId").value(1L)) + .andExpect(jsonPath("$.memberId").value(like.getMemberId())) + .andExpect(jsonPath("$.academyId").value(like.getAcademyId())) .andDo(document("post-like", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), @@ -130,15 +130,17 @@ void createLike_MemberIdAndAcademyId_RegisterLike() throws Exception { } @Test + @Order(2) @DisplayName("등록한 좋아요를 제거한다.") - @WithMockCustomOAuth2LoginUser + @WithMockCustomOAuth2LoginUser(memberId = 2) void removeLike_LikeId_Remove() throws Exception { // Given - LikePostResult postResult = likeService.createLikeOfAcademy(param); + Like savedLike = likeRepository.save(like); // When - ResultActions perform = mockMvc.perform(delete("/likes/{likeId}", postResult.likeId()) - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt())); + ResultActions perform = mockMvc.perform(delete("/likes/{likeId}", savedLike.getId()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) + .param("memberId", String.valueOf(savedMember.getId()))); // Then perform.andDo(print()) @@ -158,16 +160,17 @@ void removeLike_LikeId_Remove() throws Exception { } @Test + @Order(value = 3) @DisplayName("학원 아이디로 좋아요를 삭제한다.") - @WithMockCustomOAuth2LoginUser + @WithMockCustomOAuth2LoginUser(memberId = 3) void removeLikeOfAcademy_AcademyId_Delete() throws Exception { // Given - LikePostResult postResult = likeService.createLikeOfAcademy(param); + likeRepository.save(like); // When ResultActions perform = mockMvc.perform(delete("/likes") - .header(AUTHORIZATION_HEADER, BEARER) - .queryParam("academyId", String.valueOf(postResult.academyId()))); + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) + .queryParam("academyId", String.valueOf(savedMember.getId()))); // Then perform.andDo(print()) @@ -175,12 +178,6 @@ void removeLikeOfAcademy_AcademyId_Delete() throws Exception { .andDo(document("delete-like-academyId", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), -// requestHeaders( -// headerWithName(AUTHORIZATION_HEADER).description("JWT 토큰 (Bearer)") -// ), -// queryParameters( -// parameterWithName("academyId").description("학원 아이디") -// ) resource(ResourceSnippetParameters.builder() .tag(TAG) .summary("학원 아이디로 좋아요 제거") @@ -196,18 +193,17 @@ void removeLikeOfAcademy_AcademyId_Delete() throws Exception { } @Test + @Order(value = 4) @DisplayName("좋아요한 학원 비용 정보를 응답받는다.") - @WithMockCustomOAuth2LoginUser + @WithMockCustomOAuth2LoginUser(memberId = 4) void getAllLikes_MemberId() throws Exception { // Given - given(academyAccessService.findAcademyFeeInfo(any())) - .willReturn(new AcademyFeeInfo("학원명", 100L)); - - likeService.createLikeOfAcademy(param); + likeRepository.save(like); // When ResultActions perform = mockMvc.perform(get("/likes") - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) + .param("memberId", String.valueOf(savedMember.getId())) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); diff --git a/src/test/java/org/guzzing/studayserver/domain/like/service/LikeFacadeTest.java b/src/test/java/org/guzzing/studayserver/domain/like/service/LikeFacadeTest.java new file mode 100644 index 000000000..e28889ad1 --- /dev/null +++ b/src/test/java/org/guzzing/studayserver/domain/like/service/LikeFacadeTest.java @@ -0,0 +1,142 @@ +package org.guzzing.studayserver.domain.like.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import jakarta.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Objects; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.academy.repository.academy.AcademyRepository; +import org.guzzing.studayserver.domain.like.controller.dto.request.LikePostRequest; +import org.guzzing.studayserver.domain.like.model.Like; +import org.guzzing.studayserver.domain.like.repository.LikeRepository; +import org.guzzing.studayserver.domain.like.service.dto.request.LikePostParam; +import org.guzzing.studayserver.domain.like.service.dto.response.LikeGetResult; +import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.member.repository.MemberRepository; +import org.guzzing.studayserver.testutil.fixture.academy.AcademyFixture; +import org.guzzing.studayserver.testutil.fixture.member.MemberFixture; +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.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class LikeFacadeTest { + + @Autowired + private LikeFacade likeFacade; + + @Autowired + private LikeRepository likeRepository; + @Autowired + private MemberRepository memberRepository; + @Autowired + private AcademyRepository academyRepository; + + private Member savedMember; + private Academy savedAcademy; + private Like like; + + @BeforeEach + void setUp() { + savedMember = memberRepository.save(MemberFixture.makeMemberEntity()); + savedAcademy = academyRepository.save(AcademyFixture.academySungnam()); + like = Like.of(savedMember, savedAcademy); + } + + @Test + @DisplayName("학원에 대해서 좋아요를 등록한다.") + void createLikeOfAcademy_WithMemberId() { + // Given & When + LikePostRequest request = new LikePostRequest(savedAcademy.getId()); + LikePostParam param = LikePostRequest.to(request, savedMember.getId()); + LikePostResult result = likeFacade.createLikeOfAcademy(param); + + // Then + assertThat(result.memberId()).isEqualTo(savedMember.getId()); + assertThat(result.academyId()).isEqualTo(savedAcademy.getId()); + } + + @Test + @DisplayName("학원에 대해 등록한 좋아요를 제거한다.") + void removeLikeOfAcademy_LikeId_Remove() { + // Given + Like savedLike = likeRepository.save(like); + + // When + likeFacade.removeLike(savedLike.getId(), savedLike.getMemberId()); + + // Then + boolean result = likeRepository.existsById(savedLike.getId()); + + assertThat(result).isFalse(); + } + + @Test + @DisplayName("학원 아이디로 등록한 좋아요를 제거한다.") + void deleteLikeOfAcademy_AcademyId_Delete() { + // Given + Like savedLike = likeRepository.save(like); + + // When + likeFacade.deleteLikeOfAcademy(savedLike.getMemberId(), savedLike.getAcademyId()); + + // Then + Member member = memberRepository.findById(savedLike.getMemberId()) + .orElseThrow(EntityNotFoundException::new); + + List result = likeRepository.findByMember(member) + .stream() + .map(Like::getAcademyId) + .filter(id -> Objects.equals(id, savedLike.getAcademyId())) + .toList(); + + assertThat(result).isEmpty(); + } + + @Test + @DisplayName("내가 좋아요한 모든 학원 비용 정보를 조회한다.") + void findAllLikesOfMember_MemberId_AcademyInfo() { + // Given + Like savedLike = likeRepository.save(like); + + // When + LikeGetResult result = likeFacade.getAllLikesOfMember(savedLike.getMemberId()); + + // Then + assertThat(result.likeAcademyInfos()).isNotEmpty(); + assertThat(result.totalFee()).isZero(); + } + + @Test + @DisplayName("멤버가 해당 학원에 대해서 좋아요를 했으면 True 를 반환한다.") + void isLiked_MemberAndAcademy_ReturnTrue() { + // Given + Like savedLike = likeRepository.save(like); + + // When + final boolean result = likeFacade.isLiked(savedLike.getMemberId(), savedLike.getAcademyId()); + + // Then + assertThat(result).isTrue(); + } + + @Test + @DisplayName("멤버가 해당 학원에 대해 좋아요를 하지 않았으면 False 를 반환한다.") + void isLiked_MemberAndAcademy_ReturnFalse() { + // Given + Academy otherAcademy = academyRepository.save(AcademyFixture.twoCategoriesAcademy()); + + // When + final boolean result = likeFacade.isLiked(savedMember.getId(), otherAcademy.getId()); + + // Then + assertThat(result).isFalse(); + } + +} diff --git a/src/test/java/org/guzzing/studayserver/domain/like/service/LikeServiceTest.java b/src/test/java/org/guzzing/studayserver/domain/like/service/LikeServiceTest.java deleted file mode 100644 index fc8e469ea..000000000 --- a/src/test/java/org/guzzing/studayserver/domain/like/service/LikeServiceTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.guzzing.studayserver.domain.like.service; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; - -import java.util.List; -import java.util.Objects; -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyFeeInfo; -import org.guzzing.studayserver.domain.like.controller.dto.request.LikePostRequest; -import org.guzzing.studayserver.domain.like.model.Like; -import org.guzzing.studayserver.domain.like.repository.LikeRepository; -import org.guzzing.studayserver.domain.like.service.dto.request.LikePostParam; -import org.guzzing.studayserver.domain.like.service.dto.response.LikeGetResult; -import org.guzzing.studayserver.domain.like.service.dto.response.LikePostResult; -import org.guzzing.studayserver.domain.member.annotation.ValidMemberAspect; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; -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.transaction.annotation.Transactional; - -@SpringBootTest -@Transactional -class LikeServiceTest { - - @Autowired - private LikeService likeService; - - @Autowired - private LikeRepository likeRepository; - - @MockBean - private AcademyAccessService academyAccessService; - @MockBean - private MemberAccessService memberAccessService; - @MockBean - private ValidMemberAspect validMemberAspect; - - private final Long memberId = 1L; - private final Long academyId = 1L; - private LikePostParam param; - - @BeforeEach - void setUp() { - LikePostRequest request = new LikePostRequest(academyId); - param = LikePostRequest.to(request, memberId); - } - - @Test - @DisplayName("학원에 대해서 좋아요를 등록한다.") - void createLikeOfAcademy_WithMemberId() { - // Given & When - LikePostResult result = likeService.createLikeOfAcademy(param); - - // Then - assertThat(result.memberId()).isEqualTo(memberId); - assertThat(result.academyId()).isEqualTo(academyId); - } - - @Test - @DisplayName("학원에 대해 등록한 좋아요를 제거한다.") - void removeLikeOfAcademy_LikeId_Remove() { - // Given - LikePostResult savedLike = likeService.createLikeOfAcademy(param); - - // When - likeService.removeLike(savedLike.likeId(), memberId); - - // Then - boolean result = likeRepository.existsById(savedLike.likeId()); - - assertThat(result).isFalse(); - } - - @Test - @DisplayName("학원 아이디로 등록한 좋아요를 제거한다.") - void deleteLikeOfAcademy_AcademyId_Delete() { - // Given - LikePostResult postResult = likeService.createLikeOfAcademy(param); - - // When - likeService.deleteLikeOfAcademy(postResult.academyId(), postResult.memberId()); - - // Then - List likes = likeRepository.findByMemberId(postResult.memberId()); - List result = likes.stream() - .map(Like::getAcademyId) - .filter(id -> Objects.equals(id, postResult.academyId())) - .toList(); - - assertThat(result).isEmpty(); - } - - @Test - @DisplayName("내가 좋아요한 모든 학원 비용 정보를 조회한다.") - void findAllLikesOfMember_MemberId_AcademyInfo() { - // Given - given(academyAccessService.findAcademyFeeInfo(any())) - .willReturn(new AcademyFeeInfo("학원명", 100L)); - - LikePostResult savedLike = likeService.createLikeOfAcademy(param); - - // When - LikeGetResult result = likeService.findAllLikesOfMember(savedLike.memberId()); - - // Then - assertThat(result.likeAcademyInfos()).isNotEmpty(); - assertThat(result.totalFee()).isEqualTo(100); - } - - @Test - @DisplayName("멤버가 해당 학원에 대해서 좋아요를 했는지 여부를 반환한다.") - void isLiked_MemberAndAcademy_ReturnTrue() { - // Given - final Long memberId = 1L; - final Long academyId = 1L; - final Like like = Like.of(memberId, academyId); - likeRepository.save(like); - - // When - final boolean result = likeService.isLiked(memberId, academyId); - - // Then - assertThat(result).isTrue(); - } - - @Test - @DisplayName("멤버가 해당 학원에 대해서 좋아요를 했는지 여부를 반환한다.") - void isLiked_MemberAndAcademy_ReturnFalse() { - // Given - final Long memberId = 1L; - final Long academyId = 1L; - final Like like = Like.of(memberId, academyId); - likeRepository.save(like); - - // When - final boolean result = likeService.isLiked(memberId, 2L); - - // Then - assertThat(result).isFalse(); - } - -} diff --git a/src/test/java/org/guzzing/studayserver/domain/review/controller/ReviewRestControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/review/controller/ReviewRestControllerTest.java index 23e549a0c..3ae4888d5 100644 --- a/src/test/java/org/guzzing/studayserver/domain/review/controller/ReviewRestControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/review/controller/ReviewRestControllerTest.java @@ -2,8 +2,7 @@ import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.AUTHORIZATION_HEADER; -import static org.guzzing.studayserver.testutil.fixture.TestConfig.BEARER; +import static org.guzzing.studayserver.testutil.JwtTestConfig.AUTHORIZATION_HEADER; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; @@ -22,29 +21,36 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; -import org.guzzing.studayserver.domain.academy.listener.NewReviewListener; -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; +import org.guzzing.studayserver.domain.academy.model.Academy; +import org.guzzing.studayserver.domain.academy.model.ReviewCount; +import org.guzzing.studayserver.domain.academy.repository.academy.AcademyRepository; +import org.guzzing.studayserver.domain.academy.repository.review.ReviewCountRepository; +import org.guzzing.studayserver.domain.member.repository.MemberRepository; import org.guzzing.studayserver.domain.review.controller.dto.request.ReviewPostRequest; import org.guzzing.studayserver.domain.review.fixture.ReviewFixture; -import org.guzzing.studayserver.domain.review.repository.ReviewRepository; +import org.guzzing.studayserver.testutil.JwtTestConfig; import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser; -import org.guzzing.studayserver.testutil.fixture.TestConfig; +import org.guzzing.studayserver.testutil.fixture.academy.AcademyFixture; +import org.guzzing.studayserver.testutil.fixture.member.MemberFixture; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.transaction.annotation.Transactional; @AutoConfigureMockMvc @AutoConfigureRestDocs +@TestMethodOrder(OrderAnnotation.class) @SpringBootTest +@Transactional class ReviewRestControllerTest { private static final String TAG = "리뷰 API"; @@ -52,37 +58,40 @@ class ReviewRestControllerTest { @Autowired private MockMvc mockMvc; - @Autowired - private TestConfig testConfig; @Autowired private ObjectMapper objectMapper; + @Autowired + private JwtTestConfig jwtTestConfig; - @MockBean - private MemberAccessService memberAccessService; - @MockBean - private AcademyAccessService academyAccessService; - @MockBean - private NewReviewListener newReviewListener; - @Autowired - private ReviewRepository reviewRepository; + private MemberRepository memberRepository; + @Autowired + private AcademyRepository academyRepository; + @Autowired + private ReviewCountRepository reviewCountRepository; + + private Academy savedAcademy; @BeforeEach void setUp() { - reviewRepository.deleteAll(); + memberRepository.save(MemberFixture.makeMemberEntity()); + savedAcademy = academyRepository.save(AcademyFixture.academySungnam()); + reviewCountRepository.save(ReviewCount.makeDefaultReviewCount(savedAcademy)); } @Test + @Order(value = 1) @DisplayName("리뷰 타입이 3개 이하고, 해당 학원에 대해서 등록한 학원이 없다면 리뷰를 등록한다.") - @WithMockCustomOAuth2LoginUser + @WithMockCustomOAuth2LoginUser(memberId = 1) void registerReview_Success() throws Exception { // Given - ReviewPostRequest request = ReviewFixture.makeReviewPostRequest(true); + ReviewPostRequest request = ReviewFixture.makeReviewPostRequest(savedAcademy.getId(), + ReviewFixture.makeValidReviewMap()); String jsonBody = objectMapper.writeValueAsString(request); // When ResultActions perform = mockMvc.perform(post("/reviews") - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) .content(jsonBody) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -92,7 +101,7 @@ void registerReview_Success() throws Exception { .andExpect(status().isCreated()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.reviewId").isNumber()) - .andExpect(jsonPath("$.academyId").isNumber()) + .andExpect(jsonPath("$.academyId").value(savedAcademy.getId())) .andDo(document("post-review", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), @@ -123,17 +132,14 @@ void registerReview_Success() throws Exception { } @Test + @Order(value = 2) @DisplayName("리뷰를 등록한 적 없다면 리뷰 등록 가능함을 응답한다.") - @WithMockCustomOAuth2LoginUser - @Transactional + @WithMockCustomOAuth2LoginUser(memberId = 2) void getReviewable_NotExistsReview_Reviewable() throws Exception { - // Given - final Long academyId = 1L; - // When ResultActions perform = mockMvc.perform(get("/reviews/reviewable") - .param("academyId", String.valueOf(academyId)) - .header(AUTHORIZATION_HEADER, BEARER + testConfig.getJwt()) + .param("academyId", String.valueOf(savedAcademy.getId())) + .header(AUTHORIZATION_HEADER, jwtTestConfig.getJwt()) .accept(APPLICATION_JSON_VALUE) .contentType(APPLICATION_JSON_VALUE)); @@ -141,7 +147,7 @@ void getReviewable_NotExistsReview_Reviewable() throws Exception { perform.andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.academyId").value(1L)) + .andExpect(jsonPath("$.academyId").value(savedAcademy.getId())) .andExpect(jsonPath("$.reviewable").value(true)) .andDo(document("get-reviewable", preprocessRequest(prettyPrint()), diff --git a/src/test/java/org/guzzing/studayserver/domain/review/fixture/ReviewFixture.java b/src/test/java/org/guzzing/studayserver/domain/review/fixture/ReviewFixture.java index 1cd83ee76..191ec70a6 100644 --- a/src/test/java/org/guzzing/studayserver/domain/review/fixture/ReviewFixture.java +++ b/src/test/java/org/guzzing/studayserver/domain/review/fixture/ReviewFixture.java @@ -15,32 +15,17 @@ public class ReviewFixture { - public static final Long memberId = 1L; - public static final Long academyId = 1L; + public static ReviewPostParam makeReviewPostParam(final long memberId, final long academyId, + final Map reviewMap) { + ReviewPostRequest request = makeReviewPostRequest(academyId, reviewMap); - public static ReviewPostParam makeReviewPostParam(boolean isValid) { - ReviewPostRequest request = makeReviewPostRequest(isValid); - - return ReviewPostRequest.to(1L, request); - } - - public static ReviewPostParam makeReviewPostParam(long academyId) { - return new ReviewPostParam( - 1L, - academyId, - true, - true, - false, - false, - true, - false); + return ReviewPostRequest.to(memberId, request); } - public static ReviewPostRequest makeReviewPostRequest(boolean isValid) { - Map reviewMap = isValid ? makeValidReviewMap() : makeInvalidReviewMap(); - + public static ReviewPostRequest makeReviewPostRequest(final long academyId, + final Map reviewMap) { return new ReviewPostRequest( - 1L, + academyId, reviewMap.get(KINDNESS), reviewMap.get(CHEAP_FEE), reviewMap.get(GOOD_FACILITY), @@ -49,19 +34,6 @@ public static ReviewPostRequest makeReviewPostRequest(boolean isValid) { reviewMap.get(SHUTTLE_AVAILABILITY)); } - public static Map makeInvalidReviewMap() { - Map invalidReviewMap = new ConcurrentHashMap<>(); - - invalidReviewMap.put(KINDNESS, true); - invalidReviewMap.put(CHEAP_FEE, true); - invalidReviewMap.put(GOOD_FACILITY, true); - invalidReviewMap.put(GOOD_MANAGEMENT, false); - invalidReviewMap.put(LOVELY_TEACHING, true); - invalidReviewMap.put(SHUTTLE_AVAILABILITY, false); - - return invalidReviewMap; - } - public static Map makeValidReviewMap() { Map validReviewMap = new ConcurrentHashMap<>(); @@ -75,4 +47,17 @@ public static Map makeValidReviewMap() { return validReviewMap; } + public static Map makeInvalidReviewMap() { + Map invalidReviewMap = new ConcurrentHashMap<>(); + + invalidReviewMap.put(KINDNESS, true); + invalidReviewMap.put(CHEAP_FEE, true); + invalidReviewMap.put(GOOD_FACILITY, true); + invalidReviewMap.put(GOOD_MANAGEMENT, false); + invalidReviewMap.put(LOVELY_TEACHING, true); + invalidReviewMap.put(SHUTTLE_AVAILABILITY, false); + + return invalidReviewMap; + } + } diff --git a/src/test/java/org/guzzing/studayserver/domain/review/service/ReviewServiceTest.java b/src/test/java/org/guzzing/studayserver/domain/review/service/ReviewFacadeTest.java similarity index 55% rename from src/test/java/org/guzzing/studayserver/domain/review/service/ReviewServiceTest.java rename to src/test/java/org/guzzing/studayserver/domain/review/service/ReviewFacadeTest.java index 3f2e5b5c3..37604fccb 100644 --- a/src/test/java/org/guzzing/studayserver/domain/review/service/ReviewServiceTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/review/service/ReviewFacadeTest.java @@ -5,125 +5,108 @@ import static org.guzzing.studayserver.domain.review.model.ReviewType.CHEAP_FEE; import static org.guzzing.studayserver.domain.review.model.ReviewType.GOOD_FACILITY; +import jakarta.persistence.EntityExistsException; import java.util.Map; -import org.guzzing.studayserver.domain.academy.listener.NewReviewListener; import org.guzzing.studayserver.domain.academy.model.Academy; import org.guzzing.studayserver.domain.academy.model.ReviewCount; import org.guzzing.studayserver.domain.academy.repository.academy.AcademyRepository; import org.guzzing.studayserver.domain.academy.repository.review.ReviewCountRepository; -import org.guzzing.studayserver.domain.academy.service.AcademyAccessService; -import org.guzzing.studayserver.domain.member.service.MemberAccessService; +import org.guzzing.studayserver.domain.member.model.Member; +import org.guzzing.studayserver.domain.member.repository.MemberRepository; import org.guzzing.studayserver.domain.review.fixture.ReviewFixture; import org.guzzing.studayserver.domain.review.model.ReviewType; -import org.guzzing.studayserver.domain.review.repository.ReviewRepository; import org.guzzing.studayserver.domain.review.service.dto.request.ReviewPostParam; import org.guzzing.studayserver.domain.review.service.dto.response.ReviewPostResult; import org.guzzing.studayserver.domain.review.service.dto.response.ReviewableResult; -import org.guzzing.studayserver.global.exception.ReviewException; import org.guzzing.studayserver.testutil.fixture.academy.AcademyFixture; +import org.guzzing.studayserver.testutil.fixture.member.MemberFixture; 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.transaction.annotation.Transactional; @SpringBootTest -class ReviewServiceTest { +@Transactional +class ReviewFacadeTest { @Autowired - private ReviewService reviewService; - - @MockBean - private AcademyAccessService academyAccessService; - @MockBean - private MemberAccessService memberAccessService; + private ReviewFacade reviewFacade; @Autowired - private ReviewRepository reviewRepository; - - @Autowired - private ReviewCountRepository reviewCountRepository; + private MemberRepository memberRepository; @Autowired private AcademyRepository academyRepository; @Autowired - private NewReviewListener newReviewListener; + private ReviewCountRepository reviewCountRepository; + + private Member savedMember; + private Academy savedAcademy; @BeforeEach void setUp() { - reviewRepository.deleteAll(); + savedMember = memberRepository.save(MemberFixture.makeMemberEntity()); + savedAcademy = academyRepository.save(AcademyFixture.academySungnam()); + reviewCountRepository.save(ReviewCount.makeDefaultReviewCount(savedAcademy)); } @Test @DisplayName("해당 학원에 리뷰를 남긴 적이 없으면 리뷰를 등록한다.") void createReviewOfAcademy_NotReviewYet_RegisterReview() { // Given - Academy academy = AcademyFixture.academySungnam(); - Academy savedAcademy = academyRepository.save(academy); - - ReviewCount reviewCount = ReviewCount.makeDefaultReviewCount(academy); - reviewCountRepository.save(reviewCount); - - ReviewPostParam param = ReviewFixture.makeReviewPostParam(savedAcademy.getId()); - Map validReviewMap = ReviewFixture.makeValidReviewMap(); + Map reviewMap = ReviewFixture.makeValidReviewMap(); + ReviewPostParam param = ReviewFixture.makeReviewPostParam(savedMember.getId(), savedAcademy.getId(), reviewMap); // When - int beforeKindnessCount = reviewCountRepository.getByAcademyId(param.academyId()).getKindnessCount(); - ReviewPostResult result = reviewService.createReviewOfAcademy(param); - int afterKindnessCount = reviewCountRepository.getByAcademyId(param.academyId()).getKindnessCount(); + ReviewPostResult result = reviewFacade.createReviewOfAcademy(param); + int kindnessCount = reviewCountRepository.getByAcademyId(param.academyId()) + .getKindnessCount(); // Then - assertThat(afterKindnessCount).isEqualTo(beforeKindnessCount + 1); + assertThat(kindnessCount).isOne(); assertThat(result).satisfies(entry -> { - assertThat(entry.memberId()).isEqualTo(ReviewFixture.memberId); + assertThat(entry.memberId()).isEqualTo(savedMember.getId()); assertThat(entry.academyId()).isEqualTo(savedAcademy.getId()); - assertThat(entry.cheapFee()).isEqualTo(validReviewMap.get(CHEAP_FEE)); - assertThat(entry.goodFacility()).isEqualTo(validReviewMap.get(GOOD_FACILITY)); + assertThat(entry.cheapFee()).isEqualTo(reviewMap.get(CHEAP_FEE)); + assertThat(entry.goodFacility()).isEqualTo(reviewMap.get(GOOD_FACILITY)); }); } @Test @DisplayName("해당 학원에 리뷰를 남겼다면 리뷰 등록에 실패한다.") - @Transactional void createReviewOfAcademy_Reviewed_Fail() { // Given - boolean isValid = true; - ReviewPostParam param = ReviewFixture.makeReviewPostParam(isValid); + ReviewPostParam param = ReviewFixture.makeReviewPostParam(savedMember.getId(), savedAcademy.getId(), + ReviewFixture.makeValidReviewMap()); - reviewService.createReviewOfAcademy(param); + reviewFacade.createReviewOfAcademy(param); // When & Then - assertThatThrownBy(() -> reviewService.createReviewOfAcademy(param)) - .isInstanceOf(ReviewException.class) + assertThatThrownBy(() -> reviewFacade.createReviewOfAcademy(param)) + .isInstanceOf(EntityExistsException.class) .hasMessage("이미 리뷰를 남겼습니다."); } @Test @DisplayName("리뷰를 3 항목 초과로 남겼다면 리뷰 등록에 실패한다.") - @Transactional - void createReviewOfAcademy_GreaterThanThreeReivewTypes_Fail() { + void createReviewOfAcademy_GreaterThanThreeReviewTypes_Fail() { // Given - boolean isValid = false; - ReviewPostParam param = ReviewFixture.makeReviewPostParam(isValid); + ReviewPostParam param = ReviewFixture.makeReviewPostParam(savedMember.getId(), savedAcademy.getId(), + ReviewFixture.makeInvalidReviewMap()); // When & Then - assertThatThrownBy(() -> reviewService.createReviewOfAcademy(param)) - .isInstanceOf(ReviewException.class) + assertThatThrownBy(() -> reviewFacade.createReviewOfAcademy(param)) + .isInstanceOf(IllegalArgumentException.class) .hasMessage("리뷰는 3개 까지 가능합니다."); } @Test @DisplayName("해당 학원에 리뷰를 남긴 적 없으면 리뷰 등록 가능하다.") - @Transactional void isReviewableToAcademy_NotExistsReview_Reviewable() { - // Given - final Long memberId = 100L; - final Long academyId = 100L; - // When - ReviewableResult result = reviewService.getReviewableToAcademy(memberId, academyId); + ReviewableResult result = reviewFacade.getReviewableToAcademy(savedMember.getId(), savedAcademy.getId()); // Then assertThat(result.reviewable()).isTrue(); @@ -131,16 +114,15 @@ void isReviewableToAcademy_NotExistsReview_Reviewable() { @Test @DisplayName("해당 학원에 리뷰를 남겼다면 리뷰 등록 불가하다.") - @Transactional void isReviewableToAcademy_ExistsReview_NotReviewable() { // Given - boolean isValid = true; - ReviewPostParam param = ReviewFixture.makeReviewPostParam(isValid); + ReviewPostParam param = ReviewFixture.makeReviewPostParam(savedMember.getId(), savedAcademy.getId(), + ReviewFixture.makeValidReviewMap()); - reviewService.createReviewOfAcademy(param); + reviewFacade.createReviewOfAcademy(param); // When & Then - ReviewableResult result = reviewService.getReviewableToAcademy(param.memberId(), param.academyId()); + ReviewableResult result = reviewFacade.getReviewableToAcademy(param.memberId(), param.academyId()); assertThat(result.reviewable()).isFalse(); } diff --git a/src/test/java/org/guzzing/studayserver/testutil/fixture/TestConfig.java b/src/test/java/org/guzzing/studayserver/testutil/JwtTestConfig.java similarity index 81% rename from src/test/java/org/guzzing/studayserver/testutil/fixture/TestConfig.java rename to src/test/java/org/guzzing/studayserver/testutil/JwtTestConfig.java index 364854fd3..e978918d4 100644 --- a/src/test/java/org/guzzing/studayserver/testutil/fixture/TestConfig.java +++ b/src/test/java/org/guzzing/studayserver/testutil/JwtTestConfig.java @@ -1,11 +1,11 @@ -package org.guzzing.studayserver.testutil.fixture; +package org.guzzing.studayserver.testutil; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "test") -public class TestConfig { +public class JwtTestConfig { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String BEARER = "Bearer "; @@ -13,7 +13,7 @@ public class TestConfig { private String jwt; public String getJwt() { - return jwt; + return BEARER + jwt; } public void setJwt(String jwt) { diff --git a/src/test/java/org/guzzing/studayserver/testutil/fixture/academy/AcademyFixture.java b/src/test/java/org/guzzing/studayserver/testutil/fixture/academy/AcademyFixture.java index 7b054bbcc..d51784377 100644 --- a/src/test/java/org/guzzing/studayserver/testutil/fixture/academy/AcademyFixture.java +++ b/src/test/java/org/guzzing/studayserver/testutil/fixture/academy/AcademyFixture.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; - import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeParam; import org.guzzing.studayserver.domain.academy.model.Academy; import org.guzzing.studayserver.domain.academy.model.AcademyCategory; @@ -114,8 +113,9 @@ public static ReviewCount reviewCountDefault(Academy academy) { return ReviewCount.makeDefaultReviewCount(academy); } - public static AcademiesByLocationWithScrollParam academiesByLocationWithScrollParam(double latitude, double longitude) { - return AcademiesByLocationWithScrollParam.of(latitude, longitude, 1L,0 ); + public static AcademiesByLocationWithScrollParam academiesByLocationWithScrollParam(double latitude, + double longitude) { + return AcademiesByLocationWithScrollParam.of(latitude, longitude, 1L, 0); } public static AcademyFilterWithScrollParam academyFilterWithScrollParam( diff --git a/src/test/java/org/guzzing/studayserver/domain/dashboard/fixture/DashboardFixture.java b/src/test/java/org/guzzing/studayserver/testutil/fixture/dashboard/DashboardFixture.java similarity index 99% rename from src/test/java/org/guzzing/studayserver/domain/dashboard/fixture/DashboardFixture.java rename to src/test/java/org/guzzing/studayserver/testutil/fixture/dashboard/DashboardFixture.java index 0216362a0..f52c5f314 100644 --- a/src/test/java/org/guzzing/studayserver/domain/dashboard/fixture/DashboardFixture.java +++ b/src/test/java/org/guzzing/studayserver/testutil/fixture/dashboard/DashboardFixture.java @@ -1,4 +1,4 @@ -package org.guzzing.studayserver.domain.dashboard.fixture; +package org.guzzing.studayserver.testutil.fixture.dashboard; import static java.time.DayOfWeek.FRIDAY; import static java.time.DayOfWeek.MONDAY; diff --git a/src/test/java/org/guzzing/studayserver/testutil/fixture/member/MemberFixture.java b/src/test/java/org/guzzing/studayserver/testutil/fixture/member/MemberFixture.java index 2bbaec658..6eac25eba 100644 --- a/src/test/java/org/guzzing/studayserver/testutil/fixture/member/MemberFixture.java +++ b/src/test/java/org/guzzing/studayserver/testutil/fixture/member/MemberFixture.java @@ -7,7 +7,7 @@ public class MemberFixture { - public static Member member() { + public static Member makeMemberEntity() { return Member.of(new NickName("나는왕이다"), "12345678", MemberProvider.KAKAO, RoleType.USER); }