tests/gateway/test_line_plugin.py::TestSignature::test_valid_signature_passes tests/gateway/test_line_plugin.py::TestSignature::test_tampered_body_rejected tests/gateway/test_line_plugin.py::TestSignature::test_wrong_secret_rejected tests/gateway/test_line_plugin.py::TestSignature::test_empty_signature_rejected tests/gateway/test_line_plugin.py::TestSignature::test_empty_secret_rejected tests/gateway/test_line_plugin.py::TestSignature::test_garbage_signature_rejected tests/gateway/test_line_plugin.py::TestSourceResolution::test_user_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_group_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_room_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_unknown_source_falls_back_to_dm tests/gateway/test_line_plugin.py::TestSourceResolution::test_empty_source tests/gateway/test_line_plugin.py::TestAllowlist::test_allow_all_short_circuits tests/gateway/test_line_plugin.py::TestAllowlist::test_user_in_allowlist_passes tests/gateway/test_line_plugin.py::TestAllowlist::test_user_not_in_allowlist_rejected tests/gateway/test_line_plugin.py::TestAllowlist::test_group_uses_group_list_not_user_list tests/gateway/test_line_plugin.py::TestAllowlist::test_room_uses_room_list tests/gateway/test_line_plugin.py::TestAllowlist::test_unknown_type_rejected tests/gateway/test_line_plugin.py::TestDedup::test_first_event_not_duplicate tests/gateway/test_line_plugin.py::TestDedup::test_repeat_event_marked_duplicate tests/gateway/test_line_plugin.py::TestDedup::test_blank_id_not_treated_as_duplicate tests/gateway/test_line_plugin.py::TestDedup::test_lru_eviction_under_pressure tests/gateway/test_line_plugin.py::TestRequestCache::test_register_pending_is_pending tests/gateway/test_line_plugin.py::TestRequestCache::test_set_ready_transitions tests/gateway/test_line_plugin.py::TestRequestCache::test_set_error_transitions tests/gateway/test_line_plugin.py::TestRequestCache::test_mark_delivered_from_ready tests/gateway/test_line_plugin.py::TestRequestCache::test_mark_delivered_from_error tests/gateway/test_line_plugin.py::TestRequestCache::test_set_ready_on_delivered_is_noop tests/gateway/test_line_plugin.py::TestRequestCache::test_find_pending_for_chat tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_bold_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_italic_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_inline_code_unfenced tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_link_preserved_with_url tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_heading_prefix_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_bullet_marker_replaced tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_code_fence_content_kept tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_short_returns_single_chunk tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_long_chunks_at_paragraph_boundary tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_caps_at_five_chunks tests/gateway/test_line_plugin.py::TestSendRouting::test_system_bypass_recognized tests/gateway/test_line_plugin.py::TestSendRouting::test_send_uses_reply_when_token_present tests/gateway/test_line_plugin.py::TestSendRouting::test_send_falls_back_to_push_when_no_token tests/gateway/test_line_plugin.py::TestSendRouting::test_send_falls_back_to_push_when_reply_fails tests/gateway/test_line_plugin.py::TestSendRouting::test_send_returns_failure_when_push_fails tests/gateway/test_line_plugin.py::TestSendRouting::test_send_pending_button_caches_response tests/gateway/test_line_plugin.py::TestSendRouting::test_send_system_bypass_skips_postback_cache tests/gateway/test_line_plugin.py::TestSendRouting::test_send_caps_messages_per_call_at_five tests/gateway/test_line_plugin.py::TestSendRouting::test_format_message_strips_markdown tests/gateway/test_line_plugin.py::TestRegister::test_register_calls_register_platform tests/gateway/test_line_plugin.py::TestRegister::test_register_advertises_required_env tests/gateway/test_line_plugin.py::TestRegister::test_register_wires_allowlist_envs tests/gateway/test_line_plugin.py::TestRegister::test_register_wires_cron_home_channel tests/gateway/test_line_plugin.py::TestRegister::test_register_provides_standalone_sender tests/gateway/test_line_plugin.py::TestRegister::test_register_provides_env_enablement tests/gateway/test_line_plugin.py::TestRegister::test_register_factory_yields_line_adapter tests/gateway/test_line_plugin.py::TestRegister::test_max_message_length_below_line_per_bubble_limit tests/gateway/test_line_plugin.py::TestEnvEnablement::test_returns_none_without_credentials tests/gateway/test_line_plugin.py::TestEnvEnablement::test_returns_dict_with_credentials tests/gateway/test_line_plugin.py::TestEnvEnablement::test_seeds_port_from_env tests/gateway/test_line_plugin.py::TestEnvEnablement::test_seeds_public_url tests/gateway/test_line_plugin.py::TestStandaloneSend::test_missing_token_returns_error tests/gateway/test_line_plugin.py::TestStandaloneSend::test_missing_chat_id_returns_error tests/gateway/test_line_plugin.py::TestStandaloneSend::test_pushes_via_client_when_credentials_present tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_template_buttons_structure tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_text_truncated_to_160 tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_alt_text_truncated_to_400 tests/gateway/test_line_plugin.py::TestCheckRequirements::test_rejects_without_token tests/gateway/test_line_plugin.py::TestCheckRequirements::test_rejects_without_secret tests/gateway/test_line_plugin.py::TestValidateConfig::test_validates_from_extra tests/gateway/test_line_plugin.py::TestValidateConfig::test_rejects_empty_config tests/gateway/test_line_plugin.py::TestAdapterInit::test_init_from_config_extra tests/gateway/test_line_plugin.py::TestAdapterInit::test_env_overrides_extra tests/gateway/test_line_plugin.py::TestAdapterInit::test_csv_allowlist_parsed tests/gateway/test_line_plugin.py::TestAdapterInit::test_get_chat_info_infers_type_from_prefix tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_image_event_not_attributeerror_regression tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_every_line_type_maps_to_correct_enum tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_unknown_type_falls_back_to_text