diff --git a/app/core/database.py b/app/core/database.py index 40901120..2d96c357 100644 --- a/app/core/database.py +++ b/app/core/database.py @@ -1,5 +1,5 @@ from sqlalchemy import create_engine -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import declarative_base from sqlalchemy.orm import sessionmaker, Session from .config import settings diff --git a/models/api_models.py b/models/api_models.py index c1ba1f97..7895953b 100644 --- a/models/api_models.py +++ b/models/api_models.py @@ -1,5 +1,5 @@ -# models/api_models.py - Updated with Marketplace Support -from pydantic import BaseModel, Field, field_validator, EmailStr +# models/api_models.py - Updated with Marketplace Support and Pydantic v2 +from pydantic import BaseModel, Field, field_validator, EmailStr, ConfigDict from typing import Optional, List from datetime import datetime @@ -36,6 +36,8 @@ class UserLogin(BaseModel): class UserResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int email: str username: str @@ -45,8 +47,6 @@ class UserResponse(BaseModel): created_at: datetime updated_at: datetime - model_config = {"from_attributes": True} - class LoginResponse(BaseModel): access_token: str @@ -98,6 +98,8 @@ class ShopUpdate(BaseModel): class ShopResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int shop_code: str shop_name: str @@ -113,9 +115,6 @@ class ShopResponse(BaseModel): created_at: datetime updated_at: datetime - class Config: - from_attributes = True - class ShopListResponse(BaseModel): shops: List[ShopResponse] @@ -185,12 +184,12 @@ class ProductUpdate(ProductBase): class ProductResponse(ProductBase): + model_config = ConfigDict(from_attributes=True) + id: int created_at: datetime updated_at: datetime - model_config = {"from_attributes": True} - # NEW: Shop Product models class ShopProductCreate(BaseModel): @@ -207,6 +206,8 @@ class ShopProductCreate(BaseModel): class ShopProductResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int shop_id: int product: ProductResponse @@ -223,9 +224,6 @@ class ShopProductResponse(BaseModel): created_at: datetime updated_at: datetime - class Config: - from_attributes = True - # Stock Models class StockBase(BaseModel): @@ -246,6 +244,8 @@ class StockUpdate(BaseModel): class StockResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int gtin: str location: str @@ -253,8 +253,6 @@ class StockResponse(BaseModel): created_at: datetime updated_at: datetime - model_config = {"from_attributes": True} - class StockLocationResponse(BaseModel): location: str diff --git a/models/database_models.py b/models/database_models.py index b1857df2..b93affb8 100644 --- a/models/database_models.py +++ b/models/database_models.py @@ -1,10 +1,10 @@ # models/database_models.py - Updated with Marketplace Support from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, Text, ForeignKey, UniqueConstraint, Index -from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime -Base = declarative_base() +# Import Base from the central database module instead of creating a new one +from app.core.database import Base class User(Base): diff --git a/tests/conftest.py b/tests/conftest.py index 6766b091..f01efb16 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,8 @@ from sqlalchemy.pool import StaticPool from main import app from app.core.database import get_db, Base -from models.database_models import User, Product, Stock, Shop +# Import all models to ensure they're registered with Base metadata +from models.database_models import User, Product, Stock, Shop, MarketplaceImportJob, ShopProduct from middleware.auth import AuthManager # Use in-memory SQLite database for tests @@ -35,38 +36,41 @@ def testing_session_local(engine): @pytest.fixture(scope="function") def db(engine, testing_session_local): - """Create a fresh database for each test""" + """Create a database session for direct database operations""" # Create all tables Base.metadata.create_all(bind=engine) # Create session - db = testing_session_local() + db_session = testing_session_local() - # Override the dependency + try: + yield db_session + finally: + db_session.rollback() + db_session.close() + # Tables will be dropped by the client fixture + + +@pytest.fixture(scope="function") +def client(db): # Now client depends on db + """Create a test client with database dependency override""" + + # Override the dependency to use our test database def override_get_db(): try: yield db finally: - pass # Don't close here, we'll close in cleanup + pass # Don't close here, the db fixture handles it app.dependency_overrides[get_db] = override_get_db try: - yield db + client = TestClient(app) + yield client finally: - db.rollback() # Rollback any uncommitted changes - db.close() # Clean up the dependency override if get_db in app.dependency_overrides: del app.dependency_overrides[get_db] - # Drop all tables for next test - Base.metadata.drop_all(bind=engine) - - -@pytest.fixture(scope="function") -def client(db): - """Create a test client with database dependency override""" - return TestClient(app) @pytest.fixture(scope="session") @@ -174,10 +178,11 @@ def test_shop(db, test_user): def test_stock(db, test_product, test_shop): """Create test stock entry""" stock = Stock( - product_id=test_product.product_id, - shop_code=test_shop.shop_code, + gtin=test_product.gtin, # Fixed: use gtin instead of product_id + location=test_shop.shop_code, # Fixed: use location instead of shop_code quantity=10, - reserved_quantity=0 + reserved_quantity=0, + shop_id=test_shop.id # Add shop_id reference ) db.add(stock) db.commit() diff --git a/tests/test_auth.py b/tests/test_auth.py index ffa2cd22..75186165 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -66,7 +66,7 @@ class TestAuthenticationAPI: assert response.status_code == 401 assert "Incorrect username or password" in response.json()["detail"] - def test_login_nonexistent_user(self, client): + def test_login_nonexistent_user(self, client, db): # Added db fixture """Test login with nonexistent user""" response = client.post("/api/v1/auth/login", json={ "username": "nonexistent", @@ -116,4 +116,3 @@ class TestAuthManager: assert token_data["token_type"] == "bearer" assert "expires_in" in token_data assert isinstance(token_data["expires_in"], int) -