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

452 statements  

1from datetime import timedelta 

2 

3import grpc 

4import pytest 

5from sqlalchemy.sql import select 

6 

7from couchers import errors 

8from couchers.db import session_scope 

9from couchers.models import Message, MessageType 

10from couchers.utils import now, today 

11from proto import api_pb2, conversations_pb2, requests_pb2 

12from tests.test_fixtures import api_session, db, generate_user, requests_session, testconfig # noqa 

13 

14 

15@pytest.fixture(autouse=True) 

16def _(testconfig): 

17 pass 

18 

19 

20def test_create_request(db): 

21 user1, token1 = generate_user() 

22 user2, token2 = generate_user() 

23 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

24 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

25 today_minus_2 = (today() - timedelta(days=2)).isoformat() 

26 today_minus_3 = (today() - timedelta(days=3)).isoformat() 

27 with requests_session(token1) as api: 

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

29 api.CreateHostRequest( 

30 requests_pb2.CreateHostRequestReq( 

31 host_user_id=user1.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

32 ) 

33 ) 

34 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

35 assert e.value.details() == errors.CANT_REQUEST_SELF 

36 

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

38 api.CreateHostRequest( 

39 requests_pb2.CreateHostRequestReq( 

40 host_user_id=999, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

41 ) 

42 ) 

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

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

45 

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

47 api.CreateHostRequest( 

48 requests_pb2.CreateHostRequestReq( 

49 host_user_id=user2.id, from_date=today_plus_3, to_date=today_plus_2, text="Test request" 

50 ) 

51 ) 

52 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

53 assert e.value.details() == errors.DATE_FROM_AFTER_TO 

54 

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

56 api.CreateHostRequest( 

57 requests_pb2.CreateHostRequestReq( 

58 host_user_id=user2.id, from_date=today_minus_3, to_date=today_plus_2, text="Test request" 

59 ) 

60 ) 

61 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

62 assert e.value.details() == errors.DATE_FROM_BEFORE_TODAY 

63 

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

65 api.CreateHostRequest( 

66 requests_pb2.CreateHostRequestReq( 

67 host_user_id=user2.id, from_date=today_plus_2, to_date=today_minus_2, text="Test request" 

68 ) 

69 ) 

70 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

71 assert e.value.details() == errors.DATE_FROM_AFTER_TO 

72 

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

74 api.CreateHostRequest( 

75 requests_pb2.CreateHostRequestReq( 

76 host_user_id=user2.id, from_date="2020-00-06", to_date=today_minus_2, text="Test request" 

77 ) 

78 ) 

79 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

80 assert e.value.details() == errors.INVALID_DATE 

81 

82 res = api.CreateHostRequest( 

83 requests_pb2.CreateHostRequestReq( 

84 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

85 ) 

86 ) 

87 assert ( 

88 api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_sent=True)) 

89 .host_requests[0] 

90 .latest_message.text.text 

91 == "Test request" 

92 ) 

93 

94 today_ = today() 

95 today_plus_one_year = today_ + timedelta(days=365) 

96 today_plus_one_year_plus_2 = (today_plus_one_year + timedelta(days=2)).isoformat() 

97 today_plus_one_year_plus_3 = (today_plus_one_year + timedelta(days=3)).isoformat() 

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

99 api.CreateHostRequest( 

100 requests_pb2.CreateHostRequestReq( 

101 host_user_id=user2.id, 

102 from_date=today_plus_one_year_plus_2, 

103 to_date=today_plus_one_year_plus_3, 

104 text="Test from date after one year", 

105 ) 

106 ) 

107 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

108 assert e.value.details() == errors.DATE_FROM_AFTER_ONE_YEAR 

109 

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

111 api.CreateHostRequest( 

112 requests_pb2.CreateHostRequestReq( 

113 host_user_id=user2.id, 

114 from_date=today_plus_2, 

115 to_date=today_plus_one_year_plus_3, 

116 text="Test to date one year after from date", 

117 ) 

118 ) 

119 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

120 assert e.value.details() == errors.DATE_TO_AFTER_ONE_YEAR 

121 

122 

123def add_message(db, text, author_id, conversation_id): 

124 with session_scope() as session: 

