Coverage for src/tests/test_conversations.py: 100%
943 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-06-23 04:49 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-06-23 04:49 +0000
1from datetime import timedelta
3import grpc
4import pytest
5from google.protobuf import wrappers_pb2
7from couchers import errors
8from couchers.db import session_scope
9from couchers.jobs.worker import process_job
10from couchers.models import (
11 GroupChatRole,
12 GroupChatSubscription,
13 Notification,
14 NotificationDelivery,
15 NotificationDeliveryType,
16 NotificationTopicAction,
17)
18from couchers.sql import couchers_select as select
19from couchers.utils import Duration_from_timedelta, now, to_aware_datetime
20from proto import api_pb2, conversations_pb2, notification_data_pb2, notifications_pb2
21from tests.test_fixtures import ( # noqa
22 api_session,
23 conversations_session,
24 db,
25 generate_user,
26 make_friends,
27 make_user_block,
28 make_user_invisible,
29 notifications_session,
30 testconfig,
31)
34@pytest.fixture(autouse=True)
35def _(testconfig):
36 pass
39def test_list_group_chats(db):
40 user1, token1 = generate_user()
41 user2, token2 = generate_user()
42 user3, token3 = generate_user()
44 make_friends(user2, user1)
45 make_friends(user1, user3)
47 with conversations_session(token1) as c:
48 # no threads initially
49 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
50 assert len(res.group_chats) == 0
52 # create some group chats with messages
53 res = c.CreateGroupChat(
54 conversations_pb2.CreateGroupChatReq(
55 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title")
56 )
57 )
58 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1"))
59 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2"))
60 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
61 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 1"))
62 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 2"))
64 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
65 assert len(res.group_chats) == 2
66 assert res.no_more
68 with conversations_session(token2) as c:
69 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
70 assert len(res.group_chats) == 2
71 assert res.no_more
73 with conversations_session(token3) as c:
74 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
75 assert len(res.group_chats) == 1
76 assert res.no_more
79def test_list_empty_group_chats(db):
80 user1, token1 = generate_user()
81 user2, token2 = generate_user()
82 user3, token3 = generate_user()
84 make_friends(user1, user3)
85 make_friends(user2, user1)
86 make_friends(user2, user3)
88 with conversations_session(token1) as c:
89 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
90 assert len(res.group_chats) == 0
92 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
93 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
95 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
96 assert len(res.group_chats) == 2
97 assert res.no_more
99 with conversations_session(token2) as c:
100 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
101 assert len(res.group_chats) == 2
102 assert res.no_more
104 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
106 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
107 assert len(res.group_chats) == 3
108 assert res.no_more
110 with conversations_session(token3) as c:
111 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
112 assert len(res.group_chats) == 2
113 assert res.no_more
116def test_list_group_chats_ordering(db):
117 # user is member of 5 group chats, order them correctly
118 user, token = generate_user()
119 user2, token2 = generate_user()
120 user3, token3 = generate_user()
121 user4, token4 = generate_user()
123 make_friends(user2, user)
124 make_friends(user2, user3)
125 make_friends(user2, user4)
126 make_friends(user3, user)
127 make_friends(user3, user4)
128 make_friends(user, user4)
130 with conversations_session(token2) as c:
131 res = c.CreateGroupChat(
132 conversations_pb2.CreateGroupChatReq(
133 recipient_user_ids=[user.id], title=wrappers_pb2.StringValue(value="Chat 0")
134 )
135 )
136 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
137 res = c.CreateGroupChat(
138 conversations_pb2.CreateGroupChatReq(
139 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 1")
140 )
141 )
142 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
143 res = c.CreateGroupChat(
144 conversations_pb2.CreateGroupChatReq(
145 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 2")
146 )
147 )
148 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
150 with conversations_session(token3) as c:
151 res = c.CreateGroupChat(
152 conversations_pb2.CreateGroupChatReq(
153 recipient_user_ids=[user.id, user2.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 3")
154 )
155 )
156 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
158 with conversations_session(token) as c:
159 res = c.CreateGroupChat(
160 conversations_pb2.CreateGroupChatReq(
161 recipient_user_ids=[user2.id, user3.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 4")
162 )
163 )
164 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
165 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
166 assert len(res.group_chats) == 5
167 assert res.group_chats[0].title == "Chat 4"
168 assert res.group_chats[1].title == "Chat 3"
169 assert res.group_chats[2].title == "Chat 2"
170 assert res.group_chats[3].title == "Chat 1"
171 assert res.group_chats[4].title == "Chat 0"
173 c.SendMessage(
174 conversations_pb2.SendMessageReq(group_chat_id=res.group_chats[3].group_chat_id, text="Test message 2a")
175 )
176 c.SendMessage(
177 conversations_pb2.SendMessageReq(group_chat_id=res.group_chats[2].group_chat_id, text="Test message 2b")
178 )
180 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
181 assert len(res.group_chats) == 5
182 assert res.group_chats[0].title == "Chat 2"
183 assert res.group_chats[0].latest_message.text.text == "Test message 2b"
184 assert res.group_chats[1].title == "Chat 1"
185 assert res.group_chats[1].latest_message.text.text == "Test message 2a"
186 assert res.group_chats[2].title == "Chat 4"
187 assert res.group_chats[3].title == "Chat 3"
188 assert res.group_chats[4].title == "Chat 0"
191def test_list_group_chats_ordering_after_left(db):
192 # user is member to 4 group chats, and has left one.
193 # The one user left has the most recent message, but user left before then,
194 # this should display as e.g. 3rd most recent depending on last message when they were in the chat
195 user, token = generate_user()
196 user2, token2 = generate_user()
197 user3, token3 = generate_user()
198 user4, token4 = generate_user()
200 make_friends(user2, user)
201 make_friends(user2, user3)
202 make_friends(user2, user4)
203 make_friends(user3, user)
204 make_friends(user3, user4)
205 make_friends(user, user4)
207 with conversations_session(token2) as c:
208 res = c.CreateGroupChat(
209 conversations_pb2.CreateGroupChatReq(
210 recipient_user_ids=[user.id], title=wrappers_pb2.StringValue(value="Chat 0")
211 )
212 )
213 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
214 res = c.CreateGroupChat(
215 conversations_pb2.CreateGroupChatReq(
216 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Left Chat 1")
217 )
218 )
219 left_chat_id = res.group_chat_id
220 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Test message"))
221 res = c.CreateGroupChat(
222 conversations_pb2.CreateGroupChatReq(
223 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 2")
224 )
225 )
226 chat2_id = res.group_chat_id
227 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=chat2_id, text="Test message"))
229 with conversations_session(token3) as c:
230 res = c.CreateGroupChat(
231 conversations_pb2.CreateGroupChatReq(
232 recipient_user_ids=[user.id, user2.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 3")
233 )
234 )
235 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
237 with conversations_session(token) as c:
238 res = c.CreateGroupChat(
239 conversations_pb2.CreateGroupChatReq(
240 recipient_user_ids=[user2.id, user3.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 4")
241 )
242 )
243 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message"))
245 # leave chat
246 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=left_chat_id))
248 with conversations_session(token3) as c:
249 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=chat2_id, text="Test message"))
250 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Test message"))
252 with conversations_session(token2) as c:
253 # other user sends a message to that chat
254 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Another test message"))
255 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
256 assert len(res.group_chats) == 5
257 assert res.group_chats[0].title == "Left Chat 1"
258 assert res.group_chats[1].title == "Chat 2"
259 assert res.group_chats[2].title == "Chat 4"
260 assert res.group_chats[3].title == "Chat 3"
261 assert res.group_chats[4].title == "Chat 0"
263 with conversations_session(token) as c:
264 # we can't see the new message since we left before it was sent
265 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
266 assert len(res.group_chats) == 5
267 assert res.group_chats[0].title == "Chat 2"
268 assert res.group_chats[1].title == "Left Chat 1"
269 assert res.group_chats[2].title == "Chat 4"
270 assert res.group_chats[3].title == "Chat 3"
271 assert res.group_chats[4].title == "Chat 0"
274def test_get_group_chat_messages(db):
275 user1, token1 = generate_user()
276 user2, token2 = generate_user()
277 user3, token3 = generate_user()
279 make_friends(user1, user2)
281 with conversations_session(token1) as c:
282 # create some threads with messages
283 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
284 group_chat_id = res.group_chat_id
285 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1"))
286 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2"))
288 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
289 # created + 2 normal
290 assert len(res.messages) == 3
291 assert res.no_more
293 assert res.messages[0].text.text == "Test message 2"
294 assert res.messages[1].text.text == "Test message 1"
295 assert res.messages[2].WhichOneof("content") == "chat_created"
297 # test that another user can't access the thread
298 with conversations_session(token3) as c:
299 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
300 assert len(res.messages) == 0
303def test_get_group_chat_messages_pagination(db):
304 user1, token1 = generate_user()
305 user2, token2 = generate_user()
306 make_friends(user1, user2)
308 with conversations_session(token1) as c:
309 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
310 group_chat_id = res.group_chat_id
311 for i in range(30):
312 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text=str(i)))
314 with conversations_session(token2) as c:
315 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
316 # pagination
317 assert len(res.messages) == 20
318 assert res.messages[0].text.text == "29"
319 assert res.messages[19].text.text == "10"
320 assert not res.no_more
321 res = c.GetGroupChatMessages(
322 conversations_pb2.GetGroupChatMessagesReq(
323 group_chat_id=group_chat_id, last_message_id=res.messages[19].message_id
324 )
325 )
326 assert len(res.messages) == 11
327 assert res.messages[0].text.text == "9"
328 assert res.messages[9].text.text == "0"
329 assert res.no_more
332def test_get_group_chat_messages_joined_left(db):
333 user1, token1 = generate_user()
334 user2, token2 = generate_user()
335 user3, token3 = generate_user()
336 user4, token4 = generate_user()
337 make_friends(user1, user2)
338 make_friends(user1, user3)
339 make_friends(user1, user4)
341 with conversations_session(token1) as c:
342 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id]))
343 group_chat_id = res.group_chat_id
345 for i in range(10):
346 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text=str(i)))
348 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
350 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="10"))
352 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
354 # created + 10 normal + invited + normal
355 assert len(res.messages) == 13
357 with conversations_session(token3) as c:
358 # can only see last message after invited
359 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
360 # joined + normal
361 assert len(res.messages) == 2
362 assert res.messages[0].text.text == "10"
364 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
366 with conversations_session(token1) as c:
367 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="11"))
368 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="12"))
370 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
372 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="13"))
373 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="14"))
375 with conversations_session(token3) as c:
376 # can only see last message after invited
377 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
378 # joined + normal + left + invite + 2 normal
379 assert len(res.messages) == 6
380 assert res.messages[0].text.text == "14"
381 assert res.messages[1].text.text == "13"
382 assert res.messages[2].WhichOneof("content") == "user_invited"
383 assert res.messages[3].WhichOneof("content") == "user_left"
384 assert res.messages[4].text.text == "10"
385 assert res.messages[5].WhichOneof("content") == "user_invited"
388def test_get_group_chat_info(db):
389 user1, token1 = generate_user()
390 user2, token2 = generate_user()
391 user3, token3 = generate_user()
393 make_friends(user1, user2)
394 make_friends(user3, user1)
396 with conversations_session(token1) as c:
397 # create some threads with messages
398 res = c.CreateGroupChat(
399 conversations_pb2.CreateGroupChatReq(
400 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title")
401 )
402 )
403 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1"))
404 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2"))
405 group_chat1_id = res.group_chat_id
406 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
407 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 1"))
408 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 2"))
409 group_chat2_id = res.group_chat_id
411 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat1_id))
412 assert res.title == "Test title"
413 assert user2.id in res.member_user_ids
414 assert user1.id in res.admin_user_ids
415 assert to_aware_datetime(res.created) <= now()
416 assert res.only_admins_invite
417 assert res.is_dm
419 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat2_id))
420 assert not res.title
421 assert user2.id in res.member_user_ids
422 assert user3.id in res.member_user_ids
423 assert user1.id in res.admin_user_ids
424 assert to_aware_datetime(res.created) <= now()
425 assert res.only_admins_invite
426 assert not res.is_dm
429def test_get_group_chat_info_denied(db):
430 user1, token1 = generate_user()
431 user2, token2 = generate_user()
432 user3, token3 = generate_user()
433 user4, token4 = generate_user()
435 make_friends(user1, user2)
436 make_friends(user3, user1)
438 with conversations_session(token1) as c:
439 # create a group chat with messages
440 res = c.CreateGroupChat(
441 conversations_pb2.CreateGroupChatReq(
442 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title")
443 )
444 )
445 group_chat_id = res.group_chat_id
446 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
448 with conversations_session(token4) as c:
449 with pytest.raises(grpc.RpcError) as e:
450 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
451 assert e.value.code() == grpc.StatusCode.NOT_FOUND
454def test_get_group_chat_info_left(db):
455 user1, token1 = generate_user()
456 user2, token2 = generate_user()
457 user3, token3 = generate_user()
458 user4, token4 = generate_user()
460 make_friends(user1, user2)
461 make_friends(user3, user1)
462 make_friends(user1, user4)
464 with conversations_session(token1) as c:
465 # create a group chat with messages
466 res = c.CreateGroupChat(
467 conversations_pb2.CreateGroupChatReq(
468 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title")
469 )
470 )
471 group_chat_id = res.group_chat_id
472 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
474 with conversations_session(token3) as c:
475 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
477 with conversations_session(token1) as c:
478 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user4.id))
480 with conversations_session(token3) as c:
481 # this user left when user4 wasn't a member,
482 # so the returned members should be user1, user2, and user3 only
483 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
484 assert len(res.member_user_ids) == 3
485 assert user1.id in res.member_user_ids
486 assert user2.id in res.member_user_ids
487 assert user3.id in res.member_user_ids
490def test_remove_group_chat_user(db):
491 # create 3 uses and connect them
492 user1, token1 = generate_user()
493 user2, token2 = generate_user()
494 user3, token3 = generate_user()
495 make_friends(user1, user2)
496 make_friends(user1, user3)
498 # using user token, create a Conversations API for testing
499 with conversations_session(token1) as c:
500 # create a group chat
501 res = c.CreateGroupChat(
502 conversations_pb2.CreateGroupChatReq(
503 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title")
504 )
505 )
506 group_chat_id = res.group_chat_id
508 # remove a user from group
509 c.RemoveGroupChatUser(conversations_pb2.RemoveGroupChatUserReq(group_chat_id=group_chat_id, user_id=user2.id))
510 assert user3.id in res.member_user_ids # other users are still in the group
512 # can't remove the same user twice
513 with pytest.raises(grpc.RpcError) as e:
514 c.RemoveGroupChatUser(
515 conversations_pb2.RemoveGroupChatUserReq(group_chat_id=group_chat_id, user_id=user2.id)
516 )
517 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
520def test_edit_group_chat(db):
521 user1, token1 = generate_user()
522 user2, token2 = generate_user()
523 user3, token3 = generate_user()
524 make_friends(user1, user2)
526 with conversations_session(token1) as c:
527 # create some threads with messages
528 res = c.CreateGroupChat(
529 conversations_pb2.CreateGroupChatReq(
530 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title")
531 )
532 )
533 group_chat_id = res.group_chat_id
535 c.EditGroupChat(
536 conversations_pb2.EditGroupChatReq(
537 group_chat_id=group_chat_id,
538 title=wrappers_pb2.StringValue(value="Modified title"),
539 only_admins_invite=wrappers_pb2.BoolValue(value=False),
540 )
541 )
542 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
543 assert res.title == "Modified title"
544 assert not res.only_admins_invite
546 # make sure non-admin is not allowed to modify
547 with conversations_session(token2) as c:
548 with pytest.raises(grpc.RpcError) as e:
549 c.EditGroupChat(
550 conversations_pb2.EditGroupChatReq(
551 group_chat_id=group_chat_id,
552 title=wrappers_pb2.StringValue(value="Other title"),
553 only_admins_invite=wrappers_pb2.BoolValue(value=True),
554 )
555 )
556 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
558 # make sure non-recipient is not allowed to modify
559 with conversations_session(token3) as c:
560 with pytest.raises(grpc.RpcError) as e:
561 c.EditGroupChat(
562 conversations_pb2.EditGroupChatReq(
563 group_chat_id=group_chat_id,
564 title=wrappers_pb2.StringValue(value="Other title"),
565 only_admins_invite=wrappers_pb2.BoolValue(value=True),
566 )
567 )
568 assert e.value.code() == grpc.StatusCode.NOT_FOUND
571def test_make_remove_group_chat_admin(db):
572 user1, token1 = generate_user()
573 user2, token2 = generate_user()
574 user3, token3 = generate_user()
576 make_friends(user1, user2)
577 make_friends(user1, user3)
578 make_friends(user2, user3)
580 with conversations_session(token1) as c:
581 # create some threads with messages
582 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
583 group_chat_id = res.group_chat_id
585 # shouldn't be able to remove only admin
586 with pytest.raises(grpc.RpcError) as e:
587 c.RemoveGroupChatAdmin(
588 conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user1.id)
589 )
590 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
591 assert e.value.details() == errors.CANT_REMOVE_LAST_ADMIN
593 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id))
595 # shouldn't be able to make admin again
596 with pytest.raises(grpc.RpcError) as e:
597 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id))
598 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
599 assert e.value.details() == errors.ALREADY_ADMIN
601 with conversations_session(token2) as c:
602 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
603 assert user1.id in res.admin_user_ids
604 assert user2.id in res.admin_user_ids
606 with conversations_session(token1) as c:
607 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id))
609 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
610 assert user1.id in res.admin_user_ids
611 assert user2.id not in res.admin_user_ids
613 with conversations_session(token2) as c:
614 # shouldn't be able to make admin if not admin
615 with pytest.raises(grpc.RpcError) as e:
616 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user3.id))
617 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
620def test_send_message(db):
621 user1, token1 = generate_user()
622 user2, token2 = generate_user()
623 user3, token3 = generate_user()
624 make_friends(user1, user2)
625 make_friends(user1, user3)
627 with conversations_session(token1) as c:
628 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
629 group_chat_id = res.group_chat_id
630 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
631 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
632 assert res.messages[0].text.text == "Test message 1"
633 assert to_aware_datetime(res.messages[0].time) <= now()
634 assert res.messages[0].author_user_id == user1.id
636 # can't send message if not in chat
637 with conversations_session(token3) as c:
638 with pytest.raises(grpc.RpcError) as e:
639 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 2"))
640 assert e.value.code() == grpc.StatusCode.NOT_FOUND
642 make_user_block(user2, user1)
643 with conversations_session(token1) as c:
644 with pytest.raises(grpc.RpcError) as e:
645 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Message after block"))
646 assert e.value.details() == errors.CANT_MESSAGE_IN_CHAT
649def test_leave_invite_to_group_chat(db):
650 user1, token1 = generate_user()
651 user2, token2 = generate_user()
652 user3, token3 = generate_user()
653 user4, token4 = generate_user()
654 user5, token5 = generate_user()
655 user6, token6 = generate_user(delete_user=True)
656 user7, token7 = generate_user()
657 user8, token8 = generate_user()
659 make_friends(user1, user2)
660 make_friends(user1, user3)
661 make_friends(user1, user5)
662 make_friends(user1, user7)
663 make_friends(user1, user8)
664 make_friends(user2, user3)
665 make_friends(user4, user3)
666 make_user_block(user1, user7)
667 make_user_block(user8, user1)
669 with conversations_session(token1) as c:
670 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user5.id]))
671 group_chat_id = res.group_chat_id
672 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
674 # other user not in chat
675 with conversations_session(token3) as c:
676 with pytest.raises(grpc.RpcError) as e:
677 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
678 assert e.value.code() == grpc.StatusCode.NOT_FOUND
679 with pytest.raises(grpc.RpcError) as e:
680 res = c.InviteToGroupChat(
681 conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user4.id)
682 )
683 assert e.value.code() == grpc.StatusCode.NOT_FOUND
684 with pytest.raises(grpc.RpcError) as e:
685 res = c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
686 assert e.value.code() == grpc.StatusCode.NOT_FOUND
688 with conversations_session(token2) as c:
689 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
690 assert user3.id not in res.member_user_ids
692 # only_admins_invite defaults to true so shouldn't be able to invite
693 with pytest.raises(grpc.RpcError) as e:
694 res = c.InviteToGroupChat(
695 conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)
696 )
697 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
698 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
700 with conversations_session(token1) as c:
701 # invite invisible user fails
702 with pytest.raises(grpc.RpcError) as e:
703 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user6.id))
704 assert e.value.code() == grpc.StatusCode.NOT_FOUND
705 assert e.value.details() == errors.USER_NOT_FOUND
706 # invite fake user fails
707 with pytest.raises(grpc.RpcError) as e:
708 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=999))
709 assert e.value.code() == grpc.StatusCode.NOT_FOUND
710 assert e.value.details() == errors.USER_NOT_FOUND
711 # invite blocked user fails
712 with pytest.raises(grpc.RpcError) as e:
713 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user7.id))
714 assert e.value.code() == grpc.StatusCode.NOT_FOUND
715 assert e.value.details() == errors.USER_NOT_FOUND
716 # invite blocking user fails
717 with pytest.raises(grpc.RpcError) as e:
718 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user8.id))
719 assert e.value.code() == grpc.StatusCode.NOT_FOUND
720 assert e.value.details() == errors.USER_NOT_FOUND
722 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
723 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
724 assert user1.id in res.member_user_ids
725 assert user5.id in res.member_user_ids
726 assert user3.id in res.member_user_ids
728 # test non-admin inviting
729 c.EditGroupChat(
730 conversations_pb2.EditGroupChatReq(
731 group_chat_id=group_chat_id, only_admins_invite=wrappers_pb2.BoolValue(value=False)
732 )
733 )
735 with conversations_session(token3) as c:
736 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user2.id))
737 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
738 assert user2.id in res.member_user_ids
741def test_group_chats_with_messages_before_join(db):
742 """
743 If user 1 and 2 have a group chat and send messages, then add user 3; user 3
744 should still see the group chat!
745 """
746 user1, token1 = generate_user()
747 user2, token2 = generate_user()
748 user3, token3 = generate_user()
749 user4, token4 = generate_user()
751 make_friends(user1, user2)
752 make_friends(user1, user3)
753 make_friends(user2, user3)
754 make_friends(user1, user4)
756 with conversations_session(token1) as c:
757 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id]))
758 group_chat_id = res.group_chat_id
759 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
761 with conversations_session(token2) as c:
762 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 2"))
764 with conversations_session(token1) as c:
765 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 3"))
767 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
769 with conversations_session(token3) as c:
770 # should work
771 c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id))
773 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq())
774 assert len(res.group_chats) == 1
777def test_invite_to_dm(db):
778 user1, token1 = generate_user()
779 user2, token2 = generate_user()
780 user3, token3 = generate_user()
782 make_friends(user1, user2)
783 make_friends(user1, user3)
784 make_friends(user2, user3)
786 with conversations_session(token1) as c:
787 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
788 group_chat_id = res.group_chat_id
789 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
791 # dm, shou;dn't be able to invite someone else
792 with pytest.raises(grpc.RpcError) as e:
793 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
794 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
795 assert e.value.details() == errors.CANT_INVITE_TO_DM
798def test_sole_admin_leaves(db):
799 user1, token1 = generate_user()
800 user2, token2 = generate_user()
801 user3, token3 = generate_user()
803 make_friends(user1, user2)
804 make_friends(user1, user3)
805 make_friends(user2, user3)
807 with conversations_session(token1) as c:
808 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
809 group_chat_id = res.group_chat_id
810 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
812 # sole admin can't leave group chat
813 with pytest.raises(grpc.RpcError) as e:
814 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
815 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
816 assert e.value.details() == errors.LAST_ADMIN_CANT_LEAVE
818 with conversations_session(token2) as c:
819 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
821 with conversations_session(token3) as c:
822 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
824 # sole admin can leave when last in chat
825 with conversations_session(token1) as c:
826 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
829def test_search_messages(db):
830 user1, token1 = generate_user()
831 user2, token2 = generate_user()
832 user3, token3 = generate_user()
834 make_friends(user1, user2)
835 make_friends(user1, user3)
837 with conversations_session(token1) as c:
838 # create some threads with messages
839 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
840 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1"))
841 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2"))
842 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
843 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 3"))
844 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 4"))
846 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="message "))
847 assert len(res.results) == 4
848 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="group "))
849 assert len(res.results) == 2
850 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="message 5"))
851 assert len(res.results) == 0
853 # outside user doesn't get results
854 with conversations_session(token3) as c:
855 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message"))
856 assert len(res.results) == 0
859def test_search_messages_left_joined(db):
860 user1, token1 = generate_user()
861 user2, token2 = generate_user()
862 user3, token3 = generate_user()
863 user4, token4 = generate_user()
864 make_friends(user1, user2)
865 make_friends(user1, user3)
866 make_friends(user1, user4)
868 with conversations_session(token1) as c:
869 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id]))
870 group_chat_id = res.group_chat_id
871 for i in range(10):
872 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message " + str(i)))
874 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
875 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 10"))
876 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message"))
878 assert len(res.results) == 11
880 with conversations_session(token3) as c:
881 # can only see last message after invited
882 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message"))
884 assert len(res.results) == 1
885 assert res.results[0].message.text.text == "Test message 10"
887 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
889 with conversations_session(token1) as c:
890 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 11"))
891 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 12"))
892 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id))
893 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 13"))
894 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 14"))
896 with conversations_session(token3) as c:
897 # can only see last message after invited
898 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message"))
899 assert len(res.results) == 3
900 assert res.results[0].message.text.text == "Test message 14"
901 assert res.results[1].message.text.text == "Test message 13"
902 assert res.results[2].message.text.text == "Test message 10"
905def test_admin_behaviour(db):
906 user1, token1 = generate_user()
907 user2, token2 = generate_user()
908 user3, token3 = generate_user()
910 make_friends(user1, user2)
911 make_friends(user1, user3)
912 make_friends(user2, user3)
914 with conversations_session(token1) as c:
915 gcid = c.CreateGroupChat(
916 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])
917 ).group_chat_id
918 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id))
919 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
920 assert len(res.admin_user_ids) == 2
921 assert user1.id in res.admin_user_ids
922 assert user2.id in res.admin_user_ids
924 with conversations_session(token3) as c:
925 with pytest.raises(grpc.RpcError) as e:
926 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
927 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
928 with pytest.raises(grpc.RpcError) as e:
929 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id))
930 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
931 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
932 assert len(res.admin_user_ids) == 2
933 assert user1.id in res.admin_user_ids
934 assert user2.id in res.admin_user_ids
936 with conversations_session(token2) as c:
937 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
938 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
939 assert len(res.admin_user_ids) == 3
940 assert user1.id in res.admin_user_ids
941 assert user2.id in res.admin_user_ids
942 assert user3.id in res.admin_user_ids
944 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id))
945 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
946 assert len(res.admin_user_ids) == 2
947 assert user2.id in res.admin_user_ids
948 assert user3.id in res.admin_user_ids
950 with conversations_session(token1) as c:
951 with pytest.raises(grpc.RpcError):
952 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id))
953 with pytest.raises(grpc.RpcError):
954 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
955 with pytest.raises(grpc.RpcError):
956 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id))
957 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
958 assert len(res.admin_user_ids) == 2
959 assert user2.id in res.admin_user_ids
960 assert user3.id in res.admin_user_ids
962 with conversations_session(token2) as c:
963 # can demote self if there are other admins
964 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id))
965 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
966 assert len(res.admin_user_ids) == 1
967 assert user3.id in res.admin_user_ids
969 with conversations_session(token3) as c:
970 with pytest.raises(grpc.RpcError) as e:
971 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
972 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
973 assert e.value.details() == errors.CANT_REMOVE_LAST_ADMIN
974 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
975 assert len(res.admin_user_ids) == 1
976 assert user3.id in res.admin_user_ids
978 # last admin can't leave
979 with pytest.raises(grpc.RpcError) as e:
980 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid))
981 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
982 assert e.value.details() == errors.LAST_ADMIN_CANT_LEAVE
984 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id))
986 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid))
988 with conversations_session(token2) as c:
989 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid))
991 # last participant must be admin but can leave to orphan chat
992 with conversations_session(token1) as c:
993 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid))
996def test_add_remove_admin_failures(db):
997 user1, token1 = generate_user()
998 user2, token2 = generate_user()
999 user3, token3 = generate_user()
1000 user4, token4 = generate_user()
1001 user5, token5 = generate_user()
1003 make_friends(user1, user2)
1004 make_friends(user1, user3)
1005 make_friends(user1, user4)
1006 make_friends(user1, user5)
1008 with conversations_session(token1) as c:
1009 gcid = c.CreateGroupChat(
1010 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id, user4.id, user5.id])
1011 ).group_chat_id
1013 make_user_invisible(user3.id)
1014 make_user_block(user1, user4)
1015 make_user_block(user5, user1)
1017 # make non-existent user admin
1018 with pytest.raises(grpc.RpcError) as e:
1019 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=999))
1020 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1021 assert e.value.details() == errors.USER_NOT_FOUND
1023 # make invisible user admin
1024 with pytest.raises(grpc.RpcError) as e:
1025 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
1026 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1027 assert e.value.details() == errors.USER_NOT_FOUND
1029 # make blocked user admin
1030 with pytest.raises(grpc.RpcError) as e:
1031 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user4.id))
1032 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1033 assert e.value.details() == errors.USER_NOT_FOUND
1035 # make blocking user admin
1036 with pytest.raises(grpc.RpcError) as e:
1037 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user5.id))
1038 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1039 assert e.value.details() == errors.USER_NOT_FOUND
1041 with session_scope() as session:
1042 subscriptions = (
1043 session.execute(
1044 select(GroupChatSubscription)
1045 .where(GroupChatSubscription.group_chat_id == gcid)
1046 .where(GroupChatSubscription.role == GroupChatRole.participant)
1047 )
1048 .scalars()
1049 .all()
1050 )
1052 for subscription in subscriptions:
1053 subscription.role = GroupChatRole.admin
1055 with conversations_session(token1) as c:
1056 # remove non-existent user admin
1057 with pytest.raises(grpc.RpcError) as e:
1058 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=999))
1059 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1060 assert e.value.details() == errors.USER_NOT_FOUND
1062 # remove invisible admin
1063 with pytest.raises(grpc.RpcError) as e:
1064 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id))
1065 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1066 assert e.value.details() == errors.USER_NOT_FOUND
1068 # remove blocked admin
1069 with pytest.raises(grpc.RpcError) as e:
1070 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user4.id))
1071 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1072 assert e.value.details() == errors.USER_NOT_FOUND
1074 # remove blocking admin
1075 with pytest.raises(grpc.RpcError) as e:
1076 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user5.id))
1077 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1078 assert e.value.details() == errors.USER_NOT_FOUND
1081def test_last_seen(db):
1082 user1, token1 = generate_user()
1083 user2, token2 = generate_user()
1084 user3, token3 = generate_user()
1086 make_friends(user1, user2)
1087 make_friends(user1, user3)
1088 make_friends(user2, user3)
1090 with conversations_session(token3) as c:
1091 # this is just here to mess up any issues we get if we pretend there's only one group chat ever
1092 gcid_distraction = c.CreateGroupChat(
1093 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user1.id])
1094 ).group_chat_id
1096 with conversations_session(token1) as c:
1097 gcid = c.CreateGroupChat(
1098 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])
1099 ).group_chat_id
1101 message_ids = []
1103 for i in range(6):
1104 c.SendMessage(
1105 conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"gibberish message... {i}")
1106 )
1107 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}"))
1108 c.SendMessage(
1109 conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"gibberish message {i}")
1110 )
1112 message_ids.append(
1113 c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)).latest_message.message_id
1114 )
1116 # messages are automatically marked as seen when you send a new message
1117 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1118 assert res.unseen_message_count == 0
1120 with conversations_session(token2) as c:
1121 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1122 # created + 6 normal
1123 assert res.unseen_message_count == 7
1125 backward_offset = 3
1126 c.MarkLastSeenGroupChat(
1127 conversations_pb2.MarkLastSeenGroupChatReq(
1128 group_chat_id=gcid, last_seen_message_id=message_ids[-backward_offset - 1]
1129 )
1130 )
1132 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1133 assert res.unseen_message_count == backward_offset
1135 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text="test message ..."))
1137 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1138 assert res.unseen_message_count == 0
1140 with conversations_session(token3) as c:
1141 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1142 # created + 7 normal
1143 assert res.unseen_message_count == 8
1145 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text="test message ..."))
1147 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1148 assert res.unseen_message_count == 0
1151def test_one_dm_per_pair(db):
1152 user1, token1 = generate_user()
1153 user2, token2 = generate_user()
1154 user3, token3 = generate_user()
1156 make_friends(user1, user2)
1157 make_friends(user1, user3)
1158 make_friends(user2, user3)
1160 with conversations_session(token1) as c:
1161 # create DM with user 2
1162 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
1163 assert res.is_dm
1165 # create DM with user 3
1166 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1167 assert res.is_dm
1169 # can't create another group chat with just user 2
1170 with pytest.raises(grpc.RpcError) as e:
1171 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
1172 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1174 # can't create another group chat with just user 3
1175 with pytest.raises(grpc.RpcError) as e:
1176 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1177 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1179 # can create joined group chat
1180 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
1181 assert not res.is_dm
1183 with conversations_session(token2) as c:
1184 # can create DM with user 3
1185 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1186 assert res.is_dm
1188 # can't create another group chat with just user 1
1189 with pytest.raises(grpc.RpcError) as e:
1190 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user1.id]))
1191 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1194def test_GetDirectMessage(db):
1195 user1, token1 = generate_user()
1196 user2, token2 = generate_user()
1197 user3, token3 = generate_user()
1199 make_friends(user1, user2)
1200 make_friends(user1, user3)
1201 make_friends(user2, user3)
1203 with conversations_session(token1) as c:
1204 # no group chat with user 2
1205 with pytest.raises(grpc.RpcError) as e:
1206 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user2.id))
1207 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1209 # no group chat with nor user 3
1210 with pytest.raises(grpc.RpcError) as e:
1211 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user3.id))
1212 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1214 # create DM with user 2
1215 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
1216 assert res.is_dm
1217 gcid = res.group_chat_id
1219 # now should exist
1220 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user2.id))
1221 assert res.group_chat_id == gcid
1223 # create DM with user 3
1224 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1225 assert res.is_dm
1227 # can create joined group chat
1228 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]))
1229 assert not res.is_dm
1231 with conversations_session(token2) as c:
1232 # can create DM with user 3
1233 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1234 assert res.is_dm
1235 assert res.can_message
1236 gcid = res.group_chat_id
1238 # DM with 3 should exist, but can't message after being blocked
1239 make_user_block(user3, user2)
1240 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user3.id))
1241 assert res.group_chat_id == gcid
1242 assert not res.can_message
1245def test_total_unseen(db):
1246 user1, token1 = generate_user()
1247 user2, token2 = generate_user()
1248 user3, token3 = generate_user()
1250 # distractions
1251 user4, token4 = generate_user()
1253 make_friends(user1, user2)
1254 make_friends(user1, user3)
1255 make_friends(user2, user3)
1257 # distractions
1258 make_friends(user1, user4)
1260 with conversations_session(token1) as c:
1261 # distractions
1262 gcid_distraction = c.CreateGroupChat(
1263 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user4.id])
1264 ).group_chat_id
1265 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text="distraction..."))
1267 gcid = c.CreateGroupChat(
1268 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])
1269 ).group_chat_id
1271 for i in range(6):
1272 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}"))
1274 # distractions
1275 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text="distraction..."))
1277 # messages are automatically marked as seen when you send a new message
1278 with api_session(token1) as api:
1279 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0
1281 with api_session(token2) as api:
1282 # chat created + 6 normal messages
1283 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 7
1285 # now leave chat with user2
1286 with conversations_session(token2) as c:
1287 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid))
1289 with api_session(token2) as api:
1290 # seen messages becomes 0 when leaving
1291 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0
1293 with conversations_session(token1) as c:
1294 # distractions
1295 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text="distraction..."))
1297 # send more stuff without user 2
1298 for i in range(3):
1299 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}"))
1301 # distractions
1302 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text="distraction..."))
1304 with api_session(token2) as api:
1305 # seen messages becomes 0 when leaving
1306 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0
1308 with conversations_session(token1) as c:
1309 # add user 2 back
1310 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=gcid, user_id=user2.id))
1312 # send more stuff with user 2
1313 for i in range(12):
1314 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}"))
1316 # distractions
1317 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text="distraction..."))
1319 with api_session(token2) as api:
1320 # joined + 12 normal
1321 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 13
1324def test_regression_ListGroupChats_pagination(db):
1325 user1, token1 = generate_user()
1326 user2, token2 = generate_user()
1327 user3, token3 = generate_user()
1329 make_friends(user1, user2)
1330 make_friends(user1, user3)
1332 with conversations_session(token1) as c:
1333 # tuples of (group_chat_id, message_id)
1334 group_chat_and_message_ids = []
1335 for i in range(50):
1336 res1 = c.CreateGroupChat(
1337 conversations_pb2.CreateGroupChatReq(
1338 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value=f"Chat {i}")
1339 )
1340 )
1342 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res1.group_chat_id, text=f"Test message {i}"))
1344 res2 = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=res1.group_chat_id))
1346 group_chat_and_message_ids.append((res2.group_chat_id, res2.latest_message.message_id))
1348 seen_group_chat_ids = []
1350 last_message_id = 0
1351 more = True
1352 while more:
1353 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq(last_message_id=last_message_id))
1354 last_message_id = res.last_message_id
1355 more = not res.no_more
1357 seen_group_chat_ids.extend([chat.group_chat_id for chat in res.group_chats])
1359 assert set(seen_group_chat_ids) == {x[0] for x in group_chat_and_message_ids}, "Not all group chats returned"
1362def test_muting(db):
1363 user1, token1 = generate_user()
1364 user2, token2 = generate_user()
1365 user3, token3 = generate_user()
1367 make_friends(user1, user2)
1368 make_friends(user1, user3)
1369 make_friends(user2, user3)
1371 with conversations_session(token3) as c:
1372 # this is just here to mess up any issues we get if we pretend there's only one group chat ever
1373 gcid_distraction = c.CreateGroupChat(
1374 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user1.id])
1375 ).group_chat_id
1377 with conversations_session(token1) as c:
1378 gcid = c.CreateGroupChat(
1379 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])
1380 ).group_chat_id
1382 with conversations_session(token2) as c:
1383 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1384 assert not res.mute_info.muted
1385 assert not res.mute_info.HasField("muted_until")
1387 c.MuteGroupChat(conversations_pb2.MuteGroupChatReq(group_chat_id=gcid, forever=True))
1388 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1389 assert res.mute_info.muted
1390 assert not res.mute_info.HasField("muted_until")
1392 c.MuteGroupChat(conversations_pb2.MuteGroupChatReq(group_chat_id=gcid, unmute=True))
1393 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1394 assert not res.mute_info.muted
1395 assert not res.mute_info.HasField("muted_until")
1397 c.MuteGroupChat(
1398 conversations_pb2.MuteGroupChatReq(
1399 group_chat_id=gcid, for_duration=Duration_from_timedelta(timedelta(hours=2))
1400 )
1401 )
1402 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid))
1403 assert res.mute_info.muted
1404 assert res.mute_info.HasField("muted_until")
1405 assert to_aware_datetime(res.mute_info.muted_until) >= now() + timedelta(hours=1, minutes=59)
1406 assert to_aware_datetime(res.mute_info.muted_until) <= now() + timedelta(hours=2, minutes=1)
1409def test_chat_notifications(db):
1410 user1, token1 = generate_user()
1411 user2, token2 = generate_user()
1412 # notifs off
1413 user3, token3 = generate_user()
1414 user4, token4 = generate_user()
1415 user5, token5 = generate_user()
1416 user6, token6 = generate_user()
1418 make_friends(user1, user2)
1419 make_friends(user1, user3)
1420 make_friends(user1, user4)
1421 make_friends(user4, user5)
1422 make_friends(user4, user6)
1424 # have some of them enable/disable notifs
1425 topic_action = NotificationTopicAction.chat__message
1426 for token, enabled in [
1427 (token1, True),
1428 (token2, True),
1429 (token3, False),
1430 (token4, True),
1431 (token5, True),
1432 (token6, True),
1433 ]:
1434 with notifications_session(token) as notifications:
1435 notifications.SetNotificationSettings(
1436 notifications_pb2.SetNotificationSettingsReq(
1437 preferences=[
1438 notifications_pb2.SingleNotificationPreference(
1439 topic=topic_action.topic,
1440 action=topic_action.action,
1441 delivery_method=delivery_method,
1442 enabled=enabled,
1443 )
1444 for delivery_method in ["push", "email", "digest"]
1445 ],
1446 )
1447 )
1449 group_chat_id = None
1451 def send_msg(c, i):
1452 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text=f"Test message {i}"))
1454 with conversations_session(token1) as c:
1455 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id, user4.id]))
1456 group_chat_id = res.group_chat_id
1457 c.EditGroupChat(
1458 conversations_pb2.EditGroupChatReq(
1459 group_chat_id=group_chat_id, only_admins_invite=wrappers_pb2.BoolValue(value=False)
1460 )
1461 )
1462 send_msg(c, i=1)
1463 send_msg(c, i=2)
1465 with conversations_session(token4) as c:
1466 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user5.id))
1467 send_msg(c, i=3)
1468 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user6.id))
1469 send_msg(c, i=4)
1470 send_msg(c, i=5)
1472 with conversations_session(token3) as c:
1473 send_msg(c, i=6)
1474 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
1476 with conversations_session(token2) as c:
1477 send_msg(c, i=7)
1478 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id))
1480 with conversations_session(token6) as c:
1481 send_msg(c, i=8)
1483 # go through all bg jobs
1484 while process_job():
1485 pass
1487 # now check notifs...
1488 expected_notifs = [
1489 (user1, "user1", [3, 4, 5, 6, 7, 8]),
1490 (user2, "user2", [1, 2, 3, 4, 5, 6]),
1491 (user3, "user3", []), # notifs off
1492 (user4, "user4", [1, 2, 6, 7, 8]),
1493 (user5, "user5", [3, 4, 5, 6, 7, 8]),
1494 (user6, "user6", [4, 5, 6, 7]),
1495 ]
1497 with session_scope() as session:
1498 for user, label, expected_msgs in expected_notifs:
1499 deliv = (
1500 session.execute(
1501 select(Notification.data)
1502 .join(NotificationDelivery, NotificationDelivery.notification_id == Notification.id)
1503 .where(Notification.user_id == user.id)
1504 .where(Notification.topic_action == topic_action)
1505 .where(NotificationDelivery.delivery_type == NotificationDeliveryType.push)
1506 .order_by(Notification.created)
1507 )
1508 .scalars()
1509 .all()
1510 )
1512 def parse_message_payload(data):
1513 return notification_data_pb2.ChatMessage.FromString(data).text
1515 contents = [parse_message_payload(d) for d in deliv]
1517 print(contents)
1519 assert [f"Test message {i}" for i in expected_msgs] == contents, f"Wrong messages for {label}"
1522def test_incomplete_profile(db):
1523 user1, token1 = generate_user(complete_profile=True)
1524 user2, token2 = generate_user(complete_profile=False)
1525 user3, token3 = generate_user(complete_profile=True)
1526 make_friends(user1, user2)
1527 make_friends(user1, user3)
1529 # user 1 can make a chat
1530 with conversations_session(token1) as c:
1531 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id]))
1532 group_chat_id = res.group_chat_id
1533 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1"))
1534 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id))
1535 assert res.messages[0].text.text == "Test message 1"
1536 assert to_aware_datetime(res.messages[0].time) <= now()
1537 assert res.messages[0].author_user_id == user1.id
1539 # user 2 cannot
1540 with conversations_session(token2) as c:
1541 with pytest.raises(grpc.RpcError) as e:
1542 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id]))
1543 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
1544 assert e.value.details() == errors.INCOMPLETE_PROFILE_SEND_MESSAGE