Example #1
0
    def CreateGuide(self, request, context):
        if not request.title:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_TITLE)
        if not request.content:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_CONTENT)
        if request.address and request.HasField("location"):
            address = request.address
            if request.location.lat == 0 and request.location.lng == 0:
                context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                              errors.INVALID_COORDINATE)
            geom = create_coordinate(request.location.lat,
                                     request.location.lng)
        elif not request.address and not request.HasField("location"):
            address = None
            geom = None
        else:
            # you have to have both or neither
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.INVALID_GUIDE_LOCATION)

        if not request.parent_community_id:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_PARENT)

        with session_scope() as session:
            parent_node = session.query(Node).filter(
                Node.id == request.parent_community_id).one_or_none()

            if not parent_node:
                context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                              errors.COMMUNITY_NOT_FOUND)

            if request.photo_key and not session.query(Upload).filter(
                    Upload.key == request.photo_key).one_or_none():
                context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                              errors.PHOTO_NOT_FOUND)

            page = Page(
                parent_node=parent_node,
                type=PageType.guide,
                creator_user_id=context.user_id,
                owner_user_id=context.user_id,
                thread=Thread(),
            )
            session.add(page)
            session.flush()
            page_version = PageVersion(
                page=page,
                editor_user_id=context.user_id,
                title=request.title,
                content=request.content,
                photo_key=request.photo_key if request.photo_key else None,
                address=address,
                geom=geom,
            )
            session.add(page_version)
            session.commit()
            return page_to_pb(page, context.user_id)
Example #2
0
def test_threads_pagination(db):
    user1, token1 = generate_user()

    PARENT_THREAD_ID = 10

    # Create a dummy Thread (should be replaced by pages later on)
    with session_scope() as session:
        session.add(Thread(id=1))

    with threads_session(token1) as api:
        comment_id = pagination_test(api, PARENT_THREAD_ID)
        pagination_test(api, comment_id)
Example #3
0
def test_threads_num_responses(db):
    user1, token1 = generate_user()

    # Create a dummy Thread (should be replaced by pages later on)
    with session_scope() as session:
        dummy_thread = Thread()
        session.add(dummy_thread)
        session.flush()
        PARENT_THREAD_ID = pack_thread_id(database_id=dummy_thread.id, depth=0)

    with threads_session(token1) as api:
        # add some comments and replies to the dummy Thread
        bat_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="bat")).thread_id

        cat_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="cat")).thread_id

        dog_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="dog")).thread_id

        dogs = [
            api.PostReply(
                threads_pb2.PostReplyReq(thread_id=dog_id,
                                         content=animal)).thread_id
            for animal in ["hyena", "wolf", "prairie wolf"]
        ]
        cats = [
            api.PostReply(
                threads_pb2.PostReplyReq(thread_id=cat_id,
                                         content=animal)).thread_id
            for animal in ["cheetah", "lynx", "panther"]
        ]

        # test num_responses
        ret = api.GetThread(
            threads_pb2.GetThreadReq(thread_id=PARENT_THREAD_ID))
        assert ret.num_responses == 9

        ret = api.GetThread(threads_pb2.GetThreadReq(thread_id=dog_id))
        assert ret.num_responses == 3

        # test num_responses with page_size < num_responses
        ret = api.GetThread(
            threads_pb2.GetThreadReq(thread_id=PARENT_THREAD_ID, page_size=1))
        assert ret.num_responses == 9
Example #4
0
def create_cluster(
    session,
    parent_node_id: int,
    name: str,
    description: str,
    creator_user_id: int,
    admin_ids: List,
    is_community: bool,
):
    type = "community" if is_community else "group"
    cluster = Cluster(
        name=name,
        description=description,
        parent_node_id=parent_node_id,
        is_official_cluster=is_community,
    )
    session.add(cluster)
    session.flush()
    main_page = Page(
        parent_node=cluster.parent_node,
        creator_user_id=creator_user_id,
        owner_cluster=cluster,
        type=PageType.main_page,
        thread=Thread(),
    )
    session.add(main_page)
    session.flush()
    page_version = PageVersion(
        page=main_page,
        editor_user_id=creator_user_id,
        title=DEFAULT_PAGE_TITLE_TEMPLATE.format(name=name, type=type),
        content=DEFAULT_PAGE_CONTENT,
    )
    session.add(page_version)
    cluster.cluster_subscriptions.append(
        ClusterSubscription(
            user_id=creator_user_id,
            role=ClusterRole.admin,
        ))
    for admin_id in admin_ids:
        cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=admin_id,
                role=ClusterRole.admin,
            ))
    return cluster
