def _lecture_info(self, participant, user_viewing: bool) -> Dict[str, bool]: """Describe the participant's lecture attendance, if applicable.""" can_set_attendance = self.can_set_attendance(participant) # There are only *two* times of year where it's important to show "yes, you attended" # 1. The enrollment period where participants can record attendance (2nd lecture) # 2. The first week of WS, after lectures but before weekend trips # (this is when participants may not have recorded attendance correctly) # In later weeks, we'll enforce lecture attendance as part of trip signup. show_attendance = date_utils.is_currently_iap() and ( can_set_attendance or date_utils.ws_lectures_complete() ) if show_attendance: attended_lectures = participant.attended_lectures(date_utils.ws_year()) # We don't need to tell participants "You attended lectures!" later in WS. # This is because signup rules enforce lecture attendance *after* week 1. if user_viewing and models.Trip.objects.filter( program=enums.Program.WINTER_SCHOOL.value, trip_date__gte=date_utils.jan_1(), trip_date__lt=date_utils.local_date(), ): show_attendance = False else: # Skip unnecessary db queries attended_lectures = False # Maybe they actually did, but we're not showing. return { 'can_set_attendance': can_set_attendance, 'show_attendance': show_attendance, 'attended_lectures': attended_lectures, }
def test_no_trips_yet(self): """When there are no trips this Winter School, lectures aren't complete. (The first trips are posted on Thursday of the first lecture week - without these trips, we can reasonably infer that lectures are still ongoing) """ # Create trips from previous Winter School self._create_ws_trip(date(2017, 1, 15)) self._create_ws_trip(date(2017, 1, 28)) self.assertFalse(date_utils.ws_lectures_complete())
def get_context_data(self, **kwargs): participant = self.object = self.get_object() user_viewing = self.request.participant == participant context = super().get_context_data(**kwargs) can_set_attendance = self.can_set_attendance(participant) context['can_set_attendance'] = can_set_attendance context['show_attendance'] = date_utils.is_currently_iap() and ( date_utils.ws_lectures_complete() or can_set_attendance) if can_set_attendance: context[ 'attended_lectures'] = models.LectureAttendance.objects.filter( participant=participant, year=date_utils.ws_year()).exists() context['user_viewing'] = user_viewing if user_viewing: user = self.request.user else: user = participant.user context['par_user'] = user context['trips'] = trips = self.get_trips() context['stats'] = self.get_stats(trips) self.include_pairing(context) e_info = participant.emergency_info e_contact = e_info.emergency_contact context['emergency_info_form'] = forms.EmergencyInfoForm( instance=e_info) context['emergency_contact_form'] = forms.EmergencyContactForm( instance=e_contact) context['participant'] = participant if not user_viewing: feedback = participant.feedback_set.select_related( 'trip', 'leader') feedback = feedback.prefetch_related('leader__leaderrating_set') context['all_feedback'] = feedback context['ratings'] = participant.ratings(must_be_active=True) if participant.car: context['car_form'] = forms.CarForm(instance=participant.car) context['wimp'] = self.wimp return context
def test_future_trips(self): """When there are no past trips, but there are upcoming trips.""" self._create_ws_trip(date(2018, 1, 5)) self._create_ws_trip(date(2018, 1, 6)) # Test calling this function at various times of day expectations = { # There are future trips, but it's not yet Thursday night # (Explanation: Some leaders got ansty and created trips early) 'Wed 2018-01-03 12:00 EST': False, # It's evening, but lectures have just started 'Thu 2018-01-04 19:00 EST': False, # Leaders created trips, and it's after 9 pm, so we infer lectures are over 'Thu 2018-01-04 21:15 EST': True, # It's Friday, with upcoming trips. Lectures are definitely over. 'Fri 2018-01-05 10:23 EST': True, } for time_string, lectures_over in expectations.items(): with freeze_time(time_string): self.assertEqual(date_utils.ws_lectures_complete(), lectures_over)
def test_missed_lectures(self): # Presence of an existing WS trip is the clue that WS has started. factories.TripFactory.create(program=enums.Program.WINTER_SCHOOL.value, trip_date=date(2019, 1, 12)) self.assertTrue(date_utils.ws_lectures_complete()) ws_trip = self._upcoming_trip( program=enums.Program.WINTER_SCHOOL.value) # This participant is not a member! (that's important -- it shapes error messages) par = factories.ParticipantFactory.create(membership=None) self.assertFalse(par.attended_lectures(2019)) self.assertTrue(par.missed_lectures_for(ws_trip)) self.client.force_login(par.user) resp = self._signup(ws_trip) form = resp.context['form'] # Normally, we would prompt the participant to pay dues & sign a waiver. # However, since they might pay dues, then be frustrated that they cannot attend, we don't. self.assertEqual( form.errors, {'__all__': ["Must have attended mandatory safety lectures"]})
def test_past_trips(self): """When trips have already completed, lectures are definitely over.""" self._create_ws_trip(date(2017, 1, 12)) self.assertTrue(date_utils.ws_lectures_complete())