Skip to content

Commit ecbba24

Browse files
committed
feat(aci): Add ability to filter workflows by connected detectors
1 parent ee6a1e8 commit ecbba24

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/sentry/workflow_engine/endpoints/organization_workflow_index.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ def filter_workflows(self, request: Request, organization: Organization) -> Quer
121121
# If specific IDs are provided, skip query and project filtering
122122
return queryset
123123

124+
if raw_detectorlist := request.GET.getlist("detector"):
125+
try:
126+
detector_ids = [int(id) for id in raw_detectorlist]
127+
except ValueError:
128+
raise ValidationError({"detector": ["Invalid detector ID format"]})
129+
queryset = queryset.filter(detectorworkflow__detector_id__in=detector_ids).distinct()
130+
131+
# If detector IDs are provided, skip query and project filtering
132+
return queryset
133+
124134
if raw_query := request.GET.get("query"):
125135
for filter in parse_workflow_query(raw_query):
126136
assert isinstance(filter, SearchFilter)

tests/sentry/workflow_engine/endpoints/test_organization_workflow_index.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,53 @@ def test_query_filter_by_action(self) -> None:
346346
assert len(response3.data) == 2
347347
assert {self.workflow.name, self.workflow_two.name} == {w["name"] for w in response3.data}
348348

349+
def test_filter_by_detector(self) -> None:
350+
project_1 = self.create_project(organization=self.organization)
351+
project_2 = self.create_project(organization=self.organization)
352+
project_3 = self.create_project(organization=self.organization)
353+
354+
detector_1 = self.create_detector(project=project_1, name="Detector 1")
355+
detector_2 = self.create_detector(project=project_2, name="Detector 2")
356+
detector_3 = self.create_detector(project=project_3, name="Detector 3")
357+
358+
self.create_detector_workflow(workflow=self.workflow, detector=detector_1)
359+
self.create_detector_workflow(workflow=self.workflow_two, detector=detector_2)
360+
self.create_detector_workflow(workflow=self.workflow_three, detector=detector_3)
361+
362+
# Filter by single detector
363+
response = self.get_success_response(
364+
self.organization.slug,
365+
qs_params={"detector": str(detector_1.id)},
366+
)
367+
assert len(response.data) == 1
368+
assert response.data[0]["name"] == self.workflow.name
369+
370+
# Filter by multiple detectors
371+
response2 = self.get_success_response(
372+
self.organization.slug,
373+
qs_params=[
374+
("detector", str(detector_1.id)),
375+
("detector", str(detector_2.id)),
376+
],
377+
)
378+
assert len(response2.data) == 2
379+
assert {w["name"] for w in response2.data} == {self.workflow.name, self.workflow_two.name}
380+
381+
# Filter by non-existent detector ID returns no results
382+
response3 = self.get_success_response(
383+
self.organization.slug,
384+
qs_params={"detector": "999999"},
385+
)
386+
assert len(response3.data) == 0
387+
388+
# Invalid detector ID format returns error
389+
response4 = self.get_error_response(
390+
self.organization.slug,
391+
qs_params={"detector": "not-an-id"},
392+
status_code=400,
393+
)
394+
assert response4.data == {"detector": ["Invalid detector ID format"]}
395+
349396
def test_compound_query(self) -> None:
350397
self.create_detector_workflow(
351398
workflow=self.workflow, detector=self.create_detector(project=self.project)

0 commit comments

Comments
 (0)