Repository: carpentries/amy

Issue:
Cannot view upcoming teaching opportunities
Hi @maneesha 
Could you please help me with this?

The blue button at https://amy.carpentries.org/dashboard/instructor/
as shown in the screenshot below
![image](https://user-images.githubusercontent.com/3046889/197223287-5b007ba0-fd6a-47d6-b719-ec1509a54cc6.png)

leads to "Server Error (500)" at https://amy.carpentries.org/dashboard/instructor/teaching_opportunities/
as shown in the screenshot below
![image](https://user-images.githubusercontent.com/3046889/197223554-9cf5bde1-58e2-4f5c-b93f-392b79e46a3c.png)

Tried a few times at different hours.

Thank you in advance.


Discussion:

Resolving patch:
diff --git a/amy/recruitment/templatetags/instructorrecruitment.py b/amy/recruitment/templatetags/instructorrecruitment.py
--- a/amy/recruitment/templatetags/instructorrecruitment.py
+++ b/amy/recruitment/templatetags/instructorrecruitment.py
@@ -23,13 +23,21 @@ def is_instructor_recruitment_enabled() -> bool:
 
 
 @register.simple_tag
-def get_event_conflicts(events: Sequence[Event], event: Event) -> list[Event]:
+def get_event_conflicts(events_to_check: Sequence[Event], event: Event) -> list[Event]:
     conflicts: list[Event] = []
 
-    for event_to_check in events:
+    # event must have start and end dates, otherwise we can't get conflicts
+    if not (event.start and event.end):
+        return conflicts
+
+    for event_to_check in events_to_check:
         if event == event_to_check:
             continue
 
+        # event getting checked must have start and end dates
+        if not (event_to_check.start and event_to_check.end):
+            continue
+
         if event.start <= event_to_check.end and event.end >= event_to_check.start:
             conflicts.append(event_to_check)
 
@@ -38,14 +46,26 @@ def get_event_conflicts(events: Sequence[Event], event: Event) -> list[Event]:
 
 @register.simple_tag
 def get_events_nearby(
-    events: Sequence[Event], event: Event, days_before: int = 14, days_after: int = 14
+    events_to_check: Sequence[Event],
+    event: Event,
+    days_before: int = 14,
+    days_after: int = 14,
 ) -> list[Event]:
+    """Get events nearby another event time-wise."""
     nearby: list[Event] = []
 
-    for event_to_check in events:
+    # event must have start and end dates, otherwise we can't get nearby events
+    if not (event.start and event.end):
+        return nearby
+
+    for event_to_check in events_to_check:
         if event == event_to_check:
             continue
 
+        # event getting checked must have start and end dates
+        if not (event_to_check.start and event_to_check.end):
+            continue
+
         if (
             event.start - timedelta(days=days_before) <= event_to_check.end
             and event.end + timedelta(days=days_after) >= event_to_check.start
@@ -57,14 +77,26 @@ def get_events_nearby(
 
 @register.simple_tag
 def get_signup_conflicts(
-    signups: Sequence[InstructorRecruitmentSignup], recruitment: InstructorRecruitment
+    signups_to_check: Sequence[InstructorRecruitmentSignup],
+    recruitment: InstructorRecruitment,
 ) -> list[InstructorRecruitmentSignup]:
     conflicts: list[InstructorRecruitmentSignup] = []
 
-    for signup_to_check in signups:
+    # recruitment event must have start and end dates, otherwise we can't get conflicts
+    if not (recruitment.event.start and recruitment.event.end):
+        return conflicts
+
+    for signup_to_check in signups_to_check:
         if recruitment == signup_to_check.recruitment:
             continue
 
+        # event getting checked must have start and end dates
+        if not (
+            signup_to_check.recruitment.event.start
+            and signup_to_check.recruitment.event.end
+        ):
+            continue
+
         if (
             recruitment.event.start <= signup_to_check.recruitment.event.end
             and recruitment.event.end >= signup_to_check.recruitment.event.start


Test patch:
diff --git a/amy/recruitment/tests/test_template_tags.py b/amy/recruitment/tests/test_template_tags.py
--- a/amy/recruitment/tests/test_template_tags.py
+++ b/amy/recruitment/tests/test_template_tags.py
@@ -51,6 +51,24 @@ def test_get_event_conflicts(self) -> None:
         # Assert
         self.assertEqual(results, [event2])
 
+    def test_get_event_conflicts_no_start_or_end_dates(self) -> None:
+        """Regression test for #2243."""
+        # Arrange
+        event1 = Event(
+            slug="2022-01-01-test", start=date(2022, 1, 1), end=date(2022, 1, 2)
+        )
+        event2 = Event(slug="2022-02-01-test", start=None, end=date(2022, 2, 2))
+        event3 = Event(slug="2022-03-01-test", start=date(2022, 3, 1), end=None)
+        event4 = Event(slug="2022-xx-xx-test", start=None, end=None)
+        events = [event1, event2, event3, event4]
+        event = Event(
+            slug="2022-01-02-test", start=date(2022, 1, 2), end=date(2022, 1, 3)
+        )
+        # Act
+        results = get_event_conflicts(events, event)
+        # Assert
+        self.assertEqual(results, [event1])
+
     def test_get_events_nearby(self) -> None:
         # Arrange
         event1 = Event(
@@ -71,6 +89,24 @@ def test_get_events_nearby(self) -> None:
         # Assert
         self.assertEqual(results, [event1, event2])
 
+    def test_get_events_nearby_no_start_or_end_dates(self) -> None:
+        """Regression test for #2243."""
+        # Arrange
+        event1 = Event(
+            slug="2022-01-01-test", start=date(2022, 1, 1), end=date(2022, 1, 2)
+        )
+        event2 = Event(slug="2022-02-01-test", start=None, end=date(2022, 2, 2))
+        event3 = Event(slug="2022-03-01-test", start=date(2022, 3, 1), end=None)
+        event4 = Event(slug="2022-xx-xx-test", start=None, end=None)
+        events = [event1, event2, event3, event4]
+        event = Event(
+            slug="2021-12-22-test", start=date(2021, 12, 22), end=date(2021, 12, 23)
+        )
+        # Act
+        results = get_events_nearby(events, event)
+        # Assert
+        self.assertEqual(results, [event1])
+
     def test_get_signup_conflicts(self) -> None:
         # Arrange
         signup1 = InstructorRecruitmentSignup(
@@ -105,6 +141,42 @@ def test_get_signup_conflicts(self) -> None:
         # Assert
         self.assertEqual(results, [signup2])
 
+    def test_get_signup_conflicts_no_start_or_end_dates(self) -> None:
+        """Regression test for #2243."""
+        # Arrange
+        signup1 = InstructorRecruitmentSignup(
+            recruitment=InstructorRecruitment(
+                event=Event(
+                    slug="2022-01-01-test", start=date(2022, 1, 1), end=date(2022, 1, 2)
+                )
+            )
+        )
+        signup2 = InstructorRecruitmentSignup(
+            recruitment=InstructorRecruitment(
+                event=Event(slug="2022-02-01-test", start=None, end=date(2022, 2, 2))
+            )
+        )
+        signup3 = InstructorRecruitmentSignup(
+            recruitment=InstructorRecruitment(
+                event=Event(slug="2022-03-01-test", start=date(2022, 3, 1), end=None)
+            )
+        )
+        signup4 = InstructorRecruitmentSignup(
+            recruitment=InstructorRecruitment(
+                event=Event(slug="2022-xx-xx-test", start=None, end=None)
+            )
+        )
+        signups = [signup1, signup2, signup3, signup4]
+        recruitment = InstructorRecruitment(
+            event=Event(
+                slug="2022-01-02-test", start=date(2022, 1, 2), end=date(2022, 1, 3)
+            )
+        )
+        # Act
+        results = get_signup_conflicts(signups, recruitment)
+        # Assert
+        self.assertEqual(results, [signup1])
+
     def test_priority_label__success(self) -> None:
         # Arrange
         values = [1, RecruitmentPriority.MEDIUM]