Example #5
0
    def CreatePlace(self, request, context):
        if not request.title:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_TITLE)
        if not request.content:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_CONTENT)
        if not request.address:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_ADDRESS)
        if not request.HasField("location"):
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_PAGE_LOCATION)
        if request.location.lat == 0 and request.location.lng == 0:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.INVALID_COORDINATE)

        geom = create_coordinate(request.location.lat, request.location.lng)

        with session_scope() as session:
            if request.photo_key and not session.query(Upload).filter(
                    Upload.key == request.photo_key).one_or_none():
                context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                              errors.PHOTO_NOT_FOUND)

            page = Page(
                parent_node=get_parent_node_at_location(session, geom),
                type=PageType.place,
                creator_user_id=context.user_id,
                owner_user_id=context.user_id,
                thread=Thread(),
            )
            session.add(page)
            session.flush()
            page_version = PageVersion(
                page=page,
                editor_user_id=context.user_id,
                title=request.title,
                content=request.content,
                photo_key=request.photo_key if request.photo_key else None,
                address=request.address,
                geom=geom,
            )
            session.add(page_version)
            session.commit()
            return page_to_pb(page, context.user_id)
Example #6
0
def create_community(session, interval_lb, interval_ub, name, admins,
                     extra_members, parent):
    node = Node(
        geom=to_multi(create_1d_polygon(interval_lb, interval_ub)),
        parent_node=parent,
    )
    session.add(node)
    cluster = Cluster(
        name=f"{name}",
        description=f"Description for {name}",
        parent_node=node,
        is_official_cluster=True,
    )
    session.add(cluster)
    main_page = Page(
        parent_node=cluster.parent_node,
        creator_user_id=admins[0].id,
        owner_cluster=cluster,
        type=PageType.main_page,
        thread=Thread(),
    )
    session.add(main_page)
    page_version = PageVersion(
        page=main_page,
        editor_user_id=admins[0].id,
        title=f"Main page for the {name} community",
        content="There is nothing here yet...",
    )
    session.add(page_version)
    for admin in admins:
        cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=admin.id,
                role=ClusterRole.admin,
            ))
    for member in extra_members:
        cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=member.id,
                role=ClusterRole.member,
            ))
    session.commit()
    # other members will be added by enforce_community_memberships()
    return node
Example #7
0
    def CreateDiscussion(self, request, context):
        if not request.title:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_DISCUSSION_TITLE)
        if not request.content:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.MISSING_DISCUSSION_CONTENT)
        if not request.owner_community_id and not request.owner_group_id:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT,
                          errors.GROUP_OR_COMMUNITY_NOT_FOUND)

        with session_scope() as session:
            if request.WhichOneof("owner") == "owner_group_id":
                cluster = session.execute(
                    select(Cluster).where(~Cluster.is_official_cluster).where(
                        Cluster.id ==
                        request.owner_group_id)).scalar_one_or_none()
            elif request.WhichOneof("owner") == "owner_community_id":
                cluster = session.execute(
                    select(Cluster).where(
                        Cluster.parent_node_id ==
                        request.owner_community_id).where(
                            Cluster.is_official_cluster)).scalar_one_or_none()

            if not cluster:
                context.abort(grpc.StatusCode.NOT_FOUND,
                              errors.GROUP_OR_COMMUNITY_NOT_FOUND)

            discussion = Discussion(
                title=request.title,
                content=request.content,
                creator_user_id=context.user_id,
                owner_cluster=cluster,
                thread=Thread(),
            )
            session.add(discussion)
            session.commit()
            return discussion_to_pb(discussion, context)
