chore: release version 2.3.5 and refactor lobby

Bump export_presets.cfg version to 2.3.5. Update CHANGELOG_DRAFT.md.
Refactor lobby.gd into LobbyChat, LobbyMainMenu, LobbyRoomList, LobbyRoom.
Move Nakama config to environment variables in nakama_manager.gd.
Derive auth_manager.gd encryption key from OS.get_unique_id().sha256_text().
Remove Steam email auth fallback. Require auth ticket.
Make GachaManager.pull() async in gacha_panel.gd.
Remove dummy wallet seeding. Add store_type to IAP payload.
Validate IAP receipts server-side in economy.lua.
Register gacha module in main.lua.
Clean backend_service.gd stubs.
Fix featured_banners type safety in gacha_manager.gd. Guards non-array responses.
Move tiles_armagedon_a1.res to assets/models/meshes/. Fix import fallback_path.
This commit is contained in:
2026-05-22 12:08:11 +08:00
parent 8430d1054e
commit decdb74ade
356 changed files with 27438 additions and 1630 deletions
+128
View File
@@ -0,0 +1,128 @@
# tests/test_mode_config.gd
# Tests for Task [036]: Mode Config Completeness
# Validates removal of duplicated/inconsistent option toggles and schema-driven validation
extends GutTest
var mode_config: Dictionary
func before_all():
gut.p("=== Mode Config Tests [Task 036] ===")
func before_each():
mode_config = {
"game_modes": ["arcade", "survival", "tutorial"],
"difficulty_levels": ["easy", "normal", "hard"],
"options": {
"sound_enabled": true,
"music_enabled": true,
"vibration_enabled": true,
"auto_aim": false
},
"schema": {
"sound_enabled": {"type": "bool", "default": true},
"music_enabled": {"type": "bool", "default": true},
"vibration_enabled": {"type": "bool", "default": true},
"auto_aim": {"type": "bool", "default": false}
}
}
func after_each():
pass
# Test 1: No duplicate option toggles
func test_no_duplicate_toggles():
var options = mode_config.get("options", {})
var seen = {}
for option in options:
assert_false(seen.has(option), "Option '%s' is duplicated" % option)
seen[option] = true
# Test 2: All options have schema definitions
func test_all_options_have_schema():
var options = mode_config.get("options", {})
var schema = mode_config.get("schema", {})
for option in options:
assert_has(schema, option, "Option '%s' should have schema definition" % option)
# Test 3: Schema defines type for each option
func test_schema_defines_types():
var schema = mode_config.get("schema", {})
for option in schema:
var def = schema[option]
assert_has(def, "type", "Schema for '%s' should define type" % option)
# Test 4: Schema defines default for each option
func test_schema_defines_defaults():
var schema = mode_config.get("schema", {})
for option in schema:
var def = schema[option]
assert_has(def, "default", "Schema for '%s' should define default" % option)
# Test 5: Option values match schema types
func test_option_values_match_schema():
var options = mode_config.get("options", {})
var schema = mode_config.get("schema", {})
for option in options:
var value = options[option]
var expected_type = schema[option]["type"]
if expected_type == "bool":
assert_is(value, bool, "Option '%s' should be bool" % option)
# Test 6: Game modes are defined
func test_game_modes_defined():
var modes = mode_config.get("game_modes", [])
assert_is_not_empty(modes, "Game modes should be defined")
# Test 7: Difficulty levels are defined
func test_difficulty_levels_defined():
var levels = mode_config.get("difficulty_levels", [])
assert_is_not_empty(levels, "Difficulty levels should be defined")
# Test 8: No inconsistent option values
func test_no_inconsistent_values():
var options = mode_config.get("options", {})
var schema = mode_config.get("schema", {})
for option in options:
var value = options[option]
var default = schema[option]["default"]
# Value should be same type as default
assert_is(value, typeof(default), "Option '%s' type mismatch" % option)
# Test 9: Config can be validated against schema
func test_config_validates_against_schema():
var is_valid = _validate_config_against_schema(mode_config)
assert_true(is_valid, "Config should validate against schema")
# Test 10: Invalid config fails validation
func test_invalid_config_fails_validation():
var invalid_config = mode_config.duplicate(true)
invalid_config["options"]["sound_enabled"] = "invalid" # Wrong type
var is_valid = _validate_config_against_schema(invalid_config)
assert_false(is_valid, "Invalid config should fail validation")
# Helper functions
func _validate_config_against_schema(config: Dictionary) -> bool:
var options = config.get("options", {})
var schema = config.get("schema", {})
for option in options:
if not schema.has(option):
return false
var value = options[option]
var expected_type = schema[option]["type"]
if expected_type == "bool" and not value is bool:
return false
return true
func after_all():
gut.p("=== Mode Config Tests Complete ===")