-
Notifications
You must be signed in to change notification settings - Fork 31
fix: multiple attendances per capability #815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5322baa
dc7bca3
3edd493
2a5f63d
27b67c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| RecurringShiftWatch, | ||
| ShiftAttendance, | ||
| ShiftSlot, | ||
| ShiftUserCapability, | ||
| StaffingStatusChoices, | ||
| get_staffingstatus_choices, | ||
| ) | ||
|
|
@@ -30,25 +31,33 @@ def create_shift_with_attendance(num_attendances): | |
| slot = ShiftSlot.objects.create(shift=shift, name="cheese-making") | ||
| user = TapirUserFactory.create() | ||
| ShiftAttendance.objects.create(user=user, slot=slot) | ||
| slots.append(slot.pk) | ||
| slots.append(slot) | ||
| return shift, slots | ||
|
|
||
|
|
||
| def create_shift_watch( | ||
| user, shift, slots, last_staffing_status=None, staffing_status=None | ||
| user, | ||
| shift, | ||
| last_valid_slot_ids, | ||
| last_staffing_status=None, | ||
| staffing_status=None, | ||
| watched_capabilities=None, | ||
| ): | ||
| if last_staffing_status is None: | ||
| last_staffing_status = ShiftWatchCreator.get_initial_staffing_status_for_shift( | ||
| shift=shift | ||
| ) | ||
| if staffing_status is None: | ||
| staffing_status = [event.value for event in get_staffingstatus_choices()] | ||
| staffing_status = [] | ||
| if watched_capabilities is None: | ||
| watched_capabilities = [] | ||
| return ShiftWatchFactory( | ||
| user=user, | ||
| shift=shift, | ||
| last_valid_slot_ids=slots, | ||
| last_valid_slot_ids=[slot.pk for slot in last_valid_slot_ids], | ||
| staffing_status=staffing_status, | ||
| last_staffing_status=last_staffing_status, | ||
| watched_capabilities=watched_capabilities, | ||
| ) | ||
|
|
||
|
|
||
|
|
@@ -62,15 +71,16 @@ def setUp(self): | |
| self.NUM_REQUIRED_ATTENDANCE | ||
| ) | ||
|
|
||
| def unregister_first_slot(self): | ||
| first_slot = self.slots[0] | ||
| first_shift_attendance = ShiftAttendance.objects.filter(slot=first_slot).first() | ||
| def unregister_slot(self, slot: ShiftSlot | None = None): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| if slot is None: | ||
| slot = self.slots[0] | ||
| first_shift_attendance = ShiftAttendance.objects.filter(slot=slot).first() | ||
| first_shift_attendance.state = ShiftAttendance.State.LOOKING_FOR_STAND_IN | ||
| first_shift_attendance.save() | ||
|
|
||
| def assert_email_sent(self, expected_status_choice): | ||
| def assert_email_sent(self, expected_status_choice: str): | ||
| self.assertEqual(len(mail.outbox), 1) | ||
| self.assertIn(str(expected_status_choice.label), mail.outbox[0].body) | ||
| self.assertIn(str(expected_status_choice), mail.outbox[0].body) | ||
| self.assertEmailOfClass_GotSentTo( | ||
| ShiftWatchEmailBuilder, self.USER_EMAIL_ADDRESS, mail.outbox[0] | ||
| ) | ||
|
|
@@ -79,21 +89,22 @@ def test_handle_watchedShiftIsUnderstaffed_correctNotificationIsSent(self): | |
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| slots=self.slots, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=[StaffingStatusChoices.UNDERSTAFFED], | ||
| ) | ||
| Command().handle() | ||
| self.assertEqual(0, len(mail.outbox)) | ||
|
|
||
| self.unregister_first_slot() | ||
| self.unregister_slot() | ||
| Command().handle() | ||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED) | ||
| self.assertEqual(1, len(mail.outbox)) | ||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED.label) | ||
|
|
||
| def test_handle_watchedShiftIsAlright_noNotificationIsSent(self): | ||
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| slots=self.slots, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=list(get_staffingstatus_choices()), | ||
| ) | ||
| Command().handle() | ||
|
|
@@ -110,10 +121,11 @@ def test_handle_initialWatchUnderstaffedShift_noInitialMailIsSent(self): | |
| create_shift_watch( | ||
| user=user, | ||
| shift=shift_understaffed, | ||
| slots=slots, | ||
| last_valid_slot_ids=slots, | ||
| last_staffing_status=ShiftWatchCreator.get_initial_staffing_status_for_shift( | ||
| shift=shift_understaffed | ||
| ), | ||
| staffing_status=list(get_staffingstatus_choices()), | ||
| ) | ||
|
|
||
| Command().handle() | ||
|
|
@@ -126,24 +138,24 @@ def test_handle_initialWatchUnderstaffedShift_noInitialMailIsSent(self): | |
|
|
||
| Command().handle() | ||
|
|
||
| self.assert_email_sent(StaffingStatusChoices.ALL_CLEAR) | ||
| self.assert_email_sent(StaffingStatusChoices.ALL_CLEAR.label) | ||
|
|
||
| def test_handle_triggeredMultipleTimes_onlyOneMailIsSent(self): | ||
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| slots=self.slots, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=[StaffingStatusChoices.UNDERSTAFFED], | ||
| ) | ||
|
|
||
| self.unregister_first_slot() | ||
| self.unregister_slot() | ||
|
|
||
| self.assertEqual(len(mail.outbox), 0) | ||
|
|
||
| for _ in range(3): | ||
| Command().handle() | ||
|
|
||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED) | ||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED.label) | ||
|
|
||
| def test_handle_watchedShiftIsCurrentlyRunning_correctNotificationIsSent(self): | ||
| self.shift_ok_first.start_time = timezone.now() - datetime.timedelta(hours=4) | ||
|
|
@@ -153,14 +165,14 @@ def test_handle_watchedShiftIsCurrentlyRunning_correctNotificationIsSent(self): | |
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| slots=self.slots, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=[StaffingStatusChoices.UNDERSTAFFED], | ||
| ) | ||
|
|
||
| self.unregister_first_slot() | ||
| self.unregister_slot() | ||
|
|
||
| Command().handle() | ||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED) | ||
| self.assert_email_sent(StaffingStatusChoices.UNDERSTAFFED.label) | ||
|
|
||
| def test_handle_shiftInThePast_noNotification(self): | ||
|
|
||
|
|
@@ -173,10 +185,11 @@ def test_handle_shiftInThePast_noNotification(self): | |
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| slots=self.slots, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=list(get_staffingstatus_choices()), | ||
| ) | ||
|
|
||
| self.unregister_first_slot() | ||
| self.unregister_slot() | ||
|
|
||
| Command().handle() | ||
|
|
||
|
|
@@ -196,3 +209,45 @@ def test_handle_recurring_noInitialMailIsSent(self): | |
| Command().handle() | ||
|
|
||
| self.assertEqual(len(mail.outbox), 0) | ||
|
|
||
| def test_handle_registerAnotherUserToSameCapability_MailSent(self): | ||
| for slot in self.slots: | ||
| slot.required_capabilities = [ShiftUserCapability.SHIFT_COORDINATOR] | ||
| slot.save() | ||
|
|
||
| self.shift_watch = create_shift_watch( | ||
| user=self.user, | ||
| shift=self.shift_ok_first, | ||
| last_valid_slot_ids=self.slots, | ||
| staffing_status=[], | ||
| watched_capabilities=[ShiftUserCapability.SHIFT_COORDINATOR], | ||
| ) | ||
|
|
||
| slot_to_register = ShiftSlot.objects.create( | ||
| shift=self.shift_ok_first, name="cheese-making" | ||
| ) | ||
| slot_to_register.required_capabilities = [ShiftUserCapability.SHIFT_COORDINATOR] | ||
| self.slots.append(slot_to_register) | ||
|
|
||
| # assert first and second shift have attendance and third shift has no attendance | ||
| self.assertTrue( | ||
| ShiftAttendance.objects.filter(slot__in=self.slots[:2]).exists() | ||
| ) | ||
|
Comment on lines
+233
to
+235
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This only asserts that at least one of the slots has an attendance, we should check the count to make sure there is two, and probably filter by state too. |
||
| self.assertFalse(ShiftAttendance.objects.filter(slot=self.slots[2]).exists()) | ||
|
|
||
| Command().handle() | ||
| self.assertEqual(0, len(mail.outbox)) | ||
|
|
||
| # register user to third slot | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does that comment really explain anything that is not clear on the following line? |
||
| ShiftAttendance.objects.create( | ||
| user=TapirUserFactory.create(), slot=slot_to_register | ||
| ) | ||
| slot_to_register.save() | ||
|
|
||
| self.assertEqual( | ||
| slot_to_register.required_capabilities, | ||
| [ShiftUserCapability.SHIFT_COORDINATOR], | ||
| ) | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We set that value in the test just a few lines above, is this assert necessary? |
||
| Command().handle() | ||
| self.assert_email_sent("registered") | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think those are slots, not ids?