From 7bb89f73398d1203ca3783d0f16e2dff6b34620b Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 19:00:30 +0900 Subject: [PATCH 1/6] =?UTF-8?q?perf:=20Survey.targetId=EC=97=90=20unique?= =?UTF-8?q?=20index=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/db/migration/v11_survey_unique_index_target.sql | 1 + .../src/main/java/me/nalab/core/data/survey/SurveyEntity.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 api/src/main/resources/db/migration/v11_survey_unique_index_target.sql 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){ From 5fc2e0453ce46a7f6dea692cab79acecb7e3c15f Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 19:59:12 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20Survey=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20survey=EA=B0=80=20=EC=9E=88=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=8D=98=EC=A7=84=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/DuplicateSurveyException.java | 8 ++++++++ .../service/create/SurveyCreateService.java | 12 +++++++++--- .../service/create/SurveyCreateServiceTest.java | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 survey/survey-application/src/main/java/me/nalab/survey/application/exception/DuplicateSurveyException.java 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..1181d9e3 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,15 @@ 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.port.out.persistence.existsurvey.SurveyExistPort; +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 +46,15 @@ class SurveyCreateServiceTest { @MockBean private TargetExistCheckPort findTargetPort; + @MockBean + private SurveyExistPort surveyExistPort; + + @BeforeEach + void mockingSurveyExistPort() { + when(surveyExistPort.isSurveyExistByTargetId(anyLong())).thenReturn(false); + } + + @ParameterizedTest @MethodSource("surveyDtoLargeNullIdSources") void CREATE_NEW_SURVEY_SUCCESS(SurveyDto surveyDto) { From 3200ead40c5a4791f28e76284f946ed0b2aa5417 Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 20:01:16 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20DuplicateSurveyException=20?= =?UTF-8?q?=ED=95=B8=EB=93=A4=EB=9F=AC=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../survey/web/adaptor/advice/SurveyControllerAdvice.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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()); + } + } From 48ea22e898e1296f02b9956abf8a2e8c30bd2dc8 Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 21:37:34 +0900 Subject: [PATCH 4/6] =?UTF-8?q?test:=20Survey=EA=B0=80=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=93=B1=EB=A1=9D=EB=90=98=EC=97=88=EC=9D=84=EB=95=8C?= =?UTF-8?q?,=20=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=8D=98=EC=A7=80=EB=8A=94?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../create/SurveyCreateServiceTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 1181d9e3..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 @@ -9,7 +9,9 @@ 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; @@ -54,6 +56,24 @@ 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") From 9967ab158f6ced6949e4c8546a6749f96e522e2b Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 21:39:30 +0900 Subject: [PATCH 5/6] =?UTF-8?q?test:=20hurl=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9C=A0=EC=A0=80=EA=B0=80=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=90=98=EC=96=B4=EC=84=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EA=B0=80=20=EC=8B=A4=ED=8C=A8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=EB=A5=BC=20=EC=88=98=EC=A0=95=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support/e2e/v1_2_feedback_create.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 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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_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 From b6da2d089d1fcc281dd8aad31a77c209c0585e57 Mon Sep 17 00:00:00 2001 From: devxb Date: Wed, 6 Mar 2024 21:45:33 +0900 Subject: [PATCH 6/6] =?UTF-8?q?test:=20hurl=20feedback=5Ffind.hurl?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EC=9D=B4=20=EA=B2=B9?= =?UTF-8?q?=EC=B9=98=EB=8A=94=20=EB=B2=84=EA=B7=B8=EB=A5=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support/e2e/v1_3_feedback_find.hurl | 2 +- support/e2e/v2_3_feedback_find.hurl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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