Coverage for src/tests/test_conversations.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

868 statements  

1from datetime import timedelta 

2 

3import grpc 

4import pytest 

5from google.protobuf import wrappers_pb2 

6 

7from couchers import errors 

8from couchers.db import session_scope 

9from couchers.models import GroupChatRole, GroupChatSubscription 

10from couchers.sql import couchers_select as select 

11from couchers.utils import Duration_from_timedelta, now, to_aware_datetime 

12from proto import api_pb2, conversations_pb2 

13from tests.test_fixtures import ( # noqa 

14 api_session, 

15 conversations_session, 

16 db, 

17 generate_user, 

18 make_friends, 

19 make_user_block, 

20 make_user_invisible, 

21 testconfig, 

22) 

23 

24 

25@pytest.fixture(autouse=True) 

26def _(testconfig): 

27 pass 

28 

29 

30def test_list_group_chats(db): 

31 user1, token1 = generate_user() 

32 user2, token2 = generate_user() 

33 user3, token3 = generate_user() 

34 

35 make_friends(user2, user1) 

36 make_friends(user1, user3) 

37 

38 with conversations_session(token1) as c: 

39 # no threads initially 

40 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

41 assert len(res.group_chats) == 0 

42 

43 # create some group chats with messages 

44 res = c.CreateGroupChat( 

45 conversations_pb2.CreateGroupChatReq( 

46 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title") 

47 ) 

48 ) 

49 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1")) 

50 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2")) 

51 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

52 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 1")) 

53 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 2")) 

54 

55 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

56 assert len(res.group_chats) == 2 

57 assert res.no_more 

58 

59 with conversations_session(token2) as c: 

60 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

61 assert len(res.group_chats) == 2 

62 assert res.no_more 

63 

64 with conversations_session(token3) as c: 

65 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

66 assert len(res.group_chats) == 1 

67 assert res.no_more 

68 

69 

70def test_list_empty_group_chats(db): 

71 user1, token1 = generate_user() 

72 user2, token2 = generate_user() 

73 user3, token3 = generate_user() 

74 

75 make_friends(user1, user3) 

76 make_friends(user2, user1) 

77 make_friends(user2, user3) 

78 

79 with conversations_session(token1) as c: 

80 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

81 assert len(res.group_chats) == 0 

82 

83 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

84 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

85 

86 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

87 assert len(res.group_chats) == 2 

88 assert res.no_more 

89 

90 with conversations_session(token2) as c: 

91 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

92 assert len(res.group_chats) == 2 

93 assert res.no_more 

94 

95 c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

96 

97 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

98 assert len(res.group_chats) == 3 

99 assert res.no_more 

100 

101 with conversations_session(token3) as c: 

102 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

103 assert len(res.group_chats) == 2 

104 assert res.no_more 

105 

106 

107def test_list_group_chats_ordering(db): 

108 # user is member of 5 group chats, order them correctly 

109 user, token = generate_user() 

110 user2, token2 = generate_user() 

111 user3, token3 = generate_user() 

112 user4, token4 = generate_user() 

113 

114 make_friends(user2, user) 

115 make_friends(user2, user3) 

116 make_friends(user2, user4) 

117 make_friends(user3, user) 

118 make_friends(user3, user4) 

119 make_friends(user, user4) 

120 

121 with conversations_session(token2) as c: 

122 res = c.CreateGroupChat( 

123 conversations_pb2.CreateGroupChatReq( 

124 recipient_user_ids=[user.id], title=wrappers_pb2.StringValue(value="Chat 0") 

125 ) 

126 ) 

127 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

128 res = c.CreateGroupChat( 

129 conversations_pb2.CreateGroupChatReq( 

130 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 1") 

131 ) 

132 ) 

133 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

134 res = c.CreateGroupChat( 

135 conversations_pb2.CreateGroupChatReq( 

136 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 2") 

137 ) 

138 ) 

139 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

140 

141 with conversations_session(token3) as c: 

142 res = c.CreateGroupChat( 

143 conversations_pb2.CreateGroupChatReq( 

144 recipient_user_ids=[user.id, user2.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 3") 

145 ) 

146 ) 

147 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

148 

149 with conversations_session(token) as c: 

150 res = c.CreateGroupChat( 

151 conversations_pb2.CreateGroupChatReq( 

152 recipient_user_ids=[user2.id, user3.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 4") 

153 ) 

154 ) 

155 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

156 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

157 assert len(res.group_chats) == 5 

158 assert res.group_chats[0].title == "Chat 4" 

159 assert res.group_chats[1].title == "Chat 3" 

160 assert res.group_chats[2].title == "Chat 2" 

161 assert res.group_chats[3].title == "Chat 1" 

162 assert res.group_chats[4].title == "Chat 0" 

163 

164 c.SendMessage( 

165 conversations_pb2.SendMessageReq(group_chat_id=res.group_chats[3].group_chat_id, text="Test message 2a") 

166 ) 

167 c.SendMessage( 

168 conversations_pb2.SendMessageReq(group_chat_id=res.group_chats[2].group_chat_id, text="Test message 2b") 

169 ) 

170 

171 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

172 assert len(res.group_chats) == 5 

173 assert res.group_chats[0].title == "Chat 2" 

174 assert res.group_chats[0].latest_message.text.text == "Test message 2b" 

175 assert res.group_chats[1].title == "Chat 1" 

176 assert res.group_chats[1].latest_message.text.text == "Test message 2a" 

177 assert res.group_chats[2].title == "Chat 4" 

178 assert res.group_chats[3].title == "Chat 3" 

179 assert res.group_chats[4].title == "Chat 0" 

180 

181 

182def test_list_group_chats_ordering_after_left(db): 

183 # user is member to 4 group chats, and has left one. 

184 # The one user left has the most recent message, but user left before then, 

185 # this should display as e.g. 3rd most recent depending on last message when they were in the chat 

186 user, token = generate_user() 

187 user2, token2 = generate_user() 

188 user3, token3 = generate_user() 

189 user4, token4 = generate_user() 

190 

191 make_friends(user2, user) 

192 make_friends(user2, user3) 

193 make_friends(user2, user4) 

194 make_friends(user3, user) 

195 make_friends(user3, user4) 

196 make_friends(user, user4) 

197 

198 with conversations_session(token2) as c: 

199 res = c.CreateGroupChat( 

200 conversations_pb2.CreateGroupChatReq( 

201 recipient_user_ids=[user.id], title=wrappers_pb2.StringValue(value="Chat 0") 

202 ) 

203 ) 

204 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

205 res = c.CreateGroupChat( 

206 conversations_pb2.CreateGroupChatReq( 

207 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Left Chat 1") 

208 ) 

209 ) 

210 left_chat_id = res.group_chat_id 

211 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Test message")) 

212 res = c.CreateGroupChat( 

213 conversations_pb2.CreateGroupChatReq( 

214 recipient_user_ids=[user.id, user3.id], title=wrappers_pb2.StringValue(value="Chat 2") 

215 ) 

216 ) 

217 chat2_id = res.group_chat_id 

218 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=chat2_id, text="Test message")) 

