def test_friend_request_accepted_email(db): with session_scope() as session: from_user, api_token_from = generate_user() to_user, api_token_to = generate_user() key = random_hex(32) filename = random_hex(32) + ".jpg" session.add( Upload( key=key, filename=filename, creator_user_id=from_user.id, ) ) session.commit() to_user, api_token_to = generate_user(avatar_key=key) friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.accepted) session.add(friend_relationship) with patch("couchers.email.queue_email") as mock: send_friend_request_accepted_email(friend_relationship) assert mock.call_count == 1 (sender_name, sender_email, recipient, subject, plain, html), _ = mock.call_args assert recipient == from_user.email assert "friend" in subject.lower() assert from_user.name in plain assert from_user.name in html assert to_user.name in subject assert to_user.name in plain assert to_user.name in html assert to_user.avatar.thumbnail_url not in plain assert to_user.avatar.thumbnail_url in html assert f"{config['BASE_URL']}/user/{to_user.username}" in plain assert f"{config['BASE_URL']}/user/{to_user.username}" in html
def SendFriendRequest(self, request, context): with session_scope() as session: from_user = session.query(User).filter( User.id == context.user_id).one_or_none() if not from_user: context.abort(grpc.StatusCode.NOT_FOUND, errors.USER_NOT_FOUND) to_user = session.query(User).filter( User.id == request.user_id).one_or_none() if not to_user: context.abort(grpc.StatusCode.NOT_FOUND, errors.USER_NOT_FOUND) if get_friends_status( session, from_user.id, to_user.id) != api_pb2.User.FriendshipStatus.NOT_FRIENDS: context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.FRIENDS_ALREADY_OR_PENDING) # Race condition! friend_relationship = FriendRelationship( from_user=from_user, to_user=to_user, status=FriendStatus.pending) session.add(friend_relationship) send_friend_request_email(friend_relationship) return empty_pb2.Empty()
def test_friend_request_email(db): with session_scope(db) as session: from_user, api_token_from = generate_user(db) to_user, api_token_to = generate_user(db) friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.pending) message_id = random_hex(64) @create_autospec def mock_send_email(sender_name, sender_email, recipient, subject, plain, html): assert recipient == to_user.email assert "friend" in subject.lower() assert to_user.name in plain assert to_user.name in html assert from_user.name in subject assert from_user.name in plain assert from_user.name in html assert from_user.avatar_url not in plain assert from_user.avatar_url in html assert f"{config['BASE_URL']}/friends/" in plain assert f"{config['BASE_URL']}/friends/" in html return message_id with patch("couchers.email.send_email", mock_send_email) as mock: send_friend_request_email(friend_relationship) assert mock.call_count == 1
def SendFriendRequest(self, request, context): with session_scope(self._Session) as session: from_user = session.query(User).filter( User.id == context.user_id).one_or_none() if not from_user: context.abort(grpc.StatusCode.NOT_FOUND, "User not found.") to_user = get_user_by_field(session, request.user) if not to_user: context.abort(grpc.StatusCode.NOT_FOUND, "User not found.") if get_friends_status( session, from_user.id, to_user.id) != api_pb2.User.FriendshipStatus.NOT_FRIENDS: context.abort( grpc.StatusCode.FAILED_PRECONDITION, "Can't send friend request. Already friends or pending.") # Race condition! friend_relationship = FriendRelationship( from_user=from_user, to_user=to_user, status=FriendStatus.pending, ) session.add(friend_relationship) return empty_pb2.Empty()
def test_friend_request_email(db): with session_scope() as session: to_user, api_token_to = generate_user() # little trick here to get the upload correctly without invalidating users key = random_hex(32) filename = random_hex(32) + ".jpg" session.add( Upload( key=key, filename=filename, creator_user_id=to_user.id, ) ) session.commit() from_user, api_token_from = generate_user(avatar_key=key) friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.pending) session.add(friend_relationship) with patch("couchers.email.queue_email") as mock: send_friend_request_email(friend_relationship) assert mock.call_count == 1 (sender_name, sender_email, recipient, subject, plain, html), _ = mock.call_args assert recipient == to_user.email assert "friend" in subject.lower() assert to_user.name in plain assert to_user.name in html assert from_user.name in subject assert from_user.name in plain assert from_user.name in html assert from_user.avatar.thumbnail_url not in plain assert from_user.avatar.thumbnail_url in html assert f"{config['BASE_URL']}/connections/friends/" in plain assert f"{config['BASE_URL']}/connections/friends/" in html
def SendFriendRequest(self, request, context): if context.user_id == request.user_id: context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.CANT_FRIEND_SELF) with session_scope() as session: user = session.execute( select(User).where(User.id == context.user_id)).scalar_one() to_user = session.execute( select(User).where_users_visible(context).where( User.id == request.user_id)).scalar_one_or_none() if not to_user: context.abort(grpc.StatusCode.NOT_FOUND, errors.USER_NOT_FOUND) if (session.execute( select(FriendRelationship).where( or_( and_( FriendRelationship.from_user_id == context.user_id, FriendRelationship.to_user_id == request.user_id, ), and_( FriendRelationship.from_user_id == request.user_id, FriendRelationship.to_user_id == context.user_id, ), )). where( or_( FriendRelationship.status == FriendStatus.accepted, FriendRelationship.status == FriendStatus.pending, ))).scalar_one_or_none() is not None): context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.FRIENDS_ALREADY_OR_PENDING) # TODO: Race condition where we can create two friend reqs, needs db constraint! See comment in table friend_relationship = FriendRelationship( from_user=user, to_user=to_user, status=FriendStatus.pending) session.add(friend_relationship) session.commit() send_friend_request_email(friend_relationship) notify( user_id=friend_relationship.to_user_id, topic="friend_request", key=str(friend_relationship.from_user_id), action="send", avatar_key=user.avatar.thumbnail_url if user.avatar else None, icon="person", title=f"**{user.name}** sent you a friend request", link=urls.friend_requests_link(), ) return empty_pb2.Empty()
def make_friends(db, user1, user2): with session_scope(db) as session: friend_relationship = FriendRelationship( from_user_id=user1.id, to_user_id=user2.id, status=FriendStatus.accepted, ) session.add(friend_relationship)
def SendFriendRequest(self, request, context): if context.user_id == request.user_id: context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.CANT_FRIEND_SELF) with session_scope() as session: user = session.query(User).filter(User.id == context.user_id).one() to_user = session.query(User).filter(User.id == request.user_id).one_or_none() if not to_user: context.abort(grpc.StatusCode.NOT_FOUND, errors.USER_NOT_FOUND) if ( session.query(FriendRelationship) .filter( or_( and_( FriendRelationship.from_user_id == context.user_id, FriendRelationship.to_user_id == request.user_id, ), and_( FriendRelationship.from_user_id == request.user_id, FriendRelationship.to_user_id == context.user_id, ), ) ) .filter( or_( FriendRelationship.status == FriendStatus.accepted, FriendRelationship.status == FriendStatus.pending, ) ) .one_or_none() is not None ): context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.FRIENDS_ALREADY_OR_PENDING) # TODO: Race condition where we can create two friend reqs, needs db constraint! See comment in table friend_relationship = FriendRelationship(from_user=user, to_user=to_user, status=FriendStatus.pending) session.add(friend_relationship) send_friend_request_email(friend_relationship) return empty_pb2.Empty()
def test_reference_report_email(db): with session_scope() as session: from_user, api_token_author = generate_user() to_user, api_token_reported = generate_user() friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.accepted) session.add(friend_relationship) session.flush() reference = Reference( from_user=from_user, to_user=to_user, reference_type=ReferenceType.friend, text="This person was not nice to me.", rating=0.3, was_appropriate=False, ) with patch("couchers.email.queue_email") as mock: maybe_send_reference_report_email(reference) assert mock.call_count == 1 (sender_name, sender_email, recipient, subject, plain, html), _ = mock.call_args assert recipient == "*****@*****.**" assert "report" in subject.lower() assert "reference" in subject.lower() assert reference.from_user.username in plain assert str(reference.from_user.id) in plain assert reference.from_user.email in plain assert reference.from_user.username in html assert str(reference.from_user.id) in html assert reference.from_user.email in html assert reference.to_user.username in plain assert str(reference.to_user.id) in plain assert reference.to_user.email in plain assert reference.to_user.username in html assert str(reference.to_user.id) in html assert reference.to_user.email in html assert reference.text in plain assert reference.text in html assert "friend" in plain.lower() assert "friend" in html.lower()
def test_accept_friend_request(db): user1, token1 = generate_user() user2, token2 = generate_user() with session_scope() as session: friend_request = FriendRelationship(from_user_id=user1.id, to_user_id=user2.id, status=FriendStatus.pending) session.add(friend_request) session.commit() friend_request_id = friend_request.id with api_session(token2) as api: # check request pending res = api.ListFriendRequests(empty_pb2.Empty()) assert len(res.received) == 1 assert res.received[0].user_id == user1.id api.RespondFriendRequest( api_pb2.RespondFriendRequestReq( friend_request_id=friend_request_id, accept=True)) # check request is gone res = api.ListFriendRequests(empty_pb2.Empty()) assert len(res.sent) == 0 assert len(res.received) == 0 # check now friends res = api.ListFriends(empty_pb2.Empty()) assert len(res.user_ids) == 1 assert res.user_ids[0] == user1.id with api_session(token1) as api: # check request gone res = api.ListFriendRequests(empty_pb2.Empty()) assert len(res.sent) == 0 assert len(res.received) == 0 # check now friends res = api.ListFriends(empty_pb2.Empty()) assert len(res.user_ids) == 1 assert res.user_ids[0] == user2.id
def test_email_patching_fails(db): """ There was a problem where the mocking wasn't happening and the email dev printing function was called instead, this makes sure the patching is actually done """ with session_scope() as session: from_user, api_token_from = generate_user() to_user, api_token_to = generate_user() friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.pending) session.add(friend_relationship) patched_msg = random_hex(64) def mock_queue_email(sender_name, sender_email, recipient, subject, plain, html): raise Exception(patched_msg) with pytest.raises(Exception) as e: with patch("couchers.email.queue_email", mock_queue_email): send_friend_request_email(friend_relationship) assert str(e.value) == patched_msg
def test_reference_report_email_not_sent(db): with session_scope() as session: from_user, api_token_author = generate_user() to_user, api_token_reported = generate_user() friend_relationship = FriendRelationship(from_user=from_user, to_user=to_user, status=FriendStatus.accepted) session.add(friend_relationship) session.flush() reference = Reference( from_user=from_user, to_user=to_user, reference_type=ReferenceType.friend, text="This person was very nice to me.", rating=0.9, was_appropriate=True, ) # no email sent for a positive ref with patch("couchers.email.queue_email") as mock: maybe_send_reference_report_email(reference) assert mock.call_count == 0
def add_dummy_users(): try: logger.info(f"Adding dummy users") with session_scope() as session: with open("src/data/dummy_users.json", "r") as file: data = json.loads(file.read()) for user in data["users"]: new_user = User( username=user["username"], email=user["email"], hashed_password=hash_password(user["password"]) if user["password"] else None, name=user["name"], city=user["location"]["city"], geom=create_coordinate(user["location"]["lat"], user["location"]["lng"]), geom_radius=user["location"]["radius"], verification=user["verification"], community_standing=user["community_standing"], birthdate=date(year=user["birthdate"]["year"], month=user["birthdate"]["month"], day=user["birthdate"]["day"]), gender=user["gender"], languages="|".join(user["languages"]), occupation=user["occupation"], about_me=user["about_me"], about_place=user["about_place"], countries_visited="|".join(user["countries_visited"]), countries_lived="|".join(user["countries_lived"]), hosting_status=hostingstatus2sql[HostingStatus.Value( user["hosting_status"])] if "hosting_status" in user else None, ) session.add(new_user) session.commit() for username1, username2 in data["friendships"]: friend_relationship = FriendRelationship( from_user_id=get_user_by_field(session, username1).id, to_user_id=get_user_by_field(session, username2).id, status=FriendStatus.accepted, ) session.add(friend_relationship) session.commit() for reference in data["references"]: reference_type = (ReferenceType.HOSTED if reference["type"] == "hosted" else (ReferenceType.SURFED if reference["type"] == "surfed" else ReferenceType.FRIEND)) new_reference = Reference( from_user_id=get_user_by_field(session, reference["from"]).id, to_user_id=get_user_by_field(session, reference["to"]).id, reference_type=reference_type, text=reference["text"], rating=reference["rating"], was_safe=reference["was_safe"], ) session.add(new_reference) session.commit() for group_chat in data["group_chats"]: # Create the chat creator = group_chat["creator"] conversation = Conversation() session.add(conversation) chat = GroupChat( conversation=conversation, title=group_chat["title"], creator_id=get_user_by_field(session, creator).id, is_dm=group_chat["is_dm"], ) session.add(chat) for participant in group_chat["participants"]: subscription = GroupChatSubscription( user_id=get_user_by_field(session, participant["username"]).id, group_chat=chat, role=GroupChatRole.admin if participant["username"] == creator else GroupChatRole.participant, joined=parser.isoparse(participant["joined"]), ) session.add(subscription) for message in group_chat["messages"]: session.add( Message( message_type=MessageType.text, conversation=chat.conversation, author_id=get_user_by_field( session, message["author"]).id, time=parser.isoparse(message["time"]), text=message["message"], )) session.commit() except IntegrityError: logger.error("Failed to insert dummy users, is it already inserted?")
def add_dummy_users(): logger.info(f"Adding dummy users") with session_scope() as session: if session.execute(select( func.count()).select_from(User)).scalar_one() > 0: logger.info("Users not empty, not adding dummy users") return with open(SRC_DIR + "/data/dummy_users.json", "r") as f: data = json.loads(f.read()) for user in data["users"]: new_user = User( username=user["username"], email=user["email"], hashed_password=hash_password(user["password"]) if user["password"] else None, name=user["name"], city=user["location"]["city"], geom=create_coordinate(user["location"]["lat"], user["location"]["lng"]), geom_radius=user["location"]["radius"], community_standing=user["community_standing"], birthdate=date(year=user["birthdate"]["year"], month=user["birthdate"]["month"], day=user["birthdate"]["day"]), gender=user["gender"], occupation=user["occupation"], about_me=user["about_me"], about_place=user["about_place"], hosting_status=hostingstatus2sql[HostingStatus.Value( user["hosting_status"] if "hosting_status" in user else "HOSTING_STATUS_CANT_HOST")], new_notifications_enabled=True, accepted_tos=TOS_VERSION, accepted_community_guidelines=GUIDELINES_VERSION, ) session.add(new_user) session.flush() for language in user["languages"]: session.add( LanguageAbility(user_id=new_user.id, language_code=language[0], fluency=LanguageFluency[language[1]])) for region in user["regions_visited"]: session.add( RegionVisited(user_id=new_user.id, region_code=region)) for region in user["regions_lived"]: session.add( RegionLived(user_id=new_user.id, region_code=region)) session.commit() for username1, username2 in data["friendships"]: friend_relationship = FriendRelationship( from_user_id=session.execute( select(User).where( User.username == username1)).scalar_one().id, to_user_id=session.execute( select(User).where( User.username == username2)).scalar_one().id, status=FriendStatus.accepted, ) session.add(friend_relationship) session.commit() for reference in data["references"]: reference_type = (ReferenceType.hosted if reference["type"] == "hosted" else (ReferenceType.surfed if reference["type"] == "surfed" else ReferenceType.friend)) new_reference = Reference( from_user_id=session.execute( select(User).where( User.username == reference["from"])).scalar_one().id, to_user_id=session.execute( select(User).where( User.username == reference["to"])).scalar_one().id, reference_type=reference_type, text=reference["text"], rating=reference["rating"], was_appropriate=reference["was_appropriate"], ) session.add(new_reference) session.commit() for group_chat in data["group_chats"]: # Create the chat creator = group_chat["creator"] conversation = Conversation() session.add(conversation) chat = GroupChat( conversation=conversation, title=group_chat["title"], creator_id=session.execute( select(User).where( User.username == creator)).scalar_one().id, is_dm=group_chat["is_dm"], ) session.add(chat) for participant in group_chat["participants"]: subscription = GroupChatSubscription( user_id=session.execute( select(User).where( User.username == participant["username"])).scalar_one().id, group_chat=chat, role=GroupChatRole.admin if participant["username"] == creator else GroupChatRole.participant, joined=parser.isoparse(participant["joined"]), ) session.add(subscription) for message in group_chat["messages"]: session.add( Message( message_type=MessageType.text, conversation=chat.conversation, author_id=session.execute( select(User).where( User.username == message["author"])).scalar_one().id, time=parser.isoparse(message["time"]), text=message["message"], )) session.commit()