diff --git a/src/test/java/roomescape/util/Fixtures.kt b/src/test/java/roomescape/util/Fixtures.kt index d03b6fe5..4ae7a6b6 100644 --- a/src/test/java/roomescape/util/Fixtures.kt +++ b/src/test/java/roomescape/util/Fixtures.kt @@ -7,6 +7,8 @@ import roomescape.auth.web.LoginRequest import java.util.concurrent.atomic.AtomicLong object MemberFixture { + const val NOT_LOGGED_IN_USERID: Long = 0 + val idCounter: AtomicLong = AtomicLong(1L) fun create( diff --git a/src/test/java/roomescape/util/RoomescapeApiTest.kt b/src/test/java/roomescape/util/RoomescapeApiTest.kt index bd02bba7..23addfe6 100644 --- a/src/test/java/roomescape/util/RoomescapeApiTest.kt +++ b/src/test/java/roomescape/util/RoomescapeApiTest.kt @@ -1,30 +1,40 @@ package roomescape.util +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.ninjasquad.springmockk.MockkBean +import com.ninjasquad.springmockk.SpykBean import io.kotest.core.spec.style.BehaviorSpec import io.mockk.every -import io.restassured.http.ContentType -import io.restassured.module.kotlin.extensions.Given -import io.restassured.module.kotlin.extensions.Then -import io.restassured.module.kotlin.extensions.When -import io.restassured.response.ValidatableResponse -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.data.repository.findByIdOrNull +import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus -import roomescape.member.infrastructure.persistence.Member -import roomescape.member.infrastructure.persistence.MemberRepository +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.* 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.common.exception.RoomescapeException +import roomescape.member.business.MemberService +import roomescape.member.infrastructure.persistence.Member +import roomescape.member.infrastructure.persistence.MemberRepository +import roomescape.util.MemberFixture.NOT_LOGGED_IN_USERID -const val NOT_LOGGED_IN_USERID: Long = 0; +abstract class RoomescapeApiTest : BehaviorSpec() { -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@NoSqlInitialize -class RoomescapeApiTest( - @LocalServerPort val port: Int? = 9090, -) : BehaviorSpec() { + @SpykBean + private lateinit var AdminInterceptor: AdminInterceptor + + @SpykBean + private lateinit var loginInterceptor: LoginInterceptor + + @SpykBean + private lateinit var memberIdResolver: MemberIdResolver + + @SpykBean + lateinit var memberService: MemberService @MockkBean lateinit var memberRepository: MemberRepository @@ -32,36 +42,42 @@ class RoomescapeApiTest( @MockkBean lateinit var jwtHandler: JwtHandler - + val objectMapper: ObjectMapper = jacksonObjectMapper() val admin: Member = MemberFixture.admin() val user: Member = MemberFixture.user() - fun runGetTest(endpoint: String, token: String? = "token", assert: ValidatableResponse.() -> Unit): ValidatableResponse { - return Given { - port(port!!) - header("Cookie", "accessToken=$token") - } When { - get(endpoint) - } Then assert + fun runGetTest( + mockMvc: MockMvc, + endpoint: String, + log: Boolean = false, + assert: MockMvcResultMatchersDsl.() -> Unit + ): ResultActionsDsl = mockMvc.get(endpoint) { + header(HttpHeaders.COOKIE, "accessToken=token") + }.apply { + log.takeIf { it }?.let { this.andDo { print() } } + }.andExpect { + assert } fun runPostTest( + mockMvc: MockMvc, endpoint: String, - token: String? = "token", body: Any? = null, - assert: ValidatableResponse.() -> Unit - ): ValidatableResponse { - return Given { - port(port!!) - contentType(ContentType.JSON) - body?.let { body(it) } - header("Cookie", "accessToken=$token") - } When { - post(endpoint) - } Then assert + log: Boolean = false, + assert: MockMvcResultMatchersDsl.() -> Unit + ): ResultActionsDsl = mockMvc.post(endpoint) { + this.header(HttpHeaders.COOKIE, "accessToken=token") + body?.let { + this.contentType = MediaType.APPLICATION_JSON + this.content = objectMapper.writeValueAsString(it) + } + }.apply { + log.takeIf { it }?.let { this.andDo { print() } } + }.andExpect { + assert } - fun setUpAdmin() { + fun loginAsAdmin() { every { jwtHandler.getMemberIdFromToken(any()) } returns admin.id!! @@ -70,7 +86,7 @@ class RoomescapeApiTest( every { memberRepository.findByIdOrNull(admin.id!!) } returns admin } - fun setUpUser() { + fun loginAsUser() { every { jwtHandler.getMemberIdFromToken(any()) } returns user.id!! @@ -79,15 +95,19 @@ class RoomescapeApiTest( every { memberRepository.findByIdOrNull(user.id!!) } returns user } - fun setUpNotLoggedIn() { + fun doNotLogin() { every { jwtHandler.getMemberIdFromToken(any()) - } returns NOT_LOGGED_IN_USERID + } throws RoomescapeException(ErrorType.INVALID_TOKEN, HttpStatus.UNAUTHORIZED) - every { memberRepository.existsById(NOT_LOGGED_IN_USERID) } throws RoomescapeException( - ErrorType.LOGIN_REQUIRED, - HttpStatus.FORBIDDEN - ) + every { memberRepository.existsById(NOT_LOGGED_IN_USERID) } returns false every { memberRepository.findByIdOrNull(NOT_LOGGED_IN_USERID) } returns null } + + fun readValue(responseJson: String, valueType: Class): T = objectMapper + .readTree(responseJson)["data"] + ?.let { objectMapper.convertValue(it, valueType) } + ?: throw RuntimeException(""" + [Test] Exception occurred while reading response json: $responseJson with value type: $valueType + """.trimIndent()) }