219 

220 with conversations_session(token3) as c: 

221 res = c.CreateGroupChat( 

222 conversations_pb2.CreateGroupChatReq( 

223 recipient_user_ids=[user.id, user2.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 3") 

224 ) 

225 ) 

226 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

227 

228 with conversations_session(token) as c: 

229 res = c.CreateGroupChat( 

230 conversations_pb2.CreateGroupChatReq( 

231 recipient_user_ids=[user2.id, user3.id, user4.id], title=wrappers_pb2.StringValue(value="Chat 4") 

232 ) 

233 ) 

234 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message")) 

235 

236 # leave chat 

237 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=left_chat_id)) 

238 

239 with conversations_session(token3) as c: 

240 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=chat2_id, text="Test message")) 

241 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Test message")) 

242 

243 with conversations_session(token2) as c: 

244 # other user sends a message to that chat 

245 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=left_chat_id, text="Another test message")) 

246 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

247 assert len(res.group_chats) == 5 

248 assert res.group_chats[0].title == "Left Chat 1" 

249 assert res.group_chats[1].title == "Chat 2" 

250 assert res.group_chats[2].title == "Chat 4" 

251 assert res.group_chats[3].title == "Chat 3" 

252 assert res.group_chats[4].title == "Chat 0" 

253 

254 with conversations_session(token) as c: 

255 # we can't see the new message since we left before it was sent 

256 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

257 assert len(res.group_chats) == 5 

258 assert res.group_chats[0].title == "Chat 2" 

259 assert res.group_chats[1].title == "Left Chat 1" 

260 assert res.group_chats[2].title == "Chat 4" 

261 assert res.group_chats[3].title == "Chat 3" 

262 assert res.group_chats[4].title == "Chat 0" 

263 

264 

265def test_get_group_chat_messages(db): 

266 user1, token1 = generate_user() 

267 user2, token2 = generate_user() 

268 user3, token3 = generate_user() 

269 

270 make_friends(user1, user2) 

271 

272 with conversations_session(token1) as c: 

273 # create some threads with messages 

274 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

275 group_chat_id = res.group_chat_id 

276 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1")) 

277 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2")) 

278 

279 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

280 # created + 2 normal 

281 assert len(res.messages) == 3 

282 assert res.no_more 

283 

284 assert res.messages[0].text.text == "Test message 2" 

285 assert res.messages[1].text.text == "Test message 1" 

286 assert res.messages[2].WhichOneof("content") == "chat_created" 

287 

288 # test that another user can't access the thread 

289 with conversations_session(token3) as c: 

290 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

291 assert len(res.messages) == 0 

292 

293 

294def test_get_group_chat_messages_pagination(db): 

295 user1, token1 = generate_user() 

296 user2, token2 = generate_user() 

297 make_friends(user1, user2) 

298 

299 with conversations_session(token1) as c: 

300 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

301 group_chat_id = res.group_chat_id 

302 for i in range(30): 

303 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text=str(i))) 

304 

305 with conversations_session(token2) as c: 

306 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

307 # pagination 

308 assert len(res.messages) == 20 

309 assert res.messages[0].text.text == "29" 

310 assert res.messages[19].text.text == "10" 

311 assert not res.no_more 

312 res = c.GetGroupChatMessages( 

313 conversations_pb2.GetGroupChatMessagesReq( 

314 group_chat_id=group_chat_id, last_message_id=res.messages[19].message_id 

315 ) 

316 ) 

317 assert len(res.messages) == 11 

318 assert res.messages[0].text.text == "9" 

319 assert res.messages[9].text.text == "0" 

320 assert res.no_more 

321 

322 

323def test_get_group_chat_messages_joined_left(db): 

324 user1, token1 = generate_user() 

325 user2, token2 = generate_user() 

326 user3, token3 = generate_user() 

327 user4, token4 = generate_user() 

328 make_friends(user1, user2) 

329 make_friends(user1, user3) 

330 make_friends(user1, user4) 

331 start_time = now() 

332 

333 with conversations_session(token1) as c: 

334 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id])) 

335 group_chat_id = res.group_chat_id 

336 

337 for i in range(10): 

338 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text=str(i))) 

339 

340 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

341 

342 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="10")) 

343 

344 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

345 

346 # created + 10 normal + invited + normal 

347 assert len(res.messages) == 13 

348 

349 with conversations_session(token3) as c: 

350 # can only see last message after invited 

351 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

352 # joined + normal 

353 assert len(res.messages) == 2 

354 assert res.messages[0].text.text == "10" 

