195 lines
6.9 KiB
Kotlin
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"))
|
|
}
|
|
}
|