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.
Files changed (29) hide show
  1. firefighter/_version.py +2 -2
  2. firefighter/confluence/models.py +16 -1
  3. firefighter/incidents/management/__init__.py +1 -0
  4. firefighter/incidents/management/commands/__init__.py +1 -0
  5. firefighter/incidents/management/commands/backdate_incident_mitigated.py +94 -0
  6. firefighter/incidents/management/commands/test_postmortem_reminders.py +113 -0
  7. firefighter/incidents/migrations/0030_add_mitigated_at_field.py +22 -0
  8. firefighter/incidents/models/incident.py +43 -8
  9. firefighter/jira_app/service_postmortem.py +13 -0
  10. firefighter/jira_app/signals/postmortem_created.py +108 -46
  11. firefighter/slack/messages/slack_messages.py +162 -0
  12. firefighter/slack/migrations/0009_add_postmortem_reminder_periodic_task.py +60 -0
  13. firefighter/slack/rules.py +22 -0
  14. firefighter/slack/tasks/send_postmortem_reminders.py +127 -0
  15. firefighter/slack/views/modals/close.py +113 -3
  16. firefighter/slack/views/modals/closure_reason.py +39 -15
  17. firefighter/slack/views/modals/update_status.py +4 -4
  18. {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/METADATA +1 -1
  19. {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/RECORD +29 -22
  20. firefighter_tests/test_incidents/test_incident_urls.py +4 -0
  21. firefighter_tests/test_incidents/test_models/test_incident_model.py +109 -1
  22. firefighter_tests/test_incidents/test_views/test_incident_detail_view.py +4 -0
  23. firefighter_tests/test_slack/messages/test_slack_messages.py +4 -0
  24. firefighter_tests/test_slack/views/modals/test_close.py +4 -0
  25. firefighter_tests/test_slack/views/modals/test_closure_reason_modal.py +109 -26
  26. firefighter_tests/test_slack/views/modals/test_update_status.py +45 -51
  27. {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/WHEEL +0 -0
  28. {firefighter_incident-0.0.26.dist-info → firefighter_incident-0.0.27.dist-info}/entry_points.txt +0 -0
  29. {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 can_close is False, (
133
- f"Incident should not be closable without required milestones. Got: {can_close}, reasons: {reasons}"
134
- )
135
- assert any("MISSING_REQUIRED_KEY_EVENTS" in reason[0] for reason in reasons), (
136
- f"Expected MISSING_REQUIRED_KEY_EVENTS in reasons, got: {reasons}"
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 "response_action" in last_call_kwargs, (
167
- f"Expected 'response_action' in ack, got: {last_call_kwargs}"
168
- )
169
- assert last_call_kwargs["response_action"] == "errors", (
170
- f"Expected response_action='errors', got: {last_call_kwargs.get('response_action')}"
171
- )
172
- assert "errors" in last_call_kwargs, (
173
- f"Expected 'errors' in ack, got: {last_call_kwargs}"
174
- )
175
- assert "status" in last_call_kwargs["errors"], (
176
- f"Expected 'status' in errors, got: {last_call_kwargs.get('errors')}"
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 "Cannot close this incident" in error_msg, (
181
- f"Expected closure error, got: {error_msg}"
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 can_close is False, (
237
- "Incident should not be closable without required milestones"
238
- )
239
- assert any("MISSING_REQUIRED_KEY_EVENTS" in reason[0] for reason in reasons), (
240
- f"Expected MISSING_REQUIRED_KEY_EVENTS in reasons, got: {reasons}"
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 "response_action" in last_call_kwargs, (
268
- f"Expected 'response_action' in ack call, got: {last_call_kwargs}"
269
- )
270
- assert last_call_kwargs["response_action"] == "errors", (
271
- f"Expected response_action='errors', got: {last_call_kwargs.get('response_action')}"
272
- )
273
- assert "errors" in last_call_kwargs, (
274
- f"Expected 'errors' in ack call, got: {last_call_kwargs}"
275
- )
276
- assert "status" in last_call_kwargs["errors"], (
277
- f"Expected 'status' in errors, got: {last_call_kwargs.get('errors')}"
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 "Cannot close this incident" in error_msg, (
281
- f"Expected closure error message, got: {error_msg}"
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 first_call_kwargs == {} or "errors" not in first_call_kwargs, (
469
- f"Should allow updating priority without changing status. Got errors: {first_call_kwargs.get('errors')}"
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()