tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_config_loaded_from_env tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_home_channel_loaded tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_in_connected_platforms tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_interactive_card_preserves_title_body_and_actions tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_merge_forward_preserves_summary_lines tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_share_chat_exposes_summary_and_metadata tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_acquires_scoped_lock_and_disconnect_releases_it tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_rejects_existing_app_lock tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_retries_transient_startup_failure tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_webhook_mode_starts_local_server tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_edit_message_falls_back_to_text_when_post_update_is_rejected tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_edit_message_updates_existing_feishu_message tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_get_chat_info_uses_real_feishu_chat_api tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_accepts_custom_ws_ping_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_accepts_custom_ws_reconnect_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_ignores_invalid_ws_ping_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_uses_sdk_defaults_for_invalid_ws_reconnect_values tests/gateway/test_feishu.py::TestAdapterModule::test_runtime_ws_overrides_reapply_after_sdk_configure tests/gateway/test_feishu.py::TestAdapterBehavior::test_bot_origin_reactions_are_dropped_to_avoid_feedback_loops tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_event_handler_registers_reaction_and_card_processors tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_extracts_title_and_links tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_keeps_fence_like_code_lines_inside_code_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_keeps_full_markdown_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_preserves_trailing_spaces_in_code_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_splits_multiple_fenced_code_blocks tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_wraps_markdown_in_md_tag tests/gateway/test_feishu.py::TestAdapterBehavior::test_dedup_state_persists_across_adapter_restart tests/gateway/test_feishu.py::TestAdapterBehavior::test_default_group_policy_fallback_for_chats_without_explicit_rule tests/gateway/test_feishu.py::TestAdapterBehavior::test_download_remote_document_reads_response_before_httpx_client_closes tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_audio_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_file_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_image_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_interactive_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_media_message_with_image_mime_becomes_photo tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_media_message_with_video_mime_becomes_video tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_merge_forward_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_as_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_downloads_embedded_resources tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_uses_first_available_language_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_with_rich_elements_does_not_drop_content tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_share_chat_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_file_injects_content tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_from_raw_content_uses_relation_message_fallbacks tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_message_starting_with_slash_becomes_command tests/gateway/test_feishu.py::TestAdapterBehavior::test_global_admins_bypass_all_group_rules tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_allowlist_and_mention_both_required tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_matches_bot_name_when_only_name_available tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_matches_bot_open_id_when_configured tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_requires_mentions_even_when_policy_open tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_with_other_user_mention_is_rejected_when_bot_identity_unknown tests/gateway/test_feishu.py::TestAdapterBehavior::test_media_batch_merges_rapid_photo_messages tests/gateway/test_feishu.py::TestAdapterBehavior::test_message_event_submits_to_adapter_loop tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_admin_only_policy_requires_admin tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_allowlist_policy_gates_by_sender tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_blacklist_policy_blocks_specific_users tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_disabled_policy_blocks_all tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_group_message_keeps_group_type_when_chat_lookup_falls_back tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_message_fetches_reply_to_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_message_uses_event_sender_identity_only tests/gateway/test_feishu.py::TestAdapterBehavior::test_reaction_on_our_own_bot_message_is_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_reaction_on_peer_bot_message_is_not_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_animation_degrades_to_document_send tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_reply_uses_thread_flag tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_uploads_file_and_sends_file_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_with_caption_uses_single_post_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_does_not_retry_deterministic_api_failure tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_falls_back_to_text_when_post_payload_is_rejected tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_falls_back_to_text_when_post_response_is_unsuccessful tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_downloads_then_uses_native_image_send tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_file_uploads_image_and_sends_image_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_file_with_caption_uses_single_post_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_replies_in_thread_when_thread_metadata_present tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_retries_transient_failure tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_splits_fenced_code_blocks_into_separate_post_rows tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_metadata_reply_target_for_threaded_feishu_topic tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_post_for_advanced_markdown_lines tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_post_for_inline_markdown tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_video_uploads_file_and_sends_media_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_voice_uploads_opus_and_sends_audio_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_text_batch_flushes_when_message_count_limit_is_hit tests/gateway/test_feishu.py::TestAdapterBehavior::test_text_batch_merges_rapid_messages_into_single_event tests/gateway/test_feishu.py::TestAdapterBehavior::test_url_verification_requires_configured_verification_token tests/gateway/test_feishu.py::TestAdapterBehavior::test_user_reaction_with_managed_emoji_is_still_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_webhook_request_uses_same_message_dispatch_path tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_overwrites_stale_env_open_id tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_populates_open_id_from_bot_info tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_preserves_env_values_when_bot_info_probe_fails tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_refreshes_env_values_when_bot_info_available tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_tolerates_probe_failure_and_falls_back_to_app_info tests/gateway/test_feishu.py::TestPendingInboundQueue::test_drainer_drops_queue_when_adapter_shuts_down tests/gateway/test_feishu.py::TestPendingInboundQueue::test_drainer_replays_queued_events_when_loop_becomes_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_event_queued_when_loop_not_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_normal_path_unchanged_when_loop_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_queue_cap_evicts_oldest_beyond_max_depth tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_allows_requests_within_window tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_blocks_after_exceeding_max tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_resets_after_window_expires tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_invalid_rejected tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_missing_headers_rejected tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_valid_passes tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_connect_requires_inbound_auth_secret tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_loads_auth_secrets_from_platform_extra tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_bad_signature tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_invalid_json tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_oversized_body tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_url_verification_challenge_passes_without_signature tests/gateway/test_feishu.py::TestDedupTTL::test_duplicate_within_ttl_is_rejected tests/gateway/test_feishu.py::TestDedupTTL::test_expired_entry_is_not_considered_duplicate tests/gateway/test_feishu.py::TestDedupTTL::test_load_backward_compat_list_format tests/gateway/test_feishu.py::TestDedupTTL::test_load_tolerates_malformed_timestamp_values tests/gateway/test_feishu.py::TestDedupTTL::test_persist_saves_timestamps_as_dict tests/gateway/test_feishu.py::TestGroupMentionAtAll::test_at_all_in_content_accepts_without_explicit_bot_mention tests/gateway/test_feishu.py::TestGroupMentionAtAll::test_at_all_still_requires_policy_gate tests/gateway/test_feishu.py::TestSenderNameResolution::test_api_failure_returns_none_without_raising tests/gateway/test_feishu.py::TestSenderNameResolution::test_expired_cache_triggers_new_api_call tests/gateway/test_feishu.py::TestSenderNameResolution::test_fetches_and_caches_name_from_api tests/gateway/test_feishu.py::TestSenderNameResolution::test_returns_cached_name_within_ttl tests/gateway/test_feishu.py::TestSenderNameResolution::test_returns_none_when_client_is_none tests/gateway/test_feishu.py::TestBotNameResolution::test_api_failure_returns_none_and_does_not_poison_cache tests/gateway/test_feishu.py::TestBotNameResolution::test_bot_absent_from_response_is_not_cached tests/gateway/test_feishu.py::TestBotNameResolution::test_empty_name_in_response_is_negative_cached tests/gateway/test_feishu.py::TestBotNameResolution::test_fetches_and_caches_bot_name tests/gateway/test_feishu.py::TestBotNameResolution::test_non_zero_code_returns_none tests/gateway/test_feishu.py::TestBotNameResolution::test_returns_cached_bot_name_without_api_call tests/gateway/test_feishu.py::TestProcessingReactions::test_cache_evicts_oldest_entry_beyond_size_limit tests/gateway/test_feishu.py::TestProcessingReactions::test_cancelled_removes_typing_and_adds_nothing tests/gateway/test_feishu.py::TestProcessingReactions::test_delete_failure_on_failure_outcome_skips_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_delete_failure_on_success_outcome_retains_handle tests/gateway/test_feishu.py::TestProcessingReactions::test_env_disable_short_circuits_both_hooks tests/gateway/test_feishu.py::TestProcessingReactions::test_failure_removes_typing_then_adds_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_failure_without_preceding_start_still_adds_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_start_adds_typing_and_caches_reaction_id tests/gateway/test_feishu.py::TestProcessingReactions::test_start_does_not_cache_when_create_fails tests/gateway/test_feishu.py::TestProcessingReactions::test_start_is_idempotent_for_same_message_id tests/gateway/test_feishu.py::TestProcessingReactions::test_success_removes_typing_and_adds_nothing tests/gateway/test_feishu.py::TestProcessingReactions::test_success_without_preceding_start_is_full_noop tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_falls_back_to_name_when_bot_open_id_not_hydrated tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_handles_at_all tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_marks_self_by_name_fallback tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_marks_self_by_open_id tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_name_match_does_not_override_mismatching_open_id tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_non_self_user tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_returns_empty_for_none_input tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_tolerates_missing_id_object tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_at_all tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_dedupes_repeated_at_all tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_dedupes_repeated_user tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_falls_back_when_open_id_missing tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_filters_self_mentions tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_multiple_users tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_returns_empty_for_no_refs tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_returns_empty_when_only_self tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_single_user tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_uses_unknown_placeholder_when_name_missing tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_preserves_mid_text_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_preserves_trailing_self_before_non_terminal_char tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_returns_input_when_no_self_refs tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_returns_input_when_refs_empty tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_stops_at_first_non_self_token tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_consecutive_leading_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_leading_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_trailing_self_at_end_of_text tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_trailing_self_with_terminal_punct tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_uses_open_id_fallback_when_name_missing tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_word_boundary_prevents_prefix_collision tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_at_all_rendered_as_english_literal tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_backward_compatible_without_map tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_mention_for_missing_map_entry_degrades_to_space tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_renders_mention_with_display_name tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_renders_self_mention_with_name tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_unknown_placeholder_degrades_to_space tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_all_tag_renders_as_at_all tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_tag_falls_back_to_inline_user_name_when_map_misses tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_tag_renders_via_mentions_map tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_post_message_marks_self_via_mentions_map_lookup tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_in_text_without_mentions_payload tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_not_synthesized_if_absent_from_text tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_surfaces_ref tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_marks_bot_self_mention tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_renders_mention_by_name tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_without_mentions_param_is_backward_compatible tests/gateway/test_feishu.py::TestFeishuPostMentionsBot::test_post_mentions_bot_empty_returns_false tests/gateway/test_feishu.py::TestFeishuPostMentionsBot::test_post_mentions_bot_uses_is_self_flag tests/gateway/test_feishu.py::TestFeishuExtractMessageContent::test_returns_empty_mentions_when_missing tests/gateway/test_feishu.py::TestFeishuExtractMessageContent::test_returns_five_tuple_with_mentions tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_command_message_never_injects_hint tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_leading_self_mention_stripped_for_command tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_mid_text_self_mention_preserved tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_non_command_message_with_mentions_injects_hint tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_pure_self_mention_message_is_ignored tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_build_mentions_map_string_id_shape tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_extract_text_from_raw_content_accepts_mentions_kwarg tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_fetch_message_text_marks_is_self_via_string_id_shape tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_fetch_message_text_renders_mentions_without_hint_prefix tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_at_all_announcement tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_bot_plus_alice_plus_bob_build_group tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_mid_text_self_mention_preserved tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_no_mentions_zero_regression tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_post_at_alice_exposes_open_id tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_post_bot_plus_alice_filters_self_from_hint tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_trailing_self_mention_stripped tests/gateway/test_feishu.py::TestChatLockEviction::test_chat_locks_is_ordered_dict tests/gateway/test_feishu.py::TestChatLockEviction::test_eviction_skips_held_locks tests/gateway/test_feishu.py::TestChatLockEviction::test_lru_eviction_respects_recent_access tests/gateway/test_feishu.py::TestChatLockEviction::test_same_id_returns_same_lock_and_stays_bounded