- Refactored all `password reset` and `auth dependency` tests to utilize async patterns for compatibility with async database sessions. - Enhanced test fixtures with `pytest-asyncio` to support asynchronous database operations. - Improved user handling with async context management for `test_user` and `async_mock_user`. - Introduced `await` syntax for route calls, token generation, and database transactions in test cases.
224 lines
8.5 KiB
Python
Executable File
224 lines
8.5 KiB
Python
Executable File
# tests/test_init_db.py
|
|
import pytest
|
|
from unittest.mock import patch, MagicMock
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.init_db import init_db
|
|
from app.models.user import User
|
|
from app.schemas.users import UserCreate
|
|
|
|
|
|
class TestInitDB:
|
|
"""Tests for database initialization"""
|
|
|
|
def test_init_db_creates_superuser_when_not_exists(self, db_session, monkeypatch):
|
|
"""Test that init_db creates superuser when it doesn't exist"""
|
|
# Set environment variables
|
|
monkeypatch.setenv("FIRST_SUPERUSER_EMAIL", "admin@test.com")
|
|
monkeypatch.setenv("FIRST_SUPERUSER_PASSWORD", "TestPassword123!")
|
|
|
|
# Reload settings to pick up environment variables
|
|
from app.core import config
|
|
import importlib
|
|
importlib.reload(config)
|
|
from app.core.config import settings
|
|
|
|
# Mock user_crud to return None (user doesn't exist)
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
mock_crud.get_by_email.return_value = None
|
|
|
|
# Create a mock user to return from create
|
|
from datetime import datetime, timezone
|
|
import uuid
|
|
mock_user = User(
|
|
id=uuid.uuid4(),
|
|
email="admin@test.com",
|
|
password_hash="hashed",
|
|
first_name="Admin",
|
|
last_name="User",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
created_at=datetime.now(timezone.utc),
|
|
updated_at=datetime.now(timezone.utc)
|
|
)
|
|
mock_crud.create.return_value = mock_user
|
|
|
|
# Call init_db
|
|
user = init_db(db_session)
|
|
|
|
# Verify user was created
|
|
assert user is not None
|
|
assert user.email == "admin@test.com"
|
|
assert user.is_superuser is True
|
|
mock_crud.create.assert_called_once()
|
|
|
|
def test_init_db_returns_existing_superuser(self, db_session, monkeypatch):
|
|
"""Test that init_db returns existing superuser without creating new one"""
|
|
# Set environment variables
|
|
monkeypatch.setenv("FIRST_SUPERUSER_EMAIL", "existing@test.com")
|
|
monkeypatch.setenv("FIRST_SUPERUSER_PASSWORD", "TestPassword123!")
|
|
|
|
# Reload settings
|
|
from app.core import config
|
|
import importlib
|
|
importlib.reload(config)
|
|
|
|
# Mock user_crud to return existing user
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
from datetime import datetime, timezone
|
|
import uuid
|
|
existing_user = User(
|
|
id=uuid.uuid4(),
|
|
email="existing@test.com",
|
|
password_hash="hashed",
|
|
first_name="Existing",
|
|
last_name="User",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
created_at=datetime.now(timezone.utc),
|
|
updated_at=datetime.now(timezone.utc)
|
|
)
|
|
mock_crud.get_by_email.return_value = existing_user
|
|
|
|
# Call init_db
|
|
user = init_db(db_session)
|
|
|
|
# Verify existing user was returned
|
|
assert user is not None
|
|
assert user.email == "existing@test.com"
|
|
# create should NOT be called
|
|
mock_crud.create.assert_not_called()
|
|
|
|
def test_init_db_uses_defaults_when_env_not_set(self, db_session):
|
|
"""Test that init_db uses default credentials when env vars not set"""
|
|
# Mock settings to return None for superuser credentials
|
|
with patch('app.init_db.settings') as mock_settings:
|
|
mock_settings.FIRST_SUPERUSER_EMAIL = None
|
|
mock_settings.FIRST_SUPERUSER_PASSWORD = None
|
|
|
|
# Mock user_crud
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
mock_crud.get_by_email.return_value = None
|
|
|
|
from datetime import datetime, timezone
|
|
import uuid
|
|
mock_user = User(
|
|
id=uuid.uuid4(),
|
|
email="admin@example.com",
|
|
password_hash="hashed",
|
|
first_name="Admin",
|
|
last_name="User",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
created_at=datetime.now(timezone.utc),
|
|
updated_at=datetime.now(timezone.utc)
|
|
)
|
|
mock_crud.create.return_value = mock_user
|
|
|
|
# Call init_db
|
|
with patch('app.init_db.logger') as mock_logger:
|
|
user = init_db(db_session)
|
|
|
|
# Verify default email was used
|
|
mock_crud.get_by_email.assert_called_with(db_session, email="admin@example.com")
|
|
# Verify warning was logged since credentials not set
|
|
assert mock_logger.warning.called
|
|
|
|
def test_init_db_handles_creation_error(self, db_session, monkeypatch):
|
|
"""Test that init_db handles errors during user creation"""
|
|
# Set environment variables
|
|
monkeypatch.setenv("FIRST_SUPERUSER_EMAIL", "admin@test.com")
|
|
monkeypatch.setenv("FIRST_SUPERUSER_PASSWORD", "TestPassword123!")
|
|
|
|
# Reload settings
|
|
from app.core import config
|
|
import importlib
|
|
importlib.reload(config)
|
|
|
|
# Mock user_crud to raise an exception
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
mock_crud.get_by_email.return_value = None
|
|
mock_crud.create.side_effect = Exception("Database error")
|
|
|
|
# Call init_db and expect exception
|
|
with pytest.raises(Exception) as exc_info:
|
|
init_db(db_session)
|
|
|
|
assert "Database error" in str(exc_info.value)
|
|
|
|
def test_init_db_logs_superuser_creation(self, db_session, monkeypatch):
|
|
"""Test that init_db logs appropriate messages"""
|
|
# Set environment variables
|
|
monkeypatch.setenv("FIRST_SUPERUSER_EMAIL", "admin@test.com")
|
|
monkeypatch.setenv("FIRST_SUPERUSER_PASSWORD", "TestPassword123!")
|
|
|
|
# Reload settings
|
|
from app.core import config
|
|
import importlib
|
|
importlib.reload(config)
|
|
|
|
# Mock user_crud
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
mock_crud.get_by_email.return_value = None
|
|
|
|
from datetime import datetime, timezone
|
|
import uuid
|
|
mock_user = User(
|
|
id=uuid.uuid4(),
|
|
email="admin@test.com",
|
|
password_hash="hashed",
|
|
first_name="Admin",
|
|
last_name="User",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
created_at=datetime.now(timezone.utc),
|
|
updated_at=datetime.now(timezone.utc)
|
|
)
|
|
mock_crud.create.return_value = mock_user
|
|
|
|
# Call init_db with logger mock
|
|
with patch('app.init_db.logger') as mock_logger:
|
|
user = init_db(db_session)
|
|
|
|
# Verify info log was called
|
|
assert mock_logger.info.called
|
|
info_call_args = str(mock_logger.info.call_args)
|
|
assert "Created first superuser" in info_call_args
|
|
|
|
def test_init_db_logs_existing_user(self, db_session, monkeypatch):
|
|
"""Test that init_db logs when user already exists"""
|
|
# Set environment variables
|
|
monkeypatch.setenv("FIRST_SUPERUSER_EMAIL", "existing@test.com")
|
|
monkeypatch.setenv("FIRST_SUPERUSER_PASSWORD", "TestPassword123!")
|
|
|
|
# Reload settings
|
|
from app.core import config
|
|
import importlib
|
|
importlib.reload(config)
|
|
|
|
# Mock user_crud to return existing user
|
|
with patch('app.init_db.user_crud') as mock_crud:
|
|
from datetime import datetime, timezone
|
|
import uuid
|
|
existing_user = User(
|
|
id=uuid.uuid4(),
|
|
email="existing@test.com",
|
|
password_hash="hashed",
|
|
first_name="Existing",
|
|
last_name="User",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
created_at=datetime.now(timezone.utc),
|
|
updated_at=datetime.now(timezone.utc)
|
|
)
|
|
mock_crud.get_by_email.return_value = existing_user
|
|
|
|
# Call init_db with logger mock
|
|
with patch('app.init_db.logger') as mock_logger:
|
|
user = init_db(db_session)
|
|
|
|
# Verify info log was called
|
|
assert mock_logger.info.called
|
|
info_call_args = str(mock_logger.info.call_args)
|
|
assert "already exists" in info_call_args.lower()
|