def setUp(self): self.now = timezone.now() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.series = PickupDateSeriesFactory(max_collectors=3, place=self.place)
def setUp(self): super().setUp() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) # Create far in the future to generate no pickup dates # They would lead to interfering websocket messages self.series = PickupDateSeriesFactory(place=self.place, start_date=timezone.now() + relativedelta(months=2))
def test_delete(self): now = timezone.now() two_weeks_ago = now - relativedelta(weeks=2) with freeze_time(two_weeks_ago, tick=True): series = PickupDateSeriesFactory(place=self.place, start_date=two_weeks_ago) pickup_dates = series.pickup_dates.all() past_date_count = pickup_dates.filter(date__startswith__lt=now).count() self.assertGreater(pickup_dates.count(), 2) series.delete() upcoming_pickups = PickupDate.objects.filter(date__startswith__gte=now, is_disabled=False) self.assertEqual(upcoming_pickups.count(), 0, upcoming_pickups) self.assertEqual(PickupDate.objects.filter(date__startswith__lt=now).count(), past_date_count)
def setUp(self): self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.pickup = PickupDateFactory(place=self.place) self.pickup_url = '/api/pickup-dates/{}/'.format(self.pickup.id) self.series = PickupDateSeriesFactory(place=self.place) self.series_url = '/api/pickup-date-series/{}/'.format(self.series.id)
def setUp(self): self.now = timezone.now() self.url = '/api/places/' self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.place_url = self.url + str(self.place.id) + '/' self.series = PickupDateSeriesFactory(max_collectors=3, place=self.place)
def setUp(self): self.url = '/api/pickup-date-series/' self.series = PickupDateSeriesFactory() self.series_url = '/api/pickup-date-series/{}/'.format(self.series.id) self.non_member = UserFactory() self.series_data = { 'place': self.series.place.id, 'rule': 'FREQ=WEEKLY', 'start_date': timezone.now() }
def test_create_all_pickup_dates_inactive_places(self): self.place.status = PlaceStatus.ARCHIVED.value self.place.save() start_date = self.place.group.timezone.localize(datetime.now().replace(2017, 3, 18, 15, 0, 0, 0)) PickupDateSeriesFactory(place=self.place, start_date=start_date) PickupDate.objects.all().delete() PickupDateSeries.objects.update_pickups() self.assertEqual(PickupDate.objects.count(), 0)
def setUp(self): self.url = '/api/pickup-dates/' # pickup date for group with one member and one place self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.pickup = PickupDateFactory(place=self.place) # and another place + group + pick-update self.group2 = GroupFactory(members=[self.member]) self.place2 = PlaceFactory(group=self.group2) self.pickup2 = PickupDateFactory(place=self.place2) # a pickup date series self.series = PickupDateSeriesFactory(place=self.place) # another pickup date series self.series2 = PickupDateSeriesFactory(place=self.place)
def test_daylight_saving_time_to_winter(self): start_date = self.place.group.timezone.localize(datetime.now().replace(2016, 10, 22, 15, 0, 0, 0)) before_dst_switch = timezone.now().replace(2016, 10, 22, 4, 40, 13) with freeze_time(before_dst_switch, tick=True): series = PickupDateSeriesFactory(place=self.place, start_date=start_date) expected_dates = [] for month, day in [(10, 22), (10, 29), (11, 5), (11, 12)]: expected_dates.append(self.place.group.timezone.localize(datetime(2016, month, day, 15, 0))) for actual_date, expected_date in zip(PickupDate.objects.filter(series=series), expected_dates): self.assertEqual(actual_date.date.start, expected_date)
class PickupDateSeriesReceiverTests(WSTestCase): def setUp(self): super().setUp() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) # Create far in the future to generate no pickup dates # They would lead to interfering websocket messages self.series = PickupDateSeriesFactory(place=self.place, start_date=timezone.now() + relativedelta(months=2)) def test_receive_series_changes(self): self.client = self.connect_as(self.member) date = faker.future_datetime( end_date='+30d', tzinfo=timezone.utc) + relativedelta(months=2) self.series.start_date = date self.series.save() response = self.client.messages_by_topic.get('pickups:series')[0] self.assertEqual(parse(response['payload']['start_date']), date) self.assertEqual(len(self.client.messages), 1) def test_receive_series_delete(self): self.client = self.connect_as(self.member) id = self.series.id self.series.delete() response = self.client.messages_by_topic.get( 'pickups:series_deleted')[0] self.assertEqual(response['payload']['id'], id) self.assertEqual(len(self.client.messages), 1)
class TestPickupDateSeriesChangeAPI(APITestCase, ExtractPaginationMixin): """ This is an integration test for the pickup-date-series API with pre-created series """ def setUp(self): self.now = timezone.now() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.series = PickupDateSeriesFactory(max_collectors=3, place=self.place) def test_change_max_collectors_for_series(self): "should change all future instances (except for individually changed ones), but not past ones" url = '/api/pickup-date-series/{}/'.format(self.series.id) self.client.force_login(user=self.member) response = self.client.patch(url, {'max_collectors': 99}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['max_collectors'], 99) url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) for _ in response.data: self.assertEqual(_['max_collectors'], 99) def test_change_series_activates_group(self): self.group.status = GroupStatus.INACTIVE.value self.group.save() url = '/api/pickup-date-series/{}/'.format(self.series.id) self.client.force_login(user=self.member) self.client.patch(url, {'max_collectors': 99}) self.group.refresh_from_db() self.assertEqual(self.group.status, GroupStatus.ACTIVE.value) def test_change_start_time(self): self.client.force_login(user=self.member) # get original times url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) original_dates = [parse(_['date'][0]) for _ in response.data] # change times url = '/api/pickup-date-series/{}/'.format(self.series.id) new_startdate = shift_date_in_local_time( self.series.start_date, relativedelta(hours=2, minutes=20), self.group.timezone) response = self.client.patch(url, {'start_date': new_startdate.isoformat()}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(parse(response.data['start_date']), new_startdate) # compare resulting pickups url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) for response_pickup, old_date in zip(response.data, original_dates): self.assertEqual( parse(response_pickup['date'][0]), shift_date_in_local_time(old_date, relativedelta(hours=2, minutes=20), self.group.timezone)) def test_change_start_date_to_future(self): self.client.force_login(user=self.member) # get original dates url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) original_dates = [parse(_['date'][0]) for _ in response.data] # change dates url = '/api/pickup-date-series/{}/'.format(self.series.id) new_startdate = shift_date_in_local_time(self.series.start_date, relativedelta(days=5), self.group.timezone) response = self.client.patch(url, {'start_date': new_startdate.isoformat()}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(parse(response.data['start_date']), new_startdate) # compare resulting pickups url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) for response_pickup, old_date in zip_longest(response.data, original_dates): self.assertEqual( parse(response_pickup['date'][0]), shift_date_in_local_time(old_date, relativedelta(days=5), self.group.timezone)) def test_change_start_date_to_past(self): self.client.force_login(user=self.member) # get original dates url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) original_dates = [parse(_['date'][0]) for _ in response.data] # change dates url = '/api/pickup-date-series/{}/'.format(self.series.id) new_startdate = shift_date_in_local_time(self.series.start_date, relativedelta(days=-5), self.group.timezone) response = self.client.patch(url, {'start_date': new_startdate.isoformat()}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(parse(response.data['start_date']), new_startdate) # compare resulting pickups url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) # shifting 5 days to the past is similar to shifting 2 days to the future for response_pickup, old_date in zip_longest(response.data, original_dates): new_date = shift_date_in_local_time(old_date, relativedelta(days=2), self.group.timezone) if new_date > self.now + relativedelta( weeks=self.place.weeks_in_advance): # date too far in future self.assertIsNone(response_pickup) else: self.assertEqual(parse(response_pickup['date'][0]), new_date) def test_set_end_date(self): self.client.force_login(user=self.member) # change rule url = '/api/pickup-date-series/{}/'.format(self.series.id) rule = 'FREQ=WEEKLY;UNTIL={}'.format( (self.now + relativedelta(days=8)).strftime('%Y%m%dT%H%M%S')) response = self.client.patch(url, {'rule': rule}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['rule'], rule) # compare resulting pickups url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(len(response.data), 2, response.data) def test_set_end_date_with_timezone(self): self.client.force_login(user=self.member) url = '/api/pickup-date-series/{}/'.format(self.series.id) rule = 'FREQ=WEEKLY;UNTIL={}+0100'.format( (self.now + relativedelta(days=8)).strftime('%Y%m%dT%H%M%S')) response = self.client.patch(url, {'rule': rule}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) def test_set_end_date_with_users_have_joined_pickup(self): self.client.force_login(user=self.member) self.series.pickup_dates.last().add_collector(self.member) # change rule url = '/api/pickup-date-series/{}/'.format(self.series.id) rule = rrulestr(self.series.rule, dtstart=self.now) \ .replace(until=self.now) response = self.client.patch(url, { 'rule': str(rule), }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['rule'], str(rule)) # compare resulting pickups url = '/api/pickup-dates/' response = self.get_results(url, { 'series': self.series.id, 'date_min': self.now }) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(len(response.data), 1, response.data) def test_disable_pickup_series(self): "the series should get removed, empty upcoming pickups disabled, non-empty pickups kept" self.client.force_login(user=self.member) joined_pickup = self.series.pickup_dates.last() joined_pickup.add_collector(self.member) url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT, response.data) url = '/api/pickup-dates/' response = self.get_results(url, {'date_min': self.now}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) empty_pickups = [p for p in response.data if len(p['collectors']) == 0] self.assertEqual(empty_pickups, []) url = '/api/pickup-dates/{}/'.format(joined_pickup.id) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['collectors'], [self.member.id]) self.assertFalse(response.data['is_disabled']) def test_change_max_collectors_to_invalid_number_fails(self): self.client.force_login(user=self.member) url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.patch(url, {'max_collectors': -1}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.data) def test_set_invalid_place_fails(self): original_place = self.series.place unrelated_place = PlaceFactory() self.client.force_login(user=self.member) url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.patch(url, {'place': unrelated_place.id}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['place'], original_place.id) self.series.refresh_from_db() self.assertEqual(self.series.place.id, original_place.id) def test_set_multiple_rules_fails(self): self.client.force_login(user=self.member) url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.patch( url, {'rule': 'RRULE:FREQ=WEEKLY;BYDAY=MO\nRRULE:FREQ=MONTHLY'}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.data) self.assertEqual( response.data, {'rule': ['Only single recurrence rules are allowed.']}) def test_keep_changes_to_max_collectors(self): self.client.force_login(user=self.member) pickup_under_test = self.series.pickup_dates.first() url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) # change setting of pickup response = self.client.patch(url, {'max_collectors': 666}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['max_collectors'], 666) # run regular update command of series self.series.update_pickups() # check if changes persist url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['max_collectors'], 666) # modify series max_collectors series_url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.patch(series_url, {'max_collectors': 20}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) # check if changes persist url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['max_collectors'], 666) def test_keep_changes_to_description(self): self.client.force_login(user=self.member) pickup_under_test = self.series.pickup_dates.first() url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) # change setting of pickup response = self.client.patch(url, {'description': 'asdf'}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['description'], 'asdf') # run regular update command of series self.series.update_pickups() # check if changes persist url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['description'], 'asdf') # modify series description series_url = '/api/pickup-date-series/{}/'.format(self.series.id) response = self.client.patch(series_url, {'description': 'new series description'}) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) # check if changes persist url = '/api/pickup-dates/{}/'.format(pickup_under_test.id) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['description'], 'asdf') def test_invalid_rule_fails(self): url = '/api/pickup-date-series/{}/'.format(self.series.id) self.client.force_login(user=self.member) response = self.client.patch(url, {'rule': 'FREQ=WEEKLY;BYDAY='}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.data) def test_keeps_joined_pickups(self): # join pickups [p.add_collector(self.member) for p in self.series.pickup_dates.all()] # change series rule to add another day today = self.now.astimezone(self.group.timezone).weekday() tomorrow = shift_date_in_local_time(self.now, relativedelta(days=1), self.group.timezone).astimezone( self.group.timezone).weekday() recurrence = rrule.rrule( freq=rrule.WEEKLY, byweekday=[ today, tomorrow, ], ) series_url = '/api/pickup-date-series/{}/'.format(self.series.id) self.client.force_login(user=self.member) response = self.client.patch(series_url, { 'rule': str(recurrence), }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.series.refresh_from_db() response = self.client.get('/api/pickup-dates/?series={}'.format( self.series.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) # self.assertEqual([parse(p['date'][0]) for p in response.data['results']], [ # shift_date_in_local_time(self.series.start_date, delta, self.group.timezone) for delta in ( # relativedelta(days=0), # relativedelta(days=1), # relativedelta(days=7), # relativedelta(days=8), # relativedelta(days=14), # relativedelta(days=15), # relativedelta(days=21), # relativedelta(days=22), # ) # ]) self.assertEqual( [p['collectors'] for p in response.data['results']], list( interleave( [[self.member.id] for _ in range(4)], [[] for _ in range(4)], )), ) def test_removes_empty_leftover_pickups_when_reducing_weeks_in_advance( self): # join one pickup joined_pickup = self.series.pickup_dates.first() joined_pickup.add_collector(self.member) # change weeks_in_advance place_url = '/api/places/{}/'.format(self.place.id) self.client.force_login(user=self.member) response = self.client.patch(place_url, { 'weeks_in_advance': 1, }) self.assertEqual(response.status_code, status.HTTP_200_OK) response = self.get_results('/api/pickup-dates/?series={}'.format( self.series.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['id'], joined_pickup.id) self.assertEqual(response.data[0]['collectors'], [self.member.id]) def test_cannot_move_pickups_in_a_series(self): self.client.force_login(user=self.member) pickup = self.series.pickup_dates.last() response = self.client.patch( '/api/pickup-dates/{}/'.format(pickup.id), { 'date': (pickup.date + relativedelta(weeks=7)).as_list(), }, format='json', ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn('You can\'t move pickups', response.data['date'][0]) def test_cannot_change_pickup_has_duration_in_a_series(self): self.client.force_login(user=self.member) pickup = self.series.pickup_dates.last() response = self.client.patch( '/api/pickup-dates/{}/'.format(pickup.id), {'has_duration': True}, format='json', ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( 'You cannot modify the duration of pickups that are part of a series', response.data['has_duration'][0])
def setUp(self): self.series = PickupDateSeriesFactory()