148 lines
5.3 KiB
Kotlin

package roomescape.auth.web
import com.ninjasquad.springmockk.SpykBean
import io.mockk.every
import org.hamcrest.Matchers.equalTo
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.data.repository.findByIdOrNull
import org.springframework.test.web.servlet.MockMvc
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.service.AuthService
import roomescape.common.exception.CommonErrorCode
import roomescape.common.exception.ErrorCode
import roomescape.util.MemberFixture
import roomescape.util.RoomescapeApiTest
@WebMvcTest(controllers = [AuthController::class])
class AuthControllerTest(
val mockMvc: MockMvc
) : RoomescapeApiTest() {
@SpykBean
private lateinit var authService: AuthService
val userRequest: LoginRequest = MemberFixture.userLoginRequest()
init {
Given("로그인 요청을 보낼 때") {
val endpoint = "/login"
When("로그인에 성공하면") {
val expectedToken = "expectedToken"
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns user
every {
jwtHandler.createToken(user.id!!)
} returns expectedToken
Then("토큰을 반환한다.") {
runPostTest(
mockMvc = mockMvc,
endpoint = endpoint,
body = userRequest,
) {
status { isOk() }
jsonPath("$.data.accessToken", equalTo(expectedToken))
}
}
}
When("회원을 찾지 못하면") {
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns null
Then("에러 응답을 받는다.") {
val expectedError = AuthErrorCode.LOGIN_FAILED
runPostTest(
mockMvc = mockMvc,
endpoint = endpoint,
body = userRequest,
) {
status { isEqualTo(expectedError.httpStatus.value()) }
jsonPath("$.code", equalTo(expectedError.errorCode))
}
}
}
When("입력 값이 잘못되면") {
val expectedErrorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE
Then("400 에러를 응답한다") {
listOf(
userRequest.copy(email = "invalid"),
userRequest.copy(password = " "),
"{\"email\": \"null\", \"password\": \"null\"}"
).forEach {
runPostTest(
mockMvc = mockMvc,
endpoint = endpoint,
body = it,
) {
status { isEqualTo(expectedErrorCode.httpStatus.value()) }
jsonPath("$.code", equalTo(expectedErrorCode.errorCode))
}
}
}
}
}
Given("로그인 상태를 확인할 때") {
val endpoint = "/login/check"
When("로그인된 회원의 ID로 요청하면") {
loginAsUser()
Then("회원의 이름과 권한을 응답한다") {
runGetTest(
mockMvc = mockMvc,
endpoint = endpoint,
) {
status { isOk() }
jsonPath("$.data.name", equalTo(user.name))
jsonPath("$.data.role", equalTo(user.role.name))
}
}
}
When("토큰은 있지만 회원을 찾을 수 없으면") {
val invalidMemberId: Long = -1L
every { jwtHandler.getMemberIdFromToken(any()) } returns invalidMemberId
every { memberRepository.findByIdOrNull(invalidMemberId) } returns null
Then("에러 응답을 받는다.") {
val expectedError = AuthErrorCode.UNIDENTIFIABLE_MEMBER
runGetTest(
mockMvc = mockMvc,
endpoint = endpoint,
) {
status { isEqualTo(expectedError.httpStatus.value()) }
jsonPath("$.code", equalTo(expectedError.errorCode))
}
}
}
}
Given("로그아웃 요청을 보낼 때") {
val endpoint = "/logout"
When("토큰으로 memberId 조회가 가능하면") {
every {
jwtHandler.getMemberIdFromToken(any())
} returns 1L
Then("정상 응답한다.") {
runPostTest(
mockMvc = mockMvc,
endpoint = endpoint,
) {
status { isNoContent() }
}
}
}
}
}
}