generated from pricelees/issue-pr-template
refactor: 로그인 처리 로직 수정으로 인한 테스트 변경
This commit is contained in:
parent
0f1ce2a497
commit
0ff0f4e9fc
@ -1,16 +1,18 @@
|
|||||||
package com.sangdol.roomescape.auth
|
package com.sangdol.roomescape.auth
|
||||||
|
|
||||||
|
import com.ninjasquad.springmockk.MockkBean
|
||||||
import com.ninjasquad.springmockk.SpykBean
|
import com.ninjasquad.springmockk.SpykBean
|
||||||
import com.sangdol.common.types.web.HttpStatus
|
import com.sangdol.common.types.web.HttpStatus
|
||||||
import com.sangdol.roomescape.admin.exception.AdminErrorCode
|
import com.sangdol.roomescape.admin.exception.AdminErrorCode
|
||||||
import com.sangdol.roomescape.auth.business.CLAIM_ADMIN_TYPE_KEY
|
import com.sangdol.roomescape.auth.business.CLAIM_ADMIN_TYPE_KEY
|
||||||
import com.sangdol.roomescape.auth.business.CLAIM_PERMISSION_KEY
|
import com.sangdol.roomescape.auth.business.CLAIM_PERMISSION_KEY
|
||||||
import com.sangdol.roomescape.auth.business.CLAIM_STORE_ID_KEY
|
import com.sangdol.roomescape.auth.business.CLAIM_STORE_ID_KEY
|
||||||
|
import com.sangdol.roomescape.auth.business.LoginHistoryEventListener
|
||||||
|
import com.sangdol.roomescape.auth.business.domain.LoginHistoryEvent
|
||||||
|
import com.sangdol.roomescape.auth.business.domain.PrincipalType
|
||||||
|
import com.sangdol.roomescape.auth.dto.LoginRequest
|
||||||
import com.sangdol.roomescape.auth.exception.AuthErrorCode
|
import com.sangdol.roomescape.auth.exception.AuthErrorCode
|
||||||
import com.sangdol.roomescape.auth.infrastructure.jwt.JwtUtils
|
import com.sangdol.roomescape.auth.infrastructure.jwt.JwtUtils
|
||||||
import com.sangdol.roomescape.auth.infrastructure.persistence.LoginHistoryRepository
|
|
||||||
import com.sangdol.roomescape.auth.dto.LoginRequest
|
|
||||||
import com.sangdol.roomescape.auth.business.domain.PrincipalType
|
|
||||||
import com.sangdol.roomescape.supports.AdminFixture
|
import com.sangdol.roomescape.supports.AdminFixture
|
||||||
import com.sangdol.roomescape.supports.FunSpecSpringbootTest
|
import com.sangdol.roomescape.supports.FunSpecSpringbootTest
|
||||||
import com.sangdol.roomescape.supports.UserFixture
|
import com.sangdol.roomescape.supports.UserFixture
|
||||||
@ -18,19 +20,31 @@ import com.sangdol.roomescape.supports.runTest
|
|||||||
import com.sangdol.roomescape.user.exception.UserErrorCode
|
import com.sangdol.roomescape.user.exception.UserErrorCode
|
||||||
import com.sangdol.roomescape.user.infrastructure.persistence.UserEntity
|
import com.sangdol.roomescape.user.infrastructure.persistence.UserEntity
|
||||||
import io.kotest.assertions.assertSoftly
|
import io.kotest.assertions.assertSoftly
|
||||||
import io.kotest.matchers.collections.shouldHaveSize
|
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import io.mockk.every
|
import io.mockk.*
|
||||||
import io.restassured.response.ValidatableResponse
|
import io.restassured.response.ValidatableResponse
|
||||||
import org.hamcrest.CoreMatchers.equalTo
|
import org.hamcrest.CoreMatchers.equalTo
|
||||||
|
|
||||||
class AuthApiTest(
|
class AuthApiTest(
|
||||||
@SpykBean private val jwtUtils: JwtUtils,
|
@SpykBean private val jwtUtils: JwtUtils,
|
||||||
private val loginHistoryRepository: LoginHistoryRepository
|
@MockkBean(relaxed = true) private val loginHistoryEventListener: LoginHistoryEventListener,
|
||||||
) : FunSpecSpringbootTest() {
|
) : FunSpecSpringbootTest() {
|
||||||
|
|
||||||
|
lateinit var slot: CapturingSlot<LoginHistoryEvent>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
beforeTest {
|
||||||
|
slot = slot<LoginHistoryEvent>()
|
||||||
|
every {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(capture(slot))
|
||||||
|
} just Runs
|
||||||
|
}
|
||||||
|
|
||||||
|
afterTest {
|
||||||
|
clearMocks(jwtUtils, loginHistoryEventListener)
|
||||||
|
}
|
||||||
|
|
||||||
context("로그인을 시도한다.") {
|
context("로그인을 시도한다.") {
|
||||||
context("성공 응답") {
|
context("성공 응답") {
|
||||||
listOf(
|
listOf(
|
||||||
@ -64,6 +78,7 @@ class AuthApiTest(
|
|||||||
password = user.password,
|
password = user.password,
|
||||||
type = PrincipalType.USER,
|
type = PrincipalType.USER,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val token: String = it.extract().path("data.accessToken")
|
val token: String = it.extract().path("data.accessToken")
|
||||||
jwtUtils.extractSubject(token) shouldBe user.id.toString()
|
jwtUtils.extractSubject(token) shouldBe user.id.toString()
|
||||||
}
|
}
|
||||||
@ -71,6 +86,16 @@ class AuthApiTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
context("실패 응답") {
|
context("실패 응답") {
|
||||||
|
|
||||||
|
lateinit var slot: CapturingSlot<LoginHistoryEvent>
|
||||||
|
|
||||||
|
beforeTest {
|
||||||
|
slot = slot<LoginHistoryEvent>()
|
||||||
|
every {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(capture(slot))
|
||||||
|
} just Runs
|
||||||
|
}
|
||||||
|
|
||||||
context("계정이 맞으면 로그인 실패 이력을 남긴다.") {
|
context("계정이 맞으면 로그인 실패 이력을 남긴다.") {
|
||||||
test("비밀번호가 틀린 경우") {
|
test("비밀번호가 틀린 경우") {
|
||||||
val admin = testAuthUtil.createAdmin(AdminFixture.default)
|
val admin = testAuthUtil.createAdmin(AdminFixture.default)
|
||||||
@ -88,9 +113,14 @@ class AuthApiTest(
|
|||||||
body("code", equalTo(AuthErrorCode.LOGIN_FAILED.errorCode))
|
body("code", equalTo(AuthErrorCode.LOGIN_FAILED.errorCode))
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
assertSoftly(loginHistoryRepository.findByPrincipalId(admin.id)[0]) {
|
verify(exactly = 1) {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSoftly(slot.captured) {
|
||||||
|
this.id shouldBe admin.id
|
||||||
|
this.type shouldBe PrincipalType.ADMIN
|
||||||
this.success shouldBe false
|
this.success shouldBe false
|
||||||
this.principalType shouldBe PrincipalType.ADMIN
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,9 +145,14 @@ class AuthApiTest(
|
|||||||
body("code", equalTo(AuthErrorCode.TEMPORARY_AUTH_ERROR.errorCode))
|
body("code", equalTo(AuthErrorCode.TEMPORARY_AUTH_ERROR.errorCode))
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
assertSoftly(loginHistoryRepository.findByPrincipalId(admin.id)[0]) {
|
verify(exactly = 1) {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSoftly(slot.captured) {
|
||||||
|
this.id shouldBe admin.id
|
||||||
|
this.type shouldBe PrincipalType.ADMIN
|
||||||
this.success shouldBe false
|
this.success shouldBe false
|
||||||
this.principalType shouldBe PrincipalType.ADMIN
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +179,9 @@ class AuthApiTest(
|
|||||||
body("code", equalTo(UserErrorCode.USER_NOT_FOUND.errorCode))
|
body("code", equalTo(UserErrorCode.USER_NOT_FOUND.errorCode))
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
loginHistoryRepository.findAll() shouldHaveSize 0
|
verify(exactly = 0) {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +205,9 @@ class AuthApiTest(
|
|||||||
body("code", equalTo(AdminErrorCode.ADMIN_NOT_FOUND.errorCode))
|
body("code", equalTo(AdminErrorCode.ADMIN_NOT_FOUND.errorCode))
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
loginHistoryRepository.findAll() shouldHaveSize 0
|
verify(exactly = 0) {
|
||||||
|
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,10 +237,13 @@ class AuthApiTest(
|
|||||||
).also {
|
).also {
|
||||||
extraAssertions?.invoke(it)
|
extraAssertions?.invoke(it)
|
||||||
|
|
||||||
assertSoftly(loginHistoryRepository.findByPrincipalId(id)) { history ->
|
verify(exactly = 1) {
|
||||||
history shouldHaveSize (1)
|
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
|
||||||
history[0].success shouldBe true
|
}
|
||||||
history[0].principalType shouldBe type
|
assertSoftly(slot.captured) {
|
||||||
|
this.id shouldBe id
|
||||||
|
this.type shouldBe type
|
||||||
|
this.success shouldBe true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,64 +0,0 @@
|
|||||||
package com.sangdol.roomescape.auth
|
|
||||||
|
|
||||||
import com.ninjasquad.springmockk.MockkBean
|
|
||||||
import com.sangdol.common.types.web.HttpStatus
|
|
||||||
import com.sangdol.roomescape.auth.infrastructure.persistence.LoginHistoryRepository
|
|
||||||
import com.sangdol.roomescape.auth.dto.LoginRequest
|
|
||||||
import com.sangdol.roomescape.auth.business.domain.PrincipalType
|
|
||||||
import com.sangdol.roomescape.supports.AdminFixture
|
|
||||||
import com.sangdol.roomescape.supports.FunSpecSpringbootTest
|
|
||||||
import com.sangdol.roomescape.supports.UserFixture
|
|
||||||
import com.sangdol.roomescape.supports.runTest
|
|
||||||
import io.mockk.clearMocks
|
|
||||||
import io.mockk.every
|
|
||||||
|
|
||||||
class FailOnSaveLoginHistoryTest(
|
|
||||||
@MockkBean private val loginHistoryRepository: LoginHistoryRepository
|
|
||||||
) : FunSpecSpringbootTest() {
|
|
||||||
|
|
||||||
init {
|
|
||||||
context("로그인 이력 저장 과정에서 예외가 발생해도 로그인 작업 자체는 정상 처리된다.") {
|
|
||||||
beforeTest {
|
|
||||||
clearMocks(loginHistoryRepository)
|
|
||||||
|
|
||||||
every {
|
|
||||||
loginHistoryRepository.save(any())
|
|
||||||
} throws RuntimeException("intended exception")
|
|
||||||
}
|
|
||||||
|
|
||||||
test("회원") {
|
|
||||||
val user = testAuthUtil.signup(UserFixture.createRequest)
|
|
||||||
val request = LoginRequest(user.email, user.password, PrincipalType.USER)
|
|
||||||
|
|
||||||
runTest(
|
|
||||||
using = {
|
|
||||||
body(request)
|
|
||||||
},
|
|
||||||
on = {
|
|
||||||
post("/auth/login")
|
|
||||||
},
|
|
||||||
expect = {
|
|
||||||
statusCode(HttpStatus.OK.value())
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("관리자") {
|
|
||||||
val admin = testAuthUtil.createAdmin(AdminFixture.default)
|
|
||||||
val request = LoginRequest(admin.account, admin.password, PrincipalType.ADMIN)
|
|
||||||
|
|
||||||
runTest(
|
|
||||||
using = {
|
|
||||||
body(request)
|
|
||||||
},
|
|
||||||
on = {
|
|
||||||
post("/auth/login")
|
|
||||||
},
|
|
||||||
expect = {
|
|
||||||
statusCode(HttpStatus.OK.value())
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user