125 message = Message( 

126 conversation_id=conversation_id, author_id=author_id, text=text, message_type=MessageType.text 

127 ) 

128 

129 session.add(message) 

130 

131 

132def test_GetHostRequest(db): 

133 user1, token1 = generate_user() 

134 user2, token2 = generate_user() 

135 user3, token3 = generate_user() 

136 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

137 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

138 with requests_session(token1) as api: 

139 host_request_id = api.CreateHostRequest( 

140 requests_pb2.CreateHostRequestReq( 

141 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

142 ) 

143 ).host_request_id 

144 

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

146 api.GetHostRequest(requests_pb2.GetHostRequestReq(host_request_id=999)) 

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

148 assert e.value.details() == errors.HOST_REQUEST_NOT_FOUND 

149 

150 api.SendHostRequestMessage( 

151 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 1") 

152 ) 

153 

154 res = api.GetHostRequest(requests_pb2.GetHostRequestReq(host_request_id=host_request_id)) 

155 assert res.latest_message.text.text == "Test message 1" 

156 

157 

158def test_ListHostRequests(db): 

159 user1, token1 = generate_user() 

160 user2, token2 = generate_user() 

161 user3, token3 = generate_user() 

162 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

163 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

164 with requests_session(token1) as api: 

165 host_request_1 = api.CreateHostRequest( 

166 requests_pb2.CreateHostRequestReq( 

167 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

168 ) 

169 ).host_request_id 

170 

171 host_request_2 = api.CreateHostRequest( 

172 requests_pb2.CreateHostRequestReq( 

173 host_user_id=user3.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 2" 

174 ) 

175 ).host_request_id 

176 

177 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_sent=True)) 

178 assert res.no_more 

179 assert len(res.host_requests) == 2 

180 

181 with requests_session(token2) as api: 

182 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

183 assert res.no_more 

184 assert len(res.host_requests) == 1 

185 assert res.host_requests[0].latest_message.text.text == "Test request 1" 

186 assert res.host_requests[0].surfer_user_id == user1.id 

187 assert res.host_requests[0].host_user_id == user2.id 

188 assert res.host_requests[0].status == conversations_pb2.HOST_REQUEST_STATUS_PENDING 

189 

190 add_message(db, "Test request 1 message 1", user2.id, host_request_1) 

191 add_message(db, "Test request 1 message 2", user2.id, host_request_1) 

192 add_message(db, "Test request 1 message 3", user2.id, host_request_1) 

193 

194 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

195 assert res.host_requests[0].latest_message.text.text == "Test request 1 message 3" 

196 

197 api.CreateHostRequest( 

198 requests_pb2.CreateHostRequestReq( 

199 host_user_id=user1.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 3" 

200 ) 

201 ) 

202 

203 add_message(db, "Test request 2 message 1", user1.id, host_request_2) 

204 add_message(db, "Test request 2 message 2", user3.id, host_request_2) 

205 

206 with requests_session(token3) as api: 

207 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

208 assert res.no_more 

209 assert len(res.host_requests) == 1 

210 assert res.host_requests[0].latest_message.text.text == "Test request 2 message 2" 

211 

212 with requests_session(token1) as api: 

213 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

214 assert len(res.host_requests) == 1 

215 

216 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq()) 

217 assert len(res.host_requests) == 3 

218 

219 

220def test_ListHostRequests_pagination_regression(db): 

221 """ 

222 ListHostRequests was skipping a request when getting multiple pages 

223 """ 

224 user1, token1 = generate_user() 

225 user2, token2 = generate_user() 

226 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

227 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

228 with requests_session(token1) as api: 

229 host_request_1 = api.CreateHostRequest( 

230 requests_pb2.CreateHostRequestReq( 

231 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

232 ) 

233 ).host_request_id 

234 

235 host_request_2 = api.CreateHostRequest( 

236 requests_pb2.CreateHostRequestReq( 

237 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 2" 

238 ) 

239 ).host_request_id 

240 

241 host_request_3 = api.CreateHostRequest( 

242 requests_pb2.CreateHostRequestReq( 

243 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 3" 

244 ) 

245 ).host_request_id 

246 

247 with requests_session(token2) as api: 

248 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

249 assert res.no_more 

