mirror of
https://github.com/sortedcord/alemno-payments.git
synced 2026-07-22 04:02:49 +05:30
setup dependencies and fix test_job_repositories missing deps
This commit is contained in:
15
app/core/dependencies.py
Normal file
15
app/core/dependencies.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.db.session import get_db
|
||||
from app.repositories.job_repository import JobRepository
|
||||
from app.services.job_service import JobService
|
||||
|
||||
|
||||
def get_job_repository(db: AsyncSession = Depends(get_db)) -> JobRepository:
|
||||
"""Dependency to retrieve JobRepository"""
|
||||
return JobRepository(db)
|
||||
|
||||
|
||||
def get_job_service(repo: JobRepository = Depends(get_job_repository)) -> JobService:
|
||||
"""Dependency to retrieve JobService"""
|
||||
return JobService(repo)
|
||||
@@ -1,11 +1,20 @@
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
|
||||
class AlemnoException(Exception):
|
||||
"""Base exception for Alemno Payments Application"""
|
||||
pass
|
||||
|
||||
|
||||
class JobNotFoundException(AlemnoException):
|
||||
"""Raised when a job is not found"""
|
||||
def __init__(self, job_id: str):
|
||||
self.job_id = job_id
|
||||
super().__init__(f"Job with ID {job_id} not found")
|
||||
|
||||
|
||||
class InvalidCSVException(AlemnoException):
|
||||
"""Raised when the uploaded CSV is invalid"""
|
||||
def __init__(self, detail: str):
|
||||
self.detail = detail
|
||||
super().__init__(detail)
|
||||
|
||||
@@ -3,11 +3,15 @@ from typing import AsyncGenerator
|
||||
import pytest
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.dependencies import get_db
|
||||
from app.db.base import Base
|
||||
from app.main import app
|
||||
|
||||
# Use a test database suffix or a separate database for testing
|
||||
TEST_DATABASE_URL = settings.DATABASE_URL.replace(settings.POSTGRES_DB, f"test_{settings.POSTGRES_DB}")
|
||||
|
||||
# Create async engine for test db
|
||||
test_engine = create_async_engine(
|
||||
TEST_DATABASE_URL,
|
||||
@@ -58,3 +62,39 @@ def initialize_test_db():
|
||||
loop.run_until_complete(teardown_db())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def db_session() -> AsyncGenerator[AsyncSession, None]:
|
||||
"""Provide a transactional test database session."""
|
||||
if _db_offline:
|
||||
pytest.skip("PostgreSQL database is offline")
|
||||
return
|
||||
|
||||
async with TestAsyncSessionLocal() as session:
|
||||
try:
|
||||
yield session
|
||||
await session.commit()
|
||||
except Exception:
|
||||
await session.rollback()
|
||||
raise
|
||||
finally:
|
||||
await session.close()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def client(db_session: AsyncSession) -> AsyncGenerator[AsyncClient, None]:
|
||||
"""Provide an HTTPX AsyncClient for FastAPI endpoint testing with db overrides."""
|
||||
# Override get_db dependency to use the test session
|
||||
async def override_get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
yield db_session
|
||||
|
||||
app.dependency_overrides[get_db] = override_get_db
|
||||
|
||||
async with AsyncClient(
|
||||
transport=ASGITransport(app=app),
|
||||
base_url="http://test",
|
||||
) as client:
|
||||
yield client
|
||||
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
56
tests/repositories/test_job_repository.py
Normal file
56
tests/repositories/test_job_repository.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.repositories.job_repository import JobRepository
|
||||
from app.db.models.job import Job
|
||||
|
||||
# Set up asyncio marker
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
||||
async def test_create_and_get_job(db_session: AsyncSession):
|
||||
repo = JobRepository(db_session)
|
||||
|
||||
# Create job
|
||||
job = await repo.create(filename="test_transactions.csv")
|
||||
assert job.id is not None
|
||||
assert job.status == "pending"
|
||||
assert job.filename == "test_transactions.csv"
|
||||
|
||||
# Retrieve job
|
||||
fetched_job = await repo.get_by_id(job.id)
|
||||
assert fetched_job is not None
|
||||
assert fetched_job.id == job.id
|
||||
assert fetched_job.filename == "test_transactions.csv"
|
||||
|
||||
|
||||
async def test_update_job(db_session: AsyncSession):
|
||||
repo = JobRepository(db_session)
|
||||
job = await repo.create(filename="update_test.csv")
|
||||
|
||||
# Update status and count
|
||||
updated = await repo.update(job, status="completed", row_count=10, summary={"total": 100})
|
||||
assert updated.status == "completed"
|
||||
assert updated.row_count == 10
|
||||
assert updated.summary == {"total": 100}
|
||||
|
||||
# Retrieve to verify persistence
|
||||
fetched = await repo.get_by_id(job.id)
|
||||
assert fetched.status == "completed"
|
||||
assert fetched.row_count == 10
|
||||
|
||||
|
||||
async def test_list_jobs(db_session: AsyncSession):
|
||||
repo = JobRepository(db_session)
|
||||
|
||||
# Clear existing if any
|
||||
await repo.create(filename="list_1.csv")
|
||||
await repo.create(filename="list_2.csv")
|
||||
|
||||
jobs = await repo.list_all()
|
||||
assert len(jobs) >= 2
|
||||
|
||||
pending_jobs = await repo.list_all(status="pending")
|
||||
assert len(pending_jobs) >= 2
|
||||
|
||||
completed_jobs = await repo.list_all(status="completed")
|
||||
assert len(completed_jobs) == 1 # From the update test above
|
||||
Reference in New Issue
Block a user