feat: Integration Test에서 사용할 정상 생성 Request가 담긴 Fixture 정의 및 반영

This commit is contained in:
이상진 2025-09-04 11:47:25 +09:00
parent fff54cdec9
commit 43dbadba86
3 changed files with 80 additions and 42 deletions

View File

@ -19,12 +19,12 @@ import roomescape.theme.business.MIN_DURATION
import roomescape.theme.business.MIN_PARTICIPANTS import roomescape.theme.business.MIN_PARTICIPANTS
import roomescape.theme.business.MIN_PRICE import roomescape.theme.business.MIN_PRICE
import roomescape.theme.exception.ThemeErrorCode import roomescape.theme.exception.ThemeErrorCode
import roomescape.theme.infrastructure.persistence.v2.Difficulty
import roomescape.theme.infrastructure.persistence.v2.ThemeEntityV2 import roomescape.theme.infrastructure.persistence.v2.ThemeEntityV2
import roomescape.theme.infrastructure.persistence.v2.ThemeRepositoryV2 import roomescape.theme.infrastructure.persistence.v2.ThemeRepositoryV2
import roomescape.theme.web.ThemeCreateRequestV2 import roomescape.theme.web.ThemeCreateRequestV2
import roomescape.theme.web.ThemeUpdateRequest import roomescape.theme.web.ThemeUpdateRequest
import roomescape.util.FunSpecSpringbootTest import roomescape.util.FunSpecSpringbootTest
import roomescape.util.ThemeFixtureV2.createRequest
import roomescape.util.assertProperties import roomescape.util.assertProperties
import roomescape.util.runTest import roomescape.util.runTest
import kotlin.random.Random import kotlin.random.Random
@ -33,19 +33,6 @@ class ThemeApiTest(
private val themeRepository: ThemeRepositoryV2 private val themeRepository: ThemeRepositoryV2
) : FunSpecSpringbootTest() { ) : FunSpecSpringbootTest() {
private val request: ThemeCreateRequestV2 = ThemeCreateRequestV2(
name = "Matilda Green",
description = "constituto",
thumbnailUrl = "https://duckduckgo.com/?q=mediocrem",
difficulty = Difficulty.VERY_EASY,
price = 10000,
minParticipants = 3,
maxParticipants = 5,
availableMinutes = 80,
expectedMinutesFrom = 60,
expectedMinutesTo = 70,
isOpen = true
)
init { init {
context("관리자가 아니면 접근할 수 없다.") { context("관리자가 아니면 접근할 수 없다.") {
@ -64,7 +51,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request) body(createRequest)
}, },
on = { on = {
post("/admin/themes") post("/admin/themes")
@ -97,7 +84,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request) body(createRequest)
}, },
on = { on = {
patch("/admin/themes/1") patch("/admin/themes/1")
@ -119,7 +106,7 @@ class ThemeApiTest(
context("일반 회원도 접근할 수 있다.") { context("일반 회원도 접근할 수 있다.") {
test("테마 조회: GET /v2/themes") { test("테마 조회: GET /v2/themes") {
createDummyTheme(request.copy(name = "test123", isOpen = true)) createDummyTheme(createRequest.copy(name = "test123", isOpen = true))
runTest( runTest(
token = loginUtil.loginAsUser(), token = loginUtil.loginAsUser(),
@ -148,7 +135,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request) body(createRequest)
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -158,11 +145,11 @@ class ThemeApiTest(
body("data.id", notNullValue()) body("data.id", notNullValue())
} }
).also { ).also {
val createdThemeId: String = it.extract().path("data.id") val createdThemeId: Long = it.extract().path("data.id")
val createdTheme: ThemeEntityV2 = themeRepository.findByIdOrNull(createdThemeId.toLong()) val createdTheme: ThemeEntityV2 = themeRepository.findByIdOrNull(createdThemeId)
?: throw AssertionError("Unexpected Exception Occurred.") ?: throw AssertionError("Unexpected Exception Occurred.")
createdTheme.name shouldBe request.name createdTheme.name shouldBe createRequest.name
createdTheme.createdAt shouldNotBeNull {} createdTheme.createdAt shouldNotBeNull {}
createdTheme.createdBy shouldNotBeNull {} createdTheme.createdBy shouldNotBeNull {}
createdTheme.updatedAt shouldNotBeNull {} createdTheme.updatedAt shouldNotBeNull {}
@ -172,12 +159,12 @@ class ThemeApiTest(
test("이미 동일한 이름의 테마가 있으면 실패한다.") { test("이미 동일한 이름의 테마가 있으면 실패한다.") {
val commonName = "test123" val commonName = "test123"
createDummyTheme(request.copy(name = commonName)) createDummyTheme(createRequest.copy(name = commonName))
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(name = commonName)) body(createRequest.copy(name = commonName))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -193,7 +180,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(price = (MIN_PRICE - 1))) body(createRequest.copy(price = (MIN_PRICE - 1)))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -215,7 +202,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(availableMinutes = (MIN_DURATION - 1).toShort())) body(createRequest.copy(availableMinutes = (MIN_DURATION - 1).toShort()))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -228,7 +215,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(expectedMinutesFrom = (MIN_DURATION - 1).toShort())) body(createRequest.copy(expectedMinutesFrom = (MIN_DURATION - 1).toShort()))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -241,7 +228,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(expectedMinutesTo = (MIN_DURATION - 1).toShort())) body(createRequest.copy(expectedMinutesTo = (MIN_DURATION - 1).toShort()))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -256,7 +243,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(expectedMinutesFrom = 100, expectedMinutesTo = 99)) body(createRequest.copy(expectedMinutesFrom = 100, expectedMinutesTo = 99))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -273,7 +260,7 @@ class ThemeApiTest(
token = token, token = token,
using = { using = {
body( body(
request.copy( createRequest.copy(
availableMinutes = 100, availableMinutes = 100,
expectedMinutesFrom = 101, expectedMinutesFrom = 101,
expectedMinutesTo = 101 expectedMinutesTo = 101
@ -301,7 +288,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(minParticipants = (MIN_PARTICIPANTS - 1).toShort())) body(createRequest.copy(minParticipants = (MIN_PARTICIPANTS - 1).toShort()))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -314,7 +301,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(maxParticipants = (MIN_PARTICIPANTS - 1).toShort())) body(createRequest.copy(maxParticipants = (MIN_PARTICIPANTS - 1).toShort()))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -329,7 +316,7 @@ class ThemeApiTest(
runTest( runTest(
token = token, token = token,
using = { using = {
body(request.copy(minParticipants = 10, maxParticipants = 9)) body(createRequest.copy(minParticipants = 10, maxParticipants = 9))
}, },
on = { on = {
post(apiPath) post(apiPath)
@ -345,8 +332,8 @@ class ThemeApiTest(
context("모든 테마를 조회한다.") { context("모든 테마를 조회한다.") {
beforeTest { beforeTest {
createDummyTheme(request.copy(name = "open", isOpen = true)) createDummyTheme(createRequest.copy(name = "open", isOpen = true))
createDummyTheme(request.copy(name = "close", isOpen = false)) createDummyTheme(createRequest.copy(name = "close", isOpen = false))
} }
test("관리자 페이지에서는 비공개 테마까지 포함하여 간단한 정보만 조회된다.") { test("관리자 페이지에서는 비공개 테마까지 포함하여 간단한 정보만 조회된다.") {
@ -389,7 +376,7 @@ class ThemeApiTest(
context("관리자 페이지에서 특정 테마의 상세 정보를 조회한다.") { context("관리자 페이지에서 특정 테마의 상세 정보를 조회한다.") {
test("정상 응답") { test("정상 응답") {
val createdTheme: ThemeEntityV2 = createDummyTheme(request) val createdTheme: ThemeEntityV2 = createDummyTheme(createRequest)
runTest( runTest(
token = loginUtil.loginAsAdmin(), token = loginUtil.loginAsAdmin(),
@ -398,7 +385,7 @@ class ThemeApiTest(
}, },
expect = { expect = {
statusCode(HttpStatus.OK.value()) statusCode(HttpStatus.OK.value())
body("data.id", equalTo(createdTheme.id.toString())) body("data.id", equalTo(createdTheme.id))
assertProperties( assertProperties(
props = setOf( props = setOf(
"id", "name", "description", "thumbnailUrl", "difficulty", "price", "isOpen", "id", "name", "description", "thumbnailUrl", "difficulty", "price", "isOpen",
@ -427,7 +414,7 @@ class ThemeApiTest(
context("테마를 삭제한다.") { context("테마를 삭제한다.") {
test("정상 삭제") { test("정상 삭제") {
val createdTheme = createDummyTheme(request) val createdTheme = createDummyTheme(createRequest)
runTest( runTest(
token = loginUtil.loginAsAdmin(), token = loginUtil.loginAsAdmin(),
@ -465,7 +452,7 @@ class ThemeApiTest(
beforeTest { beforeTest {
token = loginUtil.loginAsAdmin() token = loginUtil.loginAsAdmin()
createdTheme = createDummyTheme(request.copy(name = "theme-${Random.nextInt()}")) createdTheme = createDummyTheme(createRequest.copy(name = "theme-${Random.nextInt()}"))
apiPath = "/admin/themes/${createdTheme.id}" apiPath = "/admin/themes/${createdTheme.id}"
} }
@ -665,7 +652,7 @@ class ThemeApiTest(
} }
fun createDummyTheme(request: ThemeCreateRequestV2): ThemeEntityV2 { fun createDummyTheme(request: ThemeCreateRequestV2): ThemeEntityV2 {
val createdThemeId: String = Given { val createdThemeId: Long = Given {
contentType(MediaType.APPLICATION_JSON_VALUE) contentType(MediaType.APPLICATION_JSON_VALUE)
header("Authorization", "Bearer ${loginUtil.loginAsAdmin()}") header("Authorization", "Bearer ${loginUtil.loginAsAdmin()}")
body(request) body(request)
@ -675,7 +662,7 @@ class ThemeApiTest(
path("data.id") path("data.id")
} }
return themeRepository.findByIdOrNull(createdThemeId.toLong()) return themeRepository.findByIdOrNull(createdThemeId)
?: throw RuntimeException("unreachable line") ?: throw RuntimeException("unreachable line")
} }
} }

View File

@ -0,0 +1,51 @@
package roomescape.util
import roomescape.member.infrastructure.persistence.MemberEntity
import roomescape.member.infrastructure.persistence.Role
import roomescape.schedule.web.ScheduleCreateRequest
import roomescape.theme.infrastructure.persistence.v2.Difficulty
import roomescape.theme.web.ThemeCreateRequestV2
import java.time.LocalDate
import java.time.LocalTime
object MemberFixtureV2 {
val admin: MemberEntity = MemberEntity(
_id = 9304,
name = "ADMIN",
email = "admin@example.com",
password = "adminPassword",
role = Role.ADMIN
)
val user: MemberEntity = MemberEntity(
_id = 9305,
name = "USER",
email = "user@example.com",
password = "userPassword",
role = Role.MEMBER
)
}
object ThemeFixtureV2 {
val createRequest: ThemeCreateRequestV2 = ThemeCreateRequestV2(
name = "Matilda Green",
description = "constituto",
thumbnailUrl = "https://duckduckgo.com/?q=mediocrem",
difficulty = Difficulty.VERY_EASY,
price = 10000,
minParticipants = 3,
maxParticipants = 5,
availableMinutes = 80,
expectedMinutesFrom = 60,
expectedMinutesTo = 70,
isOpen = true
)
}
object ScheduleFixture {
val createRequest: ScheduleCreateRequest = ScheduleCreateRequest(
date = LocalDate.now().plusDays(1),
time = LocalTime.now(),
themeId = 1L
)
}

View File

@ -43,11 +43,11 @@ class LoginUtil(
} }
fun loginAsAdmin(): String { fun loginAsAdmin(): String {
return login(MemberFixture.admin().email, MemberFixture.admin().password, Role.ADMIN) return login(MemberFixtureV2.admin.email, MemberFixtureV2.admin.password, Role.ADMIN)
} }
fun loginAsUser(): String { fun loginAsUser(): String {
return login(MemberFixture.user().email, MemberFixture.user().password) return login(MemberFixtureV2.user.email, MemberFixtureV2.user.password)
} }
} }