Files
Escape-penacony-standalone/app/src/test/java/com/catlas/escapepenacony/UpdateAndSceneTest.kt
T

195 lines
6.9 KiB
Kotlin

package com.catlas.escapepenacony
import com.catlas.escapepenacony.data.SceneTeleportPayload
import com.catlas.escapepenacony.data.TrailblazerConfig
import org.json.JSONObject
import org.junit.Assert.*
import org.junit.Test
class UpdateAndSceneTest {
// --- 1. Version Parsing Logic Tests ---
private fun parseVersions(raw: String): List<String> {
val sanitized = if (raw.startsWith("\uFEFF")) raw.substring(1) else raw
return sanitized.split(Regex("[\\r\\n,]+"))
.map { it.trim() }
.filter { it.isNotBlank() }
.distinct()
}
private fun buildDownloadUrl(baseUrl: String, version: String, filename: String = "build.zip"): String {
val sanitizedVersion = version.trim()
if (sanitizedVersion.contains("/") || sanitizedVersion.contains("\\") || sanitizedVersion.contains("..")) {
throw IllegalArgumentException("Invalid version format: traversal characters detected")
}
return "$baseUrl$sanitizedVersion/$filename"
}
@Test
fun testVersionParsing_CRLF_LF_Comma_Duplicates() {
val sample = "\uFEFF4.3.5X\r\n4.4.5X\n4.5.5X, 4.4.5X\r\n 4.6.5X \r\n\r\n"
val parsed = parseVersions(sample)
assertEquals(4, parsed.size)
assertEquals("4.3.5X", parsed[0])
assertEquals("4.4.5X", parsed[1])
assertEquals("4.5.5X", parsed[2])
assertEquals("4.6.5X", parsed[3])
assertEquals("4.6.5X", parsed.last())
}
@Test
fun testVersionParsing_SuffixesPreserved() {
val sample = "4.6.5X\n4.7.0-BETA_1\n4.7.0-RC2"
val parsed = parseVersions(sample)
assertEquals("4.7.0-RC2", parsed.last())
}
@Test
fun testVersionParsing_EmptyOrWhitespace() {
val sample = " \r\n \n \r\n"
val parsed = parseVersions(sample)
assertTrue(parsed.isEmpty())
}
@Test
fun testBuildDownloadUrl_Valid() {
val baseUrl = "https://file.garden/aewBviVxx2XDWgM-/"
val url = buildDownloadUrl(baseUrl, "4.6.5X")
assertEquals("https://file.garden/aewBviVxx2XDWgM-/4.6.5X/build.zip", url)
}
@Test(expected = IllegalArgumentException::class)
fun testBuildDownloadUrl_RejectsTraversal_Slash() {
val baseUrl = "https://file.garden/aewBviVxx2XDWgM-/"
buildDownloadUrl(baseUrl, "4.6.5X/hack")
}
@Test(expected = IllegalArgumentException::class)
fun testBuildDownloadUrl_RejectsTraversal_DotDot() {
val baseUrl = "https://file.garden/aewBviVxx2XDWgM-/"
buildDownloadUrl(baseUrl, "../etc")
}
// --- 2. Persistent.json Transformation Tests ---
@Test
fun testPersistentTransformation_PreservesOtherKeys() {
val originalJson = """
{
"send_hotfix": false,
"key": "secret123",
"avatar": {
"tb_gender": "Male",
"tb_path": "Harmony",
"march_path": "Hunt"
},
"scene": {
"plane_id": 10000,
"x": 10,
"y": 20,
"z": 30
}
}
""".trimIndent()
val root = JSONObject(originalJson)
val payload = SceneTeleportPayload(
planeId = 20461,
x = 12080,
y = 393572,
z = 322230,
calyxX = 12080,
calyxY = 393572,
calyxZ = 324030,
mapLayer = 2,
calyxGroupId = 186,
calyxInstId = 300001,
calyxEntityId = 1337,
calyxPropId = 808
)
// Apply scene
val sceneObj = root.optJSONObject("scene") ?: JSONObject().also { root.put("scene", it) }
sceneObj.put("plane_id", payload.planeId)
sceneObj.put("x", payload.x)
sceneObj.put("y", payload.y)
sceneObj.put("z", payload.z)
sceneObj.put("calyx_x", payload.calyxX)
sceneObj.put("calyx_y", payload.calyxY)
sceneObj.put("calyx_z", payload.calyxZ)
sceneObj.put("map_layer", payload.mapLayer)
sceneObj.put("calyx_group_id", payload.calyxGroupId)
sceneObj.put("calyx_inst_id", payload.calyxInstId)
sceneObj.put("calyx_entity_id", payload.calyxEntityId)
sceneObj.put("calyx_prop_id", payload.calyxPropId)
// Verify other keys strictly preserved
assertFalse(root.getBoolean("send_hotfix"))
assertEquals("secret123", root.getString("key"))
assertEquals("Male", root.getJSONObject("avatar").getString("tb_gender"))
assertEquals("Harmony", root.getJSONObject("avatar").getString("tb_path"))
// Verify updated scene keys
val updatedScene = root.getJSONObject("scene")
assertEquals(20461, updatedScene.getInt("plane_id"))
assertEquals(12080, updatedScene.getInt("x"))
assertEquals(393572, updatedScene.getInt("y"))
assertEquals(322230, updatedScene.getInt("z"))
assertEquals(2, updatedScene.getInt("map_layer"))
assertEquals(186, updatedScene.getInt("calyx_group_id"))
}
@Test
fun testTrailblazerConfigUpdate() {
val root = JSONObject("""{"avatar": {}}""")
val avatar = root.getJSONObject("avatar")
val newConfig = TrailblazerConfig(gender = "Female", tbPath = "Elation", marchPath = "Preservation")
avatar.put("tb_gender", newConfig.gender)
avatar.put("tb_path", newConfig.tbPath)
avatar.put("march_path", newConfig.marchPath)
assertEquals("Female", avatar.getString("tb_gender"))
assertEquals("Elation", avatar.getString("tb_path"))
assertEquals("Preservation", avatar.getString("march_path"))
}
@Test
fun testExRankConfigUpdate() {
val root = JSONObject("""{"avatar": {}}""")
val avatar = root.getJSONObject("avatar")
val list = listOf(
com.catlas.escapepenacony.data.ExRankConfig("JingYuan", 1204, true),
com.catlas.escapepenacony.data.ExRankConfig("DanHeng IL", 1213, false),
com.catlas.escapepenacony.data.ExRankConfig("Acheron", 1308, true)
)
val array = org.json.JSONArray()
for (cfg in list) {
val item = JSONObject()
item.put("name", cfg.name)
item.put("avatar_id", cfg.avatarId)
item.put("active", cfg.active)
array.put(item)
}
avatar.put("ex_rank", array)
val savedArray = avatar.getJSONArray("ex_rank")
assertEquals(3, savedArray.length())
assertEquals("JingYuan", savedArray.getJSONObject(0).getString("name"))
assertEquals(1204, savedArray.getJSONObject(0).getInt("avatar_id"))
assertTrue(savedArray.getJSONObject(0).getBoolean("active"))
assertEquals("DanHeng IL", savedArray.getJSONObject(1).getString("name"))
assertFalse(savedArray.getJSONObject(1).getBoolean("active"))
assertEquals("Acheron", savedArray.getJSONObject(2).getString("name"))
assertTrue(savedArray.getJSONObject(2).getBoolean("active"))
}
}