1+ from contextlib import contextmanager
12from unittest .mock import patch
23
34import pytest
@@ -16,21 +17,105 @@ def setUp(self):
1617 super ().setUp ()
1718 self .ten_mins_ago = before_now (minutes = 10 )
1819
20+ @contextmanager
21+ def mock_seer_ack (self ):
22+ with (
23+ patch (
24+ "sentry.tasks.web_vitals_issue_detection.get_seer_org_acknowledgement"
25+ ) as mock_ack ,
26+ ):
27+ mock_ack .return_value = True
28+ yield {"mock_ack" : mock_ack }
29+
30+ @contextmanager
31+ def mock_code_mapping (self ):
32+ with (
33+ patch (
34+ "sentry.tasks.web_vitals_issue_detection.get_autofix_repos_from_project_code_mappings"
35+ ) as mock_repos ,
36+ ):
37+ mock_repos .return_value = [
38+ {
39+ "provider" : "integrations:github" ,
40+ "owner" : "test-owner" ,
41+ "name" : "test-repo" ,
42+ }
43+ ]
44+ yield {"mock_repos" : mock_repos }
45+
1946 @patch ("sentry.tasks.web_vitals_issue_detection.detect_web_vitals_issues_for_project.delay" )
20- def test_run_detection_dispatches_sub_tasks (self , mock_delay ):
47+ def test_run_detection_dispatches_sub_tasks_when_enabled (self , mock_delay ):
2148 project = self .create_project ()
2249
23- with self .options (
24- {
25- "issue-detection.web-vitals-detection.enabled" : True ,
26- "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
27- }
50+ with (
51+ self .mock_seer_ack (),
52+ self .mock_code_mapping (),
53+ self .options (
54+ {
55+ "issue-detection.web-vitals-detection.enabled" : True ,
56+ "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
57+ }
58+ ),
59+ self .feature ("organizations:gen-ai-features" ),
2860 ):
2961 run_web_vitals_issue_detection ()
3062
3163 assert mock_delay .called
3264 assert mock_delay .call_args [0 ][0 ] == project .id
3365
66+ @patch ("sentry.tasks.web_vitals_issue_detection.detect_web_vitals_issues_for_project.delay" )
67+ def test_run_detection_skips_when_seer_not_acknowledged (self , mock_delay ):
68+ project = self .create_project ()
69+
70+ with (
71+ self .mock_code_mapping (),
72+ self .options (
73+ {
74+ "issue-detection.web-vitals-detection.enabled" : True ,
75+ "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
76+ }
77+ ),
78+ self .feature ("organizations:gen-ai-features" ),
79+ ):
80+ run_web_vitals_issue_detection ()
81+
82+ assert not mock_delay .called
83+
84+ @patch ("sentry.tasks.web_vitals_issue_detection.detect_web_vitals_issues_for_project.delay" )
85+ def test_run_detection_skips_when_no_github_code_mappings (self , mock_delay ):
86+ project = self .create_project ()
87+
88+ with (
89+ self .mock_seer_ack (),
90+ self .options (
91+ {
92+ "issue-detection.web-vitals-detection.enabled" : True ,
93+ "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
94+ }
95+ ),
96+ self .feature ("organizations:gen-ai-features" ),
97+ ):
98+ run_web_vitals_issue_detection ()
99+
100+ assert not mock_delay .called
101+
102+ @patch ("sentry.tasks.web_vitals_issue_detection.detect_web_vitals_issues_for_project.delay" )
103+ def test_run_detection_skips_when_not_allowlisted (self , mock_delay ):
104+ with (
105+ self .mock_seer_ack (),
106+ self .mock_code_mapping (),
107+ self .options (
108+ {
109+ "issue-detection.web-vitals-detection.enabled" : True ,
110+ "issue-detection.web-vitals-detection.projects-allowlist" : [],
111+ }
112+ ),
113+ self .feature ("organizations:gen-ai-features" ),
114+ ):
115+ run_web_vitals_issue_detection ()
116+
117+ assert not mock_delay .called
118+
34119 @pytest .mark .snuba
35120 @patch ("sentry.web_vitals.issue_platform_adapter.produce_occurrence_to_kafka" )
36121 def test_run_detection_produces_occurrences (self , mock_produce_occurrence_to_kafka ):
@@ -110,12 +195,15 @@ def test_run_detection_produces_occurrences(self, mock_produce_occurrence_to_kaf
110195 self .store_spans (spans , is_eap = True )
111196
112197 with (
198+ self .mock_seer_ack (),
199+ self .mock_code_mapping (),
113200 self .options (
114201 {
115202 "issue-detection.web-vitals-detection.enabled" : True ,
116203 "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
117204 }
118205 ),
206+ self .feature ("organizations:gen-ai-features" ),
119207 TaskRunner (),
120208 ):
121209 run_web_vitals_issue_detection ()
@@ -209,12 +297,15 @@ def test_run_detection_does_not_produce_occurrences_for_existing_issues(
209297 )
210298
211299 with (
300+ self .mock_seer_ack (),
301+ self .mock_code_mapping (),
212302 self .options (
213303 {
214304 "issue-detection.web-vitals-detection.enabled" : True ,
215305 "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
216306 }
217307 ),
308+ self .feature ("organizations:gen-ai-features" ),
218309 TaskRunner (),
219310 ):
220311 run_web_vitals_issue_detection ()
@@ -251,12 +342,15 @@ def test_run_detection_does_not_create_issue_on_insufficient_samples(
251342 self .store_spans (spans , is_eap = True )
252343
253344 with (
345+ self .mock_seer_ack (),
346+ self .mock_code_mapping (),
254347 self .options (
255348 {
256349 "issue-detection.web-vitals-detection.enabled" : True ,
257350 "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
258351 }
259352 ),
353+ self .feature ("organizations:gen-ai-features" ),
260354 TaskRunner (),
261355 ):
262356 run_web_vitals_issue_detection ()
@@ -330,12 +424,15 @@ def test_run_detection_selects_trace_closest_to_p75_web_vital_value(
330424 self .store_spans (spans , is_eap = True )
331425
332426 with (
427+ self .mock_seer_ack (),
428+ self .mock_code_mapping (),
333429 self .options (
334430 {
335431 "issue-detection.web-vitals-detection.enabled" : True ,
336432 "issue-detection.web-vitals-detection.projects-allowlist" : [project .id ],
337433 }
338434 ),
435+ self .feature ("organizations:gen-ai-features" ),
339436 TaskRunner (),
340437 ):
341438 run_web_vitals_issue_detection ()
0 commit comments