355 

356 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

357 

358 with conversations_session(token1) as c: 

359 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="11")) 

360 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="12")) 

361 

362 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

363 

364 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="13")) 

365 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="14")) 

366 

367 with conversations_session(token3) as c: 

368 # can only see last message after invited 

369 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

370 # joined + normal + left + invite + 2 normal 

371 assert len(res.messages) == 6 

372 assert res.messages[0].text.text == "14" 

373 assert res.messages[1].text.text == "13" 

374 assert res.messages[2].WhichOneof("content") == "user_invited" 

375 assert res.messages[3].WhichOneof("content") == "user_left" 

376 assert res.messages[4].text.text == "10" 

377 assert res.messages[5].WhichOneof("content") == "user_invited" 

378 

379 

380def test_get_group_chat_info(db): 

381 user1, token1 = generate_user() 

382 user2, token2 = generate_user() 

383 user3, token3 = generate_user() 

384 

385 make_friends(user1, user2) 

386 make_friends(user3, user1) 

387 

388 with conversations_session(token1) as c: 

389 # create some threads with messages 

390 res = c.CreateGroupChat( 

391 conversations_pb2.CreateGroupChatReq( 

392 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title") 

393 ) 

394 ) 

395 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1")) 

396 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2")) 

397 group_chat1_id = res.group_chat_id 

398 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

399 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 1")) 

400 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 2")) 

401 group_chat2_id = res.group_chat_id 

402 

403 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat1_id)) 

404 assert res.title == "Test title" 

405 assert user2.id in res.member_user_ids 

406 assert user1.id in res.admin_user_ids 

407 assert to_aware_datetime(res.created) <= now() 

408 assert res.only_admins_invite 

409 assert res.is_dm 

410 

411 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat2_id)) 

412 assert not res.title 

413 assert user2.id in res.member_user_ids 

414 assert user3.id in res.member_user_ids 

415 assert user1.id in res.admin_user_ids 

416 assert to_aware_datetime(res.created) <= now() 

417 assert res.only_admins_invite 

418 assert not res.is_dm 

419 

420 

421def test_get_group_chat_info_denied(db): 

422 user1, token1 = generate_user() 

423 user2, token2 = generate_user() 

424 user3, token3 = generate_user() 

425 user4, token4 = generate_user() 

426 

427 make_friends(user1, user2) 

428 make_friends(user3, user1) 

429 

430 with conversations_session(token1) as c: 

431 # create a group chat with messages 

432 res = c.CreateGroupChat( 

433 conversations_pb2.CreateGroupChatReq( 

434 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title") 

435 ) 

436 ) 

437 group_chat_id = res.group_chat_id 

438 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

439 

440 with conversations_session(token4) as c: 

441 with pytest.raises(grpc.RpcError) as e: 

442 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

443 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

444 

445 

446def test_get_group_chat_info_left(db): 

447 user1, token1 = generate_user() 

448 user2, token2 = generate_user() 

449 user3, token3 = generate_user() 

450 user4, token4 = generate_user() 

451 

452 make_friends(user1, user2) 

453 make_friends(user3, user1) 

454 make_friends(user1, user4) 

455 

456 with conversations_session(token1) as c: 

457 # create a group chat with messages 

458 res = c.CreateGroupChat( 

459 conversations_pb2.CreateGroupChatReq( 

460 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title") 

461 ) 

462 ) 

463 group_chat_id = res.group_chat_id 

464 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

465 

466 with conversations_session(token3) as c: 

467 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

468 

469 with conversations_session(token1) as c: 

470 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user4.id)) 

471 

472 with conversations_session(token3) as c: 

473 # this user left when user4 wasn't a member, 

474 # so the returned members should be user1, user2, and user3 only 

475 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

476 assert len(res.member_user_ids) == 3 

477 assert user1.id in res.member_user_ids 

478 assert user2.id in res.member_user_ids 

479 assert user3.id in res.member_user_ids 

480 

481 

482def test_remove_group_chat_user(db): 

483 # create 3 uses and connect them 

484 user1, token1 = generate_user() 

485 user2, token2 = generate_user() 

486 user3, token3 = generate_user() 

487 make_friends(user1, user2) 

488 make_friends(user1, user3) 

489 

490 # using user token, create a Conversations API for testing 

491 with conversations_session(token1) as c: 

492 # create a group chat 

493 res = c.CreateGroupChat( 

494 conversations_pb2.CreateGroupChatReq( 

495 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value="Test title") 

496 ) 

497 ) 

498 group_chat_id = res.group_chat_id 

499 

500 # remove a user from group 

501 c.RemoveGroupChatUser(conversations_pb2.RemoveGroupChatUserReq(group_chat_id=group_chat_id, user_id=user2.id)) 

502 assert user3.id in res.member_user_ids # other users are still in the group 

503 

504 # can't remove the same user twice 

505 with pytest.raises(grpc.RpcError) as e: 

506 c.RemoveGroupChatUser( 

507 conversations_pb2.RemoveGroupChatUserReq(group_chat_id=group_chat_id, user_id=user2.id) 

508 ) 

509 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

510 

511 

512def test_edit_group_chat(db): 

513 user1, token1 = generate_user() 

514 user2, token2 = generate_user() 

515 user3, token3 = generate_user() 

516 make_friends(user1, user2) 

517 

518 with conversations_session(token1) as c: 

519 # create some threads with messages 

520 res = c.CreateGroupChat( 

521 conversations_pb2.CreateGroupChatReq( 

522 recipient_user_ids=[user2.id], title=wrappers_pb2.StringValue(value="Test title") 

523 ) 

524 ) 

525 group_chat_id = res.group_chat_id 

526 

