Skip to content

Commit e419988

Browse files
authored
fix(aci): camelCase action data fields in serializer (#104597)
we already made the fix to convert the action `config` fields to camelCase in the action serializer, so we should do the same for the `data` fields
1 parent fa010e8 commit e419988

File tree

3 files changed

+31
-64
lines changed

3 files changed

+31
-64
lines changed

src/sentry/workflow_engine/endpoints/serializers/action_serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def serialize(self, obj: Action, *args, **kwargs) -> ActionSerializerResponse:
3232
"id": str(obj.id),
3333
"type": obj.type,
3434
"integrationId": str(obj.integration_id) if obj.integration_id else None,
35-
"data": obj.data,
35+
"data": convert_dict_key_case(obj.data, snake_to_camel_case),
3636
"config": convert_dict_key_case(config, snake_to_camel_case),
3737
"status": obj.get_status_display(),
3838
}

tests/sentry/workflow_engine/endpoints/serializers/test_action_serializer.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from sentry.api.serializers import serialize
22
from sentry.constants import ObjectStatus
33
from sentry.notifications.models.notificationaction import ActionTarget
4+
from sentry.notifications.types import FallthroughChoiceType
45
from sentry.testutils.cases import TestCase
56
from sentry.testutils.skips import requires_snuba
67
from sentry.workflow_engine.models import Action
@@ -103,3 +104,25 @@ def test_serialize_with_integration_and_config(self) -> None:
103104
},
104105
"status": "active",
105106
}
107+
108+
def test_serialize_with_data(self) -> None:
109+
action = self.create_action(
110+
type=Action.Type.EMAIL,
111+
data={"fallthrough_type": FallthroughChoiceType.ACTIVE_MEMBERS},
112+
config={
113+
"target_type": ActionTarget.ISSUE_OWNERS,
114+
},
115+
)
116+
117+
result = serialize(action)
118+
119+
assert result == {
120+
"id": str(action.id),
121+
"type": "email",
122+
"data": {"fallthroughType": "ActiveMembers"},
123+
"integrationId": None,
124+
"config": {
125+
"targetType": "issue_owners",
126+
},
127+
"status": "active",
128+
}

tests/sentry/workflow_engine/endpoints/test_organization_workflow_index.py