250 assert len(res.host_requests) == 3 

251 assert res.host_requests[0].latest_message.text.text == "Test request 3" 

252 assert res.host_requests[1].latest_message.text.text == "Test request 2" 

253 assert res.host_requests[2].latest_message.text.text == "Test request 1" 

254 

255 with requests_session(token2) as api: 

256 api.RespondHostRequest( 

257 requests_pb2.RespondHostRequestReq( 

258 host_request_id=host_request_2, 

259 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

260 text="Accepting host request 2", 

261 ) 

262 ) 

263 api.RespondHostRequest( 

264 requests_pb2.RespondHostRequestReq( 

265 host_request_id=host_request_1, 

266 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

267 text="Accepting host request 1", 

268 ) 

269 ) 

270 api.RespondHostRequest( 

271 requests_pb2.RespondHostRequestReq( 

272 host_request_id=host_request_3, 

273 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

274 text="Accepting host request 3", 

275 ) 

276 ) 

277 

278 with requests_session(token2) as api: 

279 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

280 assert res.no_more 

281 assert len(res.host_requests) == 3 

282 assert res.host_requests[0].latest_message.text.text == "Accepting host request 3" 

283 assert res.host_requests[1].latest_message.text.text == "Accepting host request 1" 

284 assert res.host_requests[2].latest_message.text.text == "Accepting host request 2" 

285 

286 with requests_session(token2) as api: 

287 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True, number=1)) 

288 assert not res.no_more 

289 assert len(res.host_requests) == 1 

290 assert res.host_requests[0].latest_message.text.text == "Accepting host request 3" 

291 res = api.ListHostRequests( 

292 requests_pb2.ListHostRequestsReq(only_received=True, number=1, last_request_id=res.last_request_id) 

293 ) 

294 assert not res.no_more 

295 assert len(res.host_requests) == 1 

296 assert res.host_requests[0].latest_message.text.text == "Accepting host request 1" 

297 res = api.ListHostRequests( 

298 requests_pb2.ListHostRequestsReq(only_received=True, number=1, last_request_id=res.last_request_id) 

299 ) 

300 assert res.no_more 

301 assert len(res.host_requests) == 1 

302 assert res.host_requests[0].latest_message.text.text == "Accepting host request 2" 

303 

304 

305def test_ListHostRequests_active_filter(db): 

306 user1, token1 = generate_user() 

307 user2, token2 = generate_user() 

308 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

309 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

310 

311 with requests_session(token1) as api: 

312 request_id = api.CreateHostRequest( 

313 requests_pb2.CreateHostRequestReq( 

314 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

315 ) 

316 ).host_request_id 

317 api.RespondHostRequest( 

318 requests_pb2.RespondHostRequestReq( 

319 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

320 ) 

321 ) 

322 

323 with requests_session(token2) as api: 

324 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_received=True)) 

325 assert len(res.host_requests) == 1 

326 res = api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_active=True)) 

327 assert len(res.host_requests) == 0 

328 

329 

330def test_RespondHostRequests(db): 

331 user1, token1 = generate_user() 

332 user2, token2 = generate_user() 

333 user3, token3 = generate_user() 

334 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

335 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

336 

337 with requests_session(token1) as api: 

338 request_id = api.CreateHostRequest( 

339 requests_pb2.CreateHostRequestReq( 

340 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

341 ) 

342 ).host_request_id 

343 

344 # another user can't access 

345 with requests_session(token3) as api: 

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

347 api.RespondHostRequest( 

348 requests_pb2.RespondHostRequestReq( 

349 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

350 ) 

351 ) 

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

353 assert e.value.details() == errors.HOST_REQUEST_NOT_FOUND 

354 

355 with requests_session(token1) as api: 

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

357 api.RespondHostRequest( 

358 requests_pb2.RespondHostRequestReq( 

359 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

360 ) 

361 ) 

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

363 assert e.value.details() == errors.NOT_THE_HOST 

364 

365 with requests_session(token2) as api: 

366 # non existing id 

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

368 api.RespondHostRequest( 

369 requests_pb2.RespondHostRequestReq( 

370 host_request_id=9999, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

371 ) 

372 ) 

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

374 

