firefighter-incident 0.0.26__py3-none-any.whl → 0.0.27__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/confluence/models.py +16 -1
- firefighter/incidents/management/__init__.py +1 -0
- firefighter/incidents/management/commands/__init__.py +1 -0
- firefighter/incidents/management/commands/backdate_incident_mitigated.py +94 -0
- firefighter/incidents/management/commands/test_postmortem_reminders.py +113 -0
- firefighter/incidents/migrations/0030_add_mitigated_at_field.py +22 -0
- firefighter/incidents/models/incident.py +43 -8
- firefighter/jira_app/service_postmortem.py +13 -0
- firefighter/jira_app/signals/postmortem_created.py +108 -46
- firefighter/slack/messages/slack_messages.py +162 -0
- firefighter/slack/migrations/0009_add_postmortem_reminder_periodic_task.py +60 -0
- firefighter/slack/rules.py +22 -0
- firefighter/slack/tasks/send_postmortem_reminders.py +127 -0
- firefighter/slack/views/modals/close.py +113 -3
- firefighter/slack/views/modals/closure_reason.py +39 -15
- firefighter/slack/views/modals/update_status.py +4 -4
- {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/METADATA +1 -1
- {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/RECORD +29 -22
- firefighter_tests/test_incidents/test_incident_urls.py +4 -0
- firefighter_tests/test_incidents/test_models/test_incident_model.py +109 -1
- firefighter_tests/test_incidents/test_views/test_incident_detail_view.py +4 -0
- firefighter_tests/test_slack/messages/test_slack_messages.py +4 -0
- firefighter_tests/test_slack/views/modals/test_close.py +4 -0
- firefighter_tests/test_slack/views/modals/test_closure_reason_modal.py +109 -26
- firefighter_tests/test_slack/views/modals/test_update_status.py +45 -51
- {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/WHEEL +0 -0
- {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/entry_points.txt +0 -0
- {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/licenses/LICENSE +0 -0
|
@@ -129,12 +129,12 @@ class TestUpdateStatusModal:
|
|
|
129
129
|
|
|
130
130
|
# Verify that can_be_closed returns False due to missing milestones (real check, no mock)
|
|
131
131
|
can_close, reasons = incident.can_be_closed
|
|
132
|
-
assert
|
|
133
|
-
|
|
134
|
-
)
|
|
135
|
-
assert any(
|
|
136
|
-
|
|
137
|
-
)
|
|
132
|
+
assert (
|
|
133
|
+
can_close is False
|
|
134
|
+
), f"Incident should not be closable without required milestones. Got: {can_close}, reasons: {reasons}"
|
|
135
|
+
assert any(
|
|
136
|
+
"MISSING_REQUIRED_KEY_EVENTS" in reason[0] for reason in reasons
|
|
137
|
+
), f"Expected MISSING_REQUIRED_KEY_EVENTS in reasons, got: {reasons}"
|
|
138
138
|
|
|
139
139
|
modal = UpdateStatusModal()
|
|
140
140
|
trigger_incident_workflow = mocker.patch.object(
|
|
@@ -163,26 +163,23 @@ class TestUpdateStatusModal:
|
|
|
163
163
|
assert ack.called, "ack should have been called"
|
|
164
164
|
# Check the last call (the error response)
|
|
165
165
|
last_call_kwargs = ack.call_args.kwargs
|
|
166
|
-
assert
|
|
167
|
-
|
|
168
|
-
)
|
|
169
|
-
assert
|
|
170
|
-
|
|
171
|
-
)
|
|
172
|
-
assert
|
|
173
|
-
|
|
174
|
-
)
|
|
175
|
-
assert
|
|
176
|
-
|
|
177
|
-
)
|
|
166
|
+
assert (
|
|
167
|
+
"response_action" in last_call_kwargs
|
|
168
|
+
), f"Expected 'response_action' in ack, got: {last_call_kwargs}"
|
|
169
|
+
assert (
|
|
170
|
+
last_call_kwargs["response_action"] == "errors"
|
|
171
|
+
), f"Expected response_action='errors', got: {last_call_kwargs.get('response_action')}"
|
|
172
|
+
assert (
|
|
173
|
+
"errors" in last_call_kwargs
|
|
174
|
+
), f"Expected 'errors' in ack, got: {last_call_kwargs}"
|
|
175
|
+
assert (
|
|
176
|
+
"status" in last_call_kwargs["errors"]
|
|
177
|
+
), f"Expected 'status' in errors, got: {last_call_kwargs.get('errors')}"
|
|
178
178
|
# Check that the error message mentions the missing key events
|
|
179
179
|
error_msg = last_call_kwargs["errors"]["status"]
|
|
180
|
-
assert
|
|
181
|
-
|
|
182
|
-
)
|
|
183
|
-
assert "key events" in error_msg.lower(), (
|
|
184
|
-
f"Expected 'key events' in error, got: {error_msg}"
|
|
185
|
-
)
|
|
180
|
+
assert (
|
|
181
|
+
"missing key events" in error_msg.lower()
|
|
182
|
+
), f"Expected missing key events error, got: {error_msg}"
|
|
186
183
|
|
|
187
184
|
# Verify that incident update was NOT triggered
|
|
188
185
|
trigger_incident_workflow.assert_not_called()
|
|
@@ -233,12 +230,12 @@ class TestUpdateStatusModal:
|
|
|
233
230
|
|
|
234
231
|
# Verify that can_be_closed returns False due to missing milestones
|
|
235
232
|
can_close, reasons = incident.can_be_closed
|
|
236
|
-
assert
|
|
237
|
-
|
|
238
|
-
)
|
|
239
|
-
assert any(
|
|
240
|
-
|
|
241
|
-
)
|
|
233
|
+
assert (
|
|
234
|
+
can_close is False
|
|
235
|
+
), "Incident should not be closable without required milestones"
|
|
236
|
+
assert any(
|
|
237
|
+
"MISSING_REQUIRED_KEY_EVENTS" in reason[0] for reason in reasons
|
|
238
|
+
), f"Expected MISSING_REQUIRED_KEY_EVENTS in reasons, got: {reasons}"
|
|
242
239
|
|
|
243
240
|
modal = UpdateStatusModal()
|
|
244
241
|
trigger_incident_workflow = mocker.patch.object(
|
|
@@ -264,25 +261,22 @@ class TestUpdateStatusModal:
|
|
|
264
261
|
# Assert that ack was called with errors
|
|
265
262
|
assert ack.called, "ack should have been called"
|
|
266
263
|
last_call_kwargs = ack.call_args.kwargs
|
|
267
|
-
assert
|
|
268
|
-
|
|
269
|
-
)
|
|
270
|
-
assert
|
|
271
|
-
|
|
272
|
-
)
|
|
273
|
-
assert
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
assert
|
|
277
|
-
|
|
278
|
-
)
|
|
264
|
+
assert (
|
|
265
|
+
"response_action" in last_call_kwargs
|
|
266
|
+
), f"Expected 'response_action' in ack call, got: {last_call_kwargs}"
|
|
267
|
+
assert (
|
|
268
|
+
last_call_kwargs["response_action"] == "errors"
|
|
269
|
+
), f"Expected response_action='errors', got: {last_call_kwargs.get('response_action')}"
|
|
270
|
+
assert (
|
|
271
|
+
"errors" in last_call_kwargs
|
|
272
|
+
), f"Expected 'errors' in ack call, got: {last_call_kwargs}"
|
|
273
|
+
assert (
|
|
274
|
+
"status" in last_call_kwargs["errors"]
|
|
275
|
+
), f"Expected 'status' in errors, got: {last_call_kwargs.get('errors')}"
|
|
279
276
|
error_msg = last_call_kwargs["errors"]["status"]
|
|
280
|
-
assert
|
|
281
|
-
|
|
282
|
-
)
|
|
283
|
-
assert "key events" in error_msg.lower(), (
|
|
284
|
-
f"Expected 'key events' in error message, got: {error_msg}"
|
|
285
|
-
)
|
|
277
|
+
assert (
|
|
278
|
+
"missing key events" in error_msg.lower()
|
|
279
|
+
), f"Expected missing key events error message, got: {error_msg}"
|
|
286
280
|
|
|
287
281
|
# Verify that incident update was NOT triggered
|
|
288
282
|
trigger_incident_workflow.assert_not_called()
|
|
@@ -465,9 +459,9 @@ class TestUpdateStatusModal:
|
|
|
465
459
|
first_call_kwargs = (
|
|
466
460
|
ack.call_args_list[0][1] if ack.call_args_list else ack.call_args.kwargs
|
|
467
461
|
)
|
|
468
|
-
assert
|
|
469
|
-
|
|
470
|
-
)
|
|
462
|
+
assert (
|
|
463
|
+
first_call_kwargs == {} or "errors" not in first_call_kwargs
|
|
464
|
+
), f"Should allow updating priority without changing status. Got errors: {first_call_kwargs.get('errors')}"
|
|
471
465
|
|
|
472
466
|
# Verify that incident update WAS triggered (priority changed)
|
|
473
467
|
trigger_incident_workflow.assert_called_once()
|
|
File without changes
|
{firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|