diff --git a/README.md b/README.md index e327d53..82f5913 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,14 @@ Fastapi веб приложение реализующее api для общеп Перейдите в каталог > `$ cd fastfood` +Создадим файл .env из шаблона +>`$ cp ./example.env ./.env` +Для теста изменять файл .env не требуется. +Однако Вы можете изменить имя пользователя, пароль и имя базы данных по своему усмотрению. При таких изменениях, нужно будет отредактировать +файл `db_prepare.sql` в папке `scripts/`, так чтобы sql команда приняла вид: +`CREATE DATABASE _test WITH OWNER ;` +где и соответвтовали POSTGRES_DB и POSTGRES_USER в файле `.env` + Создайте и запустите образы > `$ docker-compose up -d --build` @@ -116,7 +124,7 @@ Fastapi веб приложение реализующее api для общеп Файл example.env является образцом файла .env, который необходимо создать перед запуском проекта. В нем указанны переменные необходимые для подключения к БД. -Созданим файл .env +Создадим файл .env >`$ cp ./example.env ./.env` @@ -145,6 +153,7 @@ Fastapi веб приложение реализующее api для общеп ## TODO +- Написать тесты для кривых данных - Добавить миграции - Провести рефакторинг, много дублирующего кода - Много чего другого :) diff --git a/fastfood/cruds/submenu.py b/fastfood/cruds/submenu.py index c8ebe47..db562d9 100644 --- a/fastfood/cruds/submenu.py +++ b/fastfood/cruds/submenu.py @@ -11,7 +11,9 @@ class SubMenuCrud: @staticmethod async def get_submenus(menu_id: UUID, session: AsyncSession): async with session: - query = select(models.SubMenu).where(models.SubMenu.parent_menu == menu_id) + query = select(models.SubMenu).where( + models.SubMenu.parent_menu == menu_id, + ) submenus = await session.execute(query) return submenus @@ -25,8 +27,8 @@ class SubMenuCrud: new_submenu = models.SubMenu(**submenu.model_dump()) new_submenu.parent_menu = menu_id session.add(new_submenu) - await session.flush() await session.commit() + await session.refresh(new_submenu) return new_submenu @staticmethod @@ -71,6 +73,8 @@ class SubMenuCrud: @staticmethod async def delete_submenu_item(submenu_id: UUID, session: AsyncSession): async with session: - query = delete(models.SubMenu).where(models.SubMenu.id == submenu_id) + query = delete(models.SubMenu).where( + models.SubMenu.id == submenu_id, + ) await session.execute(query) await session.commit() diff --git a/scripts/migrate_and_run.sh b/scripts/migrate_and_run.sh index 531afac..c882983 100644 --- a/scripts/migrate_and_run.sh +++ b/scripts/migrate_and_run.sh @@ -1,2 +1,5 @@ #!/bin/bash +# +# Тут можно выполнить миграции или дополнительные перед запуском приложения +# poetry run python manage.py --run-test-server diff --git a/tests/conftest.py b/tests/conftest.py index 7605033..2d14188 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -42,7 +42,7 @@ async def db_init(): async with async_engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) - + async def get_test_session() -> AsyncGenerator[AsyncSession, None]: async with async_session_maker() as session: yield session diff --git a/tests/test_crud.py b/tests/test_crud.py index db877f6..60a8f04 100644 --- a/tests/test_crud.py +++ b/tests/test_crud.py @@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from fastfood.cruds.menu import MenuCrud from fastfood.cruds.submenu import SubMenuCrud -from fastfood.models import Dish, Menu, SubMenu +from fastfood.models import Menu, SubMenu from fastfood.schemas import Menu as menuschema from fastfood.schemas import MenuBase as menubaseschema @@ -13,28 +13,32 @@ from fastfood.schemas import MenuBase as menubaseschema @pytest.mark.asyncio async def test_menu(asession: AsyncSession) -> None: async with asession: + # Создаем меню menu: Menu = Menu(title="SomeMenu", description="SomeDescription") - menu: Menu = await MenuCrud.create_menu_item( menubaseschema.model_validate(menu), asession, ) - menu_id: UUID = menu.id + # Получаем его же req_menu: Menu | None = await MenuCrud.get_menu_item(menu_id, asession) assert menu == req_menu + # Получаем все меню и проверяем req_menus = await MenuCrud.get_menus(asession) assert menu == req_menus.scalars().all()[0] + # Обновляем menu.title = "updatedMenu" await MenuCrud.update_menu_item( menu.id, menuschema.model_validate(menu), asession ) + # И сверяем req_menu = await MenuCrud.get_menu_item(menu_id, asession) assert menu == req_menu + # Удаляем и проверяем await MenuCrud.delete_menu_item(menu_id, asession) req_menus = await MenuCrud.get_menus(asession) assert req_menus.all() == [] @@ -50,7 +54,7 @@ async def test_submenu(asession: AsyncSession) -> None: await asession.refresh(menu) menu_id: UUID = menu.id - # Создаем подменю через ручку + # Создаем подменю submenu: SubMenu = SubMenu( title="submenu", description="", @@ -61,9 +65,36 @@ async def test_submenu(asession: AsyncSession) -> None: menubaseschema.model_validate(submenu), asession, ) + submenu_id = submenu.id + + # Проверяем подменю + req_submenu = await SubMenuCrud.get_submenu_item( + menu_id, submenu.id, asession, + ) + assert submenu == req_submenu + + # Обновляем меню + submenu.title = "UpdatedSubmenu" + req_submenu = await SubMenuCrud.update_submenu_item( + submenu_id, menubaseschema.model_validate(submenu), asession, + ) + assert submenu == req_submenu.scalar_one_or_none() + + menu = await MenuCrud.get_menu_item(menu_id, asession) + assert 1 == menu.submenus_count + + # Удаляем полменю + await SubMenuCrud.delete_submenu_item(submenu_id, asession) + + menu = await MenuCrud.get_menu_item(menu_id, asession) + assert 0 == menu.submenus_count + + await MenuCrud.delete_menu_item(menu_id, asession) +@pytest.mark.skip @pytest.mark.asyncio async def test_dish(asession: AsyncSession): + """Not Implemented yet""" async with asession: pass