Files
whale-town-front/tests/unit/test_auth_baselevel_regressions.gd

186 lines
5.6 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends SceneTree
# Auth/BaseLevel 回归测试(无需 GUT
#
# 运行方式:
# "D:\\technology\\biancheng\\Godot\\Godot_v4.5.1-stable_win64.exe" --headless --path . --script tests/unit/test_auth_baselevel_regressions.gd
var _failures: Array[String] = []
class TestBaseLevel:
extends BaseLevel
func _ready() -> void:
# 测试场景中跳过原始 _ready避免网络/场景副作用
pass
func _init() -> void:
call_deferred("_run")
func _run() -> void:
await _test_forgot_password_response_handler()
await _test_auth_request_tracking_cleanup()
await _test_verification_code_timestamp_and_remaining_time()
await _test_send_code_cooldown_starts_on_success_only()
await _test_join_session_wait_has_timeout_guards()
if _failures.is_empty():
print("PASS: test_auth_baselevel_regressions")
quit(0)
return
for failure in _failures:
push_error(failure)
print("FAIL: test_auth_baselevel_regressions (%d)" % _failures.size())
quit(1)
func _test_forgot_password_response_handler() -> void:
var manager := AuthManager.new()
var toast_message: String = ""
manager.show_toast_message.connect(func(message: String, _is_success: bool): toast_message = message)
manager._on_forgot_password_response(true, {}, {})
_assert(
"重置验证码" in toast_message,
"忘记密码成功响应应使用 forgot_password 处理器文案"
)
toast_message = ""
manager._on_forgot_password_response(false, {"error_code": "USER_NOT_FOUND", "message": "用户不存在"}, {})
_assert(
("用户不存在" in toast_message) and ("请检查邮箱或手机号" in toast_message),
"忘记密码失败响应应使用 forgot_password 错误分支"
)
manager.cleanup()
func _test_auth_request_tracking_cleanup() -> void:
var manager := AuthManager.new()
manager.active_request_ids = ["req_a", "req_b"]
manager._on_network_request_completed("req_a", true, {})
_assert(
manager.active_request_ids.size() == 1 and manager.active_request_ids[0] == "req_b",
"请求完成后应从 active_request_ids 中移除对应 request_id"
)
manager._on_network_request_failed("req_b", "NETWORK_ERROR", "x")
_assert(
manager.active_request_ids.is_empty(),
"请求失败后也应从 active_request_ids 中移除对应 request_id"
)
manager.cleanup()
func _test_verification_code_timestamp_and_remaining_time() -> void:
var manager := AuthManager.new()
var email := "cooldown_regression@example.com"
manager._record_verification_code_sent(email)
var sent_timestamp: int = int(manager.verification_codes_sent[email].get("time", 0))
_assert(
sent_timestamp > 86400,
"验证码发送时间应记录 Unix 时间戳,避免跨天计算异常"
)
manager.verification_codes_sent[email].time = int(Time.get_unix_time_from_system()) - 1000
_assert(
manager.get_remaining_cooldown_time(email) == 0,
"冷却已过期时,剩余时间应为 0"
)
manager.cleanup()
func _test_send_code_cooldown_starts_on_success_only() -> void:
var packed_scene: PackedScene = load("res://scenes/ui/AuthScene.tscn")
_assert(packed_scene != null, "应能加载 AuthScene.tscn")
if packed_scene == null:
return
var auth_scene: Control = packed_scene.instantiate()
root.add_child(auth_scene)
await process_frame
auth_scene.register_email.text = "invalid_email"
auth_scene._on_send_code_pressed()
await process_frame
_assert(
auth_scene.cooldown_timer == null,
"邮箱不合法时不应启动验证码冷却计时器"
)
_assert(
not auth_scene.send_code_btn.disabled,
"邮箱不合法时发送按钮不应被锁定"
)
# 模拟发送成功回调触发冷却(并补齐 manager 内部冷却记录)
auth_scene.auth_manager._record_verification_code_sent("regression@example.com")
auth_scene._on_controller_verification_code_sent("ok")
_assert(
auth_scene.cooldown_timer != null,
"验证码发送成功后应启动冷却计时器"
)
_assert(
auth_scene.send_code_btn.disabled,
"验证码发送成功后应禁用发送按钮"
)
auth_scene.queue_free()
await process_frame
func _test_join_session_wait_has_timeout_guards() -> void:
var level := TestBaseLevel.new()
root.add_child(level)
await process_frame
var original_token: String = LocationManager._auth_token
var original_poll_interval: float = level._join_token_poll_interval
var original_token_timeout: float = level._join_token_wait_timeout
var original_player_timeout_frames: int = level._join_player_wait_timeout_frames
level._join_token_poll_interval = 0.01
level._join_token_wait_timeout = 0.03
level._join_player_wait_timeout_frames = 2
# 场景 1: Token 一直未就绪,函数应在超时后退出,而不是无限递归等待
LocationManager._auth_token = ""
level._join_session_with_player("test_session")
await create_timer(0.15).timeout
_assert(
not level._is_joining_session,
"Token 长时间未就绪时应超时退出 join 流程"
)
# 场景 2: Token 已就绪但玩家一直未生成,也应在上限后退出
LocationManager._auth_token = "dummy_token"
level._player_spawned = false
level._local_player = null
level._join_session_with_player("test_session")
await process_frame
await process_frame
await process_frame
await process_frame
_assert(
not level._is_joining_session,
"玩家长时间未就绪时应在帧上限后退出 join 流程"
)
# 恢复现场
LocationManager._auth_token = original_token
level._join_token_poll_interval = original_poll_interval
level._join_token_wait_timeout = original_token_timeout
level._join_player_wait_timeout_frames = original_player_timeout_frames
level.queue_free()
await process_frame
func _assert(condition: bool, message: String) -> void:
if not condition:
_failures.append(message)