Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release]: 중복 survey생성을 막는다 #386

Merged
merged 6 commits into from
Mar 6, 2024
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create unique index survey_idx_target_id on survey(target_id)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class SurveyEntity extends TimeBaseEntity {
@OneToMany(mappedBy = "survey", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<FormQuestionEntity> formQuestionableList;

@JoinColumn(name = "target_id", nullable = false)
@JoinColumn(name = "target_id", nullable = false, unique = true)
private Long targetId;

SurveyEntity(SurveyEntityBuilder<?, ?> surveyEntityBuilder){
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v1_2_feedback_create.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v1_3_feedback_find.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v1_4_bookmark.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v1_6_find_gallery_preview.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v1_7_bookmark_survey.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion support/e2e/v2_3_feedback_find.hurl
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package me.nalab.survey.application.exception;

public class DuplicateSurveyException extends RuntimeException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

에러 공통 있으면 그쪽에 제네릭으로 만들어도 될듯?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 이해가 안되는데, 좀 더 설명 plz

Copy link
Member

@dojinyou dojinyou Mar 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DuplicationException<Survey>(message) 이런 느낌으로 쓰면 좋겠다?


public DuplicateSurveyException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
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;

@Override
@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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -43,6 +48,33 @@ class SurveyCreateServiceTest {
@MockBean
private TargetExistCheckPort findTargetPort;

@MockBean
private SurveyExistPort surveyExistPort;
dojinyou marked this conversation as resolved.
Show resolved Hide resolved

@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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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());
}

}
Loading