diff --git a/backend/src/main/java/reviewme/review/domain/exception/InvalidTextAnswerLengthException.java b/backend/src/main/java/reviewme/review/domain/exception/InvalidTextAnswerLengthException.java index 236531179..75d0c36e4 100644 --- a/backend/src/main/java/reviewme/review/domain/exception/InvalidTextAnswerLengthException.java +++ b/backend/src/main/java/reviewme/review/domain/exception/InvalidTextAnswerLengthException.java @@ -6,9 +6,13 @@ @Slf4j public class InvalidTextAnswerLengthException extends BadRequestException { - public InvalidTextAnswerLengthException(int answerLength, int minLength, int maxLength) { + public InvalidTextAnswerLengthException(long questionId, int answerLength, int minLength, int maxLength) { super("답변의 길이는 %d자 이상 %d자 이하여야 해요.".formatted(minLength, maxLength)); - log.warn("AnswerLength is out of bound - answerLength: {}, minLength: {}, maxLength: {}", - answerLength, minLength, maxLength, this); + log.warn("AnswerLength is out of bound - questionId: {}, answerLength: {}, minLength: {}, maxLength: {}", + questionId, answerLength, minLength, maxLength, this); + } + + public InvalidTextAnswerLengthException(long questionId, int answerLength, int maxLength) { + this(questionId, answerLength, 0, maxLength); } } diff --git a/backend/src/main/java/reviewme/review/service/module/TextAnswerValidator.java b/backend/src/main/java/reviewme/review/service/module/TextAnswerValidator.java index 5e22c00ff..0d1c50de4 100644 --- a/backend/src/main/java/reviewme/review/service/module/TextAnswerValidator.java +++ b/backend/src/main/java/reviewme/review/service/module/TextAnswerValidator.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import reviewme.question.domain.Question; import reviewme.question.repository.QuestionRepository; import reviewme.review.domain.TextAnswer; import reviewme.review.domain.exception.InvalidTextAnswerLengthException; @@ -11,26 +12,28 @@ @RequiredArgsConstructor public class TextAnswerValidator { + 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) { - validateExistQuestion(textAnswer); - validateLength(textAnswer); - } + Question question = questionRepository.findById(textAnswer.getQuestionId()) + .orElseThrow(() -> new SubmittedQuestionNotFoundException(textAnswer.getQuestionId())); - private void validateExistQuestion(TextAnswer textAnswer) { - if (!questionRepository.existsById(textAnswer.getQuestionId())) { - throw new SubmittedQuestionNotFoundException(textAnswer.getQuestionId()); - } + validateLength(textAnswer, question); } - private void validateLength(TextAnswer textAnswer) { + private void validateLength(TextAnswer textAnswer, Question question) { int answerLength = textAnswer.getContent().length(); - if (answerLength < MIN_LENGTH || answerLength > MAX_LENGTH) { - throw new InvalidTextAnswerLengthException(answerLength, MIN_LENGTH, MAX_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/test/java/reviewme/review/service/module/TextAnswerValidatorTest.java b/backend/src/test/java/reviewme/review/service/module/TextAnswerValidatorTest.java index 6f365a37d..9ffcef873 100644 --- a/backend/src/test/java/reviewme/review/service/module/TextAnswerValidatorTest.java +++ b/backend/src/test/java/reviewme/review/service/module/TextAnswerValidatorTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static reviewme.fixture.QuestionFixture.서술형_옵션_질문; import static reviewme.fixture.QuestionFixture.서술형_필수_질문; import org.junit.jupiter.api.Test; @@ -37,7 +38,7 @@ class TextAnswerValidatorTest { @ParameterizedTest @ValueSource(ints = {19, 10001}) - void 답변_길이가_유효하지_않으면_예외가_발생한다(int length) { + void 필수_질문의_답변_길이가_유효하지_않으면_예외가_발생한다(int length) { // given String content = "답".repeat(length); Question savedQuestion = questionRepository.save(서술형_필수_질문()); @@ -47,4 +48,27 @@ class TextAnswerValidatorTest { assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) .isInstanceOf(InvalidTextAnswerLengthException.class); } + + @Test + void 선택_질문의_답변_길이가_유효하지_않으면_예외가_발생한다() { + // given + String content = "답".repeat(10001); + Question savedQuestion = questionRepository.save(서술형_옵션_질문()); + TextAnswer textAnswer = new TextAnswer(savedQuestion.getId(), content); + + // when, then + assertThatThrownBy(() -> textAnswerValidator.validate(textAnswer)) + .isInstanceOf(InvalidTextAnswerLengthException.class); + } + + @Test + void 선택_질문은_최소_글자수_제한을_받지_않는다() { + // given + String content = "답".repeat(1); + Question savedQuestion = questionRepository.save(서술형_옵션_질문()); + TextAnswer textAnswer = new TextAnswer(savedQuestion.getId(), content); + + // when, then + assertThatCode(() -> textAnswerValidator.validate(textAnswer)).doesNotThrowAnyException(); + } }