375 # host can't confirm or cancel (host should accept/reject) 

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

377 api.RespondHostRequest( 

378 requests_pb2.RespondHostRequestReq( 

379 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED 

380 ) 

381 ) 

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

383 assert e.value.details() == errors.INVALID_HOST_REQUEST_STATUS 

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

385 api.RespondHostRequest( 

386 requests_pb2.RespondHostRequestReq( 

387 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

388 ) 

389 ) 

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

391 assert e.value.details() == errors.INVALID_HOST_REQUEST_STATUS 

392 

393 api.RespondHostRequest( 

394 requests_pb2.RespondHostRequestReq( 

395 host_request_id=request_id, 

396 status=conversations_pb2.HOST_REQUEST_STATUS_REJECTED, 

397 text="Test rejection message", 

398 ) 

399 ) 

400 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=request_id)) 

401 assert res.messages[0].text.text == "Test rejection message" 

402 assert res.messages[1].WhichOneof("content") == "host_request_status_changed" 

403 assert res.messages[1].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_REJECTED 

404 # should be able to move from rejected -> accepted 

405 api.RespondHostRequest( 

406 requests_pb2.RespondHostRequestReq( 

407 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

408 ) 

409 ) 

410 

411 with requests_session(token1) as api: 

412 # can't make pending 

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

414 api.RespondHostRequest( 

415 requests_pb2.RespondHostRequestReq( 

416 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_PENDING 

417 ) 

418 ) 

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

420 assert e.value.details() == errors.INVALID_HOST_REQUEST_STATUS 

421 

422 # can confirm then cancel 

423 api.RespondHostRequest( 

424 requests_pb2.RespondHostRequestReq( 

425 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED 

426 ) 

427 ) 

428 

429 api.RespondHostRequest( 

430 requests_pb2.RespondHostRequestReq( 

431 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

432 ) 

433 ) 

434 

435 # can't confirm after having cancelled 

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

437 api.RespondHostRequest( 

438 requests_pb2.RespondHostRequestReq( 

439 host_request_id=request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED 

440 ) 

441 ) 

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

443 assert e.value.details() == errors.INVALID_HOST_REQUEST_STATUS 

444 

445 # at this point there should be 7 messages 

446 # 2 for creation, 2 for the status change with message, 3 for the other status changed 

447 with requests_session(token1) as api: 

448 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=request_id)) 

449 assert len(res.messages) == 7 

450 assert res.messages[0].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

451 assert res.messages[1].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED 

452 assert res.messages[2].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

453 assert res.messages[4].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_REJECTED 

454 assert res.messages[6].WhichOneof("content") == "chat_created" 

455 

456 

457def test_get_host_request_messages(db): 

458 user1, token1 = generate_user() 

459 user2, token2 = generate_user() 

460 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

461 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

462 with requests_session(token1) as api: 

463 res = api.CreateHostRequest( 

464 requests_pb2.CreateHostRequestReq( 

465 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

466 ) 

467 ) 

468 conversation_id = res.host_request_id 

469 

470 add_message(db, "Test request 1 message 1", user1.id, conversation_id) 

471 add_message(db, "Test request 1 message 2", user1.id, conversation_id) 

472 add_message(db, "Test request 1 message 3", user1.id, conversation_id) 

473 

474 with requests_session(token2) as api: 

475 api.RespondHostRequest( 

476 requests_pb2.RespondHostRequestReq( 

477 host_request_id=conversation_id, status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

478 ) 

479 ) 

480 

481 add_message(db, "Test request 1 message 4", user2.id, conversation_id) 

482 add_message(db, "Test request 1 message 5", user2.id, conversation_id) 

483 

484 api.RespondHostRequest( 

485 requests_pb2.RespondHostRequestReq( 

486 host_request_id=conversation_id, status=conversations_pb2.HOST_REQUEST_STATUS_REJECTED 

487 ) 

488 ) 

489 

490 with requests_session(token1) as api: 

491 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=conversation_id)) 

492 # 9 including initial message 

493 assert len(res.messages) == 9 

494 assert res.no_more 

495 

496 res = api.GetHostRequestMessages( 

497 requests_pb2.GetHostRequestMessagesReq(host_request_id=conversation_id, number=3) 

498 ) 

