Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 48 additions & 31 deletions tests/unit/app/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

# pylint: disable=protected-access

from typing import Generator
from pathlib import Path
import tempfile
import pytest
from pytest_mock import MockerFixture
from pytest_mock import MockerFixture, MockType
from sqlalchemy.engine.base import Engine
from sqlalchemy.orm import Session

Expand All @@ -14,7 +15,7 @@


@pytest.fixture(name="reset_database_state")
def reset_database_state_fixture():
def reset_database_state_fixture() -> Generator:
"""Reset global database state before and after tests."""
original_engine = database.engine
original_session_local = database.session_local
Expand All @@ -31,7 +32,7 @@ def reset_database_state_fixture():


@pytest.fixture(name="base_postgres_config")
def base_postgres_config_fixture():
def base_postgres_config_fixture() -> PostgreSQLDatabaseConfiguration:
"""Provide base PostgreSQL configuration for tests."""
return PostgreSQLDatabaseConfiguration(
host="localhost",
Expand All @@ -47,7 +48,7 @@ def base_postgres_config_fixture():
class TestGetEngine:
"""Test cases for get_engine function."""

def test_get_engine_when_initialized(self, mocker: MockerFixture):
def test_get_engine_when_initialized(self, mocker: MockerFixture) -> None:
"""Test get_engine returns engine when initialized."""
mock_engine = mocker.MagicMock(spec=Engine)
database.engine = mock_engine
Expand All @@ -56,7 +57,7 @@ def test_get_engine_when_initialized(self, mocker: MockerFixture):

assert result is mock_engine

def test_get_engine_when_not_initialized(self):
def test_get_engine_when_not_initialized(self) -> None:
"""Test get_engine raises RuntimeError when not initialized."""
database.engine = None

Expand All @@ -68,7 +69,7 @@ def test_get_engine_when_not_initialized(self):
class TestGetSession:
"""Test cases for get_session function."""

def test_get_session_when_initialized(self, mocker: MockerFixture):
def test_get_session_when_initialized(self, mocker: MockerFixture) -> None:
"""Test get_session returns session when initialized."""
mock_session_local = mocker.MagicMock()
mock_session = mocker.MagicMock(spec=Session)
Expand All @@ -80,7 +81,7 @@ def test_get_session_when_initialized(self, mocker: MockerFixture):
assert result is mock_session
mock_session_local.assert_called_once()

def test_get_session_when_not_initialized(self):
def test_get_session_when_not_initialized(self) -> None:
"""Test get_session raises RuntimeError when not initialized."""
database.session_local = None

Expand All @@ -91,7 +92,7 @@ def test_get_session_when_not_initialized(self):
class TestCreateTables:
"""Test cases for create_tables function."""

def test_create_tables_success(self, mocker: MockerFixture):
def test_create_tables_success(self, mocker: MockerFixture) -> None:
"""Test create_tables calls Base.metadata.create_all with engine."""
mock_base = mocker.patch("app.database.Base")
mock_get_engine = mocker.patch("app.database.get_engine")
Expand All @@ -103,7 +104,9 @@ def test_create_tables_success(self, mocker: MockerFixture):
mock_get_engine.assert_called_once()
mock_base.metadata.create_all.assert_called_once_with(mock_engine)

def test_create_tables_when_engine_not_initialized(self, mocker: MockerFixture):
def test_create_tables_when_engine_not_initialized(
self, mocker: MockerFixture
) -> None:
"""Test create_tables raises error when engine not initialized."""
mock_get_engine = mocker.patch("app.database.get_engine")
mock_get_engine.side_effect = RuntimeError("Database engine not initialized")
Expand All @@ -115,7 +118,7 @@ def test_create_tables_when_engine_not_initialized(self, mocker: MockerFixture):
class TestCreateSqliteEngine:
"""Test cases for _create_sqlite_engine function."""

def test_create_sqlite_engine_success(self):
def test_create_sqlite_engine_success(self) -> None:
"""Test _create_sqlite_engine creates engine successfully."""
with tempfile.TemporaryDirectory() as temp_dir:
db_path = Path(temp_dir) / "test.db"
Expand All @@ -126,7 +129,7 @@ def test_create_sqlite_engine_success(self):
assert isinstance(engine, Engine)
assert f"sqlite:///{db_path}" in str(engine.url)

def test_create_sqlite_engine_directory_not_exists(self):
def test_create_sqlite_engine_directory_not_exists(self) -> None:
"""Test _create_sqlite_engine raises error when directory doesn't exist."""
config = SQLiteDatabaseConfiguration(db_path="/nonexistent/path/test.db")

Expand All @@ -135,7 +138,7 @@ def test_create_sqlite_engine_directory_not_exists(self):
):
database._create_sqlite_engine(config)

def test_create_sqlite_engine_creation_failure(self, mocker: MockerFixture):
def test_create_sqlite_engine_creation_failure(self, mocker: MockerFixture) -> None:
"""Test _create_sqlite_engine handles engine creation failure."""
mock_create_engine = mocker.patch("app.database.create_engine")
with tempfile.TemporaryDirectory() as temp_dir:
Expand All @@ -151,8 +154,10 @@ class TestCreatePostgresEngine:
"""Test cases for _create_postgres_engine function."""

