tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_top_level_mattermost_progress_uses_event_message_id tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_threaded_mattermost_progress_prefers_existing_thread_root tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_telegram_progress_does_not_use_message_id_as_thread_id tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_interim_assistant_messages tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_platform_opt_in_can_enable_interim_assistant_messages tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_thinking_progress tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_show_reasoning tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_platform_opt_in_can_enable_show_reasoning tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_global_thinking_progress_still_applies_to_other_platforms tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_apply_env_overrides_mattermost tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_not_loaded_without_token tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_home_channel tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_url_warning_without_url tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_image_markdown_to_url tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_image_markdown_strips_alt_text tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_regular_markdown_preserved tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_regular_links_preserved tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_plain_text_unchanged tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_multiple_images tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_short_message_single_chunk tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_long_message_splits tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_custom_max_length tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_exactly_at_limit tests/gateway/test_mattermost.py::TestMattermostSend::test_send_calls_api_post tests/gateway/test_mattermost.py::TestMattermostSend::test_send_empty_content_succeeds tests/gateway/test_mattermost.py::TestMattermostSend::test_send_with_thread_reply tests/gateway/test_mattermost.py::TestMattermostSend::test_send_without_thread_no_root_id tests/gateway/test_mattermost.py::TestMattermostSend::test_send_uses_metadata_thread_id_for_progress_messages tests/gateway/test_mattermost.py::TestMattermostSend::test_progress_send_with_invalid_thread_root_never_falls_back_flat tests/gateway/test_mattermost.py::TestMattermostSend::test_notify_send_with_invalid_thread_root_falls_back_flat_with_warning tests/gateway/test_mattermost.py::TestMattermostSend::test_notify_send_with_server_error_does_not_fall_back_flat tests/gateway/test_mattermost.py::TestMattermostSend::test_send_api_failure tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_parse_posted_event tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_own_messages tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_non_posted_events tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_system_posts tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_channel_type_mapping tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_thread_id_from_root_id tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_invalid_post_json_ignored tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_require_mention_true_skips_without_mention tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_require_mention_false_responds_to_all tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_free_response_channel_responds_without_mention tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_non_free_channel_still_requires_mention tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_dm_always_responds tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_mention_stripped_from_text tests/gateway/test_mattermost.py::TestMattermostFileUpload::test_send_image_downloads_and_uploads tests/gateway/test_mattermost.py::TestMattermostDedup::test_duplicate_post_ignored tests/gateway/test_mattermost.py::TestMattermostDedup::test_different_post_ids_both_processed tests/gateway/test_mattermost.py::TestMattermostDedup::test_prune_seen_clears_expired tests/gateway/test_mattermost.py::TestMattermostDedup::test_seen_cache_tracks_post_ids tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_with_token_and_url tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_without_token tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_without_url tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_image_media_type_is_full_mime tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_audio_media_type_is_full_mime tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_document_media_type_is_full_mime tests/gateway/test_mattermost.py::test_mattermost_top_level_channel_post_is_thread_root tests/gateway/test_mattermost.py::test_mattermost_dm_post_does_not_seed_thread_root