Skip to content

Commit

Permalink
[BE] 특정 사용자의 프로젝트 이름을 중복 사용하지 못하게 수정 (#218) (#235)
Browse files Browse the repository at this point in the history
* feat: 프로젝트 이름 중복 체크 로직 추가

* test: 프로젝트 이름 중복에 대한 테스트 코드 추가

* feat: 프로젝트 이름 중복에 대한 인수 테스트 추가

* refactor: asciidoc 파일명 수정

* refactor: 가독성 좋게 코드 수정
  • Loading branch information
jaeseongDev authored and jujubebat committed Jul 21, 2021
1 parent eba7986 commit 59304b6
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 24 deletions.
34 changes: 18 additions & 16 deletions backend/src/docs/asciidoc/api/v1/projects.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,50 @@

==== Request

include::{snippets}/api/v1/projects/post/1/http-request.adoc[]
include::{snippets}/api/v1/projects/post/1/request-headers.adoc[]
include::{snippets}/api/v1/projects/post/1/request-fields.adoc[]
include::{snippets}/api/v1/projects/post/success-save/http-request.adoc[]
include::{snippets}/api/v1/projects/post/success-save/request-headers.adoc[]
include::{snippets}/api/v1/projects/post/success-save/request-fields.adoc[]

==== Response

include::{snippets}/api/v1/projects/post/1/http-response.adoc[]
include::{snippets}/api/v1/projects/post/1/response-fields.adoc[]
include::{snippets}/api/v1/projects/post/success-save/http-response.adoc[]
include::{snippets}/api/v1/projects/post/success-save/response-fields.adoc[]

==== Header의 Authorization에 값을 안 넣은 경우
include::{snippets}/api/v1/projects/post/2/http-response.adoc[]
include::{snippets}/api/v1/projects/post/fail-jwt/http-response.adoc[]

==== Project의 이름이 중복된 경우
include::{snippets}/api/v1/projects/post/fail-duplicate-name/http-response.adoc[]

=== 전체 조회 (GET /api/v1/projects)

==== Request

include::{snippets}/api/v1/projects/get/1/http-request.adoc[]
include::{snippets}/api/v1/projects/get/1/request-headers.adoc[]
include::{snippets}/api/v1/projects/get/success-findall/http-request.adoc[]
include::{snippets}/api/v1/projects/get/success-findall/request-headers.adoc[]

==== Response

include::{snippets}/api/v1/projects/get/1/http-response.adoc[]
include::{snippets}/api/v1/projects/get/1/response-fields.adoc[]
include::{snippets}/api/v1/projects/get/success-findall/http-response.adoc[]
include::{snippets}/api/v1/projects/get/success-findall/response-fields.adoc[]

==== Header의 Authorization에 값을 안 넣은 경우
include::{snippets}/api/v1/projects/get/2/http-response.adoc[]
include::{snippets}/api/v1/projects/get/fail-jwt/http-response.adoc[]

=== 단일 조회 (GET /api/v1/projects/{id})

==== Request

include::{snippets}/api/v1/projects/{id}/get/1/http-request.adoc[]
include::{snippets}/api/v1/projects/{id}/get/1/request-headers.adoc[]
include::{snippets}/api/v1/projects/{id}/get/success-findone/http-request.adoc[]
include::{snippets}/api/v1/projects/{id}/get/success-findone/request-headers.adoc[]

==== Response

include::{snippets}/api/v1/projects/{id}/get/1/http-response.adoc[]
include::{snippets}/api/v1/projects/{id}/get/1/response-fields.adoc[]
include::{snippets}/api/v1/projects/{id}/get/success-findone/http-response.adoc[]
include::{snippets}/api/v1/projects/{id}/get/success-findone/response-fields.adoc[]

==== Header의 Authorization에 값을 안 넣은 경우
include::{snippets}/api/v1/projects/{id}/get/2/http-response.adoc[]
include::{snippets}/api/v1/projects/{id}/get/fail-jwt/http-response.adoc[]

=== 프로젝트 키로 유저 아이디 조회 (GET /api/v1/projects/user-id)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum ExceptionWithMessageAndCode {
// 프로젝트 관련 : 7xx
NOT_FOUND_PROJECT(new NotFoundException("해당하는 프로젝트가 없습니다.", 700)),
DUPLICATE_PROJECT_SECRET_KEY(new ConflictException("프로젝트의 Secret Key의 중복이 발생했습니다. 다시 프로젝트 생성을 시도해주세요.", 701)),
DUPLICATE_PROJECT_NAME(new ConflictException("동일한 프로젝트 이름이 존재합니다. 다시 프로젝트 생성을 시도해주세요.", 702)),

// 로그인 관련 : 8xx
SHOULD_LOGIN(new UnauthorizedException("로그인을 해야 합니다.", 800)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface ProjectRepository extends JpaRepository<Project, Long> {

Optional<Project> findByIdAndUserId(Long projectId, Long userId);

Optional<Project> findByNameAndUserId(String name, Long userId);

void deleteByIdAndUserId(Long projectId, Long userId);

boolean existsByIdAndUserId(Long projectId, Long userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ProjectService {
private final ProjectRepository projectRepository;

public ProjectResponse save(ProjectCreateRequest projectRequest, User user, SecretKeyFactory secretKeyFactory) {
validateDuplicateProjectName(projectRequest, user);
Project project = Project.builder()
.name(projectRequest.getName())
.secretKeyFactory(secretKeyFactory)
Expand All @@ -39,6 +40,14 @@ public ProjectResponse save(ProjectCreateRequest projectRequest, User user, Secr
return ProjectResponse.from(project);
}

private void validateDuplicateProjectName(ProjectCreateRequest projectRequest, User user) {
Optional<Project> possibleProject = projects
.findByNameAndUserId(projectRequest.getName(), user.getId());
possibleProject.ifPresent(project -> {
throw ExceptionWithMessageAndCode.DUPLICATE_PROJECT_NAME.getException();
});
}

public List<ProjectResponse> findByUserId(Long id) {
return projectRepository.findByUserId(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void setUser() {
public void save() throws Exception {
프로젝트_생성됨()
.andDo(
document("api/v1/projects/post/1",
document("api/v1/projects/post/success-save",
requestHeaders(
headerWithName("Authorization").description("JWT - Bearer 토큰")
),
Expand All @@ -89,7 +89,26 @@ public void save_fail() throws Exception {
.content(asJsonString(new ProjectCreateRequest("프로젝트이름"))))
.andExpect(status().isUnauthorized())
.andDo(
document("api/v1/projects/post/2",
document("api/v1/projects/post/fail-jwt",
responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지"),
fieldWithPath("code").type(JsonFieldType.NUMBER).description("에러 코드")
))
);
}

@Test
@DisplayName("중복되는 프로젝트 이름으로 등록하려고 하면 실패한다.")
public void save_fail_duplicateProjectName() throws Exception {
프로젝트_생성됨();
this.mockMvc.perform(post("/api/v1/projects")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token)
.content(asJsonString(new ProjectCreateRequest("프로젝트이름")))
)
.andExpect(status().isConflict())
.andDo(
document("api/v1/projects/post/fail-duplicate-name",
responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지"),
fieldWithPath("code").type(JsonFieldType.NUMBER).description("에러 코드")
Expand Down Expand Up @@ -122,7 +141,7 @@ public void findAll() throws Exception {
)
.andExpect(status().isOk())
.andDo(
document("api/v1/projects/get/1",
document("api/v1/projects/get/success-findall",
requestHeaders(
headerWithName("Authorization").description("JWT - Bearer 토큰")
),
Expand All @@ -145,7 +164,7 @@ public void findAll_fail() throws Exception {
)
.andExpect(status().isUnauthorized())
.andDo(
document("api/v1/projects/get/2",
document("api/v1/projects/get/fail-jwt",
responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지"),
fieldWithPath("code").type(JsonFieldType.NUMBER).description("에러 코드")
Expand All @@ -166,7 +185,7 @@ public void findOne() throws Exception {
)
.andExpect(status().isOk())
.andDo(
document("api/v1/projects/{id}/get/1",
document("api/v1/projects/{id}/get/success-findone",
requestHeaders(
headerWithName("Authorization").description("JWT - Bearer 토큰")
),
Expand Down Expand Up @@ -194,7 +213,7 @@ public void findOne_fail() throws Exception {
)
.andExpect(status().isUnauthorized())
.andDo(
document("api/v1/projects/{id}/get/2",
document("api/v1/projects/{id}/get/fail-jwt",
responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지"),
fieldWithPath("code").type(JsonFieldType.NUMBER).description("에러 코드")
Expand Down Expand Up @@ -287,6 +306,5 @@ public void findByProjectKey_fail() throws Exception {
)
);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.darass.darass.project.dto.ProjectCreateRequest;
import com.darass.darass.project.dto.ProjectResponse;
import com.darass.darass.project.domain.Project;
import com.darass.darass.project.domain.RandomSecretKeyFactory;
import com.darass.darass.project.repository.ProjectRepository;
import com.darass.darass.user.domain.GuestUser;
import com.darass.darass.user.domain.User;
Expand Down Expand Up @@ -69,6 +70,16 @@ public void save_validateDuplicateSecretKey() {

assertThatThrownBy(() -> {
projectService.save(new ProjectCreateRequest("B 프로젝트"), user, new CustomSecretKeyFactory("abcd"));
}).isInstanceOf(ExceptionWithMessageAndCode.DUPLICATE_PROJECT_SECRET_KEY.getException().getClass());
}).isEqualTo(ExceptionWithMessageAndCode.DUPLICATE_PROJECT_SECRET_KEY.getException());
}

@Test
@DisplayName("중복된 프로젝트 이름으로 생성했을 때, 예외를 터뜨리는 지 체크")
public void save_validateDuplicateProjectName() {
projectService.save(new ProjectCreateRequest("A프로젝트"), user, new RandomSecretKeyFactory());

assertThatThrownBy(() -> {
projectService.save(new ProjectCreateRequest("A프로젝트"), user, new RandomSecretKeyFactory());
}).isEqualTo(ExceptionWithMessageAndCode.DUPLICATE_PROJECT_NAME.getException());
}
}

0 comments on commit 59304b6

Please sign in to comment.