Ejemplo n.º 1
0
async def test_user_can_delete_own_comment(app: FastAPI,
                                           authorized_client: AsyncClient,
                                           test_article: Article) -> None:
    created_comment_response = await authorized_client.post(
        app.url_path_for("comments:create-comment-for-article",
                         slug=test_article.slug),
        json={"comment": {
            "body": "comment"
        }},
    )

    created_comment = CommentInResponse(**created_comment_response.json())

    await authorized_client.delete(
        app.url_path_for(
            "comments:delete-comment-from-article",
            slug=test_article.slug,
            comment_id=str(created_comment.comment.id_),
        ))

    comments_for_article_response = await authorized_client.get(
        app.url_path_for("comments:get-comments-for-article",
                         slug=test_article.slug))

    comments = ListOfCommentsInResponse(**comments_for_article_response.json())

    assert len(comments.comments) == 0
Ejemplo n.º 2
0
async def test_user_can_change_following_for_another_user(
    app: FastAPI,
    authorized_client: AsyncClient,
    pool: Pool,
    test_user: UserInDB,
    api_method: str,
    route_name: str,
    following: bool,
) -> None:
    async with pool.acquire() as conn:
        users_repo = UsersRepository(conn)
        user = await users_repo.create_user(
            username="******",
            email="*****@*****.**",
            password="******",
        )

        if not following:
            profiles_repo = ProfilesRepository(conn)
            await profiles_repo.add_user_into_followers(
                target_user=user, requested_user=test_user)

    change_following_response = await authorized_client.request(
        api_method, app.url_path_for(route_name, username=user.username))
    assert change_following_response.status_code == status.HTTP_200_OK

    response = await authorized_client.get(
        app.url_path_for("profiles:get-profile", username=user.username))
    profile = ProfileInResponse(**response.json())
    assert profile.profile.username == user.username
    assert profile.profile.following == following
Ejemplo n.º 3
0
async def test_user_can_change_favorite_state(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_article: Article,
    test_user: UserInDB,
    pool: Pool,
    api_method: str,
    route_name: str,
    favorite_state: bool,
) -> None:
    if not favorite_state:
        async with pool.acquire() as connection:
            articles_repo = ArticlesRepository(connection)
            await articles_repo.add_article_into_favorites(
                article=test_article, user=test_user)

    await authorized_client.request(
        api_method, app.url_path_for(route_name, slug=test_article.slug))

    response = await authorized_client.get(
        app.url_path_for("articles:get-article", slug=test_article.slug))

    article = ArticleInResponse(**response.json())

    assert article.article.favorited == favorite_state
    assert article.article.favorites_count == int(favorite_state)
Ejemplo n.º 4
0
def setup_frontend_services(app: FastAPI):
    """
    Setup entrypoint for this app module.

    Used in core.application.init_app
    """
    def _on_startup() -> None:
        def is_included(key) -> bool:
            return (
                app.state.settings.CATALOG_DEV_FEATURES_ENABLED
                # FIXME: STILL UNDER DEVELOPMENT
                #  - Parameter services
                #  - Iterator
                #  - Iterator consumer
                or not is_parameter_service(key) or
                not is_frontend_service(key) or not is_iterator_service(key) or
                not is_iterator_consumer_service(key))

        catalog = [
            _as_dict(metadata) for metadata in iter_service_docker_data()
            if is_included(metadata.key)
        ]
        app.state.frontend_services_catalog = catalog

    app.add_event_handler("startup", _on_startup)
Ejemplo n.º 5
0
def setup_mongo(app: FastAPI):
    """
    Создаем инстанс Монги
    """
    # app.client = ma.AsyncIOMotorClient(MONGO_HOST)
    app.mongo = {}

    for db in app.config['databases']:
        client = ma.AsyncIOMotorClient(db['address'])
        app.mongo[db['name']] = {}

        for collection in db['collections']:
            index_fields = collection.get('index_fields')
            if index_fields:
                if len(list(set(collection['index_fields']) - set(collection['fields']))) > 0:
                    raise WrongCollectionFormat('"index_fields" got an extra fields not included in "fields"')

            db_instance = client[db['name']]
            collection_instance = db_instance[collection['name']]

            app.mongo[db['name']][collection['name']] = MongoInstance(
                BaseModel(db_instance, collection_instance),
                collection['fields'],
                index_fields,
            )
