[#39] '시간' -> '일정' 스키마 변경으로 테마별 시간 지정 #40

Merged
pricelees merged 16 commits from refactor/#39 into main 2025-09-04 04:14:12 +00:00
3 changed files with 80 additions and 42 deletions
Showing only changes of commit 43dbadba86 - Show all commits

View File

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