527 c.EditGroupChat( 

528 conversations_pb2.EditGroupChatReq( 

529 group_chat_id=group_chat_id, 

530 title=wrappers_pb2.StringValue(value="Modified title"), 

531 only_admins_invite=wrappers_pb2.BoolValue(value=False), 

532 ) 

533 ) 

534 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

535 assert res.title == "Modified title" 

536 assert not res.only_admins_invite 

537 

538 # make sure non-admin is not allowed to modify 

539 with conversations_session(token2) as c: 

540 with pytest.raises(grpc.RpcError) as e: 

541 c.EditGroupChat( 

542 conversations_pb2.EditGroupChatReq( 

543 group_chat_id=group_chat_id, 

544 title=wrappers_pb2.StringValue(value="Other title"), 

545 only_admins_invite=wrappers_pb2.BoolValue(value=True), 

546 ) 

547 ) 

548 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

549 

550 # make sure non-recipient is not allowed to modify 

551 with conversations_session(token3) as c: 

552 with pytest.raises(grpc.RpcError) as e: 

553 c.EditGroupChat( 

554 conversations_pb2.EditGroupChatReq( 

555 group_chat_id=group_chat_id, 

556 title=wrappers_pb2.StringValue(value="Other title"), 

557 only_admins_invite=wrappers_pb2.BoolValue(value=True), 

558 ) 

559 ) 

560 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

561 

562 

563def test_make_remove_group_chat_admin(db): 

564 user1, token1 = generate_user() 

565 user2, token2 = generate_user() 

566 user3, token3 = generate_user() 

567 

568 make_friends(user1, user2) 

569 make_friends(user1, user3) 

570 make_friends(user2, user3) 

571 

572 with conversations_session(token1) as c: 

573 # create some threads with messages 

574 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

575 group_chat_id = res.group_chat_id 

576 

577 # shouldn't be able to remove only admin 

578 with pytest.raises(grpc.RpcError) as e: 

579 c.RemoveGroupChatAdmin( 

580 conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user1.id) 

581 ) 

582 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

583 assert e.value.details() == errors.CANT_REMOVE_LAST_ADMIN 

584 

585 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id)) 

586 

587 # shouldn't be able to make admin again 

588 with pytest.raises(grpc.RpcError) as e: 

589 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id)) 

590 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

591 assert e.value.details() == errors.ALREADY_ADMIN 

592 

593 with conversations_session(token2) as c: 

594 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

595 assert user1.id in res.admin_user_ids 

596 assert user2.id in res.admin_user_ids 

597 

598 with conversations_session(token1) as c: 

599 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user2.id)) 

600 

601 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

602 assert user1.id in res.admin_user_ids 

603 assert not user2.id in res.admin_user_ids 

604 

605 with conversations_session(token2) as c: 

606 # shouldn't be able to make admin if not admin 

607 with pytest.raises(grpc.RpcError) as e: 

608 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=group_chat_id, user_id=user3.id)) 

609 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

610 

611 

612def test_send_message(db): 

613 user1, token1 = generate_user() 

614 user2, token2 = generate_user() 

615 user3, token3 = generate_user() 

616 make_friends(user1, user2) 

617 make_friends(user1, user3) 

618 

619 with conversations_session(token1) as c: 

620 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

621 group_chat_id = res.group_chat_id 

622 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

623 res = c.GetGroupChatMessages(conversations_pb2.GetGroupChatMessagesReq(group_chat_id=group_chat_id)) 

624 assert res.messages[0].text.text == "Test message 1" 

625 assert to_aware_datetime(res.messages[0].time) <= now() 

626 assert res.messages[0].author_user_id == user1.id 

627 

628 # can't send message if not in chat 

629 with conversations_session(token3) as c: 

630 with pytest.raises(grpc.RpcError) as e: 

631 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 2")) 

632 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

633 

634 

635def test_leave_invite_to_group_chat(db): 

636 user1, token1 = generate_user() 

637 user2, token2 = generate_user() 

638 user3, token3 = generate_user() 

639 user4, token4 = generate_user() 

640 user5, token5 = generate_user() 

641 user6, token6 = generate_user(delete_user=True) 

642 user7, token7 = generate_user() 

643 user8, token8 = generate_user() 

644 

645 make_friends(user1, user2) 

646 make_friends(user1, user3) 

647 make_friends(user1, user5) 

648 make_friends(user1, user7) 

649 make_friends(user1, user8) 

650 make_friends(user2, user3) 

651 make_friends(user4, user3) 

652 make_user_block(user1, user7) 

653 make_user_block(user8, user1) 

654 

655 with conversations_session(token1) as c: 

656 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user5.id])) 

657 group_chat_id = res.group_chat_id 

658 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

659 

660 # other user not in chat 

661 with conversations_session(token3) as c: 

662 with pytest.raises(grpc.RpcError) as e: 

663 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

664 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

665 with pytest.raises(grpc.RpcError) as e: 

666 res = c.InviteToGroupChat( 

667 conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user4.id) 

668 ) 

669 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

670 with pytest.raises(grpc.RpcError) as e: 

671 res = c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

672 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

673 

674 with conversations_session(token2) as c: 

675 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

676 assert not user3.id in res.member_user_ids 

677 

678 # only_admins_invite defaults to true so shouldn't be able to invite 

679 with pytest.raises(grpc.RpcError) as e: 

680 res = c.InviteToGroupChat( 

681 conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id) 

682 ) 

683 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

684 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

685 

686 with conversations_session(token1) as c: 

687 # invite invisible user fails 

688 with pytest.raises(grpc.RpcError) as e: 

689 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user6.id)) 

690 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

691 assert e.value.details() == errors.USER_NOT_FOUND 

692 # invite fake user fails 

693 with pytest.raises(grpc.RpcError) as e: 

694 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=999)) 

695 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

696 assert e.value.details() == errors.USER_NOT_FOUND 

697 # invite blocked user fails 

698 with pytest.raises(grpc.RpcError) as e: 