Ejemplo n.º 6
0
async def test_filtering_with_limit_and_offset(app: FastAPI,
                                               authorized_client: AsyncClient,
                                               test_user: UserInDB,
                                               pool: Pool) -> None:
    async with pool.acquire() as connection:
        articles_repo = ArticlesRepository(connection)

        for i in range(5, 10):
            await articles_repo.create_article(
                slug=f"slug-{i}",
                title="tmp",
                description="tmp",
                body="tmp",
                author=test_user,
            )

    full_response = await authorized_client.get(
        app.url_path_for("articles:list-articles"))
    full_articles = ListOfArticlesInResponse(**full_response.json())

    response = await authorized_client.get(
        app.url_path_for("articles:list-articles"),
        params={
            "limit": 2,
            "offset": 3
        })

    articles_from_response = ListOfArticlesInResponse(**response.json())
    assert full_articles.articles[3:] == articles_from_response.articles
Ejemplo n.º 7
0
def setup_mongo(app: FastAPI):
    app.client = ma.AsyncIOMotorClient(MONGO_HOST)
    app.db = app.client[MONGO_DB_NAME]

    app.mongo = {
        'beer': Beer(app.db),
        'wine': Wine(app.db),
        'vodka': Vodka(app.db)
    }
Ejemplo n.º 8
0
def setup_fastAPI(fh, nginx_x_accel_redirect_base=None, apache_xsendfile=None):
    def wsgi_application(env, start_response):
        trans = Bunch(
            response=Response(),
            app=Bunch(config=Bunch(
                nginx_x_accel_redirect_base=nginx_x_accel_redirect_base,
                apache_xsendfile=apache_xsendfile)))
        trans.response.headers['content-length'] = len(CONTENT)
        trans.response.set_content_type('application/octet-stream')
        return send_file(start_response, trans, fh)

    app = FastAPI()
    app.mount('/test/send_file', WSGIMiddleware(wsgi_application))
    return app
Ejemplo n.º 9
0
async def test_empty_feed_if_user_has_not_followings(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_article: Article,
    test_user: UserInDB,
    pool: Pool,
) -> None:
    async with pool.acquire() as connection:
        users_repo = UsersRepository(connection)
        articles_repo = ArticlesRepository(connection)

        for i in range(5):
            user = await users_repo.create_user(username=f"user-{i}",
                                                email=f"user-{i}@email.com",
                                                password="******")
            for j in range(5):
                await articles_repo.create_article(
                    slug=f"slug-{i}-{j}",
                    title="tmp",
                    description="tmp",
                    body="tmp",
                    author=user,
                    tags=[f"tag-{i}-{j}"],
                )

    response = await authorized_client.get(
        app.url_path_for("articles:get-user-feed-articles"))

    articles = ListOfArticlesInResponse(**response.json())
    assert articles.articles == []
Ejemplo n.º 10
0
def _create_instance(settings: Settings) -> FastAPI:
    return FastAPI(
        debug=settings.WEB_APP_DEBUG,
        title=settings.WEB_APP_TITLE,
        description=settings.WEB_APP_DESCRIPTION,
        version=settings.WEB_APP_VERSION,
    )
