[#37] 테마 스키마 재정의 #38

Merged
pricelees merged 13 commits from refactor/#37-1 into main 2025-09-03 02:03:37 +00:00
Showing only changes of commit 915ed71c99 - Show all commits

View File

@ -0,0 +1,106 @@
package roomescape.util
import io.restassured.module.kotlin.extensions.Extract
import io.restassured.module.kotlin.extensions.Given
import io.restassured.module.kotlin.extensions.Then
import io.restassured.module.kotlin.extensions.When
import io.restassured.response.Response
import io.restassured.response.ValidatableResponse
import io.restassured.specification.RequestSpecification
import org.springframework.http.MediaType
import roomescape.auth.web.LoginRequest
import roomescape.common.config.next
import roomescape.member.infrastructure.persistence.MemberEntity
import roomescape.member.infrastructure.persistence.MemberRepository
import roomescape.member.infrastructure.persistence.Role
class LoginUtil(
private val memberRepository: MemberRepository
) {
fun login(email: String, password: String, role: Role = Role.MEMBER): String {
if (!memberRepository.existsByEmail(email)) {
memberRepository.save(
MemberEntity(
_id = TsidFactory.next(),
email = email,
password = password,
name = email.split("@").first(),
role = role
)
)
}
return Given {
contentType(MediaType.APPLICATION_JSON_VALUE)
body(LoginRequest(email, password))
} When {
post("/login")
} Then {
statusCode(200)
} Extract {
path("data.accessToken")
}
}
fun loginAsAdmin(): String {
return login(MemberFixture.admin().email, MemberFixture.admin().password, Role.ADMIN)
}
fun loginAsUser(): String {
return login(MemberFixture.user().email, MemberFixture.user().password)
}
}
fun runTest(
token: String? = null,
using: RequestSpecification.() -> RequestSpecification = { this },
on: RequestSpecification.() -> Response,
expect: ValidatableResponse.() -> Unit
): ValidatableResponse {
return Given {
contentType(MediaType.APPLICATION_JSON_VALUE)
token?.also { header("Authorization", "Bearer $token") }
using()
} When {
on()
} Then {
expect()
}
}
/**
* @param props: RestAssured 응답 Body 에서 존재 & Null 여부를 확인할 프로퍼티 이름
*/
fun ValidatableResponse.assertProperties(props: Set<String>, propsNameIfList: String? = null) {
val jsonDefaultPath = propsNameIfList?.let { "data.$propsNameIfList" } ?: "data"
val json = extract().jsonPath().get<Any>(jsonDefaultPath)
fun checkMap(map: Map<*, *>) {
val responseKeys = map.keys.map { it.toString() }.toSet()
val expectedKeys = props
val missing = expectedKeys - responseKeys
val extra = responseKeys - expectedKeys
require(missing.isEmpty() && extra.isEmpty()) {
buildString {
if (missing.isNotEmpty()) append("Missing keys: $missing. ")
if (extra.isNotEmpty()) append("Unexpected keys: $extra.")
}
}
expectedKeys.forEach { key ->
require(map[key] != null) { "Property '$key' is null" }
}
}
when (json) {
is List<*> -> json.forEach { item ->
val map = item as? Map<*, *> ?: error("Expected Map but got ${item?.javaClass}")
checkMap(map)
}
is Map<*, *> -> checkMap(json)
else -> error("Unexpected data type: ${json::class}")
}
}