Coverage for src/tests/test_events.py: 100%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from datetime import timedelta
3import grpc
4import pytest
5from google.protobuf import wrappers_pb2
6from psycopg2.extras import DateTimeTZRange
7from sqlalchemy.sql.expression import update
9from couchers import errors
10from couchers.db import session_scope
11from couchers.models import EventOccurrence
12from couchers.utils import Timestamp_from_datetime, now, to_aware_datetime
13from proto import events_pb2, threads_pb2
14from tests.test_communities import create_community, create_group
15from tests.test_fixtures import db, events_session, generate_user, testconfig, threads_session # noqa
18@pytest.fixture(autouse=True)
19def _(testconfig):
20 pass
23def test_CreateEvent(db):
24 # test cases:
25 # can create event
26 # cannot create event with missing details
27 # can create online event
28 # can create in person event
29 # can't create event that starts in the past
30 # can create in different timezones
32 # event creator
33 user1, token1 = generate_user()
34 # community moderator
35 user2, token2 = generate_user()
36 # third party
37 user3, token3 = generate_user()
39 with session_scope() as session:
40 c_id = create_community(session, 0, 2, "Community", [user2], [], None).id
42 time_before = now()
43 start_time = now() + timedelta(hours=2)
44 end_time = start_time + timedelta(hours=3)
46 with events_session(token1) as api:
47 # in person event
48 res = api.CreateEvent(
49 events_pb2.CreateEventReq(
50 title="Dummy Title",
51 content="Dummy content.",
52 photo_key=None,
53 offline_information=events_pb2.OfflineEventInformation(
54 address="Near Null Island",
55 lat=0.1,
56 lng=0.2,
57 ),
58 start_time=Timestamp_from_datetime(start_time),
59 end_time=Timestamp_from_datetime(end_time),
60 timezone="UTC",
61 )
62 )
64 assert res.is_next
65 assert res.title == "Dummy Title"
66 assert res.slug == "dummy-title"
67 assert res.content == "Dummy content."
68 assert not res.photo_url
69 assert res.WhichOneof("mode") == "offline_information"
70 assert res.offline_information.lat == 0.1
71 assert res.offline_information.lng == 0.2
72 assert res.offline_information.address == "Near Null Island"
73 assert time_before <= to_aware_datetime(res.created) <= now()
74 assert time_before <= to_aware_datetime(res.last_edited) <= now()
75 assert res.creator_user_id == user1.id
76 assert to_aware_datetime(res.start_time) == start_time
77 assert to_aware_datetime(res.end_time) == end_time
78 # assert res.timezone == "UTC"
79 assert res.start_time_display
80 assert res.end_time_display
81 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
82 assert res.organizer
83 assert res.subscriber
84 assert res.going_count == 1
85 assert res.maybe_count == 0
86 assert res.organizer_count == 1
87 assert res.subscriber_count == 1
88 assert res.owner_user_id == user1.id
89 assert not res.owner_community_id
90 assert not res.owner_group_id
91 assert res.thread.thread_id
92 assert res.can_edit
93 assert not res.can_moderate
95 event_id = res.event_id
97 with events_session(token2) as api:
98 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
100 assert res.is_next
101 assert res.title == "Dummy Title"
102 assert res.slug == "dummy-title"
103 assert res.content == "Dummy content."
104 assert not res.photo_url
105 assert res.WhichOneof("mode") == "offline_information"
106 assert res.offline_information.lat == 0.1
107 assert res.offline_information.lng == 0.2
108 assert res.offline_information.address == "Near Null Island"
109 assert time_before <= to_aware_datetime(res.created) <= now()
110 assert time_before <= to_aware_datetime(res.last_edited) <= now()
111 assert res.creator_user_id == user1.id
112 assert to_aware_datetime(res.start_time) == start_time
113 assert to_aware_datetime(res.end_time) == end_time
114 # assert res.timezone == "UTC"
115 assert res.start_time_display
116 assert res.end_time_display
117 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
118 assert not res.organizer
119 assert not res.subscriber
120 assert res.going_count == 1
121 assert res.maybe_count == 0
122 assert res.organizer_count == 1
123 assert res.subscriber_count == 1
124 assert res.owner_user_id == user1.id
125 assert not res.owner_community_id
126 assert not res.owner_group_id
127 assert res.thread.thread_id
128 assert not res.can_edit
129 assert res.can_moderate
131 with events_session(token3) as api:
132 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
134 assert res.is_next
135 assert res.title == "Dummy Title"
136 assert res.slug == "dummy-title"
137 assert res.content == "Dummy content."
138 assert not res.photo_url
139 assert res.WhichOneof("mode") == "offline_information"
140 assert res.offline_information.lat == 0.1
141 assert res.offline_information.lng == 0.2
142 assert res.offline_information.address == "Near Null Island"
143 assert time_before <= to_aware_datetime(res.created) <= now()
144 assert time_before <= to_aware_datetime(res.last_edited) <= now()
145 assert res.creator_user_id == user1.id
146 assert to_aware_datetime(res.start_time) == start_time
147 assert to_aware_datetime(res.end_time) == end_time
148 # assert res.timezone == "UTC"
149 assert res.start_time_display
150 assert res.end_time_display
151 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
152 assert not res.organizer
153 assert not res.subscriber
154 assert res.going_count == 1
155 assert res.maybe_count == 0
156 assert res.organizer_count == 1
157 assert res.subscriber_count == 1
158 assert res.owner_user_id == user1.id
159 assert not res.owner_community_id
160 assert not res.owner_group_id
161 assert res.thread.thread_id
162 assert not res.can_edit
163 assert not res.can_moderate
165 with events_session(token1) as api:
166 # online only event
167 res = api.CreateEvent(
168 events_pb2.CreateEventReq(
169 title="Dummy Title",
170 content="Dummy content.",
171 photo_key=None,
172 online_information=events_pb2.OnlineEventInformation(
173 link="https://couchers.org/meet/",
174 ),
175 parent_community_id=c_id,
176 start_time=Timestamp_from_datetime(start_time),
177 end_time=Timestamp_from_datetime(end_time),
178 timezone="UTC",
179 )
180 )
182 assert res.is_next
183 assert res.title == "Dummy Title"
184 assert res.slug == "dummy-title"
185 assert res.content == "Dummy content."
186 assert not res.photo_url
187 assert res.WhichOneof("mode") == "online_information"
188 assert res.online_information.link == "https://couchers.org/meet/"
189 assert time_before <= to_aware_datetime(res.created) <= now()
190 assert time_before <= to_aware_datetime(res.last_edited) <= now()
191 assert res.creator_user_id == user1.id
192 assert to_aware_datetime(res.start_time) == start_time
193 assert to_aware_datetime(res.end_time) == end_time
194 # assert res.timezone == "UTC"
195 assert res.start_time_display
196 assert res.end_time_display
197 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
198 assert res.organizer
199 assert res.subscriber
200 assert res.going_count == 1
201 assert res.maybe_count == 0
202 assert res.organizer_count == 1
203 assert res.subscriber_count == 1
204 assert res.owner_user_id == user1.id
205 assert not res.owner_community_id
206 assert not res.owner_group_id
207 assert res.thread.thread_id
208 assert res.can_edit
209 assert not res.can_moderate
211 event_id = res.event_id
213 with events_session(token2) as api:
214 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
216 assert res.is_next
217 assert res.title == "Dummy Title"
218 assert res.slug == "dummy-title"
219 assert res.content == "Dummy content."
220 assert not res.photo_url
221 assert res.WhichOneof("mode") == "online_information"
222 assert res.online_information.link == "https://couchers.org/meet/"
223 assert time_before <= to_aware_datetime(res.created) <= now()
224 assert time_before <= to_aware_datetime(res.last_edited) <= now()
225 assert res.creator_user_id == user1.id
226 assert to_aware_datetime(res.start_time) == start_time
227 assert to_aware_datetime(res.end_time) == end_time
228 # assert res.timezone == "UTC"
229 assert res.start_time_display
230 assert res.end_time_display
231 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
232 assert not res.organizer
233 assert not res.subscriber
234 assert res.going_count == 1
235 assert res.maybe_count == 0
236 assert res.organizer_count == 1
237 assert res.subscriber_count == 1
238 assert res.owner_user_id == user1.id
239 assert not res.owner_community_id
240 assert not res.owner_group_id
241 assert res.thread.thread_id
242 assert not res.can_edit
243 assert res.can_moderate
245 with events_session(token3) as api:
246 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
248 assert res.is_next
249 assert res.title == "Dummy Title"
250 assert res.slug == "dummy-title"
251 assert res.content == "Dummy content."
252 assert not res.photo_url
253 assert res.WhichOneof("mode") == "online_information"
254 assert res.online_information.link == "https://couchers.org/meet/"
255 assert time_before <= to_aware_datetime(res.created) <= now()
256 assert time_before <= to_aware_datetime(res.last_edited) <= now()
257 assert res.creator_user_id == user1.id
258 assert to_aware_datetime(res.start_time) == start_time
259 assert to_aware_datetime(res.end_time) == end_time
260 # assert res.timezone == "UTC"
261 assert res.start_time_display
262 assert res.end_time_display
263 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
264 assert not res.organizer
265 assert not res.subscriber
266 assert res.going_count == 1
267 assert res.maybe_count == 0
268 assert res.organizer_count == 1
269 assert res.subscriber_count == 1
270 assert res.owner_user_id == user1.id
271 assert not res.owner_community_id
272 assert not res.owner_group_id
273 assert res.thread.thread_id
274 assert not res.can_edit
275 assert not res.can_moderate
277 with events_session(token1) as api:
278 with pytest.raises(grpc.RpcError) as e:
279 api.CreateEvent(
280 events_pb2.CreateEventReq(
281 title="Dummy Title",
282 content="Dummy content.",
283 photo_key=None,
284 online_information=events_pb2.OnlineEventInformation(
285 link="https://couchers.org/meet/",
286 ),
287 start_time=Timestamp_from_datetime(start_time),
288 end_time=Timestamp_from_datetime(end_time),
289 timezone="UTC",
290 )
291 )
292 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
293 assert e.value.details() == errors.ONLINE_EVENT_MISSING_PARENT_COMMUNITY
295 with pytest.raises(grpc.RpcError) as e:
296 api.CreateEvent(
297 events_pb2.CreateEventReq(
298 # title="Dummy Title",
299 content="Dummy content.",
300 photo_key=None,
301 offline_information=events_pb2.OfflineEventInformation(
302 address="Near Null Island",
303 lat=0.1,
304 lng=0.1,
305 ),
306 start_time=Timestamp_from_datetime(start_time),
307 end_time=Timestamp_from_datetime(end_time),
308 timezone="UTC",
309 )
310 )
311 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
312 assert e.value.details() == errors.MISSING_EVENT_TITLE
314 with pytest.raises(grpc.RpcError) as e:
315 api.CreateEvent(
316 events_pb2.CreateEventReq(
317 title="Dummy Title",
318 # content="Dummy content.",
319 photo_key=None,
320 offline_information=events_pb2.OfflineEventInformation(
321 address="Near Null Island",
322 lat=0.1,
323 lng=0.1,
324 ),
325 start_time=Timestamp_from_datetime(start_time),
326 end_time=Timestamp_from_datetime(end_time),
327 timezone="UTC",
328 )
329 )
330 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
331 assert e.value.details() == errors.MISSING_EVENT_CONTENT
333 with pytest.raises(grpc.RpcError) as e:
334 api.CreateEvent(
335 events_pb2.CreateEventReq(
336 title="Dummy Title",
337 content="Dummy content.",
338 photo_key="nonexistent",
339 offline_information=events_pb2.OfflineEventInformation(
340 address="Near Null Island",
341 lat=0.1,
342 lng=0.1,
343 ),
344 start_time=Timestamp_from_datetime(start_time),
345 end_time=Timestamp_from_datetime(end_time),
346 timezone="UTC",
347 )
348 )
349 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
350 assert e.value.details() == errors.PHOTO_NOT_FOUND
352 with pytest.raises(grpc.RpcError) as e:
353 api.CreateEvent(
354 events_pb2.CreateEventReq(
355 title="Dummy Title",
356 content="Dummy content.",
357 photo_key=None,
358 offline_information=events_pb2.OfflineEventInformation(
359 address="Near Null Island",
360 ),
361 start_time=Timestamp_from_datetime(start_time),
362 end_time=Timestamp_from_datetime(end_time),
363 timezone="UTC",
364 )
365 )
366 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
367 assert e.value.details() == errors.MISSING_EVENT_ADDRESS_OR_LOCATION
369 with pytest.raises(grpc.RpcError) as e:
370 api.CreateEvent(
371 events_pb2.CreateEventReq(
372 title="Dummy Title",
373 content="Dummy content.",
374 photo_key=None,
375 offline_information=events_pb2.OfflineEventInformation(
376 lat=0.1,
377 lng=0.1,
378 ),
379 start_time=Timestamp_from_datetime(start_time),
380 end_time=Timestamp_from_datetime(end_time),
381 timezone="UTC",
382 )
383 )
384 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
385 assert e.value.details() == errors.MISSING_EVENT_ADDRESS_OR_LOCATION
387 with pytest.raises(grpc.RpcError) as e:
388 api.CreateEvent(
389 events_pb2.CreateEventReq(
390 title="Dummy Title",
391 content="Dummy content.",
392 photo_key=None,
393 online_information=events_pb2.OnlineEventInformation(),
394 start_time=Timestamp_from_datetime(start_time),
395 end_time=Timestamp_from_datetime(end_time),
396 timezone="UTC",
397 )
398 )
399 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
400 assert e.value.details() == errors.ONLINE_EVENT_REQUIRES_LINK
402 with pytest.raises(grpc.RpcError) as e:
403 api.CreateEvent(
404 events_pb2.CreateEventReq(
405 title="Dummy Title",
406 content="Dummy content.",
407 parent_community_id=c_id,
408 online_information=events_pb2.OnlineEventInformation(
409 link="https://couchers.org/meet/",
410 ),
411 start_time=Timestamp_from_datetime(now() - timedelta(hours=2)),
412 end_time=Timestamp_from_datetime(end_time),
413 timezone="UTC",
414 )
415 )
416 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
417 assert e.value.details() == errors.EVENT_IN_PAST
419 with pytest.raises(grpc.RpcError) as e:
420 api.CreateEvent(
421 events_pb2.CreateEventReq(
422 title="Dummy Title",
423 content="Dummy content.",
424 parent_community_id=c_id,
425 online_information=events_pb2.OnlineEventInformation(
426 link="https://couchers.org/meet/",
427 ),
428 start_time=Timestamp_from_datetime(end_time),
429 end_time=Timestamp_from_datetime(start_time),
430 timezone="UTC",
431 )
432 )
433 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
434 assert e.value.details() == errors.EVENT_ENDS_BEFORE_STARTS
436 with pytest.raises(grpc.RpcError) as e:
437 api.CreateEvent(
438 events_pb2.CreateEventReq(
439 title="Dummy Title",
440 content="Dummy content.",
441 parent_community_id=c_id,
442 online_information=events_pb2.OnlineEventInformation(
443 link="https://couchers.org/meet/",
444 ),
445 start_time=Timestamp_from_datetime(now() + timedelta(days=500, hours=2)),
446 end_time=Timestamp_from_datetime(now() + timedelta(days=500, hours=5)),
447 timezone="UTC",
448 )
449 )
450 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
451 assert e.value.details() == errors.EVENT_TOO_FAR_IN_FUTURE
453 with pytest.raises(grpc.RpcError) as e:
454 api.CreateEvent(
455 events_pb2.CreateEventReq(
456 title="Dummy Title",
457 content="Dummy content.",
458 parent_community_id=c_id,
459 online_information=events_pb2.OnlineEventInformation(
460 link="https://couchers.org/meet/",
461 ),
462 start_time=Timestamp_from_datetime(start_time),
463 end_time=Timestamp_from_datetime(now() + timedelta(days=100)),
464 timezone="UTC",
465 )
466 )
467 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
468 assert e.value.details() == errors.EVENT_TOO_LONG
471def test_ScheduleEvent(db):
472 # test cases:
473 # can schedule a new event occurrence
475 user, token = generate_user()
477 with session_scope() as session:
478 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
480 time_before = now()
481 start_time = now() + timedelta(hours=2)
482 end_time = start_time + timedelta(hours=3)
484 with events_session(token) as api:
485 res = api.CreateEvent(
486 events_pb2.CreateEventReq(
487 title="Dummy Title",
488 content="Dummy content.",
489 parent_community_id=c_id,
490 online_information=events_pb2.OnlineEventInformation(
491 link="https://couchers.org/meet/",
492 ),
493 start_time=Timestamp_from_datetime(start_time),
494 end_time=Timestamp_from_datetime(end_time),
495 timezone="UTC",
496 )
497 )
499 new_start_time = now() + timedelta(hours=6)
500 new_end_time = new_start_time + timedelta(hours=2)
502 res = api.ScheduleEvent(
503 events_pb2.ScheduleEventReq(
504 event_id=res.event_id,
505 content="New event occurrence",
506 offline_information=events_pb2.OfflineEventInformation(
507 address="A bit further but still near Null Island",
508 lat=0.3,
509 lng=0.2,
510 ),
511 start_time=Timestamp_from_datetime(new_start_time),
512 end_time=Timestamp_from_datetime(new_end_time),
513 timezone="UTC",
514 )
515 )
517 res = api.GetEvent(events_pb2.GetEventReq(event_id=res.event_id))
519 assert not res.is_next
520 assert res.title == "Dummy Title"
521 assert res.slug == "dummy-title"
522 assert res.content == "New event occurrence"
523 assert not res.photo_url
524 assert res.WhichOneof("mode") == "offline_information"
525 assert res.offline_information.lat == 0.3
526 assert res.offline_information.lng == 0.2
527 assert res.offline_information.address == "A bit further but still near Null Island"
528 assert time_before <= to_aware_datetime(res.created) <= now()
529 assert time_before <= to_aware_datetime(res.last_edited) <= now()
530 assert res.creator_user_id == user.id
531 assert to_aware_datetime(res.start_time) == new_start_time
532 assert to_aware_datetime(res.end_time) == new_end_time
533 # assert res.timezone == "UTC"
534 assert res.start_time_display
535 assert res.end_time_display
536 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
537 assert res.organizer
538 assert res.subscriber
539 assert res.going_count == 1
540 assert res.maybe_count == 0
541 assert res.organizer_count == 1
542 assert res.subscriber_count == 1
543 assert res.owner_user_id == user.id
544 assert not res.owner_community_id
545 assert not res.owner_group_id
546 assert res.thread.thread_id
547 assert res.can_edit
548 assert res.can_moderate
551def test_cannot_overlap_occurrences_schedule(db):
552 user, token = generate_user()
554 with session_scope() as session:
555 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
557 start = now()
559 with events_session(token) as api:
560 res = api.CreateEvent(
561 events_pb2.CreateEventReq(
562 title="Dummy Title",
563 content="Dummy content.",
564 parent_community_id=c_id,
565 online_information=events_pb2.OnlineEventInformation(
566 link="https://couchers.org/meet/",
567 ),
568 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
569 end_time=Timestamp_from_datetime(start + timedelta(hours=3)),
570 timezone="UTC",
571 )
572 )
574 with pytest.raises(grpc.RpcError) as e:
575 api.ScheduleEvent(
576 events_pb2.ScheduleEventReq(
577 event_id=res.event_id,
578 content="New event occurrence",
579 offline_information=events_pb2.OfflineEventInformation(
580 address="A bit further but still near Null Island",
581 lat=0.3,
582 lng=0.2,
583 ),
584 start_time=Timestamp_from_datetime(start + timedelta(hours=2)),
585 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
586 timezone="UTC",
587 )
588 )
589 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
590 assert e.value.details() == errors.EVENT_CANT_OVERLAP
593def test_cannot_overlap_occurrences_update(db):
594 user, token = generate_user()
596 with session_scope() as session:
597 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
599 start = now()
601 with events_session(token) as api:
602 res = api.CreateEvent(
603 events_pb2.CreateEventReq(
604 title="Dummy Title",
605 content="Dummy content.",
606 parent_community_id=c_id,
607 online_information=events_pb2.OnlineEventInformation(
608 link="https://couchers.org/meet/",
609 ),
610 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
611 end_time=Timestamp_from_datetime(start + timedelta(hours=3)),
612 timezone="UTC",
613 )
614 )
616 event_id = api.ScheduleEvent(
617 events_pb2.ScheduleEventReq(
618 event_id=res.event_id,
619 content="New event occurrence",
620 offline_information=events_pb2.OfflineEventInformation(
621 address="A bit further but still near Null Island",
622 lat=0.3,
623 lng=0.2,
624 ),
625 start_time=Timestamp_from_datetime(start + timedelta(hours=4)),
626 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
627 timezone="UTC",
628 )
629 ).event_id
631 # can overlap with this current existing occurrence
632 api.UpdateEvent(
633 events_pb2.UpdateEventReq(
634 event_id=event_id,
635 start_time=Timestamp_from_datetime(start + timedelta(hours=5)),
636 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
637 )
638 )
640 with pytest.raises(grpc.RpcError) as e:
641 api.UpdateEvent(
642 events_pb2.UpdateEventReq(
643 event_id=event_id,
644 start_time=Timestamp_from_datetime(start + timedelta(hours=2)),
645 end_time=Timestamp_from_datetime(start + timedelta(hours=4)),
646 )
647 )
648 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
649 assert e.value.details() == errors.EVENT_CANT_OVERLAP
652def test_UpdateEvent_single(db):
653 # test cases:
654 # owner can update
655 # community owner can update
656 # can't mess up online/in person dichotomy
657 # notifies attendees
659 # event creator
660 user1, token1 = generate_user()
661 # community moderator
662 user2, token2 = generate_user()
663 # third parties
664 user3, token3 = generate_user()
665 user4, token4 = generate_user()
666 user5, token5 = generate_user()
667 user6, token6 = generate_user()
669 with session_scope() as session:
670 c_id = create_community(session, 0, 2, "Community", [user2], [], None).id
672 time_before = now()
673 start_time = now() + timedelta(hours=2)
674 end_time = start_time + timedelta(hours=3)
676 with events_session(token1) as api:
677 res = api.CreateEvent(
678 events_pb2.CreateEventReq(
679 title="Dummy Title",
680 content="Dummy content.",
681 offline_information=events_pb2.OfflineEventInformation(
682 address="Near Null Island",
683 lat=0.1,
684 lng=0.2,
685 ),
686 start_time=Timestamp_from_datetime(start_time),
687 end_time=Timestamp_from_datetime(end_time),
688 timezone="UTC",
689 )
690 )
692 event_id = res.event_id
694 with events_session(token4) as api:
695 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
697 with events_session(token5) as api:
698 api.SetEventAttendance(
699 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
700 )
702 with events_session(token6) as api:
703 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
704 api.SetEventAttendance(
705 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_MAYBE)
706 )
708 time_before_update = now()
710 with events_session(token1) as api:
711 res = api.UpdateEvent(
712 events_pb2.UpdateEventReq(
713 event_id=event_id,
714 )
715 )
717 with events_session(token1) as api:
718 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
720 assert res.is_next
721 assert res.title == "Dummy Title"
722 assert res.slug == "dummy-title"
723 assert res.content == "Dummy content."
724 assert not res.photo_url
725 assert res.WhichOneof("mode") == "offline_information"
726 assert res.offline_information.lat == 0.1
727 assert res.offline_information.lng == 0.2
728 assert res.offline_information.address == "Near Null Island"
729 assert time_before <= to_aware_datetime(res.created) <= time_before_update
730 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
731 assert res.creator_user_id == user1.id
732 assert to_aware_datetime(res.start_time) == start_time
733 assert to_aware_datetime(res.end_time) == end_time
734 # assert res.timezone == "UTC"
735 assert res.start_time_display
736 assert res.end_time_display
737 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
738 assert res.organizer
739 assert res.subscriber
740 assert res.going_count == 2
741 assert res.maybe_count == 1
742 assert res.organizer_count == 1
743 assert res.subscriber_count == 3
744 assert res.owner_user_id == user1.id
745 assert not res.owner_community_id
746 assert not res.owner_group_id
747 assert res.thread.thread_id
748 assert res.can_edit
749 assert not res.can_moderate
751 with events_session(token2) as api:
752 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
754 assert res.is_next
755 assert res.title == "Dummy Title"
756 assert res.slug == "dummy-title"
757 assert res.content == "Dummy content."
758 assert not res.photo_url
759 assert res.WhichOneof("mode") == "offline_information"
760 assert res.offline_information.lat == 0.1
761 assert res.offline_information.lng == 0.2
762 assert res.offline_information.address == "Near Null Island"
763 assert time_before <= to_aware_datetime(res.created) <= time_before_update
764 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
765 assert res.creator_user_id == user1.id
766 assert to_aware_datetime(res.start_time) == start_time
767 assert to_aware_datetime(res.end_time) == end_time
768 # assert res.timezone == "UTC"
769 assert res.start_time_display
770 assert res.end_time_display
771 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
772 assert not res.organizer
773 assert not res.subscriber
774 assert res.going_count == 2
775 assert res.maybe_count == 1
776 assert res.organizer_count == 1
777 assert res.subscriber_count == 3
778 assert res.owner_user_id == user1.id
779 assert not res.owner_community_id
780 assert not res.owner_group_id
781 assert res.thread.thread_id
782 assert not res.can_edit
783 assert res.can_moderate
785 with events_session(token3) as api:
786 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
788 assert res.is_next
789 assert res.title == "Dummy Title"
790 assert res.slug == "dummy-title"
791 assert res.content == "Dummy content."
792 assert not res.photo_url
793 assert res.WhichOneof("mode") == "offline_information"
794 assert res.offline_information.lat == 0.1
795 assert res.offline_information.lng == 0.2
796 assert res.offline_information.address == "Near Null Island"
797 assert time_before <= to_aware_datetime(res.created) <= time_before_update
798 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
799 assert res.creator_user_id == user1.id
800 assert to_aware_datetime(res.start_time) == start_time
801 assert to_aware_datetime(res.end_time) == end_time
802 # assert res.timezone == "UTC"
803 assert res.start_time_display
804 assert res.end_time_display
805 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
806 assert not res.organizer
807 assert not res.subscriber
808 assert res.going_count == 2
809 assert res.maybe_count == 1
810 assert res.organizer_count == 1
811 assert res.subscriber_count == 3
812 assert res.owner_user_id == user1.id
813 assert not res.owner_community_id
814 assert not res.owner_group_id
815 assert res.thread.thread_id
816 assert not res.can_edit
817 assert not res.can_moderate
819 with events_session(token1) as api:
820 res = api.UpdateEvent(
821 events_pb2.UpdateEventReq(
822 event_id=event_id,
823 title=wrappers_pb2.StringValue(value="Dummy Title"),
824 content=wrappers_pb2.StringValue(value="Dummy content."),
825 online_information=events_pb2.OnlineEventInformation(link="https://couchers.org/meet/"),
826 start_time=Timestamp_from_datetime(start_time),
827 end_time=Timestamp_from_datetime(end_time),
828 timezone=wrappers_pb2.StringValue(value="UTC"),
829 )
830 )
832 assert res.is_next
833 assert res.title == "Dummy Title"
834 assert res.slug == "dummy-title"
835 assert res.content == "Dummy content."
836 assert not res.photo_url
837 assert res.WhichOneof("mode") == "online_information"
838 assert res.online_information.link == "https://couchers.org/meet/"
839 assert time_before <= to_aware_datetime(res.created) <= time_before_update
840 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
841 assert res.creator_user_id == user1.id
842 assert to_aware_datetime(res.start_time) == start_time
843 assert to_aware_datetime(res.end_time) == end_time
844 # assert res.timezone == "UTC"
845 assert res.start_time_display
846 assert res.end_time_display
847 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
848 assert res.organizer
849 assert res.subscriber
850 assert res.going_count == 2
851 assert res.maybe_count == 1
852 assert res.organizer_count == 1
853 assert res.subscriber_count == 3
854 assert res.owner_user_id == user1.id
855 assert not res.owner_community_id
856 assert not res.owner_group_id
857 assert res.thread.thread_id
858 assert res.can_edit
859 assert not res.can_moderate
861 event_id = res.event_id
863 with events_session(token2) as api:
864 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
866 assert res.is_next
867 assert res.title == "Dummy Title"
868 assert res.slug == "dummy-title"
869 assert res.content == "Dummy content."
870 assert not res.photo_url
871 assert res.WhichOneof("mode") == "online_information"
872 assert res.online_information.link == "https://couchers.org/meet/"
873 assert time_before <= to_aware_datetime(res.created) <= time_before_update
874 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
875 assert res.creator_user_id == user1.id
876 assert to_aware_datetime(res.start_time) == start_time
877 assert to_aware_datetime(res.end_time) == end_time
878 # assert res.timezone == "UTC"
879 assert res.start_time_display
880 assert res.end_time_display
881 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
882 assert not res.organizer
883 assert not res.subscriber
884 assert res.going_count == 2
885 assert res.maybe_count == 1
886 assert res.organizer_count == 1
887 assert res.subscriber_count == 3
888 assert res.owner_user_id == user1.id
889 assert not res.owner_community_id
890 assert not res.owner_group_id
891 assert res.thread.thread_id
892 assert not res.can_edit
893 assert res.can_moderate
895 with events_session(token3) as api:
896 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
898 assert res.is_next
899 assert res.title == "Dummy Title"
900 assert res.slug == "dummy-title"
901 assert res.content == "Dummy content."
902 assert not res.photo_url
903 assert res.WhichOneof("mode") == "online_information"
904 assert res.online_information.link == "https://couchers.org/meet/"
905 assert time_before <= to_aware_datetime(res.created) <= time_before_update
906 assert time_before_update <= to_aware_datetime(res.last_edited) <= now()
907 assert res.creator_user_id == user1.id
908 assert to_aware_datetime(res.start_time) == start_time
909 assert to_aware_datetime(res.end_time) == end_time
910 # assert res.timezone == "UTC"
911 assert res.start_time_display
912 assert res.end_time_display
913 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
914 assert not res.organizer
915 assert not res.subscriber
916 assert res.going_count == 2
917 assert res.maybe_count == 1
918 assert res.organizer_count == 1
919 assert res.subscriber_count == 3
920 assert res.owner_user_id == user1.id
921 assert not res.owner_community_id
922 assert not res.owner_group_id
923 assert res.thread.thread_id
924 assert not res.can_edit
925 assert not res.can_moderate
927 with events_session(token1) as api:
928 res = api.UpdateEvent(
929 events_pb2.UpdateEventReq(
930 event_id=event_id,
931 offline_information=events_pb2.OfflineEventInformation(
932 address="Near Null Island",
933 lat=0.1,
934 lng=0.2,
935 ),
936 )
937 )
939 with events_session(token3) as api:
940 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
942 assert res.WhichOneof("mode") == "offline_information"
943 assert res.offline_information.address == "Near Null Island"
944 assert res.offline_information.lat == 0.1
945 assert res.offline_information.lng == 0.2
948def test_UpdateEvent_all(db):
949 # event creator
950 user1, token1 = generate_user()
951 # community moderator
952 user2, token2 = generate_user()
953 # third parties
954 user3, token3 = generate_user()
955 user4, token4 = generate_user()
956 user5, token5 = generate_user()
957 user6, token6 = generate_user()
959 with session_scope() as session:
960 c_id = create_community(session, 0, 2, "Community", [user2], [], None).id
962 time_before = now()
963 start_time = now() + timedelta(hours=1)
964 end_time = start_time + timedelta(hours=1.5)
966 event_ids = []
968 with events_session(token1) as api:
969 res = api.CreateEvent(
970 events_pb2.CreateEventReq(
971 title="Dummy Title",
972 content="0th occurrence",
973 offline_information=events_pb2.OfflineEventInformation(
974 address="Near Null Island",
975 lat=0.1,
976 lng=0.2,
977 ),
978 start_time=Timestamp_from_datetime(start_time),
979 end_time=Timestamp_from_datetime(end_time),
980 timezone="UTC",
981 )
982 )
984 event_id = res.event_id
985 event_ids.append(event_id)
987 with events_session(token4) as api:
988 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
990 with events_session(token5) as api:
991 api.SetEventAttendance(
992 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
993 )
995 with events_session(token6) as api:
996 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
997 api.SetEventAttendance(
998 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_MAYBE)
999 )
1001 with events_session(token1) as api:
1002 for i in range(5):
1003 res = api.ScheduleEvent(
1004 events_pb2.ScheduleEventReq(
1005 event_id=event_ids[-1],
1006 content=f"{i+1}th occurrence",
1007 online_information=events_pb2.OnlineEventInformation(
1008 link="https://couchers.org/meet/",
1009 ),
1010 start_time=Timestamp_from_datetime(start_time + timedelta(hours=2 + i)),
1011 end_time=Timestamp_from_datetime(start_time + timedelta(hours=2.5 + i)),
1012 timezone="UTC",
1013 )
1014 )
1016 event_ids.append(res.event_id)
1018 updated_event_id = event_ids[3]
1020 time_before_update = now()
1022 with events_session(token1) as api:
1023 res = api.UpdateEvent(
1024 events_pb2.UpdateEventReq(
1025 event_id=updated_event_id,
1026 title=wrappers_pb2.StringValue(value="New Title"),
1027 content=wrappers_pb2.StringValue(value="New content."),
1028 online_information=events_pb2.OnlineEventInformation(link="https://couchers.org/meet/"),
1029 update_all_future=True,
1030 )
1031 )
1033 time_after_update = now()
1035 with events_session(token2) as api:
1036 for i in range(3):
1037 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_ids[i]))
1038 assert res.content == f"{i}th occurrence"
1039 assert time_before <= to_aware_datetime(res.last_edited) <= time_before_update
1041 for i in range(3, 6):
1042 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_ids[i]))
1043 assert res.content == "New content."
1044 assert time_before_update <= to_aware_datetime(res.last_edited) <= time_after_update
1047def test_GetEvent(db):
1048 # event creator
1049 user1, token1 = generate_user()
1050 # community moderator
1051 user2, token2 = generate_user()
1052 # third parties
1053 user3, token3 = generate_user()
1054 user4, token4 = generate_user()
1055 user5, token5 = generate_user()
1056 user6, token6 = generate_user()
1058 with session_scope() as session:
1059 c_id = create_community(session, 0, 2, "Community", [user2], [], None).id
1061 time_before = now()
1062 start_time = now() + timedelta(hours=2)
1063 end_time = start_time + timedelta(hours=3)
1065 with events_session(token1) as api:
1066 # in person event
1067 res = api.CreateEvent(
1068 events_pb2.CreateEventReq(
1069 title="Dummy Title",
1070 content="Dummy content.",
1071 offline_information=events_pb2.OfflineEventInformation(
1072 address="Near Null Island",
1073 lat=0.1,
1074 lng=0.2,
1075 ),
1076 start_time=Timestamp_from_datetime(start_time),
1077 end_time=Timestamp_from_datetime(end_time),
1078 timezone="UTC",
1079 )
1080 )
1082 event_id = res.event_id
1084 with events_session(token4) as api:
1085 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
1087 with events_session(token5) as api:
1088 api.SetEventAttendance(
1089 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
1090 )
1092 with events_session(token6) as api:
1093 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
1094 api.SetEventAttendance(
1095 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_MAYBE)
1096 )
1098 with events_session(token1) as api:
1099 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
1101 assert res.is_next
1102 assert res.title == "Dummy Title"
1103 assert res.slug == "dummy-title"
1104 assert res.content == "Dummy content."
1105 assert not res.photo_url
1106 assert res.WhichOneof("mode") == "offline_information"
1107 assert res.offline_information.lat == 0.1
1108 assert res.offline_information.lng == 0.2
1109 assert res.offline_information.address == "Near Null Island"
1110 assert time_before <= to_aware_datetime(res.created) <= now()
1111 assert time_before <= to_aware_datetime(res.last_edited) <= now()
1112 assert res.creator_user_id == user1.id
1113 assert to_aware_datetime(res.start_time) == start_time
1114 assert to_aware_datetime(res.end_time) == end_time
1115 # assert res.timezone == "UTC"
1116 assert res.start_time_display
1117 assert res.end_time_display
1118 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_GOING
1119 assert res.organizer
1120 assert res.subscriber
1121 assert res.going_count == 2
1122 assert res.maybe_count == 1
1123 assert res.organizer_count == 1
1124 assert res.subscriber_count == 3
1125 assert res.owner_user_id == user1.id
1126 assert not res.owner_community_id
1127 assert not res.owner_group_id
1128 assert res.thread.thread_id
1129 assert res.can_edit
1130 assert not res.can_moderate
1132 with events_session(token2) as api:
1133 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
1135 assert res.is_next
1136 assert res.title == "Dummy Title"
1137 assert res.slug == "dummy-title"
1138 assert res.content == "Dummy content."
1139 assert not res.photo_url
1140 assert res.WhichOneof("mode") == "offline_information"
1141 assert res.offline_information.lat == 0.1
1142 assert res.offline_information.lng == 0.2
1143 assert res.offline_information.address == "Near Null Island"
1144 assert time_before <= to_aware_datetime(res.created) <= now()
1145 assert time_before <= to_aware_datetime(res.last_edited) <= now()
1146 assert res.creator_user_id == user1.id
1147 assert to_aware_datetime(res.start_time) == start_time
1148 assert to_aware_datetime(res.end_time) == end_time
1149 # assert res.timezone == "UTC"
1150 assert res.start_time_display
1151 assert res.end_time_display
1152 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
1153 assert not res.organizer
1154 assert not res.subscriber
1155 assert res.going_count == 2
1156 assert res.maybe_count == 1
1157 assert res.organizer_count == 1
1158 assert res.subscriber_count == 3
1159 assert res.owner_user_id == user1.id
1160 assert not res.owner_community_id
1161 assert not res.owner_group_id
1162 assert res.thread.thread_id
1163 assert not res.can_edit
1164 assert res.can_moderate
1166 with events_session(token3) as api:
1167 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
1169 assert res.is_next
1170 assert res.title == "Dummy Title"
1171 assert res.slug == "dummy-title"
1172 assert res.content == "Dummy content."
1173 assert not res.photo_url
1174 assert res.WhichOneof("mode") == "offline_information"
1175 assert res.offline_information.lat == 0.1
1176 assert res.offline_information.lng == 0.2
1177 assert res.offline_information.address == "Near Null Island"
1178 assert time_before <= to_aware_datetime(res.created) <= now()
1179 assert time_before <= to_aware_datetime(res.last_edited) <= now()
1180 assert res.creator_user_id == user1.id
1181 assert to_aware_datetime(res.start_time) == start_time
1182 assert to_aware_datetime(res.end_time) == end_time
1183 # assert res.timezone == "UTC"
1184 assert res.start_time_display
1185 assert res.end_time_display
1186 assert res.attendance_state == events_pb2.ATTENDANCE_STATE_NOT_GOING
1187 assert not res.organizer
1188 assert not res.subscriber
1189 assert res.going_count == 2
1190 assert res.maybe_count == 1
1191 assert res.organizer_count == 1
1192 assert res.subscriber_count == 3
1193 assert res.owner_user_id == user1.id
1194 assert not res.owner_community_id
1195 assert not res.owner_group_id
1196 assert res.thread.thread_id
1197 assert not res.can_edit
1198 assert not res.can_moderate
1201def test_ListEventAttendees(db):
1202 # event creator
1203 user1, token1 = generate_user()
1204 # others
1205 user2, token2 = generate_user()
1206 user3, token3 = generate_user()
1207 user4, token4 = generate_user()
1208 user5, token5 = generate_user()
1209 user6, token6 = generate_user()
1211 with session_scope() as session:
1212 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1214 with events_session(token1) as api:
1215 event_id = api.CreateEvent(
1216 events_pb2.CreateEventReq(
1217 title="Dummy Title",
1218 content="Dummy content.",
1219 offline_information=events_pb2.OfflineEventInformation(
1220 address="Near Null Island",
1221 lat=0.1,
1222 lng=0.2,
1223 ),
1224 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1225 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1226 timezone="UTC",
1227 )
1228 ).event_id
1230 for token in [token2, token3, token4, token5]:
1231 with events_session(token) as api:
1232 api.SetEventAttendance(
1233 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
1234 )
1236 with events_session(token6) as api:
1237 assert api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).going_count == 5
1239 res = api.ListEventAttendees(events_pb2.ListEventAttendeesReq(event_id=event_id, page_size=2))
1240 assert res.attendee_user_ids == [user1.id, user2.id]
1242 res = api.ListEventAttendees(
1243 events_pb2.ListEventAttendeesReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1244 )
1245 assert res.attendee_user_ids == [user3.id, user4.id]
1247 res = api.ListEventAttendees(
1248 events_pb2.ListEventAttendeesReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1249 )
1250 assert res.attendee_user_ids == [user5.id]
1251 assert not res.next_page_token
1254def test_ListEventSubscribers(db):
1255 # event creator
1256 user1, token1 = generate_user()
1257 # others
1258 user2, token2 = generate_user()
1259 user3, token3 = generate_user()
1260 user4, token4 = generate_user()
1261 user5, token5 = generate_user()
1262 user6, token6 = generate_user()
1264 with session_scope() as session:
1265 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1267 with events_session(token1) as api:
1268 event_id = api.CreateEvent(
1269 events_pb2.CreateEventReq(
1270 title="Dummy Title",
1271 content="Dummy content.",
1272 offline_information=events_pb2.OfflineEventInformation(
1273 address="Near Null Island",
1274 lat=0.1,
1275 lng=0.2,
1276 ),
1277 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1278 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1279 timezone="UTC",
1280 )
1281 ).event_id
1283 for token in [token2, token3, token4, token5]:
1284 with events_session(token) as api:
1285 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
1287 with events_session(token6) as api:
1288 assert api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).subscriber_count == 5
1290 res = api.ListEventSubscribers(events_pb2.ListEventSubscribersReq(event_id=event_id, page_size=2))
1291 assert res.subscriber_user_ids == [user1.id, user2.id]
1293 res = api.ListEventSubscribers(
1294 events_pb2.ListEventSubscribersReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1295 )
1296 assert res.subscriber_user_ids == [user3.id, user4.id]
1298 res = api.ListEventSubscribers(
1299 events_pb2.ListEventSubscribersReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1300 )
1301 assert res.subscriber_user_ids == [user5.id]
1302 assert not res.next_page_token
1305def test_ListEventOrganizers(db):
1306 # event creator
1307 user1, token1 = generate_user()
1308 # others
1309 user2, token2 = generate_user()
1310 user3, token3 = generate_user()
1311 user4, token4 = generate_user()
1312 user5, token5 = generate_user()
1313 user6, token6 = generate_user()
1315 with session_scope() as session:
1316 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1318 with events_session(token1) as api:
1319 event_id = api.CreateEvent(
1320 events_pb2.CreateEventReq(
1321 title="Dummy Title",
1322 content="Dummy content.",
1323 offline_information=events_pb2.OfflineEventInformation(
1324 address="Near Null Island",
1325 lat=0.1,
1326 lng=0.2,
1327 ),
1328 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1329 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1330 timezone="UTC",
1331 )
1332 ).event_id
1334 with events_session(token1) as api:
1335 for user_id in [user2.id, user3.id, user4.id, user5.id]:
1336 api.InviteEventOrganizer(events_pb2.InviteEventOrganizerReq(event_id=event_id, user_id=user_id))
1338 with events_session(token6) as api:
1339 assert api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer_count == 5
1341 res = api.ListEventOrganizers(events_pb2.ListEventOrganizersReq(event_id=event_id, page_size=2))
1342 assert res.organizer_user_ids == [user1.id, user2.id]
1344 res = api.ListEventOrganizers(
1345 events_pb2.ListEventOrganizersReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1346 )
1347 assert res.organizer_user_ids == [user3.id, user4.id]
1349 res = api.ListEventOrganizers(
1350 events_pb2.ListEventOrganizersReq(event_id=event_id, page_size=2, page_token=res.next_page_token)
1351 )
1352 assert res.organizer_user_ids == [user5.id]
1353 assert not res.next_page_token
1356def test_TransferEvent(db):
1357 user1, token1 = generate_user()
1358 user2, token2 = generate_user()
1359 user3, token3 = generate_user()
1360 user4, token4 = generate_user()
1362 with session_scope() as session:
1363 c = create_community(session, 0, 2, "Community", [user3], [], None)
1364 h = create_group(session, "Group", [user4], [], c)
1365 c_id = c.id
1366 h_id = h.id
1368 with events_session(token1) as api:
1369 event_id = api.CreateEvent(
1370 events_pb2.CreateEventReq(
1371 title="Dummy Title",
1372 content="Dummy content.",
1373 offline_information=events_pb2.OfflineEventInformation(
1374 address="Near Null Island",
1375 lat=0.1,
1376 lng=0.2,
1377 ),
1378 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1379 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1380 timezone="UTC",
1381 )
1382 ).event_id
1384 api.TransferEvent(
1385 events_pb2.TransferEventReq(
1386 event_id=event_id,
1387 new_owner_community_id=c_id,
1388 )
1389 )
1391 with pytest.raises(grpc.RpcError) as e:
1392 api.TransferEvent(
1393 events_pb2.TransferEventReq(
1394 event_id=event_id,
1395 new_owner_group_id=h_id,
1396 )
1397 )
1398 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
1399 assert e.value.details() == errors.EVENT_TRANSFER_PERMISSION_DENIED
1401 event_id = api.CreateEvent(
1402 events_pb2.CreateEventReq(
1403 title="Dummy Title",
1404 content="Dummy content.",
1405 offline_information=events_pb2.OfflineEventInformation(
1406 address="Near Null Island",
1407 lat=0.1,
1408 lng=0.2,
1409 ),
1410 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1411 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1412 timezone="UTC",
1413 )
1414 ).event_id
1416 api.TransferEvent(
1417 events_pb2.TransferEventReq(
1418 event_id=event_id,
1419 new_owner_group_id=h_id,
1420 )
1421 )
1423 with pytest.raises(grpc.RpcError) as e:
1424 api.TransferEvent(
1425 events_pb2.TransferEventReq(
1426 event_id=event_id,
1427 new_owner_community_id=c_id,
1428 )
1429 )
1430 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
1431 assert e.value.details() == errors.EVENT_TRANSFER_PERMISSION_DENIED
1434def test_SetEventSubscription(db):
1435 user1, token1 = generate_user()
1436 user2, token2 = generate_user()
1438 with session_scope() as session:
1439 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1441 with events_session(token1) as api:
1442 event_id = api.CreateEvent(
1443 events_pb2.CreateEventReq(
1444 title="Dummy Title",
1445 content="Dummy content.",
1446 offline_information=events_pb2.OfflineEventInformation(
1447 address="Near Null Island",
1448 lat=0.1,
1449 lng=0.2,
1450 ),
1451 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1452 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1453 timezone="UTC",
1454 )
1455 ).event_id
1457 with events_session(token2) as api:
1458 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).subscriber
1459 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=True))
1460 assert api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).subscriber
1461 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=event_id, subscribe=False))
1462 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).subscriber
1465def test_SetEventAttendance(db):
1466 user1, token1 = generate_user()
1467 user2, token2 = generate_user()
1469 with session_scope() as session:
1470 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1472 with events_session(token1) as api:
1473 event_id = api.CreateEvent(
1474 events_pb2.CreateEventReq(
1475 title="Dummy Title",
1476 content="Dummy content.",
1477 offline_information=events_pb2.OfflineEventInformation(
1478 address="Near Null Island",
1479 lat=0.1,
1480 lng=0.2,
1481 ),
1482 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1483 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1484 timezone="UTC",
1485 )
1486 ).event_id
1488 with events_session(token2) as api:
1489 assert (
1490 api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).attendance_state
1491 == events_pb2.ATTENDANCE_STATE_NOT_GOING
1492 )
1493 api.SetEventAttendance(
1494 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
1495 )
1496 assert (
1497 api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).attendance_state
1498 == events_pb2.ATTENDANCE_STATE_GOING
1499 )
1500 api.SetEventAttendance(
1501 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_MAYBE)
1502 )
1503 assert (
1504 api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).attendance_state
1505 == events_pb2.ATTENDANCE_STATE_MAYBE
1506 )
1507 api.SetEventAttendance(
1508 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_NOT_GOING)
1509 )
1510 assert (
1511 api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).attendance_state
1512 == events_pb2.ATTENDANCE_STATE_NOT_GOING
1513 )
1516def test_InviteEventOrganizer(db):
1517 user1, token1 = generate_user()
1518 user2, token2 = generate_user()
1520 with session_scope() as session:
1521 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1523 with events_session(token1) as api:
1524 event_id = api.CreateEvent(
1525 events_pb2.CreateEventReq(
1526 title="Dummy Title",
1527 content="Dummy content.",
1528 offline_information=events_pb2.OfflineEventInformation(
1529 address="Near Null Island",
1530 lat=0.1,
1531 lng=0.2,
1532 ),
1533 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1534 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1535 timezone="UTC",
1536 )
1537 ).event_id
1539 with events_session(token2) as api:
1540 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1542 with pytest.raises(grpc.RpcError) as e:
1543 api.InviteEventOrganizer(events_pb2.InviteEventOrganizerReq(event_id=event_id, user_id=user1.id))
1544 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
1545 assert e.value.details() == errors.EVENT_EDIT_PERMISSION_DENIED
1547 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1549 with events_session(token1) as api:
1550 api.InviteEventOrganizer(events_pb2.InviteEventOrganizerReq(event_id=event_id, user_id=user2.id))
1552 with events_session(token2) as api:
1553 assert api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1556def test_ListEventOccurrences(db):
1557 user1, token1 = generate_user()
1558 user2, token2 = generate_user()
1559 user3, token3 = generate_user()
1561 with session_scope() as session:
1562 c_id = create_community(session, 0, 2, "Community", [user2], [], None).id
1564 time_before = now()
1565 start = now()
1567 event_ids = []
1569 with events_session(token1) as api:
1570 res = api.CreateEvent(
1571 events_pb2.CreateEventReq(
1572 title="First occurrence",
1573 content="Dummy content.",
1574 parent_community_id=c_id,
1575 online_information=events_pb2.OnlineEventInformation(
1576 link="https://couchers.org/meet/",
1577 ),
1578 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
1579 end_time=Timestamp_from_datetime(start + timedelta(hours=1.5)),
1580 timezone="UTC",
1581 )
1582 )
1584 event_ids.append(res.event_id)
1586 for i in range(5):
1587 res = api.ScheduleEvent(
1588 events_pb2.ScheduleEventReq(
1589 event_id=event_ids[-1],
1590 content=f"{i}th occurrence",
1591 online_information=events_pb2.OnlineEventInformation(
1592 link="https://couchers.org/meet/",
1593 ),
1594 start_time=Timestamp_from_datetime(start + timedelta(hours=2 + i)),
1595 end_time=Timestamp_from_datetime(start + timedelta(hours=2.5 + i)),
1596 timezone="UTC",
1597 )
1598 )
1600 event_ids.append(res.event_id)
1602 res = api.ListEventOccurrences(events_pb2.ListEventOccurrencesReq(event_id=event_ids[-1], page_size=2))
1603 assert [event.event_id for event in res.events] == event_ids[:2]
1605 res = api.ListEventOccurrences(
1606 events_pb2.ListEventOccurrencesReq(event_id=event_ids[-1], page_size=2, page_token=res.next_page_token)
1607 )
1608 assert [event.event_id for event in res.events] == event_ids[2:4]
1610 res = api.ListEventOccurrences(
1611 events_pb2.ListEventOccurrencesReq(event_id=event_ids[-1], page_size=2, page_token=res.next_page_token)
1612 )
1613 assert [event.event_id for event in res.events] == event_ids[4:6]
1614 assert not res.next_page_token
1617def test_ListMyEvents(db):
1618 user1, token1 = generate_user()
1619 user2, token2 = generate_user()
1620 user3, token3 = generate_user()
1621 user4, token4 = generate_user()
1622 user5, token5 = generate_user()
1624 with session_scope() as session:
1625 c_id = create_community(session, 0, 2, "Community", [user3], [], None).id
1626 c2_id = create_community(session, 0, 2, "Community", [user4], [], None).id
1628 start = now()
1630 def new_event(hours_from_now, community_id, online=True):
1631 if online:
1632 return events_pb2.CreateEventReq(
1633 title="Dummy Online Title",
1634 content="Dummy content.",
1635 online_information=events_pb2.OnlineEventInformation(
1636 link="https://couchers.org/meet/",
1637 ),
1638 parent_community_id=community_id,
1639 timezone="UTC",
1640 start_time=Timestamp_from_datetime(start + timedelta(hours=hours_from_now)),
1641 end_time=Timestamp_from_datetime(start + timedelta(hours=hours_from_now + 0.5)),
1642 )
1643 else:
1644 return events_pb2.CreateEventReq(
1645 title="Dummy Offline Title",
1646 content="Dummy content.",
1647 offline_information=events_pb2.OfflineEventInformation(
1648 address="Near Null Island",
1649 lat=0.1,
1650 lng=0.2,
1651 ),
1652 timezone="UTC",
1653 start_time=Timestamp_from_datetime(start + timedelta(hours=hours_from_now)),
1654 end_time=Timestamp_from_datetime(start + timedelta(hours=hours_from_now + 0.5)),
1655 )
1657 with events_session(token1) as api:
1658 e2 = api.CreateEvent(new_event(2, c_id, True)).event_id
1660 with events_session(token2) as api:
1661 e1 = api.CreateEvent(new_event(1, c_id, False)).event_id
1663 with events_session(token1) as api:
1664 e3 = api.CreateEvent(new_event(3, c_id, False)).event_id
1666 with events_session(token2) as api:
1667 e5 = api.CreateEvent(new_event(5, c_id, True)).event_id
1669 with events_session(token3) as api:
1670 e4 = api.CreateEvent(new_event(4, c_id, True)).event_id
1672 with events_session(token4) as api:
1673 e6 = api.CreateEvent((new_event(6, c2_id, True))).event_id
1675 with events_session(token1) as api:
1676 api.InviteEventOrganizer(events_pb2.InviteEventOrganizerReq(event_id=e3, user_id=user3.id))
1678 with events_session(token1) as api:
1679 api.SetEventAttendance(
1680 events_pb2.SetEventAttendanceReq(event_id=e1, attendance_state=events_pb2.ATTENDANCE_STATE_MAYBE)
1681 )
1682 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=e4, subscribe=True))
1684 with events_session(token2) as api:
1685 api.SetEventAttendance(
1686 events_pb2.SetEventAttendanceReq(event_id=e3, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
1687 )
1689 with events_session(token3) as api:
1690 api.SetEventSubscription(events_pb2.SetEventSubscriptionReq(event_id=e2, subscribe=True))
1692 with events_session(token1) as api:
1693 # test pagination first
1694 res = api.ListMyEvents(events_pb2.ListMyEventsReq(page_size=2))
1695 assert [event.event_id for event in res.events] == [e1, e2]
1696 res = api.ListMyEvents(events_pb2.ListMyEventsReq(page_size=2, page_token=res.next_page_token))
1697 assert [event.event_id for event in res.events] == [e3, e4]
1698 assert not res.next_page_token
1700 res = api.ListMyEvents(
1701 events_pb2.ListMyEventsReq(
1702 subscribed=True,
1703 attending=True,
1704 organizing=True,
1705 )
1706 )
1707 assert [event.event_id for event in res.events] == [e1, e2, e3, e4]
1709 res = api.ListMyEvents(events_pb2.ListMyEventsReq())
1710 assert [event.event_id for event in res.events] == [e1, e2, e3, e4]
1712 res = api.ListMyEvents(events_pb2.ListMyEventsReq(subscribed=True))
1713 assert [event.event_id for event in res.events] == [e2, e3, e4]
1715 res = api.ListMyEvents(events_pb2.ListMyEventsReq(attending=True))
1716 assert [event.event_id for event in res.events] == [e1, e2, e3]
1718 res = api.ListMyEvents(events_pb2.ListMyEventsReq(organizing=True))
1719 assert [event.event_id for event in res.events] == [e2, e3]
1721 with events_session(token2) as api:
1722 res = api.ListMyEvents(events_pb2.ListMyEventsReq())
1723 assert [event.event_id for event in res.events] == [e1, e3, e5]
1725 res = api.ListMyEvents(events_pb2.ListMyEventsReq(subscribed=True))
1726 assert [event.event_id for event in res.events] == [e1, e5]
1728 res = api.ListMyEvents(events_pb2.ListMyEventsReq(attending=True))
1729 assert [event.event_id for event in res.events] == [e1, e3, e5]
1731 res = api.ListMyEvents(events_pb2.ListMyEventsReq(organizing=True))
1732 assert [event.event_id for event in res.events] == [e1, e5]
1734 with events_session(token3) as api:
1735 res = api.ListMyEvents(events_pb2.ListMyEventsReq())
1736 assert [event.event_id for event in res.events] == [e1, e2, e3, e4, e5]
1738 res = api.ListMyEvents(events_pb2.ListMyEventsReq(subscribed=True))
1739 assert [event.event_id for event in res.events] == [e2, e4]
1741 res = api.ListMyEvents(events_pb2.ListMyEventsReq(attending=True))
1742 assert [event.event_id for event in res.events] == [e4]
1744 res = api.ListMyEvents(events_pb2.ListMyEventsReq(organizing=True))
1745 assert [event.event_id for event in res.events] == [e3, e4]
1747 res = api.ListMyEvents(events_pb2.ListMyEventsReq(my_communities=True))
1748 assert [event.event_id for event in res.events] == [e1, e2, e3, e4, e5]
1750 with events_session(token5) as api:
1751 res = api.ListAllEvents(events_pb2.ListAllEventsReq())
1752 assert [event.event_id for event in res.events] == [e1, e2, e3, e4, e5, e6]
1755def test_RemoveEventOrganizer(db):
1756 user1, token1 = generate_user()
1757 user2, token2 = generate_user()
1759 with session_scope() as session:
1760 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1762 with events_session(token1) as api:
1763 event_id = api.CreateEvent(
1764 events_pb2.CreateEventReq(
1765 title="Dummy Title",
1766 content="Dummy content.",
1767 offline_information=events_pb2.OfflineEventInformation(
1768 address="Near Null Island",
1769 lat=0.1,
1770 lng=0.2,
1771 ),
1772 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1773 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1774 timezone="UTC",
1775 )
1776 ).event_id
1778 with events_session(token2) as api:
1779 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1781 with pytest.raises(grpc.RpcError) as e:
1782 api.RemoveEventOrganizer(events_pb2.RemoveEventOrganizerReq(event_id=event_id))
1783 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1784 assert e.value.details() == errors.EVENT_NOT_AN_ORGANIZER
1786 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1788 with events_session(token1) as api:
1789 api.InviteEventOrganizer(events_pb2.InviteEventOrganizerReq(event_id=event_id, user_id=user2.id))
1791 with pytest.raises(grpc.RpcError) as e:
1792 api.RemoveEventOrganizer(events_pb2.RemoveEventOrganizerReq(event_id=event_id))
1793 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1794 assert e.value.details() == errors.EVENT_CANT_REMOVE_OWNER_AS_ORGANIZER
1796 with events_session(token2) as api:
1797 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
1798 assert res.organizer
1799 assert res.organizer_count == 2
1800 api.RemoveEventOrganizer(events_pb2.RemoveEventOrganizerReq(event_id=event_id))
1801 assert not api.GetEvent(events_pb2.GetEventReq(event_id=event_id)).organizer
1803 with pytest.raises(grpc.RpcError) as e:
1804 api.RemoveEventOrganizer(events_pb2.RemoveEventOrganizerReq(event_id=event_id))
1805 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1806 assert e.value.details() == errors.EVENT_NOT_AN_ORGANIZER
1808 res = api.GetEvent(events_pb2.GetEventReq(event_id=event_id))
1809 assert not res.organizer
1810 assert res.organizer_count == 1
1813def test_ListEventAttendees_regression(db):
1814 # see issue #1617:
1815 #
1816 # 1. Create an event
1817 # 2. Transfer the event to a community (although this step probably not necessarily, only needed for it to show up in UI/`ListEvents` from `communities.proto`
1818 # 3. Change the current user's attendance state to "not going" (with `SetEventAttendance`)
1819 # 4. Change the current user's attendance state to "going" again
1820 #
1821 # **Expected behaviour**
1822 # `ListEventAttendees` should return the current user's ID
1823 #
1824 # **Actual/current behaviour**
1825 # `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
1827 user1, token1 = generate_user()
1828 user2, token2 = generate_user()
1829 user3, token3 = generate_user()
1830 user4, token4 = generate_user()
1831 user5, token5 = generate_user()
1833 with session_scope() as session:
1834 c_id = create_community(session, 0, 2, "Community", [user1], [], None).id
1836 start_time = now() + timedelta(hours=2)
1837 end_time = start_time + timedelta(hours=3)
1839 with events_session(token1) as api:
1840 res = api.CreateEvent(
1841 events_pb2.CreateEventReq(
1842 title="Dummy Title",
1843 content="Dummy content.",
1844 online_information=events_pb2.OnlineEventInformation(
1845 link="https://couchers.org",
1846 ),
1847 parent_community_id=c_id,
1848 start_time=Timestamp_from_datetime(start_time),
1849 end_time=Timestamp_from_datetime(end_time),
1850 timezone="UTC",
1851 )
1852 )
1854 res = api.TransferEvent(
1855 events_pb2.TransferEventReq(
1856 event_id=res.event_id,
1857 new_owner_community_id=c_id,
1858 )
1859 )
1861 event_id = res.event_id
1863 api.SetEventAttendance(
1864 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_NOT_GOING)
1865 )
1866 api.SetEventAttendance(
1867 events_pb2.SetEventAttendanceReq(event_id=event_id, attendance_state=events_pb2.ATTENDANCE_STATE_GOING)
1868 )
1870 res = api.ListEventAttendees(events_pb2.ListEventAttendeesReq(event_id=event_id))
1871 assert len(res.attendee_user_ids) == 1
1872 assert res.attendee_user_ids[0] == user1.id
1875def test_event_threads(db):
1876 user1, token1 = generate_user()
1877 user2, token2 = generate_user()
1878 user3, token3 = generate_user()
1879 user4, token4 = generate_user()
1881 with session_scope() as session:
1882 c = create_community(session, 0, 2, "Community", [user3], [], None)
1883 h = create_group(session, "Group", [user4], [], c)
1884 c_id = c.id
1885 h_id = h.id
1887 with events_session(token1) as api:
1888 event = api.CreateEvent(
1889 events_pb2.CreateEventReq(
1890 title="Dummy Title",
1891 content="Dummy content.",
1892 offline_information=events_pb2.OfflineEventInformation(
1893 address="Near Null Island",
1894 lat=0.1,
1895 lng=0.2,
1896 ),
1897 start_time=Timestamp_from_datetime(now() + timedelta(hours=2)),
1898 end_time=Timestamp_from_datetime(now() + timedelta(hours=5)),
1899 timezone="UTC",
1900 )
1901 )
1903 with threads_session(token2) as api:
1904 reply_id = api.PostReply(threads_pb2.PostReplyReq(thread_id=event.thread.thread_id, content="hi")).thread_id
1906 with events_session(token3) as api:
1907 res = api.GetEvent(events_pb2.GetEventReq(event_id=event.event_id))
1908 assert res.thread.num_responses == 1
1910 with threads_session(token3) as api:
1911 ret = api.GetThread(threads_pb2.GetThreadReq(thread_id=res.thread.thread_id))
1912 assert len(ret.replies) == 1
1913 assert not ret.next_page_token
1914 assert ret.replies[0].thread_id == reply_id
1915 assert ret.replies[0].content == "hi"
1916 assert ret.replies[0].author_user_id == user2.id
1917 assert ret.replies[0].num_replies == 0
1920def test_can_overlap_other_events_schedule_regression(db):
1921 # we had a bug where we were checking overlapping for *all* occurrences of *all* events, not just the ones for this event
1922 user, token = generate_user()
1924 with session_scope() as session:
1925 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
1927 start = now()
1929 with events_session(token) as api:
1930 # create another event, should be able to overlap with this one
1931 api.CreateEvent(
1932 events_pb2.CreateEventReq(
1933 title="Dummy Title",
1934 content="Dummy content.",
1935 parent_community_id=c_id,
1936 online_information=events_pb2.OnlineEventInformation(
1937 link="https://couchers.org/meet/",
1938 ),
1939 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
1940 end_time=Timestamp_from_datetime(start + timedelta(hours=5)),
1941 timezone="UTC",
1942 )
1943 )
1945 # this event
1946 res = api.CreateEvent(
1947 events_pb2.CreateEventReq(
1948 title="Dummy Title",
1949 content="Dummy content.",
1950 parent_community_id=c_id,
1951 online_information=events_pb2.OnlineEventInformation(
1952 link="https://couchers.org/meet/",
1953 ),
1954 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
1955 end_time=Timestamp_from_datetime(start + timedelta(hours=2)),
1956 timezone="UTC",
1957 )
1958 )
1960 # this doesn't overlap with the just created event, but does overlap with the occurrence from earlier; which should be no problem
1961 api.ScheduleEvent(
1962 events_pb2.ScheduleEventReq(
1963 event_id=res.event_id,
1964 content="New event occurrence",
1965 offline_information=events_pb2.OfflineEventInformation(
1966 address="A bit further but still near Null Island",
1967 lat=0.3,
1968 lng=0.2,
1969 ),
1970 start_time=Timestamp_from_datetime(start + timedelta(hours=3)),
1971 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
1972 timezone="UTC",
1973 )
1974 )
1977def test_can_overlap_other_events_update_regression(db):
1978 user, token = generate_user()
1980 with session_scope() as session:
1981 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
1983 start = now()
1985 with events_session(token) as api:
1986 # create another event, should be able to overlap with this one
1987 api.CreateEvent(
1988 events_pb2.CreateEventReq(
1989 title="Dummy Title",
1990 content="Dummy content.",
1991 parent_community_id=c_id,
1992 online_information=events_pb2.OnlineEventInformation(
1993 link="https://couchers.org/meet/",
1994 ),
1995 start_time=Timestamp_from_datetime(start + timedelta(hours=1)),
1996 end_time=Timestamp_from_datetime(start + timedelta(hours=3)),
1997 timezone="UTC",
1998 )
1999 )
2001 res = api.CreateEvent(
2002 events_pb2.CreateEventReq(
2003 title="Dummy Title",
2004 content="Dummy content.",
2005 parent_community_id=c_id,
2006 online_information=events_pb2.OnlineEventInformation(
2007 link="https://couchers.org/meet/",
2008 ),
2009 start_time=Timestamp_from_datetime(start + timedelta(hours=7)),
2010 end_time=Timestamp_from_datetime(start + timedelta(hours=8)),
2011 timezone="UTC",
2012 )
2013 )
2015 event_id = api.ScheduleEvent(
2016 events_pb2.ScheduleEventReq(
2017 event_id=res.event_id,
2018 content="New event occurrence",
2019 offline_information=events_pb2.OfflineEventInformation(
2020 address="A bit further but still near Null Island",
2021 lat=0.3,
2022 lng=0.2,
2023 ),
2024 start_time=Timestamp_from_datetime(start + timedelta(hours=4)),
2025 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
2026 timezone="UTC",
2027 )
2028 ).event_id
2030 # can overlap with this current existing occurrence
2031 api.UpdateEvent(
2032 events_pb2.UpdateEventReq(
2033 event_id=event_id,
2034 start_time=Timestamp_from_datetime(start + timedelta(hours=5)),
2035 end_time=Timestamp_from_datetime(start + timedelta(hours=6)),
2036 )
2037 )
2039 api.UpdateEvent(
2040 events_pb2.UpdateEventReq(
2041 event_id=event_id,
2042 start_time=Timestamp_from_datetime(start + timedelta(hours=2)),
2043 end_time=Timestamp_from_datetime(start + timedelta(hours=4)),
2044 )
2045 )
2048def test_list_past_events_regression(db):
2049 # test for a bug where listing past events didn't work if they didn't have a future occurence
2050 user, token = generate_user()
2052 with session_scope() as session:
2053 c_id = create_community(session, 0, 2, "Community", [user], [], None).id
2055 start = now()
2057 with events_session(token) as api:
2058 api.CreateEvent(
2059 events_pb2.CreateEventReq(
2060 title="Dummy Title",
2061 content="Dummy content.",
2062 parent_community_id=c_id,
2063 online_information=events_pb2.OnlineEventInformation(
2064 link="https://couchers.org/meet/",
2065 ),
2066 start_time=Timestamp_from_datetime(start + timedelta(hours=3)),
2067 end_time=Timestamp_from_datetime(start + timedelta(hours=4)),
2068 timezone="UTC",
2069 )
2070 )
2072 with session_scope() as session:
2073 session.execute(
2074 update(EventOccurrence).values(
2075 during=DateTimeTZRange(start + timedelta(hours=-5), start + timedelta(hours=-4))
2076 )
2077 )
2079 with events_session(token) as api:
2080 res = api.ListAllEvents(events_pb2.ListAllEventsReq(past=True))
2081 assert len(res.events) == 1