699 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user7.id)) 

700 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

701 assert e.value.details() == errors.USER_NOT_FOUND 

702 # invite blocking user fails 

703 with pytest.raises(grpc.RpcError) as e: 

704 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user8.id)) 

705 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

706 assert e.value.details() == errors.USER_NOT_FOUND 

707 

708 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

709 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

710 assert user1.id in res.member_user_ids 

711 assert user5.id in res.member_user_ids 

712 assert user3.id in res.member_user_ids 

713 

714 # test non-admin inviting 

715 c.EditGroupChat( 

716 conversations_pb2.EditGroupChatReq( 

717 group_chat_id=group_chat_id, only_admins_invite=wrappers_pb2.BoolValue(value=False) 

718 ) 

719 ) 

720 

721 with conversations_session(token3) as c: 

722 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user2.id)) 

723 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

724 assert user2.id in res.member_user_ids 

725 

726 

727def test_group_chats_with_messages_before_join(db): 

728 """ 

729 If user 1 and 2 have a group chat and send messages, then add user 3; user 3 

730 should still see the group chat! 

731 """ 

732 user1, token1 = generate_user() 

733 user2, token2 = generate_user() 

734 user3, token3 = generate_user() 

735 user4, token4 = generate_user() 

736 

737 make_friends(user1, user2) 

738 make_friends(user1, user3) 

739 make_friends(user2, user3) 

740 make_friends(user1, user4) 

741 

742 with conversations_session(token1) as c: 

743 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id])) 

744 group_chat_id = res.group_chat_id 

745 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

746 

747 with conversations_session(token2) as c: 

748 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 2")) 

749 

750 with conversations_session(token1) as c: 

751 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 3")) 

752 

753 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

754 

755 with conversations_session(token3) as c: 

756 # should work 

757 c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=group_chat_id)) 

758 

759 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq()) 

760 assert len(res.group_chats) == 1 

761 

762 

763def test_invite_to_dm(db): 

764 user1, token1 = generate_user() 

765 user2, token2 = generate_user() 

766 user3, token3 = generate_user() 

767 

768 make_friends(user1, user2) 

769 make_friends(user1, user3) 

770 make_friends(user2, user3) 

771 

772 with conversations_session(token1) as c: 

773 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

774 group_chat_id = res.group_chat_id 

775 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

776 

777 # dm, shou;dn't be able to invite someone else 

778 with pytest.raises(grpc.RpcError) as e: 

779 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

780 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

781 assert e.value.details() == errors.CANT_INVITE_TO_DM 

782 

783 

784def test_sole_admin_leaves(db): 

785 user1, token1 = generate_user() 

786 user2, token2 = generate_user() 

787 user3, token3 = generate_user() 

788 

789 make_friends(user1, user2) 

790 make_friends(user1, user3) 

791 make_friends(user2, user3) 

792 

793 with conversations_session(token1) as c: 

794 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

795 group_chat_id = res.group_chat_id 

796 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 1")) 

797 

798 # sole admin can't leave group chat 

799 with pytest.raises(grpc.RpcError) as e: 

800 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

801 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

802 assert e.value.details() == errors.LAST_ADMIN_CANT_LEAVE 

803 

804 with conversations_session(token2) as c: 

805 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

806 

807 with conversations_session(token3) as c: 

808 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

809 

810 # sole admin can leave when last in chat 

811 with conversations_session(token1) as c: 

812 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

813 

814 

815def test_search_messages(db): 

816 user1, token1 = generate_user() 

817 user2, token2 = generate_user() 

818 user3, token3 = generate_user() 

819 

820 make_friends(user1, user2) 

821 make_friends(user1, user3) 

822 

823 with conversations_session(token1) as c: 

824 # create some threads with messages 

825 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

826 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 1")) 

827 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test message 2")) 

828 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

829 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 3")) 

830 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res.group_chat_id, text="Test group message 4")) 

831 

832 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="message ")) 

833 assert len(res.results) == 4 

834 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="group ")) 

835 assert len(res.results) == 2 

836 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="message 5")) 

837 assert len(res.results) == 0 

838 

839 # outside user doesn't get results 

840 with conversations_session(token3) as c: 

841 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message")) 

842 assert len(res.results) == 0 

843 

844 

845def test_search_messages_left_joined(db): 

846 user1, token1 = generate_user() 

847 user2, token2 = generate_user() 

848 user3, token3 = generate_user() 

849 user4, token4 = generate_user() 

850 make_friends(user1, user2) 

851 make_friends(user1, user3) 

852 make_friends(user1, user4) 

853 start_time = now() 

854 

855 with conversations_session(token1) as c: 

856 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user4.id])) 

857 group_chat_id = res.group_chat_id 

858 for i in range(10): 

859 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message " + str(i))) 

860 

861 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

862 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 10")) 

863 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message")) 

864 

865 assert len(res.results) == 11 

866 

867 with conversations_session(token3) as c: 

868 # can only see last message after invited 

869 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message")) 

870 

871 assert len(res.results) == 1 

872 assert res.results[0].message.text.text == "Test message 10" 

873 

874 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=group_chat_id)) 

875 

876 with conversations_session(token1) as c: 

877 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 11")) 

878 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 12")) 

879 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=group_chat_id, user_id=user3.id)) 

880 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 13")) 

881 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=group_chat_id, text="Test message 14")) 

882 

883 with conversations_session(token3) as c: 

884 # can only see last message after invited 

885 res = c.SearchMessages(conversations_pb2.SearchMessagesReq(query="Test message")) 

886 assert len(res.results) == 3 

887 assert res.results[0].message.text.text == "Test message 14" 

888 assert res.results[1].message.text.text == "Test message 13" 

889 assert res.results[2].message.text.text == "Test message 10" 

890 

891 

892def test_admin_behaviour(db): 

