test: 테마 API 권한 변경에 따른 테스트 수정

This commit is contained in:
이상진 2025-09-14 23:35:22 +09:00
parent 7d2fd3b667
commit c3eceedea1
2 changed files with 159 additions and 47 deletions

View File

@ -64,12 +64,53 @@ object AdminFixture {
storeId = null storeId = null
) )
fun createStoreAdmin(
id: Long = tsidFactory.next(),
account: String = "admin",
password: String = "adminPassword",
name: String = "admin12345",
phone: String = randomPhoneNumber(),
storeId: Long = tsidFactory.next(),
permissionLevel: AdminPermissionLevel = AdminPermissionLevel.FULL_ACCESS
): AdminEntity {
return create(
id = id,
account = account,
password = password,
name = name,
phone = phone,
type = AdminType.STORE,
storeId = storeId,
permissionLevel = permissionLevel
)
}
fun createHqAdmin(
id: Long = tsidFactory.next(),
account: String = "admin",
password: String = "adminPassword",
name: String = "admin12345",
phone: String = randomPhoneNumber(),
permissionLevel: AdminPermissionLevel = AdminPermissionLevel.FULL_ACCESS
): AdminEntity {
return create(
id = id,
account = account,
password = password,
name = name,
phone = phone,
type = AdminType.HQ,
storeId = null,
permissionLevel = permissionLevel
)
}
fun create( fun create(
id: Long = tsidFactory.next(), id: Long = tsidFactory.next(),
account: String = "admin", account: String = "admin",
password: String = "adminPassword", password: String = "adminPassword",
name: String = "admin12345", name: String = "admin12345",
phone: String = "01012345678", phone: String = randomPhoneNumber(),
type: AdminType = AdminType.STORE, type: AdminType = AdminType.STORE,
storeId: Long? = tsidFactory.next(), storeId: Long? = tsidFactory.next(),
permissionLevel: AdminPermissionLevel = AdminPermissionLevel.FULL_ACCESS permissionLevel: AdminPermissionLevel = AdminPermissionLevel.FULL_ACCESS

View File

@ -11,6 +11,7 @@ import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import roomescape.admin.infrastructure.persistence.AdminPermissionLevel import roomescape.admin.infrastructure.persistence.AdminPermissionLevel
import roomescape.admin.infrastructure.persistence.AdminType
import roomescape.auth.exception.AuthErrorCode import roomescape.auth.exception.AuthErrorCode
import roomescape.theme.business.MIN_DURATION import roomescape.theme.business.MIN_DURATION
import roomescape.theme.business.MIN_PARTICIPANTS import roomescape.theme.business.MIN_PARTICIPANTS
@ -52,9 +53,9 @@ class ThemeApiTest(
) )
} }
listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { AdminPermissionLevel.entries.forEach {
test("권한이 ${it}인 관리자") { test("관리자: Type=${AdminType.STORE} / Permission=${it}") {
val admin = AdminFixture.create(permissionLevel = it) val admin = AdminFixture.createStoreAdmin(permissionLevel = it)
runExceptionTest( runExceptionTest(
token = authUtil.adminLogin(admin), token = authUtil.adminLogin(admin),
@ -64,12 +65,26 @@ class ThemeApiTest(
expectedErrorCode = AuthErrorCode.ACCESS_DENIED expectedErrorCode = AuthErrorCode.ACCESS_DENIED
) )
} }
if (it == AdminPermissionLevel.READ_ALL || it == AdminPermissionLevel.READ_SUMMARY) {
test("관리자: Type=${AdminType.HQ} / Permission=${it}") {
val admin = AdminFixture.createHqAdmin(permissionLevel = it)
runExceptionTest(
token = authUtil.adminLogin(admin),
method = HttpMethod.POST,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
} }
} }
test("정상 생성 및 감사 정보 확인") { test("정상 생성 및 감사 정보 확인") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
@ -97,7 +112,7 @@ class ThemeApiTest(
} }
test("이미 동일한 이름의 테마가 있으면 실패한다.") { test("이미 동일한 이름의 테마가 있으면 실패한다.") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
val commonName = "test123" val commonName = "test123"
dummyInitializer.createTheme( dummyInitializer.createTheme(
adminToken = token, adminToken = token,
@ -120,7 +135,7 @@ class ThemeApiTest(
} }
test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") { test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -143,7 +158,7 @@ class ThemeApiTest(
} }
test("field: availableMinutes") { test("field: availableMinutes") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -157,7 +172,7 @@ class ThemeApiTest(
} }
test("field: expectedMinutesFrom") { test("field: expectedMinutesFrom") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -171,7 +186,7 @@ class ThemeApiTest(
} }
test("field: expectedMinutesTo") { test("field: expectedMinutesTo") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -187,7 +202,7 @@ class ThemeApiTest(
context("시간 범위가 잘못 지정되면 실패한다.") { context("시간 범위가 잘못 지정되면 실패한다.") {
test("최소 예상 시간 > 최대 예상 시간") { test("최소 예상 시간 > 최대 예상 시간") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -204,7 +219,7 @@ class ThemeApiTest(
} }
test("최대 예상 시간 > 이용 가능 시간") { test("최대 예상 시간 > 이용 가능 시간") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -234,7 +249,7 @@ class ThemeApiTest(
} }
test("field: minParticipants") { test("field: minParticipants") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -248,7 +263,7 @@ class ThemeApiTest(
} }
test("field: maxParticipants") { test("field: maxParticipants") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -264,7 +279,7 @@ class ThemeApiTest(
context("인원 범위가 잘못 지정되면 실패한다.") { context("인원 범위가 잘못 지정되면 실패한다.") {
test("최소 인원 > 최대 인원") { test("최소 인원 > 최대 인원") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
runTest( runTest(
token = token, token = token,
using = { using = {
@ -284,7 +299,7 @@ class ThemeApiTest(
context("입력된 모든 ID에 대한 테마를 조회한다.") { context("입력된 모든 ID에 대한 테마를 조회한다.") {
test("정상 응답") { test("정상 응답") {
val adminToken = authUtil.defaultStoreAdminLogin() val adminToken = authUtil.defaultHqAdminLogin()
val themeSize = 3 val themeSize = 3
val themeIds = mutableListOf<Long>() val themeIds = mutableListOf<Long>()
@ -309,7 +324,7 @@ class ThemeApiTest(
} }
test("없는 테마가 있으면 생략한다.") { test("없는 테마가 있으면 생략한다.") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
val themeSize = 3 val themeSize = 3
val themeIds = mutableListOf<Long>() val themeIds = mutableListOf<Long>()
@ -359,11 +374,25 @@ class ThemeApiTest(
expectedErrorCode = AuthErrorCode.ACCESS_DENIED expectedErrorCode = AuthErrorCode.ACCESS_DENIED
) )
} }
AdminPermissionLevel.entries.forEach {
test("관리자: Type=${AdminType.STORE} / Permission=${it}") {
val admin = AdminFixture.createStoreAdmin(permissionLevel = it)
runExceptionTest(
token = authUtil.adminLogin(admin),
method = HttpMethod.POST,
requestBody = createRequest,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
} }
test("비공개 테마까지 포함하여 간단한 정보만 조회된다.") { test("비공개 테마까지 포함하여 간단한 정보만 조회된다.") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
requests.forEach { dummyInitializer.createTheme(token, it) } requests.forEach { dummyInitializer.createTheme(token, it) }
runTest( runTest(
@ -384,7 +413,7 @@ class ThemeApiTest(
context("예약 페이지에서 테마를 조회한다.") { context("예약 페이지에서 테마를 조회한다.") {
test("공개된 테마의 전체 정보가 조회된다.") { test("공개된 테마의 전체 정보가 조회된다.") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
listOf( listOf(
createRequest.copy(name = "open", isOpen = true), createRequest.copy(name = "open", isOpen = true),
createRequest.copy(name = "close", isOpen = false) createRequest.copy(name = "close", isOpen = false)
@ -434,20 +463,35 @@ class ThemeApiTest(
) )
} }
test("권한이 ${AdminPermissionLevel.READ_SUMMARY}인 관리자") { AdminPermissionLevel.entries.forEach {
val admin = AdminFixture.create(permissionLevel = AdminPermissionLevel.READ_SUMMARY) test("관리자: Type=${AdminType.STORE} / Permission=${it}") {
val admin = AdminFixture.createStoreAdmin(permissionLevel = it)
runExceptionTest( runExceptionTest(
token = authUtil.adminLogin(admin), token = authUtil.adminLogin(admin),
method = HttpMethod.GET, method = HttpMethod.GET,
endpoint = endpoint, endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED expectedErrorCode = AuthErrorCode.ACCESS_DENIED
) )
}
if (it == AdminPermissionLevel.READ_SUMMARY) {
test("관리자: Type=${AdminType.HQ} / Permission=${it}") {
val admin = AdminFixture.createHqAdmin(permissionLevel = it)
runExceptionTest(
token = authUtil.adminLogin(admin),
method = HttpMethod.GET,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
} }
} }
test("정상 응답") { test("정상 응답") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
val createdTheme = dummyInitializer.createTheme( val createdTheme = dummyInitializer.createTheme(
adminToken = token, adminToken = token,
request = createRequest request = createRequest
@ -475,7 +519,7 @@ class ThemeApiTest(
test("테마가 없으면 실패한다.") { test("테마가 없으면 실패한다.") {
runExceptionTest( runExceptionTest(
token = authUtil.defaultStoreAdminLogin(), token = authUtil.defaultHqAdminLogin(),
method = HttpMethod.GET, method = HttpMethod.GET,
endpoint = "/admin/themes/$INVALID_PK", endpoint = "/admin/themes/$INVALID_PK",
expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND
@ -505,9 +549,9 @@ class ThemeApiTest(
) )
} }
listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { AdminPermissionLevel.entries.forEach {
test("권한이 ${it}인 관리자") { test("관리자: Type=${AdminType.STORE} / Permission=${it}") {
val admin = AdminFixture.create(permissionLevel = it) val admin = AdminFixture.createStoreAdmin(permissionLevel = it)
runExceptionTest( runExceptionTest(
token = authUtil.adminLogin(admin), token = authUtil.adminLogin(admin),
@ -516,11 +560,24 @@ class ThemeApiTest(
expectedErrorCode = AuthErrorCode.ACCESS_DENIED expectedErrorCode = AuthErrorCode.ACCESS_DENIED
) )
} }
if (it == AdminPermissionLevel.READ_ALL || it == AdminPermissionLevel.READ_SUMMARY) {
test("관리자: Type=${AdminType.HQ} / Permission=${it}") {
val admin = AdminFixture.createHqAdmin(permissionLevel = it)
runExceptionTest(
token = authUtil.adminLogin(admin),
method = HttpMethod.DELETE,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
} }
} }
test("정상 삭제") { test("정상 삭제") {
val token = authUtil.defaultStoreAdminLogin() val token = authUtil.defaultHqAdminLogin()
val createdTheme = dummyInitializer.createTheme( val createdTheme = dummyInitializer.createTheme(
adminToken = token, adminToken = token,
request = createRequest request = createRequest
@ -541,7 +598,7 @@ class ThemeApiTest(
test("테마가 없으면 실패한다.") { test("테마가 없으면 실패한다.") {
runExceptionTest( runExceptionTest(
token = authUtil.defaultStoreAdminLogin(), token = authUtil.defaultHqAdminLogin(),
method = HttpMethod.DELETE, method = HttpMethod.DELETE,
endpoint = "/admin/themes/$INVALID_PK", endpoint = "/admin/themes/$INVALID_PK",
expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND expectedErrorCode = ThemeErrorCode.THEME_NOT_FOUND
@ -573,9 +630,9 @@ class ThemeApiTest(
) )
} }
listOf(AdminPermissionLevel.READ_SUMMARY, AdminPermissionLevel.READ_ALL).forEach { AdminPermissionLevel.entries.forEach {
test("권한이 ${it}인 관리자") { test("관리자: Type=${AdminType.STORE} / Permission=${it}") {
val admin = AdminFixture.create(permissionLevel = it) val admin = AdminFixture.createStoreAdmin(permissionLevel = it)
runExceptionTest( runExceptionTest(
token = authUtil.adminLogin(admin), token = authUtil.adminLogin(admin),
@ -585,6 +642,20 @@ class ThemeApiTest(
expectedErrorCode = AuthErrorCode.ACCESS_DENIED expectedErrorCode = AuthErrorCode.ACCESS_DENIED
) )
} }
if (it == AdminPermissionLevel.READ_ALL || it == AdminPermissionLevel.READ_SUMMARY) {
test("관리자: Type=${AdminType.HQ} / Permission=${it}") {
val admin = AdminFixture.createHqAdmin(permissionLevel = it)
runExceptionTest(
token = authUtil.adminLogin(admin),
method = HttpMethod.PATCH,
endpoint = endpoint,
requestBody = request,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
} }
} }
@ -592,11 +663,11 @@ class ThemeApiTest(
test("정상 수정 및 감사 정보 변경 확인") { test("정상 수정 및 감사 정보 변경 확인") {
val createdTheme: ThemeEntity = dummyInitializer.createTheme( val createdTheme: ThemeEntity = dummyInitializer.createTheme(
adminToken = authUtil.defaultStoreAdminLogin(), adminToken = authUtil.defaultHqAdminLogin(),
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
) )
val otherAdminToken: String = authUtil.adminLogin( val otherAdminToken: String = authUtil.adminLogin(
AdminFixture.create(account = "hello", phone = "0101828402") AdminFixture.createHqAdmin(permissionLevel = AdminPermissionLevel.WRITABLE)
) )
runTest( runTest(
@ -622,12 +693,12 @@ class ThemeApiTest(
test("입력값이 없으면 수정하지 않는다.") { test("입력값이 없으면 수정하지 않는다.") {
val createdTheme: ThemeEntity = dummyInitializer.createTheme( val createdTheme: ThemeEntity = dummyInitializer.createTheme(
adminToken = authUtil.defaultStoreAdminLogin(), adminToken = authUtil.defaultHqAdminLogin(),
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
) )
runTest( runTest(
token = authUtil.defaultStoreAdminLogin(), token = authUtil.defaultHqAdminLogin(),
using = { using = {
body(ThemeUpdateRequest()) body(ThemeUpdateRequest())
}, },
@ -647,7 +718,7 @@ class ThemeApiTest(
test("테마가 없으면 실패한다.") { test("테마가 없으면 실패한다.") {
runExceptionTest( runExceptionTest(
token = authUtil.defaultStoreAdminLogin(), token = authUtil.defaultHqAdminLogin(),
method = HttpMethod.PATCH, method = HttpMethod.PATCH,
endpoint = "/admin/themes/$INVALID_PK", endpoint = "/admin/themes/$INVALID_PK",
requestBody = updateRequest, requestBody = updateRequest,
@ -656,7 +727,7 @@ class ThemeApiTest(
} }
test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") { test("금액이 ${MIN_PRICE}원 미만이면 실패한다.") {
val adminToken = authUtil.defaultStoreAdminLogin() val adminToken = authUtil.defaultHqAdminLogin()
val createdTheme: ThemeEntity = dummyInitializer.createTheme( val createdTheme: ThemeEntity = dummyInitializer.createTheme(
adminToken = adminToken, adminToken = adminToken,
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
@ -676,7 +747,7 @@ class ThemeApiTest(
lateinit var createdTheme: ThemeEntity lateinit var createdTheme: ThemeEntity
beforeTest { beforeTest {
adminToken = authUtil.defaultStoreAdminLogin() adminToken = authUtil.defaultHqAdminLogin()
createdTheme = dummyInitializer.createTheme( createdTheme = dummyInitializer.createTheme(
adminToken = adminToken, adminToken = adminToken,
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
@ -719,7 +790,7 @@ class ThemeApiTest(
lateinit var createdTheme: ThemeEntity lateinit var createdTheme: ThemeEntity
beforeTest { beforeTest {
adminToken = authUtil.defaultStoreAdminLogin() adminToken = authUtil.defaultHqAdminLogin()
createdTheme = dummyInitializer.createTheme( createdTheme = dummyInitializer.createTheme(
adminToken = adminToken, adminToken = adminToken,
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
@ -760,7 +831,7 @@ class ThemeApiTest(
lateinit var createdTheme: ThemeEntity lateinit var createdTheme: ThemeEntity
beforeTest { beforeTest {
adminToken = authUtil.defaultStoreAdminLogin() adminToken = authUtil.defaultHqAdminLogin()
createdTheme = dummyInitializer.createTheme( createdTheme = dummyInitializer.createTheme(
adminToken = adminToken, adminToken = adminToken,
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")
@ -793,7 +864,7 @@ class ThemeApiTest(
lateinit var createdTheme: ThemeEntity lateinit var createdTheme: ThemeEntity
beforeTest { beforeTest {
adminToken = authUtil.defaultStoreAdminLogin() adminToken = authUtil.defaultHqAdminLogin()
createdTheme = dummyInitializer.createTheme( createdTheme = dummyInitializer.createTheme(
adminToken = adminToken, adminToken = adminToken,
request = createRequest.copy(name = "theme-${Random.nextInt()}") request = createRequest.copy(name = "theme-${Random.nextInt()}")