diff --git a/aciniformes_backend/routes/alert.py b/aciniformes_backend/routes/alert.py deleted file mode 100644 index 77cda16..0000000 --- a/aciniformes_backend/routes/alert.py +++ /dev/null @@ -1,96 +0,0 @@ -from __future__ import annotations - -import logging - -from auth_lib.fastapi import UnionAuth -from fastapi import APIRouter, Depends -from fastapi.exceptions import HTTPException -from pydantic import BaseModel -from starlette import status - -from aciniformes_backend.serivce import AlertServiceInterface, alert_service -from aciniformes_backend.serivce import exceptions as exc - - -logger = logging.getLogger(__name__) - - -class CreateSchema(BaseModel): - data: dict[str, str | list | dict | bool | int | float] - filter: str - - -class PostResponseSchema(CreateSchema): - id: int | None = None - - -class UpdateSchema(BaseModel): - data: dict[str, str | list | dict] | None = None - filter: str | None = None - - -class GetSchema(BaseModel): - id: int - - -router = APIRouter() - - -@router.post("") -async def create( - create_schema: CreateSchema, - alert: AlertServiceInterface = Depends(alert_service), - _: dict[str] = Depends(UnionAuth(['pinger.alert.create'])), -) -> PostResponseSchema: - """Создание уведомления.""" - id_ = await alert.create(create_schema.model_dump(exclude_unset=True)) - return PostResponseSchema(**create_schema.model_dump(), id=id_) - - -@router.get("") -async def get_all( - alert: AlertServiceInterface = Depends(alert_service), - _: dict[str] = Depends(UnionAuth(['pinger.alert.read'])), -): - """Возвращает все уведомления.""" - res = await alert.get_all() - return res - - -@router.get("/{id}") -async def get( - id: int, - alert: AlertServiceInterface = Depends(alert_service), - _: dict[str] = Depends(UnionAuth(['pinger.alert.read'])), -): - """Возвращает одно уведомление.""" - try: - res = await alert.get_by_id(id) - except exc.ObjectNotFound: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) - return res - - -@router.patch("/{id}") -async def update( - id: int, - update_schema: UpdateSchema, - alert: AlertServiceInterface = Depends(alert_service), - _: dict[str] = Depends(UnionAuth(['pinger.alert.update'])), -): - """Обновление уведомления по id.""" - try: - res = await alert.update(id, update_schema.model_dump(exclude_unset=True)) - except exc.ObjectNotFound: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) - return res - - -@router.delete("/{id}") -async def delete( - id: int, - alert: AlertServiceInterface = Depends(alert_service), - _: dict[str] = Depends(UnionAuth(['pinger.alert.delete'])), -): - """Удаление уведомления по id.""" - await alert.delete(id) diff --git a/aciniformes_backend/routes/base.py b/aciniformes_backend/routes/base.py index 394025c..8fda466 100644 --- a/aciniformes_backend/routes/base.py +++ b/aciniformes_backend/routes/base.py @@ -5,7 +5,6 @@ from aciniformes_backend import __version__ from aciniformes_backend.settings import get_settings -from .alert import router as alert_router from .fetcher import router as fetcher_router from .mectric import router as metric_router from .receiver import router as receiver_router @@ -34,7 +33,6 @@ allow_headers=settings.CORS_ALLOW_HEADERS, ) -app.include_router(alert_router, prefix="/alert", tags=["Alert"]) app.include_router(receiver_router, prefix="/receiver", tags=["Receiver"]) app.include_router(fetcher_router, prefix="/fetcher", tags=["Fetcher"]) app.include_router(metric_router, prefix="/metric", tags=["Metric"]) diff --git a/aciniformes_backend/serivce/exceptions.py b/aciniformes_backend/routes/exceptions.py similarity index 100% rename from aciniformes_backend/serivce/exceptions.py rename to aciniformes_backend/routes/exceptions.py diff --git a/aciniformes_backend/routes/fetcher.py b/aciniformes_backend/routes/fetcher.py index c0fa904..5a7d372 100644 --- a/aciniformes_backend/routes/fetcher.py +++ b/aciniformes_backend/routes/fetcher.py @@ -1,17 +1,18 @@ import logging +import sqlalchemy as sa from auth_lib.fastapi import UnionAuth from fastapi import APIRouter, Depends from fastapi.exceptions import HTTPException +from fastapi_sqlalchemy import db from pydantic import BaseModel, HttpUrl from pydantic.functional_serializers import PlainSerializer from starlette import status from typing_extensions import Annotated +import aciniformes_backend.models as db_models from aciniformes_backend.models.fetcher import FetcherType -from aciniformes_backend.serivce import FetcherServiceInterface -from aciniformes_backend.serivce import exceptions as exc -from aciniformes_backend.serivce import fetcher_service +from aciniformes_backend.routes import exceptions as exc logger = logging.getLogger(__name__) @@ -43,64 +44,75 @@ class GetSchema(BaseModel): @router.post("", response_model=ResponsePostSchema) -async def create( +def create( create_schema: CreateSchema, - fetcher: FetcherServiceInterface = Depends(fetcher_service), _: dict[str] = Depends(UnionAuth(['pinger.fetcher.create'])), ): """ Создает новый сборщик метрик. """ - id_ = await fetcher.create(create_schema.model_dump()) - return ResponsePostSchema(**create_schema.model_dump(), id=id_) + q = sa.insert(db_models.Fetcher).values(**create_schema.model_dump()).returning(db_models.Fetcher) + fetcher = db.session.scalar(q) + db.session.flush() + return ResponsePostSchema(**create_schema.model_dump(), id=fetcher.id_) @router.get("") -async def get_all( - fetcher: FetcherServiceInterface = Depends(fetcher_service), +def get_all( _: dict[str] = Depends(UnionAuth(['pinger.fetcher.read'])), ): """ Возвращает все сборщики метрик. """ - res = await fetcher.get_all() - return res + return list(db.session.scalars(sa.select(db_models.Fetcher)).all()) @router.get("/{id}") -async def get( +def get( id: int, - fetcher: FetcherServiceInterface = Depends(fetcher_service), _: dict[str] = Depends(UnionAuth(['pinger.fetcher.read'])), ): """Получение одного сборщика метрик по id""" try: - res = await fetcher.get_by_id(id) + q = sa.select(db_models.Fetcher).where(db_models.Fetcher.id_ == id) + res = db.session.scalar(q) + if not res: + raise exc.ObjectNotFound(id) + return res except exc.ObjectNotFound: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) - return res @router.patch("/{id}") -async def update( +def update( id: int, update_schema: UpdateSchema, - fetcher: FetcherServiceInterface = Depends(fetcher_service), _: dict[str] = Depends(UnionAuth(['pinger.fetcher.update'])), ): """Обновление одного сборщика метрик по id""" try: - res = await fetcher.update(id, update_schema.model_dump(exclude_unset=True)) + q = sa.select(db_models.Fetcher).where(db_models.Fetcher.id_ == id) + res = db.session.scalar(q) + if not res: + raise exc.ObjectNotFound(id) + q = ( + sa.update(db_models.Fetcher) + .where(db_models.Fetcher.id_ == id) + .values(**update_schema) + .returning(db_models.Fetcher) + ) + res = db.session.execute(q).scalar() except exc.ObjectNotFound: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) return res @router.delete("/{id}") -async def delete( +def delete( id: int, - fetcher: FetcherServiceInterface = Depends(fetcher_service), _: dict[str] = Depends(UnionAuth(['pinger.fetcher.delete'])), ): """Удаление одного сборщика метрик по id""" - await fetcher.delete(id) + q = sa.delete(db_models.Fetcher).where(db_models.Fetcher.id_ == id) + db.session.execute(q) + db.session.flush() diff --git a/aciniformes_backend/routes/mectric.py b/aciniformes_backend/routes/mectric.py index 6469981..b856fd5 100644 --- a/aciniformes_backend/routes/mectric.py +++ b/aciniformes_backend/routes/mectric.py @@ -1,12 +1,13 @@ +import sqlalchemy as sa from auth_lib.fastapi import UnionAuth from fastapi import APIRouter, Depends from fastapi.exceptions import HTTPException +from fastapi_sqlalchemy import db from pydantic import BaseModel from starlette import status -from aciniformes_backend.serivce import MetricServiceInterface -from aciniformes_backend.serivce import exceptions as exc -from aciniformes_backend.serivce import metric_service +import aciniformes_backend.models as db_models +from aciniformes_backend.routes import exceptions as exc class CreateSchema(BaseModel): @@ -30,35 +31,36 @@ class GetSchema(BaseModel): @router.post("", response_model=ResponsePostSchema) -async def create( +def create( metric_schema: CreateSchema, - metric: MetricServiceInterface = Depends(metric_service), _: dict[str] = Depends(UnionAuth(['pinger.metric.create'])), ): """Создание метрики.""" - id_ = await metric.create(metric_schema.model_dump()) - return ResponsePostSchema(**metric_schema.model_dump(), id=id_) + q = sa.insert(db_models.Metric).values(**metric_schema.model_dump()).returning(db_models.Metric) + metric = db.session.scalar(q) + db.session.flush() + return ResponsePostSchema(**metric_schema.model_dump(), id=metric.id_) @router.get("") -async def get_all( - metric: MetricServiceInterface = Depends(metric_service), +def get_all( _: dict[str] = Depends(UnionAuth(['pinger.metric.read'])), ): """Получение всех метрик.""" - res = await metric.get_all() - return res + return list(db.session.scalars(sa.select(db_models.Metric)).all()) @router.get("/{id}") -async def get( +def get( id: int, - metric: MetricServiceInterface = Depends(metric_service), _: dict[str] = Depends(UnionAuth(['pinger.metric.read'])), ): """Получение одной метрики по id.""" try: - res = await metric.get_by_id(id) + q = sa.select(db_models.Metric).where(db_models.Metric.id_ == id) + res = db.session.scalar(q) + if not res: + raise exc.ObjectNotFound(id) + return res except exc.ObjectNotFound: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) - return res diff --git a/aciniformes_backend/routes/receiver.py b/aciniformes_backend/routes/receiver.py index 5c08821..699b8af 100644 --- a/aciniformes_backend/routes/receiver.py +++ b/aciniformes_backend/routes/receiver.py @@ -1,15 +1,16 @@ import logging from enum import Enum +import sqlalchemy as sa from auth_lib.fastapi import UnionAuth from fastapi import APIRouter, Depends from fastapi.exceptions import HTTPException +from fastapi_sqlalchemy import db from pydantic import BaseModel from starlette import status -from aciniformes_backend.serivce import ReceiverServiceInterface -from aciniformes_backend.serivce import exceptions as exc -from aciniformes_backend.serivce import receiver_service +import aciniformes_backend.models as db_models +from aciniformes_backend.routes import exceptions as exc logger = logging.getLogger(__name__) @@ -48,60 +49,70 @@ class GetSchema(BaseModel): @router.post("", response_model=PostResponseSchema) -async def create( +def create( create_schema: CreateSchema, - receiver: ReceiverServiceInterface = Depends(receiver_service), _: dict[str] = Depends(UnionAuth(['pinger.receiver.create'])), ): """Создание получателя уведомлений.""" - id_ = await receiver.create(create_schema.model_dump()) - return PostResponseSchema(**create_schema.model_dump(), id=id_) + q = sa.insert(db_models.Receiver).values(**create_schema.model_dump()).returning(db_models.Receiver) + receiver = db.session.execute(q).scalar() + db.session.flush() + return PostResponseSchema(**create_schema.model_dump(), id=receiver.id_) @router.get("") -async def get_all( - receiver: ReceiverServiceInterface = Depends(receiver_service), +def get_all( _: dict[str] = Depends(UnionAuth(['pinger.receiver.read'])), ): """Получить всех получателей уведомлений.""" - res = await receiver.get_all() - return res + return list(db.session.scalars(sa.select(db_models.Receiver)).all()) @router.get("/{id}") -async def get( +def get( id: int, - receiver: ReceiverServiceInterface = Depends(receiver_service), _: dict[str] = Depends(UnionAuth(['pinger.receiver.read'])), ): """Получение получателя уведомлений.""" try: - res = await receiver.get_by_id(id) - return res + q = sa.select(db_models.Receiver).where(db_models.Receiver.id_ == id) + res = db.session.scalar(q) + if not res: + raise exc.ObjectNotFound(id) except exc.ObjectNotFound: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) @router.patch("/{id}") -async def update( +def update( id: int, update_schema: UpdateSchema, - receiver: ReceiverServiceInterface = Depends(receiver_service), _: dict[str] = Depends(UnionAuth(['pinger.receiver.update'])), ): """Обновление получателя уведомлений по id.""" try: - res = await receiver.update(id, update_schema.model_dump(exclude_unset=True)) + q = sa.select(db_models.Receiver).where(db_models.Receiver.id_ == id) + res = db.session.scalar(q) + if not res: + raise exc.ObjectNotFound(id) + q = ( + sa.update(db_models.Receiver) + .where(db_models.Receiver.id_ == id) + .values(**update_schema.model_dump()) + .returning(db_models.Receiver) + ) + res = db.session.execute(q).scalar() except exc.ObjectNotFound: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) return res @router.delete("/{id}") -async def delete( +def delete( id: int, - receiver: ReceiverServiceInterface = Depends(receiver_service), _: dict[str] = Depends(UnionAuth(['pinger.receiver.delete'])), ): """Удаление получателя уведомлений по id.""" - await receiver.delete(id) + q = sa.delete(db_models.Receiver).where(db_models.Receiver.id_ == id) + db.session.execute(q) + db.session.flush() diff --git a/aciniformes_backend/serivce/__init__.py b/aciniformes_backend/serivce/__init__.py deleted file mode 100644 index 547f6a6..0000000 --- a/aciniformes_backend/serivce/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from .base import AlertServiceInterface, FetcherServiceInterface, MetricServiceInterface, ReceiverServiceInterface -from .bootstrap import alert_service, fetcher_service, metric_service, receiver_service - - -__all__ = [ - "AlertServiceInterface", - "FetcherServiceInterface", - "MetricServiceInterface", - "ReceiverServiceInterface", - "metric_service", - "receiver_service", - "alert_service", - "fetcher_service", - "exceptions", -] diff --git a/aciniformes_backend/serivce/alert.py b/aciniformes_backend/serivce/alert.py deleted file mode 100644 index e300b5b..0000000 --- a/aciniformes_backend/serivce/alert.py +++ /dev/null @@ -1,36 +0,0 @@ -import sqlalchemy as sa - -import aciniformes_backend.models as db_models -import aciniformes_backend.serivce.exceptions as exc - -from .base import AlertServiceInterface - - -class PgAlertService(AlertServiceInterface): - async def create(self, item: dict) -> int: - q = sa.insert(db_models.Alert).values(**item).returning(db_models.Alert) - alert = self.session.execute(q).scalar() - self.session.flush() - return alert.id_ - - async def get_by_id(self, id_: int) -> db_models.Alert: - q = sa.select(db_models.Alert).where(db_models.Alert.id_ == id_) - res = self.session.execute(q).scalar() - if not res: - raise exc.ObjectNotFound(id_) - return res - - async def delete(self, id_: int) -> None: - q = sa.delete(db_models.Alert).where(db_models.Alert.id_ == id_) - self.session.execute(q) - self.session.flush() - - async def update(self, id_: int, item: dict) -> db_models.Alert: - q = sa.update(db_models.Alert).where(db_models.Alert.id_ == id_).values(**item).returning(db_models.Alert) - if not await self.get_by_id(id_): - raise exc.ObjectNotFound(id_) - res = self.session.execute(q).scalar() - return res - - async def get_all(self) -> list[db_models.BaseModel]: - return list(self.session.scalars(sa.select(db_models.Alert)).all()) diff --git a/aciniformes_backend/serivce/base.py b/aciniformes_backend/serivce/base.py deleted file mode 100644 index b353a27..0000000 --- a/aciniformes_backend/serivce/base.py +++ /dev/null @@ -1,66 +0,0 @@ -from abc import ABCMeta, abstractmethod - -import sqlalchemy.orm - -import aciniformes_backend.models as db_models - - -class BaseService(metaclass=ABCMeta): - def __init__(self, session: sqlalchemy.orm.Session | None): - self.session = session - - @abstractmethod - async def get_all(self) -> list[db_models.BaseModel]: - raise NotImplementedError - - @abstractmethod - async def create(self, item: dict) -> int: - raise NotImplementedError - - -class AlertServiceInterface(BaseService, metaclass=ABCMeta): - @abstractmethod - async def get_by_id(self, id_: int) -> db_models.Alert: - raise NotImplementedError - - @abstractmethod - async def delete(self, id_: int) -> None: - raise NotImplementedError - - @abstractmethod - async def update(self, id_: int, item: dict) -> db_models.Alert: - raise NotImplementedError - - -class ReceiverServiceInterface(BaseService, metaclass=ABCMeta): - @abstractmethod - async def get_by_id(self, id_: int) -> db_models.Receiver: - raise NotImplementedError - - @abstractmethod - async def delete(self, id_: int) -> None: - raise NotImplementedError - - @abstractmethod - async def update(self, id_: int, item: dict) -> db_models.Receiver: - raise NotImplementedError - - -class FetcherServiceInterface(BaseService, metaclass=ABCMeta): - @abstractmethod - async def get_by_id(self, id_: int) -> db_models.Fetcher: - raise NotImplementedError - - @abstractmethod - async def delete(self, id_: int) -> None: - raise NotImplementedError - - @abstractmethod - async def update(self, id_: int, item: dict) -> db_models.Fetcher: - raise NotImplementedError - - -class MetricServiceInterface(BaseService, metaclass=ABCMeta): - @abstractmethod - async def get_by_id(self, id_: int) -> db_models.Metric: - raise NotImplementedError diff --git a/aciniformes_backend/serivce/bootstrap.py b/aciniformes_backend/serivce/bootstrap.py deleted file mode 100644 index 7d1febe..0000000 --- a/aciniformes_backend/serivce/bootstrap.py +++ /dev/null @@ -1,22 +0,0 @@ -from fastapi_sqlalchemy import db - -from .alert import PgAlertService -from .fetcher import PgFetcherService -from .metric import PgMetricService -from .receiver import PgReceiverService - - -def metric_service(): - return PgMetricService(db.session) - - -def alert_service(): - return PgAlertService(db.session) - - -def receiver_service(): - return PgReceiverService(db.session) - - -def fetcher_service(): - return PgFetcherService(db.session) diff --git a/aciniformes_backend/serivce/fetcher.py b/aciniformes_backend/serivce/fetcher.py deleted file mode 100644 index fbb1cf6..0000000 --- a/aciniformes_backend/serivce/fetcher.py +++ /dev/null @@ -1,36 +0,0 @@ -import sqlalchemy as sa - -import aciniformes_backend.models as db_models -import aciniformes_backend.serivce.exceptions as exc - -from .base import FetcherServiceInterface - - -class PgFetcherService(FetcherServiceInterface): - async def create(self, item: dict) -> int: - q = sa.insert(db_models.Fetcher).values(**item).returning(db_models.Fetcher) - fetcher = self.session.scalar(q) - self.session.flush() - return fetcher.id_ - - async def get_by_id(self, id_: int) -> db_models.Fetcher: - q = sa.select(db_models.Fetcher).where(db_models.Fetcher.id_ == id_) - res = self.session.scalar(q) - if not res: - raise exc.ObjectNotFound(id_) - return res - - async def delete(self, id_: int) -> None: - q = sa.delete(db_models.Fetcher).where(db_models.Fetcher.id_ == id_) - self.session.execute(q) - self.session.flush() - - async def update(self, id_: int, item: dict) -> db_models.Fetcher: - q = sa.update(db_models.Fetcher).where(db_models.Fetcher.id_ == id_).values(**item).returning(db_models.Fetcher) - if not await self.get_by_id(id_): - raise exc.ObjectNotFound(id_) - res = self.session.execute(q).scalar() - return res - - async def get_all(self) -> list[db_models.BaseModel]: - return list(self.session.scalars(sa.select(db_models.Fetcher)).all()) diff --git a/aciniformes_backend/serivce/metric.py b/aciniformes_backend/serivce/metric.py deleted file mode 100644 index 95527b8..0000000 --- a/aciniformes_backend/serivce/metric.py +++ /dev/null @@ -1,24 +0,0 @@ -import sqlalchemy as sa - -import aciniformes_backend.models as db_models -import aciniformes_backend.serivce.exceptions as exc - -from .base import MetricServiceInterface - - -class PgMetricService(MetricServiceInterface): - async def create(self, item: dict) -> int: - q = sa.insert(db_models.Metric).values(**item).returning(db_models.Metric) - metric = self.session.scalar(q) - self.session.flush() - return metric.id_ - - async def get_by_id(self, id_: int) -> db_models.Metric: - q = sa.select(db_models.Metric).where(db_models.Metric.id_ == id_) - res = self.session.scalar(q) - if not res: - raise exc.ObjectNotFound(id_) - return res - - async def get_all(self) -> list[db_models.BaseModel]: - return list(self.session.scalars(sa.select(db_models.Metric)).all()) diff --git a/aciniformes_backend/serivce/receiver.py b/aciniformes_backend/serivce/receiver.py deleted file mode 100644 index ac52723..0000000 --- a/aciniformes_backend/serivce/receiver.py +++ /dev/null @@ -1,43 +0,0 @@ -from typing import Type - -import sqlalchemy as sa - -import aciniformes_backend.models as db_models -import aciniformes_backend.serivce.exceptions as exc - -from .base import ReceiverServiceInterface - - -class PgReceiverService(ReceiverServiceInterface): - async def create(self, item: dict) -> int: - q = sa.insert(db_models.Receiver).values(**item).returning(db_models.Receiver) - receiver = self.session.execute(q).scalar() - self.session.flush() - return receiver.id_ - - async def get_by_id(self, id_: int) -> Type[db_models.Receiver]: - q = sa.select(db_models.Receiver).where(db_models.Receiver.id_ == id_) - res = self.session.scalar(q) - if not res: - raise exc.ObjectNotFound(id_) - return res - - async def delete(self, id_: int) -> None: - q = sa.delete(db_models.Receiver).where(db_models.Receiver.id_ == id_) - self.session.execute(q) - self.session.flush() - - async def update(self, id_: int, item: dict) -> Type[db_models.Receiver]: - q = ( - sa.update(db_models.Receiver) - .where(db_models.Receiver.id_ == id_) - .values(**item) - .returning(db_models.Receiver) - ) - if not await self.get_by_id(id_): - raise exc.ObjectNotFound(id_) - res = self.session.execute(q).scalar() - return res - - async def get_all(self) -> list[db_models.BaseModel]: - return list(self.session.scalars(sa.select(db_models.Receiver)).all()) diff --git a/tests/backend/api/test_alert.py b/tests/backend/api/test_alert.py deleted file mode 100644 index ece8224..0000000 --- a/tests/backend/api/test_alert.py +++ /dev/null @@ -1,95 +0,0 @@ -import json - -import pytest -import pytest_asyncio -from starlette import status - -from aciniformes_backend.serivce.alert import PgAlertService -from aciniformes_backend.settings import get_settings - - -settings = get_settings() - - -alert = { - "data": {"type": "string", "name": "string"}, - "filter": "string", -} - - -@pytest_asyncio.fixture -async def this_alert(dbsession): - global alert - _alert = await PgAlertService(dbsession).create(item=alert) - yield _alert - - -@pytest.mark.authenticated("pinger.alert.create") -def test_post_success(crud_client): - body = { - "data": {"type": "string", "name": "string"}, - "filter": "string", - } - res = crud_client.post("/alert", json=body) - res_body = res.json() - assert res.status_code == status.HTTP_200_OK - assert res_body["data"] == body["data"] - assert res_body["filter"] == body["filter"] - - -@pytest.mark.authenticated("pinger.alert.read") -def test_get_by_id_success(crud_client, this_alert): - res = crud_client.get(f"/alert/{this_alert}") - assert res.status_code == status.HTTP_200_OK - res_body = res.json() - assert res_body["data"] == alert["data"] - assert res_body["filter"] == alert["filter"] - - -@pytest.mark.authenticated("pinger.alert.read", "pinger.alert.delete") -def test_delete_by_id_success(crud_client, this_alert): - res = crud_client.delete(f"/alert/{this_alert}") - assert res.status_code == status.HTTP_200_OK - get = crud_client.get(f"/alert/{this_alert}") - assert get.status_code == status.HTTP_404_NOT_FOUND - - -@pytest.mark.authenticated("pinger.alert.read") -def test_get_success(crud_client, this_alert): - res = crud_client.get("/alert") - assert res.status_code == status.HTTP_200_OK - res_body = res.json() - assert len(res_body) - get = crud_client.get(f"/alert/{this_alert}") - assert get.json() in res_body - - -@pytest.mark.authenticated("pinger.alert.read", "pinger.alert.update") -def test_patch_by_id_success(crud_client, this_alert): - body = { - "data": {"type": "string", "name": "string"}, - "filter": "string", - } - res = crud_client.patch(f"/alert/{this_alert}", data=json.dumps(body)) - assert res.status_code == status.HTTP_200_OK - res_body = res.json() - assert res_body["data"] == body["data"] - get = crud_client.get(f"/alert/{this_alert}") - assert get.status_code == status.HTTP_200_OK - assert get.json() == res_body - - -@pytest.mark.authenticated("pinger.alert.read") -def test_get_by_id_not_found(crud_client, this_alert): - res = crud_client.get(f"/alert/{this_alert+2}") - assert res.status_code == status.HTTP_404_NOT_FOUND - - -@pytest.mark.authenticated("pinger.alert.read", "pinger.alert.update") -def test_patch_by_id_not_found(crud_client, this_alert): - body = { - "data": {"type": "string", "name": "string"}, - "filter": "string", - } - res = crud_client.patch(f"/alert/{888}", data=json.dumps(body)) - assert res.status_code == status.HTTP_404_NOT_FOUND diff --git a/tests/backend/api/test_fetcher.py b/tests/backend/api/test_fetcher.py index 07084c3..0ec4d85 100644 --- a/tests/backend/api/test_fetcher.py +++ b/tests/backend/api/test_fetcher.py @@ -3,9 +3,10 @@ import pytest import pytest_asyncio +import sqlalchemy as sa from starlette import status -from aciniformes_backend.serivce.fetcher import PgFetcherService +import aciniformes_backend.models as db_models fetcher = { @@ -19,7 +20,16 @@ @pytest_asyncio.fixture async def this_fetcher(dbsession): - yield await PgFetcherService(dbsession).create(item=fetcher) + global fetcher + q = sa.insert(db_models.Fetcher).values(**fetcher).returning(db_models.Fetcher) + fetcher_db = dbsession.scalar(q) + dbsession.flush() + + yield fetcher_db.id_ + + q = sa.delete(db_models.Fetcher).where(db_models.Fetcher.id_ == id) + dbsession.execute(q) + dbsession.flush() @pytest.mark.authenticated("pinger.fetcher.create") @@ -39,6 +49,7 @@ def test_post_success(crud_client): @pytest.mark.authenticated("pinger.fetcher.read") def test_get_by_id_success(crud_client, this_fetcher): + global fetcher res = crud_client.get(f"/fetcher/{this_fetcher}") assert res.status_code == status.HTTP_200_OK _new_fetcher = deepcopy(fetcher) diff --git a/tests/backend/api/test_metric.py b/tests/backend/api/test_metric.py index f47d9d1..39ffd03 100644 --- a/tests/backend/api/test_metric.py +++ b/tests/backend/api/test_metric.py @@ -1,8 +1,9 @@ import pytest import pytest_asyncio +import sqlalchemy as sa from starlette import status -from aciniformes_backend.serivce.metric import PgMetricService +import aciniformes_backend.models as db_models metric = {"name": "string", "ok": True, "time_delta": 0} @@ -10,7 +11,16 @@ @pytest_asyncio.fixture async def this_metric(dbsession): - yield await PgMetricService(dbsession).create(item=metric) + global metric + q = sa.insert(db_models.Metric).values(**metric).returning(db_models.Metric) + metric_db = dbsession.scalar(q) + dbsession.flush() + + yield metric_db.id_ + + q = sa.delete(db_models.Metric).where(db_models.Metric.id_ == id) + dbsession.execute(q) + dbsession.flush() @pytest.mark.authenticated("pinger.metric.create") @@ -27,6 +37,7 @@ def test_post_success(crud_client): @pytest.mark.authenticated("pinger.metric.read") def test_get_by_id_success(crud_client, this_metric): + global metric res = crud_client.get(f"/metric/{this_metric}") assert res.status_code == status.HTTP_200_OK for k, v in metric.items(): diff --git a/tests/backend/api/test_reciever.py b/tests/backend/api/test_reciever.py index 28efc39..ce4aab3 100644 --- a/tests/backend/api/test_reciever.py +++ b/tests/backend/api/test_reciever.py @@ -2,9 +2,11 @@ import pytest import pytest_asyncio +import sqlalchemy as sa +from fastapi_sqlalchemy import db from starlette import status -from aciniformes_backend.serivce.receiver import PgReceiverService +import aciniformes_backend.models as db_models receiver = {"url": "https://google.com", "method": "post", "receiver_body": {}} @@ -13,8 +15,15 @@ @pytest_asyncio.fixture async def this_receiver(dbsession): global receiver - _receiver = await PgReceiverService(dbsession).create(item=receiver) - yield _receiver + q = sa.insert(db_models.Receiver).values(**receiver).returning(db_models.Receiver) + receiver_db = dbsession.execute(q).scalar() + dbsession.flush() + + yield receiver_db.id_ + + q = sa.delete(db_models.Receiver).where(db_models.Receiver.id_ == id) + dbsession.execute(q) + dbsession.flush() @pytest.mark.authenticated("pinger.receiver.create") @@ -29,6 +38,7 @@ def test_post_success(crud_client): @pytest.mark.authenticated("pinger.receiver.read") def test_get_by_id_success(crud_client, this_receiver): + global receiver res = crud_client.get(f"/receiver/{this_receiver}") assert res.status_code == status.HTTP_200_OK res_body = res.json() diff --git a/tests/backend/service/__init__.py b/tests/backend/service/__init__.py deleted file mode 100644 index 1ca2d6c..0000000 --- a/tests/backend/service/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# real service impl, only service methods testing diff --git a/tests/backend/service/test_alert_serivce.py b/tests/backend/service/test_alert_serivce.py deleted file mode 100644 index 4bd28a7..0000000 --- a/tests/backend/service/test_alert_serivce.py +++ /dev/null @@ -1,119 +0,0 @@ -import pytest -import sqlalchemy - -import aciniformes_backend.serivce.exceptions as exc -from aciniformes_backend.models import Alert, Receiver -from aciniformes_backend.routes.alert import CreateSchema as AlertCreateSchema -from aciniformes_backend.routes.receiver import CreateSchema as ReceiverCreateSchema -from aciniformes_backend.serivce.alert import PgAlertService -from aciniformes_backend.serivce.receiver import PgReceiverService - - -@pytest.fixture -def receiver_schema(): - body = {"url": "https://google.com", "method": "post", "receiver_body": {}} - schema = ReceiverCreateSchema(**body) - return schema - - -@pytest.fixture -def db_receiver(dbsession, receiver_schema): - q = sqlalchemy.insert(Receiver).values(**receiver_schema.model_dump(exclude_unset=True)).returning(Receiver) - receiver = dbsession.execute(q).scalar() - dbsession.flush() - yield receiver - if dbsession.get(Receiver, receiver.id_): - dbsession.delete(receiver) - dbsession.flush() - - -@pytest.fixture -def alert_schema(receiver_schema): - body = { - "data": {"type": "string", "name": "string"}, - "filter": "string", - } - schema = AlertCreateSchema(**body) - return schema - - -@pytest.fixture -def db_alert(db_receiver, dbsession, alert_schema): - q = sqlalchemy.insert(Alert).values(**alert_schema.model_dump(exclude_unset=True)).returning(Alert) - alert = dbsession.execute(q).scalar() - dbsession.flush() - yield alert - if dbsession.get(Alert, alert.id_): - dbsession.delete(alert) - dbsession.flush() - - -class TestReceiverService: - @pytest.mark.asyncio - async def test_create(self, receiver_schema, dbsession): - res = await PgReceiverService(dbsession).create(item=receiver_schema.model_dump()) - assert res is not None - assert type(res) == int - q = dbsession.query(Receiver).filter(Receiver.id_ == res).one_or_none() - assert q is not None - - @pytest.mark.asyncio - async def test_get_all(self, db_receiver, dbsession): - res = await PgReceiverService(dbsession).get_all() - assert len(res) - assert type(res) is list - assert type(res[0]) is Receiver - - @pytest.mark.asyncio - async def test_get_by_id(self, db_receiver, dbsession): - res = await PgReceiverService(dbsession).get_by_id(db_receiver.id_) - assert res is not None - assert res.url == db_receiver.url - with pytest.raises(exc.ObjectNotFound): - await PgReceiverService(dbsession).get_by_id(db_receiver.id_ + 1000) - - @pytest.mark.asyncio - async def test_delete(self, db_receiver, dbsession): - await PgReceiverService(dbsession).delete(db_receiver.id_) - - @pytest.mark.asyncio - async def test_update(self, db_receiver, dbsession): - res = await PgReceiverService(dbsession).update( - db_receiver.id_, {"url": "Alex", "method": "post", "receiver_body": {}} - ) - assert res.url == "Alex" - assert res.receiver_body == {} - - -class TestAlertService: - @pytest.mark.asyncio - async def test_create(self, alert_schema, db_receiver, dbsession): - res = await PgAlertService(dbsession).create( - alert_schema.model_dump(exclude_unset=True), - ) - assert type(res) == int - - @pytest.mark.asyncio - async def test_get_all(self, db_alert, dbsession): - res = await PgAlertService(dbsession).get_all() - assert len(res) - assert type(res) is list - assert type(res[0]) is Alert - - @pytest.mark.asyncio - async def test_get_by_id(self, dbsession, db_alert): - res = await PgAlertService(dbsession).get_by_id(db_alert.id_) - assert res is not None - assert res.data == db_alert.data - assert res.filter == db_alert.filter - with pytest.raises(exc.ObjectNotFound): - await PgAlertService(dbsession).get_by_id(db_alert.id_ + 1000) - - @pytest.mark.asyncio - async def test_delete(self, dbsession, db_alert): - await PgAlertService(dbsession).delete(db_alert.id_) - - @pytest.mark.asyncio - async def test_update(self, dbsession, db_alert): - res = await PgAlertService(dbsession).update(db_alert.id_, {"data": {"type": "stig", "name": "stig"}}) - assert res.data == {"type": "stig", "name": "stig"} diff --git a/tests/backend/service/test_fetcher_service.py b/tests/backend/service/test_fetcher_service.py deleted file mode 100644 index 0d968b4..0000000 --- a/tests/backend/service/test_fetcher_service.py +++ /dev/null @@ -1,62 +0,0 @@ -import pytest -import sqlalchemy - -from aciniformes_backend.models import Fetcher -from aciniformes_backend.routes.fetcher import CreateSchema as FetcherCreateSchema -from aciniformes_backend.serivce.fetcher import PgFetcherService - - -@pytest.fixture -def fetcher_schema(): - body = { - "id": 6, - "type_": "ping", - "address": "https://www.python.org", - "fetch_data": "string", - "delay_ok": 30, - "delay_fail": 40, - } - schema = FetcherCreateSchema(**body) - return schema - - -@pytest.fixture() -def db_fetcher(dbsession, fetcher_schema): - q = sqlalchemy.insert(Fetcher).values(**fetcher_schema.model_dump(exclude_unset=True)).returning(Fetcher) - fetcher = dbsession.scalar(q) - dbsession.flush() - yield fetcher - if dbsession.get(Fetcher, fetcher.id_): - dbsession.delete(fetcher) - dbsession.flush() - - -class TestFetcherService: - @pytest.mark.asyncio - async def test_create(self, dbsession, fetcher_schema): - res = await PgFetcherService(dbsession).create(fetcher_schema.model_dump(exclude_unset=True)) - assert res is not None - assert type(res) is int - q = dbsession.scalar(sqlalchemy.select(Fetcher).where(Fetcher.id_ == res)) - assert q is not None - - @pytest.mark.asyncio - async def test_get_all(self, dbsession, db_fetcher): - res = await PgFetcherService(dbsession).get_all() - assert type(res) is list - assert type(res[0]) is Fetcher - - @pytest.mark.asyncio - async def test_get_by_id(self, dbsession, db_fetcher): - res = await PgFetcherService(dbsession).get_by_id(db_fetcher.id_) - assert res.address == db_fetcher.address - assert res.type_ == db_fetcher.type_ - - @pytest.mark.asyncio - async def test_delete(self, dbsession, db_fetcher): - await PgFetcherService(dbsession).delete(db_fetcher.id_) - - @pytest.mark.asyncio - async def test_update(self, dbsession, db_fetcher): - res = await PgFetcherService(dbsession).update(db_fetcher.id_, {"type_": "post"}) - assert res.type_ == "post" diff --git a/tests/backend/service/test_metric_service.py b/tests/backend/service/test_metric_service.py deleted file mode 100644 index c9a37ee..0000000 --- a/tests/backend/service/test_metric_service.py +++ /dev/null @@ -1,46 +0,0 @@ -import pytest -import sqlalchemy - -from aciniformes_backend.models import Metric -from aciniformes_backend.routes.mectric import CreateSchema as MetricCreateSchema -from aciniformes_backend.serivce.metric import PgMetricService - - -@pytest.fixture -def metric_schema(): - body = {"id": 44, "name": "string", "ok": True, "time_delta": 0} - schema = MetricCreateSchema(**body) - return schema - - -@pytest.fixture() -def db_metric(dbsession, metric_schema): - q = sqlalchemy.insert(Metric).values(**metric_schema.model_dump(exclude_unset=True)).returning(Metric) - metric = dbsession.scalar(q) - dbsession.flush() - yield metric - if dbsession.get(Metric, metric.id_): - dbsession.delete(metric) - dbsession.flush() - - -class TestMetricService: - @pytest.mark.asyncio - async def test_create(self, metric_schema, dbsession): - res = await PgMetricService(dbsession).create(metric_schema.model_dump(exclude_unset=True)) - assert res is not None - assert type(res) is int - q = dbsession.scalar(sqlalchemy.select(Metric).where(Metric.id_ == res)) - assert q is not None - - @pytest.mark.asyncio - async def test_get_all(self, dbsession): - res = await PgMetricService(dbsession).get_all() - assert type(res) is list - assert type(res[0]) is Metric - - @pytest.mark.asyncio - async def test_get_by_id(self, dbsession, db_metric): - res = await PgMetricService(dbsession).get_by_id(db_metric.id_) - assert res.name == db_metric.name - assert res.ok == db_metric.ok