From 12a8a0a2ce451fc6f9ae2030bdb8427d3b4cf4d9 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Sat, 27 Jun 2026 23:44:01 +0300 Subject: [PATCH 01/11] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D0=B0=D1=8F=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0=20conftest.py?= =?UTF-8?q?=20=D1=81=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=D0=BC=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=D1=82=D0=B0=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE?= =?UTF-8?q?=20=D1=84=D0=B8=D0=B7=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.dev.txt | 1 + tests/conftest.py | 110 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/requirements.dev.txt b/requirements.dev.txt index c8d847a..e51c72c 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -5,3 +5,4 @@ isort pytest pytest-cov pytest-mock +testcontainers[postgres] diff --git a/tests/conftest.py b/tests/conftest.py index e69de29..cd3a72e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -0,0 +1,110 @@ +# Тут импорты +import pytest +from pytest import MonkeyPatch +from pathlib import Path +from functools import lru_cache +from fastapi.testclient import TestClient +from alembic import command +from alembic.config import Config as AlembicConfig +from testcontainers.postgres import PostgresContainer +from modal_backend.settings import Settings +from sqlalchemy import create_engine +from sqlalchemy.orm import Session + +class PostgresConfig: + """Дата-класс со значениями для контейнера с тестовой БД и для alembic-миграции.""" + container_name: str = "modal-service-api_test" + username: str = "postgres" + host: str = "localhost" + external_port: int = 5432 + image: str = "postgres:15" + host_auth_method: str = "trust" + alembic_ini: str = Path(__file__).resolve().parent.parent / "alembic.ini" + + @classmethod + def get_url(cls) -> str: + """Возвращает URI для подключения к БД.""" + return f"postgresql://{cls.username}@{cls.host}:{cls.external_port}/postgres" + +@pytest.fixture(scope="session") +def session_mp(): + mp = MonkeyPatch() + yield mp + mp.undo() + + +@pytest.fixture(scope="session") +def get_settings_mock(session_mp): + """Переопределение get_settings в modal_backend/settings.py.""" + + @lru_cache + def get_test_settings(): + test_settings = Settings() + test_settings.DB_DSN = PostgresConfig.get_url() + return test_settings + + dsn_mock = session_mp.setattr(name="modal_backend.settings.get_settings", value=get_test_settings) + return dsn_mock + + +@pytest.fixture(scope="session") +def get_app_with_test_settings(get_settings_mock): + """Загрузка app с тестовыми настройками.""" + from modal_backend.routes import app + return app + + +@pytest.fixture(scope="session") +def db_container(get_settings_mock): + """Фикстура настройки БД для тестов в Docker-контейнере.""" + container = ( + PostgresContainer( + image=PostgresConfig.image, username=PostgresConfig.username, dbname=PostgresConfig.container_name + ) + .with_bind_ports(5432, PostgresConfig.external_port) + .with_env("POSTGRES_HOST_AUTH_METHOD", PostgresConfig.ham) + .with_name(PostgresConfig.container_name) + ) + container.start() + cfg = AlembicConfig(str(PostgresConfig.alembic_ini.resolve())) + cfg.set_main_option("script_location", "%(here)s/migrations") + command.upgrade(cfg, "head") + try: + yield PostgresConfig.get_url() + finally: + container.stop() + + +@pytest.fixture(scope="session") +def engine(db_container): + """Фикстура настройки пула соединений к БД""" + engine = create_engine(str(db_container), pool_pre_ping=True) + yield engine + engine.dispose() + + +@pytest.fixture() +def dbsession(engine): + """Фикстура настройки Session для работы с БД в тестах, реализующая паттерн 'Транзакционный откат'""" + #берем соединение из пула + connection = engine.connect() + #начинаем внешнюю транзакцию(на уровне соедниения) + transaction = connection.begin() + #создаём сессю на основе взятого из пула соединения + session = Session(bind=connection) + yield session + #закрываем сессию + session.close() + #откатываем внешнюю транзакцию, все savepoint-ы откатываются, БД чиста + transaction.rollback() + #возвращаем соединение в пул + connection.close() + +@pytest.fixture +def client(mocker, get_app_with_test_settings): + app = get_app_with_test_settings + client = TestClient(app) + return client + + + From 933e8fb467c88ac8fd580ef9adc3cc523a7ff2c2 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Sat, 27 Jun 2026 23:55:16 +0300 Subject: [PATCH 02/11] =?UTF-8?q?=D0=91=D1=8B=D0=BB=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D1=8B=20black=20=D0=B8=20i?= =?UTF-8?q?sort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/conftest.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index cd3a72e..edf0f5e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,23 +1,27 @@ # Тут импорты -import pytest -from pytest import MonkeyPatch -from pathlib import Path from functools import lru_cache -from fastapi.testclient import TestClient +from pathlib import Path + +import pytest from alembic import command from alembic.config import Config as AlembicConfig -from testcontainers.postgres import PostgresContainer -from modal_backend.settings import Settings +from fastapi.testclient import TestClient +from pytest import MonkeyPatch from sqlalchemy import create_engine from sqlalchemy.orm import Session +from testcontainers.postgres import PostgresContainer + +from modal_backend.settings import Settings + class PostgresConfig: """Дата-класс со значениями для контейнера с тестовой БД и для alembic-миграции.""" + container_name: str = "modal-service-api_test" username: str = "postgres" host: str = "localhost" external_port: int = 5432 - image: str = "postgres:15" + image: str = "postgres:15" host_auth_method: str = "trust" alembic_ini: str = Path(__file__).resolve().parent.parent / "alembic.ini" @@ -26,6 +30,7 @@ def get_url(cls) -> str: """Возвращает URI для подключения к БД.""" return f"postgresql://{cls.username}@{cls.host}:{cls.external_port}/postgres" + @pytest.fixture(scope="session") def session_mp(): mp = MonkeyPatch() @@ -42,7 +47,7 @@ def get_test_settings(): test_settings = Settings() test_settings.DB_DSN = PostgresConfig.get_url() return test_settings - + dsn_mock = session_mp.setattr(name="modal_backend.settings.get_settings", value=get_test_settings) return dsn_mock @@ -51,6 +56,7 @@ def get_test_settings(): def get_app_with_test_settings(get_settings_mock): """Загрузка app с тестовыми настройками.""" from modal_backend.routes import app + return app @@ -86,25 +92,23 @@ def engine(db_container): @pytest.fixture() def dbsession(engine): """Фикстура настройки Session для работы с БД в тестах, реализующая паттерн 'Транзакционный откат'""" - #берем соединение из пула + # берем соединение из пула connection = engine.connect() - #начинаем внешнюю транзакцию(на уровне соедниения) + # начинаем внешнюю транзакцию(на уровне соедниения) transaction = connection.begin() - #создаём сессю на основе взятого из пула соединения + # создаём сессю на основе взятого из пула соединения session = Session(bind=connection) yield session - #закрываем сессию + # закрываем сессию session.close() - #откатываем внешнюю транзакцию, все savepoint-ы откатываются, БД чиста + # откатываем внешнюю транзакцию, все savepoint-ы откатываются, БД чиста transaction.rollback() - #возвращаем соединение в пул + # возвращаем соединение в пул connection.close() - + + @pytest.fixture def client(mocker, get_app_with_test_settings): app = get_app_with_test_settings client = TestClient(app) - return client - - - + return client From f37cd298a01c21bb511d854609f16f049320492c Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Wed, 15 Jul 2026 23:21:41 +0300 Subject: [PATCH 03/11] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=BE=20=D1=84=D0=B8=D0=B7=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D1=81=D0=BA=D0=BE=D0=B5=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=BE=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D0=BA=D0=B0=D1=82=D0=B0?= =?UTF-8?q?;=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0?= =?UTF-8?q?=20conftest.py;=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=D1=82=D1=83=D1=80=D0=B0=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20not=5Ftype?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/conftest.py | 97 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 22 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index edf0f5e..d94c9ce 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,3 @@ -# Тут импорты from functools import lru_cache from pathlib import Path @@ -8,19 +7,20 @@ from fastapi.testclient import TestClient from pytest import MonkeyPatch from sqlalchemy import create_engine -from sqlalchemy.orm import Session +from sqlalchemy.orm import sessionmaker from testcontainers.postgres import PostgresContainer +from modal_backend.models.db import NoteType from modal_backend.settings import Settings class PostgresConfig: """Дата-класс со значениями для контейнера с тестовой БД и для alembic-миграции.""" - container_name: str = "modal-service-api_test" + container_name: str = "modal_backend-test" username: str = "postgres" host: str = "localhost" - external_port: int = 5432 + external_port: int = 5433 image: str = "postgres:15" host_auth_method: str = "trust" alembic_ini: str = Path(__file__).resolve().parent.parent / "alembic.ini" @@ -48,7 +48,7 @@ def get_test_settings(): test_settings.DB_DSN = PostgresConfig.get_url() return test_settings - dsn_mock = session_mp.setattr(name="modal_backend.settings.get_settings", value=get_test_settings) + dsn_mock = session_mp.setattr("modal_backend.settings.get_settings", get_test_settings) return dsn_mock @@ -68,11 +68,12 @@ def db_container(get_settings_mock): image=PostgresConfig.image, username=PostgresConfig.username, dbname=PostgresConfig.container_name ) .with_bind_ports(5432, PostgresConfig.external_port) - .with_env("POSTGRES_HOST_AUTH_METHOD", PostgresConfig.ham) + .with_env("POSTGRES_HOST_AUTH_METHOD", PostgresConfig.host_auth_method) .with_name(PostgresConfig.container_name) ) container.start() - cfg = AlembicConfig(str(PostgresConfig.alembic_ini.resolve())) + alembic_ini = PostgresConfig.alembic_ini + cfg = AlembicConfig(str(alembic_ini.resolve())) cfg.set_main_option("script_location", "%(here)s/migrations") command.upgrade(cfg, "head") try: @@ -83,7 +84,7 @@ def db_container(get_settings_mock): @pytest.fixture(scope="session") def engine(db_container): - """Фикстура настройки пула соединений к БД""" + """Фикстура настройки пула соединений к БД.""" engine = create_engine(str(db_container), pool_pre_ping=True) yield engine engine.dispose() @@ -91,24 +92,76 @@ def engine(db_container): @pytest.fixture() def dbsession(engine): - """Фикстура настройки Session для работы с БД в тестах, реализующая паттерн 'Транзакционный откат'""" - # берем соединение из пула - connection = engine.connect() - # начинаем внешнюю транзакцию(на уровне соедниения) - transaction = connection.begin() - # создаём сессю на основе взятого из пула соединения - session = Session(bind=connection) + """Фикстура настройки Session для работы с БД в тестах.""" + TestingLocalSession = sessionmaker(bind=engine) + session = TestingLocalSession() yield session - # закрываем сессию session.close() - # откатываем внешнюю транзакцию, все savepoint-ы откатываются, БД чиста - transaction.rollback() - # возвращаем соединение в пул - connection.close() -@pytest.fixture -def client(mocker, get_app_with_test_settings): +@pytest.fixture() +def authlib_user_data(): + """ + Данные о пользователе, возвращаемые сервисом auth. + """ + return { + "session_scopes": [{"id": 0, "name": "string", "comment": "string"}], + "user_scopes": [{"id": 0, "name": "string", "comment": "string"}], + "indirect_groups": [{"id": 0, "name": "string", "parent_id": 0}], + "groups": [{"id": 0, "name": "string", "parent_id": 0}], + "id": 0, + "email": "string", + "userdata": [ + {"category": "Личная информация", "param": "Полное имя", "value": "Тестовый Тест"}, + ], + } + + +@pytest.fixture() +def authlib_mock(mocker): + auth_mock = mocker.patch("auth_lib.fastapi.UnionAuth.__call__", autospec=True) + return auth_mock + + +@pytest.fixture() +def user_mock(authlib_mock, authlib_user_data): + authlib_mock.return_value = authlib_user_data + return authlib_mock + + +@pytest.fixture() +def client(get_app_with_test_settings, user_mock): app = get_app_with_test_settings client = TestClient(app) return client + + +def create_note_type(name: str, type_id: int, is_deleted: bool = False): + """Вспомогательная функция-мини-фабрика для создания разных типов модалок""" + return NoteType(name=name, type_id=type_id, is_deleted=is_deleted) + + +@pytest.fixture() +def note_types(dbsession): + """Создает три разных типа модалок, один тип помечен на удаление.""" + note_type_data = [ + ( + "Name 1", + 1, + ), + ( + "Name 2", + 2, + ), + ("Name 3", 3, True), + ] + + note_types = [create_note_type(*note_type) for note_type in note_type_data] + + for note_type in note_types: + dbsession.add(note_type) + dbsession.commit() + yield note_types + for note_type in note_types: + dbsession.delete(note_type) + dbsession.commit() From 13c6d3b503aef6114fb4ffcc567dc0e1c1ffbc23 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Wed, 15 Jul 2026 23:29:33 +0300 Subject: [PATCH 04/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20note=5Ftype?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_routes/test_note_type.py | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tests/test_routes/test_note_type.py diff --git a/tests/test_routes/test_note_type.py b/tests/test_routes/test_note_type.py new file mode 100644 index 0000000..11b99f9 --- /dev/null +++ b/tests/test_routes/test_note_type.py @@ -0,0 +1,79 @@ +import pytest +from starlette import status + +from modal_backend.models import NoteType +from modal_backend.schemas.models import NoteTypeGet +from modal_backend.settings import get_settings + +url: str = "/notificationtype" +settings = get_settings() + + +@pytest.mark.parametrize( + "status_code", + [ + (status.HTTP_200_OK), + ], +) +def test_get_notification_type(client, dbsession, note_types, status_code): + response = client.get(url) + assert response.status_code == status_code + + +@pytest.mark.parametrize( + "status_code, body", + [ + ( + status.HTTP_200_OK, + { + "type_id": 4, + "name": "No_exist_type", + }, + ), + ( + status.HTTP_409_CONFLICT, + { + "type_id": 1, + "name": "Already_exist_type", + }, + ), + ( + status.HTTP_422_UNPROCESSABLE_ENTITY, + { + "type_id": -100, + "name": "string", + }, + ), + ( + status.HTTP_422_UNPROCESSABLE_ENTITY, + { + "type_id": 4, + "name": 123, + }, + ), + ( + status.HTTP_422_UNPROCESSABLE_ENTITY, + { + "type_id": "string", + "name": "string", + }, + ), + ( + status.HTTP_409_CONFLICT, + { + "type_id": 3, + "name": "NoteType with is_deleted=True", + }, + ), + ], +) +def test_post_create_notification_type(client, dbsession, note_types, status_code, body): + response = client.post(url, json=body) + assert response.status_code == status_code + + if status_code == status.HTTP_200_OK: + response_model = NoteTypeGet(**response.json()) + exist_note_type = dbsession.query(NoteType).filter(NoteType.type_id == response_model.type_id).one_or_none() + assert exist_note_type + assert exist_note_type.name == body.get("name") + assert exist_note_type.type_id == body.get("type_id") From 6c3cc36cd6970b0523283ba75d52d5a9df5d75ba Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Wed, 15 Jul 2026 23:56:30 +0300 Subject: [PATCH 05/11] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80?= =?UTF-8?q?=20with=5Fdeleted=3DTrue=20=D0=B2=20query=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81,=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=B7=D1=8F=20=D0=B1=D1=8B=D0=BB=D0=BE=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D1=82=D1=8C=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BE=D0=BA=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D1=82=D0=BA=D0=BE=D0=B9=20is=5Fdeleted?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modal_backend/utils/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 82eeeec..8239589 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -51,7 +51,7 @@ class NoteTypeService: async def create_note_type(cls, db: Session, note_type: NoteTypePost) -> NoteType: data = note_type.model_dump() type_id = data.get("type_id") - note_types = NoteType.query(session=db.session).filter(NoteType.type_id == type_id).first() + note_types = NoteType.query(session=db.session, with_deleted=True).filter(NoteType.type_id == type_id).first() if note_types: raise AlreadyExists(NoteType, type_id) new_note_type = NoteType.create(session=db.session, **data) From 19aabcacf14a13cffc0dfed6aedcb32951b68934 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 15:44:36 +0300 Subject: [PATCH 06/11] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=20with=5Fdelet?= =?UTF-8?q?ed=3DTrue=20=D0=B8=D0=B7=20query=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D0=B0=20=D0=BA=20=D0=B1=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modal_backend/utils/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 8239589..82eeeec 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -51,7 +51,7 @@ class NoteTypeService: async def create_note_type(cls, db: Session, note_type: NoteTypePost) -> NoteType: data = note_type.model_dump() type_id = data.get("type_id") - note_types = NoteType.query(session=db.session, with_deleted=True).filter(NoteType.type_id == type_id).first() + note_types = NoteType.query(session=db.session).filter(NoteType.type_id == type_id).first() if note_types: raise AlreadyExists(NoteType, type_id) new_note_type = NoteType.create(session=db.session, **data) From 76fe2fba4287bdbd240033908c04358631067473 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 15:46:05 +0300 Subject: [PATCH 07/11] Cosmetic fix --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index d94c9ce..5ebcfcd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -137,7 +137,7 @@ def client(get_app_with_test_settings, user_mock): def create_note_type(name: str, type_id: int, is_deleted: bool = False): - """Вспомогательная функция-мини-фабрика для создания разных типов модалок""" + """Вспомогательная функция-мини-фабрика для создания разных типов модалок в фикстуре note_types.""" return NoteType(name=name, type_id=type_id, is_deleted=is_deleted) From a697a9435d8dcf5af7ab3cb9fd219d3bd744f209 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 15:48:03 +0300 Subject: [PATCH 08/11] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D1=82=D1=80=D0=B8=D1=86=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20type=5Fid;=20?= =?UTF-8?q?=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B8=20test=5Fget=5Fnotification=5Ftype?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_routes/test_note_type.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/test_routes/test_note_type.py b/tests/test_routes/test_note_type.py index 11b99f9..9553abc 100644 --- a/tests/test_routes/test_note_type.py +++ b/tests/test_routes/test_note_type.py @@ -15,10 +15,14 @@ (status.HTTP_200_OK), ], ) -def test_get_notification_type(client, dbsession, note_types, status_code): +def test_get_notification_type(client, note_types, status_code): response = client.get(url) assert response.status_code == status_code + type_ids_of_note_types = [note_type.type_id for note_type in note_types] + for note_type in response.json(): + assert note_type.get("type_id") in type_ids_of_note_types + @pytest.mark.parametrize( "status_code, body", @@ -37,13 +41,6 @@ def test_get_notification_type(client, dbsession, note_types, status_code): "name": "Already_exist_type", }, ), - ( - status.HTTP_422_UNPROCESSABLE_ENTITY, - { - "type_id": -100, - "name": "string", - }, - ), ( status.HTTP_422_UNPROCESSABLE_ENTITY, { @@ -59,10 +56,10 @@ def test_get_notification_type(client, dbsession, note_types, status_code): }, ), ( - status.HTTP_409_CONFLICT, + status.HTTP_200_OK, { "type_id": 3, - "name": "NoteType with is_deleted=True", + "name": "Successful create NoteType with is_deleted=True", }, ), ], From ad1e879b9c040af43272fc2ea335b8834c8d6227 Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 17:22:37 +0300 Subject: [PATCH 09/11] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BE=D0=BA=20=D1=81=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B2=D1=84=D1=82=20=D0=B4=D0=B5=D0=BB=D0=B8=D1=82=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/conftest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5ebcfcd..c036660 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -136,14 +136,14 @@ def client(get_app_with_test_settings, user_mock): return client -def create_note_type(name: str, type_id: int, is_deleted: bool = False): +def create_note_type(name: str, type_id: int): """Вспомогательная функция-мини-фабрика для создания разных типов модалок в фикстуре note_types.""" - return NoteType(name=name, type_id=type_id, is_deleted=is_deleted) + return NoteType(name=name, type_id=type_id) @pytest.fixture() def note_types(dbsession): - """Создает три разных типа модалок, один тип помечен на удаление.""" + """Создает три разных типа модалок.""" note_type_data = [ ( "Name 1", @@ -153,7 +153,7 @@ def note_types(dbsession): "Name 2", 2, ), - ("Name 3", 3, True), + ("Name 3", 3), ] note_types = [create_note_type(*note_type) for note_type in note_type_data] From cc99942b706b6b4d7282a0b39c9e289e7063758e Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 17:24:03 +0300 Subject: [PATCH 10/11] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=82=D0=B8=D0=BF=D0=BE=D0=B2=20=D0=BC=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=20=D1=81=20=D0=B8=D0=B4=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=BD=D1=8B=D0=BC=D0=B8=20type=5Fid,=20=D0=B3?= =?UTF-8?q?=D0=B4=D0=B5=20=D1=83=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BC=D0=B5=D1=87=D0=B5=D0=BD=20=D1=81=D0=BE=D1=84?= =?UTF-8?q?=D1=82=20=D0=B4=D0=B5=D0=BB=D0=B8=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_routes/test_note_type.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/test_routes/test_note_type.py b/tests/test_routes/test_note_type.py index 9553abc..dc9538e 100644 --- a/tests/test_routes/test_note_type.py +++ b/tests/test_routes/test_note_type.py @@ -18,7 +18,7 @@ def test_get_notification_type(client, note_types, status_code): response = client.get(url) assert response.status_code == status_code - + pytest.set_trace() type_ids_of_note_types = [note_type.type_id for note_type in note_types] for note_type in response.json(): assert note_type.get("type_id") in type_ids_of_note_types @@ -55,13 +55,6 @@ def test_get_notification_type(client, note_types, status_code): "name": "string", }, ), - ( - status.HTTP_200_OK, - { - "type_id": 3, - "name": "Successful create NoteType with is_deleted=True", - }, - ), ], ) def test_post_create_notification_type(client, dbsession, note_types, status_code, body): From 24e29ce37cdabf19e80f728f577d9507348c44ca Mon Sep 17 00:00:00 2001 From: NamazovMaksim Date: Thu, 16 Jul 2026 17:25:26 +0300 Subject: [PATCH 11/11] Cosmetic fix --- tests/test_routes/test_note_type.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_routes/test_note_type.py b/tests/test_routes/test_note_type.py index dc9538e..4420d16 100644 --- a/tests/test_routes/test_note_type.py +++ b/tests/test_routes/test_note_type.py @@ -18,7 +18,6 @@ def test_get_notification_type(client, note_types, status_code): response = client.get(url) assert response.status_code == status_code - pytest.set_trace() type_ids_of_note_types = [note_type.type_id for note_type in note_types] for note_type in response.json(): assert note_type.get("type_id") in type_ids_of_note_types