499 assert not res.no_more 

500 assert len(res.messages) == 3 

501 assert res.messages[0].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_REJECTED 

502 assert res.messages[0].WhichOneof("content") == "host_request_status_changed" 

503 assert res.messages[1].text.text == "Test request 1 message 5" 

504 assert res.messages[2].text.text == "Test request 1 message 4" 

505 

506 res = api.GetHostRequestMessages( 

507 requests_pb2.GetHostRequestMessagesReq( 

508 host_request_id=conversation_id, last_message_id=res.messages[2].message_id, number=6 

509 ) 

510 ) 

511 assert res.no_more 

512 assert len(res.messages) == 6 

513 assert res.messages[0].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

514 assert res.messages[0].WhichOneof("content") == "host_request_status_changed" 

515 assert res.messages[1].text.text == "Test request 1 message 3" 

516 assert res.messages[2].text.text == "Test request 1 message 2" 

517 assert res.messages[3].text.text == "Test request 1 message 1" 

518 assert res.messages[4].text.text == "Test request 1" 

519 assert res.messages[5].WhichOneof("content") == "chat_created" 

520 

521 

522def test_SendHostRequestMessage(db): 

523 user1, token1 = generate_user() 

524 user2, token2 = generate_user() 

525 user3, token3 = generate_user() 

526 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

527 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

528 with requests_session(token1) as api: 

529 host_request_id = api.CreateHostRequest( 

530 requests_pb2.CreateHostRequestReq( 

531 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request 1" 

532 ) 

533 ).host_request_id 

534 

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

536 api.SendHostRequestMessage( 

537 requests_pb2.SendHostRequestMessageReq(host_request_id=999, text="Test message 1") 

538 ) 

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

540 

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

542 api.SendHostRequestMessage(requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="")) 

543 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

544 assert e.value.details() == errors.INVALID_MESSAGE 

545 

546 api.SendHostRequestMessage( 

547 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 1") 

548 ) 

549 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=host_request_id)) 

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

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

552 

553 with requests_session(token3) as api: 

554 # other user can't send 

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

556 api.SendHostRequestMessage( 

557 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 2") 

558 ) 

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

560 assert e.value.details() == errors.HOST_REQUEST_NOT_FOUND 

561 

562 with requests_session(token2) as api: 

563 api.SendHostRequestMessage( 

564 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 2") 

565 ) 

566 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=host_request_id)) 

567 # including 2 for creation control message and message 

568 assert len(res.messages) == 4 

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

570 assert res.messages[0].author_user_id == user2.id 

571 

572 # can't send messages to a rejected, confirmed or cancelled request, but can for accepted 

573 api.RespondHostRequest( 

574 requests_pb2.RespondHostRequestReq( 

575 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_REJECTED 

576 ) 

577 ) 

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

579 api.SendHostRequestMessage( 

580 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 3") 

581 ) 

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

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

584 

585 api.RespondHostRequest( 

586 requests_pb2.RespondHostRequestReq( 

587 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED 

588 ) 

589 ) 

590 

591 with requests_session(token1) as api: 

592 api.RespondHostRequest( 

593 requests_pb2.RespondHostRequestReq( 

594 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED 

595 ) 

596 ) 

597 api.SendHostRequestMessage( 

598 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 3") 

599 ) 

600 

601 api.RespondHostRequest( 

602 requests_pb2.RespondHostRequestReq( 

603 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

604 ) 

605 ) 

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

607 api.SendHostRequestMessage( 

608 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 3") 

609 ) 

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

611 assert e.value.details() == errors.HOST_REQUEST_CLOSED 

612 

613 

614def test_get_updates(db): 

615 user1, token1 = generate_user() 

616 user2, token2 = generate_user() 

617 user3, token3 = generate_user() 

618 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

619 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

620 with requests_session(token1) as api: 

621 host_request_id = api.CreateHostRequest( 

622 requests_pb2.CreateHostRequestReq( 

623 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test message 0" 

624 ) 

625 ).host_request_id 

626 

627 api.SendHostRequestMessage( 

628 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 1") 

629 ) 

630 api.SendHostRequestMessage( 

631 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 2") 

632 ) 