Example #8
0
def create_group(session, name, admins, members, parent_community):
    cluster = Cluster(
        name=f"{name}",
        description=f"Description for {name}",
        parent_node=parent_community,
    )
    session.add(cluster)
    main_page = Page(
        parent_node=cluster.parent_node,
        creator_user=admins[0],
        owner_cluster=cluster,
        type=PageType.main_page,
        thread=Thread(),
    )
    session.add(main_page)
    page_version = PageVersion(
        page=main_page,
        editor_user=admins[0],
        title=f"Main page for the {name} community",
        content="There is nothing here yet...",
    )
    session.add(page_version)
    for admin in admins:
        cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user=admin,
                role=ClusterRole.admin,
            ))
    for member in members:
        cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user=member,
                role=ClusterRole.member,
            ))
    session.commit()
    return cluster
Example #9
0
    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)
Example #10
0
def test_page_constraints(db):
    user, token = generate_user()

    with session_scope() as session:
        c_id = create_community(session, 0, 2, "Root node", [user], [],
                                None).id

    # check we can't create a page without an owner
    with pytest.raises(IntegrityError) as e:
        with session_scope() as session:
            page = Page(
                parent_node_id=c_id,
                # note no owner
                creator_user_id=user.id,
                type=PageType.guide,
                thread=Thread(),
            )
            session.add(page)
            session.add(
                PageVersion(
                    page=page,
                    editor_user_id=user.id,
                    title=f"Title",
                    content="Content",
                ))
    assert "violates check constraint" in str(e.value)
    assert "one_owner" in str(e.value)

    with session_scope() as session:
        node = Node(geom=to_multi(
            create_polygon_lat_lng([[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]])))
        session.add(node)
        cluster = Cluster(
            name=f"Testing Community",
            description=f"Description for testing community",
            parent_node=node,
        )
        session.add(cluster)
        session.flush()
        cluster_parent_id = cluster.parent_node_id
        cluster_id = cluster.id

    # check we can't create a page with two owners
    with pytest.raises(IntegrityError) as e:
        with session_scope() as session:
            page = Page(
                parent_node_id=cluster_parent_id,
                creator_user_id=user.id,
                owner_cluster_id=cluster_id,
                owner_user_id=user.id,
                type=PageType.guide,
                thread=Thread(),
            )
            session.add(page)
            session.add(
                PageVersion(
                    page=page,
                    editor_user_id=user.id,
                    title=f"Title",
                    content="Content",
                ))
    assert "violates check constraint" in str(e.value)
    assert "one_owner" in str(e.value)

    # main page must be owned by the right cluster
    with pytest.raises(IntegrityError) as e:
        with session_scope() as session:
            main_page = Page(
                parent_node_id=cluster_parent_id,
                # note owner is not cluster
                creator_user_id=user.id,
                owner_user_id=user.id,
                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.",
                ))
    assert "violates check constraint" in str(e.value)
    assert "main_page_owned_by_cluster" in str(e.value)

    # can only have one main page
    with pytest.raises(IntegrityError) as e:
        with session_scope() as session:
            main_page1 = Page(
                parent_node_id=cluster_parent_id,
                creator_user_id=user.id,
                owner_cluster_id=cluster_id,
                type=PageType.main_page,
                thread=Thread(),
            )
            session.add(main_page1)
            session.add(
                PageVersion(
                    page=main_page1,
                    editor_user_id=user.id,
                    title=f"Main page 1 for the testing community",
                    content="Empty.",
                ))
            main_page2 = Page(
                parent_node_id=cluster_parent_id,
                creator_user_id=user.id,
                owner_cluster_id=cluster_id,
                type=PageType.main_page,
                thread=Thread(),
            )
            session.add(main_page2)
            session.add(
                PageVersion(
                    page=main_page2,
                    editor_user_id=user.id,
                    title=f"Main page 2 for the testing community",
                    content="Empty.",
                ))
    assert "violates unique constraint" in str(e.value)
    assert "ix_pages_owner_cluster_id_type" in str(e.value)