def test_create_postgres_engine_success_default_schema(
self, mocker: MockerFixture, base_postgres_config
):
self,
mocker: MockerFixture,
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test _create_postgres_engine creates engine successfully with default schema."""
mock_create_engine = mocker.patch("app.database.create_engine")
mock_engine = mocker.MagicMock(spec=Engine)
Expand All @@ -171,8 +176,10 @@ def test_create_postgres_engine_success_default_schema(
assert expected_url == call_args[0][0]

def test_create_postgres_engine_success_custom_schema(
self, mocker: MockerFixture, base_postgres_config
):
self,
mocker: MockerFixture,
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test _create_postgres_engine creates engine successfully with custom schema."""
mock_create_engine = mocker.patch("app.database.create_engine")
mock_engine = mocker.MagicMock(spec=Engine)
Expand All @@ -193,8 +200,10 @@ def test_create_postgres_engine_success_custom_schema(
mock_connection.commit.assert_called_once()

def test_create_postgres_engine_with_ca_cert(
self, mocker: MockerFixture, base_postgres_config
):
self,
mocker: MockerFixture,
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test _create_postgres_engine with CA certificate path."""
mock_create_engine = mocker.patch("app.database.create_engine")
mock_engine = mocker.MagicMock(spec=Engine)
Expand All @@ -212,8 +221,10 @@ def test_create_postgres_engine_with_ca_cert(
assert call_args[1]["connect_args"]["sslrootcert"] == cert_file.name

def test_create_postgres_engine_creation_failure(
self, mocker: MockerFixture, base_postgres_config
):
self,
mocker: MockerFixture,
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test _create_postgres_engine handles engine creation failure."""
mock_create_engine = mocker.patch("app.database.create_engine")
mock_create_engine.side_effect = Exception("Connection failed")
Expand All @@ -222,8 +233,10 @@ def test_create_postgres_engine_creation_failure(
database._create_postgres_engine(base_postgres_config)

def test_create_postgres_engine_schema_creation_failure(
self, mocker: MockerFixture, base_postgres_config
):
self,
mocker: MockerFixture,
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test _create_postgres_engine handles schema creation failure."""
mock_create_engine = mocker.patch("app.database.create_engine")
mock_engine = mocker.MagicMock(spec=Engine)
Expand All @@ -246,10 +259,10 @@ def _setup_common_mocks(
self,
*,
mocker: MockerFixture,
mock_sessionmaker,
mock_logger,
enable_debug=False,
):
mock_sessionmaker: MockType,
mock_logger: MockType,
enable_debug: bool = False,
) -> tuple[MockType, MockType]:
"""Setup common mocks for initialize_database tests."""
mock_engine = mocker.MagicMock(spec=Engine)
mock_session_local = mocker.MagicMock()
Expand All @@ -258,8 +271,12 @@ def _setup_common_mocks(
return mock_engine, mock_session_local

def _verify_common_assertions(
self, *, mock_sessionmaker, mock_engine, mock_session_local
):
self,
*,
mock_sessionmaker: MockType,
mock_engine: MockType,
mock_session_local: MockType,
) -> None:
"""Verify common assertions for initialize_database tests."""
mock_sessionmaker.assert_called_once_with(
autocommit=False, autoflush=False, bind=mock_engine
Expand All @@ -270,7 +287,7 @@ def _verify_common_assertions(
def test_initialize_database_sqlite(
self,
mocker: MockerFixture,
):
) -> None:
"""Test initialize_database with SQLite configuration."""
# Setup mocks
mock_configuration = mocker.patch("app.database.configuration")
Expand Down Expand Up @@ -304,8 +321,8 @@ def test_initialize_database_sqlite(
def test_initialize_database_postgres(
self,
mocker: MockerFixture,
base_postgres_config,
):
base_postgres_config: PostgreSQLDatabaseConfiguration,
) -> None:
"""Test initialize_database with PostgreSQL configuration."""
# Setup mocks
mock_configuration = mocker.patch("app.database.configuration")
Expand Down
18 changes: 9 additions & 9 deletions tests/unit/app/test_routers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Unit tests for routers.py."""

from typing import Any, Optional
from typing import Any, Optional, Sequence, Callable

from fastapi import FastAPI

Expand Down Expand Up @@ -37,14 +37,14 @@ def include_router( # pylint: disable=too-many-arguments
router: Any,
*,
prefix: str = "",
tags=None,
dependencies=None,
responses=None,
deprecated=None,
include_in_schema=None,
default_response_class=None,
callbacks=None,
generate_unique_id_function=None,
tags: Optional[list] = None,
dependencies: Optional[Sequence] = None,
responses: Optional[dict] = None,
deprecated: Optional[bool] = None,
include_in_schema: Optional[bool] = None,
default_response_class: Optional[Any] = None,
callbacks: Optional[list] = None,
generate_unique_id_function: Optional[Callable] = None,
) -> None:
"""Register new router."""
self.routers.append((router, prefix))
Expand Down
Loading
Loading