feat: 테스트에 새로 추가된 Store 기능 도입 및 테마 API 테스트

This commit is contained in:
이상진 2025-09-17 13:00:54 +09:00
parent dc37ae6d1a
commit b8cf1d6c9d
6 changed files with 92 additions and 78 deletions

View File

@ -5,6 +5,7 @@ import io.restassured.module.kotlin.extensions.Given
import io.restassured.module.kotlin.extensions.When import io.restassured.module.kotlin.extensions.When
import org.springframework.data.repository.findByIdOrNull import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.MediaType import org.springframework.http.MediaType
import roomescape.common.config.next
import roomescape.payment.business.PaymentWriter import roomescape.payment.business.PaymentWriter
import roomescape.payment.infrastructure.client.CardDetail import roomescape.payment.infrastructure.client.CardDetail
import roomescape.payment.infrastructure.client.EasyPayDetail import roomescape.payment.infrastructure.client.EasyPayDetail
@ -25,12 +26,16 @@ import roomescape.schedule.infrastructure.persistence.ScheduleRepository
import roomescape.schedule.infrastructure.persistence.ScheduleStatus import roomescape.schedule.infrastructure.persistence.ScheduleStatus
import roomescape.schedule.web.ScheduleCreateRequest import roomescape.schedule.web.ScheduleCreateRequest
import roomescape.schedule.web.ScheduleUpdateRequest import roomescape.schedule.web.ScheduleUpdateRequest
import roomescape.store.infrastructure.persistence.StoreEntity
import roomescape.store.infrastructure.persistence.StoreRepository
import roomescape.store.infrastructure.persistence.StoreStatus
import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.infrastructure.persistence.ThemeRepository import roomescape.theme.infrastructure.persistence.ThemeRepository
import roomescape.theme.web.ThemeCreateRequest import roomescape.theme.web.ThemeCreateRequest
import java.time.LocalDateTime import java.time.LocalDateTime
class DummyInitializer( class DummyInitializer(
private val storeRepository: StoreRepository,
private val themeRepository: ThemeRepository, private val themeRepository: ThemeRepository,
private val scheduleRepository: ScheduleRepository, private val scheduleRepository: ScheduleRepository,
private val reservationRepository: ReservationRepository, private val reservationRepository: ReservationRepository,
@ -241,4 +246,19 @@ class DummyInitializer(
return reservationRepository.findByIdOrNull(createdReservationId) return reservationRepository.findByIdOrNull(createdReservationId)
?: throw RuntimeException("unexpected error occurred") ?: throw RuntimeException("unexpected error occurred")
} }
fun createStore(): StoreEntity {
return StoreEntity(
id = tsidFactory.next(),
name = "Hello 매장-${System.currentTimeMillis()}",
address = "강북구 행복로 123",
contact = randomPhoneNumber(),
businessRegNum = randomBusinessRegNum(),
regionCode = "1111000000",
status = StoreStatus.ACTIVE
).also {
storeRepository.save(it)
}
}
} }

View File

@ -12,6 +12,7 @@ import roomescape.payment.web.PaymentConfirmRequest
import roomescape.reservation.web.PendingReservationCreateRequest import roomescape.reservation.web.PendingReservationCreateRequest
import roomescape.schedule.web.ScheduleCreateRequest import roomescape.schedule.web.ScheduleCreateRequest
import roomescape.store.infrastructure.persistence.StoreEntity import roomescape.store.infrastructure.persistence.StoreEntity
import roomescape.store.infrastructure.persistence.StoreStatus
import roomescape.theme.infrastructure.persistence.Difficulty import roomescape.theme.infrastructure.persistence.Difficulty
import roomescape.theme.web.ThemeCreateRequest import roomescape.theme.web.ThemeCreateRequest
import roomescape.user.infrastructure.persistence.UserEntity import roomescape.user.infrastructure.persistence.UserEntity
@ -32,15 +33,17 @@ object StoreFixture {
name: String = "테스트-${randomString()}", name: String = "테스트-${randomString()}",
address: String = "서울특별시 강북구 행복길 123", address: String = "서울특별시 강북구 행복길 123",
contact: String = randomPhoneNumber(), contact: String = randomPhoneNumber(),
businessRegNum: String = "123-45-67890", businessRegNum: String = randomBusinessRegNum(),
regionCode: String = "1111000000" regionCode: String = "1111000000",
status: StoreStatus = StoreStatus.ACTIVE
) = StoreEntity( ) = StoreEntity(
id = id, id = id,
name = name, name = name,
address = address, address = address,
contact = contact, contact = contact,
businessRegNum = businessRegNum, businessRegNum = businessRegNum,
regionCode = regionCode regionCode = regionCode,
status = status
) )
} }

