feat: Add API endpoint for managing categories

This commit is contained in:
2026-07-03 08:33:48 +05:30
parent be6c95c497
commit 8488e3bdd0
15 changed files with 413 additions and 48 deletions

View File

@@ -0,0 +1,32 @@
import pytest
from httpx import AsyncClient
pytestmark = pytest.mark.asyncio
async def test_get_categories_seeded_defaults(client: AsyncClient):
# Retrieve categories and verify the default list is present (since lifespan seeds them)
response = await client.get("/api/v1/categories")
assert response.status_code == 200
categories = response.json()
assert len(categories) >= 8
names = [c["name"] for c in categories]
assert "Food" in names
assert "Shopping" in names
assert "Travel" in names
assert "Other" in names
async def test_create_and_duplicate_category(client: AsyncClient):
# 1. Create a new category
response = await client.post("/api/v1/categories", json={"name": "Medical"})
assert response.status_code == 201
data = response.json()
assert "id" in data
assert data["name"] == "Medical"
# 2. Try creating the same category (duplicate, case-insensitive check)
dup_response = await client.post("/api/v1/categories", json={"name": "medical"})
assert dup_response.status_code == 400
assert "already exists" in dup_response.json()["detail"]

View File

@@ -46,6 +46,24 @@ def initialize_test_db():
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)
# Seed categories in test DB
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.models.category import Category
async with AsyncSession(test_engine) as session:
defaults = [
Category(name="Food"),
Category(name="Shopping"),
Category(name="Travel"),
Category(name="Transport"),
Category(name="Utilities"),
Category(name="Cash Withdrawal"),
Category(name="Entertainment"),
Category(name="Other"),
]
session.add_all(defaults)
await session.commit()
async def teardown_db():
async with test_engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)

View File

@@ -18,7 +18,9 @@ async def test_classify_transactions_batch_retry_success():
{"txn_id": "TX2", "merchant": "Amazon", "amount": 1200.0},
]
results = await classify_transactions_batch(mock_client, batch_txns)
results = await classify_transactions_batch(
mock_client, batch_txns, ["Food", "Shopping", "Other"]
)
assert len(results) == 2
assert results["TX1"]["category"] == "Food"
assert results["TX1"]["failed"] is False
@@ -37,7 +39,9 @@ async def test_classify_transactions_batch_retry_failure():
# Patch sleep to make retry test run instantly
with patch("asyncio.sleep", return_value=None):
results = await classify_transactions_batch(mock_client, batch_txns)
results = await classify_transactions_batch(
mock_client, batch_txns, ["Food", "Shopping", "Other"]
)
assert len(results) == 1
assert results["TX1"]["category"] == "Other"