633 api.RespondHostRequest( 

634 requests_pb2.RespondHostRequestReq( 

635 host_request_id=host_request_id, 

636 status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED, 

637 text="Test message 3", 

638 ) 

639 ) 

640 

641 api.CreateHostRequest( 

642 requests_pb2.CreateHostRequestReq( 

643 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test message 4" 

644 ) 

645 ) 

646 

647 res = api.GetHostRequestMessages(requests_pb2.GetHostRequestMessagesReq(host_request_id=host_request_id)) 

648 assert len(res.messages) == 6 

649 assert res.messages[0].text.text == "Test message 3" 

650 assert res.messages[1].host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

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

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

653 assert res.messages[4].text.text == "Test message 0" 

654 message_id_3 = res.messages[0].message_id 

655 message_id_cancel = res.messages[1].message_id 

656 message_id_2 = res.messages[2].message_id 

657 message_id_1 = res.messages[3].message_id 

658 message_id_0 = res.messages[4].message_id 

659 

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

661 api.GetHostRequestUpdates(requests_pb2.GetHostRequestUpdatesReq(newest_message_id=0)) 

662 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

663 

664 res = api.GetHostRequestUpdates(requests_pb2.GetHostRequestUpdatesReq(newest_message_id=message_id_1)) 

665 assert res.no_more 

666 assert len(res.updates) == 5 

667 assert res.updates[0].message.text.text == "Test message 2" 

668 assert ( 

669 res.updates[1].message.host_request_status_changed.status == conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

670 ) 

671 assert res.updates[1].status == conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

672 assert res.updates[2].message.text.text == "Test message 3" 

673 assert res.updates[3].message.WhichOneof("content") == "chat_created" 

674 assert res.updates[3].status == conversations_pb2.HOST_REQUEST_STATUS_PENDING 

675 assert res.updates[4].message.text.text == "Test message 4" 

676 

677 res = api.GetHostRequestUpdates(requests_pb2.GetHostRequestUpdatesReq(newest_message_id=message_id_1, number=1)) 

678 assert not res.no_more 

679 assert len(res.updates) == 1 

680 assert res.updates[0].message.text.text == "Test message 2" 

681 assert res.updates[0].status == conversations_pb2.HOST_REQUEST_STATUS_CANCELLED 

682 

683 with requests_session(token3) as api: 

684 # other user can't access 

685 res = api.GetHostRequestUpdates(requests_pb2.GetHostRequestUpdatesReq(newest_message_id=message_id_1)) 

686 assert len(res.updates) == 0 

687 

688 

689def test_mark_last_seen(db): 

690 user1, token1 = generate_user() 

691 user2, token2 = generate_user() 

692 user3, token3 = generate_user() 

693 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

694 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

695 with requests_session(token1) as api: 

696 host_request_id = api.CreateHostRequest( 

697 requests_pb2.CreateHostRequestReq( 

698 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test message 0" 

699 ) 

700 ).host_request_id 

701 

702 host_request_id_2 = api.CreateHostRequest( 

703 requests_pb2.CreateHostRequestReq( 

704 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test message 0a" 

705 ) 

706 ).host_request_id 

707 

708 api.SendHostRequestMessage( 

709 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 1") 

710 ) 

711 api.SendHostRequestMessage( 

712 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id, text="Test message 2") 

713 ) 

714 api.RespondHostRequest( 

715 requests_pb2.RespondHostRequestReq( 

716 host_request_id=host_request_id, 

717 status=conversations_pb2.HOST_REQUEST_STATUS_CANCELLED, 

718 text="Test message 3", 

719 ) 

720 ) 

721 

722 # test Ping unseen host request count, should be automarked after sending 

723 with api_session(token1) as api: 

724 assert api.Ping(api_pb2.PingReq()).unseen_received_host_request_count == 0 

725 assert api.Ping(api_pb2.PingReq()).unseen_sent_host_request_count == 0 

726 

727 with api_session(token2) as api: 

728 assert api.Ping(api_pb2.PingReq()).unseen_received_host_request_count == 2 

729 assert api.Ping(api_pb2.PingReq()).unseen_sent_host_request_count == 0 

730 

731 with requests_session(token2) as api: 