Ejemplo n.º 11
0
async def test_user_can_not_modify_article_that_is_not_authored_by_him(
    app: FastAPI,
    authorized_client: AsyncClient,
    pool: Pool,
    api_method: str,
    route_name: str,
) -> None:
    async with pool.acquire() as connection:
        users_repo = UsersRepository(connection)
        user = await users_repo.create_user(username="******",
                                            email="*****@*****.**",
                                            password="******")
        articles_repo = ArticlesRepository(connection)
        await articles_repo.create_article(
            slug="test-slug",
            title="Test Slug",
            description="Slug for tests",
            body="Test " * 100,
            author=user,
            tags=["tests", "testing", "pytest"],
        )

    response = await authorized_client.request(
        api_method,
        app.url_path_for(route_name, slug="test-slug"),
        json={"article": {
            "title": "Updated Title"
        }},
    )
    assert response.status_code == status.HTTP_403_FORBIDDEN
Ejemplo n.º 12
0
async def test_unregistered_user_will_receive_profile_without_following(
        app: FastAPI, client: AsyncClient, test_user: UserInDB) -> None:
    response = await client.get(
        app.url_path_for("profiles:get-profile", username=test_user.username))
    profile = ProfileInResponse(**response.json())
    assert profile.profile.username == test_user.username
    assert not profile.profile.following
Ejemplo n.º 13
0
async def test_user_can_not_change_following_state_to_the_same_twice(
    app: FastAPI,
    authorized_client: AsyncClient,
    pool: Pool,
    test_user: UserInDB,
    api_method: str,
    route_name: str,
    following: bool,
) -> None:
    async with pool.acquire() as conn:
        users_repo = UsersRepository(conn)
        user = await users_repo.create_user(
            username="******",
            email="*****@*****.**",
            password="******",
        )

        if following:
            profiles_repo = ProfilesRepository(conn)
            await profiles_repo.add_user_into_followers(
                target_user=user, requested_user=test_user)

    response = await authorized_client.request(
        api_method, app.url_path_for(route_name, username=user.username))

    assert response.status_code == status.HTTP_400_BAD_REQUEST
Ejemplo n.º 14
0
async def test_article_will_contain_only_attached_tags(
        app: FastAPI, authorized_client: AsyncClient, test_user: UserInDB,
        pool: Pool) -> None:
    attached_tags = ["tag1", "tag3"]

    async with pool.acquire() as connection:
        articles_repo = ArticlesRepository(connection)

        await articles_repo.create_article(
            slug=f"test-slug",
            title="tmp",
            description="tmp",
            body="tmp",
            author=test_user,
            tags=attached_tags,
        )

        for i in range(5):
            await articles_repo.create_article(
                slug=f"slug-{i}",
                title="tmp",
                description="tmp",
                body="tmp",
                author=test_user,
                tags=[f"tag-{i}"],
            )

    response = await authorized_client.get(
        app.url_path_for("articles:get-article", slug="test-slug"))
    article = ArticleInResponse(**response.json())
    assert len(article.article.tags) == len(attached_tags)
    assert set(article.article.tags) == set(attached_tags)
Ejemplo n.º 15
0
async def test_user_successful_login(
    app: FastAPI, client: AsyncClient, test_user: UserInDB
) -> None:
    login_json = {"user": {"email": "*****@*****.**", "password": "******"}}

    response = await client.post(app.url_path_for("auth:login"), json=login_json)
    assert response.status_code == HTTP_200_OK
Ejemplo n.º 16
0
async def test_user_can_update_article(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_article: Article,
    update_field: str,
    update_value: str,
    extra_updates: dict,
) -> None:  # type: ignore
    response = await authorized_client.put(
        app.url_path_for("articles:update-article", slug=test_article.slug),
        json={"article": {
            update_field: update_value
        }},
    )

    assert response.status_code == status.HTTP_200_OK

    article = ArticleInResponse(**response.json()).article
    article_as_dict = article.dict()
    assert article_as_dict[update_field] == update_value

    for extra_field, extra_value in extra_updates.items():
        assert article_as_dict[extra_field] == extra_value

    exclude_fields = {update_field, *extra_updates.keys(), "updated_at"}
    assert article.dict(exclude=exclude_fields) == test_article.dict(
        exclude=exclude_fields)
