firefighter-incident 0.0.14__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- firefighter/_version.py +2 -2
- firefighter/api/serializers.py +9 -0
- firefighter/confluence/signals/incident_updated.py +2 -2
- firefighter/incidents/enums.py +22 -2
- firefighter/incidents/forms/closure_reason.py +45 -0
- firefighter/incidents/forms/unified_incident.py +406 -0
- firefighter/incidents/forms/update_status.py +87 -1
- firefighter/incidents/migrations/0027_add_closure_fields.py +40 -0
- firefighter/incidents/migrations/0028_add_closure_reason_constraint.py +33 -0
- firefighter/incidents/migrations/0029_add_custom_fields_to_incident.py +22 -0
- firefighter/incidents/models/incident.py +32 -5
- firefighter/incidents/static/css/main.min.css +1 -1
- firefighter/incidents/templates/layouts/partials/status_pill.html +1 -1
- firefighter/incidents/views/reports.py +3 -3
- firefighter/raid/apps.py +9 -26
- firefighter/raid/client.py +2 -2
- firefighter/raid/forms.py +75 -238
- firefighter/raid/signals/incident_created.py +38 -13
- firefighter/raid/signals/incident_updated.py +3 -2
- firefighter/slack/messages/slack_messages.py +19 -4
- firefighter/slack/rules.py +1 -1
- firefighter/slack/signals/create_incident_conversation.py +6 -0
- firefighter/slack/signals/incident_updated.py +7 -1
- firefighter/slack/views/modals/__init__.py +4 -0
- firefighter/slack/views/modals/base_modal/form_utils.py +63 -0
- firefighter/slack/views/modals/close.py +15 -2
- firefighter/slack/views/modals/closure_reason.py +193 -0
- firefighter/slack/views/modals/open.py +60 -13
- firefighter/slack/views/modals/opening/details/unified.py +203 -0
- firefighter/slack/views/modals/opening/select_impact.py +1 -1
- firefighter/slack/views/modals/opening/set_details.py +3 -2
- firefighter/slack/views/modals/postmortem.py +10 -2
- firefighter/slack/views/modals/update_status.py +28 -2
- firefighter/slack/views/modals/utils.py +51 -0
- {firefighter_incident-0.0.14.dist-info → firefighter_incident-0.0.16.dist-info}/METADATA +1 -1
- {firefighter_incident-0.0.14.dist-info → firefighter_incident-0.0.16.dist-info}/RECORD +62 -38
- firefighter_tests/test_incidents/test_enums.py +100 -0
- firefighter_tests/test_incidents/test_forms/conftest.py +179 -0
- firefighter_tests/test_incidents/test_forms/test_closure_reason.py +91 -0
- firefighter_tests/test_incidents/test_forms/test_unified_incident_form.py +570 -0
- firefighter_tests/test_incidents/test_forms/test_unified_incident_form_integration.py +581 -0
- firefighter_tests/test_incidents/test_forms/test_unified_incident_form_p4_p5.py +410 -0
- firefighter_tests/test_incidents/test_forms/test_update_status_workflow.py +343 -0
- firefighter_tests/test_incidents/test_forms/test_workflow_transitions.py +167 -0
- firefighter_tests/test_incidents/test_models/test_incident_model.py +68 -0
- firefighter_tests/test_raid/conftest.py +154 -0
- firefighter_tests/test_raid/test_p1_p3_jira_fields.py +372 -0
- firefighter_tests/test_raid/test_raid_forms.py +10 -253
- firefighter_tests/test_raid/test_raid_signals.py +187 -0
- firefighter_tests/test_slack/messages/__init__.py +0 -0
- firefighter_tests/test_slack/messages/test_slack_messages.py +367 -0
- firefighter_tests/test_slack/views/modals/conftest.py +140 -0
- firefighter_tests/test_slack/views/modals/test_close.py +65 -3
- firefighter_tests/test_slack/views/modals/test_closure_reason_modal.py +138 -0
- firefighter_tests/test_slack/views/modals/test_form_utils_multiple_choice.py +249 -0
- firefighter_tests/test_slack/views/modals/test_open.py +146 -2
- firefighter_tests/test_slack/views/modals/test_opening_unified.py +421 -0
- firefighter_tests/test_slack/views/modals/test_update_status.py +327 -3
- firefighter_tests/test_slack/views/modals/test_utils.py +135 -0
- firefighter/raid/views/open_normal.py +0 -139
- firefighter/slack/views/modals/opening/details/critical.py +0 -88
- {firefighter_incident-0.0.14.dist-info → firefighter_incident-0.0.16.dist-info}/WHEEL +0 -0
- {firefighter_incident-0.0.14.dist-info → firefighter_incident-0.0.16.dist-info}/entry_points.txt +0 -0
- {firefighter_incident-0.0.14.dist-info → firefighter_incident-0.0.16.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"""Tests for unified incident opening modal."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from firefighter.incidents.models.impact import LevelChoices
|
|
9
|
+
from firefighter.slack.views.modals.base_modal.form_utils import SlackForm
|
|
10
|
+
from firefighter.slack.views.modals.opening.details.unified import (
|
|
11
|
+
OpeningUnifiedModal,
|
|
12
|
+
UnifiedIncidentFormSlack,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.mark.django_db
|
|
17
|
+
class TestUnifiedIncidentFormSlack:
|
|
18
|
+
"""Test Slack-specific version of unified form."""
|
|
19
|
+
|
|
20
|
+
def test_form_initializes_with_impacts_and_response_type(
|
|
21
|
+
self, priority_factory, impact_level_factory
|
|
22
|
+
):
|
|
23
|
+
"""Form should properly receive impacts_data and response_type."""
|
|
24
|
+
priority_factory(value=1, default=True)
|
|
25
|
+
customer_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Customers")
|
|
26
|
+
|
|
27
|
+
impacts_data = {"customers_impact": customer_impact}
|
|
28
|
+
|
|
29
|
+
form = UnifiedIncidentFormSlack(
|
|
30
|
+
impacts_data=impacts_data,
|
|
31
|
+
response_type="critical",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Should configure field visibility
|
|
35
|
+
assert "zendesk_ticket_id" in form.fields
|
|
36
|
+
assert "suggested_team_routing" not in form.fields
|
|
37
|
+
|
|
38
|
+
def test_slack_blocks_generation_with_multiple_choice_fields(
|
|
39
|
+
self, priority_factory, environment_factory
|
|
40
|
+
):
|
|
41
|
+
"""Slack blocks should generate correctly with multiple choice fields."""
|
|
42
|
+
priority_factory(value=1, default=True)
|
|
43
|
+
environment_factory(value="PRD", default=True)
|
|
44
|
+
environment_factory(value="STG", default=False)
|
|
45
|
+
|
|
46
|
+
# Use SlackForm wrapper to generate blocks
|
|
47
|
+
slack_form = SlackForm(UnifiedIncidentFormSlack)(
|
|
48
|
+
impacts_data={},
|
|
49
|
+
response_type="critical",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Should generate blocks without errors
|
|
53
|
+
blocks = slack_form.slack_blocks()
|
|
54
|
+
assert len(blocks) > 0
|
|
55
|
+
|
|
56
|
+
# Find environment block (multi-select)
|
|
57
|
+
env_blocks = [b for b in blocks if hasattr(b, "block_id") and b.block_id == "environment"]
|
|
58
|
+
assert len(env_blocks) == 1
|
|
59
|
+
|
|
60
|
+
env_block = env_blocks[0]
|
|
61
|
+
assert env_block.element.type == "multi_static_select"
|
|
62
|
+
|
|
63
|
+
def test_priority_field_is_hidden(self, priority_factory):
|
|
64
|
+
"""Priority field should not appear in Slack blocks."""
|
|
65
|
+
priority_factory(value=1, default=True)
|
|
66
|
+
|
|
67
|
+
# Use SlackForm wrapper to generate blocks
|
|
68
|
+
slack_form = SlackForm(UnifiedIncidentFormSlack)(
|
|
69
|
+
impacts_data={},
|
|
70
|
+
response_type="critical",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
blocks = slack_form.slack_blocks()
|
|
74
|
+
|
|
75
|
+
# Priority field should not generate a block (it's hidden)
|
|
76
|
+
priority_blocks = [
|
|
77
|
+
b for b in blocks if hasattr(b, "block_id") and b.block_id == "priority"
|
|
78
|
+
]
|
|
79
|
+
assert len(priority_blocks) == 0
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@pytest.mark.django_db
|
|
83
|
+
class TestOpeningUnifiedModal:
|
|
84
|
+
"""Test the unified opening modal."""
|
|
85
|
+
|
|
86
|
+
def test_build_modal_fn_passes_context_to_form(
|
|
87
|
+
self, priority_factory, impact_level_factory
|
|
88
|
+
):
|
|
89
|
+
"""build_modal_fn should pass impacts and response_type to form."""
|
|
90
|
+
priority_factory(value=1, default=True)
|
|
91
|
+
customer_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Customers")
|
|
92
|
+
|
|
93
|
+
modal = OpeningUnifiedModal()
|
|
94
|
+
|
|
95
|
+
open_incident_context = {
|
|
96
|
+
"response_type": "critical",
|
|
97
|
+
"impact_form_data": {"customers_impact": customer_impact},
|
|
98
|
+
"details_form_data": {},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
102
|
+
|
|
103
|
+
# Should build view without errors
|
|
104
|
+
assert view is not None
|
|
105
|
+
assert view.type == "modal"
|
|
106
|
+
assert len(view.blocks) > 0
|
|
107
|
+
|
|
108
|
+
# Check private_metadata contains our context
|
|
109
|
+
metadata = json.loads(view.private_metadata)
|
|
110
|
+
assert metadata["response_type"] == "critical"
|
|
111
|
+
assert "impact_form_data" in metadata
|
|
112
|
+
|
|
113
|
+
def test_build_modal_fn_critical_incident_hides_feature_team(
|
|
114
|
+
self, priority_factory
|
|
115
|
+
):
|
|
116
|
+
"""Critical incident should not show feature team field."""
|
|
117
|
+
priority_factory(value=1, default=True)
|
|
118
|
+
|
|
119
|
+
modal = OpeningUnifiedModal()
|
|
120
|
+
|
|
121
|
+
open_incident_context = {
|
|
122
|
+
"response_type": "critical",
|
|
123
|
+
"impact_form_data": {},
|
|
124
|
+
"details_form_data": {},
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
128
|
+
|
|
129
|
+
# Check that feature team field is not in blocks
|
|
130
|
+
feature_team_blocks = [
|
|
131
|
+
b
|
|
132
|
+
for b in view.blocks
|
|
133
|
+
if hasattr(b, "block_id") and b.block_id == "suggested_team_routing"
|
|
134
|
+
]
|
|
135
|
+
assert len(feature_team_blocks) == 0
|
|
136
|
+
|
|
137
|
+
def test_build_modal_fn_normal_incident_shows_feature_team(
|
|
138
|
+
self, priority_factory
|
|
139
|
+
):
|
|
140
|
+
"""Normal incident (P4-P5) should show feature team field."""
|
|
141
|
+
priority_factory(value=4, default=True)
|
|
142
|
+
|
|
143
|
+
modal = OpeningUnifiedModal()
|
|
144
|
+
|
|
145
|
+
open_incident_context = {
|
|
146
|
+
"response_type": "normal",
|
|
147
|
+
"impact_form_data": {},
|
|
148
|
+
"details_form_data": {},
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
152
|
+
|
|
153
|
+
# Check that feature team field IS in blocks
|
|
154
|
+
feature_team_blocks = [
|
|
155
|
+
b
|
|
156
|
+
for b in view.blocks
|
|
157
|
+
if hasattr(b, "block_id") and b.block_id == "suggested_team_routing"
|
|
158
|
+
]
|
|
159
|
+
assert len(feature_team_blocks) == 1
|
|
160
|
+
|
|
161
|
+
def test_build_modal_fn_customer_impact_shows_zendesk(
|
|
162
|
+
self, priority_factory, impact_level_factory
|
|
163
|
+
):
|
|
164
|
+
"""Customer impact should show Zendesk field."""
|
|
165
|
+
priority_factory(value=1, default=True)
|
|
166
|
+
customer_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Customers")
|
|
167
|
+
|
|
168
|
+
modal = OpeningUnifiedModal()
|
|
169
|
+
|
|
170
|
+
open_incident_context = {
|
|
171
|
+
"response_type": "critical",
|
|
172
|
+
"impact_form_data": {"customers_impact": customer_impact},
|
|
173
|
+
"details_form_data": {},
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
177
|
+
|
|
178
|
+
# Check that zendesk field IS in blocks
|
|
179
|
+
zendesk_blocks = [
|
|
180
|
+
b
|
|
181
|
+
for b in view.blocks
|
|
182
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
183
|
+
]
|
|
184
|
+
assert len(zendesk_blocks) == 1
|
|
185
|
+
|
|
186
|
+
def test_build_modal_fn_seller_impact_shows_seller_fields(
|
|
187
|
+
self, priority_factory, impact_level_factory
|
|
188
|
+
):
|
|
189
|
+
"""Seller impact should show seller-specific fields."""
|
|
190
|
+
priority_factory(value=1, default=True)
|
|
191
|
+
seller_impact = impact_level_factory(value=LevelChoices.LOW, impact__name="Sellers")
|
|
192
|
+
|
|
193
|
+
modal = OpeningUnifiedModal()
|
|
194
|
+
|
|
195
|
+
open_incident_context = {
|
|
196
|
+
"response_type": "critical",
|
|
197
|
+
"impact_form_data": {"sellers_impact": seller_impact},
|
|
198
|
+
"details_form_data": {},
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
202
|
+
|
|
203
|
+
# Check seller fields are in blocks
|
|
204
|
+
seller_contract_blocks = [
|
|
205
|
+
b
|
|
206
|
+
for b in view.blocks
|
|
207
|
+
if hasattr(b, "block_id") and b.block_id == "seller_contract_id"
|
|
208
|
+
]
|
|
209
|
+
assert len(seller_contract_blocks) == 1
|
|
210
|
+
|
|
211
|
+
zoho_blocks = [
|
|
212
|
+
b
|
|
213
|
+
for b in view.blocks
|
|
214
|
+
if hasattr(b, "block_id") and b.block_id == "zoho_desk_ticket_id"
|
|
215
|
+
]
|
|
216
|
+
assert len(zoho_blocks) == 1
|
|
217
|
+
|
|
218
|
+
def test_build_modal_fn_business_impact_only_hides_customer_seller_fields(
|
|
219
|
+
self, priority_factory, impact_level_factory
|
|
220
|
+
):
|
|
221
|
+
"""Business impact only should not show customer/seller fields."""
|
|
222
|
+
priority_factory(value=1, default=True)
|
|
223
|
+
business_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Business")
|
|
224
|
+
|
|
225
|
+
modal = OpeningUnifiedModal()
|
|
226
|
+
|
|
227
|
+
open_incident_context = {
|
|
228
|
+
"response_type": "critical",
|
|
229
|
+
"impact_form_data": {"business_impact": business_impact},
|
|
230
|
+
"details_form_data": {},
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
234
|
+
|
|
235
|
+
# Should NOT show customer or seller fields
|
|
236
|
+
zendesk_blocks = [
|
|
237
|
+
b
|
|
238
|
+
for b in view.blocks
|
|
239
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
240
|
+
]
|
|
241
|
+
assert len(zendesk_blocks) == 0
|
|
242
|
+
|
|
243
|
+
seller_blocks = [
|
|
244
|
+
b
|
|
245
|
+
for b in view.blocks
|
|
246
|
+
if hasattr(b, "block_id") and b.block_id == "seller_contract_id"
|
|
247
|
+
]
|
|
248
|
+
assert len(seller_blocks) == 0
|
|
249
|
+
|
|
250
|
+
def test_build_modal_fn_employee_impact_only_hides_customer_seller_fields(
|
|
251
|
+
self, priority_factory, impact_level_factory
|
|
252
|
+
):
|
|
253
|
+
"""Employee impact only should not show customer/seller fields."""
|
|
254
|
+
priority_factory(value=1, default=True)
|
|
255
|
+
employee_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Employees")
|
|
256
|
+
|
|
257
|
+
modal = OpeningUnifiedModal()
|
|
258
|
+
|
|
259
|
+
open_incident_context = {
|
|
260
|
+
"response_type": "critical",
|
|
261
|
+
"impact_form_data": {"employees_impact": employee_impact},
|
|
262
|
+
"details_form_data": {},
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
266
|
+
|
|
267
|
+
# Should NOT show customer or seller fields
|
|
268
|
+
zendesk_blocks = [
|
|
269
|
+
b
|
|
270
|
+
for b in view.blocks
|
|
271
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
272
|
+
]
|
|
273
|
+
assert len(zendesk_blocks) == 0
|
|
274
|
+
|
|
275
|
+
seller_blocks = [
|
|
276
|
+
b
|
|
277
|
+
for b in view.blocks
|
|
278
|
+
if hasattr(b, "block_id") and b.block_id == "seller_contract_id"
|
|
279
|
+
]
|
|
280
|
+
assert len(seller_blocks) == 0
|
|
281
|
+
|
|
282
|
+
def test_build_modal_fn_all_impacts_shows_all_fields(
|
|
283
|
+
self, priority_factory, impact_level_factory
|
|
284
|
+
):
|
|
285
|
+
"""All impact types should show all specific fields."""
|
|
286
|
+
priority_factory(value=1, default=True)
|
|
287
|
+
customer_impact = impact_level_factory(value=LevelChoices.LOW, impact__name="Customers")
|
|
288
|
+
seller_impact = impact_level_factory(value=LevelChoices.LOW, impact__name="Sellers")
|
|
289
|
+
employee_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Employees")
|
|
290
|
+
business_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Business")
|
|
291
|
+
|
|
292
|
+
modal = OpeningUnifiedModal()
|
|
293
|
+
|
|
294
|
+
open_incident_context = {
|
|
295
|
+
"response_type": "critical",
|
|
296
|
+
"impact_form_data": {
|
|
297
|
+
"customers_impact": customer_impact,
|
|
298
|
+
"sellers_impact": seller_impact,
|
|
299
|
+
"employees_impact": employee_impact,
|
|
300
|
+
"business_impact": business_impact,
|
|
301
|
+
},
|
|
302
|
+
"details_form_data": {},
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
306
|
+
|
|
307
|
+
# Should show both customer and seller fields
|
|
308
|
+
zendesk_blocks = [
|
|
309
|
+
b
|
|
310
|
+
for b in view.blocks
|
|
311
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
312
|
+
]
|
|
313
|
+
assert len(zendesk_blocks) == 1
|
|
314
|
+
|
|
315
|
+
seller_blocks = [
|
|
316
|
+
b
|
|
317
|
+
for b in view.blocks
|
|
318
|
+
if hasattr(b, "block_id") and b.block_id == "seller_contract_id"
|
|
319
|
+
]
|
|
320
|
+
assert len(seller_blocks) == 1
|
|
321
|
+
|
|
322
|
+
def test_build_modal_fn_none_impacts_hides_all_fields(
|
|
323
|
+
self, priority_factory, impact_level_factory
|
|
324
|
+
):
|
|
325
|
+
"""All impacts at NONE level should not show any specific fields."""
|
|
326
|
+
priority_factory(value=1, default=True)
|
|
327
|
+
customer_impact = impact_level_factory(value=LevelChoices.NONE, impact__name="Customers")
|
|
328
|
+
seller_impact = impact_level_factory(value=LevelChoices.NONE, impact__name="Sellers")
|
|
329
|
+
|
|
330
|
+
modal = OpeningUnifiedModal()
|
|
331
|
+
|
|
332
|
+
open_incident_context = {
|
|
333
|
+
"response_type": "critical",
|
|
334
|
+
"impact_form_data": {
|
|
335
|
+
"customers_impact": customer_impact,
|
|
336
|
+
"sellers_impact": seller_impact,
|
|
337
|
+
},
|
|
338
|
+
"details_form_data": {},
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
342
|
+
|
|
343
|
+
# Should NOT show any specific fields
|
|
344
|
+
zendesk_blocks = [
|
|
345
|
+
b
|
|
346
|
+
for b in view.blocks
|
|
347
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
348
|
+
]
|
|
349
|
+
assert len(zendesk_blocks) == 0
|
|
350
|
+
|
|
351
|
+
seller_blocks = [
|
|
352
|
+
b
|
|
353
|
+
for b in view.blocks
|
|
354
|
+
if hasattr(b, "block_id") and b.block_id == "seller_contract_id"
|
|
355
|
+
]
|
|
356
|
+
assert len(seller_blocks) == 0
|
|
357
|
+
|
|
358
|
+
def test_build_modal_fn_normal_with_customer_shows_team_and_zendesk(
|
|
359
|
+
self, priority_factory, impact_level_factory
|
|
360
|
+
):
|
|
361
|
+
"""P4-P5 with customer impact should show both feature team and Zendesk."""
|
|
362
|
+
priority_factory(value=4, default=True)
|
|
363
|
+
customer_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Customers")
|
|
364
|
+
|
|
365
|
+
modal = OpeningUnifiedModal()
|
|
366
|
+
|
|
367
|
+
open_incident_context = {
|
|
368
|
+
"response_type": "normal",
|
|
369
|
+
"impact_form_data": {"customers_impact": customer_impact},
|
|
370
|
+
"details_form_data": {},
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
view = modal.build_modal_fn(open_incident_context=open_incident_context)
|
|
374
|
+
|
|
375
|
+
# Should show both fields
|
|
376
|
+
team_blocks = [
|
|
377
|
+
b
|
|
378
|
+
for b in view.blocks
|
|
379
|
+
if hasattr(b, "block_id") and b.block_id == "suggested_team_routing"
|
|
380
|
+
]
|
|
381
|
+
assert len(team_blocks) == 1
|
|
382
|
+
|
|
383
|
+
zendesk_blocks = [
|
|
384
|
+
b
|
|
385
|
+
for b in view.blocks
|
|
386
|
+
if hasattr(b, "block_id") and b.block_id == "zendesk_ticket_id"
|
|
387
|
+
]
|
|
388
|
+
assert len(zendesk_blocks) == 1
|
|
389
|
+
|
|
390
|
+
def test_handle_modal_fn_preserves_custom_fields_in_validation(
|
|
391
|
+
self, priority_factory, impact_level_factory
|
|
392
|
+
):
|
|
393
|
+
"""Form validation during submission should preserve custom fields based on impact context."""
|
|
394
|
+
# Setup
|
|
395
|
+
priority = priority_factory(value=1, default=True)
|
|
396
|
+
customer_impact = impact_level_factory(value=LevelChoices.HIGH, impact__name="Customers")
|
|
397
|
+
|
|
398
|
+
modal = OpeningUnifiedModal()
|
|
399
|
+
|
|
400
|
+
# Simulate private_metadata as it would be in the modal submission
|
|
401
|
+
private_metadata = {
|
|
402
|
+
"response_type": "critical",
|
|
403
|
+
"impact_form_data": {"customers_impact": str(customer_impact.id)},
|
|
404
|
+
"details_form_data": {"priority": str(priority.id)},
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
# This is what handle_modal_fn now does (with our fix)
|
|
408
|
+
# It passes open_incident_context to the form initialization
|
|
409
|
+
slack_form = modal.get_form_class()(
|
|
410
|
+
data={}, # Empty data for this test - we just want to verify field visibility
|
|
411
|
+
open_incident_context=private_metadata,
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
form = slack_form.form
|
|
415
|
+
|
|
416
|
+
# Verify that zendesk_ticket_id field exists in the form
|
|
417
|
+
# This proves the context was passed correctly and field visibility was configured
|
|
418
|
+
assert "zendesk_ticket_id" in form.fields, "zendesk_ticket_id should be present in form fields when customer impact is selected"
|
|
419
|
+
|
|
420
|
+
# Verify that suggested_team_routing is NOT in the form (critical incident)
|
|
421
|
+
assert "suggested_team_routing" not in form.fields, "suggested_team_routing should not be present for critical incidents"
|