893 user1, token1 = generate_user() 

894 user2, token2 = generate_user() 

895 user3, token3 = generate_user() 

896 

897 make_friends(user1, user2) 

898 make_friends(user1, user3) 

899 make_friends(user2, user3) 

900 

901 with conversations_session(token1) as c: 

902 gcid = c.CreateGroupChat( 

903 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]) 

904 ).group_chat_id 

905 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id)) 

906 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

907 assert len(res.admin_user_ids) == 2 

908 assert user1.id in res.admin_user_ids 

909 assert user2.id in res.admin_user_ids 

910 

911 with conversations_session(token3) as c: 

912 with pytest.raises(grpc.RpcError) as e: 

913 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

914 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

915 with pytest.raises(grpc.RpcError) as e: 

916 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id)) 

917 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

918 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

919 assert len(res.admin_user_ids) == 2 

920 assert user1.id in res.admin_user_ids 

921 assert user2.id in res.admin_user_ids 

922 

923 with conversations_session(token2) as c: 

924 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

925 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

926 assert len(res.admin_user_ids) == 3 

927 assert user1.id in res.admin_user_ids 

928 assert user2.id in res.admin_user_ids 

929 assert user3.id in res.admin_user_ids 

930 

931 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id)) 

932 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

933 assert len(res.admin_user_ids) == 2 

934 assert user2.id in res.admin_user_ids 

935 assert user3.id in res.admin_user_ids 

936 

937 with conversations_session(token1) as c: 

938 with pytest.raises(grpc.RpcError): 

939 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id)) 

940 with pytest.raises(grpc.RpcError): 

941 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

942 with pytest.raises(grpc.RpcError): 

943 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id)) 

944 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

945 assert len(res.admin_user_ids) == 2 

946 assert user2.id in res.admin_user_ids 

947 assert user3.id in res.admin_user_ids 

948 

949 with conversations_session(token2) as c: 

950 # can demote self if there are other admins 

951 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user2.id)) 

952 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

953 assert len(res.admin_user_ids) == 1 

954 assert user3.id in res.admin_user_ids 

955 

956 with conversations_session(token3) as c: 

957 with pytest.raises(grpc.RpcError) as e: 

958 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

959 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

960 assert e.value.details() == errors.CANT_REMOVE_LAST_ADMIN 

961 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

962 assert len(res.admin_user_ids) == 1 

963 assert user3.id in res.admin_user_ids 

964 

965 # last admin can't leave 

966 with pytest.raises(grpc.RpcError) as e: 

967 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid)) 

968 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

969 assert e.value.details() == errors.LAST_ADMIN_CANT_LEAVE 

970 

971 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user1.id)) 

972 

973 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid)) 

974 

975 with conversations_session(token2) as c: 

976 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid)) 

977 

978 # last participant must be admin but can leave to orphan chat 

979 with conversations_session(token1) as c: 

980 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid)) 

981 

982 

983def test_add_remove_admin_failures(db): 

984 user1, token1 = generate_user() 

985 user2, token2 = generate_user() 

986 user3, token3 = generate_user() 

987 user4, token4 = generate_user() 

988 user5, token5 = generate_user() 

989 

990 make_friends(user1, user2) 

991 make_friends(user1, user3) 

992 make_friends(user1, user4) 

993 make_friends(user1, user5) 

994 

995 with conversations_session(token1) as c: 

996 gcid = c.CreateGroupChat( 

997 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id, user4.id, user5.id]) 

998 ).group_chat_id 

999 

1000 make_user_invisible(user3.id) 

1001 make_user_block(user1, user4) 

1002 make_user_block(user5, user1) 

1003 

1004 # make non-existent user admin 

1005 with pytest.raises(grpc.RpcError) as e: 

1006 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=999)) 

1007 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1008 assert e.value.details() == errors.USER_NOT_FOUND 

1009 

1010 # make invisible user admin 

1011 with pytest.raises(grpc.RpcError) as e: 

1012 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

1013 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1014 assert e.value.details() == errors.USER_NOT_FOUND 

1015 

1016 # make blocked user admin 

1017 with pytest.raises(grpc.RpcError) as e: 

1018 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user4.id)) 

1019 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1020 assert e.value.details() == errors.USER_NOT_FOUND 

1021 

1022 # make blocking user admin 

1023 with pytest.raises(grpc.RpcError) as e: 

1024 c.MakeGroupChatAdmin(conversations_pb2.MakeGroupChatAdminReq(group_chat_id=gcid, user_id=user5.id)) 

1025 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1026 assert e.value.details() == errors.USER_NOT_FOUND 

1027 

1028 with session_scope() as session: 

1029 subscriptions = ( 

1030 session.execute( 

1031 select(GroupChatSubscription) 

1032 .where(GroupChatSubscription.group_chat_id == gcid) 

1033 .where(GroupChatSubscription.role == GroupChatRole.participant) 

1034 ) 

1035 .scalars() 

1036 .all() 

1037 ) 

1038 

1039 for subscription in subscriptions: 

1040 subscription.role = GroupChatRole.admin 

1041 

1042 with conversations_session(token1) as c: 

1043 # remove non-existent user admin 

1044 with pytest.raises(grpc.RpcError) as e: 

1045 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=999)) 

1046 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1047 assert e.value.details() == errors.USER_NOT_FOUND 

1048 

1049 # remove invisible admin 

1050 with pytest.raises(grpc.RpcError) as e: 

1051 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user3.id)) 

1052 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1053 assert e.value.details() == errors.USER_NOT_FOUND 

1054 

1055 # remove blocked admin 

1056 with pytest.raises(grpc.RpcError) as e: 

1057 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user4.id)) 

1058 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1059 assert e.value.details() == errors.USER_NOT_FOUND 

1060 

1061 # remove blocking admin 

1062 with pytest.raises(grpc.RpcError) as e: 