Ejemplo n.º 17
0
async def test_user_can_retrieve_article_if_exists(
        app: FastAPI, authorized_client: AsyncClient,
        test_article: Article) -> None:
    response = await authorized_client.get(
        app.url_path_for("articles:get-article", slug=test_article.slug))
    article = ArticleInResponse(**response.json())
    assert article.article == test_article
Ejemplo n.º 18
0
def override_fastapi_openapi_method(app: FastAPI):
    # pylint: disable=protected-access
    app._original_openapi = types.MethodType(copy_func(app.openapi),
                                             app)  # type: ignore

    def _custom_openapi_method(self: FastAPI) -> Dict:
        """Overrides FastAPI.openapi member function
        returns OAS schema with vendor extensions
        """
        # NOTE: see fastapi.applications.py:FastApi.openapi(self) implementation
        if not self.openapi_schema:
            self.openapi_schema = self._original_openapi()  # type: ignore
            _patch_openapi_specs(self.openapi_schema)

        return self.openapi_schema

    app.openapi = types.MethodType(_custom_openapi_method, app)
Ejemplo n.º 19
0
async def test_unable_to_login_with_wrong_jwt_prefix(app: FastAPI,
                                                     client: AsyncClient,
                                                     token: str) -> None:
    response = await client.get(
        app.url_path_for("users:get-current-user"),
        headers={"Authorization": f"WrongPrefix {token}"},
    )
    assert response.status_code == HTTP_403_FORBIDDEN
Ejemplo n.º 20
0
async def test_unable_to_login_when_user_does_not_exist_any_more(
        app: FastAPI, client: AsyncClient, authorization_prefix: str) -> None:
    token = create_access_token_for_user(
        User(username="******", email="*****@*****.**"), "secret")
    response = await client.get(
        app.url_path_for("users:get-current-user"),
        headers={"Authorization": f"{authorization_prefix} {token}"},
    )
    assert response.status_code == HTTP_403_FORBIDDEN
Ejemplo n.º 21
0
async def test_user_receiving_feed_with_limit_and_offset(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_article: Article,
    test_user: UserInDB,
    pool: Pool,
) -> None:
    async with pool.acquire() as connection:
        users_repo = UsersRepository(connection)
        profiles_repo = ProfilesRepository(connection)
        articles_repo = ArticlesRepository(connection)

        for i in range(5):
            user = await users_repo.create_user(username=f"user-{i}",
                                                email=f"user-{i}@email.com",
                                                password="******")
            if i == 2:
                await profiles_repo.add_user_into_followers(
                    target_user=user, requested_user=test_user)

            for j in range(5):
                await articles_repo.create_article(
                    slug=f"slug-{i}-{j}",
                    title="tmp",
                    description="tmp",
                    body="tmp",
                    author=user,
                    tags=[f"tag-{i}-{j}"],
                )

    full_response = await authorized_client.get(
        app.url_path_for("articles:get-user-feed-articles"))
    full_articles = ListOfArticlesInResponse(**full_response.json())

    response = await authorized_client.get(
        app.url_path_for("articles:get-user-feed-articles"),
        params={
            "limit": 2,
            "offset": 3
        },
    )

    articles_from_response = ListOfArticlesInResponse(**response.json())
    assert full_articles.articles[3:] == articles_from_response.articles
Ejemplo n.º 22
0
async def test_user_can_not_retrieve_not_existing_article(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_article: Article,
    api_method: str,
    route_name: str,
) -> None:
    response = await authorized_client.request(
        api_method, app.url_path_for(route_name, slug="wrong-slug"))
    assert response.status_code == status.HTTP_404_NOT_FOUND
Ejemplo n.º 23
0
def setup_app(app: FastAPI):

    BASEDIR = os.path.dirname(os.path.realpath(__file__))
    PHOTO_PATH = os.path.join(BASEDIR, 'photo/')

    app.photo_path = {
        'beer': os.path.join(PHOTO_PATH, 'beer'),
        'wine': os.path.join(PHOTO_PATH, 'wine'),
        'vodka': os.path.join(PHOTO_PATH, 'vodka'),
    }