Example #11
0
def test_page_transfer(db):
    # transfers the pages
    user1, token1 = generate_user()
    # admin of the community/group
    user2, token2 = generate_user()
    # member of the community/group, shouldn't ever have edit access to anything
    user3, token3 = generate_user()
    with session_scope() as session:
        # create a community
        node = Node(geom=to_multi(
            create_polygon_lat_lng([[0, 0], [0, 2], [2, 2], [2, 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=user2.id,
            owner_cluster=community_cluster,
            type=PageType.main_page,
            thread=Thread(),
        )
        session.add(main_page)
        session.add(
            PageVersion(
                page=main_page,
                editor_user_id=user2.id,
                title=f"Main page for the testing community",
                content="Empty.",
            ))
        community_cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=user2.id,
                role=ClusterRole.admin,
            ))
        community_cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=user3.id,
                role=ClusterRole.member,
            ))

        # 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=user2.id,
            owner_cluster=group_cluster,
            type=PageType.main_page,
            thread=Thread(),
        )
        session.add(main_page)
        session.add(
            PageVersion(
                page=main_page,
                editor_user_id=user2.id,
                title=f"Main page for the testing community",
                content="Empty.",
            ))
        group_cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=user2.id,
                role=ClusterRole.admin,
            ))
        group_cluster.cluster_subscriptions.append(
            ClusterSubscription(
                user_id=user3.id,
                role=ClusterRole.member,
            ))
        session.flush()

        community_id = node.id
        community_cluster_id = community_cluster.id
        group_id = group_cluster.id

    with pages_session(token1) as api:
        create_page_req = pages_pb2.CreatePlaceReq(
            title="title",
            content="content",
            address="address",
            location=pages_pb2.Coordinate(
                lat=1,
                lng=1,
            ),
        )

        # transfer should work fine to a community
        page1 = api.CreatePlace(create_page_req)
        assert page1.owner_user_id == user1.id
        assert page1.can_edit
        assert not page1.can_moderate

    with pages_session(token2) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token1) as api:
        page1 = api.TransferPage(
            pages_pb2.TransferPageReq(
                page_id=page1.page_id,
                new_owner_community_id=community_id,
            ))
        assert page1.owner_community_id == community_id
        assert not page1.can_edit
        assert not page1.can_moderate

    with pages_session(token2) as api:
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token1) as api:
        # now we're no longer the owner, can't transfer
        page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id))
        with pytest.raises(grpc.RpcError) as e:
            api.TransferPage(
                pages_pb2.TransferPageReq(
                    page_id=page1.page_id,
                    new_owner_group_id=group_id,
                ))
        assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
        assert e.value.details() == errors.PAGE_TRANSFER_PERMISSION_DENIED
        page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id))
        assert page1.owner_community_id == community_id
        assert not page1.can_edit
        assert not page1.can_moderate

    with pages_session(token2) as api:
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate

    with pages_session(token1) as api:
        # try a new page, just for fun
        page2 = api.CreatePlace(create_page_req)
        assert page2.owner_user_id == user1.id

        page2 = api.TransferPage(
            pages_pb2.TransferPageReq(
                page_id=page2.page_id,
                new_owner_community_id=community_id,
            ))
        assert page2.owner_community_id == community_id

    with pages_session(token2) as api:
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate

    with pages_session(token1) as api:
        # can't transfer a page to an official cluster, only through community
        page3 = api.CreatePlace(create_page_req)
        assert page3.owner_user_id == user1.id

        with pytest.raises(grpc.RpcError) as e:
            api.TransferPage(
                pages_pb2.TransferPageReq(
                    page_id=page3.page_id,
                    new_owner_community_id=community_cluster_id,
                ))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.GROUP_OR_COMMUNITY_NOT_FOUND
        page3 = api.GetPage(pages_pb2.GetPageReq(page_id=page3.page_id))
        assert page3.owner_user_id == user1.id

        # can transfer to group
        page4 = api.CreatePlace(create_page_req)
        assert page4.owner_user_id == user1.id
        assert page4.can_edit
        assert not page4.can_moderate

    with pages_session(token2) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate

    with pages_session(token1) as api:
        page4 = api.TransferPage(
            pages_pb2.TransferPageReq(
                page_id=page4.page_id,
                new_owner_group_id=group_id,
            ))
        assert page4.owner_group_id == group_id
        assert not page4.can_edit
        assert not page4.can_moderate

    with pages_session(token2) as api:
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
        assert api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate

    with pages_session(token3) as api:
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
        assert not api.GetPage(
            pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate

    with pages_session(token1) as api:
        # now we're no longer the owner, can't transfer
        with pytest.raises(grpc.RpcError) as e:
            api.TransferPage(
                pages_pb2.TransferPageReq(
                    page_id=page4.page_id,
                    new_owner_community_id=community_id,
                ))
        assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
        assert e.value.details() == errors.PAGE_TRANSFER_PERMISSION_DENIED
        page4 = api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id))
        assert page4.owner_group_id == group_id
