From e607a3883b89e8e8b5f584966633764925ecbe03 Mon Sep 17 00:00:00 2001 From: xb205 <62425964+devxb@users.noreply.github.com> Date: Wed, 6 Mar 2024 23:26:26 +0900 Subject: [PATCH] =?UTF-8?q?[release]:=20=EC=A4=91=EB=B3=B5=20survey?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9D=84=20=EB=A7=89=EB=8A=94=EB=8B=A4=20(#3?= =?UTF-8?q?86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v11_survey_unique_index_target.sql | 1 + .../nalab/core/data/survey/SurveyEntity.java | 2 +- support/e2e/v1_2_feedback_create.hurl | 2 +- support/e2e/v1_3_feedback_find.hurl | 2 +- support/e2e/v1_4_bookmark.hurl | 2 +- support/e2e/v1_6_find_gallery_preview.hurl | 2 +- support/e2e/v1_7_bookmark_survey.hurl | 2 +- support/e2e/v2_3_feedback_find.hurl | 2 +- .../exception/DuplicateSurveyException.java | 8 +++++ .../service/create/SurveyCreateService.java | 12 +++++-- .../create/SurveyCreateServiceTest.java | 32 +++++++++++++++++++ .../advice/SurveyControllerAdvice.java | 8 ++++- 12 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 api/src/main/resources/db/migration/v11_survey_unique_index_target.sql create mode 100644 survey/survey-application/src/main/java/me/nalab/survey/application/exception/DuplicateSurveyException.java diff --git a/api/src/main/resources/db/migration/v11_survey_unique_index_target.sql b/api/src/main/resources/db/migration/v11_survey_unique_index_target.sql new file mode 100644 index 00000000..5b5d8d12 --- /dev/null +++ b/api/src/main/resources/db/migration/v11_survey_unique_index_target.sql @@ -0,0 +1 @@ +create unique index survey_idx_target_id on survey(target_id) diff --git a/core/data/src/main/java/me/nalab/core/data/survey/SurveyEntity.java b/core/data/src/main/java/me/nalab/core/data/survey/SurveyEntity.java index c67b1aa0..b2c902d4 100644 --- a/core/data/src/main/java/me/nalab/core/data/survey/SurveyEntity.java +++ b/core/data/src/main/java/me/nalab/core/data/survey/SurveyEntity.java @@ -32,7 +32,7 @@ public class SurveyEntity extends TimeBaseEntity { @OneToMany(mappedBy = "survey", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List formQuestionableList; - @JoinColumn(name = "target_id", nullable = false) + @JoinColumn(name = "target_id", nullable = false, unique = true) private Long targetId; SurveyEntity(SurveyEntityBuilder surveyEntityBuilder){ diff --git a/support/e2e/v1_2_feedback_create.hurl b/support/e2e/v1_2_feedback_create.hurl index 7532b5cf..d133129c 100644 --- a/support/e2e/v1_2_feedback_create.hurl +++ b/support/e2e/v1_2_feedback_create.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # Default provider를 통해서 로그인 진행 { "nickname": "devxb", - "email": "hello@12345" + "email": "create_feedback@naver.com" } HTTP 200 diff --git a/support/e2e/v1_3_feedback_find.hurl b/support/e2e/v1_3_feedback_find.hurl index 87352df0..f8acd40f 100644 --- a/support/e2e/v1_3_feedback_find.hurl +++ b/support/e2e/v1_3_feedback_find.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # 로그인 { "nickname" : "luffy", - "email" : "test@gmail.com" + "email" : "feedback_find_1@gmail.com" } HTTP 200 diff --git a/support/e2e/v1_4_bookmark.hurl b/support/e2e/v1_4_bookmark.hurl index 5703918e..6c8bf55f 100644 --- a/support/e2e/v1_4_bookmark.hurl +++ b/support/e2e/v1_4_bookmark.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # Default provider를 통해서 로그인 진행 { "nickname": "devxb", - "email": "hello@12345" + "email": "bookmark@google.com" } HTTP 200 diff --git a/support/e2e/v1_6_find_gallery_preview.hurl b/support/e2e/v1_6_find_gallery_preview.hurl index 1a53bba0..08fa59b5 100644 --- a/support/e2e/v1_6_find_gallery_preview.hurl +++ b/support/e2e/v1_6_find_gallery_preview.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # Default provider를 통해서 로그인 진행 { "nickname": "find_gallery", - "email": "hello@1234567" + "email": "find_gallery_preview@naver.com" } HTTP 200 diff --git a/support/e2e/v1_7_bookmark_survey.hurl b/support/e2e/v1_7_bookmark_survey.hurl index cbd4c7dc..22f20ec8 100644 --- a/support/e2e/v1_7_bookmark_survey.hurl +++ b/support/e2e/v1_7_bookmark_survey.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # Default provider를 통해서 로그인 진행 { "nickname": "bookmark_survey", - "email": "hello@123456" + "email": "bookmark_survey@kakao.com" } HTTP 200 diff --git a/support/e2e/v2_3_feedback_find.hurl b/support/e2e/v2_3_feedback_find.hurl index 363bdda6..54f99f76 100644 --- a/support/e2e/v2_3_feedback_find.hurl +++ b/support/e2e/v2_3_feedback_find.hurl @@ -1,7 +1,7 @@ POST http://nalab-server:8080/v1/oauth/default # 로그인 { "nickname" : "luffy", - "email" : "test@gmail.com" + "email" : "feedback_find_2@gmail.com" } HTTP 200 diff --git a/survey/survey-application/src/main/java/me/nalab/survey/application/exception/DuplicateSurveyException.java b/survey/survey-application/src/main/java/me/nalab/survey/application/exception/DuplicateSurveyException.java new file mode 100644 index 00000000..b34c730d --- /dev/null +++ b/survey/survey-application/src/main/java/me/nalab/survey/application/exception/DuplicateSurveyException.java @@ -0,0 +1,8 @@ +package me.nalab.survey.application.exception; + +public class DuplicateSurveyException extends RuntimeException { + + public DuplicateSurveyException(String message) { + super(message); + } +} diff --git a/survey/survey-application/src/main/java/me/nalab/survey/application/service/create/SurveyCreateService.java b/survey/survey-application/src/main/java/me/nalab/survey/application/service/create/SurveyCreateService.java index a82dc8df..0daeb5b8 100644 --- a/survey/survey-application/src/main/java/me/nalab/survey/application/service/create/SurveyCreateService.java +++ b/survey/survey-application/src/main/java/me/nalab/survey/application/service/create/SurveyCreateService.java @@ -1,23 +1,26 @@ package me.nalab.survey.application.service.create; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - +import java.text.MessageFormat; import lombok.RequiredArgsConstructor; import me.nalab.core.idgenerator.idcore.IdGenerator; import me.nalab.survey.application.common.survey.dto.SurveyDto; import me.nalab.survey.application.common.survey.mapper.SurveyDtoMapper; +import me.nalab.survey.application.exception.DuplicateSurveyException; import me.nalab.survey.application.exception.TargetDoesNotExistException; import me.nalab.survey.application.port.in.web.CreateSurveyUseCase; import me.nalab.survey.application.port.out.persistence.SurveyCreatePort; import me.nalab.survey.application.port.out.persistence.TargetExistCheckPort; +import me.nalab.survey.application.port.out.persistence.existsurvey.SurveyExistPort; import me.nalab.survey.domain.survey.Survey; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor class SurveyCreateService implements CreateSurveyUseCase { private final SurveyCreatePort surveyCreatePort; + private final SurveyExistPort surveyExistPort; private final TargetExistCheckPort targetExistCheckPort; private final IdGenerator idGenerator; @@ -25,6 +28,9 @@ class SurveyCreateService implements CreateSurveyUseCase { @Transactional public void createSurvey(Long targetId, SurveyDto surveyDto) { throwIfDoesNotExistTarget(targetId); + if (surveyExistPort.isSurveyExistByTargetId(targetId)) { + throw new DuplicateSurveyException(MessageFormat.format("이미 Survey를 등록한 Target \"{0}\" 입니다.", targetId)); + } Survey survey = SurveyDtoMapper.toSurvey(surveyDto); survey.withId(idGenerator::generate); surveyCreatePort.createSurvey(targetId, survey); diff --git a/survey/survey-application/src/test/java/me/nalab/survey/application/service/create/SurveyCreateServiceTest.java b/survey/survey-application/src/test/java/me/nalab/survey/application/service/create/SurveyCreateServiceTest.java index 0d17e1a1..eafbf1c8 100644 --- a/survey/survey-application/src/test/java/me/nalab/survey/application/service/create/SurveyCreateServiceTest.java +++ b/survey/survey-application/src/test/java/me/nalab/survey/application/service/create/SurveyCreateServiceTest.java @@ -2,12 +2,17 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; +import me.nalab.survey.application.exception.DuplicateSurveyException; +import me.nalab.survey.application.port.out.persistence.existsurvey.SurveyExistPort; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,6 +48,33 @@ class SurveyCreateServiceTest { @MockBean private TargetExistCheckPort findTargetPort; + @MockBean + private SurveyExistPort surveyExistPort; + + @BeforeEach + void mockingSurveyExistPort() { + when(surveyExistPort.isSurveyExistByTargetId(anyLong())).thenReturn(false); + } + + @Test + @DisplayName("targetId에 해당하는 유저가 survey를 이미 등록했다면, DuplicateSurveyException을 던진다.") + void THROW_DUPLICATE_SURVEY_EXCEPTION_WHEN_SURVEY_WAS_DUPLICATED() { + // given + RandomSurveyDtoFixture.initGenerator(); + var surveyDto = RandomSurveyDtoFixture.createRandomSurveyDto(); + Long targetId = 1L; + + when(findTargetPort.isExistTargetByTargetId(targetId)).thenReturn(true); + when(surveyExistPort.isSurveyExistByTargetId(anyLong())).thenReturn(true); + + // when + var result = Assertions.catchException(() -> createSurveyUseCase.createSurvey(targetId, surveyDto)); + + // then + Assertions.assertThat(result.getClass()).isEqualTo(DuplicateSurveyException.class); + } + + @ParameterizedTest @MethodSource("surveyDtoLargeNullIdSources") void CREATE_NEW_SURVEY_SUCCESS(SurveyDto surveyDto) { diff --git a/survey/survey-web-adaptor/src/main/java/me/nalab/survey/web/adaptor/advice/SurveyControllerAdvice.java b/survey/survey-web-adaptor/src/main/java/me/nalab/survey/web/adaptor/advice/SurveyControllerAdvice.java index 8c0e017e..9df39938 100644 --- a/survey/survey-web-adaptor/src/main/java/me/nalab/survey/web/adaptor/advice/SurveyControllerAdvice.java +++ b/survey/survey-web-adaptor/src/main/java/me/nalab/survey/web/adaptor/advice/SurveyControllerAdvice.java @@ -1,12 +1,12 @@ package me.nalab.survey.web.adaptor.advice; +import me.nalab.survey.application.exception.DuplicateSurveyException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import me.nalab.survey.application.exception.SurveyDoesNotExistException; -import me.nalab.survey.application.exception.SurveyDoesNotHasTargetException; import me.nalab.survey.application.exception.TargetDoesNotExistException; import me.nalab.survey.application.exception.TargetDoesNotHasSurveyException; @@ -32,4 +32,10 @@ ErrorTemplate handleSurveyDoesNotExistException(SurveyDoesNotExistException surv "Cannot found any survey form id \"" + surveyDoesNotExistException.getSurveyId() + "\""); } + @ExceptionHandler(DuplicateSurveyException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorTemplate handleDuplicateSurveyException(DuplicateSurveyException duplicateSurveyException) { + return ErrorTemplate.of(duplicateSurveyException.getMessage()); + } + }