140 lines
5.1 KiB
Kotlin

package roomescape.system.auth.web
import io.mockk.every
import org.hamcrest.Matchers.containsString
import org.hamcrest.Matchers.`is`
import org.springframework.data.repository.findByIdOrNull
import roomescape.util.MemberFixture
import roomescape.util.RoomescapeApiTest
import roomescape.common.exception.ErrorType
class AuthControllerTest : RoomescapeApiTest() {
val userRequest: LoginRequest = MemberFixture.userLoginRequest()
init {
Given("로그인 요청을 보낼 때") {
val endpoint: String = "/login"
When("로그인에 성공하면") {
val expectedToken: String = "expectedToken"
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns user
every {
jwtHandler.createToken(user.id!!)
} returns expectedToken
Then("토큰을 쿠키에 담아 응답한다") {
runPostTest(endpoint, body = MemberFixture.userLoginRequest()) {
statusCode(200)
cookie("accessToken", expectedToken)
header("Set-Cookie", containsString("Max-Age=1800000"))
header("Set-Cookie", containsString("HttpOnly"))
header("Set-Cookie", containsString("Secure"))
}
}
}
When("회원을 찾지 못하면") {
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns null
Then("400 에러를 응답한다") {
runPostTest(endpoint, body = userRequest) {
log().all()
statusCode(400)
body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name))
}
}
}
When("잘못된 요청을 보내면 400 에러를 응답한다.") {
Then("이메일 형식이 잘못된 경우") {
val invalidRequest: LoginRequest = userRequest.copy(email = "invalid")
runPostTest(endpoint, body = invalidRequest) {
log().all()
statusCode(400)
body("message", `is`("이메일 형식이 일치하지 않습니다. 예시: abc123@gmail.com"))
}
}
Then("비밀번호가 공백인 경우") {
val invalidRequest = userRequest.copy(password = " ")
runPostTest(endpoint, body = invalidRequest) {
log().all()
statusCode(400)
body("message", `is`("비밀번호는 공백일 수 없습니다."))
}
}
}
}
Given("로그인 상태를 확인할 때") {
val endpoint: String = "/login/check"
When("로그인된 회원의 ID로 요청하면") {
every { jwtHandler.getMemberIdFromToken(any()) } returns user.id!!
every { memberRepository.findByIdOrNull(user.id!!) } returns user
Then("회원의 이름을 응답한다") {
runGetTest(endpoint) {
statusCode(200)
body("data.name", `is`(user.name))
}
}
}
When("토큰은 있지만 회원을 찾을 수 없으면") {
val invalidMemberId: Long = -1L
every { jwtHandler.getMemberIdFromToken(any()) } returns invalidMemberId
every { memberRepository.findByIdOrNull(invalidMemberId) } returns null
Then("400 에러를 응답한다.") {
runGetTest(endpoint) {
statusCode(400)
body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name))
}
}
}
}
Given("로그아웃 요청을 보낼 때") {
val endpoint: String = "/logout"
When("로그인 상태가 아니라면") {
setUpNotLoggedIn()
Then("로그인 페이지로 이동한다.") {
runPostTest(endpoint) {
log().all()
statusCode(302)
header("Location", containsString("/login"))
}
}
}
When("로그인 상태라면") {
setUpUser()
every { memberRepository.findByIdOrNull(user.id!!) } returns user
Then("토큰의 존재 여부와 무관하게 토큰을 만료시킨다.") {
runPostTest(endpoint) {
log().all()
statusCode(200)
cookie("accessToken", "")
header("Set-Cookie", containsString("Max-Age=0"))
}
}
}
}
}
}