Repository: couchers-org/couchers
Issue: Can't edit event

Subject: Can't edit event
Description:
Tried to edit an event and change the time

Results:
It says my event can't have overlapping times... 

Backend version: develop-c14158d6
Frontend version: develop-c14158d6
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Page: https://app.couchers.org/event/242/istanbul-online-3/edit
User: emily (135)

Changed files:
app/backend/src/tests/test_events.py, app/backend/src/couchers/servicers/events.py

diff --git a/app/backend/src/couchers/servicers/events.py b/app/backend/src/couchers/servicers/events.py
index 5f351fd7e..675b06490 100644
--- a/app/backend/src/couchers/servicers/events.py
+++ b/app/backend/src/couchers/servicers/events.py
@@ -325,7 +325,11 @@ class Events(events_pb2_grpc.EventsServicer):
 
             # && is the overlap operator for ranges
             if (
-                session.execute(select(EventOccurrence.id).where(EventOccurrence.during.op("&&")(during)))
+                session.execute(
+                    select(EventOccurrence.id)
+                    .where(EventOccurrence.event_id == event.id)
+                    .where(EventOccurrence.during.op("&&")(during))
+                )
                 .scalars()
                 .first()
                 is not None
@@ -421,6 +425,7 @@ class Events(events_pb2_grpc.EventsServicer):
                 if (
                     session.execute(
                         select(EventOccurrence.id)
+                        .where(EventOccurrence.event_id == event.id)
                         .where(EventOccurrence.id != occurrence.id)
                         .where(EventOccurrence.during.op("&&")(during))
                     )
diff --git a/app/backend/src/tests/test_events.py b/app/backend/src/tests/test_events.py
index 8b3bbe44e..0b3f81622 100644
--- a/app/backend/src/tests/test_events.py
+++ b/app/backend/src/tests/test_events.py
@@ -1812,7 +1812,7 @@ def test_ListEventAttendees_regression(db):
     # `ListEventAttendees` should return the current user's ID
     #
     # **Actual/current behaviour**
-    # `ListEventAttendees` returns another user's ID. This ID seems to be determined from the row's auto increment ID in `event_occurence_attendees` in the database
+    # `ListEventAttendees` returns another user's ID. This ID seems to be determined from the row's auto increment ID in `event_occurrence_attendees` in the database
 
     user1, token1 = generate_user()
     user2, token2 = generate_user()
@@ -1905,3 +1905,131 @@ def test_event_threads(db):
         assert ret.replies[0].content == "hi"
         assert ret.replies[0].author_user_id == user2.id
         assert ret.replies[0].num_replies == 0
+
+
+def test_can_overlap_other_events_schedule_regression(db):
+    # we had a bug where we were checking overlapping for *all* occurrences of *all* events, not just the ones for this event
+    user, token = generate_user()
+
+    with session_scope() as session:
+        c_id = create_community(session, 0, 2, "Community", [user], [], None).id
+
+    start = now()
+
+    with events_session(token) as api:
+        # create another event, should be able to overlap with this one
+        api.CreateEvent(
+            events_pb2.CreateEventReq(
+                title="Dummy Title",
+                content="Dummy content.",
+                parent_community_id=c_id,
+                online_information=events_pb2.OnlineEventInformation(
+                    link="https://app.couchers.org/meet/",
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=5)),
+                timezone="UTC",
+            )
+        )
+
+        # this event
+        res = api.CreateEvent(
+            events_pb2.CreateEventReq(
+                title="Dummy Title",
+                content="Dummy content.",
+                parent_community_id=c_id,
+                online_information=events_pb2.OnlineEventInformation(
+                    link="https://app.couchers.org/meet/",
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=2)),
+                timezone="UTC",
+            )
+        )
+
+        # this doesn't overlap with the just created event, but does overlap with the occurrence from earlier; which should be no problem
+        api.ScheduleEvent(
+            events_pb2.ScheduleEventReq(
+                event_id=res.event_id,
+                content="New event occurrence",
+                offline_information=events_pb2.OfflineEventInformation(
+                    address="A bit further but still near Null Island",
+                    lat=0.3,
+                    lng=0.2,
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=3)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
+                timezone="UTC",
+            )
+        )
+
+
+def test_can_overlap_other_events_update_regression(db):
+    user, token = generate_user()
+
+    with session_scope() as session:
+        c_id = create_community(session, 0, 2, "Community", [user], [], None).id
+
+    start = now()
+
+    with events_session(token) as api:
+        # create another event, should be able to overlap with this one
+        api.CreateEvent(
+            events_pb2.CreateEventReq(
+                title="Dummy Title",
+                content="Dummy content.",
+                parent_community_id=c_id,
+                online_information=events_pb2.OnlineEventInformation(
+                    link="https://app.couchers.org/meet/",
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=3)),
+                timezone="UTC",
+            )
+        )
+
+        res = api.CreateEvent(
+            events_pb2.CreateEventReq(
+                title="Dummy Title",
+                content="Dummy content.",
+                parent_community_id=c_id,
+                online_information=events_pb2.OnlineEventInformation(
+                    link="https://app.couchers.org/meet/",
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=7)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=8)),
+                timezone="UTC",
+            )
+        )
+
+        event_id = api.ScheduleEvent(
+            events_pb2.ScheduleEventReq(
+                event_id=res.event_id,
+                content="New event occurrence",
+                offline_information=events_pb2.OfflineEventInformation(
+                    address="A bit further but still near Null Island",
+                    lat=0.3,
+                    lng=0.2,
+                ),
+                start_time=Timestamp_from_datetime(start + timedelta(hours=4)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
+                timezone="UTC",
+            )
+        ).event_id
+
+        # can overlap with this current existing occurrence
+        api.UpdateEvent(
+            events_pb2.UpdateEventReq(
+                event_id=event_id,
+                start_time=Timestamp_from_datetime(start + timedelta(hours=5)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
+            )
+        )
+
+        api.UpdateEvent(
+            events_pb2.UpdateEventReq(
+                event_id=event_id,
+                start_time=Timestamp_from_datetime(start + timedelta(hours=2)),
+                end_time=Timestamp_from_datetime(start + timedelta(hours=4)),
+            )
+        )