From 1e6159f84d26cac09094b51edaa8aa004e2e2de0 Mon Sep 17 00:00:00 2001 From: Awhn Date: Fri, 8 Nov 2024 22:56:07 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Review=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gamsa/activity/domain/Activity.java | 6 +- .../activity/dto/ActivityDetailResponse.java | 52 +++++---- .../activity/service/ActivityService.java | 35 ++++-- .../history/dto/HistoryFindSliceResponse.java | 8 +- .../gamsa/history/service/HistoryService.java | 33 ++++-- .../java/com/gamsa/review/domain/Answer.java | 4 +- .../java/com/gamsa/review/domain/Review.java | 12 +- .../com/gamsa/review/dto/ReviewResponse.java | 21 ++++ .../gamsa/review/entity/AnswerJpaEntity.java | 37 ++++-- .../review/entity/QuestionJpaEntity.java | 26 ++--- .../gamsa/review/entity/ReviewJpaEntity.java | 51 +++++++-- .../repository/AnswerJpaRepository.java | 9 ++ .../repository/QuestionJpaRepository.java | 4 + .../repository/ReviewJpaRepository.java | 11 ++ .../review/repository/ReviewRepository.java | 4 + .../repository/ReviewRepositoryImpl.java | 26 +++++ .../gamsa/review/service/ReviewService.java | 52 ++++++--- .../history/service/HitstoryServiceTest.java | 42 ++++--- .../review/stub/StubAnswerRepository.java | 12 ++ .../review/stub/StubQuestionRepository.java | 34 ++++++ .../review/stub/StubReviewRepository.java | 108 ++++++++++++++++++ 21 files changed, 474 insertions(+), 113 deletions(-) create mode 100644 src/main/java/com/gamsa/review/dto/ReviewResponse.java create mode 100644 src/main/java/com/gamsa/review/repository/AnswerJpaRepository.java create mode 100644 src/main/java/com/gamsa/review/repository/ReviewJpaRepository.java create mode 100644 src/main/java/com/gamsa/review/repository/ReviewRepositoryImpl.java create mode 100644 src/test/java/com/gamsa/review/stub/StubAnswerRepository.java create mode 100644 src/test/java/com/gamsa/review/stub/StubQuestionRepository.java create mode 100644 src/test/java/com/gamsa/review/stub/StubReviewRepository.java diff --git a/src/main/java/com/gamsa/activity/domain/Activity.java b/src/main/java/com/gamsa/activity/domain/Activity.java index 96afa9f..34f3b96 100644 --- a/src/main/java/com/gamsa/activity/domain/Activity.java +++ b/src/main/java/com/gamsa/activity/domain/Activity.java @@ -1,10 +1,12 @@ package com.gamsa.activity.domain; import com.gamsa.activity.constant.Category; -import java.time.LocalDateTime; import lombok.Builder; import lombok.Getter; +import java.math.BigDecimal; +import java.time.LocalDateTime; + @Getter @Builder public class Activity { @@ -23,6 +25,8 @@ public class Activity { private boolean adultPossible; private boolean teenPossible; private boolean groupPossible; + private BigDecimal latitude; + private BigDecimal longitude; private int actWeek; private String actManager; private String actPhone; diff --git a/src/main/java/com/gamsa/activity/dto/ActivityDetailResponse.java b/src/main/java/com/gamsa/activity/dto/ActivityDetailResponse.java index 9e50ce7..ac421ac 100644 --- a/src/main/java/com/gamsa/activity/dto/ActivityDetailResponse.java +++ b/src/main/java/com/gamsa/activity/dto/ActivityDetailResponse.java @@ -3,11 +3,15 @@ import com.gamsa.activity.constant.Category; import com.gamsa.activity.domain.Activity; -import java.time.LocalDateTime; +import com.gamsa.review.dto.QuestionResponse; import lombok.Builder; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Map; + @Getter @Builder @RequiredArgsConstructor @@ -35,29 +39,29 @@ public class ActivityDetailResponse { private final InstituteDetailResponse institute; private final DistrictDetailResponse sidoGungu; - public static ActivityDetailResponse from(Activity activity) { + public static ActivityDetailResponse from(Activity activity, Map scores) { return ActivityDetailResponse.builder() - .actId(activity.getActId()) - .actTitle(activity.getActTitle()) - .actLocation(activity.getActLocation()) - .description(activity.getDescription()) - .noticeStartDate(activity.getNoticeStartDate()) - .noticeEndDate(activity.getNoticeEndDate()) - .actStartDate(activity.getActStartDate()) - .actEndDate(activity.getActEndDate()) - .actStartTime(activity.getActStartTime()) - .actEndTime(activity.getActEndTime()) - .recruitTotalNum(activity.getRecruitTotalNum()) - .adultPossible(activity.isAdultPossible()) - .teenPossible(activity.isTeenPossible()) - .groupPossible(activity.isGroupPossible()) - .actWeek(activity.getActWeek()) - .actManager(activity.getActManager()) - .actPhone(activity.getActPhone()) - .url(activity.getUrl()) - .category(activity.getCategory()) - .institute(InstituteDetailResponse.from(activity.getInstitute())) - .sidoGungu(DistrictDetailResponse.from(activity.getSidoGungu())) - .build(); + .actId(activity.getActId()) + .actTitle(activity.getActTitle()) + .actLocation(activity.getActLocation()) + .description(activity.getDescription()) + .noticeStartDate(activity.getNoticeStartDate()) + .noticeEndDate(activity.getNoticeEndDate()) + .actStartDate(activity.getActStartDate()) + .actEndDate(activity.getActEndDate()) + .actStartTime(activity.getActStartTime()) + .actEndTime(activity.getActEndTime()) + .recruitTotalNum(activity.getRecruitTotalNum()) + .adultPossible(activity.isAdultPossible()) + .teenPossible(activity.isTeenPossible()) + .groupPossible(activity.isGroupPossible()) + .actWeek(activity.getActWeek()) + .actManager(activity.getActManager()) + .actPhone(activity.getActPhone()) + .url(activity.getUrl()) + .category(activity.getCategory()) + .institute(InstituteDetailResponse.from(activity.getInstitute(), scores)) + .sidoGungu(DistrictDetailResponse.from(activity.getSidoGungu())) + .build(); } } diff --git a/src/main/java/com/gamsa/activity/service/ActivityService.java b/src/main/java/com/gamsa/activity/service/ActivityService.java index 88b1687..5d197b6 100644 --- a/src/main/java/com/gamsa/activity/service/ActivityService.java +++ b/src/main/java/com/gamsa/activity/service/ActivityService.java @@ -12,11 +12,18 @@ import com.gamsa.activity.repository.ActivityRepository; import com.gamsa.activity.repository.DistrictRepository; import com.gamsa.activity.repository.InstituteRepository; +import com.gamsa.review.dto.QuestionResponse; +import com.gamsa.review.service.QuestionService; +import com.gamsa.review.service.ReviewService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + @RequiredArgsConstructor @Service public class ActivityService { @@ -24,33 +31,45 @@ public class ActivityService { private final ActivityRepository activityRepository; private final InstituteRepository instituteRepository; private final DistrictRepository districtRepository; + private final QuestionService questionService; + private final ReviewService reviewService; public void save(ActivitySaveRequest saveRequest) { // 중복 여부 확인 activityRepository.findById(saveRequest.getActId()) - .ifPresent(activity -> { - throw new ActivityException(ActivityErrorCode.ACTIVITY_ALREADY_EXISTS); - }); + .ifPresent(activity -> { + throw new ActivityException(ActivityErrorCode.ACTIVITY_ALREADY_EXISTS); + }); // 기관 존재 확인 Institute institute = instituteRepository.findById(saveRequest.getInstituteId()) - .orElseThrow(() -> new ActivityException(ActivityErrorCode.INSTITUTE_NOT_EXISTS)); + .orElseThrow(() -> new ActivityException(ActivityErrorCode.INSTITUTE_NOT_EXISTS)); // 시도, 군구 존재 확인 District sidoGungu = districtRepository.findBySidoGunguCode(saveRequest.getSidoGunguCode()) - .orElseThrow(() -> new ActivityException(ActivityErrorCode.DISTRICT_NOT_EXISTS)); + .orElseThrow(() -> new ActivityException(ActivityErrorCode.DISTRICT_NOT_EXISTS)); activityRepository.save(saveRequest.toModel(institute, sidoGungu)); } public Slice findSlice(ActivityFilterRequest request, - Pageable pageable) { + Pageable pageable) { Slice activities = activityRepository.findSlice(request, pageable); return activities.map(ActivityFindSliceResponse::from); } public ActivityDetailResponse findById(Long activityId) { Activity activity = activityRepository.findById(activityId) - .orElseThrow(() -> new ActivityException(ActivityErrorCode.ACTIVITY_NOT_EXISTS)); - return ActivityDetailResponse.from(activity); + .orElseThrow(() -> new ActivityException(ActivityErrorCode.ACTIVITY_NOT_EXISTS)); + + + Map scores = new HashMap<>(); + long instituteId = activity.getInstitute().getInstituteId(); + + questionService.findAllResponse().forEach(question -> { + BigDecimal score = reviewService.getAverageScore(instituteId, question.getQuestionId()); + scores.put(question, score); + }); + + return ActivityDetailResponse.from(activity, scores); } } diff --git a/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java b/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java index c01fb39..9b3c9de 100644 --- a/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java +++ b/src/main/java/com/gamsa/history/dto/HistoryFindSliceResponse.java @@ -3,10 +3,14 @@ import com.gamsa.activity.dto.ActivityDetailResponse; import com.gamsa.history.constant.ActivityStatus; import com.gamsa.history.domain.History; +import com.gamsa.review.dto.QuestionResponse; import lombok.Builder; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.math.BigDecimal; +import java.util.Map; + @Getter @Builder @RequiredArgsConstructor @@ -18,13 +22,13 @@ public class HistoryFindSliceResponse { private final ActivityStatus activityStatus; private final boolean reviewed; - public static HistoryFindSliceResponse from(final History history) { + public static HistoryFindSliceResponse from(History history, Map scores) { return HistoryFindSliceResponse.builder() .historyId(history.getHistoryId()) .avatarId(history.getAvatar().getAvatarId()) .activityStatus(history.getActivityStatus()) .reviewed(history.isReviewed()) - .activity(ActivityDetailResponse.from(history.getActivity())) + .activity(ActivityDetailResponse.from(history.getActivity(), scores)) .build(); } } diff --git a/src/main/java/com/gamsa/history/service/HistoryService.java b/src/main/java/com/gamsa/history/service/HistoryService.java index 6807550..2c0bcf7 100644 --- a/src/main/java/com/gamsa/history/service/HistoryService.java +++ b/src/main/java/com/gamsa/history/service/HistoryService.java @@ -8,39 +8,58 @@ import com.gamsa.history.dto.HistoryFindSliceResponse; import com.gamsa.history.dto.HistorySaveRequest; import com.gamsa.history.repository.HistoryRepository; -import java.time.LocalDateTime; -import java.util.NoSuchElementException; +import com.gamsa.review.dto.QuestionResponse; +import com.gamsa.review.service.QuestionService; +import com.gamsa.review.service.ReviewService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.NoSuchElementException; + @RequiredArgsConstructor @Service public class HistoryService { private final HistoryRepository historyRepository; private final AvatarRepository avatarRepository; private final ActivityRepository activityRepository; + private final QuestionService questionService; + private final ReviewService reviewService; public void save(HistorySaveRequest saveRequest, Long userId) { Avatar avatar = avatarRepository.findByUserId(userId) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(NoSuchElementException::new); Activity activity = activityRepository.findById(saveRequest.getActId()) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(NoSuchElementException::new); History history = saveRequest.toModel(avatar, activity); historyRepository.save(history); } public Slice findSliceByAvatarId(Long userId, Pageable pageable) { Avatar avatar = avatarRepository.findByUserId(userId) - .orElseThrow(NoSuchElementException::new); + .orElseThrow(NoSuchElementException::new); Slice histories = historyRepository - .findSliceByAvatarId(avatar.getAvatarId(), pageable); + .findSliceByAvatarId(avatar.getAvatarId(), pageable); histories.forEach(this::checkDate); - return histories.map(HistoryFindSliceResponse::from); + return histories.map(history -> { + Map scores = new HashMap<>(); + long instituteId = history.getActivity().getInstitute().getInstituteId(); + + questionService.findAllResponse().forEach(question -> { + BigDecimal score = reviewService.getAverageScore(instituteId, question.getQuestionId()); + scores.put(question, score); + }); + + return HistoryFindSliceResponse.from(history, scores); + }); } public void delete(long historyId) { diff --git a/src/main/java/com/gamsa/review/domain/Answer.java b/src/main/java/com/gamsa/review/domain/Answer.java index a1c07e9..3c69b71 100644 --- a/src/main/java/com/gamsa/review/domain/Answer.java +++ b/src/main/java/com/gamsa/review/domain/Answer.java @@ -6,7 +6,7 @@ @Getter @Builder public class Answer { - - private Question question; + private Long answerId; private int score; + private Question question; } diff --git a/src/main/java/com/gamsa/review/domain/Review.java b/src/main/java/com/gamsa/review/domain/Review.java index 3495742..ba82f6f 100644 --- a/src/main/java/com/gamsa/review/domain/Review.java +++ b/src/main/java/com/gamsa/review/domain/Review.java @@ -1,12 +1,22 @@ package com.gamsa.review.domain; -import java.util.List; +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.domain.Institute; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.history.domain.History; import lombok.Builder; import lombok.Getter; +import java.util.List; + @Getter @Builder public class Review { + private Long reviewId; private List answers; + private Avatar avatar; + private Activity activity; + private Institute institute; + private History history; } diff --git a/src/main/java/com/gamsa/review/dto/ReviewResponse.java b/src/main/java/com/gamsa/review/dto/ReviewResponse.java new file mode 100644 index 0000000..00dabd2 --- /dev/null +++ b/src/main/java/com/gamsa/review/dto/ReviewResponse.java @@ -0,0 +1,21 @@ +package com.gamsa.review.dto; + +import com.gamsa.review.domain.Question; +import lombok.Builder; +import lombok.Getter; + +import java.math.BigDecimal; + +@Getter +@Builder +public class ReviewResponse { + private QuestionResponse question; + private BigDecimal score; + + public static ReviewResponse from(Question question, BigDecimal score) { + return ReviewResponse.builder() + .question(QuestionResponse.from(question)) + .score(score) + .build(); + } +} diff --git a/src/main/java/com/gamsa/review/entity/AnswerJpaEntity.java b/src/main/java/com/gamsa/review/entity/AnswerJpaEntity.java index 49ddf84..bf9da5f 100644 --- a/src/main/java/com/gamsa/review/entity/AnswerJpaEntity.java +++ b/src/main/java/com/gamsa/review/entity/AnswerJpaEntity.java @@ -1,12 +1,8 @@ package com.gamsa.review.entity; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import com.gamsa.review.domain.Answer; +import jakarta.persistence.*; +import lombok.*; @Getter @Builder @@ -16,4 +12,31 @@ @Table(name = "answer") public class AnswerJpaEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "answer_id") + private Long answerId; + + @Column + private int score; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "question_id") + private QuestionJpaEntity question; + + public static AnswerJpaEntity from(Answer answer) { + return AnswerJpaEntity.builder() + .answerId(answer.getAnswerId()) + .score(answer.getScore()) + .question(QuestionJpaEntity.from(answer.getQuestion())) + .build(); + } + + public Answer toModel() { + return Answer.builder() + .answerId(answerId) + .score(score) + .question(question.toModel()) + .build(); + } } diff --git a/src/main/java/com/gamsa/review/entity/QuestionJpaEntity.java b/src/main/java/com/gamsa/review/entity/QuestionJpaEntity.java index b14f56b..6f0db0d 100644 --- a/src/main/java/com/gamsa/review/entity/QuestionJpaEntity.java +++ b/src/main/java/com/gamsa/review/entity/QuestionJpaEntity.java @@ -1,17 +1,8 @@ package com.gamsa.review.entity; import com.gamsa.review.domain.Question; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import jakarta.persistence.*; +import lombok.*; @Getter @Builder @@ -29,10 +20,17 @@ public class QuestionJpaEntity { @Column(name = "content", length = 255) private String content; + public static QuestionJpaEntity from(Question question) { + return QuestionJpaEntity.builder() + .questionId(question.getQuestionId()) + .content(question.getContent()) + .build(); + } + public Question toModel() { return Question.builder() - .questionId(questionId) - .content(content) - .build(); + .questionId(questionId) + .content(content) + .build(); } } diff --git a/src/main/java/com/gamsa/review/entity/ReviewJpaEntity.java b/src/main/java/com/gamsa/review/entity/ReviewJpaEntity.java index 3f9f074..18d0896 100644 --- a/src/main/java/com/gamsa/review/entity/ReviewJpaEntity.java +++ b/src/main/java/com/gamsa/review/entity/ReviewJpaEntity.java @@ -1,18 +1,13 @@ package com.gamsa.review.entity; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; +import com.gamsa.activity.entity.ActivityJpaEntity; +import com.gamsa.activity.entity.InstituteJpaEntity; +import com.gamsa.history.entity.HistoryJpaEntity; +import com.gamsa.review.domain.Review; +import jakarta.persistence.*; +import lombok.*; + import java.util.List; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; @Getter @Builder @@ -30,4 +25,36 @@ public class ReviewJpaEntity { @OneToMany private List answers; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "activity_id") + private ActivityJpaEntity activity; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "institute_id") + private InstituteJpaEntity institute; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "history_id") + private HistoryJpaEntity history; + + public static ReviewJpaEntity from(Review review) { + return ReviewJpaEntity.builder() + .reviewId(review.getReviewId()) + .answers(review.getAnswers().stream().map(answer -> AnswerJpaEntity.from(answer)).toList()) + .activity(ActivityJpaEntity.from(review.getActivity())) + .institute(InstituteJpaEntity.from(review.getInstitute())) + .history(HistoryJpaEntity.from(review.getHistory())) + .build(); + } + + public Review toModel() { + return Review.builder() + .reviewId(reviewId) + .answers(answers.stream().map(AnswerJpaEntity::toModel).toList()) + .activity(activity.toModel()) + .institute(institute.toModel()) + .history(history.toModel()) + .build(); + + } } diff --git a/src/main/java/com/gamsa/review/repository/AnswerJpaRepository.java b/src/main/java/com/gamsa/review/repository/AnswerJpaRepository.java new file mode 100644 index 0000000..d6ceb00 --- /dev/null +++ b/src/main/java/com/gamsa/review/repository/AnswerJpaRepository.java @@ -0,0 +1,9 @@ +package com.gamsa.review.repository; + +import com.gamsa.review.entity.AnswerJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AnswerJpaRepository extends JpaRepository { + +} + diff --git a/src/main/java/com/gamsa/review/repository/QuestionJpaRepository.java b/src/main/java/com/gamsa/review/repository/QuestionJpaRepository.java index 761400d..b4ed04a 100644 --- a/src/main/java/com/gamsa/review/repository/QuestionJpaRepository.java +++ b/src/main/java/com/gamsa/review/repository/QuestionJpaRepository.java @@ -1,8 +1,12 @@ package com.gamsa.review.repository; +import com.gamsa.review.domain.Answer; import com.gamsa.review.entity.QuestionJpaEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository public interface QuestionJpaRepository extends JpaRepository { + public void save(Answer answer); } diff --git a/src/main/java/com/gamsa/review/repository/ReviewJpaRepository.java b/src/main/java/com/gamsa/review/repository/ReviewJpaRepository.java new file mode 100644 index 0000000..a3b0bb2 --- /dev/null +++ b/src/main/java/com/gamsa/review/repository/ReviewJpaRepository.java @@ -0,0 +1,11 @@ +package com.gamsa.review.repository; + +import com.gamsa.review.entity.ReviewJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ReviewJpaRepository extends JpaRepository { + List findByInstituteInstituteIdAndAnswersQuestionQuestionId(Long instituteId, Long questionId); + +} diff --git a/src/main/java/com/gamsa/review/repository/ReviewRepository.java b/src/main/java/com/gamsa/review/repository/ReviewRepository.java index dfe55c2..f3e2c88 100644 --- a/src/main/java/com/gamsa/review/repository/ReviewRepository.java +++ b/src/main/java/com/gamsa/review/repository/ReviewRepository.java @@ -2,7 +2,11 @@ import com.gamsa.review.domain.Review; +import java.util.List; + public interface ReviewRepository { void save(Review review); + + List findReviews(Long instituteId, Long questionId); } diff --git a/src/main/java/com/gamsa/review/repository/ReviewRepositoryImpl.java b/src/main/java/com/gamsa/review/repository/ReviewRepositoryImpl.java new file mode 100644 index 0000000..734552e --- /dev/null +++ b/src/main/java/com/gamsa/review/repository/ReviewRepositoryImpl.java @@ -0,0 +1,26 @@ +package com.gamsa.review.repository; + +import com.gamsa.review.domain.Review; +import com.gamsa.review.entity.ReviewJpaEntity; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@RequiredArgsConstructor +@Repository +public class ReviewRepositoryImpl implements ReviewRepository { + private final ReviewJpaRepository reviewJpaRepository; + + @Override + public void save(Review review) { + reviewJpaRepository.save(ReviewJpaEntity.from(review)); + } + + @Override + public List findReviews(Long instituteId, Long questionId) { + return reviewJpaRepository.findByInstituteInstituteIdAndAnswersQuestionQuestionId(instituteId, questionId).stream().map(ReviewJpaEntity::toModel).toList(); + } + + +} diff --git a/src/main/java/com/gamsa/review/service/ReviewService.java b/src/main/java/com/gamsa/review/service/ReviewService.java index 34a50c1..c8e6501 100644 --- a/src/main/java/com/gamsa/review/service/ReviewService.java +++ b/src/main/java/com/gamsa/review/service/ReviewService.java @@ -12,12 +12,15 @@ import com.gamsa.review.repository.QuestionRepository; import com.gamsa.review.repository.ReviewRepository; import com.gamsa.user.repository.UserRepository; -import java.util.List; -import java.util.NoSuchElementException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.OptionalDouble; + @RequiredArgsConstructor @Service public class ReviewService { @@ -32,10 +35,10 @@ public class ReviewService { public void saveReview(Long userId, ReviewSaveRequest saveRequest) { userRepository.findById(userId) - .orElseThrow((() -> new NoSuchElementException("존재하지 않는 계정"))); + .orElseThrow((() -> new NoSuchElementException("존재하지 않는 계정"))); History history = historyRepository.findById(saveRequest.getHistoryId()) - .orElseThrow(() -> new NoSuchElementException("존재하지 않는 기록")); + .orElseThrow(() -> new NoSuchElementException("존재하지 않는 기록")); Avatar avatar = history.getAvatar(); Activity activity = history.getActivity(); @@ -46,26 +49,41 @@ public void saveReview(Long userId, ReviewSaveRequest saveRequest) { // save review Review review = Review.builder() - .avatar(avatar) - .history(history) - .institute(activity.getInstitute()) - .build(); + .avatar(avatar) + .history(history) + .institute(activity.getInstitute()) + .build(); reviewRepository.save(review); // save answers List answers = saveRequest.getAnswers().stream() - .map(answer -> { - Question question = questionRepository.findById(answer.getQuestionId()) - .orElseThrow(() -> new NoSuchElementException("존재하지 않는 질문")); + .map(answer -> { + Question question = questionRepository.findById(answer.getQuestionId()) + .orElseThrow(() -> new NoSuchElementException("존재하지 않는 질문")); - return Answer.builder() - .question(question) - .score(answer.getScore()) - .build(); - }) - .toList(); + return Answer.builder() + .question(question) + .score(answer.getScore()) + .build(); + }) + .toList(); answers.forEach(answerRepository::save); } + + public BigDecimal getAverageScore(long instituteId, long questionId) { + OptionalDouble averageScore = reviewRepository.findReviews(instituteId, questionId) + .stream() + .flatMap(review -> review.getAnswers().stream()) + .filter(answer -> answer.getQuestion().getQuestionId() == questionId) + .mapToInt(Answer::getScore) + .average(); + + if (averageScore.isPresent()) { + return BigDecimal.valueOf(averageScore.getAsDouble()); + } else { + return BigDecimal.ZERO; + } + } } diff --git a/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java b/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java index 9344843..bd7ab2d 100644 --- a/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java +++ b/src/test/java/com/gamsa/history/service/HitstoryServiceTest.java @@ -1,37 +1,51 @@ package com.gamsa.history.service; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - import com.gamsa.activity.stub.StubExistsActivityRepository; import com.gamsa.avatar.stub.StubExistsAvatarRepository; import com.gamsa.history.dto.HistorySaveRequest; import com.gamsa.history.stub.StubHistoryRepository; +import com.gamsa.review.service.QuestionService; +import com.gamsa.review.service.ReviewService; +import com.gamsa.review.stub.StubAnswerRepository; +import com.gamsa.review.stub.StubQuestionRepository; +import com.gamsa.review.stub.StubReviewRepository; +import com.gamsa.user.stub.StubExistsUserRepository; import org.junit.jupiter.api.Test; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class HitstoryServiceTest { HistorySaveRequest historySaveRequest = HistorySaveRequest.builder() .actId(1L) .build(); + ReviewService reviewService = new ReviewService( + new StubExistsUserRepository(), + new StubQuestionRepository(), + new StubReviewRepository(), + new StubAnswerRepository(), + new StubHistoryRepository() + ); + + QuestionService questionService = new QuestionService( + new StubQuestionRepository() + ); + + HistoryService historyService = new HistoryService(new StubHistoryRepository(), + new StubExistsAvatarRepository(), new StubExistsActivityRepository(), questionService, reviewService); + @Test void 새로운_기록_저장() { - //given - HistoryService historyService = new HistoryService(new StubHistoryRepository(), - new StubExistsAvatarRepository(), new StubExistsActivityRepository()); - //when & then assertDoesNotThrow(() -> historyService.save(historySaveRequest, 1L)); } @Test void 유저_기록_찾기() { - //given - HistoryService historyService = new HistoryService(new StubHistoryRepository(), - new StubExistsAvatarRepository(), new StubExistsActivityRepository()); //when & then Pageable pageable = PageRequest.of(0, 10); @@ -40,20 +54,12 @@ public class HitstoryServiceTest { @Test void 기록_삭제() { - //given - HistoryService historyService = new HistoryService(new StubHistoryRepository(), - new StubExistsAvatarRepository(), new StubExistsActivityRepository()); - //when & then assertDoesNotThrow(() -> historyService.delete(1L)); } @Test void 리뷰_상태_업데이트() { - //given - HistoryService historyService = new HistoryService(new StubHistoryRepository(), - new StubExistsAvatarRepository(), new StubExistsActivityRepository()); - //when & then assertDoesNotThrow(() -> historyService.updateReviewed(1L, true)); } diff --git a/src/test/java/com/gamsa/review/stub/StubAnswerRepository.java b/src/test/java/com/gamsa/review/stub/StubAnswerRepository.java new file mode 100644 index 0000000..242863d --- /dev/null +++ b/src/test/java/com/gamsa/review/stub/StubAnswerRepository.java @@ -0,0 +1,12 @@ +package com.gamsa.review.stub; + +import com.gamsa.review.domain.Answer; +import com.gamsa.review.repository.AnswerRepository; + +public class StubAnswerRepository implements AnswerRepository { + + @Override + public void save(Answer answer) { + // do nothing + } +} diff --git a/src/test/java/com/gamsa/review/stub/StubQuestionRepository.java b/src/test/java/com/gamsa/review/stub/StubQuestionRepository.java new file mode 100644 index 0000000..dc1489b --- /dev/null +++ b/src/test/java/com/gamsa/review/stub/StubQuestionRepository.java @@ -0,0 +1,34 @@ +package com.gamsa.review.stub; + +import com.gamsa.review.domain.Question; +import com.gamsa.review.repository.QuestionRepository; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class StubQuestionRepository implements QuestionRepository { + + Question question1 = Question.builder() + .questionId(1) + .content("질문 테스트1") + .build(); + + Question question2 = Question.builder() + .questionId(2) + .content("질문 테스트2") + .build(); + + List questions = Arrays.asList(question1, question2); + + @Override + public List findAllQuestion() { + return questions; + } + + @Override + public Optional findById(Integer id) { + return Optional.of(question1); + } + +} diff --git a/src/test/java/com/gamsa/review/stub/StubReviewRepository.java b/src/test/java/com/gamsa/review/stub/StubReviewRepository.java new file mode 100644 index 0000000..464a340 --- /dev/null +++ b/src/test/java/com/gamsa/review/stub/StubReviewRepository.java @@ -0,0 +1,108 @@ +package com.gamsa.review.stub; + +import com.gamsa.activity.domain.Activity; +import com.gamsa.activity.domain.District; +import com.gamsa.activity.domain.Institute; +import com.gamsa.avatar.constant.AgeRange; +import com.gamsa.avatar.constant.Experienced; +import com.gamsa.avatar.domain.Avatar; +import com.gamsa.history.constant.ActivityStatus; +import com.gamsa.history.domain.History; +import com.gamsa.review.domain.Answer; +import com.gamsa.review.domain.Question; +import com.gamsa.review.domain.Review; +import com.gamsa.review.repository.ReviewRepository; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +public class StubReviewRepository implements ReviewRepository { + + Question question = Question.builder() + .questionId(1) + .content("질문 테스트1") + .build(); + + Answer answer = Answer.builder() + .answerId(1L) + .question(question) + .score(0) + .build(); + + private final District district = District.builder() + .sidoCode(1234) + .sidoGunguCode(8888) + .sidoName("서울특별시") + .gunguName("강남구") + .sido(false) + .build(); + + private final Institute institute = Institute.builder() + .instituteId(1L) + .name("도서관") + .location("서울시") + .latitude(new BigDecimal("123456789.12341234")) + .longitude(new BigDecimal("987654321.43214321")) + .phone("010xxxxxxxx") + .build(); + + private final Activity activity = Activity.builder() + .actId(1L) + .actTitle("어린이놀이안전관리 및 놀잇감 청결유지 및 정리") + .actLocation("아이사랑꿈터 서구 5호점") + .description("봉사 내용") + .noticeStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .noticeEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartDate(LocalDateTime.of(2024, 9, 10, 0, 0)) + .actEndDate(LocalDateTime.of(2024, 12, 7, 0, 0)) + .actStartTime(13) + .actEndTime(18) + .recruitTotalNum(1) + .adultPossible(true) + .teenPossible(false) + .groupPossible(false) + .actWeek(0111110) + .actManager("윤순영") + .actPhone("032-577-3026") + .url("https://...") + .institute(institute) + .sidoGungu(district) + .build(); + + Avatar avatar = Avatar.builder() + .avatarId(1L) + .avatarLevel(1L) + .avatarExp(1L) + .nickname("닉네임") + .ageRange(AgeRange.ADULT) + .experienced(Experienced.NOVICE) + .build(); + + History history = History.builder() + .historyId(1L) + .activity(activity) + .avatar(avatar) + .activityStatus(ActivityStatus.APPLIED) + .reviewed(false) + .build(); + + Review review1 = Review.builder() + .reviewId(1L) + .answers(List.of(answer)) + .activity(activity) + .institute(institute) + .history(history) + .build(); + + @Override + public void save(Review review) { + // do nothing + } + + @Override + public List findReviews(Long instituteID, Long questionId) { + return List.of(review1); + + } +}