From b855b75138a8c949f5cf3fe900ae4a31ba5a09f8 Mon Sep 17 00:00:00 2001 From: EugenM Date: Fri, 15 Jun 2018 23:19:16 +0200 Subject: [PATCH 1/6] Multiple calendar slug values for api_occurrences url. --- schedule/views.py | 17 +++++++--- tests/test_views.py | 83 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/schedule/views.py b/schedule/views.py index 58248aa0..2828beb8 100644 --- a/schedule/views.py +++ b/schedule/views.py @@ -298,18 +298,20 @@ def get_next_url(request, default): def api_occurrences(request): start = request.GET.get('start') end = request.GET.get('end') - calendar_slug = request.GET.get('calendar_slug') + calendar_slugs_raw = request.GET.get('calendar_slug') timezone = request.GET.get('timezone') + calendar_slugs = calendar_slugs_raw.split(',') if calendar_slugs_raw else [] + try: - response_data = _api_occurrences(start, end, calendar_slug, timezone) + response_data = _api_occurrences(start, end, calendar_slugs, timezone) except (ValueError, Calendar.DoesNotExist) as e: return HttpResponseBadRequest(e) return JsonResponse(response_data, safe=False) -def _api_occurrences(start, end, calendar_slug, timezone): +def _api_occurrences(start, end, calendar_slugs, timezone): if not start or not end: raise ValueError('Start and end parameters are required') @@ -343,9 +345,14 @@ def convert(ddatetime): start = utc.localize(start) end = utc.localize(end) - if calendar_slug: + if calendar_slugs: # will raise DoesNotExist exception if no match - calendars = [Calendar.objects.get(slug=calendar_slug)] + calendars = list(Calendar.objects.filter(slug__in=calendar_slugs)) + missing_calendars = set(calendar_slugs) - set([s.slug for s in calendars]) + if missing_calendars: + missing_msg = ", ".join("'{0}'".format(s) for s in missing_calendars) + msg = "Calendars {0} does not exist.".format(missing_msg) + raise Calendar.DoesNotExist(missing_calendars) # if no calendar slug is given, get all the calendars else: calendars = Calendar.objects.all() diff --git a/tests/test_views.py b/tests/test_views.py index b696bf85..50e83434 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -67,7 +67,7 @@ def test_get_occurrence_raises(self): def test_get_occurrence_persisted(self): date = timezone.make_aware(datetime.datetime(year=2008, month=1, - day=5, hour=8, minute=0, second=0), + day=5, hour=8, minute=0, second=0), pytz.utc) occurrence = self.event.get_occurrence(date) occurrence.save() @@ -202,7 +202,10 @@ def test_occurrences_api_returns_the_expected_occurrences(self): reverse("api_occurrences") + "?calendar={}&start={}&end={}".format( 'MyCal', datetime.datetime(2008, 1, 5), datetime.datetime(2008, 1, 6))) self.assertEqual(response.status_code, 200) - expected_content = [{'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-05-05T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 9}] + expected_content = [ + {'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', + 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-05-05T00:00:00Z', + 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 9}] self.assertEqual(json.loads(response.content.decode()), expected_content) def test_occurrences_api_without_parameters_return_status_400(self): @@ -244,7 +247,20 @@ def test_occurrences_api_checks_valid_occurrence_ids(self): datetime.datetime(2008, 1, 5), datetime.datetime(2008, 1, 8))) self.assertEqual(response.status_code, 200) - expected_content = [{'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 10}, {'existed': False, 'end': '2008-01-06T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-06T08:00:00Z', 'id': 10}, {'existed': False, 'end': '2008-01-07T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 10}, {'existed': True, 'end': '2008-01-07T08:00:00Z', 'description': 'Persisted occ test', 'creator': 'None', 'color': '', 'title': 'My persisted Occ', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 1}] + expected_content = [ + {'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', + 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', + 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 10}, + {'existed': False, 'end': '2008-01-06T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', + 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', + 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-06T08:00:00Z', 'id': 10}, + {'existed': False, 'end': '2008-01-07T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', + 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', + 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 10}, + {'existed': True, 'end': '2008-01-07T08:00:00Z', 'description': 'Persisted occ test', 'creator': 'None', + 'color': '', 'title': 'My persisted Occ', 'rule': '', 'event_id': 8, + 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', + 'start': '2008-01-07T08:00:00Z', 'id': 1}] self.assertEqual(json.loads(response.content.decode()), expected_content) # test timezone param response = self.client.get( @@ -254,7 +270,23 @@ def test_occurrences_api_checks_valid_occurrence_ids(self): datetime.datetime(2008, 1, 8), 'America/Chicago')) self.assertEqual(response.status_code, 200) - expected_content = [{u'existed': False, u'end': u'2008-01-05T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-05T02:00:00-06:00', u'id': 10}, {u'existed': False, u'end': u'2008-01-06T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-06T02:00:00-06:00', u'id': 10}, {u'existed': False, u'end': u'2008-01-07T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-07T02:00:00-06:00', u'id': 10}, {u'existed': True, u'end': u'2008-01-07T02:00:00-06:00', u'description': u'Persisted occ test', u'creator': u'None', u'color': '', u'title': u'My persisted Occ', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-07T02:00:00-06:00', u'id': 1}] + expected_content = [ + {u'existed': False, u'end': u'2008-01-05T03:00:00-06:00', u'description': '', u'creator': u'None', + u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, + u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', + u'start': u'2008-01-05T02:00:00-06:00', u'id': 10}, + {u'existed': False, u'end': u'2008-01-06T03:00:00-06:00', u'description': '', u'creator': u'None', + u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, + u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', + u'start': u'2008-01-06T02:00:00-06:00', u'id': 10}, + {u'existed': False, u'end': u'2008-01-07T03:00:00-06:00', u'description': '', u'creator': u'None', + u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, + u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', + u'start': u'2008-01-07T02:00:00-06:00', u'id': 10}, + {u'existed': True, u'end': u'2008-01-07T02:00:00-06:00', u'description': u'Persisted occ test', + u'creator': u'None', u'color': '', u'title': u'My persisted Occ', u'rule': u'', u'event_id': 8, + u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', + u'start': u'2008-01-07T02:00:00-06:00', u'id': 1}] self.assertEqual(json.loads(response.content.decode()), expected_content) def test_occurrences_api_works_with_and_without_cal_slug(self): @@ -303,7 +335,7 @@ def test_cal_slug_filters_returned_events(self): # Test both present with no cal arg response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', - 'end': '2008-02-05'} + 'end': '2008-02-05'} ) self.assertEqual(response.status_code, 200) resp_list = json.loads(response.content.decode('utf-8')) @@ -369,6 +401,47 @@ def test_occurrences_api_fails_with_incorrect_date_string_formats(self): expected_error = "does not match format '%Y-%m-%dT%H:%M:%S'" self.assertIn(expected_error, resp) + def test_cal_multiple_slugs_return_all_events(self): + calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') + calendar2 = Calendar.objects.create(name="MyCal2", slug='MyCalSlug2') + calendarOther = Calendar.objects.create(name="MyCalOther", slug='MyCalSlugOther') + + event1 = Event.objects.create( + title='Recent Event 1', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendar1, + ) + event2 = Event.objects.create( + title='Recent Event 2', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendar2, + ) + + eventOther = Event.objects.create( + title='Recent Event Other', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendarOther, + ) + + # Test both present with no cal arg + response = self.client.get(reverse("api_occurrences"), + {'start': '2008-01-05', + 'end': '2008-02-05', + 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2',]), } + ) + self.assertEqual(response.status_code, 200) + resp_list = json.loads(response.content.decode('utf-8')) + self.assertIn(event1.title, [d['title'] for d in resp_list]) + self.assertIn(event2.title, [d['title'] for d in resp_list]) + + self.assertNotIn(eventOther.title, [d['title'] for d in resp_list]) + def test_check_next_url_valid_case(self): expected = '/calendar/1' res = check_next_url('/calendar/1') From 23344915c3caa80bd51a07249b80e6f8baa4dfd3 Mon Sep 17 00:00:00 2001 From: EugenM Date: Sat, 16 Jun 2018 11:04:41 +0200 Subject: [PATCH 2/6] Revert "Multiple calendar slug values for api_occurrences url." Need to fix autoformatted lines of code and a grammar error. This reverts commit b855b75138a8c949f5cf3fe900ae4a31ba5a09f8. --- schedule/views.py | 17 +++------- tests/test_views.py | 83 +++------------------------------------------ 2 files changed, 10 insertions(+), 90 deletions(-) diff --git a/schedule/views.py b/schedule/views.py index 2828beb8..58248aa0 100644 --- a/schedule/views.py +++ b/schedule/views.py @@ -298,20 +298,18 @@ def get_next_url(request, default): def api_occurrences(request): start = request.GET.get('start') end = request.GET.get('end') - calendar_slugs_raw = request.GET.get('calendar_slug') + calendar_slug = request.GET.get('calendar_slug') timezone = request.GET.get('timezone') - calendar_slugs = calendar_slugs_raw.split(',') if calendar_slugs_raw else [] - try: - response_data = _api_occurrences(start, end, calendar_slugs, timezone) + response_data = _api_occurrences(start, end, calendar_slug, timezone) except (ValueError, Calendar.DoesNotExist) as e: return HttpResponseBadRequest(e) return JsonResponse(response_data, safe=False) -def _api_occurrences(start, end, calendar_slugs, timezone): +def _api_occurrences(start, end, calendar_slug, timezone): if not start or not end: raise ValueError('Start and end parameters are required') @@ -345,14 +343,9 @@ def convert(ddatetime): start = utc.localize(start) end = utc.localize(end) - if calendar_slugs: + if calendar_slug: # will raise DoesNotExist exception if no match - calendars = list(Calendar.objects.filter(slug__in=calendar_slugs)) - missing_calendars = set(calendar_slugs) - set([s.slug for s in calendars]) - if missing_calendars: - missing_msg = ", ".join("'{0}'".format(s) for s in missing_calendars) - msg = "Calendars {0} does not exist.".format(missing_msg) - raise Calendar.DoesNotExist(missing_calendars) + calendars = [Calendar.objects.get(slug=calendar_slug)] # if no calendar slug is given, get all the calendars else: calendars = Calendar.objects.all() diff --git a/tests/test_views.py b/tests/test_views.py index 50e83434..b696bf85 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -67,7 +67,7 @@ def test_get_occurrence_raises(self): def test_get_occurrence_persisted(self): date = timezone.make_aware(datetime.datetime(year=2008, month=1, - day=5, hour=8, minute=0, second=0), + day=5, hour=8, minute=0, second=0), pytz.utc) occurrence = self.event.get_occurrence(date) occurrence.save() @@ -202,10 +202,7 @@ def test_occurrences_api_returns_the_expected_occurrences(self): reverse("api_occurrences") + "?calendar={}&start={}&end={}".format( 'MyCal', datetime.datetime(2008, 1, 5), datetime.datetime(2008, 1, 6))) self.assertEqual(response.status_code, 200) - expected_content = [ - {'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', - 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-05-05T00:00:00Z', - 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 9}] + expected_content = [{'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-05-05T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 9}] self.assertEqual(json.loads(response.content.decode()), expected_content) def test_occurrences_api_without_parameters_return_status_400(self): @@ -247,20 +244,7 @@ def test_occurrences_api_checks_valid_occurrence_ids(self): datetime.datetime(2008, 1, 5), datetime.datetime(2008, 1, 8))) self.assertEqual(response.status_code, 200) - expected_content = [ - {'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', - 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', - 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 10}, - {'existed': False, 'end': '2008-01-06T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', - 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', - 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-06T08:00:00Z', 'id': 10}, - {'existed': False, 'end': '2008-01-07T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', - 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', - 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 10}, - {'existed': True, 'end': '2008-01-07T08:00:00Z', 'description': 'Persisted occ test', 'creator': 'None', - 'color': '', 'title': 'My persisted Occ', 'rule': '', 'event_id': 8, - 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', - 'start': '2008-01-07T08:00:00Z', 'id': 1}] + expected_content = [{'existed': False, 'end': '2008-01-05T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-05T08:00:00Z', 'id': 10}, {'existed': False, 'end': '2008-01-06T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-06T08:00:00Z', 'id': 10}, {'existed': False, 'end': '2008-01-07T09:00:00Z', 'description': '', 'creator': 'None', 'color': '', 'title': 'Recent Event', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 10}, {'existed': True, 'end': '2008-01-07T08:00:00Z', 'description': 'Persisted occ test', 'creator': 'None', 'color': '', 'title': 'My persisted Occ', 'rule': '', 'event_id': 8, 'end_recurring_period': '2008-01-08T00:00:00Z', 'cancelled': False, 'calendar': 'MyCalSlug', 'start': '2008-01-07T08:00:00Z', 'id': 1}] self.assertEqual(json.loads(response.content.decode()), expected_content) # test timezone param response = self.client.get( @@ -270,23 +254,7 @@ def test_occurrences_api_checks_valid_occurrence_ids(self): datetime.datetime(2008, 1, 8), 'America/Chicago')) self.assertEqual(response.status_code, 200) - expected_content = [ - {u'existed': False, u'end': u'2008-01-05T03:00:00-06:00', u'description': '', u'creator': u'None', - u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, - u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', - u'start': u'2008-01-05T02:00:00-06:00', u'id': 10}, - {u'existed': False, u'end': u'2008-01-06T03:00:00-06:00', u'description': '', u'creator': u'None', - u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, - u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', - u'start': u'2008-01-06T02:00:00-06:00', u'id': 10}, - {u'existed': False, u'end': u'2008-01-07T03:00:00-06:00', u'description': '', u'creator': u'None', - u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, - u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', - u'start': u'2008-01-07T02:00:00-06:00', u'id': 10}, - {u'existed': True, u'end': u'2008-01-07T02:00:00-06:00', u'description': u'Persisted occ test', - u'creator': u'None', u'color': '', u'title': u'My persisted Occ', u'rule': u'', u'event_id': 8, - u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', - u'start': u'2008-01-07T02:00:00-06:00', u'id': 1}] + expected_content = [{u'existed': False, u'end': u'2008-01-05T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-05T02:00:00-06:00', u'id': 10}, {u'existed': False, u'end': u'2008-01-06T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-06T02:00:00-06:00', u'id': 10}, {u'existed': False, u'end': u'2008-01-07T03:00:00-06:00', u'description': '', u'creator': u'None', u'color': '', u'title': u'Recent Event', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-07T02:00:00-06:00', u'id': 10}, {u'existed': True, u'end': u'2008-01-07T02:00:00-06:00', u'description': u'Persisted occ test', u'creator': u'None', u'color': '', u'title': u'My persisted Occ', u'rule': u'', u'event_id': 8, u'end_recurring_period': u'2008-01-07T18:00:00-06:00', u'cancelled': False, u'calendar': u'MyCalSlug', u'start': u'2008-01-07T02:00:00-06:00', u'id': 1}] self.assertEqual(json.loads(response.content.decode()), expected_content) def test_occurrences_api_works_with_and_without_cal_slug(self): @@ -335,7 +303,7 @@ def test_cal_slug_filters_returned_events(self): # Test both present with no cal arg response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', - 'end': '2008-02-05'} + 'end': '2008-02-05'} ) self.assertEqual(response.status_code, 200) resp_list = json.loads(response.content.decode('utf-8')) @@ -401,47 +369,6 @@ def test_occurrences_api_fails_with_incorrect_date_string_formats(self): expected_error = "does not match format '%Y-%m-%dT%H:%M:%S'" self.assertIn(expected_error, resp) - def test_cal_multiple_slugs_return_all_events(self): - calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') - calendar2 = Calendar.objects.create(name="MyCal2", slug='MyCalSlug2') - calendarOther = Calendar.objects.create(name="MyCalOther", slug='MyCalSlugOther') - - event1 = Event.objects.create( - title='Recent Event 1', - start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), - end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), - end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), - calendar=calendar1, - ) - event2 = Event.objects.create( - title='Recent Event 2', - start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), - end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), - end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), - calendar=calendar2, - ) - - eventOther = Event.objects.create( - title='Recent Event Other', - start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), - end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), - end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), - calendar=calendarOther, - ) - - # Test both present with no cal arg - response = self.client.get(reverse("api_occurrences"), - {'start': '2008-01-05', - 'end': '2008-02-05', - 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2',]), } - ) - self.assertEqual(response.status_code, 200) - resp_list = json.loads(response.content.decode('utf-8')) - self.assertIn(event1.title, [d['title'] for d in resp_list]) - self.assertIn(event2.title, [d['title'] for d in resp_list]) - - self.assertNotIn(eventOther.title, [d['title'] for d in resp_list]) - def test_check_next_url_valid_case(self): expected = '/calendar/1' res = check_next_url('/calendar/1') From dc3dc5e902c5cf3944f92e996a02b431c70e9d7e Mon Sep 17 00:00:00 2001 From: EugenM Date: Sat, 16 Jun 2018 11:13:20 +0200 Subject: [PATCH 3/6] Multiple calendar slugs in api_occurence url. --- schedule/views.py | 17 ++++++++++++----- tests/test_views.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/schedule/views.py b/schedule/views.py index 58248aa0..cde05c51 100644 --- a/schedule/views.py +++ b/schedule/views.py @@ -298,18 +298,20 @@ def get_next_url(request, default): def api_occurrences(request): start = request.GET.get('start') end = request.GET.get('end') - calendar_slug = request.GET.get('calendar_slug') timezone = request.GET.get('timezone') + calendar_slugs_raw = request.GET.get('calendar_slug') + calendar_slugs = calendar_slugs_raw.split(',') if calendar_slugs_raw else [] + try: - response_data = _api_occurrences(start, end, calendar_slug, timezone) + response_data = _api_occurrences(start, end, calendar_slugs, timezone) except (ValueError, Calendar.DoesNotExist) as e: return HttpResponseBadRequest(e) return JsonResponse(response_data, safe=False) -def _api_occurrences(start, end, calendar_slug, timezone): +def _api_occurrences(start, end, calendar_slugs, timezone): if not start or not end: raise ValueError('Start and end parameters are required') @@ -343,9 +345,14 @@ def convert(ddatetime): start = utc.localize(start) end = utc.localize(end) - if calendar_slug: + if calendar_slugs: # will raise DoesNotExist exception if no match - calendars = [Calendar.objects.get(slug=calendar_slug)] + calendars = list(Calendar.objects.filter(slug__in=calendar_slugs)) + missing_calendars = set(calendar_slugs) - set([s.slug for s in calendars]) + if missing_calendars: + missing_msg = ", ".join("'{0}'".format(s) for s in missing_calendars) + msg = "Calendars {0} do not exist.".format(missing_msg) + raise Calendar.DoesNotExist(missing_calendars) # if no calendar slug is given, get all the calendars else: calendars = Calendar.objects.all() diff --git a/tests/test_views.py b/tests/test_views.py index b696bf85..922503dc 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -369,6 +369,47 @@ def test_occurrences_api_fails_with_incorrect_date_string_formats(self): expected_error = "does not match format '%Y-%m-%dT%H:%M:%S'" self.assertIn(expected_error, resp) + def test_cal_multiple_slugs_return_all_events(self): + calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') + calendar2 = Calendar.objects.create(name="MyCal2", slug='MyCalSlug2') + calendarOther = Calendar.objects.create(name="MyCalOther", slug='MyCalSlugOther') + + event1 = Event.objects.create( + title='Recent Event 1', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendar1, + ) + event2 = Event.objects.create( + title='Recent Event 2', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendar2, + ) + + eventOther = Event.objects.create( + title='Recent Event Other', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendarOther, + ) + + # Test both present with no cal arg + response = self.client.get(reverse("api_occurrences"), + {'start': '2008-01-05', + 'end': '2008-02-05', + 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2',]), } + ) + self.assertEqual(response.status_code, 200) + resp_list = json.loads(response.content.decode('utf-8')) + self.assertIn(event1.title, [d['title'] for d in resp_list]) + self.assertIn(event2.title, [d['title'] for d in resp_list]) + + self.assertNotIn(eventOther.title, [d['title'] for d in resp_list]) + def test_check_next_url_valid_case(self): expected = '/calendar/1' res = check_next_url('/calendar/1') From 4bd58ce5d9813aa49c6b797a9d72586329c20b72 Mon Sep 17 00:00:00 2001 From: EugenM Date: Sun, 17 Jun 2018 20:52:53 +0200 Subject: [PATCH 4/6] Added negative test for multiple calendar slugs. Fixed wrong error message. --- schedule/views.py | 2 +- tests/test_views.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/schedule/views.py b/schedule/views.py index cde05c51..1426434e 100644 --- a/schedule/views.py +++ b/schedule/views.py @@ -352,7 +352,7 @@ def convert(ddatetime): if missing_calendars: missing_msg = ", ".join("'{0}'".format(s) for s in missing_calendars) msg = "Calendars {0} do not exist.".format(missing_msg) - raise Calendar.DoesNotExist(missing_calendars) + raise Calendar.DoesNotExist(msg) # if no calendar slug is given, get all the calendars else: calendars = Calendar.objects.all() diff --git a/tests/test_views.py b/tests/test_views.py index 922503dc..b0de0fe2 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -410,6 +410,25 @@ def test_cal_multiple_slugs_return_all_events(self): self.assertNotIn(eventOther.title, [d['title'] for d in resp_list]) + def test_cal_request_missing_returns_400(self): + calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') + + event1 = Event.objects.create( + title='Recent Event 1', + start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), + end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), + end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), + calendar=calendar1, + ) + + # Test both present with no cal arg + response = self.client.get(reverse("api_occurrences"), + {'start': '2008-01-05', + 'end': '2008-02-05', + 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlugOther',]), } + ) + self.assertContains(response, 'MyCalSlugOther', status_code=400) + def test_check_next_url_valid_case(self): expected = '/calendar/1' res = check_next_url('/calendar/1') From 83f4e712a5c9b5f7fb8b9ded4f3268a76fce0612 Mon Sep 17 00:00:00 2001 From: EugenM Date: Sun, 17 Jun 2018 21:18:59 +0200 Subject: [PATCH 5/6] fixed flake errors. --- tests/test_views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_views.py b/tests/test_views.py index b0de0fe2..6d33c13f 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -401,7 +401,7 @@ def test_cal_multiple_slugs_return_all_events(self): response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', 'end': '2008-02-05', - 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2',]), } + 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2', ]), } ) self.assertEqual(response.status_code, 200) resp_list = json.loads(response.content.decode('utf-8')) @@ -413,7 +413,7 @@ def test_cal_multiple_slugs_return_all_events(self): def test_cal_request_missing_returns_400(self): calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') - event1 = Event.objects.create( + Event.objects.create( title='Recent Event 1', start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), @@ -425,7 +425,7 @@ def test_cal_request_missing_returns_400(self): response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', 'end': '2008-02-05', - 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlugOther',]), } + 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlugOther', ]), } ) self.assertContains(response, 'MyCalSlugOther', status_code=400) From ebcb79d8d148c282df22efd9ff2978ed08d0a1cf Mon Sep 17 00:00:00 2001 From: EugenM Date: Sun, 17 Jun 2018 21:18:59 +0200 Subject: [PATCH 6/6] fixed flake errors. --- tests/test_views.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/test_views.py b/tests/test_views.py index b0de0fe2..c9f1874a 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -396,12 +396,14 @@ def test_cal_multiple_slugs_return_all_events(self): end_recurring_period=datetime.datetime(2008, 5, 5, 0, 0, tzinfo=pytz.utc), calendar=calendarOther, ) + + calendar_slug = ','.join(['MyCalSlug1','MyCalSlug2', ]) # Test both present with no cal arg response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', 'end': '2008-02-05', - 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlug2',]), } + 'calendar_slug': calendar_slug, } ) self.assertEqual(response.status_code, 200) resp_list = json.loads(response.content.decode('utf-8')) @@ -413,7 +415,7 @@ def test_cal_multiple_slugs_return_all_events(self): def test_cal_request_missing_returns_400(self): calendar1 = Calendar.objects.create(name="MyCal1", slug='MyCalSlug1') - event1 = Event.objects.create( + Event.objects.create( title='Recent Event 1', start=datetime.datetime(2008, 1, 5, 8, 0, tzinfo=pytz.utc), end=datetime.datetime(2008, 1, 5, 9, 0, tzinfo=pytz.utc), @@ -421,11 +423,12 @@ def test_cal_request_missing_returns_400(self): calendar=calendar1, ) + calendar_slug = ','.join(['MyCalSlug1','MyCalSlugOther', ]) # Test both present with no cal arg response = self.client.get(reverse("api_occurrences"), {'start': '2008-01-05', 'end': '2008-02-05', - 'calendar_slug': ','.join(['MyCalSlug1','MyCalSlugOther',]), } + 'calendar_slug': calendar_slug, } ) self.assertContains(response, 'MyCalSlugOther', status_code=400)