diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/dto/response/QuestionResponse.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/dto/response/QuestionResponse.java index 2a12d0f..1ba2dee 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/dto/response/QuestionResponse.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/dto/response/QuestionResponse.java @@ -6,14 +6,16 @@ public record QuestionResponse( Long questionId, String content, int charLimit, - String answer + String answer, + boolean custom ) { - public static QuestionResponse from(Question question) { + public static QuestionResponse from(Question question, boolean custom) { return new QuestionResponse( question.getId(), question.getContent(), question.getLimit(), - question.getAnswer() + question.getAnswer(), + custom ); } } diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionService.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionService.java index 0bf0cb2..c355f83 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionService.java @@ -136,7 +136,7 @@ private CustomQuestionCandidate saveCustomCandidate( public QuestionSelectionResponse getSelectedQuestions(User user, Long mockApplyId) { MockApply mockApply = getOwnedMockApply(user, mockApplyId); List questions = questionRepository.findAllByMockApplyIdOrderByIdAsc(mockApply.getId()).stream() - .map(QuestionResponse::from) + .map(this::toQuestionResponse) .toList(); return new QuestionSelectionResponse(mockApply.getId(), mockApply.getStatus(), questions); @@ -169,7 +169,7 @@ public QuestionSelectionResponse saveSelectedQuestions( return new QuestionSelectionResponse( mockApply.getId(), mockApply.getStatus(), - savedQuestions.stream().map(QuestionResponse::from).toList() + savedQuestions.stream().map(this::toQuestionResponse).toList() ); } @@ -200,10 +200,14 @@ public QuestionAnswerResponse saveAnswers( mockApply.getId(), mockApply.getStatus(), mockApplyRepository.calculateSequence(mockApply), - questions.stream().map(QuestionResponse::from).toList() + questions.stream().map(this::toQuestionResponse).toList() ); } + private QuestionResponse toQuestionResponse(Question question) { + return QuestionResponse.from(question, isCustomQuestion(question.getContent())); + } + private MockApply getOwnedMockApply(User user, Long mockApplyId) { MockApply mockApply = mockApplyRepository.findById(mockApplyId) .orElseThrow(() -> new GeneralException( @@ -234,10 +238,13 @@ private int resolveCharLimit(Integer charLimit) { return charLimit; } + private boolean isCustomQuestion(String content) { + return DEFAULT_CANDIDATES.stream() + .noneMatch(candidate -> candidate.content().equals(content)); + } + private void validateCustomCandidate(String content) { - boolean existsInDefault = DEFAULT_CANDIDATES.stream() - .anyMatch(candidate -> candidate.content().equals(content)); - if (existsInDefault) { + if (!isCustomQuestion(content)) { throw new GeneralException(GeneralErrorCode.INVALID_PARAMETER, "이미 기본 후보에 존재하는 문항입니다."); } } diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionServiceTest.java index 155ed99..6b75283 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/QuestionServiceTest.java @@ -37,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; @SpringBootTest @ActiveProfiles("test") @@ -73,7 +74,7 @@ void saveSelectedQuestions() { User user = saveUser("question-save@example.com"); MockApply mockApply = saveMockApply(user); QuestionSelectionSaveRequest request = new QuestionSelectionSaveRequest(List.of( - new QuestionSelectionSaveRequest.QuestionItem("지원 동기를 작성해주세요.", 700, false), + new QuestionSelectionSaveRequest.QuestionItem("지원 동기와 입사 후 목표를 작성해주세요.", 700, false), new QuestionSelectionSaveRequest.QuestionItem("직접 추가한 문항입니다.", null, true) )); @@ -82,10 +83,12 @@ void saveSelectedQuestions() { assertThat(response.mockApplyId()).isEqualTo(mockApply.getId()); assertThat(response.status()).isEqualTo(MockApplyStatus.ANSWER_WRITE); assertThat(response.questions()).hasSize(2); - assertThat(response.questions().get(0).content()).isEqualTo("지원 동기를 작성해주세요."); + assertThat(response.questions().get(0).content()).isEqualTo("지원 동기와 입사 후 목표를 작성해주세요."); assertThat(response.questions().get(0).charLimit()).isEqualTo(700); + assertThat(response.questions().get(0).custom()).isFalse(); assertThat(response.questions().get(1).content()).isEqualTo("직접 추가한 문항입니다."); assertThat(response.questions().get(1).charLimit()).isEqualTo(1000); + assertThat(response.questions().get(1).custom()).isTrue(); assertThat(mockApply.getStatus()).isEqualTo(MockApplyStatus.ANSWER_WRITE); assertThat(questionRepository.findAllByMockApplyId(mockApply.getId())).hasSize(2); } @@ -106,11 +109,33 @@ void saveSelectedQuestionsReplacesExistingQuestions() { assertThat(response.questions()).hasSize(1); assertThat(response.questions().get(0).content()).isEqualTo("새 문항"); + assertThat(response.questions().get(0).custom()).isTrue(); assertThat(questionRepository.findAllByMockApplyId(mockApply.getId())) .extracting(Question::getContent) .containsExactly("새 문항"); } + @Test + @DisplayName("선택 문항 조회 시 직접 추가 여부를 함께 반환한다") + void getSelectedQuestionsReturnsCustomFlag() { + User user = saveUser("question-selected-custom-flag@example.com"); + MockApply mockApply = saveMockApply(user); + questionService.saveSelectedQuestions(user, mockApply.getId(), new QuestionSelectionSaveRequest(List.of( + new QuestionSelectionSaveRequest.QuestionItem("지원 동기와 입사 후 목표를 작성해주세요.", 700, false), + new QuestionSelectionSaveRequest.QuestionItem("직접 추가한 문항입니다.", 1000, true) + ))); + + QuestionSelectionResponse response = questionService.getSelectedQuestions(user, mockApply.getId()); + + assertThat(response.questions()).hasSize(2); + assertThat(response.questions()) + .extracting("content", "custom") + .containsExactlyInAnyOrder( + tuple("지원 동기와 입사 후 목표를 작성해주세요.", false), + tuple("직접 추가한 문항입니다.", true) + ); + } + @Test @DisplayName("직접 추가 문항은 선택 문항으로 저장하지 않고 후보 목록에 추가한다") void addCustomQuestionCandidate() {