예제 #1
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
예제 #2
0
def test_node_constraints(db):
    # check we can't have two official clusters for a given node
    with pytest.raises(IntegrityError) as e:
        with session_scope() as session:
            node = Node(geom=to_multi(create_1d_polygon(0, 2)))
            session.add(node)
            cluster1 = Cluster(
                name=f"Testing community, cluster 1",
                description=f"Testing community description",
                parent_node=node,
                is_official_cluster=True,
            )
            session.add(cluster1)
            cluster2 = Cluster(
                name=f"Testing community, cluster 2",
                description=f"Testing community description",
                parent_node=node,
                is_official_cluster=True,
            )
            session.add(cluster2)
    assert "violates unique constraint" in str(e.value)
    assert "ix_clusters_owner_parent_node_id_is_official_cluster" in str(
        e.value)
예제 #3
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)
예제 #4
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
예제 #5
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?")
예제 #6
0
def create_node(session, geom, parent_node_id):
    node = Node(geom=from_shape(geom), parent_node_id=parent_node_id)
    session.add(node)
    session.flush()
    return node
예제 #7
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