1063 c.RemoveGroupChatAdmin(conversations_pb2.RemoveGroupChatAdminReq(group_chat_id=gcid, user_id=user5.id)) 

1064 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1065 assert e.value.details() == errors.USER_NOT_FOUND 

1066 

1067 

1068def test_last_seen(db): 

1069 user1, token1 = generate_user() 

1070 user2, token2 = generate_user() 

1071 user3, token3 = generate_user() 

1072 

1073 make_friends(user1, user2) 

1074 make_friends(user1, user3) 

1075 make_friends(user2, user3) 

1076 

1077 with conversations_session(token3) as c: 

1078 # this is just here to mess up any issues we get if we pretend there's only one group chat ever 

1079 gcid_distraction = c.CreateGroupChat( 

1080 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user1.id]) 

1081 ).group_chat_id 

1082 

1083 with conversations_session(token1) as c: 

1084 gcid = c.CreateGroupChat( 

1085 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]) 

1086 ).group_chat_id 

1087 

1088 message_ids = [] 

1089 

1090 for i in range(6): 

1091 c.SendMessage( 

1092 conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"gibberish message... {i}") 

1093 ) 

1094 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}")) 

1095 c.SendMessage( 

1096 conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"gibberish message {i}") 

1097 ) 

1098 

1099 message_ids.append( 

1100 c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)).latest_message.message_id 

1101 ) 

1102 

1103 # messages are automatically marked as seen when you send a new message 

1104 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1105 assert res.unseen_message_count == 0 

1106 

1107 with conversations_session(token2) as c: 

1108 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1109 # created + 6 normal 

1110 assert res.unseen_message_count == 7 

1111 

1112 backward_offset = 3 

1113 c.MarkLastSeenGroupChat( 

1114 conversations_pb2.MarkLastSeenGroupChatReq( 

1115 group_chat_id=gcid, last_seen_message_id=message_ids[-backward_offset - 1] 

1116 ) 

1117 ) 

1118 

1119 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1120 assert res.unseen_message_count == backward_offset 

1121 

1122 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message ...")) 

1123 

1124 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1125 assert res.unseen_message_count == 0 

1126 

1127 with conversations_session(token3) as c: 

1128 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1129 # created + 7 normal 

1130 assert res.unseen_message_count == 8 

1131 

1132 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message ...")) 

1133 

1134 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1135 assert res.unseen_message_count == 0 

1136 

1137 

1138def test_one_dm_per_pair(db): 

1139 user1, token1 = generate_user() 

1140 user2, token2 = generate_user() 

1141 user3, token3 = generate_user() 

1142 

1143 make_friends(user1, user2) 

1144 make_friends(user1, user3) 

1145 make_friends(user2, user3) 

1146 

1147 with conversations_session(token1) as c: 

1148 # create DM with user 2 

1149 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

1150 assert res.is_dm 

1151 

1152 # create DM with user 3 

1153 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

1154 assert res.is_dm 

1155 

1156 # can't create another group chat with just user 2 

1157 with pytest.raises(grpc.RpcError) as e: 

1158 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

1159 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

1160 

1161 # can't create another group chat with just user 3 

1162 with pytest.raises(grpc.RpcError) as e: 

1163 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

1164 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

1165 

1166 # can create joined group chat 

1167 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

1168 assert not res.is_dm 

1169 

1170 with conversations_session(token2) as c: 

1171 # can create DM with user 3 

1172 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

1173 assert res.is_dm 

1174 

1175 # can't create another group chat with just user 1 

1176 with pytest.raises(grpc.RpcError) as e: 

1177 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user1.id])) 

1178 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION 

1179 

1180 

1181def test_GetDirectMessage(db): 

1182 user1, token1 = generate_user() 

1183 user2, token2 = generate_user() 

1184 user3, token3 = generate_user() 

1185 

1186 make_friends(user1, user2) 

1187 make_friends(user1, user3) 

1188 make_friends(user2, user3) 

1189 

1190 with conversations_session(token1) as c: 

1191 # no group chat with user 2 

1192 with pytest.raises(grpc.RpcError) as e: 

1193 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user2.id)) 

1194 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1195 

1196 # no group chat with nor user 3 

1197 with pytest.raises(grpc.RpcError) as e: 

1198 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user3.id)) 

1199 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

1200 

1201 # create DM with user 2 

1202 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id])) 

1203 assert res.is_dm 

1204 gcid = res.group_chat_id 

1205 

1206 # now should exist 

1207 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user2.id)) 

1208 assert res.group_chat_id == gcid 

1209 

1210 # create DM with user 3 

1211 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

1212 assert res.is_dm 

1213 

1214 # can create joined group chat 

1215 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id])) 

1216 assert not res.is_dm 

1217 

1218 with conversations_session(token2) as c: 

1219 # can create DM with user 3 

1220 res = c.CreateGroupChat(conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user3.id])) 

1221 assert res.is_dm 

1222 gcid = res.group_chat_id 

1223 

1224 # DM with 3 should exist 

1225 res = c.GetDirectMessage(conversations_pb2.GetDirectMessageReq(user_id=user3.id)) 

1226 assert res.group_chat_id == gcid 

1227 

1228 

1229def test_total_unseen(db): 

1230 user1, token1 = generate_user() 

1231 user2, token2 = generate_user() 

1232 user3, token3 = generate_user() 

1233 

1234 # distractions 

1235 user4, token4 = generate_user() 

1236 

1237 make_friends(user1, user2) 

1238 make_friends(user1, user3) 

1239 make_friends(user2, user3) 

1240 

1241 # distractions 

1242 make_friends(user1, user4) 

1243 

1244 start_time = now() 

1245 

1246 with conversations_session(token1) as c: 

1247 # distractions 

1248 gcid_distraction = c.CreateGroupChat( 

1249 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user4.id]) 