Lines changed: 7 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,11 @@
1111
from sentry.deletions.tasks.scheduled import run_scheduled_deletions
1212
from sentry.grouping.grouptype import ErrorGroupType
1313
from sentry.incidents.grouptype import MetricIssue
14-
from sentry.notifications.types import FallthroughChoiceType
1514
from sentry.testutils.asserts import assert_org_audit_log_exists
1615
from sentry.testutils.cases import APITestCase
1716
from sentry.testutils.outbox import outbox_runner
1817
from sentry.testutils.silo import region_silo_test
19-
from sentry.workflow_engine.models import (
20-
Action,
21-
DataConditionGroupAction,
22-
DetectorWorkflow,
23-
Workflow,
24-
WorkflowDataConditionGroup,
25-
WorkflowFireHistory,
26-
)
18+
from sentry.workflow_engine.models import Action, DetectorWorkflow, Workflow, WorkflowFireHistory
2719
from sentry.workflow_engine.models.data_condition import Condition
2820
from sentry.workflow_engine.typings.notification_action import (
2921
ActionTarget,
@@ -447,7 +439,7 @@ def test_create_workflow__with_config(self) -> None:
447439

448440
assert response.status_code == 201
449441
new_workflow = Workflow.objects.get(id=response.data["id"])
450-
assert new_workflow.config == self.valid_workflow["config"]
442+
assert response.data == serialize(new_workflow)
451443

452444
def test_create_workflow__with_triggers(self) -> None:
453445
self.valid_workflow["triggers"] = {
@@ -462,10 +454,7 @@ def test_create_workflow__with_triggers(self) -> None:
462454

463455
assert response.status_code == 201
464456
new_workflow = Workflow.objects.get(id=response.data["id"])
465-
assert new_workflow.when_condition_group is not None
466-
assert str(new_workflow.when_condition_group.id) == response.data.get("triggers", {}).get(
467-
"id"
468-
)
457+
assert response.data == serialize(new_workflow)
469458

470459
@mock.patch(
471460
"sentry.notifications.notification_action.registry.action_validator_registry.get",
@@ -498,11 +487,7 @@ def test_create_workflow__with_actions(self, mock_action_validator: mock.MagicMo
498487

499488
assert response.status_code == 201
500489
new_workflow = Workflow.objects.get(id=response.data["id"])
501-
new_action_filters = WorkflowDataConditionGroup.objects.filter(workflow=new_workflow)
502-
assert len(new_action_filters) == len(response.data.get("actionFilters", []))
503-
assert str(new_action_filters[0].condition_group.id) == response.data.get(
504-
"actionFilters", []
505-
)[0].get("id")
490+
assert response.data == serialize(new_workflow)
506491

507492
@mock.patch(
508493
"sentry.notifications.notification_action.registry.action_validator_registry.get",
@@ -534,24 +519,7 @@ def test_create_workflow__with_fallthrough_type_action(
534519

535520
assert response.status_code == 201
536521
new_workflow = Workflow.objects.get(id=response.data["id"])
537-
new_action_filters = WorkflowDataConditionGroup.objects.filter(workflow=new_workflow)
538-
assert len(new_action_filters) == len(response.data.get("actionFilters", []))
539-
dcga = DataConditionGroupAction.objects.filter(
540-
condition_group=new_action_filters[0].condition_group
541-
).first()
542-
assert dcga
543-
assert str(new_action_filters[0].condition_group.id) == response.data.get(
544-
"actionFilters", []
545-
)[0].get("id")
546-
assert (
547-
response.data.get("actionFilters")[0]
548-
.get("actions")[0]
549-
.get("data")
550-
.get("fallthrough_type")
551-
== FallthroughChoiceType.ACTIVE_MEMBERS.value
552-
)
553-
assert dcga.action.type == Action.Type.EMAIL
554-
assert dcga.action.data == {"fallthrough_type": "ActiveMembers"}
522+
assert response.data == serialize(new_workflow)
555523

556524
@responses.activate
557525
def test_create_workflow_with_sentry_app_action(self) -> None:
@@ -587,19 +555,7 @@ def test_create_workflow_with_sentry_app_action(self) -> None:
587555
raw_data=self.valid_workflow,
588556
)
589557
updated_workflow = Workflow.objects.get(id=response.data["id"])
590-
new_action_filters = WorkflowDataConditionGroup.objects.filter(workflow=updated_workflow)
591-
dcga = DataConditionGroupAction.objects.filter(
592-
condition_group=new_action_filters[0].condition_group
593-
)
594-
action = dcga[0].action
595-
596-
assert action.type == Action.Type.SENTRY_APP
597-
assert action.config == {
598-
"sentry_app_identifier": SentryAppIdentifier.SENTRY_APP_ID,
599-
"target_identifier": str(self.sentry_app.id),
600-
"target_type": ActionTarget.SENTRY_APP.value,
601-
}
602-
assert action.data["settings"] == self.sentry_app_settings
558+
assert response.data == serialize(updated_workflow)
603559

604560
@responses.activate
605561
def test_create_sentry_app_action_missing_settings(self) -> None:
@@ -679,19 +635,7 @@ def test_create_sentry_app_action_no_settings(self) -> None:
679635
raw_data=self.valid_workflow,
680636
)
681637
updated_workflow = Workflow.objects.get(id=response.data["id"])
682-
new_action_filters = WorkflowDataConditionGroup.objects.filter(workflow=updated_workflow)
683-
dcga = DataConditionGroupAction.objects.filter(
684-
condition_group=new_action_filters[0].condition_group
685-
)
686-
action = dcga[0].action
687-
688-
assert action.type == Action.Type.SENTRY_APP
689-
assert action.config == {
690-
"sentry_app_identifier": SentryAppIdentifier.SENTRY_APP_ID,
691-
"target_identifier": str(sentry_app.id),
692-
"target_type": ActionTarget.SENTRY_APP.value,
693-
}
694-
assert action.data == {}
638+
assert response.data == serialize(updated_workflow)
695639

696640
def test_create_invalid_workflow(self) -> None:
697641
self.valid_workflow["name"] = ""

0 commit comments

Comments
 (0)