extends GutTest # ============================================================================ # test_chat_manager.gd - ChatManager 单元测试 # ============================================================================ # 测试聊天系统业务逻辑的功能 # # 测试覆盖: # - 初始化测试 # - Token 管理 # - 频率限制 # - 消息历史管理 # - 错误处理 # - 信号发射 # ============================================================================ var chat_manager: ChatManager # ============================================================================ # 测试设置和清理 # ============================================================================ func before_each(): # 每个测试前创建新实例 chat_manager = ChatManager.new() add_child(chat_manager) func after_each(): # 每个测试后清理 if is_instance_valid(chat_manager): chat_manager.queue_free() chat_manager = null # ============================================================================ # 初始化测试 # ============================================================================ func test_chat_manager_initialization(): # 测试管理器初始化 assert_not_null(chat_manager, "ChatManager 应该成功初始化") assert_not_null(chat_manager._websocket_manager, "WebSocket 管理器应该被创建") assert_not_null(chat_manager._socket_client, "Socket.IO 客户端应该被创建") assert_false(chat_manager.is_chat_connected(), "初始状态应该是未连接") # ============================================================================ # Token 管理测试 # ============================================================================ func test_set_game_token(): # 测试设置游戏 token chat_manager.set_game_token("test_token_123") assert_eq(chat_manager.get_game_token(), "test_token_123", "Token 应该被正确设置") func test_get_game_token_initially_empty(): # 测试初始 token 为空 assert_eq(chat_manager.get_game_token(), "", "初始 token 应该为空字符串") func test_set_empty_token(): # 测试设置空 token chat_manager.set_game_token("") assert_eq(chat_manager.get_game_token(), "", "空 token 应该被接受") func test_update_token(): # 测试更新 token chat_manager.set_game_token("token1") assert_eq(chat_manager.get_game_token(), "token1", "第一个 token 应该被设置") chat_manager.set_game_token("token2") assert_eq(chat_manager.get_game_token(), "token2", "token 应该被更新") # ============================================================================ # 频率限制测试 # ============================================================================ func test_can_send_message_initially(): # 测试初始状态可以发送消息 assert_true(chat_manager.can_send_message(), "初始状态应该可以发送消息") func test_can_send_message_after_one_send(): # 测试发送一条消息后仍可发送 chat_manager._record_message_timestamp() assert_true(chat_manager.can_send_message(), "发送一条消息后应该仍可以发送") func test_rate_limit_exceeded(): # 测试达到频率限制 # 记录 10 条消息(达到限制) for i in range(10): chat_manager._record_message_timestamp() assert_false(chat_manager.can_send_message(), "达到频率限制后不应该可以发送消息") func test_rate_limit_window_expires(): # 测试频率限制窗口过期 # 记录 10 条消息 for i in range(10): chat_manager._record_message_timestamp() # 模拟时间流逝(将时间戳设置为很久以前) var old_time := Time.get_unix_time_from_system() - 100.0 chat_manager._message_timestamps = [] for i in range(10): chat_manager._message_timestamps.append(old_time) assert_true(chat_manager.can_send_message(), "旧消息过期后应该可以发送新消息") func test_get_time_until_next_message(): # 测试获取下次可发送消息的等待时间 chat_manager._message_timestamps = [] var wait_time := chat_manager.get_time_until_next_message() assert_eq(wait_time, 0.0, "没有消息时等待时间应该为 0") # ============================================================================ # 消息历史管理测试 # ============================================================================ func test_add_message_to_history(): # 测试添加消息到历史 var message := { "from_user": "Alice", "content": "Hello!", "timestamp": 1000.0, "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history.size(), 1, "历史应该有 1 条消息") assert_eq(chat_manager._message_history[0].from_user, "Alice", "消息发送者应该是 Alice") func test_message_history_limit(): # 测试消息历史限制(最多 100 条) # 添加 101 条消息 for i in range(101): var message := { "from_user": "User" + str(i), "content": "Message " + str(i), "timestamp": float(i), "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history.size(), 100, "消息历史应该被限制在 100 条") func test_get_message_history(): # 测试获取消息历史 var message1 := {"from_user": "Alice", "content": "Hi", "timestamp": 100.0} var message2 := {"from_user": "Bob", "content": "Hello", "timestamp": 200.0} chat_manager._add_message_to_history(message1) chat_manager._add_message_to_history(message2) var history := chat_manager.get_message_history() assert_eq(history.size(), 2, "应该返回 2 条消息") assert_eq(history[0].content, "Hi", "第一条消息内容应该匹配") func test_clear_message_history(): # 测试清空消息历史 var message := {"from_user": "Alice", "content": "Hi", "timestamp": 100.0} chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history.size(), 1, "应该有 1 条消息") chat_manager.clear_message_history() assert_eq(chat_manager._message_history.size(), 0, "历史应该被清空") # ============================================================================ # 错误处理测试 # ============================================================================ func test_error_message_mapping(): # 测试错误消息映射 var error_codes := ["AUTH_FAILED", "RATE_LIMIT", "CONTENT_FILTERED", "CONTENT_TOO_LONG", "PERMISSION_DENIED", "SESSION_EXPIRED", "ZULIP_ERROR", "INTERNAL_ERROR"] for code in error_codes: assert_true(ChatManager.CHAT_ERROR_MESSAGES.has(code), "错误码 " + code + " 应该有对应的错误消息") func test_handle_error(): # 测试错误处理 watch_signals(chat_manager) chat_manager._handle_error("AUTH_FAILED", "测试错误") assert_signal_emitted(chat_manager, "chat_error_occurred", "应该发射 chat_error_occurred 信号") # ============================================================================ # 常量测试 # ============================================================================ func test_websocket_url_constant(): # 测试 WebSocket URL 常量 assert_eq(ChatManager.WEBSOCKET_URL, "wss://whaletownend.xinghangee.icu/game", "WebSocket URL 应该匹配") func test_rate_limit_constants(): # 测试频率限制常量 assert_eq(ChatManager.RATE_LIMIT_MESSAGES, 10, "频率限制消息数应该是 10") assert_eq(ChatManager.RATE_LIMIT_WINDOW, 60.0, "频率限制时间窗口应该是 60 秒") func test_message_limit_constants(): # 测试消息限制常量 assert_eq(ChatManager.MAX_MESSAGE_LENGTH, 1000, "最大消息长度应该是 1000") assert_eq(ChatManager.MAX_MESSAGE_HISTORY, 100, "最大消息历史应该是 100") # ============================================================================ # 信号测试 # ============================================================================ func test_chat_message_sent_signal(): # 测试消息发送信号 watch_signals(chat_manager) chat_manager.emit_signal("chat_message_sent", "msg123", 1000.0) assert_signal_emitted(chat_manager, "chat_message_sent", "应该发射 chat_message_sent 信号") func test_chat_message_received_signal(): # 测试消息接收信号 watch_signals(chat_manager) chat_manager.emit_signal("chat_message_received", "Alice", "Hello!", true, 1000.0) assert_signal_emitted(chat_manager, "chat_message_received", "应该发射 chat_message_received 信号") func test_chat_error_occurred_signal(): # 测试错误发生信号 watch_signals(chat_manager) chat_manager.emit_signal("chat_error_occurred", "AUTH_FAILED", "认证失败") assert_signal_emitted(chat_manager, "chat_error_occurred", "应该发射 chat_error_occurred 信号") func test_chat_connection_state_changed_signal(): # 测试连接状态变化信号 watch_signals(chat_manager) chat_manager.emit_signal("chat_connection_state_changed", WebSocketManager.ConnectionState.CONNECTED) assert_signal_emitted(chat_manager, "chat_connection_state_changed", "应该发射 chat_connection_state_changed 信号") # ============================================================================ # 边界条件测试 # ============================================================================ func test_empty_message_content(): # 测试空消息内容 var message := { "from_user": "Alice", "content": "", "timestamp": 1000.0, "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history.size(), 1, "空消息应该被添加到历史") func test_very_long_message_content(): # 测试超长消息内容(边界测试) var long_content := "x".repeat(1000) var message := { "from_user": "Alice", "content": long_content, "timestamp": 1000.0, "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history[0].content.length(), 1000, "超长消息应该被保留") func test_unicode_in_message(): # 测试消息中的 Unicode 字符 var message := { "from_user": "玩家", "content": "你好,世界!🎮🎉", "timestamp": 1000.0, "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history[0].content, "你好,世界!🎮🎉", "Unicode 内容应该被正确保留") func test_zero_timestamp(): # 测试零时间戳 var message := { "from_user": "Alice", "content": "Hello", "timestamp": 0.0, "is_self": false } chat_manager._add_message_to_history(message) assert_eq(chat_manager._message_history[0].timestamp, 0.0, "零时间戳应该被保留") # ============================================================================ # 消息时间戳记录测试 # ============================================================================ func test_record_message_timestamp(): # 测试记录消息时间戳 chat_manager._record_message_timestamp() assert_eq(chat_manager._message_timestamps.size(), 1, "应该记录 1 个时间戳") func test_multiple_message_timestamps(): # 测试记录多个消息时间戳 for i in range(5): chat_manager._record_message_timestamp() assert_eq(chat_manager._message_timestamps.size(), 5, "应该记录 5 个时间戳") func test_timestamps_in_order(): # 测试时间戳应该按顺序记录 chat_manager._record_message_timestamp() await get_tree().process_frame chat_manager._record_message_timestamp() assert_gt(chat_manager._message_timestamps[1], chat_manager._message_timestamps[0], "后来的时间戳应该更大")