View File

@ -59,6 +59,7 @@ abstract class FunSpecSpringbootTest : FunSpec({
class TestConfig { class TestConfig {
@Bean @Bean
fun dummyInitializer( fun dummyInitializer(
storeRepository: StoreRepository,
themeRepository: ThemeRepository, themeRepository: ThemeRepository,
scheduleRepository: ScheduleRepository, scheduleRepository: ScheduleRepository,
reservationRepository: ReservationRepository, reservationRepository: ReservationRepository,
@ -70,7 +71,8 @@ class TestConfig {
scheduleRepository = scheduleRepository, scheduleRepository = scheduleRepository,
reservationRepository = reservationRepository, reservationRepository = reservationRepository,
paymentWriter = paymentWriter, paymentWriter = paymentWriter,
paymentRepository = paymentRepository paymentRepository = paymentRepository,
storeRepository = storeRepository
) )
} }
} }

View File

@ -21,7 +21,7 @@ import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.infrastructure.persistence.ThemeRepository import roomescape.theme.infrastructure.persistence.ThemeRepository
import roomescape.theme.web.ThemeUpdateRequest import roomescape.theme.web.ThemeUpdateRequest
class HQAdminThemeApiTest( class AdminThemeApiTest(
private val themeRepository: ThemeRepository private val themeRepository: ThemeRepository
) : FunSpecSpringbootTest() { ) : FunSpecSpringbootTest() {
@ -236,6 +236,58 @@ class HQAdminThemeApiTest(
} }
} }
context("현재 active 상태인 모든 테마의 ID, 이름을 조회한다.") {
val endpoint = "/admin/themes/active"
context("권한이 없으면 접근할 수 없다.") {
test("비회원") {
runExceptionTest(
method = HttpMethod.GET,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND
)
}
test("회원") {
runExceptionTest(
token = testAuthUtil.defaultUserLogin(),
method = HttpMethod.GET,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
test("정상 응답") {
val createdThemes = initialize("Active 상태 테마 2개 / Inactive 상태 테마 1개 생성") {
val token = testAuthUtil.defaultHqAdminLogin()
listOf(
dummyInitializer.createTheme(token, createRequest.copy(name = "test1", isActive = true)),
dummyInitializer.createTheme(token, createRequest.copy(name = "test2", isActive = false)),
dummyInitializer.createTheme(token, createRequest.copy(name = "test3", isActive = true))
)
}
runTest(
token = testAuthUtil.defaultStoreAdminLogin(),
on = {
get(endpoint)
},
expect = {
statusCode(200)
body("data.themes.size()", equalTo(createdThemes.filter { it.isActive }.size))
assertProperties(
props = setOf("id", "name"),
propsNameIfList = "themes"
)
},
)
}
}
context("테마 요약 목록을 조회한다.") { context("테마 요약 목록을 조회한다.") {
val endpoint = "/admin/themes" val endpoint = "/admin/themes"
@ -361,14 +413,19 @@ class HQAdminThemeApiTest(
}, },
expect = { expect = {
statusCode(HttpStatus.OK.value()) statusCode(HttpStatus.OK.value())
body("data.id", equalTo(createdTheme.id)) body("data.theme.id", equalTo(createdTheme.id))
assertProperties(props = setOf("theme", "isActive", "audit"))
assertProperties( assertProperties(
props = setOf( props = setOf(
"id", "name", "description", "thumbnailUrl", "difficulty", "price", "isActive", "id", "name", "description", "thumbnailUrl", "difficulty", "price",
"minParticipants", "maxParticipants", "minParticipants", "maxParticipants",
"availableMinutes", "expectedMinutesFrom", "expectedMinutesTo", "availableMinutes", "expectedMinutesFrom", "expectedMinutesTo",
"createdAt", "createdBy", "updatedAt", "updatedBy" ),
propsNameIfList = "theme"
) )
assertProperties(
props = setOf("createdAt", "createdBy", "updatedAt", "updatedBy"),
propsNameIfList = "audit"
) )
} }
) )

View File

@ -1,67 +0,0 @@
package roomescape.theme
import org.hamcrest.CoreMatchers.equalTo
import org.springframework.http.HttpMethod
import roomescape.auth.exception.AuthErrorCode
import roomescape.supports.FunSpecSpringbootTest
import roomescape.supports.ThemeFixture.createRequest
import roomescape.supports.assertProperties
import roomescape.supports.initialize
import roomescape.supports.runExceptionTest
import roomescape.supports.runTest
class StoreAdminThemeApiTest : FunSpecSpringbootTest() {
init {
context("현재 active 상태인 모든 테마의 ID, 이름을 조회한다.") {
val endpoint = "/admin/themes/active"
context("권한이 없으면 접근할 수 없다.") {
test("비회원") {
runExceptionTest(
method = HttpMethod.GET,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND
)
}
test("회원") {
runExceptionTest(
token = testAuthUtil.defaultUserLogin(),
method = HttpMethod.GET,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
test("정상 응답") {
val createdThemes = initialize("Active 상태 테마 2개 / Inactive 상태 테마 1개 생성") {
val token = testAuthUtil.defaultHqAdminLogin()
listOf(
dummyInitializer.createTheme(token, createRequest.copy(name = "test1", isActive = true)),
dummyInitializer.createTheme(token, createRequest.copy(name = "test2", isActive = false)),
dummyInitializer.createTheme(token, createRequest.copy(name = "test3", isActive = true))
)
}
runTest(
token = testAuthUtil.defaultStoreAdminLogin(),
on = {
get(endpoint)
},
expect = {
statusCode(200)
body("data.themes.size()", equalTo(createdThemes.filter { it.isActive }.size))
assertProperties(
props = setOf("id", "name"),
propsNameIfList = "themes"
)
},
)
}
}
}
}

View File

@ -9,7 +9,7 @@ import roomescape.theme.exception.ThemeErrorCode
import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeEntity
import roomescape.theme.web.ThemeIdListRequest import roomescape.theme.web.ThemeIdListRequest
class PublicThemeApiTest : FunSpecSpringbootTest() { class ThemeApiTest : FunSpecSpringbootTest() {
init { init {
context("입력된 모든 ID에 대한 테마를 조회한다.") { context("입력된 모든 ID에 대한 테마를 조회한다.") {
test("정상 응답 + 없는 테마가 있으면 생략한다.") { test("정상 응답 + 없는 테마가 있으면 생략한다.") {
@ -38,7 +38,6 @@ class PublicThemeApiTest : FunSpecSpringbootTest() {
} }
} }
context("ID로 테마 정보를 조회한다.") { context("ID로 테마 정보를 조회한다.") {
test("정상 응답") { test("정상 응답") {
val createdTheme: ThemeEntity = initialize("조회를 위한 테마 생성") { val createdTheme: ThemeEntity = initialize("조회를 위한 테마 생성") {