Example #12
0
def add_dummy_communities():
    try:
        logger.info(f"Adding dummy communities")
        with session_scope() as session:
            if session.query(Node).count() > 0:
                logger.info("Nodes not empty, not adding dummy communities")
                return

            with open("src/data/dummy_communities.json", "r") as file:
                data = json.loads(file.read())

            for community in data["communities"]:
                geom = None
                if "coordinates" in community:
                    geom = create_polygon_lng_lat(community["coordinates"])
                elif "osm_id" in community:
                    with open(f"src/data/osm/{community['osm_id']}.geojson"
                              ) as f:
                        geojson = json.loads(f.read())
                    # pick the first feature
                    geom = geojson_to_geom(geojson["features"][0]["geometry"])
                    if "geom_simplify" in community:
                        geom = func.ST_Simplify(geom,
                                                community["geom_simplify"],
                                                True)
                else:
                    ValueError("No geom or osm_id specified for node")

                name = community["name"]

                admins = session.query(User).filter(
                    User.username.in_(community["admins"])).all()
                members = session.query(User).filter(
                    User.username.in_(community["members"])).all()

                parent_name = community["parent"]

                if parent_name:
                    parent_node = (session.query(Node).join(
                        Cluster, Cluster.parent_node_id == Node.id).filter(
                            Cluster.is_official_cluster).filter(
                                Cluster.name == community["parent"]).one())

                node = Node(
                    geom=to_multi(geom),
                    parent_node=parent_node if parent_name else None,
                )

                session.add(node)

                cluster = Cluster(
                    name=f"{name}",
                    description=f"Description for {name}",
                    parent_node=node,
                    is_official_cluster=True,
                )

                session.add(cluster)

                main_page = Page(
                    parent_node=node,
                    creator_user=admins[0],
                    owner_cluster=cluster,
                    type=PageType.main_page,
                    thread=Thread(),
                )

                session.add(main_page)

                page_version = PageVersion(
                    page=main_page,
                    editor_user=admins[0],
                    title=f"Main page for the {name} community",
                    content="There is nothing here yet...",
                )

                session.add(page_version)

                for admin in admins:
                    cluster.cluster_subscriptions.append(
                        ClusterSubscription(
                            user=admin,
                            role=ClusterRole.admin,
                        ))

                for member in members:
                    cluster.cluster_subscriptions.append(
                        ClusterSubscription(
                            user=member,
                            role=ClusterRole.member,
                        ))

            for group in data["groups"]:
                name = group["name"]

                admins = session.query(User).filter(
                    User.username.in_(group["admins"])).all()
                members = session.query(User).filter(
                    User.username.in_(group["members"])).all()

                parent_node = (session.query(Node).join(
                    Cluster, Cluster.parent_node_id == Node.id).filter(
                        Cluster.is_official_cluster).filter(
                            Cluster.name == group["parent"]).one())

                cluster = Cluster(
                    name=f"{name}",
                    description=f"Description for the group {name}",
                    parent_node=parent_node,
                )

                session.add(cluster)

                main_page = Page(
                    parent_node=cluster.parent_node,
                    creator_user=admins[0],
                    owner_cluster=cluster,
                    type=PageType.main_page,
                    thread=Thread(),
                )

                session.add(main_page)

                page_version = PageVersion(
                    page=main_page,
                    editor_user=admins[0],
                    title=f"Main page for the {name} group",
                    content="There is nothing here yet...",
                )

                session.add(page_version)

                for admin in admins:
                    cluster.cluster_subscriptions.append(
                        ClusterSubscription(
                            user=admin,
                            role=ClusterRole.admin,
                        ))

                for member in members:
                    cluster.cluster_subscriptions.append(
                        ClusterSubscription(
                            user=member,
                            role=ClusterRole.member,
                        ))

            for place in data["places"]:
                owner_cluster = session.query(Cluster).filter(
                    Cluster.name == place["owner"]).one()
                creator = session.query(User).filter(
                    User.username == place["creator"]).one()

                page = Page(
                    parent_node=owner_cluster.parent_node,
                    creator_user=creator,
                    owner_cluster=owner_cluster,
                    type=PageType.place,
                    thread=Thread(),
                )

                session.add(page)

                page_version = PageVersion(
                    page=page,
                    editor_user=creator,
                    title=place["title"],
                    content=place["content"],
                    address=place["address"],
                    geom=create_coordinate(place["coordinate"][1],
                                           place["coordinate"][0]),
                )

                session.add(page_version)

            for guide in data["guides"]:
                owner_cluster = session.query(Cluster).filter(
                    Cluster.name == guide["owner"]).one()
                creator = session.query(User).filter(
                    User.username == guide["creator"]).one()

                page = Page(
                    parent_node=owner_cluster.parent_node,
                    creator_user=creator,
                    owner_cluster=owner_cluster,
                    type=PageType.guide,
                    thread=Thread(),
                )

                session.add(page)

                page_version = PageVersion(
                    page=page,
                    editor_user=creator,
                    title=guide["title"],
                    content=guide["content"],
                    geom=create_coordinate(guide["coordinate"][1],
                                           guide["coordinate"][0])
                    if "coordinate" in guide else None,
                )

                session.add(page_version)

    except IntegrityError:
        logger.error(
            "Failed to insert dummy communities, are they already inserted?")
