From b8cf1d6c9d796af35ce6bd2e1117daad8b0a24ab Mon Sep 17 00:00:00 2001 From: pricelees Date: Wed, 17 Sep 2025 13:00:54 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=20=EC=B6=94=EA=B0=80=EB=90=9C=20Store=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=8F=84=EC=9E=85=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EB=A7=88=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomescape/supports/DummyInitializer.kt | 20 ++++++ .../kotlin/roomescape/supports/Fixtures.kt | 9 ++- .../roomescape/supports/KotestConfig.kt | 4 +- ...inThemeApiTest.kt => AdminThemeApiTest.kt} | 67 +++++++++++++++++-- .../theme/StoreAdminThemeApiTest.kt | 67 ------------------- ...{PublicThemeApiTest.kt => ThemeApiTest.kt} | 3 +- 6 files changed, 92 insertions(+), 78 deletions(-) rename src/test/kotlin/roomescape/theme/{HQAdminThemeApiTest.kt => AdminThemeApiTest.kt} (92%) delete mode 100644 src/test/kotlin/roomescape/theme/StoreAdminThemeApiTest.kt rename src/test/kotlin/roomescape/theme/{PublicThemeApiTest.kt => ThemeApiTest.kt} (98%) diff --git a/src/test/kotlin/roomescape/supports/DummyInitializer.kt b/src/test/kotlin/roomescape/supports/DummyInitializer.kt index 6b4309f6..90c9b082 100644 --- a/src/test/kotlin/roomescape/supports/DummyInitializer.kt +++ b/src/test/kotlin/roomescape/supports/DummyInitializer.kt @@ -5,6 +5,7 @@ import io.restassured.module.kotlin.extensions.Given import io.restassured.module.kotlin.extensions.When import org.springframework.data.repository.findByIdOrNull import org.springframework.http.MediaType +import roomescape.common.config.next import roomescape.payment.business.PaymentWriter import roomescape.payment.infrastructure.client.CardDetail 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.web.ScheduleCreateRequest 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.ThemeRepository import roomescape.theme.web.ThemeCreateRequest import java.time.LocalDateTime class DummyInitializer( + private val storeRepository: StoreRepository, private val themeRepository: ThemeRepository, private val scheduleRepository: ScheduleRepository, private val reservationRepository: ReservationRepository, @@ -241,4 +246,19 @@ class DummyInitializer( return reservationRepository.findByIdOrNull(createdReservationId) ?: 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) + } + } } diff --git a/src/test/kotlin/roomescape/supports/Fixtures.kt b/src/test/kotlin/roomescape/supports/Fixtures.kt index a83fb6f8..a4b62fea 100644 --- a/src/test/kotlin/roomescape/supports/Fixtures.kt +++ b/src/test/kotlin/roomescape/supports/Fixtures.kt @@ -12,6 +12,7 @@ import roomescape.payment.web.PaymentConfirmRequest import roomescape.reservation.web.PendingReservationCreateRequest import roomescape.schedule.web.ScheduleCreateRequest import roomescape.store.infrastructure.persistence.StoreEntity +import roomescape.store.infrastructure.persistence.StoreStatus import roomescape.theme.infrastructure.persistence.Difficulty import roomescape.theme.web.ThemeCreateRequest import roomescape.user.infrastructure.persistence.UserEntity @@ -32,15 +33,17 @@ object StoreFixture { name: String = "테스트-${randomString()}점", address: String = "서울특별시 강북구 행복길 123", contact: String = randomPhoneNumber(), - businessRegNum: String = "123-45-67890", - regionCode: String = "1111000000" + businessRegNum: String = randomBusinessRegNum(), + regionCode: String = "1111000000", + status: StoreStatus = StoreStatus.ACTIVE ) = StoreEntity( id = id, name = name, address = address, contact = contact, businessRegNum = businessRegNum, - regionCode = regionCode + regionCode = regionCode, + status = status ) } diff --git a/src/test/kotlin/roomescape/supports/KotestConfig.kt b/src/test/kotlin/roomescape/supports/KotestConfig.kt index 5ee8b11c..280c2a52 100644 --- a/src/test/kotlin/roomescape/supports/KotestConfig.kt +++ b/src/test/kotlin/roomescape/supports/KotestConfig.kt @@ -59,6 +59,7 @@ abstract class FunSpecSpringbootTest : FunSpec({ class TestConfig { @Bean fun dummyInitializer( + storeRepository: StoreRepository, themeRepository: ThemeRepository, scheduleRepository: ScheduleRepository, reservationRepository: ReservationRepository, @@ -70,7 +71,8 @@ class TestConfig { scheduleRepository = scheduleRepository, reservationRepository = reservationRepository, paymentWriter = paymentWriter, - paymentRepository = paymentRepository + paymentRepository = paymentRepository, + storeRepository = storeRepository ) } } diff --git a/src/test/kotlin/roomescape/theme/HQAdminThemeApiTest.kt b/src/test/kotlin/roomescape/theme/AdminThemeApiTest.kt similarity index 92% rename from src/test/kotlin/roomescape/theme/HQAdminThemeApiTest.kt rename to src/test/kotlin/roomescape/theme/AdminThemeApiTest.kt index 50f2ba2f..898a3d46 100644 --- a/src/test/kotlin/roomescape/theme/HQAdminThemeApiTest.kt +++ b/src/test/kotlin/roomescape/theme/AdminThemeApiTest.kt @@ -21,7 +21,7 @@ import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeRepository import roomescape.theme.web.ThemeUpdateRequest -class HQAdminThemeApiTest( +class AdminThemeApiTest( private val themeRepository: ThemeRepository ) : 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("테마 요약 목록을 조회한다.") { val endpoint = "/admin/themes" @@ -361,14 +413,19 @@ class HQAdminThemeApiTest( }, expect = { statusCode(HttpStatus.OK.value()) - body("data.id", equalTo(createdTheme.id)) + body("data.theme.id", equalTo(createdTheme.id)) + assertProperties(props = setOf("theme", "isActive", "audit")) assertProperties( props = setOf( - "id", "name", "description", "thumbnailUrl", "difficulty", "price", "isActive", + "id", "name", "description", "thumbnailUrl", "difficulty", "price", "minParticipants", "maxParticipants", "availableMinutes", "expectedMinutesFrom", "expectedMinutesTo", - "createdAt", "createdBy", "updatedAt", "updatedBy" - ) + ), + propsNameIfList = "theme" + ) + assertProperties( + props = setOf("createdAt", "createdBy", "updatedAt", "updatedBy"), + propsNameIfList = "audit" ) } ) diff --git a/src/test/kotlin/roomescape/theme/StoreAdminThemeApiTest.kt b/src/test/kotlin/roomescape/theme/StoreAdminThemeApiTest.kt deleted file mode 100644 index 69885294..00000000 --- a/src/test/kotlin/roomescape/theme/StoreAdminThemeApiTest.kt +++ /dev/null @@ -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" - ) - }, - ) - } - } - } -} diff --git a/src/test/kotlin/roomescape/theme/PublicThemeApiTest.kt b/src/test/kotlin/roomescape/theme/ThemeApiTest.kt similarity index 98% rename from src/test/kotlin/roomescape/theme/PublicThemeApiTest.kt rename to src/test/kotlin/roomescape/theme/ThemeApiTest.kt index a872dc87..596af41d 100644 --- a/src/test/kotlin/roomescape/theme/PublicThemeApiTest.kt +++ b/src/test/kotlin/roomescape/theme/ThemeApiTest.kt @@ -9,7 +9,7 @@ import roomescape.theme.exception.ThemeErrorCode import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.web.ThemeIdListRequest -class PublicThemeApiTest : FunSpecSpringbootTest() { +class ThemeApiTest : FunSpecSpringbootTest() { init { context("입력된 모든 ID에 대한 테마를 조회한다.") { test("정상 응답 + 없는 테마가 있으면 생략한다.") { @@ -38,7 +38,6 @@ class PublicThemeApiTest : FunSpecSpringbootTest() { } } - context("ID로 테마 정보를 조회한다.") { test("정상 응답") { val createdTheme: ThemeEntity = initialize("조회를 위한 테마 생성") {