@@ -669,6 +669,64 @@ def test_send_thread_update_explorer_response_missing_scope_has_footer(
669669 assert "Reinstall" in footer_text
670670 assert "Thread context is unavailable" in footer_text
671671
672+ @patch ("sentry.integrations.slack.integration.SlackIntegration.send_threaded_message" )
673+ @patch (
674+ "sentry.integrations.slack.integration.SlackIntegration.has_history_scope" ,
675+ return_value = False ,
676+ )
677+ def test_send_thread_update_explorer_response_missing_scope_no_footer_on_second_message (
678+ self , mock_has_history_scope , mock_send_threaded_message
679+ ):
680+ """Subsequent explorer responses in the same thread should not repeat the footer."""
681+ data = SeerExplorerResponse (
682+ run_id = 12345 ,
683+ organization_id = self .organization .id ,
684+ summary = "Test summary" ,
685+ )
686+ install = self .integration .get_installation (organization_id = self .organization .id )
687+ thread = SlackThreadDetails (thread_ts = self .thread_ts , channel_id = self .channel_id )
688+
689+ # First call — footer should be present
690+ send_thread_update (install = install , thread = thread , data = data )
691+ renderable_first = mock_send_threaded_message .call_args .kwargs ["renderable" ]
692+ assert renderable_first ["blocks" ][- 1 ].type == "context"
693+
694+ mock_send_threaded_message .reset_mock ()
695+
696+ # Second call in same thread — footer should be absent
697+ send_thread_update (install = install , thread = thread , data = data )
698+ renderable_second = mock_send_threaded_message .call_args .kwargs ["renderable" ]
699+ for block in renderable_second ["blocks" ]:
700+ assert block .type != "context"
701+
702+ @patch ("sentry.integrations.slack.integration.SlackIntegration.send_threaded_message" )
703+ @patch (
704+ "sentry.integrations.slack.integration.SlackIntegration.has_history_scope" ,
705+ return_value = False ,
706+ )
707+ def test_send_thread_update_explorer_response_missing_scope_different_thread_gets_footer (
708+ self , mock_has_history_scope , mock_send_threaded_message
709+ ):
710+ """Different threads should each get their own first-time footer."""
711+ data = SeerExplorerResponse (
712+ run_id = 12345 ,
713+ organization_id = self .organization .id ,
714+ summary = "Test summary" ,
715+ )
716+ install = self .integration .get_installation (organization_id = self .organization .id )
717+ thread_a = SlackThreadDetails (thread_ts = self .thread_ts , channel_id = self .channel_id )
718+ thread_b = SlackThreadDetails (thread_ts = "9999999999.999999" , channel_id = self .channel_id )
719+
720+ send_thread_update (install = install , thread = thread_a , data = data )
721+ renderable_a = mock_send_threaded_message .call_args .kwargs ["renderable" ]
722+ assert renderable_a ["blocks" ][- 1 ].type == "context"
723+
724+ mock_send_threaded_message .reset_mock ()
725+
726+ send_thread_update (install = install , thread = thread_b , data = data )
727+ renderable_b = mock_send_threaded_message .call_args .kwargs ["renderable" ]
728+ assert renderable_b ["blocks" ][- 1 ].type == "context"
729+
672730 @patch ("sentry.integrations.slack.integration.SlackIntegration.send_threaded_message" )
673731 @patch (
674732 "sentry.integrations.slack.integration.SlackIntegration.has_history_scope" ,
0 commit comments