Ejemplo n.º 24
0
async def test_user_will_receive_error_for_not_existing_comment(
        app: FastAPI, authorized_client: AsyncClient,
        test_article: Article) -> None:
    not_found_response = await authorized_client.delete(
        app.url_path_for(
            "comments:delete-comment-from-article",
            slug=test_article.slug,
            comment_id="1",
        ))

    assert not_found_response.status_code == status.HTTP_404_NOT_FOUND
Ejemplo n.º 25
0
async def test_user_can_not_change_following_state_for_him_self(
    app: FastAPI,
    authorized_client: AsyncClient,
    test_user: UserInDB,
    api_method: str,
    route_name: str,
) -> None:
    response = await authorized_client.request(
        api_method, app.url_path_for(route_name, username=test_user.username))

    assert response.status_code == status.HTTP_400_BAD_REQUEST
Ejemplo n.º 26
0
async def test_user_login_when_credential_part_does_not_match(
    app: FastAPI,
    client: AsyncClient,
    test_user: UserInDB,
    credentials_part: str,
    credentials_value: str,
) -> None:
    login_json = {"user": {"email": "*****@*****.**", "password": "******"}}
    login_json["user"][credentials_part] = credentials_value
    response = await client.post(app.url_path_for("auth:login"), json=login_json)
    assert response.status_code == HTTP_400_BAD_REQUEST
Ejemplo n.º 27
0
async def test_user_can_add_comment_for_article(app: FastAPI,
                                                authorized_client: AsyncClient,
                                                test_article: Article) -> None:
    created_comment_response = await authorized_client.post(
        app.url_path_for("comments:create-comment-for-article",
                         slug=test_article.slug),
        json={"comment": {
            "body": "comment"
        }},
    )

    created_comment = CommentInResponse(**created_comment_response.json())

    comments_for_article_response = await authorized_client.get(
        app.url_path_for("comments:get-comments-for-article",
                         slug=test_article.slug))

    comments = ListOfCommentsInResponse(**comments_for_article_response.json())

    assert created_comment.comment == comments.comments[0]
Ejemplo n.º 28
0
async def test_user_can_not_create_article_with_duplicated_slug(
        app: FastAPI, authorized_client: AsyncClient,
        test_article: Article) -> None:
    article_data = {
        "title": "Test Slug",
        "body": "does not matter",
        "description": "¯\\_(ツ)_/¯",
    }
    response = await authorized_client.post(
        app.url_path_for("articles:create-article"),
        json={"article": article_data})
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Ejemplo n.º 29
0
def create_dynamic_router(schema: Schema, app: FastAPI, old_slug: str = None):
    router = APIRouter()

    route_get_entities(router=router, schema=schema)
    route_get_entity(router=router, schema=schema)
    route_create_entity(router=router, schema=schema)
    route_update_entity(router=router, schema=schema)
    route_delete_entity(router=router, schema=schema)

    router_routes = [(r.path, r.methods) for r in router.routes]
    routes_to_remove = []
    for route in app.routes:
        if (route.path, route.methods) in router_routes:
            routes_to_remove.append(route)
        elif old_slug and (route.path.startswith(f'/entity/{old_slug}/')
                           or route.path == f'/entity/{old_slug}'):
            routes_to_remove.append(route)
    for route in routes_to_remove:
        app.routes.remove(route)

    app.include_router(router, prefix='/entity')
    app.openapi_schema = None
Ejemplo n.º 30
0
async def test_list_of_tags_when_tags_exist(
    app: FastAPI, client: AsyncClient, pool: Pool
) -> None:
    tags = ["tag1", "tag2", "tag3", "tag4", "tag1"]

    async with pool.acquire() as conn:
        tags_repo = TagsRepository(conn)
        await tags_repo.create_tags_that_dont_exist(tags=tags)

    response = await client.get(app.url_path_for("tags:get-all"))
    tags_from_response = response.json()["tags"]
    assert len(tags_from_response) == len(set(tags))
    assert all((tag in tags for tag in tags_from_response))