def test_ping(db): user, token = generate_user() with real_api_session(token) as api: res = api.Ping(api_pb2.PingReq()) assert res.user.user_id == user.id assert res.user.username == user.username assert res.user.name == user.name assert res.user.city == user.city assert res.user.hometown == user.hometown assert res.user.verification == 0.0 assert res.user.community_standing == user.community_standing assert res.user.num_references == 0 assert res.user.gender == user.gender assert res.user.pronouns == user.pronouns assert res.user.age == user.age assert (res.user.lat, res.user.lng) == (user.coordinates or (0, 0)) # the joined time is fuzzed # but shouldn't be before actual joined time, or more than one hour behind assert user.joined - timedelta(hours=1) <= to_aware_datetime( res.user.joined) <= user.joined # same for last_active assert user.last_active - timedelta(hours=1) <= to_aware_datetime( res.user.last_active) <= user.last_active assert res.user.hosting_status == api_pb2.HOSTING_STATUS_CANT_HOST assert res.user.meetup_status == api_pb2.MEETUP_STATUS_OPEN_TO_MEETUP assert res.user.occupation == user.occupation assert res.user.education == user.education assert res.user.about_me == user.about_me assert res.user.my_travels == user.my_travels assert res.user.things_i_like == user.things_i_like assert set(language_ability.code for language_ability in res.user.language_abilities) == set( ["fin", "fra"]) assert res.user.about_place == user.about_place assert res.user.regions_visited == [ "FIN", "REU", "CHE" ] # Tests alphabetization by region name assert res.user.regions_lived == ["EST", "FRA", "ESP"] # Ditto assert res.user.additional_information == user.additional_information assert res.user.friends == api_pb2.User.FriendshipStatus.NA assert not res.user.HasField("pending_friend_request")
def test_ping(db): user, token = generate_user("tester") with real_api_session(token) as api: res = api.Ping(api_pb2.PingReq()) assert res.user.user_id == user.id assert res.user.username == user.username assert res.user.name == user.name assert res.user.city == user.city assert res.user.hometown == user.hometown assert res.user.verification == user.verification assert res.user.community_standing == user.community_standing assert res.user.num_references == 0 assert res.user.gender == user.gender assert res.user.pronouns == user.pronouns assert res.user.age == user.age assert (res.user.lat, res.user.lng) == (user.coordinates or (0, 0)) # the joined time is fuzzed # but shouldn't be before actual joined time, or more than one hour behind assert user.joined - timedelta(hours=1) <= to_aware_datetime( res.user.joined) <= user.joined # same for last_active assert user.last_active - timedelta(hours=1) <= to_aware_datetime( res.user.last_active) <= user.last_active assert res.user.hosting_status == api_pb2.HOSTING_STATUS_UNKNOWN assert res.user.meetup_status == api_pb2.MEETUP_STATUS_UNKNOWN assert res.user.occupation == user.occupation assert res.user.education == user.education assert res.user.about_me == user.about_me assert res.user.my_travels == user.my_travels assert res.user.things_i_like == user.things_i_like assert res.user.about_place == user.about_place # TODO: this list serialisation will be fixed hopefully soon assert res.user.languages == user.languages.split("|") assert res.user.countries_visited == user.countries_visited.split("|") assert res.user.countries_lived == user.countries_lived.split("|") assert res.user.additional_information == user.additional_information assert res.user.friends == api_pb2.User.FriendshipStatus.NA assert not res.user.HasField("pending_friend_request") assert len(res.user.mutual_friends) == 0
def test_get_page(db): user1, token1 = generate_user() user2, token2 = generate_user() with session_scope() as session: c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id with pages_session(token1) as api: time_before_create = now() page_id = api.CreatePlace( pages_pb2.CreatePlaceReq( title="dummy title", content="dummy content", address="dummy address", location=pages_pb2.Coordinate( lat=1, lng=1, ), )).page_id with pages_session(token2) as api: time_before_get = now() res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) assert res.title == "dummy title" assert res.content == "dummy content" assert res.address == "dummy address" assert res.location.lat == 1 assert res.location.lng == 1 assert res.slug == "dummy-title" assert time_before_create < to_aware_datetime( res.created) < time_before_get assert time_before_create < to_aware_datetime( res.last_edited) < time_before_get assert res.last_editor_user_id == user1.id assert res.creator_user_id == user1.id assert res.owner_user_id == user1.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user1.id] assert not res.can_edit assert not res.can_moderate
def test_ping(db): user, token = generate_user(db, "tester") with real_api_session(db, token) as api: res = api.Ping(api_pb2.PingReq()) assert res.user.user_id == user.id assert res.user.username == user.username assert res.user.name == user.name assert res.user.city == user.city assert res.user.verification == user.verification assert res.user.community_standing == user.community_standing assert res.user.num_references == 0 assert res.user.gender == user.gender assert res.user.age == user.age assert res.user.color == user.color # the joined time is fuzzed # but shouldn't be before actual joined time, or more than one hour behind assert user.joined - timedelta(hours=1) <= to_aware_datetime( res.user.joined) <= user.joined # same for last_active assert user.last_active - timedelta(hours=1) <= to_aware_datetime( res.user.last_active) <= user.last_active assert res.user.hosting_status == api_pb2.HOSTING_STATUS_UNKNOWN assert res.user.occupation == user.occupation assert res.user.about_me == user.about_me assert res.user.about_place == user.about_place # TODO: this list serialisation will be fixed hopefully soon assert res.user.languages == user.languages.split("|") assert res.user.countries_visited == user.countries_visited.split("|") assert res.user.countries_lived == user.countries_lived.split("|") assert res.user.friends == api_pb2.User.FriendshipStatus.NA assert len(res.user.mutual_friends) == 0
def test_create_page_place(db): user, token = generate_user() with session_scope() as session: c_id = create_community(session, 0, 2, "Root node", [user], [], None).id with pages_session(token) as api: time_before = now() res = api.CreatePlace( pages_pb2.CreatePlaceReq( title="dummy !#¤%&/-*' title", content="dummy content", address="dummy address", location=pages_pb2.Coordinate( lat=1, lng=1, ), )) assert res.title == "dummy !#¤%&/-*' title" assert res.type == pages_pb2.PAGE_TYPE_PLACE assert res.content == "dummy content" assert res.address == "dummy address" assert res.location.lat == 1 assert res.location.lng == 1 assert res.slug == "dummy-title" assert time_before < to_aware_datetime(res.created) < now() assert time_before < to_aware_datetime(res.last_edited) < now() assert res.last_editor_user_id == user.id assert res.creator_user_id == user.id assert res.owner_user_id == user.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user.id] assert res.can_edit assert res.can_moderate
def test_AvailableWriteReferences_and_ListPendingReferencesToWrite(db): user1, token1 = generate_user() user2, token2 = generate_user() user3, token3 = generate_user() user4, token4 = generate_user() user5, token5 = generate_user(delete_user=True) user6, token6 = generate_user() user7, token7 = generate_user() make_user_block(user1, user6) make_user_block(user7, user1) with session_scope() as session: # too old hr1 = create_host_request(session, user3.id, user1.id, timedelta(days=20)) # already wrote friend ref to user3 create_friend_reference(session, user1.id, user3.id, timedelta(days=15, seconds=70)) # already given _, hr2 = create_host_reference(session, user2.id, user1.id, timedelta(days=10, seconds=110), surfing=True) create_host_reference(session, user1.id, user2.id, timedelta(days=10, seconds=100), host_request_id=hr2) # valid hosted hr3 = create_host_request(session, user3.id, user1.id, timedelta(days=8)) # valid surfed hr4 = create_host_request(session, user1.id, user4.id, timedelta(days=5)) # not yet complete hr5 = create_host_request(session, user2.id, user1.id, timedelta(days=2), status=HostRequestStatus.pending) # already wrote friend ref to user2 create_friend_reference(session, user1.id, user2.id, timedelta(days=1)) # user5 deleted, reference won't show up as pending create_host_request(session, user1.id, user5.id, timedelta(days=5)) # user6 blocked, reference won't show up as pending create_host_request(session, user1.id, user6.id, timedelta(days=5)) # user7 blocking, reference won't show up as pending create_host_request(session, user1.id, user7.id, timedelta(days=5)) with references_session(token1) as api: # can't write reference for invisible user with pytest.raises(grpc.RpcError) as e: api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq( to_user_id=user5.id)) assert e.value.code() == grpc.StatusCode.NOT_FOUND assert e.value.details() == errors.USER_NOT_FOUND # can't write reference for blocking user with pytest.raises(grpc.RpcError) as e: api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq( to_user_id=user7.id)) assert e.value.code() == grpc.StatusCode.NOT_FOUND assert e.value.details() == errors.USER_NOT_FOUND # can't write reference for blocked user with pytest.raises(grpc.RpcError) as e: api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq( to_user_id=user6.id)) assert e.value.code() == grpc.StatusCode.NOT_FOUND assert e.value.details() == errors.USER_NOT_FOUND # can't write anything to myself res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id)) assert not res.can_write_friend_reference assert len(res.available_write_references) == 0 res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id)) # can't write friend ref to user2 assert not res.can_write_friend_reference # none we can write for user2 assert len(res.available_write_references) == 0 res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user3.id)) # can't write friend ref to user3 assert not res.can_write_friend_reference # can write one reference because we hosted user3 assert len(res.available_write_references) == 1 w = res.available_write_references[0] assert w.host_request_id == hr3 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED assert now() + timedelta(days=6) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=7) res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user4.id)) # can write friend ref to user4 assert res.can_write_friend_reference # can write one reference because we surfed with user4 assert len(res.available_write_references) == 1 w = res.available_write_references[0] assert w.host_request_id == hr4 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED assert now() + timedelta(days=9) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=10) # finally check the general list res = api.ListPendingReferencesToWrite(empty_pb2.Empty()) assert len(res.pending_references) == 2 w = res.pending_references[0] assert w.host_request_id == hr3 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED assert now() + timedelta(days=6) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=7) w = res.pending_references[1] assert w.host_request_id == hr4 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED assert now() + timedelta(days=9) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=10)
def test_WriteFriendReference(db): user1, token1 = generate_user() user2, token2 = generate_user() user3, token3 = generate_user() with references_session(token1) as api: # can write normal friend reference res = api.WriteFriendReference( references_pb2.WriteFriendReferenceReq( to_user_id=user2.id, text="A test reference", was_appropriate=True, rating=0.5, )) assert res.from_user_id == user1.id assert res.to_user_id == user2.id assert res.reference_type == references_pb2.REFERENCE_TYPE_FRIEND assert res.text == "A test reference" assert now() - timedelta(hours=24) <= to_aware_datetime( res.written_time) <= now() assert not res.host_request_id with references_session(token3) as api: # check it shows up res = api.ListReferences( references_pb2.ListReferencesReq( from_user_id=user1.id, to_user_id=user2.id, reference_type_filter=[references_pb2.REFERENCE_TYPE_FRIEND])) assert len(res.references) == 1 ref = res.references[0] assert ref.from_user_id == user1.id assert ref.to_user_id == user2.id assert ref.reference_type == references_pb2.REFERENCE_TYPE_FRIEND assert ref.text == "A test reference" assert now() - timedelta(hours=24) <= to_aware_datetime( ref.written_time) <= now() assert not ref.host_request_id with references_session(token1) as api: # can't write a second friend reference with pytest.raises(grpc.RpcError) as e: api.WriteFriendReference( references_pb2.WriteFriendReferenceReq( to_user_id=user2.id, text="A test reference", was_appropriate=True, rating=0.5, )) assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION assert e.value.details() == errors.REFERENCE_ALREADY_GIVEN with references_session(token2) as api: # can't write a reference about yourself with pytest.raises(grpc.RpcError) as e: api.WriteFriendReference( references_pb2.WriteFriendReferenceReq( to_user_id=user2.id, text="I'm really awesome", was_appropriate=True, rating=1.0, )) assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT assert e.value.details() == errors.CANT_REFER_SELF
def UpdateEvent(self, request, context): with session_scope() as session: res = session.execute( select(Event, EventOccurrence).where( EventOccurrence.id == request.event_id).where( EventOccurrence.event_id == Event.id)).one_or_none() if not res: context.abort(grpc.StatusCode.NOT_FOUND, errors.EVENT_NOT_FOUND) event, occurrence = res if not _can_edit_event(session, event, context.user_id): context.abort(grpc.StatusCode.PERMISSION_DENIED, errors.EVENT_EDIT_PERMISSION_DENIED) occurrence_update = {"last_edited": now()} if request.HasField("title"): event.title = request.title.value event.last_edited = now() if request.HasField("content"): occurrence_update["content"] = request.content.value if request.HasField("photo_key"): occurrence_update["photo_key"] = request.photo_key.value if request.HasField("online_information"): if not request.online_information.link: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.ONLINE_EVENT_REQUIRES_LINK) occurrence_update["link"] = request.online_information.link occurrence_update["geom"] = None occurrence_update["address"] = None elif request.HasField("offline_information"): occurrence_update["link"] = None if request.offline_information.lat == 0 and request.offline_information.lng == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_COORDINATE) occurrence_update["geom"] = create_coordinate( request.offline_information.lat, request.offline_information.lng) occurrence_update[ "address"] = request.offline_information.address if request.HasField("start_time") or request.HasField("end_time"): if request.update_all_future: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.EVENT_CANT_UPDATE_ALL_TIMES) if request.HasField("start_time"): start_time = to_aware_datetime(request.start_time) else: start_time = occurrence.start_time if request.HasField("end_time"): end_time = to_aware_datetime(request.end_time) else: end_time = occurrence.end_time _check_occurrence_time_validity(start_time, end_time, context) during = DateTimeTZRange(start_time, end_time) # && is the overlap operator for ranges if (session.execute( select(EventOccurrence.id).where( EventOccurrence.event_id == event.id).where( EventOccurrence.id != occurrence.id).where( EventOccurrence.during.op("&&") (during))).scalars().first() is not None): context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.EVENT_CANT_OVERLAP) occurrence_update["during"] = during # TODO # if request.HasField("timezone"): # occurrence_update["timezone"] = request.timezone # allow editing any event which hasn't ended more than 24 hours before now # when editing all future events, we edit all which have not yet ended if request.update_all_future: session.execute( update(EventOccurrence).where( EventOccurrence.end_time >= now() - timedelta(hours=24)).where( EventOccurrence.start_time >= occurrence.start_time ).values(occurrence_update).execution_options( synchronize_session=False)) else: if occurrence.end_time < now() - timedelta(hours=24): context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.EVENT_CANT_UPDATE_OLD_EVENT) session.execute( update(EventOccurrence).where( EventOccurrence.end_time >= now() - timedelta(hours=24)).where( EventOccurrence.id == occurrence.id).values( occurrence_update).execution_options( synchronize_session=False)) # TODO notify session.flush() # since we have synchronize_session=False, we have to refresh the object session.refresh(occurrence) return event_to_pb(session, occurrence, context)
def ScheduleEvent(self, request, context): if not request.content: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_CONTENT) if request.HasField("online_information"): online = True geom = None address = None link = request.online_information.link elif request.HasField("offline_information"): online = False if not (request.offline_information.address and request.offline_information.lat and request.offline_information.lng): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_ADDRESS_OR_LOCATION) if request.offline_information.lat == 0 and request.offline_information.lng == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_COORDINATE) geom = create_coordinate(request.offline_information.lat, request.offline_information.lng) address = request.offline_information.address link = None else: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_ADDRESS_LOCATION_OR_LINK) start_time = to_aware_datetime(request.start_time) end_time = to_aware_datetime(request.end_time) _check_occurrence_time_validity(start_time, end_time, context) with session_scope() as session: res = session.execute( select(Event, EventOccurrence).where( EventOccurrence.id == request.event_id).where( EventOccurrence.event_id == Event.id)).one_or_none() if not res: context.abort(grpc.StatusCode.NOT_FOUND, errors.EVENT_NOT_FOUND) event, occurrence = res if not _can_edit_event(session, event, context.user_id): context.abort(grpc.StatusCode.PERMISSION_DENIED, errors.EVENT_EDIT_PERMISSION_DENIED) if (request.photo_key and not session.execute( select(Upload).where(Upload.key == request.photo_key)). scalar_one_or_none()): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.PHOTO_NOT_FOUND) during = DateTimeTZRange(start_time, end_time) # && is the overlap operator for ranges if (session.execute( select(EventOccurrence.id).where( EventOccurrence.event_id == event.id).where( EventOccurrence.during.op("&&")( during))).scalars().first() is not None): context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.EVENT_CANT_OVERLAP) occurrence = EventOccurrence( event=event, content=request.content, geom=geom, address=address, link=link, photo_key=request.photo_key if request.photo_key != "" else None, # timezone=timezone, during=during, creator_user_id=context.user_id, ) session.add(occurrence) attendee = EventOccurrenceAttendee( user_id=context.user_id, occurrence=occurrence, attendee_status=AttendeeStatus.going, ) session.add(attendee) session.flush() # TODO: notify return event_to_pb(session, occurrence, context)
def CreateEvent(self, request, context): if not request.title: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_TITLE) if not request.content: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_CONTENT) if request.HasField("online_information"): online = True geom = None address = None if not request.online_information.link: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.ONLINE_EVENT_REQUIRES_LINK) link = request.online_information.link elif request.HasField("offline_information"): online = False if not (request.offline_information.address and request.offline_information.lat and request.offline_information.lng): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_ADDRESS_OR_LOCATION) if request.offline_information.lat == 0 and request.offline_information.lng == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_COORDINATE) geom = create_coordinate(request.offline_information.lat, request.offline_information.lng) address = request.offline_information.address link = None else: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_EVENT_ADDRESS_LOCATION_OR_LINK) start_time = to_aware_datetime(request.start_time) end_time = to_aware_datetime(request.end_time) _check_occurrence_time_validity(start_time, end_time, context) with session_scope() as session: if request.parent_community_id: parent_node = session.execute( select(Node).where(Node.id == request.parent_community_id) ).scalar_one_or_none() else: if online: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.ONLINE_EVENT_MISSING_PARENT_COMMUNITY) # parent community computed from geom parent_node = get_parent_node_at_location(session, geom) if not parent_node: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.COMMUNITY_NOT_FOUND) if (request.photo_key and not session.execute( select(Upload).where(Upload.key == request.photo_key)). scalar_one_or_none()): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.PHOTO_NOT_FOUND) event = Event( title=request.title, parent_node_id=parent_node.id, owner_user_id=context.user_id, thread=Thread(), creator_user_id=context.user_id, ) session.add(event) occurrence = EventOccurrence( event=event, content=request.content, geom=geom, address=address, link=link, photo_key=request.photo_key if request.photo_key != "" else None, # timezone=timezone, during=DateTimeTZRange(start_time, end_time), creator_user_id=context.user_id, ) session.add(occurrence) organizer = EventOrganizer( user_id=context.user_id, event=event, ) session.add(organizer) subscription = EventSubscription( user_id=context.user_id, event=event, ) session.add(subscription) attendee = EventOccurrenceAttendee( user_id=context.user_id, occurrence=occurrence, attendee_status=AttendeeStatus.going, ) session.add(attendee) session.commit() return event_to_pb(session, occurrence, context)
def test_update_page(db): user, token = generate_user() with session_scope() as session: c_id = create_community(session, 0, 2, "Root node", [user], [], None).id with pages_session(token) as api: time_before_create = now() page_id = api.CreatePlace( pages_pb2.CreatePlaceReq( title="dummy title", content="dummy content", address="dummy address", location=pages_pb2.Coordinate( lat=1, lng=1, ), )).page_id time_before_update = now() api.UpdatePage( pages_pb2.UpdatePageReq( page_id=page_id, title=wrappers_pb2.StringValue(value="test title"), )) time_before_get = now() res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) assert res.title == "test title" assert res.content == "dummy content" assert res.address == "dummy address" assert res.location.lat == 1 assert res.location.lng == 1 assert res.slug == "test-title" assert time_before_create < to_aware_datetime( res.created) < time_before_update assert time_before_update < to_aware_datetime( res.last_edited) < time_before_get assert to_aware_datetime(res.created) < to_aware_datetime( res.last_edited) assert res.last_editor_user_id == user.id assert res.creator_user_id == user.id assert res.owner_user_id == user.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user.id] assert res.can_edit assert res.can_moderate time_before_second_update = now() api.UpdatePage( pages_pb2.UpdatePageReq( page_id=page_id, content=wrappers_pb2.StringValue(value="test content"), )) time_before_second_get = now() res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) assert res.title == "test title" assert res.content == "test content" assert res.address == "dummy address" assert res.location.lat == 1 assert res.location.lng == 1 assert res.slug == "test-title" assert time_before_create < to_aware_datetime( res.created) < time_before_update assert time_before_second_update < to_aware_datetime( res.last_edited) < time_before_second_get assert to_aware_datetime(res.created) < to_aware_datetime( res.last_edited) assert res.last_editor_user_id == user.id assert res.creator_user_id == user.id assert res.owner_user_id == user.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user.id] assert res.can_edit assert res.can_moderate time_before_third_update = now() api.UpdatePage( pages_pb2.UpdatePageReq( page_id=page_id, address=wrappers_pb2.StringValue(value="test address"), )) time_before_third_get = now() res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) assert res.title == "test title" assert res.content == "test content" assert res.address == "test address" assert res.location.lat == 1 assert res.location.lng == 1 assert res.slug == "test-title" assert time_before_create < to_aware_datetime( res.created) < time_before_update assert time_before_third_update < to_aware_datetime( res.last_edited) < time_before_third_get assert to_aware_datetime(res.created) < to_aware_datetime( res.last_edited) assert res.last_editor_user_id == user.id assert res.creator_user_id == user.id assert res.owner_user_id == user.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user.id] assert res.can_edit assert res.can_moderate time_before_fourth_update = now() api.UpdatePage( pages_pb2.UpdatePageReq( page_id=page_id, location=pages_pb2.Coordinate( lat=3, lng=1.222, ), )) time_before_fourth_get = now() res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) assert res.title == "test title" assert res.content == "test content" assert res.address == "test address" assert res.location.lat == 3 assert res.location.lng == 1.222 assert res.slug == "test-title" assert time_before_create < to_aware_datetime( res.created) < time_before_update assert time_before_fourth_update < to_aware_datetime( res.last_edited) < time_before_fourth_get assert to_aware_datetime(res.created) < to_aware_datetime( res.last_edited) assert res.last_editor_user_id == user.id assert res.creator_user_id == user.id assert res.owner_user_id == user.id assert not res.owner_community_id assert not res.owner_group_id assert res.editor_user_ids == [user.id] assert res.can_edit assert res.can_moderate
def test_create_and_get_discussion(db): generate_user() user, token = generate_user() user2, token2 = generate_user() generate_user() generate_user() with session_scope() as session: community = create_community(session, 0, 1, "Testing Community", [user2], [], None) group_id = create_group(session, "Testing Group", [user2], [], community).id community_id = community.id with discussions_session(token) as api: time_before_create = now() res = api.CreateDiscussion( discussions_pb2.CreateDiscussionReq( title="dummy title", content="dummy content", owner_community_id=community_id, )) time_after_create = now() assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create <= to_aware_datetime( res.created) <= time_after_create assert res.creator_user_id == user.id assert res.owner_community_id == community_id discussion_id = res.discussion_id with discussions_session(token) as api: res = api.GetDiscussion( discussions_pb2.GetDiscussionReq(discussion_id=discussion_id, )) assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create <= to_aware_datetime( res.created) <= time_after_create assert res.creator_user_id == user.id assert res.owner_community_id == community_id with discussions_session(token) as api: time_before_create = now() res = api.CreateDiscussion( discussions_pb2.CreateDiscussionReq( title="dummy title", content="dummy content", owner_group_id=group_id, )) time_after_create = now() assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create <= to_aware_datetime( res.created) <= time_after_create assert res.creator_user_id == user.id assert res.owner_group_id == group_id discussion_id = res.discussion_id with discussions_session(token) as api: res = api.GetDiscussion( discussions_pb2.GetDiscussionReq(discussion_id=discussion_id, )) assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create <= to_aware_datetime( res.created) <= time_after_create assert res.creator_user_id == user.id assert res.owner_group_id == group_id
def UserSearch(self, request, context): with session_scope() as session: query = session.query(User).filter(~User.is_banned) if request.HasField("query"): if request.query_name_only: query = query.filter( or_(User.name.ilike(f"%{request.query.value}%"), User.username.ilike(f"%{request.query.value}%"))) else: query = query.filter( or_( User.name.ilike(f"%{request.query.value}%"), User.username.ilike(f"%{request.query.value}%"), User.city.ilike(f"%{request.query.value}%"), User.hometown.ilike(f"%{request.query.value}%"), User.about_me.ilike(f"%{request.query.value}%"), User.my_travels.ilike(f"%{request.query.value}%"), User.things_i_like.ilike( f"%{request.query.value}%"), User.about_place.ilike(f"%{request.query.value}%"), User.additional_information.ilike( f"%{request.query.value}%"), )) if request.HasField("last_active"): raw_dt = to_aware_datetime(request.last_active) coarsened_dt = raw_dt.replace(minute=(raw_dt.minute // 15) * 15, second=0, microsecond=0) query = query.filter(User.last_active >= coarsened_dt) if request.HasField("gender"): query = query.filter( User.gender.ilike(f"%{request.gender.value}%")) if len(request.hosting_status_filter) > 0: query = query.filter( User.hosting_status.in_([ hostingstatus2sql[status] for status in request.hosting_status_filter ])) if len(request.smoking_location_filter) > 0: query = query.filter( User.smoking_allowed.in_([ smokinglocation2sql[loc] for loc in request.smoking_location_filter ])) if len(request.sleeping_arrangement_filter) > 0: query = query.filter( User.sleeping_arrangement.in_([ sleepingarrangement2sql[arr] for arr in request.sleeping_arrangement_filter ])) if len(request.parking_details_filter) > 0: query = query.filter( User.parking_details.in_([ parkingdetails2sql[det] for det in request.parking_details_filter ])) if request.HasField("guests"): query = query.filter(User.max_guests >= request.guests.value) if request.HasField("last_minute"): query = query.filter(User.last_minute == last_minute.value) if request.HasField("has_pets"): query = query.filter(User.has_pets == has_pets.value) if request.HasField("accepts_pets"): query = query.filter(User.accepts_pets == accepts_pets.value) if request.HasField("has_kids"): query = query.filter(User.has_kids == has_kids.value) if request.HasField("accepts_kids"): query = query.filter(User.accepts_kids == accepts_kids.value) if request.HasField("has_housemates"): query = query.filter( User.has_housemates == has_housemates.value) if request.HasField("wheelchair_accessible"): query = query.filter( User.wheelchair_accessible == wheelchair_accessible.value) if request.HasField("smokes_at_home"): query = query.filter( User.smokes_at_home == smokes_at_home.value) if request.HasField("drinking_allowed"): query = query.filter( User.drinking_allowed == drinking_allowed.value) if request.HasField("drinks_at_home"): query = query.filter( User.drinks_at_home == drinks_at_home.value) if request.HasField("parking"): query = query.filter(User.parking == parking.value) if request.HasField("camping_ok"): query = query.filter(User.camping_ok == camping_ok.value) if request.HasField("search_in_area"): # EPSG4326 measures distance in decimal degress # we want to check whether two circles overlap, so check if the distance between their centers is less # than the sum of their radii, divided by 111111 m ~= 1 degree (at the equator) search_point = create_coordinate(request.search_in_area.lat, request.search_in_area.lng) query = query.filter( func.ST_DWithin( User.geom, search_point, (User.geom_radius + request.search_in_area.radius) / 111111)) if request.HasField("search_in_community_id"): # could do a join here as well, but this is just simpler node = session.query(Node).filter( Node.id == request.search_in_community_id).one_or_none() if not node: context.abort(grpc.StatusCode.NOT_FOUND, errors.COMMUNITY_NOT_FOUND) query = query.filter(func.ST_Contains(node.geom, User.geom)) if request.only_with_references: query = query.join(Reference, Reference.to_user_id == User.id) # TODO: # google.protobuf.StringValue language = 11; # bool friends_only = 13; # google.protobuf.UInt32Value age_min = 14; # google.protobuf.UInt32Value age_max = 15; page_size = min(MAX_PAGINATION_LENGTH, request.page_size or MAX_PAGINATION_LENGTH) next_user_id = int(request.page_token) if request.page_token else 0 users = query.filter(User.id >= next_user_id).order_by( User.id).limit(page_size + 1).all() return search_pb2.UserSearchRes( results=[ search_pb2.Result( rank=1, user=user_model_to_pb(user, session, context), ) for user in users[:page_size] ], next_page_token=str(users[-1].id) if len(users) > page_size else None, )
def test_references(db): user1, token1 = generate_user() user2, token2 = generate_user() alltypes = set([ api_pb2.ReferenceType.FRIEND, api_pb2.ReferenceType.HOSTED, api_pb2.ReferenceType.SURFED ]) # write all three reference types for typ in alltypes: req = api_pb2.WriteReferenceReq(to_user_id=user2.id, reference_type=typ, text="kinda weird sometimes") with api_session(token1) as api: res = api.WriteReference(req) assert isinstance(res, empty_pb2.Empty) # See what I have written. Paginate it. seen_types = set() for i in range(3): req = api_pb2.GetGivenReferencesReq(from_user_id=user1.id, number=1, start_at=i) with api_session(token1) as api: res = api.GetGivenReferences(req) assert res.total_matches == 3 assert len(res.references) == 1 assert res.references[0].from_user_id == user1.id assert res.references[0].to_user_id == user2.id assert res.references[0].text == "kinda weird sometimes" assert abs(to_aware_datetime(res.references[0].written_time) - now()) <= timedelta(days=32) assert res.references[0].reference_type not in seen_types seen_types.add(res.references[0].reference_type) assert seen_types == alltypes # See what user2 have received. Paginate it. seen_types = set() for i in range(3): req = api_pb2.GetReceivedReferencesReq(to_user_id=user2.id, number=1, start_at=i) with api_session(token1) as api: res = api.GetReceivedReferences(req) assert res.total_matches == 3 assert len(res.references) == 1 assert res.references[0].from_user_id == user1.id assert res.references[0].to_user_id == user2.id assert res.references[0].text == "kinda weird sometimes" assert res.references[0].reference_type not in seen_types seen_types.add(res.references[0].reference_type) assert seen_types == alltypes # Check available types with api_session(token1) as api: res = api.AvailableWriteReferenceTypes( api_pb2.AvailableWriteReferenceTypesReq(to_user_id=user2.id)) assert res.reference_types == [] with api_session(token2) as api: res = api.AvailableWriteReferenceTypes( api_pb2.AvailableWriteReferenceTypesReq(to_user_id=user1.id)) assert set(res.reference_types) == alltypes # Forbidden to write a second reference of the same type req = api_pb2.WriteReferenceReq( to_user_id=user2.id, reference_type=api_pb2.ReferenceType.HOSTED, text="ok") with api_session(token1) as api: with pytest.raises(grpc.RpcError) as e: api.WriteReference(req) assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION assert e.value.details() == errors.REFERENCE_ALREADY_GIVEN # Nonexisting user req = api_pb2.WriteReferenceReq( to_user_id=0x7FFFFFFFFFFFFFFF, reference_type=api_pb2.ReferenceType.HOSTED, text="ok") with api_session(token1) as api: with pytest.raises(grpc.RpcError) as e: api.WriteReference(req) assert e.value.code() == grpc.StatusCode.NOT_FOUND assert e.value.details() == errors.USER_NOT_FOUND # yourself req = api_pb2.WriteReferenceReq( to_user_id=user1.id, reference_type=api_pb2.ReferenceType.HOSTED, text="ok") with api_session(token1) as api: with pytest.raises(grpc.RpcError) as e: api.WriteReference(req) assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT assert e.value.details() == errors.CANT_REFER_SELF with api_session(token2) as api: # test the number of references in GetUser and Ping res = api.GetUser(api_pb2.GetUserReq(user=user2.username)) assert res.num_references == 3 res = api.Ping(api_pb2.PingReq()) assert res.user.num_references == 3
def test_AvailableWriteReferences_and_ListPendingReferencesToWrite(db): user1, token1 = generate_user() user2, token2 = generate_user() user3, token3 = generate_user() user4, token4 = generate_user() with session_scope() as session: # too old hr1 = create_host_request(session, user3.id, user1.id, timedelta(days=20)) # already wrote friend ref to user3 create_friend_reference(session, user1.id, user3.id, timedelta(days=15, seconds=70)) # already given _, hr2 = create_host_reference(session, user2.id, user1.id, timedelta(days=10, seconds=110), surfing=True) create_host_reference(session, user1.id, user2.id, timedelta(days=10, seconds=100), host_request_id=hr2) print(hr2) # valid hosted hr3 = create_host_request(session, user3.id, user1.id, timedelta(days=8)) # valid surfed hr4 = create_host_request(session, user1.id, user4.id, timedelta(days=5)) # not yet complete hr5 = create_host_request(session, user2.id, user1.id, timedelta(days=2), status=HostRequestStatus.accepted) # already wrote friend ref to user2 create_friend_reference(session, user1.id, user2.id, timedelta(days=1)) with references_session(token1) as api: # can't write anything to myself res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user1.id)) assert not res.can_write_friend_reference assert len(res.available_write_references) == 0 res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user2.id)) # can't write friend ref to user2 assert not res.can_write_friend_reference # none we can write for user2 assert len(res.available_write_references) == 0 res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user3.id)) # can't write friend ref to user3 assert not res.can_write_friend_reference # can write one reference because we hosted user3 assert len(res.available_write_references) == 1 w = res.available_write_references[0] assert w.host_request_id == hr3 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED assert now() + timedelta(days=6) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=7) res = api.AvailableWriteReferences( references_pb2.AvailableWriteReferencesReq(to_user_id=user4.id)) # can write friend ref to user4 assert res.can_write_friend_reference # can write one reference because we surfed with user4 assert len(res.available_write_references) == 1 w = res.available_write_references[0] assert w.host_request_id == hr4 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED assert now() + timedelta(days=9) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=10) # finally check the general list res = api.ListPendingReferencesToWrite(empty_pb2.Empty()) assert len(res.pending_references) == 2 w = res.pending_references[0] assert w.host_request_id == hr3 assert w.reference_type == references_pb2.REFERENCE_TYPE_HOSTED assert now() + timedelta(days=6) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=7) w = res.pending_references[1] assert w.host_request_id == hr4 assert w.reference_type == references_pb2.REFERENCE_TYPE_SURFED assert now() + timedelta(days=9) <= to_aware_datetime( w.time_expires) <= now() + timedelta(days=10)
def test_create_and_get_discussion(db): generate_user() user, token = generate_user() generate_user() generate_user() with session_scope() as session: node = Node(geom=to_multi( create_polygon_lat_lng([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]))) session.add(node) community_cluster = Cluster( name=f"Testing Community", description=f"Description for testing community", parent_node=node, is_official_cluster=True, ) session.add(community_cluster) main_page = Page( parent_node=community_cluster.parent_node, creator_user_id=user.id, owner_cluster=community_cluster, type=PageType.main_page, thread=Thread(), ) session.add(main_page) session.add( PageVersion( page=main_page, editor_user_id=user.id, title=f"Main page for the testing community", content="Empty.", )) # create a group group_cluster = Cluster( name=f"Testing Group", description=f"Description for testing group", parent_node=node, ) session.add(group_cluster) main_page = Page( parent_node=group_cluster.parent_node, creator_user_id=user.id, owner_cluster=group_cluster, type=PageType.main_page, thread=Thread(), ) session.add(main_page) session.add( PageVersion( page=main_page, editor_user_id=user.id, title=f"Main page for the testing community", content="Empty.", )) session.flush() community_id = node.id community_cluster_id = community_cluster.id group_id = group_cluster.id with discussions_session(token) as api: time_before_create = now() res = api.CreateDiscussion( discussions_pb2.CreateDiscussionReq( title="dummy title", content="dummy content", owner_community_id=community_id, )) time_after_create = now() assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create < to_aware_datetime( res.created) < time_after_create assert res.creator_user_id == user.id assert res.owner_community_id == community_id discussion_id = res.discussion_id with discussions_session(token) as api: res = api.GetDiscussion( discussions_pb2.GetDiscussionReq(discussion_id=discussion_id, )) assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create < to_aware_datetime( res.created) < time_after_create assert res.creator_user_id == user.id assert res.owner_community_id == community_id with discussions_session(token) as api: time_before_create = now() res = api.CreateDiscussion( discussions_pb2.CreateDiscussionReq( title="dummy title", content="dummy content", owner_group_id=group_id, )) time_after_create = now() assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create < to_aware_datetime( res.created) < time_after_create assert res.creator_user_id == user.id assert res.owner_group_id == group_id discussion_id = res.discussion_id with discussions_session(token) as api: res = api.GetDiscussion( discussions_pb2.GetDiscussionReq(discussion_id=discussion_id, )) assert res.title == "dummy title" assert res.content == "dummy content" assert res.slug == "dummy-title" assert time_before_create < to_aware_datetime( res.created) < time_after_create assert res.creator_user_id == user.id assert res.owner_group_id == group_id