732 assert api.ListHostRequests(requests_pb2.ListHostRequestsReq()).host_requests[0].last_seen_message_id == 0 

733 

734 api.MarkLastSeenHostRequest( 

735 requests_pb2.MarkLastSeenHostRequestReq(host_request_id=host_request_id, last_seen_message_id=3) 

736 ) 

737 

738 assert api.ListHostRequests(requests_pb2.ListHostRequestsReq()).host_requests[0].last_seen_message_id == 3 

739 

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

741 api.MarkLastSeenHostRequest( 

742 requests_pb2.MarkLastSeenHostRequestReq(host_request_id=host_request_id, last_seen_message_id=1) 

743 ) 

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

745 assert e.value.details() == errors.CANT_UNSEE_MESSAGES 

746 

747 # this will be used to test sent request notifications 

748 host_request_id_3 = api.CreateHostRequest( 

749 requests_pb2.CreateHostRequestReq( 

750 host_user_id=user1.id, from_date=today_plus_2, to_date=today_plus_3, text="Another test request" 

751 ) 

752 ).host_request_id 

753 

754 # this should make id_2 all read 

755 api.SendHostRequestMessage( 

756 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id_2, text="Test") 

757 ) 

758 

759 with api_session(token2) as api: 

760 assert api.Ping(api_pb2.PingReq()).unseen_received_host_request_count == 1 

761 assert api.Ping(api_pb2.PingReq()).unseen_sent_host_request_count == 0 

762 

763 # make sure sent and received count for unseen notifications 

764 with requests_session(token1) as api: 

765 api.SendHostRequestMessage( 

766 requests_pb2.SendHostRequestMessageReq(host_request_id=host_request_id_3, text="Test message") 

767 ) 

768 

769 with api_session(token2) as api: 

770 assert api.Ping(api_pb2.PingReq()).unseen_received_host_request_count == 1 

771 assert api.Ping(api_pb2.PingReq()).unseen_sent_host_request_count == 1 

772 

773 

774def test_response_rate(db): 

775 user1, token1 = generate_user() 

776 user2, token2 = generate_user() 

777 

778 today_plus_2 = (today() + timedelta(days=2)).isoformat() 

779 today_plus_3 = (today() + timedelta(days=3)).isoformat() 

780 

781 with requests_session(token1) as api: 

782 # no requests: insufficient 

783 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

784 assert res.HasField("insufficient_data") 

785 

786 # send a request and back date it by 36 hours 

787 host_request_1 = api.CreateHostRequest( 

788 requests_pb2.CreateHostRequestReq( 

789 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

790 ) 

791 ).host_request_id 

792 with session_scope() as session: 

793 session.execute( 

794 select(Message) 

795 .where(Message.conversation_id == host_request_1) 

796 .where(Message.message_type == MessageType.chat_created) 

797 ).scalar_one().time = now() - timedelta(hours=36) 

798 

799 # still insufficient 

800 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

801 assert res.HasField("insufficient_data") 

802 

803 # send a request and back date it by 35 hours 

804 host_request_2 = api.CreateHostRequest( 

805 requests_pb2.CreateHostRequestReq( 

806 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

807 ) 

808 ).host_request_id 

809 with session_scope() as session: 

810 session.execute( 

811 select(Message) 

812 .where(Message.conversation_id == host_request_2) 

813 .where(Message.message_type == MessageType.chat_created) 

814 ).scalar_one().time = now() - timedelta(hours=35) 

815 

816 # still insufficient 

817 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

818 assert res.HasField("insufficient_data") 

819 

820 # send a request and back date it by 34 hours 

821 host_request_3 = api.CreateHostRequest( 

822 requests_pb2.CreateHostRequestReq( 

823 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

824 ) 

825 ).host_request_id 

826 with session_scope() as session: 

827 session.execute( 

828 select(Message) 

829 .where(Message.conversation_id == host_request_3) 

830 .where(Message.message_type == MessageType.chat_created) 

831 ).scalar_one().time = now() - timedelta(hours=34) 

832 

833 # now low 

834 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

835 assert res.HasField("low") 

836 

837 with requests_session(token2) as api: 

838 # accept a host req 

