From bd38615f3fb80c343347821386bd3b05830624e9 Mon Sep 17 00:00:00 2001 From: myqewr Date: Sun, 23 Mar 2025 21:21:23 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20add=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/docs/asciidoc/index.adoc | 25 +++++- .../server/adapter/controller/user/.gitkeep | 0 .../user/EmailDuplicationCheckController.java | 32 ++++++++ .../ftm/server/adapter/dto/response/.gitkeep | 0 .../EmailDuplicationCheckResponse.java | 14 ++++ .../gateway/repository/UserRepository.java | 5 +- .../common/exception/CustomException.java | 5 ++ .../handler/GlobalExceptionHandler.java | 63 +++++++++++++++ .../response/enums/ErrorResponseCode.java | 2 +- .../domain/dto/query/FindByEmailQuery.java | 32 ++++++++ .../domain/dto/vo/EmailDuplicationVo.java | 12 +++ .../com/ftm/server/domain/service/.gitkeep | 0 .../server/domain/service/UserService.java | 20 +++++ .../ftm/server/domain/usecase/user/.gitkeep | 0 .../user/EmailDuplicationCheckUseCase.java | 18 +++++ .../security/SecurityConfig.java | 4 +- src/test/java/com/ftm/server/BaseTest.java | 61 ++++++++++++++ .../user/EmailDuplicationCheckTest.java | 80 +++++++++++++++++++ .../asciidoctor/query-parameters.snippet | 3 +- 20 files changed, 370 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/com/ftm/server/adapter/controller/user/.gitkeep create mode 100644 src/main/java/com/ftm/server/adapter/controller/user/EmailDuplicationCheckController.java delete mode 100644 src/main/java/com/ftm/server/adapter/dto/response/.gitkeep create mode 100644 src/main/java/com/ftm/server/adapter/dto/response/EmailDuplicationCheckResponse.java create mode 100644 src/main/java/com/ftm/server/common/handler/GlobalExceptionHandler.java create mode 100644 src/main/java/com/ftm/server/domain/dto/query/FindByEmailQuery.java create mode 100644 src/main/java/com/ftm/server/domain/dto/vo/EmailDuplicationVo.java delete mode 100644 src/main/java/com/ftm/server/domain/service/.gitkeep create mode 100644 src/main/java/com/ftm/server/domain/service/UserService.java delete mode 100644 src/main/java/com/ftm/server/domain/usecase/user/.gitkeep create mode 100644 src/main/java/com/ftm/server/domain/usecase/user/EmailDuplicationCheckUseCase.java create mode 100644 src/test/java/com/ftm/server/BaseTest.java create mode 100644 src/test/java/com/ftm/server/user/EmailDuplicationCheckTest.java diff --git a/.gitignore b/.gitignore index c279f7e..78e875a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ out/ ### env ### .env +local.env ### sql ### *.sql diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 0010e28..60671a2 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -34,7 +34,7 @@ Content-Type : application/json { "status": "http status" , "code": "custom status code", - "message" : "response message" + "message" : "response message", "data": "data" } ---- @@ -69,7 +69,7 @@ Content-Type: application/json { "status": "CREATED", // 예시 "code": "S002", //예시 - "message" : "resource가 정상적으로 생성되었습니다." + "message" : "resource가 정상적으로 생성되었습니다.", "data": null } ---- @@ -82,7 +82,7 @@ Content-Type: application/json { "status": "OK", //예시 "code": "S001", //예시 - "message" : "요청이 정상적으로 처리되었습니다." + "message" : "요청이 정상적으로 처리되었습니다.", "data": { "id": 123, "name": "example" @@ -99,3 +99,22 @@ Content-Type: application/json | 공통 | 500 | INTERNAL_SERVER_ERROR | E500_001 | 서버 측에서 처리하지 못한 예외가 발생하면 모든 api 요청에 대해 공통적으로 반환됨. |=== +== 회원 + +=== **1. 이메일 중복 확인** + +이메일 중복을 확인하는 api입니다. + +==== Request +include::{snippets}/api/users/email/duplication/1/http-request.adoc[] + +==== Request Query Parameter Fields +include::{snippets}/api/users/email/duplication/1/query-parameters.adoc[] + +==== 성공 Response +include::{snippets}/api/users/email/duplication/1/http-response.adoc[] + +==== Response Body Fields +include::{snippets}/api/users/email/duplication/1/response-fields.adoc[] + +--- diff --git a/src/main/java/com/ftm/server/adapter/controller/user/.gitkeep b/src/main/java/com/ftm/server/adapter/controller/user/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/ftm/server/adapter/controller/user/EmailDuplicationCheckController.java b/src/main/java/com/ftm/server/adapter/controller/user/EmailDuplicationCheckController.java new file mode 100644 index 0000000..039415c --- /dev/null +++ b/src/main/java/com/ftm/server/adapter/controller/user/EmailDuplicationCheckController.java @@ -0,0 +1,32 @@ +package com.ftm.server.adapter.controller.user; + +import com.ftm.server.adapter.dto.response.EmailDuplicationCheckResponse; +import com.ftm.server.common.response.ApiResponse; +import com.ftm.server.common.response.enums.SuccessResponseCode; +import com.ftm.server.domain.dto.query.FindByEmailQuery; +import com.ftm.server.domain.usecase.user.EmailDuplicationCheckUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class EmailDuplicationCheckController { + + private final EmailDuplicationCheckUseCase emailDuplicationCheckUseCase; + + @GetMapping("api/users/email/duplication") + public ResponseEntity> emailDuplicationCheck( + @RequestParam(value = "email") String email) { + return ResponseEntity.status(HttpStatus.OK) + .body( + ApiResponse.success( + SuccessResponseCode.OK, + EmailDuplicationCheckResponse.from( + emailDuplicationCheckUseCase.emailDuplicationCheck( + FindByEmailQuery.of(email))))); + } +} diff --git a/src/main/java/com/ftm/server/adapter/dto/response/.gitkeep b/src/main/java/com/ftm/server/adapter/dto/response/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/ftm/server/adapter/dto/response/EmailDuplicationCheckResponse.java b/src/main/java/com/ftm/server/adapter/dto/response/EmailDuplicationCheckResponse.java new file mode 100644 index 0000000..3e1463b --- /dev/null +++ b/src/main/java/com/ftm/server/adapter/dto/response/EmailDuplicationCheckResponse.java @@ -0,0 +1,14 @@ +package com.ftm.server.adapter.dto.response; + +import com.ftm.server.domain.dto.vo.EmailDuplicationVo; +import lombok.Data; + +@Data +public class EmailDuplicationCheckResponse { + + private final Boolean isDuplicated; + + public static EmailDuplicationCheckResponse from(EmailDuplicationVo emailDuplicationVo) { + return new EmailDuplicationCheckResponse(emailDuplicationVo.getIsDuplicated()); + } +} diff --git a/src/main/java/com/ftm/server/adapter/gateway/repository/UserRepository.java b/src/main/java/com/ftm/server/adapter/gateway/repository/UserRepository.java index cc58a6c..6ff244b 100644 --- a/src/main/java/com/ftm/server/adapter/gateway/repository/UserRepository.java +++ b/src/main/java/com/ftm/server/adapter/gateway/repository/UserRepository.java @@ -3,4 +3,7 @@ import com.ftm.server.entity.entities.User; import org.springframework.data.jpa.repository.JpaRepository; -public interface UserRepository extends JpaRepository {} +public interface UserRepository extends JpaRepository { + + Boolean existsByEmail(String email); +} diff --git a/src/main/java/com/ftm/server/common/exception/CustomException.java b/src/main/java/com/ftm/server/common/exception/CustomException.java index 796ea57..1478483 100644 --- a/src/main/java/com/ftm/server/common/exception/CustomException.java +++ b/src/main/java/com/ftm/server/common/exception/CustomException.java @@ -8,6 +8,11 @@ public class CustomException extends RuntimeException { private final ErrorResponseCode errorResponseCode; + public CustomException(ErrorResponseCode errorResponseCode, String message) { + super(message); // 예외 메시지 설정 + this.errorResponseCode = errorResponseCode; + } + public CustomException(ErrorResponseCode errorResponseCode) { super(errorResponseCode.getMessage()); // 예외 메시지 설정 this.errorResponseCode = errorResponseCode; diff --git a/src/main/java/com/ftm/server/common/handler/GlobalExceptionHandler.java b/src/main/java/com/ftm/server/common/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..c196d43 --- /dev/null +++ b/src/main/java/com/ftm/server/common/handler/GlobalExceptionHandler.java @@ -0,0 +1,63 @@ +package com.ftm.server.common.handler; + +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.ApiResponse; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import org.springframework.web.multipart.support.MissingServletRequestPartException; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler({CustomException.class}) + public ResponseEntity handleCustomException(CustomException e) { + log.error( + "[{}] code:{} / code message:{}", + e.getErrorResponseCode().name(), + e.getErrorResponseCode().getCode(), + e.getMessage()); + return ResponseEntity.status(e.getErrorResponseCode().getHttpStatus()) + .body(ApiResponse.fail(e.getErrorResponseCode())); + } + + // 기타 처리되지 못한 exception + @ExceptionHandler(Exception.class) + public ResponseEntity handlingException(Exception e) { + + log.error( + "[Exception] code : {} code message : {}", + ErrorResponseCode.UNKNOWN_SERVER_ERROR.getCode(), + e.getMessage()); + return ResponseEntity.status(ErrorResponseCode.UNKNOWN_SERVER_ERROR.getHttpStatus()) + .body(ApiResponse.fail(ErrorResponseCode.UNKNOWN_SERVER_ERROR)); + } + + // request body의 type이 잘못된 경우 + @ExceptionHandler({ + MethodArgumentNotValidException + .class, // json body (requestpart의 body, requestBody의 body)의 필드가 설정한 유효값을 만족시키지 않거나, + // 필수값이 누락됨. + HttpMessageNotReadableException + .class, // json body (requestpart의 body, requestBody의 body)의 필드 type이 잘못됨. + MissingServletRequestPartException.class, // required인 requestpart가 없음. + MissingServletRequestParameterException.class, // requried인 request param이 없음. + MethodArgumentTypeMismatchException.class // request parameter, pathVariable의 type이 잘못됨. + }) + public ResponseEntity handleMissingServletRequestPartException(Exception e) { + + log.error( + "[Exception] code : {} code message : {}", + ErrorResponseCode.INVALID_REQUEST_ARGUMENT.getCode(), + e.getMessage()); + return ResponseEntity.status(ErrorResponseCode.INVALID_REQUEST_ARGUMENT.getHttpStatus()) + .body(ApiResponse.fail(ErrorResponseCode.INVALID_REQUEST_ARGUMENT)); + } +} diff --git a/src/main/java/com/ftm/server/common/response/enums/ErrorResponseCode.java b/src/main/java/com/ftm/server/common/response/enums/ErrorResponseCode.java index 4bf381a..56e0b41 100644 --- a/src/main/java/com/ftm/server/common/response/enums/ErrorResponseCode.java +++ b/src/main/java/com/ftm/server/common/response/enums/ErrorResponseCode.java @@ -8,7 +8,7 @@ public enum ErrorResponseCode { // 400번 INVALID_REQUEST_ARGUMENT( - HttpStatus.BAD_REQUEST, "E400_001", "클라이언트 요청이 잘못된 형식이거나, 필수 데이터가 누락되었습니다."), + HttpStatus.BAD_REQUEST, "E400_001", "클라이언트 요청값의 일부가 잘못된 형식이거나, 필수 데이터가 누락되었습니다."), // 401번 NOT_AUTHENTICATED(HttpStatus.UNAUTHORIZED, "E401_001", "인증되지 않은 사용자입니다."), diff --git a/src/main/java/com/ftm/server/domain/dto/query/FindByEmailQuery.java b/src/main/java/com/ftm/server/domain/dto/query/FindByEmailQuery.java new file mode 100644 index 0000000..2aa433e --- /dev/null +++ b/src/main/java/com/ftm/server/domain/dto/query/FindByEmailQuery.java @@ -0,0 +1,32 @@ +package com.ftm.server.domain.dto.query; + +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import java.util.regex.Pattern; +import lombok.Getter; + +@Getter +public class FindByEmailQuery { + + private static final Pattern EMAIL_PATTERN = + Pattern.compile( + "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); + + private final String email; + + private FindByEmailQuery(String email) { + if (!isValidEmail(email)) { + throw new CustomException( + ErrorResponseCode.INVALID_REQUEST_ARGUMENT, "이메일 형식이 올바르지 않습니다."); + } + this.email = email; + } + + public static FindByEmailQuery of(String email) { + return new FindByEmailQuery(email); + } + + private boolean isValidEmail(String email) { + return EMAIL_PATTERN.matcher(email).matches(); + } +} diff --git a/src/main/java/com/ftm/server/domain/dto/vo/EmailDuplicationVo.java b/src/main/java/com/ftm/server/domain/dto/vo/EmailDuplicationVo.java new file mode 100644 index 0000000..5bae6bc --- /dev/null +++ b/src/main/java/com/ftm/server/domain/dto/vo/EmailDuplicationVo.java @@ -0,0 +1,12 @@ +package com.ftm.server.domain.dto.vo; + +import lombok.Data; + +@Data +public class EmailDuplicationVo { + private final Boolean isDuplicated; + + public static EmailDuplicationVo of(Boolean isDuplicated) { + return new EmailDuplicationVo(isDuplicated); + } +} diff --git a/src/main/java/com/ftm/server/domain/service/.gitkeep b/src/main/java/com/ftm/server/domain/service/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/ftm/server/domain/service/UserService.java b/src/main/java/com/ftm/server/domain/service/UserService.java new file mode 100644 index 0000000..d4c61cf --- /dev/null +++ b/src/main/java/com/ftm/server/domain/service/UserService.java @@ -0,0 +1,20 @@ +package com.ftm.server.domain.service; + +import com.ftm.server.adapter.gateway.repository.UserRepository; +import com.ftm.server.domain.dto.query.FindByEmailQuery; +import com.ftm.server.domain.dto.vo.EmailDuplicationVo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class UserService { + + private final UserRepository userRepository; + + public EmailDuplicationVo isEmailDuplicated(FindByEmailQuery query) { + return EmailDuplicationVo.of(userRepository.existsByEmail(query.getEmail())); + } +} diff --git a/src/main/java/com/ftm/server/domain/usecase/user/.gitkeep b/src/main/java/com/ftm/server/domain/usecase/user/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/com/ftm/server/domain/usecase/user/EmailDuplicationCheckUseCase.java b/src/main/java/com/ftm/server/domain/usecase/user/EmailDuplicationCheckUseCase.java new file mode 100644 index 0000000..b0dc130 --- /dev/null +++ b/src/main/java/com/ftm/server/domain/usecase/user/EmailDuplicationCheckUseCase.java @@ -0,0 +1,18 @@ +package com.ftm.server.domain.usecase.user; + +import com.ftm.server.common.annotation.UseCase; +import com.ftm.server.domain.dto.query.FindByEmailQuery; +import com.ftm.server.domain.dto.vo.EmailDuplicationVo; +import com.ftm.server.domain.service.UserService; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class EmailDuplicationCheckUseCase { + + private final UserService userService; + + public EmailDuplicationVo emailDuplicationCheck(FindByEmailQuery query) { + return userService.isEmailDuplicated(query); + } +} diff --git a/src/main/java/com/ftm/server/infrastructure/security/SecurityConfig.java b/src/main/java/com/ftm/server/infrastructure/security/SecurityConfig.java index 4a01ff4..ac4c2c3 100644 --- a/src/main/java/com/ftm/server/infrastructure/security/SecurityConfig.java +++ b/src/main/java/com/ftm/server/infrastructure/security/SecurityConfig.java @@ -41,6 +41,8 @@ public class SecurityConfig { "https://dev-api.fittheman.site", // 개발 환경 서버 도메인 "https://fittheman.site"); // 개발 환경 클라이언트 도메인 + private static final String[] ANONYMOUS_MATCHERS = {"/docs/**", "/api/users/email/duplication"}; + @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http @@ -74,7 +76,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti authorize -> { authorize // 정적 리소스 경로 허용 - .requestMatchers("/docs/**") + .requestMatchers(ANONYMOUS_MATCHERS) .permitAll(); // TODO: 요청 허용 특정 API 추가 (회원가입, 로그인 등) diff --git a/src/test/java/com/ftm/server/BaseTest.java b/src/test/java/com/ftm/server/BaseTest.java new file mode 100644 index 0000000..127a629 --- /dev/null +++ b/src/test/java/com/ftm/server/BaseTest.java @@ -0,0 +1,61 @@ +package com.ftm.server; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; +import groovy.util.logging.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@Slf4j +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@SpringBootTest(classes = {ServerApplication.class}) +@ActiveProfiles("test") +@ExtendWith({RestDocumentationExtension.class}) +@AutoConfigureTestDatabase( + replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 +@TestPropertySource(locations = "file:.env") +public class BaseTest { + + @Autowired protected MockMvc mockMvc; + + protected final ObjectMapper mapper = new ObjectMapper(); + + @BeforeEach + void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { + this.mockMvc = + MockMvcBuilders.webAppContextSetup(context) + .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 + .apply(documentationConfiguration(restDocumentation)) + .build(); + } + + // 블필요한 header 제거 함수 + protected HeadersModifyingOperationPreprocessor getModifiedHeader() { + return modifyHeaders() + .remove("X-Content-Type-Options") + .remove("X-XSS-Protection") + .remove("Cache-Control") + .remove("Pragma") + .remove("Expires") + .remove("Content-Length") + .remove("X-Frame-Options") + .remove("Vary"); + } +} diff --git a/src/test/java/com/ftm/server/user/EmailDuplicationCheckTest.java b/src/test/java/com/ftm/server/user/EmailDuplicationCheckTest.java new file mode 100644 index 0000000..f3db733 --- /dev/null +++ b/src/test/java/com/ftm/server/user/EmailDuplicationCheckTest.java @@ -0,0 +1,80 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import jakarta.transaction.Transactional; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.restdocs.request.ParameterDescriptor; +import org.springframework.restdocs.snippet.Attributes; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailDuplicationCheckTest extends BaseTest { + + private final List queryParametersForEmail = + List.of( + parameterWithName("email") + .description("중복 확인 email") + .attributes(new Attributes.Attribute("constraint", "email 형식"))); + + private final List responseFieldDescriptorsForEmailDuplicationCheck = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isDuplicated").type("Boolean").description("중복 여부")); + + private ResultActions getResultActions(String email) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.get("/api/users/email/duplication") + .param("email", email) // query parameter + ); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "api/users/email/duplication/" + identifier, + preprocessRequest(prettyPrint()), // request 출력 형식 지정->host 이름 변경 + preprocessResponse(prettyPrint(), getModifiedHeader()), // response 출력 형식 지정 + responseFields( + responseFieldDescriptorsForEmailDuplicationCheck), // response body field + // descriptor + queryParameters(queryParametersForEmail), // query parameter descriptor + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 중복 확인 api") + .description("email 중복 확인 api입니다.") + .build())); + } + + @Test + @Transactional + void 이메일_중복_확인_성공1() throws Exception { + // given + + // when + ResultActions resultActions = getResultActions("test@gmail.com"); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } +} diff --git a/src/test/resources/org/springframework/restdocs/templates/asciidoctor/query-parameters.snippet b/src/test/resources/org/springframework/restdocs/templates/asciidoctor/query-parameters.snippet index b8ad7e5..8e24201 100644 --- a/src/test/resources/org/springframework/restdocs/templates/asciidoctor/query-parameters.snippet +++ b/src/test/resources/org/springframework/restdocs/templates/asciidoctor/query-parameters.snippet @@ -1,9 +1,10 @@ |=== -|Parameter|Description|Required|Default +|Parameter|Description|Constraint|Required|Default {{#parameters}} |{{#tableCellContent}}`+{{name}}+`{{/tableCellContent}} |{{#tableCellContent}}{{description}}{{/tableCellContent}} + |{{#tableCellContent}}{{#constraint}}{{constraint}}{{/constraint}}{{^constraint}} {{/constraint}}{{/tableCellContent}} |{{#tableCellContent}}{{#optional}}false{{/optional}}{{^optional}}true{{/optional}}{{/tableCellContent}} |{{#tableCellContent}}{{#default}}{{default}}{{/default}}{{^default}} {{/default}}{{/tableCellContent}}