generated from pricelees/issue-pr-template
[#5]: 공통 기능 코틀린 마이그레이션 및 패키지 분리 #6
@ -0,0 +1,33 @@
|
|||||||
|
package roomescape.common.dto.response
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude
|
||||||
|
import roomescape.common.exception.ErrorType
|
||||||
|
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
data class RoomescapeApiResponseKT<T>(
|
||||||
|
val success: Boolean,
|
||||||
|
val data: T? = null,
|
||||||
|
val errorType: ErrorType? = null,
|
||||||
|
val message: String? = null,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun <T> success(data: T? = null): RoomescapeApiResponseKT<T> {
|
||||||
|
return RoomescapeApiResponseKT(
|
||||||
|
success = true,
|
||||||
|
data = data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun <T> fail(errorType: ErrorType, message: String? = null): RoomescapeApiResponseKT<T> {
|
||||||
|
return RoomescapeApiResponseKT(
|
||||||
|
success = false,
|
||||||
|
errorType = errorType,
|
||||||
|
message = message ?: errorType.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,10 @@
|
|||||||
package roomescape.common.exception;
|
package roomescape.common.exception;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
public enum ErrorType {
|
public enum ErrorType {
|
||||||
|
|
||||||
// 400 Bad Request
|
// 400 Bad Request
|
||||||
@ -58,4 +63,12 @@ public enum ErrorType {
|
|||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static ErrorType from(@JsonProperty("errorType") String errorType) {
|
||||||
|
return Arrays.stream(ErrorType.values())
|
||||||
|
.filter(type -> type.name().equalsIgnoreCase(errorType))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Invalid error type: " + errorType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,158 @@
|
|||||||
|
package roomescape.common.dto.response
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.ninjasquad.springmockk.MockkBean
|
||||||
|
import com.ninjasquad.springmockk.SpykBean
|
||||||
|
import io.kotest.core.spec.style.BehaviorSpec
|
||||||
|
import org.hamcrest.CoreMatchers.equalTo
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
|
import org.springframework.test.web.servlet.get
|
||||||
|
import org.springframework.test.web.servlet.post
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import roomescape.auth.infrastructure.jwt.JwtHandler
|
||||||
|
import roomescape.auth.web.support.AdminInterceptor
|
||||||
|
import roomescape.auth.web.support.LoginInterceptor
|
||||||
|
import roomescape.auth.web.support.MemberIdResolver
|
||||||
|
import roomescape.common.exception.ErrorType
|
||||||
|
import roomescape.member.business.MemberService
|
||||||
|
import roomescape.member.infrastructure.persistence.MemberRepository
|
||||||
|
|
||||||
|
@WebMvcTest(ApiResponseTestController::class)
|
||||||
|
class RoomescapeApiResponseKTTest(
|
||||||
|
@Autowired private val mockMvc: MockMvc
|
||||||
|
) : BehaviorSpec() {
|
||||||
|
@Autowired
|
||||||
|
private lateinit var AdminInterceptor: AdminInterceptor
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var loginInterceptor: LoginInterceptor
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var memberIdResolver: MemberIdResolver
|
||||||
|
|
||||||
|
@SpykBean
|
||||||
|
private lateinit var memberService: MemberService
|
||||||
|
|
||||||
|
@MockkBean
|
||||||
|
private lateinit var memberRepository: MemberRepository
|
||||||
|
|
||||||
|
@MockkBean
|
||||||
|
private lateinit var jwtHandler: JwtHandler
|
||||||
|
|
||||||
|
init {
|
||||||
|
Given("성공 응답에") {
|
||||||
|
val endpoint = "/success"
|
||||||
|
When("객체 데이터를 담으면") {
|
||||||
|
val id: Long = 1L
|
||||||
|
val name = "name"
|
||||||
|
Then("success=true, data={객체} 형태로 응답한다.") {
|
||||||
|
mockMvc.post("$endpoint/$id/$name") {
|
||||||
|
contentType = MediaType.APPLICATION_JSON
|
||||||
|
}.andDo {
|
||||||
|
print()
|
||||||
|
}.andExpect {
|
||||||
|
status { isOk() }
|
||||||
|
jsonPath("$.success", equalTo(true))
|
||||||
|
jsonPath("$.data.id", equalTo(id.toInt()))
|
||||||
|
jsonPath("$.data.name", equalTo(name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
When("문자열 데이터를 담으면") {
|
||||||
|
val message: String = "Hello, World!"
|
||||||
|
|
||||||
|
Then("success=true, data={문자열} 형태로 응답한다.") {
|
||||||
|
mockMvc.get("/success/$message") {
|
||||||
|
contentType = MediaType.APPLICATION_JSON
|
||||||
|
}.andDo {
|
||||||
|
print()
|
||||||
|
}.andExpect {
|
||||||
|
status { isOk() }
|
||||||
|
jsonPath("$.success", equalTo(true))
|
||||||
|
jsonPath("$.data", equalTo(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Given("실패 응답에") {
|
||||||
|
val endpoint = "/fail"
|
||||||
|
val objectMapper = ObjectMapper()
|
||||||
|
|
||||||
|
When("errorType만 담으면") {
|
||||||
|
Then("success=false, errorType={errorType}, message={errorType.description} 형태로 응답한다.") {
|
||||||
|
mockMvc.post(endpoint) {
|
||||||
|
contentType = MediaType.APPLICATION_JSON
|
||||||
|
content = objectMapper.writeValueAsString(FailRequest(errorType = ErrorType.INTERNAL_SERVER_ERROR))
|
||||||
|
}.andDo {
|
||||||
|
print()
|
||||||
|
}.andExpect {
|
||||||
|
status { isOk() }
|
||||||
|
jsonPath("$.success", equalTo(false))
|
||||||
|
jsonPath("$.errorType", equalTo(ErrorType.INTERNAL_SERVER_ERROR.name))
|
||||||
|
jsonPath("$.message", equalTo(ErrorType.INTERNAL_SERVER_ERROR.description))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
When("errorType과 message를 담으면") {
|
||||||
|
val message: String = "An error occurred"
|
||||||
|
|
||||||
|
Then("success=false, errorType={errorType}, message={message} 형태로 응답한다.") {
|
||||||
|
mockMvc.post(endpoint) {
|
||||||
|
contentType = MediaType.APPLICATION_JSON
|
||||||
|
content = objectMapper.writeValueAsString(FailRequest(errorType = ErrorType.INTERNAL_SERVER_ERROR, message = message))
|
||||||
|
}.andDo {
|
||||||
|
print()
|
||||||
|
}.andExpect {
|
||||||
|
status { isOk() }
|
||||||
|
jsonPath("$.success", equalTo(false))
|
||||||
|
jsonPath("$.errorType", equalTo(ErrorType.INTERNAL_SERVER_ERROR.name))
|
||||||
|
jsonPath("$.message", equalTo(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class SuccessResponse(
|
||||||
|
val id: Long,
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class FailRequest(
|
||||||
|
val errorType: ErrorType,
|
||||||
|
val message: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
class ApiResponseTestController {
|
||||||
|
|
||||||
|
@GetMapping("/success/{message}")
|
||||||
|
fun succeedToGet(
|
||||||
|
@PathVariable message: String,
|
||||||
|
): RoomescapeApiResponseKT<String> =
|
||||||
|
RoomescapeApiResponseKT.success(message)
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/success/{id}/{name}")
|
||||||
|
fun succeedToPost(
|
||||||
|
@PathVariable id: Long,
|
||||||
|
@PathVariable name: String,
|
||||||
|
): RoomescapeApiResponseKT<SuccessResponse> =
|
||||||
|
RoomescapeApiResponseKT.success(SuccessResponse(id, name))
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/fail")
|
||||||
|
fun fail(
|
||||||
|
@RequestBody request: FailRequest
|
||||||
|
): RoomescapeApiResponseKT<Unit> =
|
||||||
|
request.message?.let {
|
||||||
|
RoomescapeApiResponseKT.fail(request.errorType, it)
|
||||||
|
} ?: RoomescapeApiResponseKT.fail(request.errorType)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user