Merge pull request #188 from simoleo89/fix/furnieditor-update-validation

fix(furni-editor): validate and sync furnidata changes
This commit is contained in:
DuckieTM
2026-06-15 07:22:24 +02:00
committed by GitHub
14 changed files with 712 additions and 74 deletions
@@ -78,4 +78,33 @@ class FurniDataManagerTest {
assertEquals(assetBase.resolve("gamedata").resolve("FurnitureData.json"), source.path());
assertFalse(source.directory());
}
@Test
void prefersRendererConfigOverLegacyFurnidataPath(@TempDir Path dir) throws Exception {
Path legacy = dir.resolve("legacy").resolve("FurnitureData.json");
Files.createDirectories(legacy.getParent());
Files.writeString(legacy, "{}");
Path assetBase = dir.resolve("nitro-assets");
Path rendererSource = assetBase.resolve("gamedata").resolve("FurnitureData.json");
Files.createDirectories(rendererSource.getParent());
Files.writeString(rendererSource, "{}");
Path rendererConfig = dir.resolve("renderer-config.json");
Files.writeString(rendererConfig, """
{
"gamedata.url": "http://localhost:5173/nitro-assets/gamedata",
"furnidata.url": "${gamedata.url}/FurnitureData.json?t=%timestamp%"
}
""");
FurnidataSourceResolver.Source source = FurnidataSourceResolver.resolveConfigured(
legacy.toString(),
rendererConfig.toString(),
assetBase.toString());
assertTrue(source.ok());
assertEquals(rendererSource, source.path());
assertEquals("renderer-config furnidata.url", source.message());
}
}
@@ -0,0 +1,52 @@
package com.eu.habbo.messages.incoming.furnieditor;
import com.google.gson.JsonParser;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class FurniEditorUpdatePayloadTest {
@Test
void acceptsSafeEditorFields() {
FurniEditorUpdatePayload payload = FurniEditorUpdatePayload.validate(JsonParser.parseString("""
{
"publicName": "Rare Chair",
"type": "s",
"width": 2,
"length": 1,
"stackHeight": 1.5,
"allowTrade": true,
"interactionModesCount": 3
}
""").getAsJsonObject());
assertTrue(payload.valid());
assertEquals(7, payload.values.size());
}
@Test
void rejectsOutOfRangeAndOversizedFields() {
assertFalse(FurniEditorUpdatePayload.validate(JsonParser.parseString("{\"width\":-1}").getAsJsonObject()).valid());
assertFalse(FurniEditorUpdatePayload.validate(JsonParser.parseString("{\"stackHeight\":1000}").getAsJsonObject()).valid());
assertFalse(FurniEditorUpdatePayload.validate(JsonParser.parseString("{\"allowTrade\":2}").getAsJsonObject()).valid());
assertFalse(FurniEditorUpdatePayload.validate(JsonParser.parseString("{\"publicName\":\"" + "x".repeat(57) + "\"}").getAsJsonObject()).valid());
}
@Test
void ignoresUnknownFieldsButRequiresAtLeastOneValidField() {
FurniEditorUpdatePayload payload = FurniEditorUpdatePayload.validate(
JsonParser.parseString("{\"itemName\":\"blocked\",\"unknown\":true}").getAsJsonObject());
assertFalse(payload.valid());
assertEquals("No valid fields to update", payload.error);
}
@Test
void buildsCatalogItemIdsTokenPattern() {
assertEquals("%,12,%", FurniEditorHelper.catalogItemIdsTokenPattern(12));
assertTrue((",112,12,13,").contains(",12,"));
assertFalse((",112,13,").contains(",12,"));
}
}