1250 ).group_chat_id 

1251 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"distraction...")) 

1252 

1253 gcid = c.CreateGroupChat( 

1254 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]) 

1255 ).group_chat_id 

1256 

1257 for i in range(6): 

1258 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}")) 

1259 

1260 # distractions 

1261 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"distraction...")) 

1262 

1263 # messages are automatically marked as seen when you send a new message 

1264 with api_session(token1) as api: 

1265 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0 

1266 

1267 with api_session(token2) as api: 

1268 # chat created + 6 normal messages 

1269 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 7 

1270 

1271 # now leave chat with user2 

1272 with conversations_session(token2) as c: 

1273 c.LeaveGroupChat(conversations_pb2.LeaveGroupChatReq(group_chat_id=gcid)) 

1274 

1275 with api_session(token2) as api: 

1276 # seen messages becomes 0 when leaving 

1277 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0 

1278 

1279 with conversations_session(token1) as c: 

1280 # distractions 

1281 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"distraction...")) 

1282 

1283 # send more stuff without user 2 

1284 for i in range(3): 

1285 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}")) 

1286 

1287 # distractions 

1288 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"distraction...")) 

1289 

1290 with api_session(token2) as api: 

1291 # seen messages becomes 0 when leaving 

1292 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 0 

1293 

1294 with conversations_session(token1) as c: 

1295 # add user 2 back 

1296 c.InviteToGroupChat(conversations_pb2.InviteToGroupChatReq(group_chat_id=gcid, user_id=user2.id)) 

1297 

1298 # send more stuff with user 2 

1299 for i in range(12): 

1300 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid, text=f"test message {i}")) 

1301 

1302 # distractions 

1303 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=gcid_distraction, text=f"distraction...")) 

1304 

1305 with api_session(token2) as api: 

1306 # joined + 12 normal 

1307 assert api.Ping(api_pb2.PingReq()).unseen_message_count == 13 

1308 

1309 

1310def test_regression_ListGroupChats_pagination(db): 

1311 user1, token1 = generate_user() 

1312 user2, token2 = generate_user() 

1313 user3, token3 = generate_user() 

1314 

1315 make_friends(user1, user2) 

1316 make_friends(user1, user3) 

1317 

1318 with conversations_session(token1) as c: 

1319 # tuples of (group_chat_id, message_id) 

1320 group_chat_and_message_ids = [] 

1321 for i in range(50): 

1322 res1 = c.CreateGroupChat( 

1323 conversations_pb2.CreateGroupChatReq( 

1324 recipient_user_ids=[user2.id, user3.id], title=wrappers_pb2.StringValue(value=f"Chat {i}") 

1325 ) 

1326 ) 

1327 

1328 c.SendMessage(conversations_pb2.SendMessageReq(group_chat_id=res1.group_chat_id, text=f"Test message {i}")) 

1329 

1330 res2 = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=res1.group_chat_id)) 

1331 

1332 group_chat_and_message_ids.append((res2.group_chat_id, res2.latest_message.message_id)) 

1333 

1334 seen_group_chat_ids = [] 

1335 

1336 last_message_id = 0 

1337 more = True 

1338 while more: 

1339 res = c.ListGroupChats(conversations_pb2.ListGroupChatsReq(last_message_id=last_message_id)) 

1340 last_message_id = res.last_message_id 

1341 more = not res.no_more 

1342 

1343 seen_group_chat_ids.extend([chat.group_chat_id for chat in res.group_chats]) 

1344 

1345 assert set(seen_group_chat_ids) == set(x[0] for x in group_chat_and_message_ids), "Not all group chats returned" 

1346 

1347 

1348def test_muting(db): 

1349 user1, token1 = generate_user() 

1350 user2, token2 = generate_user() 

1351 user3, token3 = generate_user() 

1352 

1353 make_friends(user1, user2) 

1354 make_friends(user1, user3) 

1355 make_friends(user2, user3) 

1356 

1357 with conversations_session(token3) as c: 

1358 # this is just here to mess up any issues we get if we pretend there's only one group chat ever 

1359 gcid_distraction = c.CreateGroupChat( 

1360 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user1.id]) 

1361 ).group_chat_id 

1362 

1363 with conversations_session(token1) as c: 

1364 gcid = c.CreateGroupChat( 

1365 conversations_pb2.CreateGroupChatReq(recipient_user_ids=[user2.id, user3.id]) 

1366 ).group_chat_id 

1367 

1368 with conversations_session(token2) as c: 

1369 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1370 assert not res.mute_info.muted 

1371 assert not res.mute_info.HasField("muted_until") 

1372 

1373 c.MuteGroupChat(conversations_pb2.MuteGroupChatReq(group_chat_id=gcid, forever=True)) 

1374 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1375 assert res.mute_info.muted 

1376 assert not res.mute_info.HasField("muted_until") 

1377 

1378 c.MuteGroupChat(conversations_pb2.MuteGroupChatReq(group_chat_id=gcid, unmute=True)) 

1379 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1380 assert not res.mute_info.muted 

1381 assert not res.mute_info.HasField("muted_until") 

1382 

1383 c.MuteGroupChat( 

1384 conversations_pb2.MuteGroupChatReq( 

1385 group_chat_id=gcid, for_duration=Duration_from_timedelta(timedelta(hours=2)) 

1386 ) 

1387 ) 

1388 res = c.GetGroupChat(conversations_pb2.GetGroupChatReq(group_chat_id=gcid)) 

1389 assert res.mute_info.muted 

1390 assert res.mute_info.HasField("muted_until") 

1391 assert to_aware_datetime(res.mute_info.muted_until) >= now() + timedelta(hours=1, minutes=59) 

1392 assert to_aware_datetime(res.mute_info.muted_until) <= now() + timedelta(hours=2, minutes=1)