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:
@@ -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 ===")
|
||||
Reference in New Issue
Block a user