test(json): 난독화 안정성 검증을 추가한다
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
package kr.co.vividnext.sodalive.json
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import java.io.File
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.playlist.modify.UpdatePlaylistRequest
|
||||||
|
import kr.co.vividnext.sodalive.chat.original.OriginalWorkListItemResponse
|
||||||
|
import kr.co.vividnext.sodalive.chat.original.OriginalWorkListResponse
|
||||||
|
import kr.co.vividnext.sodalive.mypage.auth.AuthResponse
|
||||||
|
import kr.co.vividnext.sodalive.mypage.can.payment.payverse.PayverseVerifyRequest
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class DtoObfuscationStabilityTest {
|
||||||
|
@Test
|
||||||
|
fun `확정 DTO class는 release minify 보존 annotation을 가진다`() {
|
||||||
|
assertSourceContains("app/src/main/java/kr/co/vividnext/sodalive/mypage/auth/AuthResponse.kt", "@Keep")
|
||||||
|
assertSourceContains(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/audio_content/playlist/modify/UpdatePlaylistRequest.kt",
|
||||||
|
"@Keep"
|
||||||
|
)
|
||||||
|
assertSourceContains(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/mypage/can/payment/payverse/PayverseChargeDto.kt",
|
||||||
|
"@Keep\ndata class PayverseVerifyRequest"
|
||||||
|
)
|
||||||
|
assertSourceContains(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/chat/original/OriginalWorkListResponse.kt",
|
||||||
|
"@Keep\ndata class OriginalWorkListResponse"
|
||||||
|
)
|
||||||
|
assertSourceContains(
|
||||||
|
"app/src/main/java/kr/co/vividnext/sodalive/chat/original/OriginalWorkListResponse.kt",
|
||||||
|
"@Keep\ndata class OriginalWorkListItemResponse"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `확정 DTO field는 SerializedName으로 JSON 이름을 고정한다`() {
|
||||||
|
assertSerializedName(OriginalWorkListResponse::class.java, "totalCount", "totalCount")
|
||||||
|
assertSerializedName(OriginalWorkListResponse::class.java, "content", "content")
|
||||||
|
assertSerializedName(OriginalWorkListItemResponse::class.java, "id", "id")
|
||||||
|
assertSerializedName(OriginalWorkListItemResponse::class.java, "imageUrl", "imageUrl")
|
||||||
|
assertSerializedName(OriginalWorkListItemResponse::class.java, "title", "title")
|
||||||
|
assertSerializedName(OriginalWorkListItemResponse::class.java, "contentType", "contentType")
|
||||||
|
assertSerializedName(AuthResponse::class.java, "gender", "gender")
|
||||||
|
assertSerializedName(UpdatePlaylistRequest::class.java, "title", "title")
|
||||||
|
assertSerializedName(UpdatePlaylistRequest::class.java, "desc", "desc")
|
||||||
|
assertSerializedName(UpdatePlaylistRequest::class.java, "contentIdAndOrderList", "contentIdAndOrderList")
|
||||||
|
assertSerializedName(PayverseVerifyRequest::class.java, "transactionId", "transactionId")
|
||||||
|
assertSerializedName(PayverseVerifyRequest::class.java, "orderId", "orderId")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertSourceContains(relativePath: String, expected: String) {
|
||||||
|
val source = File(projectRoot(), relativePath).readText()
|
||||||
|
assertTrue("$relativePath must contain $expected", source.contains(expected))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun projectRoot(): File {
|
||||||
|
val workingDirectory = File(System.getProperty("user.dir"))
|
||||||
|
return if (File(workingDirectory, "settings.gradle").exists()) {
|
||||||
|
workingDirectory
|
||||||
|
} else {
|
||||||
|
checkNotNull(workingDirectory.parentFile) { "Project root not found from $workingDirectory" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertSerializedName(clazz: Class<*>, fieldName: String, expectedValue: String) {
|
||||||
|
val field = clazz.getDeclaredField(fieldName)
|
||||||
|
val annotation = field.getAnnotation(SerializedName::class.java)
|
||||||
|
assertTrue("${clazz.simpleName}.$fieldName must have @SerializedName", annotation != null)
|
||||||
|
assertEquals(expectedValue, annotation?.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package kr.co.vividnext.sodalive.json
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import kr.co.vividnext.sodalive.home.ContentRankingSortType
|
||||||
|
import kr.co.vividnext.sodalive.home.SeriesPublishedDaysOfWeek
|
||||||
|
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.content.data.AudioRankingType
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.content.data.MainContentAllType
|
||||||
|
import kr.co.vividnext.sodalive.v2.main.content.overview.data.ContentOverviewType
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class EnumObfuscationStabilityTest {
|
||||||
|
@Test
|
||||||
|
fun `AudioRankingType은 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
AudioRankingType::class.java,
|
||||||
|
listOf("WEEKLY_POPULAR", "RISING", "REVENUE", "SALES_COUNT", "COMMENT_COUNT", "LIKE_COUNT")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `MainContentAllType은 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
MainContentAllType::class.java,
|
||||||
|
listOf("AUDIO", "SERIES", "ORIGINAL", "FREE", "POINT")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ContentSort는 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
ContentSort::class.java,
|
||||||
|
listOf("LATEST", "POPULAR", "OWNED", "PRICE_HIGH", "PRICE_LOW")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ContentOverviewType은 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
ContentOverviewType::class.java,
|
||||||
|
listOf("NEW_AND_HOT_AUDIO")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `SeriesPublishedDaysOfWeek는 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
SeriesPublishedDaysOfWeek::class.java,
|
||||||
|
listOf("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", "RANDOM")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ContentRankingSortType은 JSON 이름과 query 값을 고정한다`() {
|
||||||
|
assertEnumWireValues(
|
||||||
|
ContentRankingSortType::class.java,
|
||||||
|
listOf("REVENUE", "SALES_COUNT", "COMMENT_COUNT", "LIKE_COUNT")
|
||||||
|
) { it.queryValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : Enum<T>> assertEnumWireValues(
|
||||||
|
enumClass: Class<T>,
|
||||||
|
expectedValues: List<String>,
|
||||||
|
queryValue: (T) -> String
|
||||||
|
) {
|
||||||
|
val constants = enumClass.enumConstants?.toList().orEmpty()
|
||||||
|
assertEquals(expectedValues, constants.map { it.name })
|
||||||
|
constants.zip(expectedValues).forEach { (constant, expectedValue) ->
|
||||||
|
val field = enumClass.getField(constant.name)
|
||||||
|
val annotation = field.getAnnotation(SerializedName::class.java)
|
||||||
|
assertTrue("${enumClass.simpleName}.${constant.name} must have @SerializedName", annotation != null)
|
||||||
|
assertEquals(expectedValue, annotation?.value)
|
||||||
|
assertEquals(expectedValue, queryValue(constant))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user