def test_opens_after_closing(self): trip = factories.TripFactory.build( signups_open_at=localize(datetime(2020, 1, 15, 12, 0)), signups_close_at=localize(datetime(2020, 1, 15, 2, 0)), trip_date=date(2020, 1, 20), ) with self.assertRaises(ValidationError) as cm: trip.clean() self.assertEqual(cm.exception.message, 'Trips cannot open after they close.')
def _create_trip(**kwargs): """Create a trip with signups opening one week before, closing night before.""" trip_date = kwargs.pop('trip_date') open_date = trip_date - timedelta(days=7) day_before = trip_date - timedelta(days=1) return factories.TripFactory.create( trip_date=trip_date, signups_open_at=localize(datetime.combine(open_date, time(12, 0))), signups_close_at=localize( datetime.combine(day_before, time(21, 30))), **kwargs, )
def _make_trip(**kwargs): """Create an upcoming FCFS trip.""" trip_kwargs = { 'program': enums.Program.CLIMBING.value, 'name': "Some Cool Upcoming Trip", 'trip_date': date(2025, 12, 14), 'signups_open_at': date_utils.localize(datetime(2025, 12, 10, 12, 0)), 'signups_close_at': date_utils.localize(datetime(2025, 12, 13, 21, 30)), 'algorithm': 'fcfs', **kwargs, } return factories.TripFactory.create(**trip_kwargs)
def test_success(self): """Create a bunch of data about the participant, ensure that dumping it works.""" participant = factories.ParticipantFactory.create() participant.discounts.add(factories.DiscountFactory.create()) participant.car = factories.CarFactory.create() participant.save() factories.LeaderRatingFactory.create(participant=participant) factories.LeaderRatingFactory.create(creator=participant) factories.LotteryInfoFactory.create(participant=participant) factories.TripFactory.create(creator=participant, name="First trip") factories.TripFactory.create(creator=participant, name="Second trip") factories.FeedbackFactory.create(leader=participant) factories.FeedbackFactory.create(participant=participant) factories.SignUpFactory.create(on_trip=True, participant=participant) factories.SignUpFactory.create(on_trip=False, participant=participant) factories.SignUpFactory.create(on_trip=False, participant=participant) with freeze_time("Thu, 5 Jan 2017 18:35:40 EST"): factories.LectureAttendanceFactory.create(year=2017, participant=participant) with freeze_time("Thu, 10 Jan 2019 18:45:20 EST"): factories.LectureAttendanceFactory.create(year=2019, participant=participant) data = DataDump(participant.pk) results = data.all_data self.assertTrue(isinstance(results, OrderedDict)) self.assertEqual( results['winter_school_lecture_attendance'], [ { 'year': 2017, 'time_created': localize(datetime(2017, 1, 5, 18, 35, 40)), }, { 'year': 2019, 'time_created': localize(datetime(2019, 1, 10, 18, 45, 20)), }, ], ) # (Won't inspect the results of every value, since factory defaults may change) # Just ensure that they're actually filled. self.assertTrue(results['feedback']['received']) self.assertTrue(results['feedback']['given']) self.assertTrue(results['lottery_info']) self.assertTrue(results['leader_ratings']) self.assertTrue(results['signups'])
def test_default_signups_close_early_week(self): """Early week, we default to Wednesday morning.""" form = forms.TripForm() self.assertEqual( form.fields['signups_close_at'].initial(), date_utils.localize(datetime(2019, 10, 16, 9, 0, 0)), )
def test_default_signups_close_late_week(self): """On a Wednesday, we just default to midnight on the night before""" form = forms.TripForm() self.assertEqual( form.fields['signups_close_at'].initial(), date_utils.localize(datetime(2019, 10, 18, 23, 59, 59)), )
def _make_trip(**overrides): trip_args = dict( name="Some Cool Upcoming Trip", program=enums.Program.WINTER_NON_IAP.value, trip_type=enums.TripType.HIKING.value, level='C', trip_date=date(2025, 12, 14), difficulty_rating='Advanced', prereqs='Comfort with rough terrain', signups_open_at=localize(datetime(2025, 12, 10, 12, 0)), signups_close_at=localize(datetime(2025, 12, 13, 21, 30)), algorithm='fcfs', ) trip_args.update(overrides) trip = factories.TripFactory.create(**trip_args) return annotated_for_trip_list( models.Trip.objects.filter(pk=trip.pk)).get()
def _upcoming_trip(**kwargs): trip_kwargs = { 'program': enums.Program.CLIMBING.value, 'trip_date': date(2019, 1, 19), 'signups_open_at': date_utils.localize(datetime(2019, 1, 14, 10, 0, 0)), **kwargs, } return factories.TripFactory.create(**trip_kwargs)
def test_signups_closed_already(self): trip = factories.TripFactory.build( signups_close_at=localize(datetime(2020, 1, 15, 12, 0)), trip_date=date(2020, 1, 18), ) self.assertIsNone(trip.time_created) self.assertTrue(trip.signups_closed) with self.assertRaises(ValidationError) as cm: trip.clean() self.assertEqual(cm.exception.message, "Signups can't be closed already!")
def test_closed_trip(self): """Nobody may sign up after signups close.""" trip = self._make_trip(signups_close_at=date_utils.localize( datetime(2025, 12, 11, 11, 11))) self.assertTrue(trip.signups_closed) soup = self._render(factories.ParticipantFactory(), trip) self.assertEqual( soup.find(class_='alert-info').get_text(' ', strip=True), 'Signups for this trip are closed.', ) self.assertIsNone(soup.find('form'))
def test_not_yet_open(self): trip = self._make_trip( signups_open_at=date_utils.localize(datetime(2025, 12, 12, 13, 45)), signups_close_at=date_utils.localize(datetime( 2025, 12, 13, 23, 59)), allow_leader_signups=True, activity=models.LeaderRating.BIKING, program=enums.Program.BIKING.value, ) self.assertTrue(trip.signups_not_yet_open) # The participant may attend this trip, signups just aren't open. participant = factories.ParticipantFactory.create() self.assertFalse(any(participant.reasons_cannot_attend(trip))) soup = self._render(participant, trip) self.assertEqual( soup.find(class_='alert-info').get_text(' ', strip=True), 'Signups for this trip are not yet open.', ) self.assertIsNone(soup.find('form')) # Make that same participant into a leader! rating = factories.LeaderRatingFactory.create( participant=participant, activity=models.LeaderRating.BIKING) participant.leaderrating_set.add(rating) leader_soup = self._render(participant, trip) self.assertEqual( leader_soup.find(class_='alert-info').get_text(' ', strip=True), 'Signups for this trip are not yet open.', ) self.assertTrue(participant.is_leader) # The trip is upcoming, allows leader signups, and the participant can lead biking trips! self.assertEqual( leader_soup.find(class_='alert-success').get_text(' ', strip=True), 'However, you can sign up early as a leader!', ) self.assertTrue(leader_soup.find('form'))
def test_not_updated_since_affiliation_overhaul(self): """ Any participant with affiliation predating our new categories should re-submit! """ # This is right before the time when we released new categories! before_cutoff = date_utils.localize( datetime.datetime(2018, 10, 27, 3, 15)) participant = factories.ParticipantFactory.create() # Override the default "now" timestamp, to make participant's last profile update look old participant.profile_last_updated = before_cutoff participant.save() self.assertCountEqual( participant.problems_with_profile, [ enums.ProfileProblem.STALE_INFO, enums.ProfileProblem.LEGACY_AFFILIATION ], )
def test_trip_not_open(self): """Cannot sign up for a trip that's not open!""" not_yet_open_trip = factories.TripFactory.create( program=enums.Program.CLIMBING.value, signups_open_at=date_utils.localize(datetime( 2019, 3, 20, 10, 0, 0)), ) # The participant has an active membership that will last at least until the trip par = self._active_member() self.assertFalse(par.should_renew_for(not_yet_open_trip)) # However, because the trip is in the future, they cannot sign up! self.client.force_login(par.user) resp = self._signup(not_yet_open_trip) form = resp.context['form'] self.assertEqual(form.errors, {'__all__': ["Signups aren't open!"]}) # Participant was not placed on the trip. self.assertFalse( not_yet_open_trip.signup_set.filter(participant=par).exists())
def _assert_fcfs_at_noon(self, trip): self.assertEqual(trip.algorithm, 'fcfs') self.assertEqual( trip.signups_open_at, date_utils.localize(datetime(2020, 1, 15, 12)) )
def setUp(self): self.y2k = datetime(2000, 1, 1) test_datetimes = [self.y2k + timedelta(days=i) for i in range(15)] self.test_datetimes = [ date_utils.localize(dt) for dt in test_datetimes ]