From 1502c108dbb36a1fc94c9fac7eae4185f9f21da5 Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Fri, 25 Dec 2020 02:27:09 +0100 Subject: [PATCH 01/10] Add Methods To Check If Event Starts And Ends This Year --- events/models.py | 18 ++++++++++++++++++ events/tests/test_models.py | 23 ++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/events/models.py b/events/models.py index 3334ca326..c3b84ec18 100644 --- a/events/models.py +++ b/events/models.py @@ -181,6 +181,24 @@ def next_time(self): except IndexError: return None + def is_scheduled_to_start_this_year(self) -> bool: + current_year: int = datetime.datetime.now().year + try: + if self.next_time.dt_start.year == current_year: + return True + except Exception: + pass + return False + + def is_scheduled_to_end_this_year(self) -> bool: + current_year: int = datetime.datetime.now().year + try: + if self.next_time.dt_end.year == current_year: + return True + except Exception: + pass + return False + @property def previous_time(self): now = timezone.now() diff --git a/events/tests/test_models.py b/events/tests/test_models.py index 0f3bafe76..b6d2e7ef3 100644 --- a/events/tests/test_models.py +++ b/events/tests/test_models.py @@ -62,7 +62,6 @@ def test_recurring_event(self): self.assertEqual(self.event.next_time.dt_start, recurring_time_dtstart) self.assertTrue(rt.valid_dt_end()) - rt.begin = now - datetime.timedelta(days=5) rt.finish = now - datetime.timedelta(days=3) rt.save() @@ -186,3 +185,25 @@ def test_event_previous_event(self): # 'Event.previous_event' can return None if there is no # OccurringRule or RecurringRule found. self.assertIsNone(self.event.previous_event) + + def test_scheduled_to_start_this_year_method(self): + now = seconds_resolution(timezone.now()) + + occurring_time_dtstart = now + datetime.timedelta(days=3) + OccurringRule.objects.create( + event=self.event, + dt_start=occurring_time_dtstart, + dt_end=occurring_time_dtstart + ) + self.assertTrue(self.event.is_scheduled_to_start_this_year()) + + def test_scheduled_to_end_this_year_method(self): + now = seconds_resolution(timezone.now()) + + occurring_time_dtstart = now + datetime.timedelta(days=3) + OccurringRule.objects.create( + event=self.event, + dt_start=occurring_time_dtstart, + dt_end=occurring_time_dtstart + ) + self.assertTrue(self.event.is_scheduled_to_end_this_year()) From 4198812511cc9b2cce9ca5c8192fdb8508fc98a3 Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Fri, 25 Dec 2020 03:31:06 +0100 Subject: [PATCH 02/10] Set Up Templates For Querying Start And End Years Passed variables to the time_tag template [time_tag.html] that checks if an event was scheduled to start or end with the current year. --- templates/events/event_list.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/templates/events/event_list.html b/templates/events/event_list.html index bbfb764d2..285fa0c7d 100644 --- a/templates/events/event_list.html +++ b/templates/events/event_list.html @@ -45,8 +45,12 @@

U

{{ object.title|striptags }}

{% with object.next_time as next_time %} + {% with object.is_scheduled_to_start_this_year as scheduled_start_this_year %} + {% with object.is_scheduled_to_end_this_year as scheduled_end_this_year %} {% include "events/includes/time_tag.html" %} {% endwith %} + {% endwith %} + {% endwith %} {% if object.venue %} {% if object.venue.url %}{% endif %}{{ object.venue.name }}{% if object.venue.url %}{% endif %}{% if object.venue.address %}, {{ object.venue.address }}{% endif %} @@ -65,8 +69,12 @@

You just missed...

{{ object.title|striptags }}

