refactor: 로그인 처리 로직 수정으로 인한 테스트 변경

This commit is contained in:
이상진 2025-10-12 14:01:27 +09:00
parent 0f1ce2a497
commit 0ff0f4e9fc
2 changed files with 58 additions and 80 deletions

View File

@ -1,16 +1,18 @@
package com.sangdol.roomescape.auth
import com.ninjasquad.springmockk.MockkBean
import com.ninjasquad.springmockk.SpykBean
import com.sangdol.common.types.web.HttpStatus
import com.sangdol.roomescape.admin.exception.AdminErrorCode
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_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.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.FunSpecSpringbootTest
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.infrastructure.persistence.UserEntity
import io.kotest.assertions.assertSoftly
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.mockk.every
import io.mockk.*
import io.restassured.response.ValidatableResponse
import org.hamcrest.CoreMatchers.equalTo
class AuthApiTest(
@SpykBean private val jwtUtils: JwtUtils,
private val loginHistoryRepository: LoginHistoryRepository
@MockkBean(relaxed = true) private val loginHistoryEventListener: LoginHistoryEventListener,
) : FunSpecSpringbootTest() {
lateinit var slot: CapturingSlot<LoginHistoryEvent>
init {
beforeTest {
slot = slot<LoginHistoryEvent>()
every {
loginHistoryEventListener.onLoginCompleted(capture(slot))
} just Runs
}
afterTest {
clearMocks(jwtUtils, loginHistoryEventListener)
}
context("로그인을 시도한다.") {
context("성공 응답") {
listOf(
@ -64,6 +78,7 @@ class AuthApiTest(
password = user.password,
type = PrincipalType.USER,
) {
val token: String = it.extract().path("data.accessToken")
jwtUtils.extractSubject(token) shouldBe user.id.toString()
}
@ -71,6 +86,16 @@ class AuthApiTest(
}
context("실패 응답") {
lateinit var slot: CapturingSlot<LoginHistoryEvent>
beforeTest {
slot = slot<LoginHistoryEvent>()
every {
loginHistoryEventListener.onLoginCompleted(capture(slot))
} just Runs
}
context("계정이 맞으면 로그인 실패 이력을 남긴다.") {
test("비밀번호가 틀린 경우") {
val admin = testAuthUtil.createAdmin(AdminFixture.default)
@ -88,9 +113,14 @@ class AuthApiTest(
body("code", equalTo(AuthErrorCode.LOGIN_FAILED.errorCode))
}
).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.principalType shouldBe PrincipalType.ADMIN
}
}
}
@ -115,9 +145,14 @@ class AuthApiTest(
body("code", equalTo(AuthErrorCode.TEMPORARY_AUTH_ERROR.errorCode))
}
).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.principalType shouldBe PrincipalType.ADMIN
}
}
}
@ -144,7 +179,9 @@ class AuthApiTest(
body("code", equalTo(UserErrorCode.USER_NOT_FOUND.errorCode))
}
).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))
}
).also {
loginHistoryRepository.findAll() shouldHaveSize 0
verify(exactly = 0) {
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
}
}
}
}
@ -198,10 +237,13 @@ class AuthApiTest(
).also {
extraAssertions?.invoke(it)
assertSoftly(loginHistoryRepository.findByPrincipalId(id)) { history ->
history shouldHaveSize (1)
history[0].success shouldBe true
history[0].principalType shouldBe type
verify(exactly = 1) {
loginHistoryEventListener.onLoginCompleted(any<LoginHistoryEvent>())
}
assertSoftly(slot.captured) {
this.id shouldBe id
this.type shouldBe type
this.success shouldBe true
}
}
}

View File

@ -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())
}
)
}
}
}
}