839 api.RespondHostRequest( 

840 requests_pb2.RespondHostRequestReq( 

841 host_request_id=host_request_2, 

842 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

843 text="Accepting host request", 

844 ) 

845 ) 

846 

847 with requests_session(token1) as api: 

848 # now some w p33 = 35h 

849 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

850 assert res.HasField("some") 

851 assert res.some.response_time_p33.ToTimedelta() == timedelta(hours=35) 

852 

853 with requests_session(token2) as api: 

854 # accept another host req 

855 api.RespondHostRequest( 

856 requests_pb2.RespondHostRequestReq( 

857 host_request_id=host_request_3, 

858 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

859 text="Accepting host request", 

860 ) 

861 ) 

862 

863 with requests_session(token1) as api: 

864 # now most w p33 = 34h, p66 = 35h 

865 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

866 assert res.HasField("most") 

867 assert res.most.response_time_p33.ToTimedelta() == timedelta(hours=34) 

868 assert res.most.response_time_p66.ToTimedelta() == timedelta(hours=35) 

869 

870 with requests_session(token2) as api: 

871 # accept last host req 

872 api.RespondHostRequest( 

873 requests_pb2.RespondHostRequestReq( 

874 host_request_id=host_request_1, 

875 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

876 text="Accepting host request", 

877 ) 

878 ) 

879 

880 with requests_session(token1) as api: 

881 # now all w p33 = 34h, p66 = 35h 

882 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

883 assert res.HasField("almost_all") 

884 assert res.almost_all.response_time_p33.ToTimedelta() == timedelta(hours=34) 

885 assert res.almost_all.response_time_p66.ToTimedelta() == timedelta(hours=35) 

886 

887 # send a request and back date it by 2 hours 

888 host_request_4 = api.CreateHostRequest( 

889 requests_pb2.CreateHostRequestReq( 

890 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

891 ) 

892 ).host_request_id 

893 with session_scope() as session: 

894 session.execute( 

895 select(Message) 

896 .where(Message.conversation_id == host_request_4) 

897 .where(Message.message_type == MessageType.chat_created) 

898 ).scalar_one().time = now() - timedelta(hours=2) 

899 

900 # send a request and back date it by 4 hours 

901 host_request_5 = api.CreateHostRequest( 

902 requests_pb2.CreateHostRequestReq( 

903 host_user_id=user2.id, from_date=today_plus_2, to_date=today_plus_3, text="Test request" 

904 ) 

905 ).host_request_id 

906 with session_scope() as session: 

907 session.execute( 

908 select(Message) 

909 .where(Message.conversation_id == host_request_5) 

910 .where(Message.message_type == MessageType.chat_created) 

911 ).scalar_one().time = now() - timedelta(hours=4) 

912 

913 # now some w p33 = 35h 

914 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

915 assert res.HasField("some") 

916 assert res.some.response_time_p33.ToTimedelta() == timedelta(hours=35) 

917 

918 with requests_session(token2) as api: 

919 # accept host req 

920 api.RespondHostRequest( 

921 requests_pb2.RespondHostRequestReq( 

922 host_request_id=host_request_5, 

923 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

924 text="Accepting host request", 

925 ) 

926 ) 

927 

928 with requests_session(token1) as api: 

929 # now most w p33 = 34h, p66 = 36h 

930 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

931 assert res.HasField("most") 

932 assert res.most.response_time_p33.ToTimedelta() == timedelta(hours=34) 

933 assert res.most.response_time_p66.ToTimedelta() == timedelta(hours=36) 

934 

935 with requests_session(token2) as api: 

936 # accept host req 

937 api.RespondHostRequest( 

938 requests_pb2.RespondHostRequestReq( 

939 host_request_id=host_request_4, 

940 status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED, 

941 text="Accepting host request", 

942 ) 

943 ) 

944 

945 with requests_session(token1) as api: 

946 # now most w p33 = 4h, p66 = 35h 

947 res = api.GetResponseRate(requests_pb2.GetResponseRateReq(user_id=user2.id)) 

948 assert res.HasField("almost_all") 

949 assert res.almost_all.response_time_p33.ToTimedelta() == timedelta(hours=4) 

950 assert res.almost_all.response_time_p66.ToTimedelta() == timedelta(hours=35)