docker tests finished ok

develop
Сергей Ванюшкин 2024-01-29 22:22:36 +03:00
parent c27858e4fb
commit bde9581090
5 changed files with 56 additions and 9 deletions

View File

@ -89,6 +89,14 @@ Fastapi веб приложение реализующее api для общеп
Перейдите в каталог Перейдите в каталог
> `$ cd fastfood` > `$ cd fastfood`
Создадим файл .env из шаблона
>`$ cp ./example.env ./.env`
Для теста изменять файл .env не требуется.
Однако Вы можете изменить имя пользователя, пароль и имя базы данных по своему усмотрению. При таких изменениях, нужно будет отредактировать
файл `db_prepare.sql` в папке `scripts/`, так чтобы sql команда приняла вид:
`CREATE DATABASE <db_name>_test WITH OWNER <db_user>;`
где <db_name> и <db_user> соответвтовали POSTGRES_DB и POSTGRES_USER в файле `.env`
Создайте и запустите образы Создайте и запустите образы
> `$ docker-compose up -d --build` > `$ docker-compose up -d --build`
@ -116,7 +124,7 @@ Fastapi веб приложение реализующее api для общеп
Файл example.env является образцом файла .env, который необходимо создать перед запуском проекта. Файл example.env является образцом файла .env, который необходимо создать перед запуском проекта.
В нем указанны переменные необходимые для подключения к БД. В нем указанны переменные необходимые для подключения к БД.
Созданим файл .env Создадим файл .env
>`$ cp ./example.env ./.env` >`$ cp ./example.env ./.env`
@ -145,6 +153,7 @@ Fastapi веб приложение реализующее api для общеп
## TODO ## TODO
- Написать тесты для кривых данных
- Добавить миграции - Добавить миграции
- Провести рефакторинг, много дублирующего кода - Провести рефакторинг, много дублирующего кода
- Много чего другого :) - Много чего другого :)

View File

@ -11,7 +11,9 @@ class SubMenuCrud:
@staticmethod @staticmethod
async def get_submenus(menu_id: UUID, session: AsyncSession): async def get_submenus(menu_id: UUID, session: AsyncSession):
async with session: 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) submenus = await session.execute(query)
return submenus return submenus
@ -25,8 +27,8 @@ class SubMenuCrud:
new_submenu = models.SubMenu(**submenu.model_dump()) new_submenu = models.SubMenu(**submenu.model_dump())
new_submenu.parent_menu = menu_id new_submenu.parent_menu = menu_id
session.add(new_submenu) session.add(new_submenu)
await session.flush()
await session.commit() await session.commit()
await session.refresh(new_submenu)
return new_submenu return new_submenu
@staticmethod @staticmethod
@ -71,6 +73,8 @@ class SubMenuCrud:
@staticmethod @staticmethod
async def delete_submenu_item(submenu_id: UUID, session: AsyncSession): async def delete_submenu_item(submenu_id: UUID, session: AsyncSession):
async with session: 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.execute(query)
await session.commit() await session.commit()

View File

@ -1,2 +1,5 @@
#!/bin/bash #!/bin/bash
#
# Тут можно выполнить миграции или дополнительные перед запуском приложения
#
poetry run python manage.py --run-test-server poetry run python manage.py --run-test-server

View File

@ -42,7 +42,7 @@ async def db_init():
async with async_engine.begin() as conn: async with async_engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all) await conn.run_sync(Base.metadata.drop_all)
async def get_test_session() -> AsyncGenerator[AsyncSession, None]: async def get_test_session() -> AsyncGenerator[AsyncSession, None]:
async with async_session_maker() as session: async with async_session_maker() as session:
yield session yield session

View File

@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from fastfood.cruds.menu import MenuCrud from fastfood.cruds.menu import MenuCrud
from fastfood.cruds.submenu import SubMenuCrud 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 Menu as menuschema
from fastfood.schemas import MenuBase as menubaseschema from fastfood.schemas import MenuBase as menubaseschema
@ -13,28 +13,32 @@ from fastfood.schemas import MenuBase as menubaseschema
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_menu(asession: AsyncSession) -> None: async def test_menu(asession: AsyncSession) -> None:
async with asession: async with asession:
# Создаем меню
menu: Menu = Menu(title="SomeMenu", description="SomeDescription") menu: Menu = Menu(title="SomeMenu", description="SomeDescription")
menu: Menu = await MenuCrud.create_menu_item( menu: Menu = await MenuCrud.create_menu_item(
menubaseschema.model_validate(menu), menubaseschema.model_validate(menu),
asession, asession,
) )
menu_id: UUID = menu.id menu_id: UUID = menu.id
# Получаем его же
req_menu: Menu | None = await MenuCrud.get_menu_item(menu_id, asession) req_menu: Menu | None = await MenuCrud.get_menu_item(menu_id, asession)
assert menu == req_menu assert menu == req_menu
# Получаем все меню и проверяем
req_menus = await MenuCrud.get_menus(asession) req_menus = await MenuCrud.get_menus(asession)
assert menu == req_menus.scalars().all()[0] assert menu == req_menus.scalars().all()[0]
# Обновляем
menu.title = "updatedMenu" menu.title = "updatedMenu"
await MenuCrud.update_menu_item( await MenuCrud.update_menu_item(
menu.id, menuschema.model_validate(menu), asession menu.id, menuschema.model_validate(menu), asession
) )
# И сверяем
req_menu = await MenuCrud.get_menu_item(menu_id, asession) req_menu = await MenuCrud.get_menu_item(menu_id, asession)
assert menu == req_menu assert menu == req_menu
# Удаляем и проверяем
await MenuCrud.delete_menu_item(menu_id, asession) await MenuCrud.delete_menu_item(menu_id, asession)
req_menus = await MenuCrud.get_menus(asession) req_menus = await MenuCrud.get_menus(asession)
assert req_menus.all() == [] assert req_menus.all() == []
@ -50,7 +54,7 @@ async def test_submenu(asession: AsyncSession) -> None:
await asession.refresh(menu) await asession.refresh(menu)
menu_id: UUID = menu.id menu_id: UUID = menu.id
# Создаем подменю через ручку # Создаем подменю
submenu: SubMenu = SubMenu( submenu: SubMenu = SubMenu(
title="submenu", title="submenu",
description="", description="",
@ -61,9 +65,36 @@ async def test_submenu(asession: AsyncSession) -> None:
menubaseschema.model_validate(submenu), menubaseschema.model_validate(submenu),
asession, 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 @pytest.mark.asyncio
async def test_dish(asession: AsyncSession): async def test_dish(asession: AsyncSession):
"""Not Implemented yet"""
async with asession: async with asession:
pass pass