{% with object.previous_time as next_time %} + {% with object.is_scheduled_to_start_this_year as scheduled_start_this_year %} + {% with object.is_scheduled_to_end_this_year as scheduled_end_this_year %} {% include "events/includes/time_tag.html" %} {% endwith %} + {% endwith %} + {% endwith %} {% if object.venue %} {% if object.venue.url %}{% endif %}{{ object.venue.name }}{% if object.venue.url %}{% endif %}{% if object.venue.address %}, {{ object.venue.address }}{% endif %} From ff1ad8b61ffed710d3935e901ad49e4a8b70a5ee Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Fri, 25 Dec 2020 03:35:17 +0100 Subject: [PATCH 03/10] Insert New Test Data And Update test_views.py More events are created to test particular scenarios of events especially events set to start or end at a future year. --- events/tests/test_views.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/events/tests/test_views.py b/events/tests/test_views.py index 691817036..b8603bfdf 100644 --- a/events/tests/test_views.py +++ b/events/tests/test_views.py @@ -6,7 +6,7 @@ from django.test import TestCase from django.utils import timezone -from ..models import Calendar, Event, EventCategory, EventLocation, RecurringRule +from ..models import Calendar, Event, EventCategory, EventLocation, RecurringRule, OccurringRule from ..templatetags.events import get_events_upcoming from users.factories import UserFactory @@ -18,6 +18,11 @@ def setUpTestData(cls): cls.calendar = Calendar.objects.create(creator=cls.user, slug="test-calendar") cls.event = Event.objects.create(creator=cls.user, calendar=cls.calendar) cls.event_past = Event.objects.create(title='Past Event', creator=cls.user, calendar=cls.calendar) + cls.event_single_day = Event.objects.create(title="Single Day Event", creator=cls.user, calendar=cls.calendar) + cls.event_future_start_following_year = Event.objects.create(title='Event Starts Following Year', + creator=cls.user, calendar=cls.calendar) + cls.event_future_end_following_year = Event.objects.create(title='Event Ends Following Year', + creator=cls.user, calendar=cls.calendar) cls.now = timezone.now() @@ -34,12 +39,27 @@ def setUpTestData(cls): begin=cls.now - datetime.timedelta(days=2), finish=cls.now - datetime.timedelta(days=1), ) - + cls.rule_single_day = OccurringRule.objects.create( + event=cls.event_single_day, + dt_start=recurring_time_dtstart, + dt_end=recurring_time_dtstart + ) + cls.rule_future_start_year = OccurringRule.objects.create( + event=cls.event_future_start_following_year, + dt_start=recurring_time_dtstart + datetime.timedelta(weeks=52), + dt_end=recurring_time_dtstart + datetime.timedelta(weeks=53), + ) + cls.rule_future_end_year = OccurringRule.objects.create( + event=cls.event_future_end_following_year, + dt_start=recurring_time_dtstart, + dt_end=recurring_time_dtend + datetime.timedelta(weeks=52) + ) def test_events_homepage(self): url = reverse('events:events') response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 1) + self.assertEqual(len(response.context['object_list']), 4) + self.assertIn(Event.objects.last().title, response.content.decode()) def test_calendar_list(self): calendars_count = Calendar.objects.count() @@ -54,7 +74,7 @@ def test_event_list(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 1) + self.assertEqual(len(response.context['object_list']), 4) url = reverse('events:event_list_past', kwargs={"calendar_slug": 'unexisting'}) response = self.client.get(url) @@ -114,7 +134,7 @@ def test_event_list_date(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['object'], dt.date()) - self.assertEqual(len(response.context['object_list']), 2) + self.assertEqual(len(response.context['object_list']), 5) def test_eventlocation_list(self): venue = EventLocation.objects.create( @@ -150,12 +170,12 @@ def test_event_detail(self): self.assertEqual(self.event, response.context['object']) def test_upcoming_tag(self): - self.assertEqual(len(get_events_upcoming()), 1) + self.assertEqual(len(get_events_upcoming()), 4) self.assertEqual(len(get_events_upcoming(only_featured=True)), 0) self.rule.begin = self.now - datetime.timedelta(days=3) self.rule.finish = self.now - datetime.timedelta(days=2) self.rule.save() - self.assertEqual(len(get_events_upcoming()), 0) + self.assertEqual(len(get_events_upcoming()), 3) class EventSubmitTests(TestCase): From e3125d9f41a0c2d42ebc9d37dbc8a380b49c60ac Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Fri, 25 Dec 2020 03:38:22 +0100 Subject: [PATCH 04/10] Time Tag Now Shows Year For Events With Details Not Within The Current Year The time tag now displays the year when an event will occur. This is only for events that have been scheduled to start or end in at a future year. The accompanying functional tests have also been included. --- events/tests/test_events_functional_test.py | 41 +++++++++++++++++++++ templates/events/includes/time_tag.html | 31 +++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 events/tests/test_events_functional_test.py diff --git a/events/tests/test_events_functional_test.py b/events/tests/test_events_functional_test.py new file mode 100644 index 000000000..2813316d7 --- /dev/null +++ b/events/tests/test_events_functional_test.py @@ -0,0 +1,41 @@ +from django.test import LiveServerTestCase, TestCase +from django.utils import timezone +from selenium.common.exceptions import WebDriverException +from selenium.webdriver import Chrome + +from .test_views import EventsViewsTests +from ..models import Event + + +class EventsPageFunctionalTests(LiveServerTestCase, TestCase): + @classmethod + def setUpClass(cls): + EventsViewsTests().setUpTestData() + super().setUpClass() + cls.now = timezone.now() + + def setUp(self) -> None: + try: + self.browser = Chrome() + self.browser.implicitly_wait(5) + except WebDriverException: # GitHub Actions Django CI + from selenium import webdriver + self.browser = webdriver.FirefoxOptions() + self.browser.headless = True + webdriver.Firefox(options=self.browser) + + def tearDown(self) -> None: + self.browser.quit() + + def test_event_starting_future_year_displays_year(self): + event = Event.objects.get(title=f"Event Starts Following Year") + self.browser.get(self.live_server_url + '/events/') + future_event_span_value = self.browser.find_element_by_id(str(event.id)) + self.assertIn(str(event.next_time.dt_start.year), future_event_span_value.text) + + def test_event_ending_future_year_displays_year(self): + event = Event.objects.get(title=f"Event Ends Following Year") + self.browser.get(self.live_server_url + '/events/') + future_event_span_value = self.browser.find_element_by_id(str(event.id)) + self.assertIn(str(event.next_time.dt_end.year), future_event_span_value.text) + diff --git a/templates/events/includes/time_tag.html b/templates/events/includes/time_tag.html index 078fcf1dc..c79d0b810 100644 --- a/templates/events/includes/time_tag.html +++ b/templates/events/includes/time_tag.html @@ -1,5 +1,32 @@ {% if next_time.single_day %} - + {% else %} - + {% endif %} \ No newline at end of file From 178742b4122d7f80f665cb8d798ddde0feddf900 Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Fri, 25 Dec 2020 06:09:42 +0100 Subject: [PATCH 05/10] Move All Test Data To Functional Test All test data concerning the provision of data to serve the functional tests have been moved to the functional test. As it improves readability. All other test data at test_views.py was reset to accommodate for the reduction in number of test data instances. --- events/tests/test_events_functional_test.py | 51 +++++++++++++++------ events/tests/test_views.py | 25 +++------- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/events/tests/test_events_functional_test.py b/events/tests/test_events_functional_test.py index 2813316d7..f07146a9b 100644 --- a/events/tests/test_events_functional_test.py +++ b/events/tests/test_events_functional_test.py @@ -1,18 +1,38 @@ -from django.test import LiveServerTestCase, TestCase +import datetime + +from django.contrib.auth import get_user_model +from django.test import LiveServerTestCase from django.utils import timezone from selenium.common.exceptions import WebDriverException from selenium.webdriver import Chrome -from .test_views import EventsViewsTests -from ..models import Event +from ..models import Event, OccurringRule, Calendar -class EventsPageFunctionalTests(LiveServerTestCase, TestCase): +class EventsPageFunctionalTests(LiveServerTestCase): @classmethod def setUpClass(cls): - EventsViewsTests().setUpTestData() - super().setUpClass() cls.now = timezone.now() + cls.user = get_user_model().objects.create_user(username='username', password='password') + cls.calendar = Calendar.objects.create(creator=cls.user, slug="test-calendar-2") + cls.event_future_start_following_year = Event.objects.create(title='Event Starts Following Year', + creator=cls.user, calendar=cls.calendar) + cls.event_future_end_following_year = Event.objects.create(title='Event Ends Following Year', + creator=cls.user, calendar=cls.calendar) + recurring_time_dtstart = cls.now + datetime.timedelta(days=3) + recurring_time_dtend = recurring_time_dtstart + datetime.timedelta(days=5) + + cls.rule_future_start_year = OccurringRule.objects.create( + event=cls.event_future_start_following_year, + dt_start=recurring_time_dtstart + datetime.timedelta(weeks=52), + dt_end=recurring_time_dtstart + datetime.timedelta(weeks=53), + ) + cls.rule_future_end_year = OccurringRule.objects.create( + event=cls.event_future_end_following_year, + dt_start=recurring_time_dtstart, + dt_end=recurring_time_dtend + datetime.timedelta(weeks=52) + ) + super(EventsPageFunctionalTests, cls).setUpClass() def setUp(self) -> None: try: @@ -25,17 +45,18 @@ def setUp(self) -> None: webdriver.Firefox(options=self.browser) def tearDown(self) -> None: - self.browser.quit() + super().tearDown() + try: + self.browser.quit() + except Exception: + pass - def test_event_starting_future_year_displays_year(self): - event = Event.objects.get(title=f"Event Starts Following Year") + def test_event_starting_and_ending_future_year_displays_year(self): + event = self.event_future_start_following_year self.browser.get(self.live_server_url + '/events/') future_event_span_value = self.browser.find_element_by_id(str(event.id)) self.assertIn(str(event.next_time.dt_start.year), future_event_span_value.text) - def test_event_ending_future_year_displays_year(self): - event = Event.objects.get(title=f"Event Ends Following Year") - self.browser.get(self.live_server_url + '/events/') - future_event_span_value = self.browser.find_element_by_id(str(event.id)) - self.assertIn(str(event.next_time.dt_end.year), future_event_span_value.text) - + event_2 = Event.objects.get(title="Event Ends Following Year") + future_event_span_value = self.browser.find_element_by_id(str(event_2.id)) + self.assertIn(str(event_2.next_time.dt_end.year), future_event_span_value.text) diff --git a/events/tests/test_views.py b/events/tests/test_views.py index b8603bfdf..e111419b8 100644 --- a/events/tests/test_views.py +++ b/events/tests/test_views.py @@ -19,10 +19,6 @@ def setUpTestData(cls): cls.event = Event.objects.create(creator=cls.user, calendar=cls.calendar) cls.event_past = Event.objects.create(title='Past Event', creator=cls.user, calendar=cls.calendar) cls.event_single_day = Event.objects.create(title="Single Day Event", creator=cls.user, calendar=cls.calendar) - cls.event_future_start_following_year = Event.objects.create(title='Event Starts Following Year', - creator=cls.user, calendar=cls.calendar) - cls.event_future_end_following_year = Event.objects.create(title='Event Ends Following Year', - creator=cls.user, calendar=cls.calendar) cls.now = timezone.now() @@ -44,21 +40,12 @@ def setUpTestData(cls): dt_start=recurring_time_dtstart, dt_end=recurring_time_dtstart ) - cls.rule_future_start_year = OccurringRule.objects.create( - event=cls.event_future_start_following_year, - dt_start=recurring_time_dtstart + datetime.timedelta(weeks=52), - dt_end=recurring_time_dtstart + datetime.timedelta(weeks=53), - ) - cls.rule_future_end_year = OccurringRule.objects.create( - event=cls.event_future_end_following_year, - dt_start=recurring_time_dtstart, - dt_end=recurring_time_dtend + datetime.timedelta(weeks=52) - ) + def test_events_homepage(self): url = reverse('events:events') response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 4) + self.assertEqual(len(response.context['object_list']), 2) self.assertIn(Event.objects.last().title, response.content.decode()) def test_calendar_list(self): @@ -74,7 +61,7 @@ def test_event_list(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 4) + self.assertEqual(len(response.context['object_list']), 2) url = reverse('events:event_list_past', kwargs={"calendar_slug": 'unexisting'}) response = self.client.get(url) @@ -134,7 +121,7 @@ def test_event_list_date(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['object'], dt.date()) - self.assertEqual(len(response.context['object_list']), 5) + self.assertEqual(len(response.context['object_list']), 3) def test_eventlocation_list(self): venue = EventLocation.objects.create( @@ -170,12 +157,12 @@ def test_event_detail(self): self.assertEqual(self.event, response.context['object']) def test_upcoming_tag(self): - self.assertEqual(len(get_events_upcoming()), 4) + self.assertEqual(len(get_events_upcoming()), 2) self.assertEqual(len(get_events_upcoming(only_featured=True)), 0) self.rule.begin = self.now - datetime.timedelta(days=3) self.rule.finish = self.now - datetime.timedelta(days=2) self.rule.save() - self.assertEqual(len(get_events_upcoming()), 3) + self.assertEqual(len(get_events_upcoming()), 1) class EventSubmitTests(TestCase): From e0fdf7cf8c11816ce0b4c24e686d5c57a447e626 Mon Sep 17 00:00:00 2001 From: Nwokolo Godwin Date: Sun, 27 Dec 2020 12:05:09 +0100 Subject: [PATCH 06/10] Functional Test For Displaying Year Of Event For Future Events Now Implemented With Unit Tests --- events/tests/test_events_functional_test.py | 4 +- events/tests/test_views.py | 54 +++++++++++++++++++-- templates/events/includes/time_tag.html | 12 ++--- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/events/tests/test_events_functional_test.py b/events/tests/test_events_functional_test.py index f07146a9b..b6164409b 100644 --- a/events/tests/test_events_functional_test.py +++ b/events/tests/test_events_functional_test.py @@ -54,9 +54,9 @@ def tearDown(self) -> None: def test_event_starting_and_ending_future_year_displays_year(self): event = self.event_future_start_following_year self.browser.get(self.live_server_url + '/events/') - future_event_span_value = self.browser.find_element_by_id(str(event.id)) + future_event_span_value = self.browser.find_element_by_id("start-"+str(event.id)) self.assertIn(str(event.next_time.dt_start.year), future_event_span_value.text) event_2 = Event.objects.get(title="Event Ends Following Year") - future_event_span_value = self.browser.find_element_by_id(str(event_2.id)) + future_event_span_value = self.browser.find_element_by_id("end-"+str(event_2.id)) self.assertIn(str(event_2.next_time.dt_end.year), future_event_span_value.text) diff --git a/events/tests/test_views.py b/events/tests/test_views.py index e111419b8..7fb4f1b16 100644 --- a/events/tests/test_views.py +++ b/events/tests/test_views.py @@ -19,6 +19,10 @@ def setUpTestData(cls): cls.event = Event.objects.create(creator=cls.user, calendar=cls.calendar) cls.event_past = Event.objects.create(title='Past Event', creator=cls.user, calendar=cls.calendar) cls.event_single_day = Event.objects.create(title="Single Day Event", creator=cls.user, calendar=cls.calendar) + cls.event_starts_at_future_year = Event.objects.create(title='Event Starts Following Year', + creator=cls.user, calendar=cls.calendar) + cls.event_ends_at_future_year = Event.objects.create(title='Event Ends Following Year', + creator=cls.user, calendar=cls.calendar) cls.now = timezone.now() @@ -40,12 +44,26 @@ def setUpTestData(cls): dt_start=recurring_time_dtstart, dt_end=recurring_time_dtstart ) + cls.rule_future_start_year = OccurringRule.objects.create( + event=cls.event_starts_at_future_year, + dt_start=recurring_time_dtstart + datetime.timedelta(weeks=52), + dt_end=recurring_time_dtstart + datetime.timedelta(weeks=53), + ) + cls.rule_future_end_year = OccurringRule.objects.create( + event=cls.event_ends_at_future_year, + dt_start=recurring_time_dtstart, + dt_end=recurring_time_dtend + datetime.timedelta(weeks=52) + ) + + def tearDown(self) -> None: + from django.core.cache import cache + cache.clear() def test_events_homepage(self): url = reverse('events:events') response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 2) + self.assertEqual(len(response.context['object_list']), 4) self.assertIn(Event.objects.last().title, response.content.decode()) def test_calendar_list(self): @@ -61,7 +79,7 @@ def test_event_list(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.context['object_list']), 2) + self.assertEqual(len(response.context['object_list']), 4) url = reverse('events:event_list_past', kwargs={"calendar_slug": 'unexisting'}) response = self.client.get(url) @@ -121,7 +139,7 @@ def test_event_list_date(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['object'], dt.date()) - self.assertEqual(len(response.context['object_list']), 3) + self.assertEqual(len(response.context['object_list']), 5) def test_eventlocation_list(self): venue = EventLocation.objects.create( @@ -157,13 +175,39 @@ def test_event_detail(self): self.assertEqual(self.event, response.context['object']) def test_upcoming_tag(self): - self.assertEqual(len(get_events_upcoming()), 2) + self.assertEqual(len(get_events_upcoming()), 4) self.assertEqual(len(get_events_upcoming(only_featured=True)), 0) self.rule.begin = self.now - datetime.timedelta(days=3) self.rule.finish = self.now - datetime.timedelta(days=2) self.rule.save() - self.assertEqual(len(get_events_upcoming()), 1) + self.assertEqual(len(get_events_upcoming()), 3) + + def test_event_starting_future_year_displays_relevant_year(self): + event = self.event_starts_at_future_year + url = reverse('events:events') + response = self.client.get(url) + self.assertIn( + f'', + response.content.decode() + ) + def test_event_ending_future_year_displays_relevant_year(self): + event = self.event_ends_at_future_year + url = reverse('events:events') + response = self.client.get(url) + self.assertIn( + f'', + response.content.decode() + ) + + def test_events_scheduled_current_year_does_not_display_current_year(self): + event = self.event_single_day + url = reverse('events:events') + response = self.client.get(url) + self.assertIn( # start date + f'', + response.content.decode() + ) class EventSubmitTests(TestCase): event_submit_url = reverse_lazy('events:event_submit') diff --git a/templates/events/includes/time_tag.html b/templates/events/includes/time_tag.html index c79d0b810..90bc4491b 100644 --- a/templates/events/includes/time_tag.html +++ b/templates/events/includes/time_tag.html @@ -1,10 +1,10 @@ {% if next_time.single_day %} -