diff --git a/src/test/java/roomescape/auth/web/AuthControllerTest.kt b/src/test/java/roomescape/auth/web/AuthControllerTest.kt index 0f23f160..a4f575d1 100644 --- a/src/test/java/roomescape/auth/web/AuthControllerTest.kt +++ b/src/test/java/roomescape/auth/web/AuthControllerTest.kt @@ -1,23 +1,34 @@ package roomescape.auth.web +import com.ninjasquad.springmockk.SpykBean import io.mockk.every import org.hamcrest.Matchers.containsString -import org.hamcrest.Matchers.`is` +import org.hamcrest.Matchers.equalTo +import org.springframework.beans.factory.annotation.Autowired +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.service.AuthService import roomescape.common.exception.ErrorType import roomescape.util.MemberFixture import roomescape.util.RoomescapeApiTest -class AuthControllerTest : RoomescapeApiTest() { +@WebMvcTest(controllers = [AuthController::class]) +class AuthControllerTest( + @Autowired mockMvc: MockMvc +) : RoomescapeApiTest() { + + @SpykBean + private lateinit var authService: AuthService val userRequest: LoginRequest = MemberFixture.userLoginRequest() init { Given("로그인 요청을 보낼 때") { - val endpoint: String = "/login" + val endpoint = "/login" When("로그인에 성공하면") { - val expectedToken: String = "expectedToken" + val expectedToken = "expectedToken" every { memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password) @@ -28,12 +39,19 @@ class AuthControllerTest : RoomescapeApiTest() { } returns expectedToken Then("토큰을 쿠키에 담아 응답한다") { - runPostTest(endpoint, body = MemberFixture.userLoginRequest()) { - statusCode(200) - cookie("accessToken", expectedToken) - header("Set-Cookie", containsString("Max-Age=1800")) - header("Set-Cookie", containsString("HttpOnly")) - header("Set-Cookie", containsString("Secure")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = userRequest, + log = true + ) { + status { isOk() } + header { + string("Set-Cookie", containsString("accessToken=$expectedToken")) + string("Set-Cookie", containsString("Max-Age=1800")) + string("Set-Cookie", containsString("HttpOnly")) + string("Set-Cookie", containsString("Secure")) + } } } } @@ -44,10 +62,14 @@ class AuthControllerTest : RoomescapeApiTest() { } returns null Then("400 에러를 응답한다") { - runPostTest(endpoint, body = userRequest) { - log().all() - statusCode(400) - body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name)) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = userRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.errorType", equalTo(ErrorType.MEMBER_NOT_FOUND.name)) } } } @@ -57,36 +79,47 @@ class AuthControllerTest : RoomescapeApiTest() { Then("이메일 형식이 잘못된 경우") { val invalidRequest: LoginRequest = userRequest.copy(email = "invalid") - runPostTest(endpoint, body = invalidRequest) { - log().all() - statusCode(400) - body("message", `is`("이메일 형식이 일치하지 않습니다. 예시: abc123@gmail.com")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = invalidRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.message", containsString("이메일 형식이 일치하지 않습니다.")) } } Then("비밀번호가 공백인 경우") { val invalidRequest = userRequest.copy(password = " ") - runPostTest(endpoint, body = invalidRequest) { - log().all() - statusCode(400) - body("message", `is`("비밀번호는 공백일 수 없습니다.")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = invalidRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.message", containsString("비밀번호는 공백일 수 없습니다.")) } } } } Given("로그인 상태를 확인할 때") { - val endpoint: String = "/login/check" + val endpoint = "/login/check" When("로그인된 회원의 ID로 요청하면") { - every { jwtHandler.getMemberIdFromToken(any()) } returns user.id!! - every { memberRepository.findByIdOrNull(user.id!!) } returns user + loginAsUser() Then("회원의 이름을 응답한다") { - runGetTest(endpoint) { - statusCode(200) - body("data.name", `is`(user.name)) + runGetTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isOk() } + jsonPath("$.data.name", equalTo(user.name)) } } } @@ -98,39 +131,55 @@ class AuthControllerTest : RoomescapeApiTest() { every { memberRepository.findByIdOrNull(invalidMemberId) } returns null Then("400 에러를 응답한다.") { - runGetTest(endpoint) { - statusCode(400) - body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name)) + runGetTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isBadRequest() } + jsonPath("$.errorType", equalTo(ErrorType.MEMBER_NOT_FOUND.name)) } } } } Given("로그아웃 요청을 보낼 때") { - val endpoint: String = "/logout" + val endpoint = "/logout" When("로그인 상태가 아니라면") { - setUpNotLoggedIn() + doNotLogin() Then("로그인 페이지로 이동한다.") { - runPostTest(endpoint) { - log().all() - statusCode(302) - header("Location", containsString("/login")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { is3xxRedirection() } + header { + string("Location", "/login") + } } } } When("로그인 상태라면") { - setUpUser() - every { memberRepository.findByIdOrNull(user.id!!) } returns user + loginAsUser() Then("토큰의 존재 여부와 무관하게 토큰을 만료시킨다.") { - runPostTest(endpoint) { - log().all() - statusCode(200) - cookie("accessToken", "") - header("Set-Cookie", containsString("Max-Age=0")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isOk() } + header { + string("Set-Cookie", containsString("Max-Age=0")) + string("Set-Cookie", containsString("accessToken=")) + string("Set-Cookie", containsString("Path=/")) + string("Set-Cookie", containsString("HttpOnly")) + string("Set-Cookie", containsString("Secure")) + } } } }