Coverage for src/tests/test_references.py: 100%
592 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-20 11:53 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-20 11:53 +0000
1from datetime import timedelta
2from unittest.mock import patch
4import grpc
5import pytest
6from google.protobuf import empty_pb2
7from sqlalchemy import update
8from sqlalchemy.orm import Session
10from couchers.db import session_scope
11from couchers.materialized_views import refresh_materialized_views_rapid
12from couchers.models import (
13 Conversation,
14 FriendRelationship,
15 FriendStatus,
16 HostRequest,
17 HostRequestStatus,
18 Message,
19 MessageType,
20 ModerationObjectType,
21 Reference,
22 ReferenceType,
23 User,
24)
25from couchers.moderation.utils import create_moderation
26from couchers.proto import conversations_pb2, references_pb2, requests_pb2
27from couchers.sql import couchers_select as select
28from couchers.utils import create_coordinate, now, to_aware_datetime, today
29from tests.test_fixtures import ( # noqa
30 account_session,
31 db,
32 email_fields,
33 generate_user,
34 make_friends,
35 make_user_block,
36 mock_notification_email,
37 moderator,
38 push_collector,
39 references_session,
40 requests_session,
41 testconfig,
42)
43from tests.test_requests import valid_request_text
46@pytest.fixture(autouse=True)
47def _(testconfig):
48 pass
51def create_host_request(
52 session,
53 surfer_user_id,
54 host_user_id,
55 host_request_age=timedelta(days=15),
56 status=HostRequestStatus.confirmed,
57 host_reason_didnt_meetup=None,
58 surfer_reason_didnt_meetup=None,
59):
60 """
61 Create a host request that's `host_request_age` old
62 """
63 from_date = today() - host_request_age - timedelta(days=2)
64 to_date = today() - host_request_age
65 fake_created = now() - host_request_age - timedelta(days=3)
66 conversation = Conversation()
67 session.add(conversation)
68 session.flush()
69 session.add(
70 Message(
71 time=fake_created + timedelta(seconds=1),
72 conversation_id=conversation.id,
73 author_id=surfer_user_id,
74 message_type=MessageType.chat_created,
75 )
76 )
77 message = Message(
78 time=fake_created + timedelta(seconds=2),
79 conversation_id=conversation.id,
80 author_id=surfer_user_id,
81 text="Hi, I'm requesting to be hosted.",
82 message_type=MessageType.text,
83 )
84 session.add(message)
85 session.flush()
87 moderation_state = create_moderation(
88 session,
89 ModerationObjectType.HOST_REQUEST,
90 conversation.id,
91 surfer_user_id,
92 )
94 host_request = HostRequest(
95 conversation_id=conversation.id,
96 surfer_user_id=surfer_user_id,
97 host_user_id=host_user_id,
98 from_date=from_date,
99 to_date=to_date,
100 status=status,
101 surfer_last_seen_message_id=message.id,
102 host_reason_didnt_meetup=host_reason_didnt_meetup,
103 surfer_reason_didnt_meetup=surfer_reason_didnt_meetup,
104 hosting_city="Test City",
105 hosting_location=create_coordinate(0, 0),
106 hosting_radius=10,
107 moderation_state_id=moderation_state.id,
108 )
109 session.add(host_request)
110 session.commit()
111 return host_request.conversation_id
114def create_host_request_by_date(
115 session,
116 surfer_user_id,
117 host_user_id,
118 from_date,
119 to_date,
120 status,
121 host_sent_request_reminders,
122 last_sent_request_reminder_time,
123):
124 conversation = Conversation()
125 session.add(conversation)
126 session.flush()
128 session.add(
129 Message(
130 time=from_date + timedelta(seconds=1),
131 conversation_id=conversation.id,
132 author_id=surfer_user_id,
133 message_type=MessageType.chat_created,
134 )
135 )
137 # Unused for now, but every host request must have a message.
138 message = Message(
139 time=from_date + timedelta(seconds=2),
140 conversation_id=conversation.id,
141 author_id=surfer_user_id,
142 text="Hi, I'm requesting to be hosted.",
143 message_type=MessageType.text,
144 )
145 session.add(message)
146 session.flush()
148 moderation_state = create_moderation(
149 session,
150 ModerationObjectType.HOST_REQUEST,
151 conversation.id,
152 surfer_user_id,
153 )
155 host_request = HostRequest(
156 conversation_id=conversation.id,
157 surfer_user_id=surfer_user_id,
158 host_user_id=host_user_id,
159 from_date=from_date,
160 to_date=to_date,
161 status=status,
162 host_sent_request_reminders=host_sent_request_reminders,
163 last_sent_request_reminder_time=last_sent_request_reminder_time,
164 hosting_city="Test City",
165 hosting_location=create_coordinate(0, 0),
166 hosting_radius=10,
167 moderation_state_id=moderation_state.id,
168 )
170 session.add(host_request)
171 session.commit()
172 return host_request.conversation_id
175def create_host_reference(session, from_user_id, to_user_id, reference_age, *, surfing=True, host_request_id=None):
176 if host_request_id:
177 actual_host_request_id = host_request_id
178 else:
179 if surfing:
180 actual_host_request_id = host_request_id or create_host_request(
181 session, from_user_id, to_user_id, reference_age + timedelta(days=1)
182 )
183 else:
184 actual_host_request_id = host_request_id or create_host_request(
185 session, to_user_id, from_user_id, reference_age + timedelta(days=1)
186 )
188 host_request = session.execute(
189 select(HostRequest).where(HostRequest.conversation_id == actual_host_request_id)
190 ).scalar_one()
192 reference = Reference(
193 time=now() - reference_age,
194 from_user_id=from_user_id,
195 host_request_id=host_request.conversation_id,
196 text="Dummy reference",
197 rating=0.5,
198 was_appropriate=True,
199 )
201 if host_request.surfer_user_id == from_user_id:
202 reference.reference_type = ReferenceType.surfed
203 reference.to_user_id = host_request.host_user_id
204 assert from_user_id == host_request.surfer_user_id
205 else:
206 reference.reference_type = ReferenceType.hosted
207 reference.to_user_id = host_request.surfer_user_id
208 assert from_user_id == host_request.host_user_id
210 session.add(reference)
211 session.commit()
212 return reference.id, actual_host_request_id
215def create_friend_reference(session: Session, from_user_id: int, to_user_id: int, reference_age: timedelta) -> int:
216 reference = Reference(
217 time=now() - reference_age,
218 from_user_id=from_user_id,
219 to_user_id=to_user_id,
220 reference_type=ReferenceType.friend,
221 text="Test friend request",
222 rating=0.4,
223 was_appropriate=True,
224 )
225 session.add(reference)
226 session.commit()
227 return reference.id
230def test_ListPagination(db):
231 user1, token1 = generate_user()
232 user2, token2 = generate_user()
233 user3, token3 = generate_user()
234 user4, token4 = generate_user()
235 user5, token5 = generate_user()
236 user6, token6 = generate_user()
237 user7, token7 = generate_user()
238 user8, token8 = generate_user()
239 user9, token9 = generate_user()
241 with session_scope() as session:
242 # bidirectional references
243 ref2, hr2 = create_host_reference(session, user2.id, user1.id, timedelta(days=16, seconds=110), surfing=True)
244 ref2b, _ = create_host_reference(
245 session, user1.id, user2.id, timedelta(days=16, seconds=100), host_request_id=hr2
246 )
248 ref3, _ = create_host_reference(session, user3.id, user1.id, timedelta(days=16, seconds=90), surfing=False)
249 ref4, _ = create_host_reference(session, user4.id, user1.id, timedelta(days=16, seconds=80), surfing=True)
250 ref4b = create_friend_reference(session, user1.id, user4.id, timedelta(days=16, seconds=70))
252 ref5, hr5 = create_host_reference(session, user5.id, user1.id, timedelta(days=16, seconds=60), surfing=False)
253 ref5b, _ = create_host_reference(
254 session, user1.id, user5.id, timedelta(days=16, seconds=50), host_request_id=hr5
255 )
257 ref6, _ = create_host_reference(session, user6.id, user1.id, timedelta(days=16, seconds=40), surfing=True)
259 ref7 = create_friend_reference(session, user7.id, user1.id, timedelta(days=16, seconds=30))
261 ref8, _ = create_host_reference(session, user8.id, user1.id, timedelta(days=16, seconds=20), surfing=False)
262 ref9, _ = create_host_reference(session, user9.id, user1.id, timedelta(days=16, seconds=10), surfing=False)
264 # should be visible even under 2 weeks
265 ref7b = create_friend_reference(session, user1.id, user7.id, timedelta(days=9))
267 # hidden because it's less than 2 weeks
268 ref6hidden, _ = create_host_reference(session, user6.id, user1.id, timedelta(days=5), surfing=False)
270 # visible because both were written
271 ref8b, hr8 = create_host_reference(session, user8.id, user1.id, timedelta(days=3, seconds=20), surfing=False)
272 ref8c, _ = create_host_reference(
273 session, user1.id, user8.id, timedelta(days=3, seconds=10), host_request_id=hr8
274 )
276 # note that visibility tests don't really test real logic
278 # these check the right refs are in the right requests and appear in the right order (latest first)
280 with references_session(token2) as api:
281 # written by user1
282 res = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user1.id, page_size=2))
283 assert [ref.reference_id for ref in res.references] == [ref8c, ref7b]
285 res = api.ListReferences(
286 references_pb2.ListReferencesReq(from_user_id=user1.id, page_token=res.next_page_token, page_size=2)
287 )
288 assert [ref.reference_id for ref in res.references] == [ref5b, ref4b]
290 res = api.ListReferences(
291 references_pb2.ListReferencesReq(from_user_id=user1.id, page_token=res.next_page_token, page_size=2)
292 )
293 assert [ref.reference_id for ref in res.references] == [ref2b]
294 assert not res.next_page_token
296 # received by user1
297 res = api.ListReferences(references_pb2.ListReferencesReq(to_user_id=user1.id, page_size=5))
298 assert [ref.reference_id for ref in res.references] == [ref8b, ref9, ref8, ref7, ref6]
300 res = api.ListReferences(
301 references_pb2.ListReferencesReq(to_user_id=user1.id, page_token=res.next_page_token, page_size=5)
302 )
303 assert [ref.reference_id for ref in res.references] == [ref5, ref4, ref3, ref2]
304 assert not res.next_page_token
306 # same thing but with filters
307 res = api.ListReferences(
308 references_pb2.ListReferencesReq(
309 to_user_id=user1.id,
310 reference_type_filter=[
311 references_pb2.REFERENCE_TYPE_HOSTED,
312 references_pb2.REFERENCE_TYPE_SURFED,
313 references_pb2.REFERENCE_TYPE_FRIEND,
314 ],
315 page_size=5,
316 )
317 )
318 assert [ref.reference_id for ref in res.references] == [ref8b, ref9, ref8, ref7, ref6]
320 res = api.ListReferences(
321 references_pb2.ListReferencesReq(
322 to_user_id=user1.id,
323 reference_type_filter=[
324 references_pb2.REFERENCE_TYPE_HOSTED,
325 references_pb2.REFERENCE_TYPE_SURFED,
326 references_pb2.REFERENCE_TYPE_FRIEND,
327 ],
328 page_token=res.next_page_token,
329 page_size=5,
330 )
331 )
332 assert [ref.reference_id for ref in res.references] == [ref5, ref4, ref3, ref2]
333 assert not res.next_page_token
335 # received hosting references
336 res = api.ListReferences(
337 references_pb2.ListReferencesReq(
338 to_user_id=user1.id, reference_type_filter=[references_pb2.REFERENCE_TYPE_HOSTED], page_size=3
339 )
340 )
341 assert [ref.reference_id for ref in res.references] == [ref8b, ref9, ref8]
343 res = api.ListReferences(
344 references_pb2.ListReferencesReq(
345 to_user_id=user1.id,
346 reference_type_filter=[references_pb2.REFERENCE_TYPE_HOSTED],
347 page_token=res.next_page_token,
348 page_size=3,
349 )
350 )
351 assert [ref.reference_id for ref in res.references] == [ref5, ref3]
352 assert not res.next_page_token
354 # written friend references
355 res = api.ListReferences(
356 references_pb2.ListReferencesReq(
357 from_user_id=user1.id, reference_type_filter=[references_pb2.REFERENCE_TYPE_FRIEND]
358 )
359 )
360 assert [ref.reference_id for ref in res.references] == [ref7b, ref4b]
361 assert not res.next_page_token
363 # written surfing references
364 res = api.ListReferences(
365 references_pb2.ListReferencesReq(
366 from_user_id=user1.id, reference_type_filter=[references_pb2.REFERENCE_TYPE_SURFED]
367 )
368 )
369 assert [ref.reference_id for ref in res.references] == [ref8c, ref5b]
370 assert not res.next_page_token
372 with references_session(token7) as api:
373 # need to set at least one of from or to user
374 with pytest.raises(grpc.RpcError) as e:
375 api.ListReferences(
376 references_pb2.ListReferencesReq(reference_type_filter=[references_pb2.REFERENCE_TYPE_SURFED])
377 )
378 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
379 assert e.value.details() == "You need to specify at least one user."
381 with references_session(token5) as api:
382 # from user1 to user2
383 res = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user1.id, to_user_id=user2.id))
384 assert [ref.reference_id for ref in res.references] == [ref2b]
385 assert not res.next_page_token
387 # from user5 to user1
388 res = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user5.id, to_user_id=user1.id))
389 assert [ref.reference_id for ref in res.references] == [ref5]
390 assert not res.next_page_token
393def test_ListReference_banned_deleted_users(db):
394 user1, token1 = generate_user()
395 user2, token2 = generate_user()
396 user3, token3 = generate_user()
398 with session_scope() as session:
399 create_friend_reference(session, user2.id, user1.id, timedelta(days=15))
400 create_friend_reference(session, user3.id, user1.id, timedelta(days=16))
401 create_friend_reference(session, user1.id, user2.id, timedelta(days=15))
402 create_friend_reference(session, user1.id, user3.id, timedelta(days=16))
404 with references_session(token1) as api:
405 refs_rec = api.ListReferences(references_pb2.ListReferencesReq(to_user_id=user1.id)).references
406 refs_sent = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user1.id)).references
407 assert len(refs_rec) == 2
408 assert len(refs_sent) == 2
410 # ban user2
411 with session_scope() as session:
412 session.execute(update(User).where(User.username == user2.username).values(is_banned=True))
414 # reference to and from banned user is hidden
415 with references_session(token1) as api:
416 refs_rec = api.ListReferences(references_pb2.ListReferencesReq(to_user_id=user1.id)).references
417 refs_sent = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user1.id)).references
418 assert len(refs_rec) == 1
419 assert len(refs_sent) == 1
421 # delete user3
422 with session_scope() as session:
423 session.execute(update(User).where(User.username == user3.username).values(is_deleted=True))
425 # doesn't change; references to and from deleted users remain
426 with references_session(token1) as api:
427 refs_rec = api.ListReferences(references_pb2.ListReferencesReq(to_user_id=user1.id)).references
428 refs_sent = api.ListReferences(references_pb2.ListReferencesReq(from_user_id=user1.id)).references
429 assert len(refs_rec) == 1
430 assert len(refs_sent) == 1
433def test_WriteFriendReference(db):
434 user1, token1 = generate_user()
435 user2, token2 = generate_user()
436 user3, token3 = generate_user()
438 # Make user1 and user2 friends
439 make_friends(user1, user2)
441 with references_session(token1) as api:
442 # can write normal friend reference
443 res = api.WriteFriendReference(
444 references_pb2.WriteFriendReferenceReq(
445 to_user_id=user2.id,
446 text="A test reference",
447 was_appropriate=True,
448 rating=0.5,
449 )
450 )
451 assert res.from_user_id == user1.id
452 assert res.to_user_id == user2.id
453 assert res.reference_type == references_pb2.REFERENCE_TYPE_FRIEND
454 assert res.text == "A test reference"
455 assert now() - timedelta(hours=24) <= to_aware_datetime(res.written_time) <= now()
456 assert not res.host_request_id
458 with references_session(token3) as api:
459 # check it shows up
460 res = api.ListReferences(
461 references_pb2.ListReferencesReq(
462 from_user_id=user1.id, to_user_id=user2.id, reference_type_filter=[references_pb2.REFERENCE_TYPE_FRIEND]
463 )
464 )
465 assert len(res.references) == 1
466 ref = res.references[0]
467 assert ref.from_user_id == user1.id
468 assert ref.to_user_id == user2.id
469 assert ref.reference_type == references_pb2.REFERENCE_TYPE_FRIEND
470 assert ref.text == "A test reference"
471 assert now() - timedelta(hours=24) <= to_aware_datetime(ref.written_time) <= now()
472 assert not ref.host_request_id
474 with references_session(token1) as api:
475 # can't write a second friend reference
476 with pytest.raises(grpc.RpcError) as e:
477 api.WriteFriendReference(
478 references_pb2.WriteFriendReferenceReq(
479 to_user_id=user2.id,
480 text="A test reference",
481 was_appropriate=True,
482 rating=0.5,
483 )
484 )
485 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
486 assert e.value.details() == "Reference already given."
488 with references_session(token2) as api:
489 # can't write a reference about yourself
490 with pytest.raises(grpc.RpcError) as e:
491 api.WriteFriendReference(
492 references_pb2.WriteFriendReferenceReq(
493 to_user_id=user2.id,
494 text="I'm really awesome",
495 was_appropriate=True,
496 rating=1.0,
497 )
498 )
499 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
500 assert e.value.details() == "You can't refer yourself."
503def test_WriteFriendReference_with_empty_text(db):
504 user1, token1 = generate_user()
505 user2, token2 = generate_user()
507 with references_session(token1) as api:
508 with pytest.raises(grpc.RpcError) as e:
509 api.WriteFriendReference(
510 references_pb2.WriteFriendReferenceReq(to_user_id=user2.id, text=" ", was_appropriate=True, rating=0.8)
511 )
512 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
513 assert e.value.details() == "The text of a reference must not be empty"
516def test_WriteFriendReference_with_private_text(db, push_collector):
517 user1, token1 = generate_user()
518 user2, token2 = generate_user()
520 # Make users friends
521 make_friends(user1, user2)
523 with references_session(token1) as api:
524 with patch("couchers.email.queue_email") as mock1:
525 with mock_notification_email() as mock2:
526 api.WriteFriendReference(
527 references_pb2.WriteFriendReferenceReq(
528 to_user_id=user2.id,
529 text="They were nice!",
530 was_appropriate=True,
531 rating=0.6,
532 private_text="A bit of an odd ball, but a nice person nonetheless.",
533 )
534 )
536 # make sure an email was sent to the user receiving the ref as well as the mods
537 assert mock1.call_count == 1
538 assert mock2.call_count == 1
539 e = email_fields(mock2)
540 assert e.subject == f"[TEST] You've received a friend reference from {user1.name}!"
541 assert e.recipient == user2.email
543 push_collector.assert_user_has_single_matching(
544 user2.id,
545 title=f"You've received a friend reference from {user1.name}!",
546 body="They were nice!",
547 )
550def test_WriteFriendReference_requires_friendship(db):
551 """Test that users must be friends to write friend references"""
552 user1, token1 = generate_user()
553 user2, token2 = generate_user()
555 # Try to write friend reference without being friends
556 with references_session(token1) as api:
557 with pytest.raises(grpc.RpcError) as e:
558 api.WriteFriendReference(
559 references_pb2.WriteFriendReferenceReq(
560 to_user_id=user2.id,
561 text="A test reference",
562 was_appropriate=True,
563 rating=0.5,
564 )
565 )
566 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
567 assert e.value.details() == "You can only write friend references for confirmed friends."
569 # Now make them friends
570 make_friends(user1, user2)
572 # Should now be able to write a reference
573 with references_session(token1) as api:
574 res = api.WriteFriendReference(
575 references_pb2.WriteFriendReferenceReq(
576 to_user_id=user2.id,
577 text="A test reference",
578 was_appropriate=True,
579 rating=0.5,
580 )
581 )
582 assert res.from_user_id == user1.id
583 assert res.to_user_id == user2.id
585 # Test the unfriending scenario: delete the friendship
586 with session_scope() as session:
587 # Change the friendship status to cancelled (simulating unfriending)
588 session.execute(
589 update(FriendRelationship)
590 .where(FriendRelationship.from_user_id == user1.id, FriendRelationship.to_user_id == user2.id)
591 .values(status=FriendStatus.cancelled)
592 )
594 # Try to write another friend reference after unfriending
595 # (Note: This assumes user1 didn't already write a reference, or we test with user2 writing to user1)
596 with references_session(token2) as api:
597 with pytest.raises(grpc.RpcError) as e:
598 api.WriteFriendReference(
599 references_pb2.WriteFriendReferenceReq(
600 to_user_id=user1.id,
601 text="Another test reference",
602 was_appropriate=True,
603 rating=0.8,
604 )
605 )
606 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
607 assert e.value.details() == "You can only write friend references for confirmed friends."
610def test_host_request_states_references(db, moderator):
611 user1, token1 = generate_user()
612 user2, token2 = generate_user()
614 with session_scope() as session:
615 # can't write ref
616 hr1 = create_host_request(session, user2.id, user1.id, timedelta(days=10), status=HostRequestStatus.pending)
617 # can write ref
618 hr2 = create_host_request(session, user2.id, user1.id, timedelta(days=10), status=HostRequestStatus.accepted)
619 # can't write ref
620 hr3 = create_host_request(session, user2.id, user1.id, timedelta(days=10), status=HostRequestStatus.rejected)
621 # can write ref
622 hr4 = create_host_request(session, user2.id, user1.id, timedelta(days=10), status=HostRequestStatus.confirmed)
623 # can't write ref
624 hr5 = create_host_request(session, user2.id, user1.id, timedelta(days=10), status=HostRequestStatus.cancelled)
626 # Approve host requests so both participants can see them
627 moderator.approve_host_request(hr1)
628 moderator.approve_host_request(hr2)
629 moderator.approve_host_request(hr3)
630 moderator.approve_host_request(hr4)
631 moderator.approve_host_request(hr5)
633 with references_session(token1) as api:
634 # pending
635 api.WriteHostRequestReference(
636 references_pb2.WriteHostRequestReferenceReq(
637 host_request_id=hr2,
638 text="Should work!",
639 was_appropriate=True,
640 rating=0.9,
641 )
642 )
644 # accepted
645 api.WriteHostRequestReference(
646 references_pb2.WriteHostRequestReferenceReq(
647 host_request_id=hr4,
648 text="Should work!",
649 was_appropriate=True,
650 rating=0.9,
651 )
652 )
654 # rejected
655 with pytest.raises(grpc.RpcError) as e:
656 api.WriteHostRequestReference(
657 references_pb2.WriteHostRequestReferenceReq(
658 host_request_id=hr1,
659 text="Shouldn't work...",
660 was_appropriate=True,
661 rating=0.9,
662 )
663 )
664 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
665 assert e.value.details() == "You can't write a reference for that host request, or it wasn't found."
667 # confirmed
668 with pytest.raises(grpc.RpcError) as e:
669 api.WriteHostRequestReference(
670 references_pb2.WriteHostRequestReferenceReq(
671 host_request_id=hr3,
672 text="Shouldn't work...",
673 was_appropriate=True,
674 rating=0.9,
675 )
676 )
677 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
678 assert e.value.details() == "You can't write a reference for that host request, or it wasn't found."
680 # cancelled
681 with pytest.raises(grpc.RpcError) as e:
682 api.WriteHostRequestReference(
683 references_pb2.WriteHostRequestReferenceReq(
684 host_request_id=hr5,
685 text="Shouldn't work...",
686 was_appropriate=True,
687 rating=0.9,
688 )
689 )
690 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
691 assert e.value.details() == "You can't write a reference for that host request, or it wasn't found."
694def test_WriteHostRequestReference(db, moderator):
695 user1, token1 = generate_user()
696 user2, token2 = generate_user()
697 user3, token3 = generate_user()
698 user4, token4 = generate_user()
700 with session_scope() as session:
701 # too old
702 hr1 = create_host_request(session, user3.id, user1.id, timedelta(days=20))
703 # valid host req, surfer said we didn't show up but we can still write a req
704 hr2 = create_host_request(session, user3.id, user1.id, timedelta(days=10), surfer_reason_didnt_meetup="No show")
705 # valid surfing req
706 hr3 = create_host_request(session, user1.id, user3.id, timedelta(days=7))
707 # not yet complete
708 hr4 = create_host_request(session, user2.id, user1.id, timedelta(days=1), status=HostRequestStatus.pending)
709 # we indicated we didn't meet
710 hr5 = create_host_request(session, user4.id, user1.id, timedelta(days=7), host_reason_didnt_meetup="")
711 # we will indicate we didn't meet
712 hr6 = create_host_request(session, user4.id, user1.id, timedelta(days=8))
714 # Approve host requests so both participants can see them
715 moderator.approve_host_request(hr1)
716 moderator.approve_host_request(hr2)
717 moderator.approve_host_request(hr3)
718 moderator.approve_host_request(hr4)
719 moderator.approve_host_request(hr5)
720 moderator.approve_host_request(hr6)
722 with references_session(token3) as api:
723 # can write for this one
724 api.WriteHostRequestReference(
725 references_pb2.WriteHostRequestReferenceReq(
726 host_request_id=hr3,
727 text="Should work!",
728 was_appropriate=True,
729 rating=0.9,
730 )
731 )
733 with references_session(token1) as api:
734 # can't write reference for a HR that's not yet finished
735 with pytest.raises(grpc.RpcError) as e:
736 api.WriteHostRequestReference(
737 references_pb2.WriteHostRequestReferenceReq(
738 host_request_id=hr4,
739 text="Shouldn't work...",
740 was_appropriate=True,
741 rating=0.9,
742 )
743 )
744 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
745 assert e.value.details() == "You can't write a reference for that host request, or it wasn't found."
747 # can't write reference that's more than 2 weeks old
748 with pytest.raises(grpc.RpcError) as e:
749 api.WriteHostRequestReference(
750 references_pb2.WriteHostRequestReferenceReq(
751 host_request_id=hr1,
752 text="Shouldn't work...",
753 was_appropriate=True,
754 rating=0.9,
755 )
756 )
757 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
758 assert e.value.details() == "You can't write a reference for that host request, or it wasn't found."
760 # can write for this one
761 api.WriteHostRequestReference(
762 references_pb2.WriteHostRequestReferenceReq(
763 host_request_id=hr2,
764 text="Should work!",
765 was_appropriate=True,
766 rating=0.9,
767 )
768 )
770 # but can't write a second one for the same one
771 with pytest.raises(grpc.RpcError) as e:
772 api.WriteHostRequestReference(
773 references_pb2.WriteHostRequestReferenceReq(
774 host_request_id=hr2,
775 text="Shouldn't work...",
776 was_appropriate=True,
777 rating=0.9,
778 )
779 )
780 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
781 assert e.value.details() == "Reference already given."
783 # can write for this one too
784 api.WriteHostRequestReference(
785 references_pb2.WriteHostRequestReferenceReq(
786 host_request_id=hr3,
787 text="Should work!",
788 was_appropriate=True,
789 rating=0.9,
790 )
791 )
793 # can't write reference for a HR that we indicated we didn't show up
794 with pytest.raises(grpc.RpcError) as e:
795 api.WriteHostRequestReference(
796 references_pb2.WriteHostRequestReferenceReq(
797 host_request_id=hr5,
798 text="Shouldn't work...",
799 was_appropriate=True,
800 rating=0.9,
801 )
802 )
803 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
804 assert (
805 e.value.details()
806 == "You can't write a reference for that host request because you indicated that you didn't meet up."
807 )
809 # can't write reference for a HR that we indicate we didn't show up for
810 api.HostRequestIndicateDidntMeetup(
811 references_pb2.HostRequestIndicateDidntMeetupReq(
812 host_request_id=hr6,
813 reason_didnt_meetup="No clue?",
814 )
815 )
817 with pytest.raises(grpc.RpcError) as e:
818 api.WriteHostRequestReference(
819 references_pb2.WriteHostRequestReferenceReq(
820 host_request_id=hr6,
821 text="Shouldn't work...",
822 was_appropriate=True,
823 rating=0.9,
824 )
825 )
826 assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
827 assert (
828 e.value.details()
829 == "You can't write a reference for that host request because you indicated that you didn't meet up."
830 )
832 with references_session(token4) as api:
833 # they can still write one
834 api.WriteHostRequestReference(
835 references_pb2.WriteHostRequestReferenceReq(
836 host_request_id=hr6,
837 text="Should work!",
838 was_appropriate=True,
839 rating=0.9,
840 )
841 )
844def test_WriteHostRequestReference_private_text(db, push_collector):
845 user1, token1 = generate_user()
846 user2, token2 = generate_user()
848 with session_scope() as session:
849 hr = create_host_request(session, user1.id, user2.id, timedelta(days=10))
851 with references_session(token1) as api:
852 with patch("couchers.email.queue_email") as mock1:
853 with mock_notification_email() as mock2:
854 api.WriteHostRequestReference(
855 references_pb2.WriteHostRequestReferenceReq(
856 host_request_id=hr,
857 text="Should work!",
858 was_appropriate=True,
859 rating=0.9,
860 private_text="Something",
861 )
862 )
864 # make sure an email was sent to the user receiving the ref as well as the mods
865 assert mock1.call_count == 1
866 assert mock2.call_count == 1
868 e = email_fields(mock2)
869 assert e.subject == f"[TEST] You've received a reference from {user1.name}!"
870 assert e.recipient == user2.email
872 push_collector.assert_user_has_single_matching(
873 user2.id,
874 title=f"You've received a reference from {user1.name}!",
875 body="Please go and write a reference for them too. It's a nice gesture and helps us build a community together!",
876 )
879def test_GetHostRequestReferenceStatus(db, moderator):
880 user1, token1 = generate_user()
881 user2, token2 = generate_user()
883 # user1 writes; RPC returns has_given True
884 with session_scope() as session:
885 hr1 = create_host_request(session, user1.id, user2.id, timedelta(days=7))
886 moderator.approve_host_request(hr1)
887 with references_session(token1) as api:
888 api.WriteHostRequestReference(
889 references_pb2.WriteHostRequestReferenceReq(
890 host_request_id=hr1, text="Great stay!", was_appropriate=True, rating=0.9
891 )
892 )
893 res = api.GetHostRequestReferenceStatus(references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr1))
894 assert res.has_given is True
896 # false: no reference written yet
897 with session_scope() as session:
898 hr2 = create_host_request(session, user1.id, user2.id, timedelta(days=7))
899 moderator.approve_host_request(hr2)
900 with references_session(token1) as api:
901 res = api.GetHostRequestReferenceStatus(references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr2))
902 assert res.has_given is False
904 # false: other user wrote a reference
905 with session_scope() as session:
906 hr3 = create_host_request(session, user1.id, user2.id, timedelta(days=7))
907 moderator.approve_host_request(hr3)
908 with references_session(token2) as api:
909 api.WriteHostRequestReference(
910 references_pb2.WriteHostRequestReferenceReq(
911 host_request_id=hr3, text="Lovely guest!", was_appropriate=True, rating=0.95
912 )
913 )
914 with references_session(token1) as api:
915 res = api.GetHostRequestReferenceStatus(references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr3))
916 assert res.has_given is False
918 # false: nonexistent host request id
919 with references_session(token1) as api:
920 res = api.GetHostRequestReferenceStatus(references_pb2.GetHostRequestReferenceStatusReq(host_request_id=999999))
921 assert res.has_given is False
923 # Additional status flags
924 with session_scope() as session:
925 # expired (too old)
926 hr_expired = create_host_request(session, user2.id, user1.id, timedelta(days=20))
927 # current user (host) indicated didn't meet up
928 hr_didnt_stay_host = create_host_request(
929 session, user2.id, user1.id, timedelta(days=10), host_reason_didnt_meetup=""
930 )
931 # other user (surfer) indicated didn't meet up
932 hr_other_didnt_stay = create_host_request(
933 session, user2.id, user1.id, timedelta(days=10), surfer_reason_didnt_meetup="No show"
934 )
936 moderator.approve_host_request(hr_expired)
937 moderator.approve_host_request(hr_didnt_stay_host)
938 moderator.approve_host_request(hr_other_didnt_stay)
940 # expired: is_expired true, can_write false, didnt_stay false
941 with references_session(token1) as api:
942 res = api.GetHostRequestReferenceStatus(
943 references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr_expired)
944 )
945 assert res.has_given is False
946 assert res.is_expired is True
947 assert res.can_write is False
948 assert res.didnt_stay is False
950 # current user indicated didn't meet up: didnt_stay true, can_write false, not expired
951 with references_session(token1) as api:
952 res = api.GetHostRequestReferenceStatus(
953 references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr_didnt_stay_host)
954 )
955 assert res.has_given is False
956 assert res.is_expired is False
957 assert res.didnt_stay is True
958 assert res.can_write is False
960 # other party indicated didn't meet up: didnt_stay false, can_write true (within window), not expired
961 with references_session(token1) as api:
962 res = api.GetHostRequestReferenceStatus(
963 references_pb2.GetHostRequestReferenceStatusReq(host_request_id=hr_other_didnt_stay)
964 )
965 assert res.has_given is False
966 assert res.is_expired is False
967 assert res.didnt_stay is False
968 assert res.can_write is True
971def test_AvailableWriteReferences_and_ListPendingReferencesToWrite(db, moderator):
972 user1, token1 = generate_user()
973 user2, token2 = generate_user()
974 user3, token3 = generate_user()
975 user4, token4 = generate_user()
976 user5, token5 = generate_user(delete_user=True)
977 user6, token6 = generate_user()
978 user7, token7 = generate_user()
979 user8, token8 = generate_user()
980 user9, token9 = generate_user()
981 user10, token10 = generate_user()
982 user11, token11 = generate_user()
983 make_user_block(user1, user6)
984 make_user_block(user7, user1)
986 with session_scope() as session:
987 # too old
988 hr1 = create_host_request(session, user3.id, user1.id, timedelta(days=20))
990 # already wrote friend ref to user3
991 create_friend_reference(session, user1.id, user3.id, timedelta(days=15, seconds=70))
993 # already given
994 _, hr2 = create_host_reference(session, user2.id, user1.id, timedelta(days=10, seconds=110), surfing=True)
995 create_host_reference(session, user1.id, user2.id, timedelta(days=10, seconds=100), host_request_id=hr2)
997 # valid hosted
998 hr3 = create_host_request(session, user3.id, user1.id, timedelta(days=8))
1000 # valid surfed
1001 hr4 = create_host_request(session, user1.id, user4.id, timedelta(days=5))
1003 # not yet complete
1004 hr5 = create_host_request(session, user2.id, user1.id, timedelta(days=2), status=HostRequestStatus.pending)
1006 # already wrote friend ref to user2
1007 create_friend_reference(session, user1.id, user2.id, timedelta(days=1))
1009 # user5 deleted, reference won't show up as pending
1010 hr_user5 = create_host_request(session, user1.id, user5.id, timedelta(days=5))
1012 # user6 blocked, reference won't show up as pending
1013 hr_user6 = create_host_request(session, user1.id, user6.id, timedelta(days=5))
1015 # user7 blocking, reference won't show up as pending
1016 hr_user7 = create_host_request(session, user1.id, user7.id, timedelta(days=5))
1018 # hosted but we indicated we didn't meet up, no reason; should not show up
1019 hr_user8 = create_host_request(session, user8.id, user1.id, timedelta(days=11), host_reason_didnt_meetup="")
1021 # surfed but we indicated we didn't meet up, has reason; should not show up
1022 hr_user9 = create_host_request(
1023 session, user1.id, user9.id, timedelta(days=10), surfer_reason_didnt_meetup="They never showed up!"
1024 )
1026 # surfed but they indicated we didn't meet up, no reason; should show up
1027 hr6 = create_host_request(session, user1.id, user10.id, timedelta(days=4), host_reason_didnt_meetup="")
1029 # hosted but they indicated we didn't meet up, has reason; should show up
1030 hr7 = create_host_request(
1031 session, user11.id, user1.id, timedelta(days=3), surfer_reason_didnt_meetup="They never showed up!!"
1032 )
1034 # Approve all host requests so both participants can see them
1035 moderator.approve_host_request(hr1)
1036 moderator.approve_host_request(hr2)
1037 moderator.approve_host_request(hr3)
1038 moderator.approve_host_request(hr4)
1039 moderator.approve_host_request(hr5)
1040 moderator.approve_host_request(hr_user5)
1041 moderator.approve_host_request(hr_user6)
1042 moderator.approve_host_request(hr_user7)
1043 moderator.approve_host_request(hr_user8)
1044 moderator.approve_host_request(hr_user9)
1045 moderator.approve_host_request(hr6)
1046 moderator.approve_host_request(hr7)
1048 refresh_materialized_views_rapid(None)
1050 with references_session(token1) as api:
1051 # can't write reference for invisible user
1052 with pytest.raises(grpc.RpcError) as e:
1053 api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user5.id))
1054 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1055 assert e.value.details() == "Couldn't find that user."
1057 # can't write reference for blocking user
1058 with pytest.raises(grpc.RpcError) as e:
1059 api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user7.id))
1060 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1061 assert e.value.details() == "Couldn't find that user."
1063 # can't write reference for blocked user
1064 with pytest.raises(grpc.RpcError) as e:
1065 api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user6.id))
1066 assert e.value.code() == grpc.StatusCode.NOT_FOUND
1067 assert e.value.details() == "Couldn't find that user."
1069 # can't write anything to myself
1070 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id))
1071 assert not res.can_write_friend_reference
1072 assert len(res.available_write_references) == 0
1074 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id))
1075 # can't write friend ref to user2
1076 assert not res.can_write_friend_reference
1077 # none we can write for user2
1078 assert len(res.available_write_references) == 0
1080 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user3.id))
1081 # can't write friend ref to user3
1082 assert not res.can_write_friend_reference
1083 # can write one reference because we hosted user3
1084 assert len(res.available_write_references) == 1
1085 w = res.available_write_references[0]
1086 assert w.host_request_id == hr3
1087 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1088 assert now() + timedelta(days=6) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=7)
1090 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user4.id))
1091 # can write friend ref to user4
1092 assert res.can_write_friend_reference
1093 # can write one reference because we surfed with user4
1094 assert len(res.available_write_references) == 1
1095 w = res.available_write_references[0]
1096 assert w.host_request_id == hr4
1097 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1098 assert now() + timedelta(days=9) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=10)
1100 # can't write a req if we indicated we didn't meet up
1101 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user8.id))
1102 assert len(res.available_write_references) == 0
1103 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user9.id))
1104 assert len(res.available_write_references) == 0
1106 # can still write ref if the other person indicated we didn't meet up
1107 # surfed with them
1108 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user10.id))
1109 assert len(res.available_write_references) == 1
1110 w = res.available_write_references[0]
1111 assert w.host_request_id == hr6
1112 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1113 assert now() + timedelta(days=10) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=11)
1114 # hosted them
1115 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user11.id))
1116 assert len(res.available_write_references) == 1
1117 w = res.available_write_references[0]
1118 assert w.host_request_id == hr7
1119 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1120 assert now() + timedelta(days=11) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=12)
1122 # finally check the general list
1123 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1124 assert len(res.pending_references) == 4
1125 w = res.pending_references[0]
1126 assert w.host_request_id == hr3
1127 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1128 assert now() + timedelta(days=6) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=7)
1129 w = res.pending_references[1]
1130 assert w.host_request_id == hr4
1131 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1132 assert now() + timedelta(days=9) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=10)
1133 w = res.pending_references[2]
1134 assert w.host_request_id == hr6
1135 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1136 assert now() + timedelta(days=10) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=11)
1137 w = res.pending_references[3]
1138 assert w.host_request_id == hr7
1139 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1140 assert now() + timedelta(days=11) <= to_aware_datetime(w.time_expires) <= now() + timedelta(days=12)
1142 with account_session(token1) as account:
1143 reminders = account.GetReminders(empty_pb2.Empty()).reminders
1144 assert [reminder.WhichOneof("reminder") for reminder in reminders] == [
1145 "write_reference_reminder",
1146 "write_reference_reminder",
1147 "write_reference_reminder",
1148 "write_reference_reminder",
1149 "complete_verification_reminder",
1150 ]
1151 assert reminders[0].write_reference_reminder.host_request_id == hr3
1152 assert reminders[0].write_reference_reminder.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1153 assert reminders[0].write_reference_reminder.other_user.user_id == user3.id
1154 assert reminders[1].write_reference_reminder.host_request_id == hr4
1155 assert reminders[1].write_reference_reminder.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1156 assert reminders[1].write_reference_reminder.other_user.user_id == user4.id
1157 assert reminders[2].write_reference_reminder.host_request_id == hr6
1158 assert reminders[2].write_reference_reminder.reference_type == references_pb2.REFERENCE_TYPE_SURFED
1159 assert reminders[2].write_reference_reminder.other_user.user_id == user10.id
1160 assert reminders[3].write_reference_reminder.host_request_id == hr7
1161 assert reminders[3].write_reference_reminder.reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1162 assert reminders[3].write_reference_reminder.other_user.user_id == user11.id
1165@pytest.mark.parametrize("hs", ["host", "surfer"])
1166def test_regression_disappearing_refs(db, hs, moderator):
1167 """
1168 Roughly the reproduction steps are:
1169 * Send a host request, then have both host and surfer accept
1170 * Wait for it to elapse (or hack it with SQL like what you told me to do)
1171 * On the surfer account, leave a reference
1172 * Then on the host account, the option to leave a reference is then not available
1173 """
1174 user1, token1 = generate_user()
1175 user2, token2 = generate_user()
1176 req_start = (today() + timedelta(days=2)).isoformat()
1177 req_end = (today() + timedelta(days=3)).isoformat()
1178 with requests_session(token1) as api:
1179 res = api.CreateHostRequest(
1180 requests_pb2.CreateHostRequestReq(
1181 host_user_id=user2.id, from_date=req_start, to_date=req_end, text=valid_request_text()
1182 )
1183 )
1184 host_request_id = res.host_request_id
1186 moderator.approve_host_request(host_request_id)
1188 assert (
1189 api.ListHostRequests(requests_pb2.ListHostRequestsReq(only_sent=True))
1190 .host_requests[0]
1191 .latest_message.text.text
1192 == valid_request_text()
1193 )
1195 with requests_session(token2) as api:
1196 api.RespondHostRequest(
1197 requests_pb2.RespondHostRequestReq(
1198 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_ACCEPTED
1199 )
1200 )
1202 with requests_session(token1) as api:
1203 api.RespondHostRequest(
1204 requests_pb2.RespondHostRequestReq(
1205 host_request_id=host_request_id, status=conversations_pb2.HOST_REQUEST_STATUS_CONFIRMED
1206 )
1207 )
1209 refresh_materialized_views_rapid(None)
1211 with references_session(token1) as api:
1212 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1213 assert len(res.pending_references) == 0
1214 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id))
1215 assert len(res.available_write_references) == 0
1217 with references_session(token2) as api:
1218 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1219 assert len(res.pending_references) == 0
1220 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id))
1221 assert len(res.available_write_references) == 0
1223 # hack the time backwards
1224 hack_req_start = today() - timedelta(days=10) + timedelta(days=2)
1225 hack_req_end = today() - timedelta(days=10) + timedelta(days=3)
1226 with session_scope() as session:
1227 host_request = session.execute(select(HostRequest)).scalar_one()
1228 assert host_request.conversation_id == host_request_id
1229 host_request.from_date = hack_req_start
1230 host_request.to_date = hack_req_end
1232 with references_session(token1) as api:
1233 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1234 assert len(res.pending_references) == 1
1235 assert res.pending_references[0].host_request_id == host_request_id
1236 assert res.pending_references[0].reference_type == references_pb2.REFERENCE_TYPE_SURFED
1238 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id))
1239 assert len(res.available_write_references) == 1
1240 assert res.available_write_references[0].host_request_id == host_request_id
1241 assert res.available_write_references[0].reference_type == references_pb2.REFERENCE_TYPE_SURFED
1243 with references_session(token2) as api:
1244 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1245 assert len(res.pending_references) == 1
1246 assert res.pending_references[0].host_request_id == host_request_id
1247 assert res.pending_references[0].reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1249 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id))
1250 assert len(res.available_write_references) == 1
1251 assert res.available_write_references[0].host_request_id == host_request_id
1252 assert res.available_write_references[0].reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1254 if hs == "host":
1255 with references_session(token2) as api:
1256 api.WriteHostRequestReference(
1257 references_pb2.WriteHostRequestReferenceReq(
1258 host_request_id=host_request_id,
1259 text="Good stuff",
1260 was_appropriate=True,
1261 rating=0.86,
1262 )
1263 )
1265 with references_session(token2) as api:
1266 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1267 assert len(res.pending_references) == 0
1269 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id))
1270 assert len(res.available_write_references) == 0
1272 with references_session(token1) as api:
1273 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1274 assert len(res.pending_references) == 1
1275 assert res.pending_references[0].host_request_id == host_request_id
1276 assert res.pending_references[0].reference_type == references_pb2.REFERENCE_TYPE_SURFED
1278 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id))
1279 assert len(res.available_write_references) == 1
1280 assert res.available_write_references[0].host_request_id == host_request_id
1281 assert res.available_write_references[0].reference_type == references_pb2.REFERENCE_TYPE_SURFED
1282 else:
1283 with references_session(token1) as api:
1284 api.WriteHostRequestReference(
1285 references_pb2.WriteHostRequestReferenceReq(
1286 host_request_id=host_request_id,
1287 text="Good stuff",
1288 was_appropriate=True,
1289 rating=0.86,
1290 )
1291 )
1293 with references_session(token1) as api:
1294 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1295 assert len(res.pending_references) == 0
1297 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id))
1298 assert len(res.available_write_references) == 0
1300 with references_session(token2) as api:
1301 res = api.ListPendingReferencesToWrite(empty_pb2.Empty())
1302 assert len(res.pending_references) == 1
1303 assert res.pending_references[0].host_request_id == host_request_id
1304 assert res.pending_references[0].reference_type == references_pb2.REFERENCE_TYPE_HOSTED
1306 res = api.AvailableWriteReferences(references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id))
1307 assert len(res.available_write_references) == 1
1308 assert res.available_write_references[0].host_request_id == host_request_id
1309 assert res.available_write_references[0].reference_type == references_pb2.REFERENCE_TYPE_HOSTED