diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/Answer.java b/backend/src/main/java/reviewme/review/domain/Answer.java similarity index 95% rename from backend/src/main/java/reviewme/review/domain/abstraction/Answer.java rename to backend/src/main/java/reviewme/review/domain/Answer.java index 1e6b86833..e50701e03 100644 --- a/backend/src/main/java/reviewme/review/domain/abstraction/Answer.java +++ b/backend/src/main/java/reviewme/review/domain/Answer.java @@ -1,4 +1,4 @@ -package reviewme.review.domain.abstraction; +package reviewme.review.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/reviewme/review/domain/CheckBoxAnswerSelectedOption.java b/backend/src/main/java/reviewme/review/domain/CheckBoxAnswerSelectedOption.java deleted file mode 100644 index 8a19dc049..000000000 --- a/backend/src/main/java/reviewme/review/domain/CheckBoxAnswerSelectedOption.java +++ /dev/null @@ -1,32 +0,0 @@ -package reviewme.review.domain; - -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.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table(name = "checkbox_answer_selected_option") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -public class CheckBoxAnswerSelectedOption { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "checkbox_answer_id", nullable = false, insertable = false, updatable = false) - private long checkboxAnswerId; - - @Column(name = "selected_option_id", nullable = false) - private long selectedOptionId; - - public CheckBoxAnswerSelectedOption(long selectedOptionId) { - this.selectedOptionId = selectedOptionId; - } -} diff --git a/backend/src/main/java/reviewme/review/domain/CheckboxAnswer.java b/backend/src/main/java/reviewme/review/domain/CheckboxAnswer.java index 408b24076..6171b9fc5 100644 --- a/backend/src/main/java/reviewme/review/domain/CheckboxAnswer.java +++ b/backend/src/main/java/reviewme/review/domain/CheckboxAnswer.java @@ -1,12 +1,8 @@ package reviewme.review.domain; import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; @@ -18,31 +14,21 @@ import reviewme.review.domain.exception.QuestionNotAnsweredException; @Entity -@Table(name = "checkbox_answer") +@Table(name = "new_checkbox_answer") @NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(of = "id") +@EqualsAndHashCode(callSuper = true) @Getter -public class CheckboxAnswer { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "review_id", nullable = false, insertable = false, updatable = false) - private long reviewId; - - @Column(name = "question_id", nullable = false) - private long questionId; +public class CheckboxAnswer extends Answer { @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "checkbox_answer_id", nullable = false, updatable = false) - private List selectedOptionIds; + private List selectedOptionIds; public CheckboxAnswer(long questionId, List selectedOptionIds) { validateSelectedOptionIds(questionId, selectedOptionIds); this.questionId = questionId; this.selectedOptionIds = selectedOptionIds.stream() - .map(CheckBoxAnswerSelectedOption::new) + .map(CheckboxAnswerSelectedOption::new) .toList(); } diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerSelectedOption.java b/backend/src/main/java/reviewme/review/domain/CheckboxAnswerSelectedOption.java similarity index 84% rename from backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerSelectedOption.java rename to backend/src/main/java/reviewme/review/domain/CheckboxAnswerSelectedOption.java index 4fb64f01a..825121a8a 100644 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerSelectedOption.java +++ b/backend/src/main/java/reviewme/review/domain/CheckboxAnswerSelectedOption.java @@ -1,4 +1,4 @@ -package reviewme.review.domain.abstraction; +package reviewme.review.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -16,7 +16,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @EqualsAndHashCode(of = "id") @Getter -public class NewCheckboxAnswerSelectedOption { +public class CheckboxAnswerSelectedOption { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -28,7 +28,7 @@ public class NewCheckboxAnswerSelectedOption { @Column(name = "selected_option_id", nullable = false) private long selectedOptionId; - public NewCheckboxAnswerSelectedOption(long selectedOptionId) { + public CheckboxAnswerSelectedOption(long selectedOptionId) { this.selectedOptionId = selectedOptionId; } } diff --git a/backend/src/main/java/reviewme/review/domain/Review.java b/backend/src/main/java/reviewme/review/domain/Review.java index 899a41391..aa540e57b 100644 --- a/backend/src/main/java/reviewme/review/domain/Review.java +++ b/backend/src/main/java/reviewme/review/domain/Review.java @@ -15,14 +15,13 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @Entity -@Table(name = "review") +@Table(name = "new_review") @NoArgsConstructor(access = AccessLevel.PROTECTED) @EqualsAndHashCode(of = "id") @Getter @@ -40,35 +39,21 @@ public class Review { @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) @JoinColumn(name = "review_id", nullable = false, updatable = false) - private List textAnswers; - - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) - @JoinColumn(name = "review_id", nullable = false, updatable = false) - private List checkboxAnswers; + private List answers; @Column(name = "created_at", nullable = false) private LocalDateTime createdAt; - public Review(long templateId, long reviewGroupId, - List textAnswers, List checkboxAnswers) { + public Review(long templateId, long reviewGroupId, List answers) { this.templateId = templateId; this.reviewGroupId = reviewGroupId; - this.textAnswers = textAnswers; - this.checkboxAnswers = checkboxAnswers; + this.answers = answers; this.createdAt = LocalDateTime.now(); } public Set getAnsweredQuestionIds() { - return Stream.concat( - textAnswers.stream().map(TextAnswer::getQuestionId), - checkboxAnswers.stream().map(CheckboxAnswer::getQuestionId) - ).collect(Collectors.toSet()); - } - - public Set getAllCheckBoxOptionIds() { - return checkboxAnswers.stream() - .flatMap(answer -> answer.getSelectedOptionIds().stream()) - .map(CheckBoxAnswerSelectedOption::getSelectedOptionId) + return answers.stream() + .map(Answer::getQuestionId) .collect(Collectors.toSet()); } @@ -76,6 +61,13 @@ public boolean hasAnsweredQuestion(long questionId) { return getAnsweredQuestionIds().contains(questionId); } + public List getAnswersByType(Class clazz) { + return answers.stream() + .filter(clazz::isInstance) + .map(clazz::cast) + .toList(); + } + public LocalDate getCreatedDate() { return createdAt.toLocalDate(); } diff --git a/backend/src/main/java/reviewme/review/domain/TextAnswer.java b/backend/src/main/java/reviewme/review/domain/TextAnswer.java index a7ba8e5ff..994cb949b 100644 --- a/backend/src/main/java/reviewme/review/domain/TextAnswer.java +++ b/backend/src/main/java/reviewme/review/domain/TextAnswer.java @@ -2,9 +2,6 @@ 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.EqualsAndHashCode; @@ -13,18 +10,11 @@ import reviewme.review.domain.exception.QuestionNotAnsweredException; @Entity -@Table(name = "text_answer") +@Table(name = "new_text_answer") @NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(of = "id") +@EqualsAndHashCode(callSuper = true) @Getter -public class TextAnswer { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "question_id", nullable = false) - private long questionId; +public class TextAnswer extends Answer { @Column(name = "content", nullable = false, length = 5000) private String content; diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswer.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswer.java deleted file mode 100644 index af175ff56..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswer.java +++ /dev/null @@ -1,40 +0,0 @@ -package reviewme.review.domain.abstraction; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import java.util.List; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import reviewme.review.domain.exception.QuestionNotAnsweredException; - -@Entity -@Table(name = "new_checkbox_answer") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(callSuper = true) -@Getter -public class NewCheckboxAnswer extends Answer { - - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) - @JoinColumn(name = "checkbox_answer_id", nullable = false, updatable = false) - private List selectedOptionIds; - - public NewCheckboxAnswer(long questionId, List selectedOptionIds) { - validateSelectedOptionIds(questionId, selectedOptionIds); - this.questionId = questionId; - this.selectedOptionIds = selectedOptionIds.stream() - .map(NewCheckboxAnswerSelectedOption::new) - .toList(); - } - - private void validateSelectedOptionIds(long questionId, List selectedOptionIds) { - if (selectedOptionIds == null || selectedOptionIds.isEmpty()) { - throw new QuestionNotAnsweredException(questionId); - } - } -} diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerRepository.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerRepository.java deleted file mode 100644 index 0387f18d2..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewCheckboxAnswerRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package reviewme.review.domain.abstraction; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface NewCheckboxAnswerRepository extends JpaRepository { -} diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewReview.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewReview.java deleted file mode 100644 index 281852795..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewReview.java +++ /dev/null @@ -1,74 +0,0 @@ -package reviewme.review.domain.abstraction; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table(name = "new_review") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(of = "id") -@Getter -public class NewReview { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "template_id", nullable = false) - private long templateId; - - @Column(name = "review_group_id", nullable = false) - private long reviewGroupId; - - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) - @JoinColumn(name = "review_id", nullable = false, updatable = false) - private List answers; - - @Column(name = "created_at", nullable = false) - private LocalDateTime createdAt; - - public NewReview(long templateId, long reviewGroupId, List answers) { - this.templateId = templateId; - this.reviewGroupId = reviewGroupId; - this.answers = answers; - this.createdAt = LocalDateTime.now(); - } - - public Set getAnsweredQuestionIds() { - return answers.stream() - .map(Answer::getQuestionId) - .collect(Collectors.toSet()); - } - - public boolean hasAnsweredQuestion(long questionId) { - return getAnsweredQuestionIds().contains(questionId); - } - - public List getAnswersByType(Class clazz) { - return answers.stream() - .filter(clazz::isInstance) - .map(clazz::cast) - .toList(); - } - - public LocalDate getCreatedDate() { - return createdAt.toLocalDate(); - } -} diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewReviewRepository.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewReviewRepository.java deleted file mode 100644 index 8f933a7af..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewReviewRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package reviewme.review.domain.abstraction; - -import java.time.LocalDate; -import java.util.List; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface NewReviewRepository extends JpaRepository { - - @Query(value = """ - SELECT r.* FROM new_review r - WHERE r.review_group_id = :reviewGroupId - ORDER BY r.created_at DESC - """, nativeQuery = true) - List findAllByGroupId(long reviewGroupId); - - @Query(value = """ - SELECT r.* FROM new_review r - WHERE r.review_group_id = :reviewGroupId - AND (:lastReviewId IS NULL OR r.id < :lastReviewId) - ORDER BY r.created_at DESC, r.id DESC - LIMIT :limit - """, nativeQuery = true) - List findByReviewGroupIdWithLimit(long reviewGroupId, Long lastReviewId, int limit); - - Optional findByIdAndReviewGroupId(long reviewId, long reviewGroupId); - - @Query(value = """ - SELECT COUNT(r.id) FROM new_review r - WHERE r.review_group_id = :reviewGroupId - AND r.id < :reviewId - AND CAST(r.created_at AS DATE) <= :createdDate - """, nativeQuery = true) - Long existsOlderReviewInGroupInLong(long reviewGroupId, long reviewId, LocalDate createdDate); - - default boolean existsOlderReviewInGroup(long reviewGroupId, long reviewId, LocalDate createdDate) { - return existsOlderReviewInGroupInLong(reviewGroupId, reviewId, createdDate) > 0; - } -} diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswer.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswer.java deleted file mode 100644 index 1f0b494be..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswer.java +++ /dev/null @@ -1,33 +0,0 @@ -package reviewme.review.domain.abstraction; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import reviewme.review.domain.exception.QuestionNotAnsweredException; - -@Entity -@Table(name = "new_text_answer") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(callSuper = true) -@Getter -public class NewTextAnswer extends Answer { - - @Column(name = "content", nullable = false, length = 5000) - private String content; - - public NewTextAnswer(long questionId, String content) { - validateContent(questionId, content); - this.questionId = questionId; - this.content = content; - } - - private void validateContent(long questionId, String content) { - if (content == null || content.isEmpty()) { - throw new QuestionNotAnsweredException(questionId); - } - } -} diff --git a/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswerRepository.java b/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswerRepository.java deleted file mode 100644 index f4257101a..000000000 --- a/backend/src/main/java/reviewme/review/domain/abstraction/NewTextAnswerRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package reviewme.review.domain.abstraction; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface NewTextAnswerRepository extends JpaRepository { -} diff --git a/backend/src/main/java/reviewme/review/repository/CheckboxAnswerRepository.java b/backend/src/main/java/reviewme/review/repository/CheckboxAnswerRepository.java index 30ce44014..f98fcc110 100644 --- a/backend/src/main/java/reviewme/review/repository/CheckboxAnswerRepository.java +++ b/backend/src/main/java/reviewme/review/repository/CheckboxAnswerRepository.java @@ -1,9 +1,7 @@ package reviewme.review.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; import reviewme.review.domain.CheckboxAnswer; -@Repository public interface CheckboxAnswerRepository extends JpaRepository { } diff --git a/backend/src/main/java/reviewme/review/repository/ReviewRepository.java b/backend/src/main/java/reviewme/review/repository/ReviewRepository.java index 5b175e081..26aacb9bd 100644 --- a/backend/src/main/java/reviewme/review/repository/ReviewRepository.java +++ b/backend/src/main/java/reviewme/review/repository/ReviewRepository.java @@ -5,21 +5,19 @@ import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; import reviewme.review.domain.Review; -@Repository public interface ReviewRepository extends JpaRepository { @Query(value = """ - SELECT r.* FROM review r + SELECT r.* FROM new_review r WHERE r.review_group_id = :reviewGroupId - ORDER BY r.created_at DESC + ORDER BY r.created_at DESC """, nativeQuery = true) List findAllByGroupId(long reviewGroupId); @Query(value = """ - SELECT r.* FROM review r + SELECT r.* FROM new_review r WHERE r.review_group_id = :reviewGroupId AND (:lastReviewId IS NULL OR r.id < :lastReviewId) ORDER BY r.created_at DESC, r.id DESC @@ -30,7 +28,7 @@ public interface ReviewRepository extends JpaRepository { Optional findByIdAndReviewGroupId(long reviewId, long reviewGroupId); @Query(value = """ - SELECT COUNT(r.id) FROM review r + SELECT COUNT(r.id) FROM new_review r WHERE r.review_group_id = :reviewGroupId AND r.id < :reviewId AND CAST(r.created_at AS DATE) <= :createdDate diff --git a/backend/src/main/java/reviewme/review/repository/TextAnswerRepository.java b/backend/src/main/java/reviewme/review/repository/TextAnswerRepository.java index 0c3465399..8ad388fe8 100644 --- a/backend/src/main/java/reviewme/review/repository/TextAnswerRepository.java +++ b/backend/src/main/java/reviewme/review/repository/TextAnswerRepository.java @@ -1,9 +1,7 @@ package reviewme.review.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; import reviewme.review.domain.TextAnswer; -@Repository public interface TextAnswerRepository extends JpaRepository { } diff --git a/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java b/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java index 64cc334ad..966eaa602 100644 --- a/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java +++ b/backend/src/main/java/reviewme/review/service/ReviewRegisterService.java @@ -6,11 +6,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import reviewme.review.domain.Review; -import reviewme.review.domain.abstraction.NewReview; -import reviewme.review.domain.abstraction.NewReviewRepository; import reviewme.review.repository.ReviewRepository; -import reviewme.review.service.abstraction.mapper.NewReviewMapper; -import reviewme.review.service.abstraction.validator.NewReviewValidator; import reviewme.review.service.dto.request.ReviewRegisterRequest; import reviewme.review.service.mapper.ReviewMapper; import reviewme.review.service.validator.ReviewValidator; @@ -20,27 +16,17 @@ public class ReviewRegisterService { private static final Logger log = LoggerFactory.getLogger(ReviewRegisterService.class); + private final ReviewMapper reviewMapper; private final ReviewValidator reviewValidator; - private final ReviewRepository reviewRepository; - // 리뷰 추상화, 같은 Transactional에 넣어 처리 - private final NewReviewMapper newReviewMapper; - private final NewReviewValidator newReviewValidator; - private final NewReviewRepository newReviewRepository; - @Transactional public long registerReview(ReviewRegisterRequest request) { Review review = reviewMapper.mapToReview(request); reviewValidator.validate(review); Review registeredReview = reviewRepository.save(review); - // 새로운 테이블에 중복해서 저장 - NewReview newReview = newReviewMapper.mapToReview(request); - newReviewValidator.validate(newReview); - newReviewRepository.save(newReview); - return registeredReview.getId(); } } diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewAnswerMapper.java b/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewAnswerMapper.java deleted file mode 100644 index c8a48675f..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewAnswerMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package reviewme.review.service.abstraction.mapper; - -import reviewme.question.domain.QuestionType; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.service.dto.request.ReviewAnswerRequest; - -public interface NewAnswerMapper { - - boolean supports(QuestionType questionType); - - Answer mapToAnswer(ReviewAnswerRequest answerRequest); -} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewReviewMapper.java b/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewReviewMapper.java deleted file mode 100644 index f29e3e576..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewReviewMapper.java +++ /dev/null @@ -1,77 +0,0 @@ -package reviewme.review.service.abstraction.mapper; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.domain.abstraction.NewReview; -import reviewme.review.service.dto.request.ReviewAnswerRequest; -import reviewme.review.service.dto.request.ReviewRegisterRequest; -import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException; -import reviewme.reviewgroup.domain.ReviewGroup; -import reviewme.reviewgroup.repository.ReviewGroupRepository; -import reviewme.template.domain.Template; -import reviewme.template.repository.TemplateRepository; -import reviewme.template.service.exception.TemplateNotFoundByReviewGroupException; - -@Component -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class NewReviewMapper { - - private final AnswerMapperFactory answerMapperFactory; - private final ReviewGroupRepository reviewGroupRepository; - private final QuestionRepository questionRepository; - private final TemplateRepository templateRepository; - - public NewReview mapToReview(ReviewRegisterRequest request) { - ReviewGroup reviewGroup = reviewGroupRepository.findByReviewRequestCode(request.reviewRequestCode()) - .orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(request.reviewRequestCode())); - Template template = templateRepository.findById(reviewGroup.getTemplateId()) - .orElseThrow(() -> new TemplateNotFoundByReviewGroupException( - reviewGroup.getId(), reviewGroup.getTemplateId() - )); - - List answers = getAnswersByQuestionType(request); - return new NewReview(template.getId(), reviewGroup.getId(), answers); - } - - private List getAnswersByQuestionType(ReviewRegisterRequest request) { - List questionIds = request.answers() - .stream() - .map(ReviewAnswerRequest::questionId) - .toList(); - - Map questionMap = questionRepository.findAllById(questionIds) - .stream() - .collect(Collectors.toMap(Question::getId, Function.identity())); - - return request.answers() - .stream() - .map(answerRequest -> mapRequestToAnswer(questionMap, answerRequest)) - .filter(Objects::nonNull) - .toList(); - } - - private Answer mapRequestToAnswer(Map questions, ReviewAnswerRequest answerRequest) { - Question question = questions.get(answerRequest.questionId()); - - // TODO: 아래 코드를 삭제해야 한다 - if (question.isSelectable() && answerRequest.selectedOptionIds() != null && answerRequest.selectedOptionIds().isEmpty()) { - return null; - } - if (!question.isSelectable() && answerRequest.text() != null && answerRequest.text().isEmpty()) { - return null; - } - // END - - NewAnswerMapper answerMapper = answerMapperFactory.getAnswerMapper(question.getQuestionType()); - return answerMapper.mapToAnswer(answerRequest); - } -} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewAnswerValidator.java b/backend/src/main/java/reviewme/review/service/abstraction/validator/NewAnswerValidator.java deleted file mode 100644 index 05e36e1e7..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewAnswerValidator.java +++ /dev/null @@ -1,10 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import reviewme.review.domain.abstraction.Answer; - -public interface NewAnswerValidator { - - boolean supports(Class answerClass); - - void validate(Answer answer); -} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidator.java b/backend/src/main/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidator.java deleted file mode 100644 index 6afdc754b..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidator.java +++ /dev/null @@ -1,82 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import java.util.HashSet; -import java.util.List; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.domain.abstraction.NewCheckboxAnswerSelectedOption; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.service.exception.CheckBoxAnswerIncludedNotProvidedOptionItemException; -import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; -import reviewme.review.service.exception.SelectedOptionItemCountOutOfRangeException; -import reviewme.review.service.exception.SubmittedQuestionNotFoundException; - -@Component -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class NewCheckboxAnswerValidator implements NewAnswerValidator { - - private final QuestionRepository questionRepository; - private final OptionGroupRepository optionGroupRepository; - private final OptionItemRepository optionItemRepository; - - @Override - public boolean supports(Class answerClass) { - return NewCheckboxAnswer.class.isAssignableFrom(answerClass); - } - - @Override - public void validate(Answer answer) { - NewCheckboxAnswer checkboxAnswer = (NewCheckboxAnswer) answer; - Question question = questionRepository.findById(checkboxAnswer.getQuestionId()) - .orElseThrow(() -> new SubmittedQuestionNotFoundException(checkboxAnswer.getQuestionId())); - - OptionGroup optionGroup = optionGroupRepository.findByQuestionId(question.getId()) - .orElseThrow(() -> new OptionGroupNotFoundByQuestionIdException(question.getId())); - - validateOnlyIncludingProvidedOptionItem(checkboxAnswer, optionGroup); - validateCheckedOptionItemCount(checkboxAnswer, optionGroup); - } - - private void validateOnlyIncludingProvidedOptionItem(NewCheckboxAnswer checkboxAnswer, OptionGroup optionGroup) { - List providedOptionItemIds = optionItemRepository.findAllByOptionGroupId(optionGroup.getId()) - .stream() - .map(OptionItem::getId) - .toList(); - List answeredOptionItemIds = extractAnsweredOptionItemIds(checkboxAnswer); - - if (!new HashSet<>(providedOptionItemIds).containsAll(answeredOptionItemIds)) { - throw new CheckBoxAnswerIncludedNotProvidedOptionItemException( - checkboxAnswer.getQuestionId(), providedOptionItemIds, answeredOptionItemIds - ); - } - } - - private void validateCheckedOptionItemCount(NewCheckboxAnswer checkboxAnswer, OptionGroup optionGroup) { - int answeredOptionItemCount = extractAnsweredOptionItemIds(checkboxAnswer).size(); - - if (answeredOptionItemCount < optionGroup.getMinSelectionCount() - || answeredOptionItemCount > optionGroup.getMaxSelectionCount()) { - throw new SelectedOptionItemCountOutOfRangeException( - checkboxAnswer.getQuestionId(), - answeredOptionItemCount, - optionGroup.getMinSelectionCount(), - optionGroup.getMaxSelectionCount() - ); - } - } - - private List extractAnsweredOptionItemIds(NewCheckboxAnswer checkboxAnswer) { - return checkboxAnswer.getSelectedOptionIds() - .stream() - .map(NewCheckboxAnswerSelectedOption::getSelectedOptionId) - .toList(); - } -} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewReviewValidator.java b/backend/src/main/java/reviewme/review/service/abstraction/validator/NewReviewValidator.java deleted file mode 100644 index cad44d493..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewReviewValidator.java +++ /dev/null @@ -1,82 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.domain.abstraction.NewCheckboxAnswerSelectedOption; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.domain.abstraction.NewReview; -import reviewme.review.service.exception.MissingRequiredQuestionException; -import reviewme.review.service.exception.SubmittedQuestionAndProvidedQuestionMismatchException; -import reviewme.template.domain.Section; -import reviewme.template.domain.SectionQuestion; -import reviewme.template.repository.SectionRepository; - -@Component -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class NewReviewValidator { - - private final AnswerValidatorFactory answerValidatorFactory; - - private final SectionRepository sectionRepository; - private final QuestionRepository questionRepository; - - public void validate(NewReview review) { - validateAnswer(review.getAnswers()); - validateAllAnswersContainedInTemplate(review); - validateAllRequiredQuestionsAnswered(review); - } - - private void validateAnswer(List answers) { - for (Answer answer : answers) { - NewAnswerValidator validator = answerValidatorFactory.getAnswerValidator(answer.getClass()); - validator.validate(answer); - } - } - - private void validateAllAnswersContainedInTemplate(NewReview review) { - Set providedQuestionIds = questionRepository.findAllQuestionIdByTemplateId(review.getTemplateId()); - Set reviewedQuestionIds = review.getAnsweredQuestionIds(); - if (!providedQuestionIds.containsAll(reviewedQuestionIds)) { - throw new SubmittedQuestionAndProvidedQuestionMismatchException(reviewedQuestionIds, providedQuestionIds); - } - } - - private void validateAllRequiredQuestionsAnswered(NewReview review) { - Set displayedQuestionIds = extractDisplayedQuestionIds(review); - Set requiredQuestionIds = questionRepository.findAllById(displayedQuestionIds) - .stream() - .filter(Question::isRequired) - .map(Question::getId) - .collect(Collectors.toSet()); - - Set reviewedQuestionIds = review.getAnsweredQuestionIds(); - if (!reviewedQuestionIds.containsAll(requiredQuestionIds)) { - List missingRequiredQuestionIds = new ArrayList<>(requiredQuestionIds); - missingRequiredQuestionIds.removeAll(reviewedQuestionIds); - throw new MissingRequiredQuestionException(missingRequiredQuestionIds); - } - } - - private Set extractDisplayedQuestionIds(NewReview review) { - Set selectedOptionIds = review.getAnswersByType(NewCheckboxAnswer.class) - .stream() - .flatMap(answer -> answer.getSelectedOptionIds().stream()) - .map(NewCheckboxAnswerSelectedOption::getSelectedOptionId) - .collect(Collectors.toSet()); - List
sections = sectionRepository.findAllByTemplateId(review.getTemplateId()); - - return sections.stream() - .filter(section -> section.isVisibleBySelectedOptionIds(selectedOptionIds)) - .flatMap(section -> section.getQuestionIds().stream()) - .map(SectionQuestion::getQuestionId) - .collect(Collectors.toSet()); - } -} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidator.java b/backend/src/main/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidator.java deleted file mode 100644 index 2cf49b42c..000000000 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidator.java +++ /dev/null @@ -1,48 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.domain.abstraction.NewTextAnswer; -import reviewme.review.service.exception.InvalidTextAnswerLengthException; -import reviewme.review.service.exception.SubmittedQuestionNotFoundException; - -@Component -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) -public class NewTextAnswerValidator implements NewAnswerValidator { - - private static final int ZERO_LENGTH = 0; - private static final int MIN_LENGTH = 20; - private static final int MAX_LENGTH = 1_000; - - private final QuestionRepository questionRepository; - - @Override - public boolean supports(Class answerClass) { - return NewTextAnswer.class.isAssignableFrom(answerClass); - } - - @Override - public void validate(Answer answer) { - NewTextAnswer textAnswer = (NewTextAnswer) answer; - Question question = questionRepository.findById(textAnswer.getQuestionId()) - .orElseThrow(() -> new SubmittedQuestionNotFoundException(textAnswer.getQuestionId())); - - validateLength(textAnswer, question); - } - - private void validateLength(NewTextAnswer textAnswer, Question question) { - int answerLength = textAnswer.getContent().length(); - - if (question.isRequired() && (answerLength < MIN_LENGTH || answerLength > MAX_LENGTH)) { - throw new InvalidTextAnswerLengthException(question.getId(), answerLength, MIN_LENGTH, MAX_LENGTH); - } - - if (!question.isRequired() && answerLength > MAX_LENGTH) { - throw new InvalidTextAnswerLengthException(question.getId(), answerLength, MAX_LENGTH); - } - } -} diff --git a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java index ae444da6d..7b3cbb631 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapper.java @@ -1,28 +1,12 @@ package reviewme.review.service.mapper; -import org.springframework.stereotype.Component; -import reviewme.review.domain.CheckboxAnswer; -import reviewme.review.domain.TextAnswer; +import reviewme.question.domain.QuestionType; +import reviewme.review.domain.Answer; import reviewme.review.service.dto.request.ReviewAnswerRequest; -import reviewme.review.service.exception.CheckBoxAnswerIncludedTextException; -import reviewme.review.service.exception.TextAnswerIncludedOptionItemException; -@Component -public class AnswerMapper { +public interface AnswerMapper { - public TextAnswer mapToTextAnswer(ReviewAnswerRequest answerRequest) { - if (answerRequest.selectedOptionIds() != null) { - throw new TextAnswerIncludedOptionItemException(answerRequest.questionId()); - } + boolean supports(QuestionType questionType); - return new TextAnswer(answerRequest.questionId(), answerRequest.text()); - } - - public CheckboxAnswer mapToCheckBoxAnswer(ReviewAnswerRequest answerRequest) { - if (answerRequest.text() != null) { - throw new CheckBoxAnswerIncludedTextException(answerRequest.questionId()); - } - - return new CheckboxAnswer(answerRequest.questionId(), answerRequest.selectedOptionIds()); - } + Answer mapToAnswer(ReviewAnswerRequest answerRequest); } diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactory.java b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java similarity index 72% rename from backend/src/main/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactory.java rename to backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java index f123d7988..6dc804547 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactory.java +++ b/backend/src/main/java/reviewme/review/service/mapper/AnswerMapperFactory.java @@ -1,4 +1,4 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import java.util.List; import lombok.RequiredArgsConstructor; @@ -9,9 +9,9 @@ @RequiredArgsConstructor public class AnswerMapperFactory { - private final List answerMappers; + private final List answerMappers; - public NewAnswerMapper getAnswerMapper(QuestionType questionType) { + public AnswerMapper getAnswerMapper(QuestionType questionType) { return answerMappers.stream() .filter(answerMapper -> answerMapper.supports(questionType)) .findFirst() diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java similarity index 60% rename from backend/src/main/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapper.java rename to backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java index 515573af5..3648e32f6 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/CheckboxAnswerMapper.java @@ -1,13 +1,13 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import org.springframework.stereotype.Component; import reviewme.question.domain.QuestionType; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; +import reviewme.review.domain.CheckboxAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.CheckBoxAnswerIncludedTextException; @Component -public class NewCheckboxAnswerMapper implements NewAnswerMapper { +public class CheckboxAnswerMapper implements AnswerMapper { @Override public boolean supports(QuestionType questionType) { @@ -15,10 +15,10 @@ public boolean supports(QuestionType questionType) { } @Override - public NewCheckboxAnswer mapToAnswer(ReviewAnswerRequest answerRequest) { + public CheckboxAnswer mapToAnswer(ReviewAnswerRequest answerRequest) { if (answerRequest.text() != null) { throw new CheckBoxAnswerIncludedTextException(answerRequest.questionId()); } - return new NewCheckboxAnswer(answerRequest.questionId(), answerRequest.selectedOptionIds()); + return new CheckboxAnswer(answerRequest.questionId(), answerRequest.selectedOptionIds()); } } diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java index b4ee1f9ac..7121d99b5 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewDetailMapper.java @@ -13,6 +13,8 @@ import reviewme.question.repository.OptionGroupRepository; import reviewme.question.repository.OptionItemRepository; import reviewme.question.repository.QuestionRepository; +import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; import reviewme.review.service.dto.response.detail.OptionGroupAnswerResponse; @@ -97,7 +99,11 @@ private QuestionAnswerResponse mapToCheckboxQuestionResponse(Review review, Map> optionItemsByOptionGroup) { OptionGroup optionGroup = optionGroupsByQuestion.get(question.getId()); List optionItems = optionItemsByOptionGroup.get(optionGroup.getId()); - Set selectedOptionIds = review.getAllCheckBoxOptionIds(); + Set selectedOptionIds = review.getAnswersByType(CheckboxAnswer.class) + .stream() + .flatMap(answer -> answer.getSelectedOptionIds().stream()) + .map(CheckboxAnswerSelectedOption::getSelectedOptionId) + .collect(Collectors.toSet()); List optionItemResponse = optionItems.stream() .filter(optionItem -> selectedOptionIds.contains(optionItem.getId())) @@ -123,7 +129,7 @@ private QuestionAnswerResponse mapToCheckboxQuestionResponse(Review review, private QuestionAnswerResponse mapToTextQuestionResponse(Review review, Question question) { - List textAnswers = review.getTextAnswers(); + List textAnswers = review.getAnswersByType(TextAnswer.class); TextAnswer textAnswer = textAnswers.stream() .filter(answer -> answer.getQuestionId() == question.getId()) .findFirst() diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java index 12eadf153..aa882802a 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewListMapper.java @@ -2,12 +2,16 @@ import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.question.domain.OptionItem; import reviewme.question.domain.OptionType; import reviewme.question.repository.OptionItemRepository; +import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.Review; +import reviewme.review.domain.TextAnswer; import reviewme.review.repository.ReviewRepository; import reviewme.review.service.dto.response.list.ReviewCategoryResponse; import reviewme.review.service.dto.response.list.ReviewListElementResponse; @@ -37,14 +41,18 @@ private ReviewListElementResponse mapToReviewListElementResponse(Review review, return new ReviewListElementResponse( review.getId(), review.getCreatedDate(), - reviewPreviewGenerator.generatePreview(review.getTextAnswers()), + reviewPreviewGenerator.generatePreview(review.getAnswersByType(TextAnswer.class)), categoryResponses ); } private List mapToCategoryOptionResponse(Review review, List categoryOptionItems) { - Set checkBoxOptionIds = review.getAllCheckBoxOptionIds(); + Set checkBoxOptionIds = review.getAnswersByType(CheckboxAnswer.class) + .stream() + .flatMap(answer -> answer.getSelectedOptionIds().stream()) + .map(CheckboxAnswerSelectedOption::getSelectedOptionId) + .collect(Collectors.toSet()); return categoryOptionItems.stream() .filter(optionItem -> checkBoxOptionIds.contains(optionItem.getId())) .map(optionItem -> new ReviewCategoryResponse(optionItem.getId(), optionItem.getContent())) diff --git a/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java b/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java index c5441fdf7..c94295f44 100644 --- a/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/ReviewMapper.java @@ -1,17 +1,17 @@ package reviewme.review.service.mapper; -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; +import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.question.domain.Question; -import reviewme.question.domain.QuestionType; import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.Answer; import reviewme.review.domain.Review; -import reviewme.review.domain.TextAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.dto.request.ReviewRegisterRequest; import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException; @@ -22,38 +22,27 @@ import reviewme.template.service.exception.TemplateNotFoundByReviewGroupException; @Component -@RequiredArgsConstructor +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewMapper { - private final AnswerMapper answerMapper; + private final AnswerMapperFactory answerMapperFactory; private final ReviewGroupRepository reviewGroupRepository; private final QuestionRepository questionRepository; private final TemplateRepository templateRepository; public Review mapToReview(ReviewRegisterRequest request) { - ReviewGroup reviewGroup = findReviewGroupByRequestCodeOrThrow(request.reviewRequestCode()); - Template template = findTemplateByReviewGroupOrThrow(reviewGroup); - - List textAnswers = new ArrayList<>(); - List checkboxAnswers = new ArrayList<>(); - addAnswersByQuestionType(request, textAnswers, checkboxAnswers); - - return new Review(template.getId(), reviewGroup.getId(), textAnswers, checkboxAnswers); - } - - private ReviewGroup findReviewGroupByRequestCodeOrThrow(String reviewRequestCode) { - return reviewGroupRepository.findByReviewRequestCode(reviewRequestCode) - .orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode)); - } - - private Template findTemplateByReviewGroupOrThrow(ReviewGroup reviewGroup) { - return templateRepository.findById(reviewGroup.getTemplateId()) + ReviewGroup reviewGroup = reviewGroupRepository.findByReviewRequestCode(request.reviewRequestCode()) + .orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(request.reviewRequestCode())); + Template template = templateRepository.findById(reviewGroup.getTemplateId()) .orElseThrow(() -> new TemplateNotFoundByReviewGroupException( - reviewGroup.getId(), reviewGroup.getTemplateId())); + reviewGroup.getId(), reviewGroup.getTemplateId() + )); + + List answers = getAnswersByQuestionType(request); + return new Review(template.getId(), reviewGroup.getId(), answers); } - private void addAnswersByQuestionType(ReviewRegisterRequest request, - List textAnswers, List checkboxAnswers) { + private List getAnswersByQuestionType(ReviewRegisterRequest request) { List questionIds = request.answers() .stream() .map(ReviewAnswerRequest::questionId) @@ -61,36 +50,28 @@ private void addAnswersByQuestionType(ReviewRegisterRequest request, Map questionMap = questionRepository.findAllById(questionIds) .stream() - .collect(Collectors.toMap(Question::getId, question -> question)); + .collect(Collectors.toMap(Question::getId, Function.identity())); - for (ReviewAnswerRequest answerRequest : request.answers()) { - Question question = questionMap.get(answerRequest.questionId()); + return request.answers() + .stream() + .map(answerRequest -> mapRequestToAnswer(questionMap, answerRequest)) + .filter(Objects::nonNull) + .toList(); + } - if (question.getQuestionType() == QuestionType.TEXT) { - addIfTextAnswerExists(answerRequest, question, textAnswers); - } + private Answer mapRequestToAnswer(Map questions, ReviewAnswerRequest answerRequest) { + Question question = questions.get(answerRequest.questionId()); - if (question.getQuestionType() == QuestionType.CHECKBOX) { - addIfCheckBoxAnswerExists(answerRequest, question, checkboxAnswers); - } + // TODO: 아래 코드를 삭제해야 한다 + if (question.isSelectable() && answerRequest.selectedOptionIds() != null && answerRequest.selectedOptionIds().isEmpty()) { + return null; } - } - - private void addIfTextAnswerExists(ReviewAnswerRequest answerRequest, - Question question, - List textAnswers) { - if (question.isRequired() || answerRequest.hasTextAnswer()) { - TextAnswer textAnswer = answerMapper.mapToTextAnswer(answerRequest); - textAnswers.add(textAnswer); + if (!question.isSelectable() && answerRequest.text() != null && answerRequest.text().isEmpty()) { + return null; } - } + // END - private void addIfCheckBoxAnswerExists(ReviewAnswerRequest answerRequest, - Question question, - List checkboxAnswers) { - if (question.isRequired() || answerRequest.hasCheckboxAnswer()) { - CheckboxAnswer checkboxAnswer = answerMapper.mapToCheckBoxAnswer(answerRequest); - checkboxAnswers.add(checkboxAnswer); - } + AnswerMapper answerMapper = answerMapperFactory.getAnswerMapper(question.getQuestionType()); + return answerMapper.mapToAnswer(answerRequest); } } diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapper.java b/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java similarity index 66% rename from backend/src/main/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapper.java rename to backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java index 4b018c989..afd47ac97 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapper.java +++ b/backend/src/main/java/reviewme/review/service/mapper/TextAnswerMapper.java @@ -1,13 +1,13 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import org.springframework.stereotype.Component; import reviewme.question.domain.QuestionType; -import reviewme.review.domain.abstraction.NewTextAnswer; +import reviewme.review.domain.TextAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.TextAnswerIncludedOptionItemException; @Component -public class NewTextAnswerMapper implements NewAnswerMapper { +public class TextAnswerMapper implements AnswerMapper { @Override public boolean supports(QuestionType questionType) { @@ -15,13 +15,13 @@ public boolean supports(QuestionType questionType) { } @Override - public NewTextAnswer mapToAnswer(ReviewAnswerRequest answerRequest) { + public TextAnswer mapToAnswer(ReviewAnswerRequest answerRequest) { if (!answerRequest.hasTextAnswer()) { return null; } if (answerRequest.selectedOptionIds() != null) { throw new TextAnswerIncludedOptionItemException(answerRequest.questionId()); } - return new NewTextAnswer(answerRequest.questionId(), answerRequest.text()); + return new TextAnswer(answerRequest.questionId(), answerRequest.text()); } } diff --git a/backend/src/main/java/reviewme/review/service/abstraction/mapper/UnsupportedQuestionTypeException.java b/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java similarity index 90% rename from backend/src/main/java/reviewme/review/service/abstraction/mapper/UnsupportedQuestionTypeException.java rename to backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java index a3e83d660..b08870515 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/mapper/UnsupportedQuestionTypeException.java +++ b/backend/src/main/java/reviewme/review/service/mapper/UnsupportedQuestionTypeException.java @@ -1,4 +1,4 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import lombok.extern.slf4j.Slf4j; import reviewme.global.exception.DataInconsistencyException; diff --git a/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java new file mode 100644 index 000000000..11162cc26 --- /dev/null +++ b/backend/src/main/java/reviewme/review/service/validator/AnswerValidator.java @@ -0,0 +1,10 @@ +package reviewme.review.service.validator; + +import reviewme.review.domain.Answer; + +public interface AnswerValidator { + + boolean supports(Class answerClass); + + void validate(Answer answer); +} diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactory.java b/backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java similarity index 65% rename from backend/src/main/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactory.java rename to backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java index 98c2ac5c9..b1adc5933 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactory.java +++ b/backend/src/main/java/reviewme/review/service/validator/AnswerValidatorFactory.java @@ -1,18 +1,18 @@ -package reviewme.review.service.abstraction.validator; +package reviewme.review.service.validator; import java.util.List; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import reviewme.review.domain.abstraction.Answer; +import reviewme.review.domain.Answer; @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class AnswerValidatorFactory { - private final List answerValidators; + private final List answerValidators; - public NewAnswerValidator getAnswerValidator(Class answerClass) { + public AnswerValidator getAnswerValidator(Class answerClass) { return answerValidators.stream() .filter(validator -> validator.supports(answerClass)) .findFirst() diff --git a/backend/src/main/java/reviewme/review/service/validator/CheckBoxAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java similarity index 84% rename from backend/src/main/java/reviewme/review/service/validator/CheckBoxAnswerValidator.java rename to backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java index f906e7878..62d39728b 100644 --- a/backend/src/main/java/reviewme/review/service/validator/CheckBoxAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/CheckboxAnswerValidator.java @@ -2,6 +2,7 @@ import java.util.HashSet; import java.util.List; +import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.question.domain.OptionGroup; @@ -10,22 +11,30 @@ import reviewme.question.repository.OptionGroupRepository; import reviewme.question.repository.OptionItemRepository; import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.CheckBoxAnswerSelectedOption; +import reviewme.review.domain.Answer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.CheckboxAnswer; -import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; import reviewme.review.service.exception.CheckBoxAnswerIncludedNotProvidedOptionItemException; +import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; import reviewme.review.service.exception.SelectedOptionItemCountOutOfRangeException; import reviewme.review.service.exception.SubmittedQuestionNotFoundException; @Component -@RequiredArgsConstructor -public class CheckBoxAnswerValidator { +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public class CheckboxAnswerValidator implements AnswerValidator { private final QuestionRepository questionRepository; private final OptionGroupRepository optionGroupRepository; private final OptionItemRepository optionItemRepository; - public void validate(CheckboxAnswer checkboxAnswer) { + @Override + public boolean supports(Class answerClass) { + return CheckboxAnswer.class.isAssignableFrom(answerClass); + } + + @Override + public void validate(Answer answer) { + CheckboxAnswer checkboxAnswer = (CheckboxAnswer) answer; Question question = questionRepository.findById(checkboxAnswer.getQuestionId()) .orElseThrow(() -> new SubmittedQuestionNotFoundException(checkboxAnswer.getQuestionId())); @@ -67,7 +76,7 @@ private void validateCheckedOptionItemCount(CheckboxAnswer checkboxAnswer, Optio private List extractAnsweredOptionItemIds(CheckboxAnswer checkboxAnswer) { return checkboxAnswer.getSelectedOptionIds() .stream() - .map(CheckBoxAnswerSelectedOption::getSelectedOptionId) + .map(CheckboxAnswerSelectedOption::getSelectedOptionId) .toList(); } } diff --git a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java index df9ff96ab..2906a8507 100644 --- a/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/ReviewValidator.java @@ -4,13 +4,15 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.question.domain.Question; import reviewme.question.repository.QuestionRepository; +import reviewme.review.domain.Answer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; -import reviewme.review.domain.TextAnswer; import reviewme.review.service.exception.MissingRequiredQuestionException; import reviewme.review.service.exception.SubmittedQuestionAndProvidedQuestionMismatchException; import reviewme.template.domain.Section; @@ -18,24 +20,25 @@ import reviewme.template.repository.SectionRepository; @Component -@RequiredArgsConstructor +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewValidator { - private final TextAnswerValidator textAnswerValidator; - private final CheckBoxAnswerValidator checkBoxAnswerValidator; + private final AnswerValidatorFactory answerValidatorFactory; private final SectionRepository sectionRepository; private final QuestionRepository questionRepository; public void validate(Review review) { - validateAnswer(review.getTextAnswers(), review.getCheckboxAnswers()); + validateAnswer(review.getAnswers()); validateAllAnswersContainedInTemplate(review); validateAllRequiredQuestionsAnswered(review); } - private void validateAnswer(List textAnswers, List checkboxAnswers) { - textAnswers.forEach(textAnswerValidator::validate); - checkboxAnswers.forEach(checkBoxAnswerValidator::validate); + private void validateAnswer(List answers) { + for (Answer answer : answers) { + AnswerValidator validator = answerValidatorFactory.getAnswerValidator(answer.getClass()); + validator.validate(answer); + } } private void validateAllAnswersContainedInTemplate(Review review) { @@ -63,7 +66,11 @@ private void validateAllRequiredQuestionsAnswered(Review review) { } private Set extractDisplayedQuestionIds(Review review) { - Set selectedOptionIds = review.getAllCheckBoxOptionIds(); + Set selectedOptionIds = review.getAnswersByType(CheckboxAnswer.class) + .stream() + .flatMap(answer -> answer.getSelectedOptionIds().stream()) + .map(CheckboxAnswerSelectedOption::getSelectedOptionId) + .collect(Collectors.toSet()); List
sections = sectionRepository.findAllByTemplateId(review.getTemplateId()); return sections.stream() diff --git a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java b/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java index 02e5e2abe..78a0701dd 100644 --- a/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/validator/TextAnswerValidator.java @@ -1,23 +1,33 @@ package reviewme.review.service.validator; +import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reviewme.question.domain.Question; import reviewme.question.repository.QuestionRepository; +import reviewme.review.domain.Answer; import reviewme.review.domain.TextAnswer; import reviewme.review.service.exception.InvalidTextAnswerLengthException; import reviewme.review.service.exception.SubmittedQuestionNotFoundException; @Component -@RequiredArgsConstructor -public class TextAnswerValidator { +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public class TextAnswerValidator implements AnswerValidator { + private static final int ZERO_LENGTH = 0; private static final int MIN_LENGTH = 20; private static final int MAX_LENGTH = 1_000; private final QuestionRepository questionRepository; - public void validate(TextAnswer textAnswer) { + @Override + public boolean supports(Class answerClass) { + return TextAnswer.class.isAssignableFrom(answerClass); + } + + @Override + public void validate(Answer answer) { + TextAnswer textAnswer = (TextAnswer) answer; Question question = questionRepository.findById(textAnswer.getQuestionId()) .orElseThrow(() -> new SubmittedQuestionNotFoundException(textAnswer.getQuestionId())); diff --git a/backend/src/main/java/reviewme/review/service/abstraction/validator/UnsupportedAnswerTypeException.java b/backend/src/main/java/reviewme/review/service/validator/UnsupportedAnswerTypeException.java similarity index 88% rename from backend/src/main/java/reviewme/review/service/abstraction/validator/UnsupportedAnswerTypeException.java rename to backend/src/main/java/reviewme/review/service/validator/UnsupportedAnswerTypeException.java index ca545a999..8c0d520a2 100644 --- a/backend/src/main/java/reviewme/review/service/abstraction/validator/UnsupportedAnswerTypeException.java +++ b/backend/src/main/java/reviewme/review/service/validator/UnsupportedAnswerTypeException.java @@ -1,4 +1,4 @@ -package reviewme.review.service.abstraction.validator; +package reviewme.review.service.validator; import lombok.extern.slf4j.Slf4j; import reviewme.global.exception.DataInconsistencyException; diff --git a/backend/src/test/java/reviewme/review/domain/ReviewTest.java b/backend/src/test/java/reviewme/review/domain/ReviewTest.java index 8caeceb27..0793941a2 100644 --- a/backend/src/test/java/reviewme/review/domain/ReviewTest.java +++ b/backend/src/test/java/reviewme/review/domain/ReviewTest.java @@ -1,7 +1,6 @@ package reviewme.review.domain; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; import java.util.List; import java.util.Set; @@ -14,7 +13,7 @@ class ReviewTest { // given TextAnswer textAnswer = new TextAnswer(1L, "답변"); CheckboxAnswer checkboxAnswer = new CheckboxAnswer(2L, List.of(1L)); - Review review = new Review(1L, 1L, List.of(textAnswer), List.of(checkboxAnswer)); + Review review = new Review(1L, 1L, List.of(textAnswer, checkboxAnswer)); // when Set allQuestionIdsFromAnswers = review.getAnsweredQuestionIds(); @@ -22,35 +21,4 @@ class ReviewTest { // then assertThat(allQuestionIdsFromAnswers).containsAll(List.of(1L, 2L)); } - - @Test - void 리뷰에_등록된_모든_선택형_답변의_옵션들을_반환환다() { - // given - CheckboxAnswer checkboxAnswer1 = new CheckboxAnswer(1L, List.of(1L, 2L)); - CheckboxAnswer checkboxAnswer2 = new CheckboxAnswer(1L, List.of(3L, 4L)); - Review review = new Review(1L, 1L, List.of(), List.of(checkboxAnswer1, checkboxAnswer2)); - - // when - Set allQuestionIdsFromAnswers = review.getAllCheckBoxOptionIds(); - - // then - assertThat(allQuestionIdsFromAnswers).containsAll(List.of(1L, 2L, 3L, 4L)); - } - - @Test - void 리뷰에_특정_질문에_대한_답변이_있는지_여부를_반환한다() { - // given - long textQuestionId = 1L; - long checkBoxQuestionId = 2L; - - TextAnswer textAnswer = new TextAnswer(textQuestionId, "답변"); - CheckboxAnswer checkboxAnswer = new CheckboxAnswer(checkBoxQuestionId, List.of(1L)); - Review review = new Review(1L, 1L, List.of(textAnswer), List.of(checkboxAnswer)); - - // when, then - assertAll( - () -> assertThat(review.hasAnsweredQuestion(textQuestionId)).isTrue(), - () -> assertThat(review.hasAnsweredQuestion(checkBoxQuestionId)).isTrue() - ); - } } diff --git a/backend/src/test/java/reviewme/review/domain/abstraction/NewCheckboxAnswerTest.java b/backend/src/test/java/reviewme/review/domain/abstraction/CheckboxAnswerTest.java similarity index 71% rename from backend/src/test/java/reviewme/review/domain/abstraction/NewCheckboxAnswerTest.java rename to backend/src/test/java/reviewme/review/domain/abstraction/CheckboxAnswerTest.java index 891448e6e..8eb7cc15c 100644 --- a/backend/src/test/java/reviewme/review/domain/abstraction/NewCheckboxAnswerTest.java +++ b/backend/src/test/java/reviewme/review/domain/abstraction/CheckboxAnswerTest.java @@ -5,17 +5,18 @@ import java.util.List; import org.junit.jupiter.api.Test; +import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.exception.QuestionNotAnsweredException; -class NewCheckboxAnswerTest { +class CheckboxAnswerTest { @Test void 답변이_없는_경우_예외를_발생한다() { // given, when, then assertAll( - () -> assertThatThrownBy(() -> new NewCheckboxAnswer(1L, null)) + () -> assertThatThrownBy(() -> new CheckboxAnswer(1L, null)) .isInstanceOf(QuestionNotAnsweredException.class), - () -> assertThatThrownBy(() -> new NewCheckboxAnswer(1L, List.of())) + () -> assertThatThrownBy(() -> new CheckboxAnswer(1L, List.of())) .isInstanceOf(QuestionNotAnsweredException.class) ); } diff --git a/backend/src/test/java/reviewme/review/domain/abstraction/NewReviewTest.java b/backend/src/test/java/reviewme/review/domain/abstraction/ReviewTest.java similarity index 53% rename from backend/src/test/java/reviewme/review/domain/abstraction/NewReviewTest.java rename to backend/src/test/java/reviewme/review/domain/abstraction/ReviewTest.java index 3bda91a4c..47ead260f 100644 --- a/backend/src/test/java/reviewme/review/domain/abstraction/NewReviewTest.java +++ b/backend/src/test/java/reviewme/review/domain/abstraction/ReviewTest.java @@ -6,15 +6,18 @@ import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; +import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.Review; +import reviewme.review.domain.TextAnswer; -class NewReviewTest { +class ReviewTest { @Test void 리뷰에_등록된_답변의_모든_질문들을_반환한다() { // given - NewTextAnswer textAnswer = new NewTextAnswer(1L, "답변"); - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(2L, List.of(1L)); - NewReview review = new NewReview(1L, 1L, List.of(textAnswer, checkboxAnswer)); + TextAnswer textAnswer = new TextAnswer(1L, "답변"); + CheckboxAnswer checkboxAnswer = new CheckboxAnswer(2L, List.of(1L)); + Review review = new Review(1L, 1L, List.of(textAnswer, checkboxAnswer)); // when Set allQuestionIdsFromAnswers = review.getAnsweredQuestionIds(); @@ -26,13 +29,13 @@ class NewReviewTest { @Test void 리뷰에_등록된_타입에_따라_답변을_반환한다() { // given - NewCheckboxAnswer checkboxAnswer1 = new NewCheckboxAnswer(1L, List.of(1L, 2L)); - NewCheckboxAnswer checkboxAnswer2 = new NewCheckboxAnswer(1L, List.of(3L, 4L)); - NewTextAnswer textAnswer = new NewTextAnswer(1L, "답변"); - NewReview review = new NewReview(1L, 1L, List.of(checkboxAnswer1, checkboxAnswer2, textAnswer)); + CheckboxAnswer checkboxAnswer1 = new CheckboxAnswer(1L, List.of(1L, 2L)); + CheckboxAnswer checkboxAnswer2 = new CheckboxAnswer(1L, List.of(3L, 4L)); + TextAnswer textAnswer = new TextAnswer(1L, "답변"); + Review review = new Review(1L, 1L, List.of(checkboxAnswer1, checkboxAnswer2, textAnswer)); // when - List allQuestionIdsFromAnswers = review.getAnswersByType(NewCheckboxAnswer.class); + List allQuestionIdsFromAnswers = review.getAnswersByType(CheckboxAnswer.class); // then assertThat(allQuestionIdsFromAnswers).containsAll(List.of(checkboxAnswer1, checkboxAnswer2)); @@ -44,9 +47,9 @@ class NewReviewTest { long textQuestionId = 1L; long checkBoxQuestionId = 2L; - NewTextAnswer textAnswer = new NewTextAnswer(textQuestionId, "답변"); - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(checkBoxQuestionId, List.of(1L)); - NewReview review = new NewReview(1L, 1L, List.of(textAnswer, checkboxAnswer)); + TextAnswer textAnswer = new TextAnswer(textQuestionId, "답변"); + CheckboxAnswer checkboxAnswer = new CheckboxAnswer(checkBoxQuestionId, List.of(1L)); + Review review = new Review(1L, 1L, List.of(textAnswer, checkboxAnswer)); // when, then assertAll( diff --git a/backend/src/test/java/reviewme/review/domain/abstraction/NewTextAnswerTest.java b/backend/src/test/java/reviewme/review/domain/abstraction/TextAnswerTest.java similarity index 72% rename from backend/src/test/java/reviewme/review/domain/abstraction/NewTextAnswerTest.java rename to backend/src/test/java/reviewme/review/domain/abstraction/TextAnswerTest.java index 084b4c362..1d6f58f85 100644 --- a/backend/src/test/java/reviewme/review/domain/abstraction/NewTextAnswerTest.java +++ b/backend/src/test/java/reviewme/review/domain/abstraction/TextAnswerTest.java @@ -4,17 +4,18 @@ import static org.junit.jupiter.api.Assertions.assertAll; import org.junit.jupiter.api.Test; +import reviewme.review.domain.TextAnswer; import reviewme.review.domain.exception.QuestionNotAnsweredException; -class NewTextAnswerTest { +class TextAnswerTest { @Test void 답변이_없는_경우_예외를_발생한다() { // given, when, then assertAll( - () -> assertThatThrownBy(() -> new NewTextAnswer(1L, null)) + () -> assertThatThrownBy(() -> new TextAnswer(1L, null)) .isInstanceOf(QuestionNotAnsweredException.class), - () -> assertThatThrownBy(() -> new NewTextAnswer(1L, "")) + () -> assertThatThrownBy(() -> new TextAnswer(1L, "")) .isInstanceOf(QuestionNotAnsweredException.class) ); } diff --git a/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java b/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java index 51ea4c83f..c457ce4cd 100644 --- a/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java +++ b/backend/src/test/java/reviewme/review/repository/ReviewRepositoryTest.java @@ -50,9 +50,9 @@ class ReviewRepositoryTest { ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); Review review1 = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); Review review2 = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); // when List actual = reviewRepository.findAllByGroupId(reviewGroup.getId()); @@ -70,11 +70,11 @@ class 리뷰그룹_아이디에_해당하는_리뷰를_생성일_기준_내림 private final ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); private final Review review1 = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); private final Review review2 = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); private final Review review3 = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); @Test void 페이징_크기보다_적은_수의_리뷰가_등록되었으면_그_크기만큼의_리뷰만_반환한다() { @@ -165,9 +165,9 @@ class 주어진_리뷰보다_오래된_리뷰가_있는지_검사한다 { ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); Review firstReview = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); Review secondReview = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null)); + new Review(template.getId(), reviewGroup.getId(), null)); @Test void 주어진_리뷰가_가장_오래된_경우() { diff --git a/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java index 915693e8f..02d138f0b 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewDetailLookupServiceTest.java @@ -22,6 +22,7 @@ import reviewme.question.repository.OptionGroupRepository; import reviewme.question.repository.OptionItemRepository; import reviewme.question.repository.QuestionRepository; +import reviewme.review.domain.Answer; import reviewme.review.domain.CheckboxAnswer; import reviewme.review.domain.Review; import reviewme.review.domain.TextAnswer; @@ -72,7 +73,7 @@ class ReviewDetailLookupServiceTest { String reviewRequestCode = "hello"; String groupAccessCode = "goodBye"; ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹(reviewRequestCode, groupAccessCode)); - Review review = reviewRepository.save(new Review(0, reviewGroup.getId(), List.of(), List.of())); + Review review = reviewRepository.save(new Review(0, reviewGroup.getId(), List.of())); // when, then assertThatThrownBy(() -> reviewDetailLookupService.getReviewDetail( @@ -90,8 +91,8 @@ class ReviewDetailLookupServiceTest { ReviewGroup reviewGroup1 = reviewGroupRepository.save(리뷰_그룹(reviewRequestCode1, groupAccessCode1)); ReviewGroup reviewGroup2 = reviewGroupRepository.save(리뷰_그룹(reviewRequestCode2, groupAccessCode2)); - Review review1 = reviewRepository.save(new Review(0, reviewGroup1.getId(), List.of(), List.of())); - Review review2 = reviewRepository.save(new Review(0, reviewGroup2.getId(), List.of(), List.of())); + Review review1 = reviewRepository.save(new Review(0, reviewGroup1.getId(), List.of())); + Review review2 = reviewRepository.save(new Review(0, reviewGroup2.getId(), List.of())); // when, then assertAll( @@ -124,12 +125,12 @@ class ReviewDetailLookupServiceTest { Template template = templateRepository.save(템플릿(List.of(section1.getId(), section2.getId()))); // given - 리뷰 답변 저장 - List textAnswers = List.of(new TextAnswer(question2.getId(), "답변".repeat(20))); - List checkboxAnswers = List.of( + List answers = List.of( + new TextAnswer(question2.getId(), "답변".repeat(20)), new CheckboxAnswer(question1.getId(), List.of(optionItem1.getId(), optionItem2.getId())) ); Review review = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), textAnswers, checkboxAnswers) + new Review(template.getId(), reviewGroup.getId(), answers) ); // when @@ -158,7 +159,7 @@ class 필수가_아닌_답변에_응답하지_않았을_때 { // given - 아무것도 응답하지 않은 리뷰 답변 저장 Review review = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), null, null) + new Review(template.getId(), reviewGroup.getId(), null) ); // when @@ -188,7 +189,7 @@ class 필수가_아닌_답변에_응답하지_않았을_때 { // given - 질문 하나에만 응답한 리뷰 답변 저장 TextAnswer textAnswer = new TextAnswer(question1.getId(), "답변".repeat(20)); Review review = reviewRepository.save( - new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), null) + new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)) ); // when diff --git a/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java index bf89caa10..ab55e11ac 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewListLookupServiceTest.java @@ -84,9 +84,9 @@ class ReviewListLookupServiceTest { // given - 리뷰 답변 저장 CheckboxAnswer categoryAnswer = new CheckboxAnswer(question.getId(), List.of(categoryOption.getId())); - Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(), List.of(categoryAnswer)); + Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(categoryAnswer)); TextAnswer textAnswer = new TextAnswer(question.getId(), "텍스트형 응답"); - Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); + Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); reviewRepository.saveAll(List.of(review1, review2)); // when @@ -117,9 +117,9 @@ class ReviewListLookupServiceTest { // given - 리뷰 답변 저장 TextAnswer textAnswer = new TextAnswer(question.getId(), "텍스트형 응답"); - Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review3 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); + Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review3 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); reviewRepository.saveAll(List.of(review1, review2, review3)); // when diff --git a/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java b/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java index 7bba502ff..73ab64897 100644 --- a/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java +++ b/backend/src/test/java/reviewme/review/service/ReviewRegisterServiceTest.java @@ -109,9 +109,10 @@ class ReviewRegisterServiceTest { // when, then Review review = reviewRepository.findById(registeredReviewId).orElseThrow(); assertAll( - () -> assertThat(review.getTextAnswers()).extracting(TextAnswer::getQuestionId) + () -> assertThat(review.getAnswersByType(TextAnswer.class)).extracting(TextAnswer::getQuestionId) .containsExactly(requiredTextQuestion.getId()), - () -> assertThat(review.getCheckboxAnswers()).extracting(CheckboxAnswer::getQuestionId) + () -> assertThat(review.getAnswersByType(CheckboxAnswer.class)).extracting( + CheckboxAnswer::getQuestionId) .containsAll(List.of(requiredCheckQuestion.getId(), conditionalCheckQuestion.getId())) ); } diff --git a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewReviewMapperTest.java b/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewReviewMapperTest.java deleted file mode 100644 index dc710cbb1..000000000 --- a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewReviewMapperTest.java +++ /dev/null @@ -1,176 +0,0 @@ -package reviewme.review.service.abstraction.mapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; -import static reviewme.fixture.OptionGroupFixture.선택지_그룹; -import static reviewme.fixture.OptionItemFixture.선택지; -import static reviewme.fixture.QuestionFixture.서술형_옵션_질문; -import static reviewme.fixture.QuestionFixture.서술형_필수_질문; -import static reviewme.fixture.QuestionFixture.선택형_옵션_질문; -import static reviewme.fixture.QuestionFixture.선택형_필수_질문; -import static reviewme.fixture.ReviewGroupFixture.리뷰_그룹; -import static reviewme.fixture.SectionFixture.항상_보이는_섹션; -import static reviewme.fixture.TemplateFixture.템플릿; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.domain.abstraction.NewReview; -import reviewme.review.domain.abstraction.NewTextAnswer; -import reviewme.review.service.dto.request.ReviewAnswerRequest; -import reviewme.review.service.dto.request.ReviewRegisterRequest; -import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException; -import reviewme.reviewgroup.domain.ReviewGroup; -import reviewme.reviewgroup.repository.ReviewGroupRepository; -import reviewme.support.ServiceTest; -import reviewme.template.domain.Section; -import reviewme.template.repository.SectionRepository; -import reviewme.template.repository.TemplateRepository; - -@ServiceTest -class NewReviewMapperTest { - - @Autowired - private NewReviewMapper reviewMapper; - - @Autowired - private ReviewGroupRepository reviewGroupRepository; - - @Autowired - private OptionGroupRepository optionGroupRepository; - - @Autowired - private OptionItemRepository optionItemRepository; - - @Autowired - private QuestionRepository questionRepository; - - @Autowired - private SectionRepository sectionRepository; - - @Autowired - private TemplateRepository templateRepository; - - @Test - void 텍스트가_포함된_리뷰를_생성한다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - Question question = questionRepository.save(서술형_필수_질문()); - Section section = sectionRepository.save(항상_보이는_섹션(List.of(question.getId()))); - templateRepository.save(템플릿(List.of(section.getId()))); - - String expectedTextAnswer = "답".repeat(20); - ReviewAnswerRequest reviewAnswerRequest = new ReviewAnswerRequest(question.getId(), null, expectedTextAnswer); - ReviewRegisterRequest reviewRegisterRequest = new ReviewRegisterRequest(reviewGroup.getReviewRequestCode(), - List.of(reviewAnswerRequest)); - - // when - NewReview review = reviewMapper.mapToReview(reviewRegisterRequest); - - // then - assertThat(review.getAnswersByType(NewTextAnswer.class)).hasSize(1); - } - - @Test - void 체크박스가_포함된_리뷰를_생성한다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - Question question = questionRepository.save(선택형_필수_질문()); - OptionGroup optionGroup = optionGroupRepository.save(선택지_그룹(question.getId())); - OptionItem optionItem1 = optionItemRepository.save(선택지(optionGroup.getId())); - OptionItem optionItem2 = optionItemRepository.save(선택지(optionGroup.getId())); - - Section section = sectionRepository.save(항상_보이는_섹션(List.of(question.getId()))); - templateRepository.save(템플릿(List.of(section.getId()))); - - ReviewAnswerRequest reviewAnswerRequest = new ReviewAnswerRequest(question.getId(), - List.of(optionItem1.getId()), null); - ReviewRegisterRequest reviewRegisterRequest = new ReviewRegisterRequest(reviewGroup.getReviewRequestCode(), - List.of(reviewAnswerRequest)); - - // when - NewReview review = reviewMapper.mapToReview(reviewRegisterRequest); - - // then - assertThat(review.getAnswersByType(NewCheckboxAnswer.class)).hasSize(1); - } - - @Test - void 필수가_아닌_질문에_답변이_없을_경우_답변을_생성하지_않는다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - Question requiredTextQuestion = questionRepository.save(서술형_필수_질문()); - Question optionalTextQuestion = questionRepository.save(서술형_옵션_질문()); - - Question requeiredCheckBoxQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup optionGroup1 = optionGroupRepository.save(선택지_그룹(requeiredCheckBoxQuestion.getId())); - OptionItem optionItem1 = optionItemRepository.save(선택지(optionGroup1.getId())); - OptionItem optionItem2 = optionItemRepository.save(선택지(optionGroup1.getId())); - - Question optionalCheckBoxQuestion = questionRepository.save(선택형_옵션_질문()); - OptionGroup optionGroup2 = optionGroupRepository.save(선택지_그룹(optionalCheckBoxQuestion.getId())); - OptionItem optionItem3 = optionItemRepository.save(선택지(optionGroup2.getId())); - OptionItem optionItem4 = optionItemRepository.save(선택지(optionGroup2.getId())); - - Section section = sectionRepository.save(항상_보이는_섹션( - List.of(requiredTextQuestion.getId(), optionalTextQuestion.getId(), - requeiredCheckBoxQuestion.getId(), optionalCheckBoxQuestion.getId()))); - templateRepository.save(템플릿(List.of(section.getId()))); - - String textAnswer = "답".repeat(20); - ReviewAnswerRequest requiredTextAnswerRequest = new ReviewAnswerRequest( - requiredTextQuestion.getId(), null, textAnswer - ); - ReviewAnswerRequest optionalTextAnswerRequest = new ReviewAnswerRequest( - optionalTextQuestion.getId(), null, "" - ); - ReviewAnswerRequest requiredCheckBoxAnswerRequest = new ReviewAnswerRequest( - requeiredCheckBoxQuestion.getId(), List.of(optionItem1.getId()), null - ); - ReviewAnswerRequest optionalCheckBoxAnswerRequest = new ReviewAnswerRequest( - optionalCheckBoxQuestion.getId(), List.of(), null - ); - ReviewRegisterRequest reviewRegisterRequest = new ReviewRegisterRequest(reviewGroup.getReviewRequestCode(), - List.of(requiredTextAnswerRequest, optionalTextAnswerRequest, - requiredCheckBoxAnswerRequest, optionalCheckBoxAnswerRequest)); - - // when - NewReview review = reviewMapper.mapToReview(reviewRegisterRequest); - - // then - assertAll( - () -> assertThat(review.getAnswersByType(NewTextAnswer.class)) - .extracting(NewTextAnswer::getQuestionId) - .containsExactly(requiredTextQuestion.getId()), - () -> assertThat(review.getAnswersByType(NewCheckboxAnswer.class)) - .extracting(NewCheckboxAnswer::getQuestionId) - .containsExactly(requeiredCheckBoxQuestion.getId()) - ); - } - - @Test - void 잘못된_리뷰_요청_코드로_리뷰를_생성할_경우_예외가_발생한다() { - // given - String reviewRequestCode = "notExistCode"; - Question savedQuestion = questionRepository.save(서술형_필수_질문()); - ReviewAnswerRequest emptyTextReviewRequest = new ReviewAnswerRequest( - savedQuestion.getId(), null, ""); - ReviewRegisterRequest reviewRegisterRequest = new ReviewRegisterRequest( - reviewRequestCode, List.of(emptyTextReviewRequest)); - - // when, then - assertThatThrownBy(() -> reviewMapper.mapToReview(reviewRegisterRequest)) - .isInstanceOf(ReviewGroupNotFoundByReviewRequestCodeException.class); - } -} diff --git a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidatorTest.java deleted file mode 100644 index c18ce8723..000000000 --- a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewCheckboxAnswerValidatorTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static reviewme.fixture.OptionGroupFixture.선택지_그룹; -import static reviewme.fixture.OptionItemFixture.선택지; -import static reviewme.fixture.QuestionFixture.선택형_필수_질문; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.service.exception.CheckBoxAnswerIncludedNotProvidedOptionItemException; -import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; -import reviewme.review.service.exception.SelectedOptionItemCountOutOfRangeException; -import reviewme.review.service.exception.SubmittedQuestionNotFoundException; -import reviewme.support.ServiceTest; - -@ServiceTest -class NewCheckboxAnswerValidatorTest { - - @Autowired - private NewCheckboxAnswerValidator checkBoxAnswerValidator; - - @Autowired - private QuestionRepository questionRepository; - - @Autowired - private OptionGroupRepository optionGroupRepository; - - @Autowired - private OptionItemRepository optionItemRepository; - - @Test - void 저장되지_않은_질문에_대한_답변이면_예외가_발생한다() { - // given - long notSavedQuestionId = 100L; - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(notSavedQuestionId, List.of(1L)); - - // when, then - assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) - .isInstanceOf(SubmittedQuestionNotFoundException.class); - } - - @Test - void 옵션_그룹이_지정되지_않은_질문에_대한_답변이면_예외가_발생한다() { - // given - Question savedQuestion = questionRepository.save(선택형_필수_질문()); - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(savedQuestion.getId(), List.of(1L)); - - // when, then - assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) - .isInstanceOf(OptionGroupNotFoundByQuestionIdException.class); - } - - @Test - void 옵션그룹에서_제공하지_않은_옵션아이템을_응답하면_예외가_발생한다() { - // given - Question savedQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup savedOptionGroup = optionGroupRepository.save(선택지_그룹(savedQuestion.getId())); - OptionItem savedOptionItem = optionItemRepository.save(선택지(savedOptionGroup.getId())); - - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(savedQuestion.getId(), - List.of(savedOptionItem.getId() + 1L)); - - // when, then - assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) - .isInstanceOf(CheckBoxAnswerIncludedNotProvidedOptionItemException.class); - } - - @Test - void 옵션그룹에서_정한_최소_선택_수_보다_적게_선택하면_예외가_발생한다() { - // given - Question savedQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup savedOptionGroup = optionGroupRepository.save( - new OptionGroup(savedQuestion.getId(), 2, 3) - ); - OptionItem savedOptionItem1 = optionItemRepository.save(선택지(savedOptionGroup.getId())); - - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer(savedQuestion.getId(), - List.of(savedOptionItem1.getId())); - - // when, then - assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) - .isInstanceOf(SelectedOptionItemCountOutOfRangeException.class); - } - - @Test - void 옵션그룹에서_정한_최대_선택_수_보다_많이_선택하면_예외가_발생한다() { - // given - Question savedQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup savedOptionGroup = optionGroupRepository.save( - new OptionGroup(savedQuestion.getId(), 1, 1) - ); - OptionItem savedOptionItem1 = optionItemRepository.save(선택지(savedOptionGroup.getId(), 1)); - OptionItem savedOptionItem2 = optionItemRepository.save(선택지(savedOptionGroup.getId(), 2)); - - NewCheckboxAnswer checkboxAnswer = new NewCheckboxAnswer( - savedQuestion.getId(), List.of(savedOptionItem1.getId(), savedOptionItem2.getId())); - - // when, then - assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) - .isInstanceOf(SelectedOptionItemCountOutOfRangeException.class); - } -} diff --git a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewReviewValidatorTest.java b/backend/src/test/java/reviewme/review/service/abstraction/validator/NewReviewValidatorTest.java deleted file mode 100644 index 64d389ce3..000000000 --- a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewReviewValidatorTest.java +++ /dev/null @@ -1,153 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static reviewme.fixture.OptionGroupFixture.선택지_그룹; -import static reviewme.fixture.OptionItemFixture.선택지; -import static reviewme.fixture.QuestionFixture.서술형_옵션_질문; -import static reviewme.fixture.QuestionFixture.서술형_필수_질문; -import static reviewme.fixture.QuestionFixture.선택형_필수_질문; -import static reviewme.fixture.ReviewGroupFixture.리뷰_그룹; -import static reviewme.fixture.SectionFixture.조건부로_보이는_섹션; -import static reviewme.fixture.SectionFixture.항상_보이는_섹션; -import static reviewme.fixture.TemplateFixture.템플릿; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.OptionGroup; -import reviewme.question.domain.OptionItem; -import reviewme.question.domain.Question; -import reviewme.question.repository.OptionGroupRepository; -import reviewme.question.repository.OptionItemRepository; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.domain.abstraction.NewReview; -import reviewme.review.domain.abstraction.NewTextAnswer; -import reviewme.review.service.exception.MissingRequiredQuestionException; -import reviewme.review.service.exception.SubmittedQuestionAndProvidedQuestionMismatchException; -import reviewme.reviewgroup.domain.ReviewGroup; -import reviewme.reviewgroup.repository.ReviewGroupRepository; -import reviewme.support.ServiceTest; -import reviewme.template.domain.Section; -import reviewme.template.domain.Template; -import reviewme.template.repository.SectionRepository; -import reviewme.template.repository.TemplateRepository; - -@ServiceTest -class NewReviewValidatorTest { - - @Autowired - private QuestionRepository questionRepository; - - @Autowired - private OptionGroupRepository optionGroupRepository; - - @Autowired - private OptionItemRepository optionItemRepository; - - @Autowired - private ReviewGroupRepository reviewGroupRepository; - - @Autowired - private TemplateRepository templateRepository; - - @Autowired - private SectionRepository sectionRepository; - - @Autowired - private NewReviewValidator reviewValidator; - - @Test - void 템플릿에_있는_질문에_대한_답과_필수_질문에_모두_응답하는_경우_예외가_발생하지_않는다() { - // 리뷰 그룹 저장 - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - // 필수가 아닌 서술형 질문 저장 - Question notRequiredTextQuestion = questionRepository.save(서술형_옵션_질문()); - Section visibleSection1 = sectionRepository.save(항상_보이는_섹션(List.of(notRequiredTextQuestion.getId()), 1)); - - // 필수 선택형 질문, 섹션 저장 - Question requiredCheckQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup requiredOptionGroup = optionGroupRepository.save(선택지_그룹(requiredCheckQuestion.getId())); - OptionItem requiredOptionItem1 = optionItemRepository.save(선택지(requiredOptionGroup.getId())); - OptionItem requiredOptionItem2 = optionItemRepository.save(선택지(requiredOptionGroup.getId())); - Section visibleSection2 = sectionRepository.save(항상_보이는_섹션(List.of(requiredCheckQuestion.getId()), 2)); - - // optionItem 선택에 따라서 required 가 달라지는 섹션1 저장 - Question conditionalTextQuestion1 = questionRepository.save(서술형_필수_질문()); - Question conditionalCheckQuestion = questionRepository.save(선택형_필수_질문()); - OptionGroup conditionalOptionGroup = optionGroupRepository.save(선택지_그룹(conditionalCheckQuestion.getId())); - OptionItem conditionalOptionItem = optionItemRepository.save(선택지(conditionalOptionGroup.getId())); - Section conditionalSection1 = sectionRepository.save(조건부로_보이는_섹션( - List.of(conditionalTextQuestion1.getId(), conditionalCheckQuestion.getId()), - requiredOptionItem1.getId(), 3) - ); - - // optionItem 선택에 따라서 required 가 달라지는 섹션2 저장 - Question conditionalQuestion2 = questionRepository.save(서술형_필수_질문()); - Section conditionalSection2 = sectionRepository.save(조건부로_보이는_섹션( - List.of(conditionalQuestion2.getId()), requiredOptionItem2.getId(), 3) - ); - - // 템플릿 저장 - Template template = templateRepository.save(템플릿( - List.of(visibleSection1.getId(), visibleSection2.getId(), - conditionalSection1.getId(), conditionalSection2.getId()) - )); - - // 각 질문에 대한 답변 생성 - NewTextAnswer notRequiredTextAnswer = new NewTextAnswer(notRequiredTextQuestion.getId(), "답변".repeat(30)); - NewCheckboxAnswer alwaysRequiredCheckAnswer = new NewCheckboxAnswer(requiredCheckQuestion.getId(), - List.of(requiredOptionItem1.getId())); - NewTextAnswer conditionalTextAnswer1 = new NewTextAnswer(conditionalTextQuestion1.getId(), "답변".repeat(30)); - NewCheckboxAnswer conditionalCheckAnswer1 = new NewCheckboxAnswer(conditionalCheckQuestion.getId(), - List.of(conditionalOptionItem.getId())); - - // 리뷰 생성 - NewReview review = new NewReview(template.getId(), reviewGroup.getId(), - List.of(notRequiredTextAnswer, conditionalTextAnswer1, - alwaysRequiredCheckAnswer, conditionalCheckAnswer1)); - - // when, then - assertThatCode(() -> reviewValidator.validate(review)) - .doesNotThrowAnyException(); - } - - @Test - void 제공된_템플릿에_없는_질문에_대한_답변이_있을_경우_예외가_발생한다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - Question question1 = questionRepository.save(서술형_필수_질문()); - Question question2 = questionRepository.save(서술형_필수_질문()); - Section section = sectionRepository.save(항상_보이는_섹션(List.of(question1.getId()))); - Template template = templateRepository.save(템플릿(List.of(section.getId()))); - - NewTextAnswer textAnswer = new NewTextAnswer(question2.getId(), "답변".repeat(20)); - NewReview review = new NewReview(template.getId(), reviewGroup.getId(), List.of(textAnswer)); - - // when, then - assertThatThrownBy(() -> reviewValidator.validate(review)) - .isInstanceOf(SubmittedQuestionAndProvidedQuestionMismatchException.class); - } - - @Test - void 필수_질문에_답변하지_않은_경우_예외가_발생한다() { - // given - ReviewGroup reviewGroup = reviewGroupRepository.save(리뷰_그룹()); - - Question requiredQuestion = questionRepository.save(서술형_필수_질문()); - Question optionalQuestion = questionRepository.save(서술형_옵션_질문()); - Section section = sectionRepository.save( - 항상_보이는_섹션(List.of(requiredQuestion.getId(), optionalQuestion.getId()))); - Template template = templateRepository.save(템플릿(List.of(section.getId()))); - - NewTextAnswer optionalTextAnswer = new NewTextAnswer(optionalQuestion.getId(), "답변".repeat(20)); - NewReview review = new NewReview(template.getId(), reviewGroup.getId(), List.of(optionalTextAnswer)); - - // when, then - assertThatThrownBy(() -> reviewValidator.validate(review)) - .isInstanceOf(MissingRequiredQuestionException.class); - } -} diff --git a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidatorTest.java deleted file mode 100644 index cea001173..000000000 --- a/backend/src/test/java/reviewme/review/service/abstraction/validator/NewTextAnswerValidatorTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package reviewme.review.service.abstraction.validator; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static reviewme.fixture.QuestionFixture.서술형_옵션_질문; -import static reviewme.fixture.QuestionFixture.서술형_필수_질문; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.question.domain.Question; -import reviewme.question.repository.QuestionRepository; -import reviewme.review.domain.abstraction.NewTextAnswer; -import reviewme.review.service.exception.InvalidTextAnswerLengthException; -import reviewme.review.service.exception.SubmittedQuestionNotFoundException; -import reviewme.support.ServiceTest; - -@ServiceTest -class NewTextAnswerValidatorTest { - - @Autowired - private NewTextAnswerValidator textAnswerValidator; - - @Autowired - private QuestionRepository questionRepository; - - @Test - void 저장되지_않은_질문에_대한_대답이면_예외가_발생한다() { - // given - long notSavedQuestionId = 100L; - NewTextAnswer textAnswer = new NewTextAnswer(notSavedQuestionId, "텍스트형 응답"); - - // when, then - assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) - .isInstanceOf(SubmittedQuestionNotFoundException.class); - } - - @ParameterizedTest - @ValueSource(ints = {19, 10001}) - void 필수_질문의_답변_길이가_유효하지_않으면_예외가_발생한다(int length) { - // given - String content = "답".repeat(length); - Question savedQuestion = questionRepository.save(서술형_필수_질문()); - NewTextAnswer textAnswer = new NewTextAnswer(savedQuestion.getId(), content); - - // when, then - assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) - .isInstanceOf(InvalidTextAnswerLengthException.class); - } - - @Test - void 선택_질문의_답변_길이가_유효하지_않으면_예외가_발생한다() { - // given - String content = "답".repeat(10001); - Question savedQuestion = questionRepository.save(서술형_옵션_질문()); - NewTextAnswer textAnswer = new NewTextAnswer(savedQuestion.getId(), content); - - // when, then - assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) - .isInstanceOf(InvalidTextAnswerLengthException.class); - } - - @Test - void 선택_질문은_최소_글자수_제한을_받지_않는다() { - // given - String content = "답".repeat(1); - Question savedQuestion = questionRepository.save(서술형_옵션_질문()); - NewTextAnswer textAnswer = new NewTextAnswer(savedQuestion.getId(), content); - - // when, then - assertDoesNotThrow(() -> textAnswerValidator.validate(textAnswer)); - } -} diff --git a/backend/src/test/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactoryTest.java b/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java similarity index 82% rename from backend/src/test/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactoryTest.java rename to backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java index 18ac46e46..25d1b5018 100644 --- a/backend/src/test/java/reviewme/review/service/abstraction/mapper/AnswerMapperFactoryTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperFactoryTest.java @@ -1,4 +1,4 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -9,13 +9,13 @@ import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import reviewme.question.domain.QuestionType; -import reviewme.review.domain.abstraction.Answer; +import reviewme.review.domain.Answer; import reviewme.review.service.dto.request.ReviewAnswerRequest; @ExtendWith(OutputCaptureExtension.class) class AnswerMapperFactoryTest { - private final NewAnswerMapper answerMapper = new NewAnswerMapper() { + private final AnswerMapper answerMapper = new AnswerMapper() { @Override public boolean supports(QuestionType questionType) { @@ -31,11 +31,11 @@ public Answer mapToAnswer(ReviewAnswerRequest answerRequest) { @Test void 지원하는_타입에_따른_매퍼를_가져온다() { // given - List answerMappers = List.of(answerMapper); + List answerMappers = List.of(answerMapper); AnswerMapperFactory factory = new AnswerMapperFactory(answerMappers); // when - NewAnswerMapper actual = factory.getAnswerMapper(QuestionType.CHECKBOX); + AnswerMapper actual = factory.getAnswerMapper(QuestionType.CHECKBOX); // then assertThat(answerMapper).isEqualTo(actual); diff --git a/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperTest.java deleted file mode 100644 index f9557dde3..000000000 --- a/backend/src/test/java/reviewme/review/service/mapper/AnswerMapperTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package reviewme.review.service.mapper; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import reviewme.review.domain.CheckBoxAnswerSelectedOption; -import reviewme.review.domain.CheckboxAnswer; -import reviewme.review.domain.TextAnswer; -import reviewme.review.service.dto.request.ReviewAnswerRequest; -import reviewme.review.service.exception.CheckBoxAnswerIncludedTextException; -import reviewme.review.service.exception.TextAnswerIncludedOptionItemException; -import reviewme.support.ServiceTest; - -@ServiceTest -class AnswerMapperTest { - - @Autowired - private AnswerMapper answerMapper; - - @Test - void 답변_요청을_서술형_답변으로_매핑한다() { - // given - long questionId = 1L; - String text = "답변"; - ReviewAnswerRequest answerRequest = new ReviewAnswerRequest(questionId, null, text); - - // when - TextAnswer textAnswer = answerMapper.mapToTextAnswer(answerRequest); - - // then - assertAll( - () -> assertThat(textAnswer.getQuestionId()).isEqualTo(questionId), - () -> assertThat(textAnswer.getContent()).isEqualTo(text) - ); - } - - @Test - void 답변_요청을_선택형_답변으로_매핑한다() { - // given - long questionId = 1L; - long selectedOptionsId = 2L; - ReviewAnswerRequest answerRequest = new ReviewAnswerRequest(questionId, List.of(selectedOptionsId), null); - - // when - CheckboxAnswer checkboxAnswer = answerMapper.mapToCheckBoxAnswer(answerRequest); - - // then - assertAll( - () -> assertThat(checkboxAnswer.getQuestionId()).isEqualTo(questionId), - () -> assertThat(checkboxAnswer.getSelectedOptionIds()) - .extracting(CheckBoxAnswerSelectedOption::getSelectedOptionId) - .containsOnly(selectedOptionsId) - ); - } - - @Test - void 서술형_답변_매핑시_선택형_답변이_존재할_경우_예외가_발생한다() { - // given - long questionId = 1L; - String text = "답변"; - long selectedOptionsId = 2L; - ReviewAnswerRequest answerRequest = new ReviewAnswerRequest(questionId, List.of(selectedOptionsId), text); - - // when, then - assertThatThrownBy(() -> answerMapper.mapToTextAnswer(answerRequest)) - .isInstanceOf(TextAnswerIncludedOptionItemException.class); - } - - @Test - void 선택형_답변_매핑시_서술형_답변이_존재할_경우_예외가_발생한다() { - // given - long questionId = 1L; - String text = "답변"; - long selectedOptionsId = 2L; - ReviewAnswerRequest answerRequest = new ReviewAnswerRequest(questionId, List.of(selectedOptionsId), text); - - // when, then - assertThatThrownBy(() -> answerMapper.mapToCheckBoxAnswer(answerRequest)) - .isInstanceOf(CheckBoxAnswerIncludedTextException.class); - } -} diff --git a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/CheckboxAnswerMapperTest.java similarity index 68% rename from backend/src/test/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapperTest.java rename to backend/src/test/java/reviewme/review/service/mapper/CheckboxAnswerMapperTest.java index 6e9e352fc..eb2d96f98 100644 --- a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewCheckboxAnswerMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/CheckboxAnswerMapperTest.java @@ -1,30 +1,30 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.List; import org.junit.jupiter.api.Test; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; -import reviewme.review.domain.abstraction.NewCheckboxAnswerSelectedOption; +import reviewme.review.domain.CheckboxAnswer; +import reviewme.review.domain.CheckboxAnswerSelectedOption; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.CheckBoxAnswerIncludedTextException; -class NewCheckboxAnswerMapperTest { +class CheckboxAnswerMapperTest { @Test void 체크박스_답변을_요청으로부터_매핑한다() { // given ReviewAnswerRequest request = new ReviewAnswerRequest(1L, List.of(1L, 2L, 3L), null); - NewCheckboxAnswerMapper mapper = new NewCheckboxAnswerMapper(); + CheckboxAnswerMapper mapper = new CheckboxAnswerMapper(); // when - NewCheckboxAnswer actual = mapper.mapToAnswer(request); + CheckboxAnswer actual = mapper.mapToAnswer(request); // then assertThat(actual.getQuestionId()).isEqualTo(1L); assertThat(actual.getSelectedOptionIds()) - .extracting(NewCheckboxAnswerSelectedOption::getSelectedOptionId) + .extracting(CheckboxAnswerSelectedOption::getSelectedOptionId) .containsExactly(1L, 2L, 3L); } @@ -34,7 +34,7 @@ class NewCheckboxAnswerMapperTest { ReviewAnswerRequest request = new ReviewAnswerRequest(1L, List.of(1L, 2L, 3L), "text"); // when - NewCheckboxAnswerMapper mapper = new NewCheckboxAnswerMapper(); + CheckboxAnswerMapper mapper = new CheckboxAnswerMapper(); // then assertThatThrownBy(() -> mapper.mapToAnswer(request)) diff --git a/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java index a9237d211..0cdfe0a32 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/ReviewListMapperTest.java @@ -59,16 +59,16 @@ class ReviewListMapperTest { // given - 리뷰 답변 저장 TextAnswer textAnswer = new TextAnswer(question.getId(), "텍스트형 응답"); - Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review3 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review4 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review5 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review6 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review7 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review8 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review9 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); - Review review10 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), List.of()); + Review review1 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review2 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review3 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review4 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review5 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review6 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review7 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review8 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review9 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); + Review review10 = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); reviewRepository.saveAll( List.of(review1, review2, review3, review4, review5, review6, review7, review8, review9, review10)); diff --git a/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java index 8566e8c20..8ca15f312 100644 --- a/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/ReviewMapperTest.java @@ -77,7 +77,7 @@ class ReviewMapperTest { Review review = reviewMapper.mapToReview(reviewRegisterRequest); // then - assertThat(review.getTextAnswers()).hasSize(1); + assertThat(review.getAnswersByType(TextAnswer.class)).hasSize(1); } @Test @@ -102,7 +102,7 @@ class ReviewMapperTest { Review review = reviewMapper.mapToReview(reviewRegisterRequest); // then - assertThat(review.getCheckboxAnswers()).hasSize(1); + assertThat(review.getAnswersByType(CheckboxAnswer.class)).hasSize(1); } @Test @@ -130,13 +130,17 @@ class ReviewMapperTest { String textAnswer = "답".repeat(20); ReviewAnswerRequest requiredTextAnswerRequest = new ReviewAnswerRequest( - requiredTextQuestion.getId(), null, textAnswer); + requiredTextQuestion.getId(), null, textAnswer + ); ReviewAnswerRequest optionalTextAnswerRequest = new ReviewAnswerRequest( - optionalTextQuestion.getId(), null, ""); + optionalTextQuestion.getId(), null, "" + ); ReviewAnswerRequest requiredCheckBoxAnswerRequest = new ReviewAnswerRequest( - requeiredCheckBoxQuestion.getId(), List.of(optionItem1.getId()), null); + requeiredCheckBoxQuestion.getId(), List.of(optionItem1.getId()), null + ); ReviewAnswerRequest optionalCheckBoxAnswerRequest = new ReviewAnswerRequest( - optionalCheckBoxQuestion.getId(), List.of(), null); + optionalCheckBoxQuestion.getId(), List.of(), null + ); ReviewRegisterRequest reviewRegisterRequest = new ReviewRegisterRequest(reviewGroup.getReviewRequestCode(), List.of(requiredTextAnswerRequest, optionalTextAnswerRequest, requiredCheckBoxAnswerRequest, optionalCheckBoxAnswerRequest)); @@ -146,10 +150,10 @@ class ReviewMapperTest { // then assertAll( - () -> assertThat(review.getTextAnswers()) + () -> assertThat(review.getAnswersByType(TextAnswer.class)) .extracting(TextAnswer::getQuestionId) .containsExactly(requiredTextQuestion.getId()), - () -> assertThat(review.getCheckboxAnswers()) + () -> assertThat(review.getAnswersByType(CheckboxAnswer.class)) .extracting(CheckboxAnswer::getQuestionId) .containsExactly(requeiredCheckBoxQuestion.getId()) ); @@ -166,8 +170,7 @@ class ReviewMapperTest { reviewRequestCode, List.of(emptyTextReviewRequest)); // when, then - assertThatThrownBy(() -> reviewMapper.mapToReview( - reviewRegisterRequest)) + assertThatThrownBy(() -> reviewMapper.mapToReview(reviewRegisterRequest)) .isInstanceOf(ReviewGroupNotFoundByReviewRequestCodeException.class); } } diff --git a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapperTest.java b/backend/src/test/java/reviewme/review/service/mapper/TextAnswerMapperTest.java similarity index 79% rename from backend/src/test/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapperTest.java rename to backend/src/test/java/reviewme/review/service/mapper/TextAnswerMapperTest.java index 5feb97e7b..841e2d5a3 100644 --- a/backend/src/test/java/reviewme/review/service/abstraction/mapper/NewTextAnswerMapperTest.java +++ b/backend/src/test/java/reviewme/review/service/mapper/TextAnswerMapperTest.java @@ -1,15 +1,15 @@ -package reviewme.review.service.abstraction.mapper; +package reviewme.review.service.mapper; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.List; import org.junit.jupiter.api.Test; -import reviewme.review.domain.abstraction.NewTextAnswer; +import reviewme.review.domain.TextAnswer; import reviewme.review.service.dto.request.ReviewAnswerRequest; import reviewme.review.service.exception.TextAnswerIncludedOptionItemException; -class NewTextAnswerMapperTest { +class TextAnswerMapperTest { /* TODO: Request를 추상화해야 할까요? @@ -24,8 +24,8 @@ class NewTextAnswerMapperTest { ReviewAnswerRequest request = new ReviewAnswerRequest(1L, null, "text"); // when - NewTextAnswerMapper mapper = new NewTextAnswerMapper(); - NewTextAnswer actual = mapper.mapToAnswer(request); + TextAnswerMapper mapper = new TextAnswerMapper(); + TextAnswer actual = mapper.mapToAnswer(request); // then assertThat(actual.getContent()).isEqualTo("text"); @@ -37,7 +37,7 @@ class NewTextAnswerMapperTest { ReviewAnswerRequest request = new ReviewAnswerRequest(1L, List.of(1L), "text"); // when - NewTextAnswerMapper mapper = new NewTextAnswerMapper(); + TextAnswerMapper mapper = new TextAnswerMapper(); // then assertThatThrownBy(() -> mapper.mapToAnswer(request)) diff --git a/backend/src/test/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactoryTest.java b/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java similarity index 64% rename from backend/src/test/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactoryTest.java rename to backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java index 678526204..0a6e75db5 100644 --- a/backend/src/test/java/reviewme/review/service/abstraction/validator/AnswerValidatorFactoryTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/AnswerValidatorFactoryTest.java @@ -1,20 +1,20 @@ -package reviewme.review.service.abstraction.validator; +package reviewme.review.service.validator; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.List; import org.junit.jupiter.api.Test; -import reviewme.review.domain.abstraction.Answer; -import reviewme.review.domain.abstraction.NewCheckboxAnswer; +import reviewme.review.domain.Answer; +import reviewme.review.domain.CheckboxAnswer; class AnswerValidatorFactoryTest { - private final NewAnswerValidator validator = new NewAnswerValidator() { + private final AnswerValidator validator = new AnswerValidator() { @Override public boolean supports(Class answerClass) { - return answerClass.equals(NewCheckboxAnswer.class); + return answerClass.equals(CheckboxAnswer.class); } @Override @@ -25,11 +25,11 @@ public void validate(Answer answer) { @Test void 지원하는_타입에_따른_밸리데이터를_가져온다() { // given - List validators = List.of(validator); + List validators = List.of(validator); AnswerValidatorFactory factory = new AnswerValidatorFactory(validators); // when - NewAnswerValidator actual = factory.getAnswerValidator(NewCheckboxAnswer.class); + AnswerValidator actual = factory.getAnswerValidator(CheckboxAnswer.class); // then assertThat(actual).isEqualTo(validator); @@ -41,7 +41,7 @@ public void validate(Answer answer) { AnswerValidatorFactory factory = new AnswerValidatorFactory(List.of()); // when, then - assertThatThrownBy(() -> factory.getAnswerValidator(NewCheckboxAnswer.class)) + assertThatThrownBy(() -> factory.getAnswerValidator(CheckboxAnswer.class)) .isInstanceOf(UnsupportedAnswerTypeException.class); } } diff --git a/backend/src/test/java/reviewme/review/service/validator/CheckBoxAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java similarity index 96% rename from backend/src/test/java/reviewme/review/service/validator/CheckBoxAnswerValidatorTest.java rename to backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java index d3aa2798f..5c64c2503 100644 --- a/backend/src/test/java/reviewme/review/service/validator/CheckBoxAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/CheckboxAnswerValidatorTest.java @@ -15,17 +15,17 @@ import reviewme.question.repository.OptionItemRepository; import reviewme.question.repository.QuestionRepository; import reviewme.review.domain.CheckboxAnswer; -import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; import reviewme.review.service.exception.CheckBoxAnswerIncludedNotProvidedOptionItemException; +import reviewme.review.service.exception.OptionGroupNotFoundByQuestionIdException; import reviewme.review.service.exception.SelectedOptionItemCountOutOfRangeException; import reviewme.review.service.exception.SubmittedQuestionNotFoundException; import reviewme.support.ServiceTest; @ServiceTest -class CheckBoxAnswerValidatorTest { +class CheckboxAnswerValidatorTest { @Autowired - private CheckBoxAnswerValidator checkBoxAnswerValidator; + private CheckboxAnswerValidator checkBoxAnswerValidator; @Autowired private QuestionRepository questionRepository; @@ -82,7 +82,8 @@ class CheckBoxAnswerValidatorTest { ); OptionItem savedOptionItem1 = optionItemRepository.save(선택지(savedOptionGroup.getId())); - CheckboxAnswer checkboxAnswer = new CheckboxAnswer(savedQuestion.getId(), List.of(savedOptionItem1.getId())); + CheckboxAnswer checkboxAnswer = new CheckboxAnswer(savedQuestion.getId(), + List.of(savedOptionItem1.getId())); // when, then assertThatCode(() -> checkBoxAnswerValidator.validate(checkboxAnswer)) diff --git a/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java index 9680e8067..dca5dd59d 100644 --- a/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/ReviewValidatorTest.java @@ -12,7 +12,6 @@ import static reviewme.fixture.SectionFixture.항상_보이는_섹션; import static reviewme.fixture.TemplateFixture.템플릿; -import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -107,8 +106,8 @@ class ReviewValidatorTest { // 리뷰 생성 Review review = new Review(template.getId(), reviewGroup.getId(), - List.of(notRequiredTextAnswer, conditionalTextAnswer1), - List.of(alwaysRequiredCheckAnswer, conditionalCheckAnswer1)); + List.of(notRequiredTextAnswer, conditionalTextAnswer1, + alwaysRequiredCheckAnswer, conditionalCheckAnswer1)); // when, then assertThatCode(() -> reviewValidator.validate(review)) @@ -126,7 +125,7 @@ class ReviewValidatorTest { Template template = templateRepository.save(템플릿(List.of(section.getId()))); TextAnswer textAnswer = new TextAnswer(question2.getId(), "답변".repeat(20)); - Review review = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer), new ArrayList<>()); + Review review = new Review(template.getId(), reviewGroup.getId(), List.of(textAnswer)); // when, then assertThatThrownBy(() -> reviewValidator.validate(review)) @@ -145,7 +144,7 @@ class ReviewValidatorTest { Template template = templateRepository.save(템플릿(List.of(section.getId()))); TextAnswer optionalTextAnswer = new TextAnswer(optionalQuestion.getId(), "답변".repeat(20)); - Review review = new Review(template.getId(), reviewGroup.getId(), List.of(optionalTextAnswer), List.of()); + Review review = new Review(template.getId(), reviewGroup.getId(), List.of(optionalTextAnswer)); // when, then assertThatThrownBy(() -> reviewValidator.validate(review)) diff --git a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java index e9a28db91..0e8265bb6 100644 --- a/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/validator/TextAnswerValidatorTest.java @@ -1,7 +1,7 @@ package reviewme.review.service.validator; -import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static reviewme.fixture.QuestionFixture.서술형_옵션_질문; import static reviewme.fixture.QuestionFixture.서술형_필수_질문; @@ -32,7 +32,7 @@ class TextAnswerValidatorTest { TextAnswer textAnswer = new TextAnswer(notSavedQuestionId, "텍스트형 응답"); // when, then - assertThatCode(() -> textAnswerValidator.validate(textAnswer)) + assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) .isInstanceOf(SubmittedQuestionNotFoundException.class); } @@ -69,6 +69,6 @@ class TextAnswerValidatorTest { TextAnswer textAnswer = new TextAnswer(savedQuestion.getId(), content); // when, then - assertThatCode(() -> textAnswerValidator.validate(textAnswer)).doesNotThrowAnyException(); + assertDoesNotThrow(() -> textAnswerValidator.validate(textAnswer)); } }