From 741888f156e06037bf2f01247cb89db3a1ab0169 Mon Sep 17 00:00:00 2001 From: pricelees Date: Sat, 13 Sep 2025 11:51:05 +0900 Subject: [PATCH] =?UTF-8?q?test:=20=ED=85=8C=EB=A7=88=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=97=90=20=EC=83=88=EB=A1=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=90=9C=20=ED=9A=8C=EC=9B=90=20=EB=B0=8F=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EA=B6=8C=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/roomescape/theme/ThemeApiTest.kt | 707 ++++++++++-------- 1 file changed, 408 insertions(+), 299 deletions(-) diff --git a/src/test/kotlin/roomescape/theme/ThemeApiTest.kt b/src/test/kotlin/roomescape/theme/ThemeApiTest.kt index c96fa6a1..fd9e29a6 100644 --- a/src/test/kotlin/roomescape/theme/ThemeApiTest.kt +++ b/src/test/kotlin/roomescape/theme/ThemeApiTest.kt @@ -8,9 +8,10 @@ import io.restassured.response.ValidatableResponse import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.notNullValue import org.springframework.data.repository.findByIdOrNull +import org.springframework.http.HttpMethod import org.springframework.http.HttpStatus +import roomescape.admin.infrastructure.persistence.AdminPermissionLevel import roomescape.auth.exception.AuthErrorCode -import roomescape.member.infrastructure.persistence.Role import roomescape.theme.business.MIN_DURATION import roomescape.theme.business.MIN_PARTICIPANTS import roomescape.theme.business.MIN_PRICE @@ -19,11 +20,8 @@ import roomescape.theme.infrastructure.persistence.ThemeEntity import roomescape.theme.infrastructure.persistence.ThemeRepository import roomescape.theme.web.ThemeListRetrieveRequest import roomescape.theme.web.ThemeUpdateRequest -import roomescape.util.FunSpecSpringbootTest -import roomescape.util.INVALID_PK +import roomescape.util.* import roomescape.util.ThemeFixture.createRequest -import roomescape.util.assertProperties -import roomescape.util.runTest import kotlin.random.Random class ThemeApiTest( @@ -31,115 +29,55 @@ class ThemeApiTest( ) : FunSpecSpringbootTest() { init { - context("관리자가 아니면 접근할 수 없다.") { - lateinit var token: String - - beforeTest { - token = authUtil.loginAsUser() - } - - val commonAssertion: ValidatableResponse.() -> Unit = { - statusCode(HttpStatus.FORBIDDEN.value()) - body("code", equalTo(AuthErrorCode.ACCESS_DENIED.errorCode)) - } - - test("테마 생성: POST /admin/themes") { - runTest( - token = token, - using = { - body(createRequest) - }, - on = { - post("/admin/themes") - }, - expect = commonAssertion - ) - } - - test("테마 조회: GET /admin/themes") { - runTest( - token = token, - on = { - get("/admin/themes") - }, - expect = commonAssertion - ) - } - - test("테마 상세 조회: GET /admin/themes/{id}") { - runTest( - token = token, - on = { - get("/admin/themes/$INVALID_PK") - }, - expect = commonAssertion - ) - } - - test("테마 수정: PATCH /admin/themes/{id}") { - runTest( - token = token, - using = { - body(createRequest) - }, - on = { - patch("/admin/themes/$INVALID_PK") - }, - expect = commonAssertion - ) - } - - test("테마 삭제: DELETE /admin/themes/{id}") { - runTest( - token = token, - on = { - delete("/admin/themes/$INVALID_PK") - }, - expect = commonAssertion - ) - } - } - - context("일반 회원도 접근할 수 있다.") { - test("테마 조회: GET /v2/themes") { - val token = authUtil.loginAsUser() - - dummyInitializer.createTheme( - adminToken = authUtil.loginAsAdmin(), - request = createRequest.copy(name = "test123", isOpen = true) - ) - - runTest( - token = token, - on = { - get("/v2/themes") - }, - expect = { - statusCode(HttpStatus.OK.value()) - body("data.themes.size()", equalTo(1)) - body("data.themes[0].name", equalTo("test123")) - } - ) - } - } - context("테마를 생성한다.") { - val apiPath = "/admin/themes" + val endpoint = "/admin/themes" - lateinit var token: String + context("권한이 없으면 접근할 수 없다.") { + test("비회원") { + runExceptionTest( + method = HttpMethod.POST, + requestBody = createRequest, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } - beforeTest { - token = authUtil.loginAsAdmin() + test("회원") { + runExceptionTest( + token = authUtil.defaultUserLogin(), + method = HttpMethod.POST, + requestBody = createRequest, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + + listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { + test("권한이 ${it}인 관리자") { + val admin = AdminFixture.create(permissionLevel = it) + + runExceptionTest( + token = authUtil.adminLogin(admin), + method = HttpMethod.POST, + requestBody = createRequest, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + } } + test("정상 생성 및 감사 정보 확인") { + val token = authUtil.defaultAdminLogin() + runTest( token = token, using = { body(createRequest) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.CREATED.value()) @@ -159,6 +97,7 @@ class ThemeApiTest( } test("이미 동일한 이름의 테마가 있으면 실패한다.") { + val token = authUtil.defaultAdminLogin() val commonName = "test123" dummyInitializer.createTheme( adminToken = token, @@ -171,7 +110,7 @@ class ThemeApiTest( body(createRequest.copy(name = commonName)) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.BAD_REQUEST.value()) @@ -181,13 +120,14 @@ class ThemeApiTest( } test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(price = (MIN_PRICE - 1))) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.BAD_REQUEST.value()) @@ -203,39 +143,42 @@ class ThemeApiTest( } test("field: availableMinutes") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(availableMinutes = (MIN_DURATION - 1).toShort())) }, on = { - post(apiPath) + post(endpoint) }, expect = commonAssertion ) } test("field: expectedMinutesFrom") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(expectedMinutesFrom = (MIN_DURATION - 1).toShort())) }, on = { - post(apiPath) + post(endpoint) }, expect = commonAssertion ) } test("field: expectedMinutesTo") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(expectedMinutesTo = (MIN_DURATION - 1).toShort())) }, on = { - post(apiPath) + post(endpoint) }, expect = commonAssertion ) @@ -244,13 +187,14 @@ class ThemeApiTest( context("시간 범위가 잘못 지정되면 실패한다.") { test("최소 예상 시간 > 최대 예상 시간") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(expectedMinutesFrom = 100, expectedMinutesTo = 99)) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.BAD_REQUEST.value()) @@ -260,6 +204,7 @@ class ThemeApiTest( } test("최대 예상 시간 > 이용 가능 시간") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { @@ -272,7 +217,7 @@ class ThemeApiTest( ) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.BAD_REQUEST.value()) @@ -289,26 +234,28 @@ class ThemeApiTest( } test("field: minParticipants") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(minParticipants = (MIN_PARTICIPANTS - 1).toShort())) }, on = { - post(apiPath) + post(endpoint) }, expect = commonAssertion ) } test("field: maxParticipants") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(maxParticipants = (MIN_PARTICIPANTS - 1).toShort())) }, on = { - post(apiPath) + post(endpoint) }, expect = commonAssertion ) @@ -317,13 +264,14 @@ class ThemeApiTest( context("인원 범위가 잘못 지정되면 실패한다.") { test("최소 인원 > 최대 인원") { + val token = authUtil.defaultAdminLogin() runTest( token = token, using = { body(createRequest.copy(minParticipants = 10, maxParticipants = 9)) }, on = { - post(apiPath) + post(endpoint) }, expect = { statusCode(HttpStatus.BAD_REQUEST.value()) @@ -335,26 +283,41 @@ class ThemeApiTest( } context("입력된 모든 ID에 대한 테마를 조회한다.") { - val themeIds = mutableListOf() + val endpoint = "/themes/retrieve" - beforeTest { - for (i in 1..3) { - dummyInitializer.createTheme( - adminToken = authUtil.loginAsAdmin(), - request = createRequest.copy(name = "test$i") - ).also { - themeIds.add(it.id) - } + context("권한이 없으면 접근할 수 없다.") { + test("비회원") { + runExceptionTest( + method = HttpMethod.POST, + requestBody = ThemeListRetrieveRequest(themeIds = listOf()), + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("관리자") { + runExceptionTest( + token = authUtil.defaultAdminLogin(), + method = HttpMethod.POST, + requestBody = ThemeListRetrieveRequest(themeIds = listOf()), + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) } } - afterTest { - themeIds.clear() - } - test("정상 응답") { + val adminToken = authUtil.defaultAdminLogin() + val themeSize = 3 + val themeIds = mutableListOf() + + for (i in 1..themeSize) { + dummyInitializer.createTheme(adminToken, createRequest.copy(name = "test$i")) + .also { themeIds.add(it.id) } + } + runTest( - token = authUtil.loginAsUser(), + token = authUtil.defaultUserLogin(), using = { body(ThemeListRetrieveRequest(themeIds)) }, @@ -363,16 +326,24 @@ class ThemeApiTest( }, expect = { statusCode(HttpStatus.OK.value()) - body("data.themes.size()", equalTo(3)) + body("data.themes.size()", equalTo(themeSize)) } ) } test("없는 테마가 있으면 생략한다.") { - themeIds.add(INVALID_PK) + val token = authUtil.defaultAdminLogin() + val themeSize = 3 + val themeIds = mutableListOf() + for (i in 1..themeSize) { + dummyInitializer.createTheme(token, createRequest.copy(name = "test$i")) + .also { themeIds.add(it.id) } + } + + themeIds.add(INVALID_PK) runTest( - token = authUtil.loginAsUser(), + token = authUtil.defaultUserLogin(), using = { body(ThemeListRetrieveRequest(themeIds)) }, @@ -381,35 +352,50 @@ class ThemeApiTest( }, expect = { statusCode(HttpStatus.OK.value()) - body("data.themes.size()", equalTo(3)) + body("data.themes.size()", equalTo(themeSize)) } ) } } - context("모든 테마를 조회한다.") { - lateinit var token: String + context("관리자가 모든 테마를 조회한다.") { + val endpoint = "/admin/themes" + val requests = listOf( + createRequest.copy(name = "open", isOpen = true), + createRequest.copy(name = "close", isOpen = false) + ) - beforeTest { - token = authUtil.loginAsAdmin() - dummyInitializer.createTheme( - adminToken = token, - request = createRequest.copy(name = "open", isOpen = true) - ) - dummyInitializer.createTheme( - adminToken = token, - request = createRequest.copy(name = "close", isOpen = false) - ) + context("권한이 없으면 접근할 수 없다.") { + test("비회원") { + runExceptionTest( + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("회원") { + runExceptionTest( + token = authUtil.defaultUserLogin(), + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } } - test("관리자 페이지에서는 비공개 테마까지 포함하여 간단한 정보만 조회된다.") { + + test("비공개 테마까지 포함하여 간단한 정보만 조회된다.") { + val token = authUtil.defaultAdminLogin() + requests.forEach { dummyInitializer.createTheme(token, it) } + runTest( token = token, on = { get("/admin/themes") }, expect = { - body("data.themes.size()", equalTo(2)) + body("data.themes.size()", equalTo(requests.size)) assertProperties( props = setOf("id", "name", "difficulty", "price", "isOpen"), propsNameIfList = "themes", @@ -417,10 +403,41 @@ class ThemeApiTest( } ) } + } + + context("예약 페이지에서 테마를 조회한다.") { + val endpoint = "/v2/themes" + + context("권한이 없으면 접근할 수 없다.") { + test("비회원") { + runExceptionTest( + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("관리자") { + runExceptionTest( + token = authUtil.defaultAdminLogin(), + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + } + + test("공개된 테마의 전체 정보가 조회된다.") { + val token = authUtil.defaultAdminLogin() + listOf( + createRequest.copy(name = "open", isOpen = true), + createRequest.copy(name = "close", isOpen = false) + ).forEach { + dummyInitializer.createTheme(token, it) + } - test("예약 페이지에서는 공개된 테마의 전체 정보가 조회된다.") { runTest( - token = authUtil.loginAsUser(), + token = authUtil.defaultUserLogin(), on = { get("/v2/themes") }, @@ -441,8 +458,40 @@ class ThemeApiTest( } context("관리자 페이지에서 특정 테마의 상세 정보를 조회한다.") { + context("권한이 없으면 접근할 수 없다.") { + val endpoint = "/admin/themes/$INVALID_PK" + + test("비회원") { + runExceptionTest( + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("회원") { + runExceptionTest( + token = authUtil.defaultUserLogin(), + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + + test("권한이 ${AdminPermissionLevel.READ_SUMMARY}인 관리자") { + val admin = AdminFixture.create(permissionLevel = AdminPermissionLevel.READ_SUMMARY) + + runExceptionTest( + token = authUtil.adminLogin(admin), + method = HttpMethod.GET, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + } + test("정상 응답") { - val token = authUtil.loginAsAdmin() + val token = authUtil.defaultAdminLogin() val createdTheme = dummyInitializer.createTheme( adminToken = token, request = createRequest @@ -469,22 +518,53 @@ class ThemeApiTest( } test("테마가 없으면 실패한다.") { - runTest( - token = authUtil.loginAsAdmin(), - on = { - get("/admin/themes/$INVALID_PK") - }, - expect = { - statusCode(HttpStatus.NOT_FOUND.value()) - body("code", equalTo(ThemeErrorCode.THEME_NOT_FOUND.errorCode)) - } + runExceptionTest( + token = authUtil.defaultAdminLogin(), + method = HttpMethod.GET, + endpoint = "/admin/themes/$INVALID_PK", + expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND ) } } context("테마를 삭제한다.") { + + context("권한이 없으면 접근할 수 없다.") { + val endpoint = "/admin/themes/${INVALID_PK}" + + test("비회원") { + runExceptionTest( + method = HttpMethod.DELETE, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("회원") { + runExceptionTest( + token = authUtil.defaultUserLogin(), + method = HttpMethod.DELETE, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + + listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { + test("권한이 ${it}인 관리자") { + val admin = AdminFixture.create(permissionLevel = it) + + runExceptionTest( + token = authUtil.adminLogin(admin), + method = HttpMethod.DELETE, + endpoint = endpoint, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + } + } + test("정상 삭제") { - val token = authUtil.loginAsAdmin() + val token = authUtil.defaultAdminLogin() val createdTheme = dummyInitializer.createTheme( adminToken = token, request = createRequest @@ -504,37 +584,64 @@ class ThemeApiTest( } test("테마가 없으면 실패한다.") { - runTest( - token = authUtil.loginAsAdmin(), - on = { - delete("/admin/themes/$INVALID_PK") - }, - expect = { - statusCode(HttpStatus.NOT_FOUND.value()) - body("code", equalTo(ThemeErrorCode.THEME_NOT_FOUND.errorCode)) - } + runExceptionTest( + token = authUtil.defaultAdminLogin(), + method = HttpMethod.DELETE, + endpoint = "/admin/themes/$INVALID_PK", + expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND ) } } context("테마를 수정한다.") { - lateinit var token: String - lateinit var createdTheme: ThemeEntity - lateinit var apiPath: String + context("권한이 없으면 접근할 수 없다.") { + val endpoint = "/admin/themes/${INVALID_PK}" + val request = ThemeUpdateRequest(name = "hello") + + test("비회원") { + runExceptionTest( + method = HttpMethod.PATCH, + endpoint = endpoint, + requestBody = request, + expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND + ) + } + + test("회원") { + runExceptionTest( + token = authUtil.defaultUserLogin(), + method = HttpMethod.PATCH, + endpoint = endpoint, + requestBody = request, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + + listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { + test("권한이 ${it}인 관리자") { + val admin = AdminFixture.create(permissionLevel = it) + + runExceptionTest( + token = authUtil.adminLogin(admin), + method = HttpMethod.PATCH, + endpoint = endpoint, + requestBody = request, + expectedErrorCode = AuthErrorCode.ACCESS_DENIED + ) + } + } + } val updateRequest = ThemeUpdateRequest(name = "modified") - beforeTest { - token = authUtil.loginAsAdmin() - createdTheme = dummyInitializer.createTheme( - adminToken = token, + test("정상 수정 및 감사 정보 변경 확인") { + val createdTheme: ThemeEntity = dummyInitializer.createTheme( + adminToken = authUtil.defaultAdminLogin(), request = createRequest.copy(name = "theme-${Random.nextInt()}") ) - apiPath = "/admin/themes/${createdTheme.id}" - } - - test("정상 수정 및 감사 정보 변경 확인") { - val otherAdminToken = authUtil.login("admin1@admin.com", "admin1", Role.ADMIN) + val otherAdminToken: String = authUtil.adminLogin( + AdminFixture.create(account = "hello", phone = "0101828402") + ) runTest( token = otherAdminToken, @@ -542,7 +649,7 @@ class ThemeApiTest( body(updateRequest) }, on = { - patch(apiPath) + patch("/admin/themes/${createdTheme.id}") }, expect = { statusCode(HttpStatus.OK.value()) @@ -558,13 +665,18 @@ class ThemeApiTest( } test("입력값이 없으면 수정하지 않는다.") { + val createdTheme: ThemeEntity = dummyInitializer.createTheme( + adminToken = authUtil.defaultAdminLogin(), + request = createRequest.copy(name = "theme-${Random.nextInt()}") + ) + runTest( - token = authUtil.loginAsAdmin(), + token = authUtil.defaultAdminLogin(), using = { body(ThemeUpdateRequest()) }, on = { - patch(apiPath) + patch("/admin/themes/${createdTheme.id}") }, expect = { statusCode(HttpStatus.OK.value()) @@ -578,170 +690,167 @@ class ThemeApiTest( } test("테마가 없으면 실패한다.") { - runTest( - token = token, - using = { - body(updateRequest) - }, - on = { - patch("/admin/themes/$INVALID_PK") - }, - expect = { - statusCode(HttpStatus.NOT_FOUND.value()) - body("code", equalTo(ThemeErrorCode.THEME_NOT_FOUND.errorCode)) - } + runExceptionTest( + token = authUtil.defaultAdminLogin(), + method = HttpMethod.PATCH, + endpoint = "/admin/themes/$INVALID_PK", + requestBody = updateRequest, + expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND ) } test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") { - runTest( - token = token, - using = { - body(updateRequest.copy(price = (MIN_PRICE - 1))) - }, - on = { - patch("/admin/themes/${createdTheme.id}") - }, - expect = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.PRICE_BELOW_MINIMUM.errorCode)) - } + val adminToken = authUtil.defaultAdminLogin() + val createdTheme: ThemeEntity = dummyInitializer.createTheme( + adminToken = adminToken, + request = createRequest.copy(name = "theme-${Random.nextInt()}") + ) + + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(price = (MIN_PRICE - 1)), + expectedErrorCode = ThemeErrorCode.PRICE_BELOW_MINIMUM ) } context("입력된 시간이 ${MIN_DURATION}분 미만이면 실패한다.") { - val commonAssertion: ValidatableResponse.() -> Unit = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.DURATION_BELOW_MINIMUM.errorCode)) + lateinit var adminToken: String + lateinit var createdTheme: ThemeEntity + + beforeTest { + adminToken = authUtil.defaultAdminLogin() + createdTheme = dummyInitializer.createTheme( + adminToken = adminToken, + request = createRequest.copy(name = "theme-${Random.nextInt()}") + ) } test("field: availableMinutes") { - runTest( - token = token, - using = { - body(updateRequest.copy(availableMinutes = (MIN_DURATION - 1).toShort())) - }, - on = { - patch(apiPath) - }, - expect = commonAssertion + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(availableMinutes = (MIN_DURATION - 1).toShort()), + expectedErrorCode = ThemeErrorCode.DURATION_BELOW_MINIMUM ) } test("field: expectedMinutesFrom") { - runTest( - token = token, - using = { - body(updateRequest.copy(expectedMinutesFrom = (MIN_DURATION - 1).toShort())) - }, - on = { - patch(apiPath) - }, - expect = commonAssertion + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(expectedMinutesFrom = (MIN_DURATION - 1).toShort()), + expectedErrorCode = ThemeErrorCode.DURATION_BELOW_MINIMUM ) } test("field: expectedMinutesTo") { - runTest( - token = token, - using = { - body(updateRequest.copy(expectedMinutesTo = (MIN_DURATION - 1).toShort())) - }, - on = { - patch(apiPath) - }, - expect = commonAssertion + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(expectedMinutesTo = (MIN_DURATION - 1).toShort()), + expectedErrorCode = ThemeErrorCode.DURATION_BELOW_MINIMUM ) } } context("시간 범위가 잘못 지정되면 실패한다.") { - test("최소 예상 시간 > 최대 예상 시간") { - runTest( - token = token, - using = { - body(updateRequest.copy(expectedMinutesFrom = 100, expectedMinutesTo = 99)) - }, - on = { - patch(apiPath) - }, - expect = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.MIN_EXPECTED_TIME_EXCEEDS_MAX_EXPECTED_TIME.errorCode)) - } + lateinit var adminToken: String + lateinit var createdTheme: ThemeEntity + + beforeTest { + adminToken = authUtil.defaultAdminLogin() + createdTheme = dummyInitializer.createTheme( + adminToken = adminToken, + request = createRequest.copy(name = "theme-${Random.nextInt()}") ) } + test("최소 예상 시간 > 최대 예상 시간") { + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(expectedMinutesFrom = 100, expectedMinutesTo = 99), + expectedErrorCode = ThemeErrorCode.MIN_EXPECTED_TIME_EXCEEDS_MAX_EXPECTED_TIME + ) + } + + test("최대 예상 시간 > 이용 가능 시간") { - runTest( - token = token, - using = { - body( - updateRequest.copy( - availableMinutes = 100, - expectedMinutesFrom = 101, - expectedMinutesTo = 101 - ) - ) - }, - on = { - patch(apiPath) - }, - expect = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.EXPECTED_TIME_EXCEEDS_AVAILABLE_TIME.errorCode)) - } + val body = updateRequest.copy( + availableMinutes = 100, + expectedMinutesFrom = 101, + expectedMinutesTo = 101 + ) + + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = body, + expectedErrorCode = ThemeErrorCode.EXPECTED_TIME_EXCEEDS_AVAILABLE_TIME ) } } + context("입력된 인원이 ${MIN_PARTICIPANTS}명 미만이면 실패한다.") { - val commonAssertion: ValidatableResponse.() -> Unit = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.PARTICIPANT_BELOW_MINIMUM.errorCode)) + lateinit var adminToken: String + lateinit var createdTheme: ThemeEntity + + beforeTest { + adminToken = authUtil.defaultAdminLogin() + createdTheme = dummyInitializer.createTheme( + adminToken = adminToken, + request = createRequest.copy(name = "theme-${Random.nextInt()}") + ) } test("field: minParticipants") { - runTest( - token = token, - using = { - body(updateRequest.copy(minParticipants = (MIN_PARTICIPANTS - 1).toShort())) - }, - on = { - patch(apiPath) - }, - expect = commonAssertion + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(minParticipants = (MIN_PARTICIPANTS - 1).toShort()), + expectedErrorCode = ThemeErrorCode.PARTICIPANT_BELOW_MINIMUM ) } test("field: maxParticipants") { - runTest( - token = token, - using = { - body(updateRequest.copy(maxParticipants = (MIN_PARTICIPANTS - 1).toShort())) - }, - on = { - patch(apiPath) - }, - expect = commonAssertion + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(maxParticipants = (MIN_PARTICIPANTS - 1).toShort()), + expectedErrorCode = ThemeErrorCode.PARTICIPANT_BELOW_MINIMUM ) } } context("인원 범위가 잘못 지정되면 실패한다.") { + lateinit var adminToken: String + lateinit var createdTheme: ThemeEntity + + beforeTest { + adminToken = authUtil.defaultAdminLogin() + createdTheme = dummyInitializer.createTheme( + adminToken = adminToken, + request = createRequest.copy(name = "theme-${Random.nextInt()}") + ) + } + test("최소 인원 > 최대 인원") { - runTest( - token = token, - using = { - body(updateRequest.copy(minParticipants = 10, maxParticipants = 9)) - }, - on = { - patch(apiPath) - }, - expect = { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("code", equalTo(ThemeErrorCode.MIN_PARTICIPANT_EXCEEDS_MAX_PARTICIPANT.errorCode)) - } + runExceptionTest( + token = adminToken, + method = HttpMethod.PATCH, + endpoint = "/admin/themes/${createdTheme.id}", + requestBody = updateRequest.copy(minParticipants = 10, maxParticipants = 9), + expectedErrorCode = ThemeErrorCode.MIN_PARTICIPANT_EXCEEDS_MAX_PARTICIPANT ) } }