Example #13
0
def test_threads_basic(db):
    user1, token1 = generate_user()

    # Create a dummy Thread (should be replaced by pages later on)
    with session_scope() as session:
        dummy_thread = Thread()
        session.add(dummy_thread)
        session.flush()
        PARENT_THREAD_ID = pack_thread_id(database_id=dummy_thread.id, depth=0)

    with threads_session(token1) as api:
        bat_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="bat")).thread_id

        cat_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="cat")).thread_id

        dog_id = api.PostReply(
            threads_pb2.PostReplyReq(thread_id=PARENT_THREAD_ID,
                                     content="dog")).thread_id

        dogs = [
            api.PostReply(
                threads_pb2.PostReplyReq(thread_id=dog_id,
                                         content=animal)).thread_id
            for animal in ["hyena", "wolf", "prariewolf"]
        ]
        cats = [
            api.PostReply(
                threads_pb2.PostReplyReq(thread_id=cat_id,
                                         content=animal)).thread_id
            for animal in ["cheetah", "lynx", "panther"]
        ]

        # Make some queries
        ret = api.GetThread(
            threads_pb2.GetThreadReq(thread_id=PARENT_THREAD_ID))
        assert len(ret.replies) == 3
        assert ret.next_page_token == ""
        assert ret.replies[0].thread_id == dog_id
        assert ret.replies[0].content == "dog"
        assert ret.replies[0].author_user_id == user1.id
        assert ret.replies[0].num_replies == 3

        assert ret.replies[1].thread_id == cat_id
        assert ret.replies[1].content == "cat"
        assert ret.replies[1].author_user_id == user1.id
        assert ret.replies[1].num_replies == 3

        assert ret.replies[2].thread_id == bat_id
        assert ret.replies[2].content == "bat"
        assert ret.replies[2].author_user_id == user1.id
        assert ret.replies[2].num_replies == 0

        ret = api.GetThread(threads_pb2.GetThreadReq(thread_id=cat_id))
        assert len(ret.replies) == 3
        assert ret.next_page_token == ""
        assert [reply.thread_id for reply in ret.replies] == cats[::-1]

        ret = api.GetThread(threads_pb2.GetThreadReq(thread_id=dog_id))
        assert len(ret.replies) == 3
        assert ret.next_page_token == ""
        assert [reply.thread_id for reply in ret.replies] == dogs[::-1]
Example #14
0
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