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,144 @@
|
||||
# tests/test_admin_panel.gd
|
||||
# Tests for Task [042]: Admin Panel - JSON Type Safety & User History View
|
||||
# Validates safe array casting and history dialog functionality
|
||||
|
||||
extends GutTest
|
||||
|
||||
var admin_manager: Node
|
||||
var test_user_data: Dictionary
|
||||
|
||||
func before_all():
|
||||
gut.p("=== Admin Panel Tests [Task 042] ===")
|
||||
|
||||
func before_each():
|
||||
# Initialize admin manager
|
||||
admin_manager = preload("res://scripts/managers/admin_manager.gd").new()
|
||||
add_child(admin_manager)
|
||||
|
||||
# Sample user data for testing
|
||||
test_user_data = {
|
||||
"user_id": "test_user_123",
|
||||
"username": "TestPlayer",
|
||||
"email": "test@example.com",
|
||||
"level": 42,
|
||||
"coins": 5000,
|
||||
"gems": 250,
|
||||
"history": [
|
||||
{"action": "login", "timestamp": 1000},
|
||||
{"action": "purchase", "timestamp": 2000},
|
||||
{"action": "level_up", "timestamp": 3000}
|
||||
]
|
||||
}
|
||||
|
||||
func after_each():
|
||||
if admin_manager:
|
||||
admin_manager.queue_free()
|
||||
|
||||
# Test 1: JSON parsing returns correct type
|
||||
func test_admin_parses_user_json_correctly():
|
||||
var json_str = JSON.stringify(test_user_data)
|
||||
var parsed = JSON.parse_string(json_str)
|
||||
|
||||
assert_is(parsed, Dictionary, "Parsed JSON should be a Dictionary")
|
||||
assert_eq(parsed.user_id, "test_user_123", "User ID should match")
|
||||
|
||||
# Test 2: Safe array casting for history
|
||||
func test_admin_safely_casts_history_array():
|
||||
var history = test_user_data.get("history", [])
|
||||
|
||||
assert_is(history, Array, "History should be an Array")
|
||||
assert_eq(history.size(), 3, "History should have 3 entries")
|
||||
|
||||
# Test 3: History entries are dictionaries
|
||||
func test_admin_history_entries_are_valid_dicts():
|
||||
var history = test_user_data.get("history", [])
|
||||
|
||||
for entry in history:
|
||||
assert_is(entry, Dictionary, "Each history entry should be a Dictionary")
|
||||
assert_has(entry, "action", "History entry should have 'action' field")
|
||||
assert_has(entry, "timestamp", "History entry should have 'timestamp' field")
|
||||
|
||||
# Test 4: Invalid history data doesn't crash
|
||||
func test_admin_handles_invalid_history_gracefully():
|
||||
var invalid_data = {
|
||||
"user_id": "test_123",
|
||||
"history": "not_an_array" # Wrong type
|
||||
}
|
||||
|
||||
var history = invalid_data.get("history", [])
|
||||
|
||||
# Should default to empty array if not an array
|
||||
if not history is Array:
|
||||
history = []
|
||||
|
||||
assert_is(history, Array, "History should be converted to Array")
|
||||
|
||||
# Test 5: History dialog displays correct number of entries
|
||||
func test_admin_history_dialog_shows_all_entries():
|
||||
var history = test_user_data.get("history", [])
|
||||
var display_count = 0
|
||||
|
||||
for entry in history:
|
||||
if entry.has("action") and entry.has("timestamp"):
|
||||
display_count += 1
|
||||
|
||||
assert_eq(display_count, 3, "Should display all 3 valid history entries")
|
||||
|
||||
# Test 6: History entries are sorted by timestamp
|
||||
func test_admin_history_sorted_by_timestamp():
|
||||
var history = test_user_data.get("history", [])
|
||||
|
||||
for i in range(history.size() - 1):
|
||||
var current_time = history[i].get("timestamp", 0)
|
||||
var next_time = history[i + 1].get("timestamp", 0)
|
||||
assert_true(current_time <= next_time, "History should be sorted by timestamp")
|
||||
|
||||
# Test 7: User data with missing fields doesn't crash
|
||||
func test_admin_handles_missing_user_fields():
|
||||
var incomplete_data = {
|
||||
"user_id": "test_123"
|
||||
# Missing other fields
|
||||
}
|
||||
|
||||
var username = incomplete_data.get("username", "Unknown")
|
||||
var level = incomplete_data.get("level", 0)
|
||||
var history = incomplete_data.get("history", [])
|
||||
|
||||
assert_eq(username, "Unknown", "Should use default for missing username")
|
||||
assert_eq(level, 0, "Should use default for missing level")
|
||||
assert_is(history, Array, "Should default to empty array for missing history")
|
||||
|
||||
# Test 8: Large history doesn't cause performance issues
|
||||
func test_admin_handles_large_history():
|
||||
var large_history = []
|
||||
for i in range(1000):
|
||||
large_history.append({
|
||||
"action": "action_" + str(i),
|
||||
"timestamp": i * 1000
|
||||
})
|
||||
|
||||
var data = {"user_id": "test_123", "history": large_history}
|
||||
var history = data.get("history", [])
|
||||
|
||||
assert_eq(history.size(), 1000, "Should handle 1000 history entries")
|
||||
|
||||
# Test 9: History action types are valid strings
|
||||
func test_admin_history_actions_are_strings():
|
||||
var history = test_user_data.get("history", [])
|
||||
|
||||
for entry in history:
|
||||
var action = entry.get("action", "")
|
||||
assert_is(action, String, "Action should be a String")
|
||||
assert_true(action.length() > 0, "Action should not be empty")
|
||||
|
||||
# Test 10: Timestamps are valid numbers
|
||||
func test_admin_history_timestamps_are_numbers():
|
||||
var history = test_user_data.get("history", [])
|
||||
|
||||
for entry in history:
|
||||
var timestamp = entry.get("timestamp", 0)
|
||||
assert_is(timestamp, int, "Timestamp should be an integer")
|
||||
assert_true(timestamp >= 0, "Timestamp should be non-negative")
|
||||
|
||||
func after_all():
|
||||
gut.p("=== Admin Panel Tests Complete ===")
|
||||
Reference in New Issue
Block a user