add tests forn forms, products, productors
All checks were successful
Deploy Amap / deploy (push) Successful in 3m45s

This commit is contained in:
Julien Aldon
2026-02-25 16:39:12 +01:00
parent cfb8d435a8
commit 61cbbf0366
31 changed files with 2694 additions and 60 deletions

View File

@@ -4,25 +4,12 @@
- Extract recap - Extract recap
## Payment method max cheque number
## Link products to a form ## Link products to a form
## Wording ## Wording
- all translations - all translations
## Draft / Publish form
- By default form is in draft mode
- Validate a form (button)
- check if productor
- check if shipments
- check products
- Publish
## Only show productors / products / forms for referent of type
## Footer ## Footer
### Legal ### Legal

View File

@@ -29,6 +29,11 @@ alembic revision --autogenerate -m "message"
```console ```console
alembic upgrade head alembic upgrade head
``` ```
## Tests
```
hatch run pytest
hatch run pytest --cov=src -vv
```
## License ## License

View File

@@ -30,7 +30,10 @@ dependencies = [
"requests", "requests",
"weasyprint", "weasyprint",
"odfdo", "odfdo",
"alembic" "alembic",
"pytest",
"pytest-cov",
"pytest-mock",
] ]
[project.urls] [project.urls]

View File

@@ -0,0 +1,17 @@
class FormServiceError(Exception):
def __init__(self, message: str):
super().__init__(message)
class UserNotFoundError(FormServiceError):
pass
class ProductorNotFoundError(FormServiceError):
pass
class FormNotFoundError(FormServiceError):
pass
class FormCreateError(FormServiceError):
def __init__(self, message: str, field: str | None = None):
super().__init__(message)
self.field = field

View File

@@ -4,6 +4,7 @@ import src.models as models
from src.database import get_session from src.database import get_session
from sqlmodel import Session from sqlmodel import Session
import src.forms.service as service import src.forms.service as service
import src.forms.exceptions as exceptions
from src.auth.auth import get_current_user from src.auth.auth import get_current_user
router = APIRouter(prefix='/forms') router = APIRouter(prefix='/forms')
@@ -40,7 +41,15 @@ async def create_form(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
return service.create_one(session, form) try:
form = service.create_one(session, form)
except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.productornotfound)
except exceptions.UserNotFoundError:
raise HTTPException(status_code=404, detail=messages.usernotfound)
except exceptions.FormCreateError:
raise HTTPException(status_code=400, detail=messages.forminputinvalid)
return form
@router.put('/{id}', response_model=models.FormPublic) @router.put('/{id}', response_model=models.FormPublic)
async def update_form( async def update_form(
@@ -48,9 +57,14 @@ async def update_form(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.update_one(session, id, form) result = service.update_one(session, id, form)
if result is None: except exceptions.FormNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.notfound)
except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.productornotfound)
except exceptions.UserNotFoundError:
raise HTTPException(status_code=404, detail=messages.usernotfound)
return result return result
@router.delete('/{id}', response_model=models.FormPublic) @router.delete('/{id}', response_model=models.FormPublic)
@@ -59,7 +73,8 @@ async def delete_form(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.delete_one(session, id) result = service.delete_one(session, id)
if result is None: except exceptions.FormNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.notfound)
return result return result

View File

@@ -1,7 +1,9 @@
from sqlmodel import Session, select from sqlmodel import Session, select
import src.models as models
from sqlalchemy import func from sqlalchemy import func
import src.models as models
import src.forms.exceptions as exceptions
def get_all( def get_all(
session: Session, session: Session,
seasons: list[str], seasons: list[str],
@@ -46,6 +48,12 @@ def get_one(session: Session, form_id: int) -> models.FormPublic:
return session.get(models.Form, form_id) return session.get(models.Form, form_id)
def create_one(session: Session, form: models.FormCreate) -> models.FormPublic: def create_one(session: Session, form: models.FormCreate) -> models.FormPublic:
if not form:
raise exceptions.FormCreateError('FormCreate input cannot be None')
if not session.get(models.Productor, form.productor_id):
raise exceptions.ProductorNotFoundError(f'Productor {form.productor_id} not found')
if not session.get(models.User, form.referer_id):
raise exceptions.UserNotFoundError(f'User {form.referer_id} not found')
form_create = form.model_dump(exclude_unset=True) form_create = form.model_dump(exclude_unset=True)
new_form = models.Form(**form_create) new_form = models.Form(**form_create)
session.add(new_form) session.add(new_form)
@@ -58,7 +66,11 @@ def update_one(session: Session, id: int, form: models.FormUpdate) -> models.For
result = session.exec(statement) result = session.exec(statement)
new_form = result.first() new_form = result.first()
if not new_form: if not new_form:
return None raise exceptions.FormNotFoundError(f'Form {id} not found')
if form.productor_id and not session.get(models.Productor, form.productor_id):
raise exceptions.ProductorNotFoundError(f'Productor {form.productor_id} not found')
if form.referer_id and not session.get(models.User, form.referer_id):
raise exceptions.UserNotFoundError(f'User {form.referer_id} not found')
form_updates = form.model_dump(exclude_unset=True) form_updates = form.model_dump(exclude_unset=True)
for key, value in form_updates.items(): for key, value in form_updates.items():
setattr(new_form, key, value) setattr(new_form, key, value)
@@ -72,7 +84,7 @@ def delete_one(session: Session, id: int) -> models.FormPublic:
result = session.exec(statement) result = session.exec(statement)
form = result.first() form = result.first()
if not form: if not form:
return None raise exceptions.FormNotFoundError(f'Form {id} not found')
result = models.FormPublic.model_validate(form) result = models.FormPublic.model_validate(form)
session.delete(form) session.delete(form)
session.commit() session.commit()

View File

@@ -1,10 +1,21 @@
notfound = "Resource was not found." pdferror = 'An error occured during PDF generation please contact administrator'
pdferror = "An error occured during PDF generation please contact administrator"
tokenexipired = "Token expired" tokenexipired = 'Token expired'
invalidtoken = "Invalid token" invalidtoken = 'Invalid token'
notauthenticated = "Not authenticated" notauthenticated = 'Not authenticated'
usernotfound = "User not found" failtogettoken = 'Failed to get token'
userloggedout = "User logged out" unauthorized = 'Unauthorized'
failtogettoken = "Failed to get token" notallowed = 'Not Allowed'
unauthorized = "Unauthorized"
notallowed = "Not Allowed" notfound = 'Resource was not found.'
usernotfound = 'User not found'
userloggedout = 'User logged out'
productorinputinvalid = 'Invalid productor input'
productornotfound = 'Productor not found'
forminputinvalid = 'Invalid form input'
formnotfound = 'Form not found'
productinputinvalid = 'Invalid product input'
productnotfound = 'Product not found'

View File

@@ -0,0 +1,11 @@
class ProductorServiceError(Exception):
def __init__(self, message: str):
super().__init__(message)
class ProductorNotFoundError(ProductorServiceError):
pass
class ProductorCreateError(ProductorServiceError):
def __init__(self, message: str, field: str | None = None):
super().__init__(message)
self.field = field

View File

@@ -4,6 +4,7 @@ import src.models as models
from src.database import get_session from src.database import get_session
from sqlmodel import Session from sqlmodel import Session
import src.productors.service as service import src.productors.service as service
import src.productors.exceptions as exceptions
from src.auth.auth import get_current_user from src.auth.auth import get_current_user
router = APIRouter(prefix='/productors') router = APIRouter(prefix='/productors')
@@ -34,7 +35,11 @@ def create_productor(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
return service.create_one(session, productor) try:
result = service.create_one(session, productor)
except exceptions.ProductorCreateError:
raise HTTPException(status_code=400, detail=messages.productorinputinvalid)
return result
@router.put('/{id}', response_model=models.ProductorPublic) @router.put('/{id}', response_model=models.ProductorPublic)
def update_productor( def update_productor(
@@ -42,9 +47,10 @@ def update_productor(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.update_one(session, id, productor) result = service.update_one(session, id, productor)
if result is None: except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.productornotfound)
return result return result
@router.delete('/{id}', response_model=models.ProductorPublic) @router.delete('/{id}', response_model=models.ProductorPublic)
@@ -53,7 +59,8 @@ def delete_productor(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.delete_one(session, id) result = service.delete_one(session, id)
if result is None: except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.productornotfound)
return result return result

View File

@@ -1,5 +1,6 @@
from sqlmodel import Session, select from sqlmodel import Session, select
import src.models as models import src.models as models
import src.productors.exceptions as exceptions
def get_all( def get_all(
session: Session, session: Session,
@@ -20,7 +21,9 @@ def get_one(session: Session, productor_id: int) -> models.ProductorPublic:
return session.get(models.Productor, productor_id) return session.get(models.Productor, productor_id)
def create_one(session: Session, productor: models.ProductorCreate) -> models.ProductorPublic: def create_one(session: Session, productor: models.ProductorCreate) -> models.ProductorPublic:
productor_create = productor.model_dump(exclude_unset=True, exclude="payment_methods") if not productor:
raise exceptions.ProductorCreateError('ProductorCreate input cannot be None')
productor_create = productor.model_dump(exclude_unset=True, exclude='payment_methods')
new_productor = models.Productor(**productor_create) new_productor = models.Productor(**productor_create)
new_productor.payment_methods = [ new_productor.payment_methods = [
@@ -40,21 +43,21 @@ def update_one(session: Session, id: int, productor: models.ProductorUpdate) ->
result = session.exec(statement) result = session.exec(statement)
new_productor = result.first() new_productor = result.first()
if not new_productor: if not new_productor:
return None raise exceptions.ProductorNotFoundError(f'Productor {id} not found')
productor_updates = productor.model_dump(exclude_unset=True) productor_updates = productor.model_dump(exclude_unset=True)
if "payment_methods" in productor_updates: if 'payment_methods' in productor_updates:
new_productor.payment_methods.clear() new_productor.payment_methods.clear()
for pm in productor_updates["payment_methods"]: for pm in productor_updates['payment_methods']:
new_productor.payment_methods.append( new_productor.payment_methods.append(
models.PaymentMethod( models.PaymentMethod(
name=pm["name"], name=pm['name'],
details=pm["details"], details=pm['details'],
productor_id=id, productor_id=id,
max=pm["max"] max=pm['max']
) )
) )
del productor_updates["payment_methods"] del productor_updates['payment_methods']
for key, value in productor_updates.items(): for key, value in productor_updates.items():
setattr(new_productor, key, value) setattr(new_productor, key, value)
@@ -68,7 +71,7 @@ def delete_one(session: Session, id: int) -> models.ProductorPublic:
result = session.exec(statement) result = session.exec(statement)
productor = result.first() productor = result.first()
if not productor: if not productor:
return None raise exceptions.ProductorNotFoundError(f'Productor {id} not found')
result = models.ProductorPublic.model_validate(productor) result = models.ProductorPublic.model_validate(productor)
session.delete(productor) session.delete(productor)
session.commit() session.commit()

View File

@@ -0,0 +1,14 @@
class ProductServiceError(Exception):
def __init__(self, message: str):
super().__init__(message)
class ProductorNotFoundError(ProductServiceError):
pass
class ProductNotFoundError(ProductServiceError):
pass
class ProductCreateError(ProductServiceError):
def __init__(self, message: str, field: str | None = None):
super().__init__(message)
self.field = field

View File

@@ -4,7 +4,9 @@ import src.models as models
from src.database import get_session from src.database import get_session
from sqlmodel import Session from sqlmodel import Session
import src.products.service as service import src.products.service as service
import src.products.exceptions as exceptions
from src.auth.auth import get_current_user from src.auth.auth import get_current_user
router = APIRouter(prefix='/products') router = APIRouter(prefix='/products')
@router.get('', response_model=list[models.ProductPublic], ) @router.get('', response_model=list[models.ProductPublic], )
@@ -40,7 +42,13 @@ def create_product(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
return service.create_one(session, product) try:
result = service.create_one(session, product)
except exceptions.ProductCreateError:
raise HTTPException(status_code=400, detail=messages.productinputinvalid)
except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.productornotfound)
return result
@router.put('/{id}', response_model=models.ProductPublic) @router.put('/{id}', response_model=models.ProductPublic)
def update_product( def update_product(
@@ -48,9 +56,12 @@ def update_product(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.update_one(session, id, product) result = service.update_one(session, id, product)
if result is None: except exceptions.ProductNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.productnotfound)
except exceptions.ProductorNotFoundError:
raise HTTPException(status_code=404, detail=messages.productornotfound)
return result return result
@router.delete('/{id}', response_model=models.ProductPublic) @router.delete('/{id}', response_model=models.ProductPublic)
@@ -59,7 +70,8 @@ def delete_product(
user: models.User = Depends(get_current_user), user: models.User = Depends(get_current_user),
session: Session = Depends(get_session) session: Session = Depends(get_session)
): ):
try:
result = service.delete_one(session, id) result = service.delete_one(session, id)
if result is None: except exceptions.ProductNotFoundError:
raise HTTPException(status_code=404, detail=messages.notfound) raise HTTPException(status_code=404, detail=messages.notfound)
return result return result

View File

@@ -1,5 +1,6 @@
from sqlmodel import Session, select from sqlmodel import Session, select
import src.models as models import src.models as models
import src.products.exceptions as exceptions
def get_all( def get_all(
session: Session, session: Session,
@@ -15,7 +16,7 @@ def get_all(
if len(names) > 0: if len(names) > 0:
statement = statement.where(models.Product.name.in_(names)) statement = statement.where(models.Product.name.in_(names))
if len(productors) > 0: if len(productors) > 0:
statement = statement.join(models.Productor).where(models.Productor.name.in_(productors)) statement = statement.where(models.Productor.name.in_(productors))
if len(types) > 0: if len(types) > 0:
statement = statement.where(models.Product.type.in_(types)) statement = statement.where(models.Product.type.in_(types))
return session.exec(statement.order_by(models.Product.name)).all() return session.exec(statement.order_by(models.Product.name)).all()
@@ -24,6 +25,10 @@ def get_one(session: Session, product_id: int) -> models.ProductPublic:
return session.get(models.Product, product_id) return session.get(models.Product, product_id)
def create_one(session: Session, product: models.ProductCreate) -> models.ProductPublic: def create_one(session: Session, product: models.ProductCreate) -> models.ProductPublic:
if not product:
raise exceptions.ProductCreateError('ProductCreate input cannot be None')
if not session.get(models.Productor, product.productor_id):
raise exceptions.ProductorNotFoundError(f'Productor {product.productor_id} not found')
product_create = product.model_dump(exclude_unset=True) product_create = product.model_dump(exclude_unset=True)
new_product = models.Product(**product_create) new_product = models.Product(**product_create)
session.add(new_product) session.add(new_product)
@@ -36,7 +41,10 @@ def update_one(session: Session, id: int, product: models.ProductUpdate) -> mode
result = session.exec(statement) result = session.exec(statement)
new_product = result.first() new_product = result.first()
if not new_product: if not new_product:
return None raise exceptions.ProductNotFoundError(f'Product {id} not found')
if product.productor_id and not session.get(models.Productor, product.productor_id):
raise exceptions.ProductorNotFoundError(f'Productor {product.productor_id} not found')
product_updates = product.model_dump(exclude_unset=True) product_updates = product.model_dump(exclude_unset=True)
for key, value in product_updates.items(): for key, value in product_updates.items():
setattr(new_product, key, value) setattr(new_product, key, value)
@@ -51,7 +59,7 @@ def delete_one(session: Session, id: int) -> models.ProductPublic:
result = session.exec(statement) result = session.exec(statement)
product = result.first() product = result.first()
if not product: if not product:
return None raise exceptions.ProductNotFoundError(f'Product {id} not found')
result = models.ProductPublic.model_validate(product) result = models.ProductPublic.model_validate(product)
session.delete(product) session.delete(product)
session.commit() session.commit()

View File

@@ -1,4 +1,4 @@
from pydantic_settings import BaseSettings from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings): class Settings(BaseSettings):
origins: str origins: str
@@ -16,8 +16,9 @@ class Settings(BaseSettings):
max_age: int max_age: int
debug: bool debug: bool
class Config: model_config = SettingsConfigDict(
env_file = "../.env" env_file='../.env'
)
settings = Settings() settings = Settings()

58
backend/tests/conftest.py Normal file
View File

@@ -0,0 +1,58 @@
import pytest
from fastapi.testclient import TestClient
from sqlmodel import SQLModel, Session, create_engine
from sqlalchemy.pool import StaticPool
from .fixtures import *
from src.main import app
import src.models as models
from src.database import get_session
from src.auth.auth import get_current_user
@pytest.fixture
def mock_session(mocker):
session = mocker.Mock()
def override():
return session
app.dependency_overrides[get_session] = override
yield session
app.dependency_overrides.clear()
@pytest.fixture
def mock_user():
user = models.User(id=1, name='test user', email='test@user.com')
def override():
return user
app.dependency_overrides[get_current_user] = override
yield user
app.dependency_overrides.clear()
@pytest.fixture
def client():
return TestClient(app)
@pytest.fixture(name='session')
def session_fixture():
engine = create_engine(
"sqlite://",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
SQLModel.metadata.create_all(engine)
connection = engine.connect()
transaction = connection.begin()
session = Session(bind=connection)
try:
yield session
finally:
transaction.rollback()
session.close()
connection.close()
engine.dispose()

View File

@@ -0,0 +1,72 @@
import src.models as models
from .forms import form_factory
def contract_factory(**kwargs):
data = dict(
firstname="test",
lastname="test",
email="test@test.test",
phone="00000000",
payment_method="cheque",
cheque_quantity=1,
form_id=1,
products=[],
cheques=[],
)
data.update(kwargs)
return models.Contract(**data)
def contract_public_factory(**kwargs):
data = dict(
id=1,
firstname="test",
lastname="test",
email="test@test.test",
phone="00000000",
payment_method="cheque",
cheque_quantity=1,
total_price=10,
products=[],
form=form_factory()
)
data.update(kwargs)
return models.ContractPublic(**data)
def contract_create_factory(**kwargs):
data = dict(
firstname="test",
lastname="test",
email="test@test.test",
phone="00000000",
payment_method="cheque",
cheque_quantity=1,
products=[],
cheques=[],
form_id=1,
)
data.update(kwargs)
return models.ContractCreate(**data)
def contract_update_factory(**kwargs):
data = dict(
firstname="test",
lastname="test",
email="test@test.test",
phone="00000000",
payment_method="cheque",
cheque_quantity=1,
)
data.update(kwargs)
return models.ContractUpdate(**data)
def contract_body_factory(**kwargs):
data = dict(
firstname="test",
lastname="test",
email="test@test.test",
phone="00000000",
payment_method="cheque",
cheque_quantity=1,
)
data.update(kwargs)
return data

View File

@@ -0,0 +1,84 @@
import src.models as models
from .productors import productor_public_factory
from .shipments import shipment_public_factory
from .users import user_factory
import datetime
def form_factory(**kwargs):
data = dict(
id=1,
name="form 1",
productor_id=1,
referer_id=1,
season="hiver-2026",
start=datetime.date(2025, 10, 10),
end=datetime.date(2025, 10, 10),
minimum_shipment_value=0,
visible=True,
referer=user_factory(),
shipments=[],
productor=productor_public_factory(),
)
data.update(kwargs)
return models.Form(**data)
def form_body_factory(**kwargs):
data = dict(
name="form 1",
productor_id=1,
referer_id=1,
season="hiver-2026",
start="2025-10-10",
end="2025-10-10",
minimum_shipment_value=0,
visible=True
)
data.update(kwargs)
return data
def form_create_factory(**kwargs):
data = dict(
name="form 1",
productor_id=1,
referer_id=1,
season="hiver-2026",
start=datetime.date(2025, 10, 10),
end=datetime.date(2025, 10, 10),
minimum_shipment_value=0,
visible=True
)
data.update(kwargs)
return models.FormCreate(**data)
def form_update_factory(**kwargs):
data = dict(
name="form 1",
productor_id=1,
referer_id=1,
season="hiver-2026",
start=datetime.date(2025, 10, 10),
end=datetime.date(2025, 10, 10),
minimum_shipment_value=0,
visible=True
)
data.update(kwargs)
return models.FormUpdate(**data)
def form_public_factory(form=None, shipments=[],**kwargs):
data = dict(
id=1,
name="form 1",
productor_id=1,
referer_id=1,
season="hiver-2026",
start=datetime.date(2025, 10, 10),
end=datetime.date(2025, 10, 10),
minimum_shipment_value=0,
visible=True,
referer=user_factory(),
shipments=[],
productor=productor_public_factory(),
)
data.update(kwargs)
return models.FormPublic(**data)

View File

@@ -0,0 +1,59 @@
import src.models as models
def productor_factory(**kwargs):
data = dict(
id=1,
name="test productor",
address="test address",
type="test type"
)
data.update(kwargs)
return models.Productor(**data)
def productor_public_factory(**kwargs):
data = dict(
id=1,
name="test productor",
address="test address",
type="test type",
products=[],
payment_methods=[],
)
data.update(kwargs)
return models.ProductorPublic(**data)
def productor_create_factory(**kwargs):
data = dict(
id=1,
name="test productor",
address="test address",
type="test type",
products=[],
payment_methods=[],
)
data.update(kwargs)
return models.ProductorCreate(**data)
def productor_update_factory(**kwargs):
data = dict(
id=1,
name="test productor",
address="test address",
type="test type",
products=[],
payment_methods=[],
)
data.update(kwargs)
return models.ProductorUpdate(**data)
def productor_body_factory(**kwargs):
data = dict(
id=1,
name="test productor",
address="test address",
type="test type",
products=[],
payment_methods=[],
)
data.update(kwargs)
return data

View File

@@ -0,0 +1,64 @@
import src.models as models
from .productors import productor_factory
from .shipments import shipment_factory
def product_body_factory(**kwargs):
data = dict(
name='product test 1',
unit=models.Unit.PIECE,
price=10.2,
price_kg=20.4,
quantity=500,
quantity_unit='g',
type=models.ProductType.OCCASIONAL,
productor_id=1,
)
data.update(kwargs)
return data
def product_create_factory(**kwargs):
data = dict(
name='product test 1',
unit=models.Unit.PIECE,
price=10.2,
price_kg=20.4,
quantity=500,
quantity_unit='g',
type=models.ProductType.OCCASIONAL,
productor_id=1,
)
data.update(kwargs)
return models.ProductCreate(**data)
def product_update_factory(**kwargs):
data = dict(
name='product test 1',
unit=models.Unit.PIECE,
price=10.2,
price_kg=20.4,
quantity=500,
quantity_unit='g',
type=models.ProductType.OCCASIONAL,
productor_id=1,
)
data.update(kwargs)
return models.ProductUpdate(**data)
def product_public_factory(productor=None, shipments=[],**kwargs):
if productor is None:
productor = productor_factory()
data = dict(
id=1,
name='product test 1',
unit=models.Unit.PIECE,
price=10.2,
price_kg=20.4,
quantity=500,
quantity_unit='g',
type=models.ProductType.OCCASIONAL,
productor_id=1,
productor=productor,
shipments=shipments,
)
data.update(kwargs)
return models.ProductPublic(**data)

View File

@@ -0,0 +1,53 @@
import src.models as models
import datetime
def shipment_factory(**kwargs):
data = dict(
id=1,
name="test shipment",
date=datetime.date(2025, 10, 10),
form_id=1,
)
data.update(kwargs)
return models.Shipment(**data)
def shipment_public_factory(**kwargs):
data = dict(
id=1,
name="test shipment",
date=datetime.date(2025, 10, 10),
form_id=1,
products=[],
form=models.Form(id=1, name="test")
)
data.update(kwargs)
return models.ShipmentPublic(**data)
def shipment_create_factory(**kwargs):
data = dict(
name="test shipment",
form_id=1,
date='2025-10-10',
product_ids=[],
)
data.update(kwargs)
return models.ShipmentCreate(**data)
def shipment_update_factory(**kwargs):
data = dict(
name="test shipment",
form_id=1,
date='2025-10-10',
product_ids=[],
)
data.update(kwargs)
return models.ShipmentUpdate(**data)
def shipment_body_factory(**kwargs):
data = dict(
name="test shipment",
form_id=1,
date="2025-10-10",
)
data.update(kwargs)
return data

View File

@@ -0,0 +1,48 @@
import src.models as models
def user_factory(**kwargs):
data = dict(
id=1,
name="test user",
email="test.test@test.test",
roles=[]
)
data.update(kwargs)
return models.User(**data)
def user_public_factory(**kwargs):
data = dict(
id=1,
name="test user",
email="test.test@test.test",
roles=[]
)
data.update(kwargs)
return models.UserPublic(**data)
def user_create_factory(**kwargs):
data = dict(
name="test user",
email="test.test@test.test",
role_names=[],
)
data.update(kwargs)
return models.UserCreate(**data)
def user_update_factory(**kwargs):
data = dict(
name="test user",
email="test.test@test.test",
role_names=[],
)
data.update(kwargs)
return models.UserUpdate(**data)
def user_body_factory(**kwargs):
data = dict(
name="test user",
email="test.test@test.test",
role_names=[],
)
data.update(kwargs)
return data

119
backend/tests/fixtures.py Normal file
View File

@@ -0,0 +1,119 @@
import pytest
from sqlmodel import Session
import src.models as models
import src.forms.service as forms_service
import src.productors.service as productors_service
import src.products.service as products_service
import src.users.service as users_service
import tests.factories.forms as forms_factory
import tests.factories.productors as productors_factory
import tests.factories.products as products_factory
import tests.factories.users as users_factory
@pytest.fixture
def productor(session: Session) -> models.ProductorPublic:
productor = productors_service.create_one(
session,
productors_factory.productor_create_factory(
name='test productor',
type='Légumineuses',
)
)
return productor
@pytest.fixture
def productors(session: Session) -> models.ProductorPublic:
productors = [
productors_service.create_one(
session,
productors_factory.productor_create_factory(
name='test productor 1',
type='Légumineuses',
)
),
productors_service.create_one(
session,
productors_factory.productor_create_factory(
name='test productor 2',
type='Légumes',
)
)
]
return productors
@pytest.fixture
def products(session: Session, productor: models.ProductorPublic) -> list[models.ProductPublic]:
products = [
products_service.create_one(
session,
products_factory.product_create_factory(
name='product 1 occasionnal',
type=models.ProductType.OCCASIONAL,
productor_id=productor.id
)
),
products_service.create_one(
session,
products_factory.product_create_factory(
name='product 2 recurrent',
type=models.ProductType.RECCURENT,
productor_id=productor.id
)
),
]
return products
@pytest.fixture
def user(session: Session) -> models.UserPublic:
user = users_service.create_one(
session,
users_factory.user_create_factory(
name='test user',
email='test@test.com',
role_names=['Légumineuses']
)
)
return user
@pytest.fixture
def referer(session: Session) -> models.UserPublic:
referer = users_service.create_one(
session,
users_factory.user_create_factory(
name='test referer',
email='test@test.com',
role_names=['Légumineuses'],
)
)
return referer
@pytest.fixture
def forms(
session: Session,
productor: models.ProductorPublic,
referer: models.UserPublic
) -> list[models.FormPublic]:
forms = [
forms_service.create_one(
session,
forms_factory.form_create_factory(
name='test form 1',
productor_id=productor.id,
referer_id=referer.id,
season='test season 1',
)
),
forms_service.create_one(
session,
forms_factory.form_create_factory(
name='test form 2',
productor_id=productor.id,
referer_id=referer.id,
season='test season 2',
)
)
]
return forms

View File

@@ -0,0 +1,186 @@
import src.contracts.service as service
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.contracts as contract_factory
from fastapi.exceptions import HTTPException
class TestContracts:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
contract_factory.contract_public_factory(name="test 1", id=1),
contract_factory.contract_public_factory(name="test 2", id=2),
contract_factory.contract_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/contracts')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
[],
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
contract_factory.contract_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/contracts?forms=form test')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
['form test'],
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.contracts.service.get_all')
response = client.get('/api/contracts')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = contract_factory.contract_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
mock_is_allowed = mocker.patch.object(
service,
'is_allowed',
return_value=True
)
response = client.get('/api/contracts/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
mock_is_allowed = mocker.patch.object(
service,
'is_allowed',
return_value=True
)
response = client.get('/api/contracts/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.contracts.service.get_one')
response = client.get('/api/contracts/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
contract_result = contract_factory.contract_public_factory(name='test contract delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=contract_result
)
mock_is_allowed = mocker.patch.object(
service,
'is_allowed',
return_value=True
)
response = client.delete('/api/contracts/2')
response_data = response.json()
assert response.status_code == 200
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
contract_result = None
mock = mocker.patch.object(
service,
'delete_one',
return_value=contract_result
)
mock_is_allowed = mocker.patch.object(
service,
'is_allowed',
return_value=True
)
response = client.delete('/api/contracts/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
contract_body = contract_factory.contract_body_factory(name='test contract delete')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.contracts.service.delete_one')
response = client.delete('/api/contracts/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,249 @@
import src.forms.service as service
import src.forms.exceptions as forms_exceptions
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.forms as form_factory
from fastapi.exceptions import HTTPException
class TestForms:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
form_factory.form_public_factory(name="test 1", id=1),
form_factory.form_public_factory(name="test 2", id=2),
form_factory.form_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/forms/referents')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
[],
[],
False,
mock_user,
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
form_factory.form_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/forms/referents?current_season=true&seasons=hiver-2025&productors=test productor')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
['hiver-2025'],
['test productor'],
True,
mock_user,
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.forms.service.get_all')
response = client.get('/api/forms/referents')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = form_factory.form_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/forms/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/forms/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_create_one(self, client, mocker, mock_session, mock_user):
form_body = form_factory.form_body_factory(name='test form create')
form_create = form_factory.form_create_factory(name='test form create')
form_result = form_factory.form_public_factory(name='test form create')
mock = mocker.patch.object(
service,
'create_one',
return_value=form_result
)
response = client.post('/api/forms', json=form_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test form create'
mock.assert_called_once_with(
mock_session,
form_create
)
def test_create_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
form_body = form_factory.form_body_factory(name='test form create')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.forms.service.create_one')
response = client.post('/api/forms', json=form_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_update_one(self, client, mocker, mock_session, mock_user):
form_body = form_factory.form_body_factory(name='test form update')
form_update = form_factory.form_update_factory(name='test form update')
form_result = form_factory.form_public_factory(name='test form update')
mock = mocker.patch.object(
service,
'update_one',
return_value=form_result
)
response = client.put('/api/forms/2', json=form_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test form update'
mock.assert_called_once_with(
mock_session,
2,
form_update
)
def test_update_one_notfound(self, client, mocker, mock_session, mock_user):
form_body = form_factory.form_body_factory(name='test form update')
form_update = form_factory.form_update_factory(name='test form update')
form_result = None
mock = mocker.patch.object(
service,
'update_one',
side_effect=forms_exceptions.FormNotFoundError('Form 1 not found')
)
response = client.put('/api/forms/2', json=form_body)
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
form_update
)
def test_update_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
form_body = form_factory.form_body_factory(name='test form update')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.forms.service.update_one')
response = client.put('/api/forms/2', json=form_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
form_result = form_factory.form_public_factory(name='test form delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=form_result
)
response = client.delete('/api/forms/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test form delete'
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
form_result = None
mock = mocker.patch.object(
service,
'delete_one',
side_effect=forms_exceptions.FormNotFoundError('Form 2 not found')
)
response = client.delete('/api/forms/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.forms.service.delete_one')
response = client.delete('/api/forms/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,262 @@
import src.productors.service as service
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.productors as productor_factory
import src.productors.exceptions as exceptions
from fastapi.exceptions import HTTPException
class TestProductors:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
productor_factory.productor_public_factory(name="test 1", id=1),
productor_factory.productor_public_factory(name="test 2", id=2),
productor_factory.productor_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/productors')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
[],
[],
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
productor_factory.productor_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/productors?types=Légumineuses&names=test 2')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
['test 2'],
['Légumineuses'],
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.productors.service.get_all')
response = client.get('/api/productors')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = productor_factory.productor_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/productors/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/productors/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.productors.service.get_one')
response = client.get('/api/productors/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_create_one(self, client, mocker, mock_session, mock_user):
productor_body = productor_factory.productor_body_factory(name='test productor create')
productor_create = productor_factory.productor_create_factory(name='test productor create')
productor_result = productor_factory.productor_public_factory(name='test productor create')
mock = mocker.patch.object(
service,
'create_one',
return_value=productor_result
)
response = client.post('/api/productors', json=productor_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test productor create'
mock.assert_called_once_with(
mock_session,
productor_create
)
def test_create_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
productor_body = productor_factory.productor_body_factory(name='test productor create')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.productors.service.create_one')
response = client.post('/api/productors', json=productor_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_update_one(self, client, mocker, mock_session, mock_user):
productor_body = productor_factory.productor_body_factory(name='test productor update')
productor_update = productor_factory.productor_update_factory(name='test productor update')
productor_result = productor_factory.productor_public_factory(name='test productor update')
mock = mocker.patch.object(
service,
'update_one',
return_value=productor_result
)
response = client.put('/api/productors/2', json=productor_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test productor update'
mock.assert_called_once_with(
mock_session,
2,
productor_update
)
def test_update_one_notfound(self, client, mocker, mock_session, mock_user):
productor_body = productor_factory.productor_body_factory(name='test productor update')
productor_update = productor_factory.productor_update_factory(name='test productor update')
productor_result = None
mock = mocker.patch.object(
service,
'update_one',
side_effect=exceptions.ProductorNotFoundError('Productor 1 not found')
)
response = client.put('/api/productors/2', json=productor_body)
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
productor_update
)
def test_update_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
productor_body = productor_factory.productor_body_factory(name='test productor update')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.productors.service.update_one')
response = client.put('/api/productors/2', json=productor_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
productor_result = productor_factory.productor_public_factory(name='test productor delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=productor_result
)
response = client.delete('/api/productors/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test productor delete'
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
productor_result = None
mock = mocker.patch.object(
service,
'delete_one',
side_effect=exceptions.ProductorNotFoundError('Productor 1 not found')
)
response = client.delete('/api/productors/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
productor_body = productor_factory.productor_body_factory(name='test productor delete')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.productors.service.delete_one')
response = client.delete('/api/productors/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,264 @@
import src.products.service as service
import src.products.exceptions as exceptions
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.products as product_factory
from fastapi.exceptions import HTTPException
class TestProducts:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
product_factory.product_public_factory(name="test 1", id=1),
product_factory.product_public_factory(name="test 2", id=2),
product_factory.product_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/products')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
[],
[],
[]
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
product_factory.product_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/products?types=1&names=test 2')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
['test 2'],
[],
['1'],
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.products.service.get_all')
response = client.get('/api/products')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = product_factory.product_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/products/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/products/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.products.service.get_one')
response = client.get('/api/products/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_create_one(self, client, mocker, mock_session, mock_user):
product_body = product_factory.product_body_factory(name='test product create')
product_create = product_factory.product_create_factory(name='test product create')
product_result = product_factory.product_public_factory(name='test product create')
mock = mocker.patch.object(
service,
'create_one',
return_value=product_result
)
response = client.post('/api/products', json=product_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test product create'
mock.assert_called_once_with(
mock_session,
product_create
)
def test_create_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
product_body = product_factory.product_body_factory(name='test product create')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.products.service.create_one')
response = client.post('/api/products', json=product_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_update_one(self, client, mocker, mock_session, mock_user):
product_body = product_factory.product_body_factory(name='test product update')
product_update = product_factory.product_update_factory(name='test product update')
product_result = product_factory.product_public_factory(name='test product update')
mock = mocker.patch.object(
service,
'update_one',
return_value=product_result
)
response = client.put('/api/products/2', json=product_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test product update'
mock.assert_called_once_with(
mock_session,
2,
product_update
)
def test_update_one_notfound(self, client, mocker, mock_session, mock_user):
product_body = product_factory.product_body_factory(name='test product update')
product_update = product_factory.product_update_factory(name='test product update')
product_result = None
mock = mocker.patch.object(
service,
'update_one',
side_effect=exceptions.ProductNotFoundError('Product not found')
)
response = client.put('/api/products/2', json=product_body)
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
product_update
)
def test_update_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
product_body = product_factory.product_body_factory(name='test product update')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.products.service.update_one')
response = client.put('/api/products/2', json=product_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
product_result = product_factory.product_public_factory(name='test product delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=product_result
)
response = client.delete('/api/products/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test product delete'
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
product_result = None
mock = mocker.patch.object(
service,
'delete_one',
side_effect=exceptions.ProductNotFoundError('Product not found')
)
response = client.delete('/api/products/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
product_body = product_factory.product_body_factory(name='test product delete')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.products.service.delete_one')
response = client.delete('/api/products/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,263 @@
import src.shipments.service as service
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.shipments as shipment_factory
from fastapi.exceptions import HTTPException
class TestShipments:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
shipment_factory.shipment_public_factory(name="test 1", id=1),
shipment_factory.shipment_public_factory(name="test 2", id=2),
shipment_factory.shipment_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/shipments')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
[],
[],
[],
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
shipment_factory.shipment_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/shipments?dates=2025-10-10&names=test 2&forms=contract form 1')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
mock_user,
['test 2'],
['2025-10-10'],
['contract form 1'],
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.shipments.service.get_all')
response = client.get('/api/shipments')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = shipment_factory.shipment_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/shipments/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/shipments/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.shipments.service.get_one')
response = client.get('/api/shipments/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_create_one(self, client, mocker, mock_session, mock_user):
shipment_body = shipment_factory.shipment_body_factory(name='test shipment create')
shipment_create = shipment_factory.shipment_create_factory(name='test shipment create')
shipment_result = shipment_factory.shipment_public_factory(name='test shipment create')
mock = mocker.patch.object(
service,
'create_one',
return_value=shipment_result
)
response = client.post('/api/shipments', json=shipment_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test shipment create'
mock.assert_called_once_with(
mock_session,
shipment_create
)
def test_create_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
shipment_body = shipment_factory.shipment_body_factory(name='test shipment create')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.shipments.service.create_one')
response = client.post('/api/shipments', json=shipment_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_update_one(self, client, mocker, mock_session, mock_user):
shipment_body = shipment_factory.shipment_body_factory(name='test shipment update')
shipment_update = shipment_factory.shipment_update_factory(name='test shipment update')
shipment_result = shipment_factory.shipment_public_factory(name='test shipment update')
mock = mocker.patch.object(
service,
'update_one',
return_value=shipment_result
)
response = client.put('/api/shipments/2', json=shipment_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test shipment update'
mock.assert_called_once_with(
mock_session,
2,
shipment_update
)
def test_update_one_notfound(self, client, mocker, mock_session, mock_user):
shipment_body = shipment_factory.shipment_body_factory(name='test shipment update')
shipment_update = shipment_factory.shipment_update_factory(name='test shipment update')
shipment_result = None
mock = mocker.patch.object(
service,
'update_one',
return_value=shipment_result
)
response = client.put('/api/shipments/2', json=shipment_body)
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
shipment_update
)
def test_update_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
shipment_body = shipment_factory.shipment_body_factory(name='test shipment update')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.shipments.service.update_one')
response = client.put('/api/shipments/2', json=shipment_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
shipment_result = shipment_factory.shipment_public_factory(name='test shipment delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=shipment_result
)
response = client.delete('/api/shipments/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test shipment delete'
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
shipment_result = None
mock = mocker.patch.object(
service,
'delete_one',
return_value=shipment_result
)
response = client.delete('/api/shipments/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
shipment_body = shipment_factory.shipment_body_factory(name='test shipment delete')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.shipments.service.delete_one')
response = client.delete('/api/shipments/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,259 @@
import src.users.service as service
import src.models as models
from src.main import app
from src.auth.auth import get_current_user
import tests.factories.users as user_factory
from fastapi.exceptions import HTTPException
class TestUsers:
def test_get_all(self, client, mocker, mock_session, mock_user):
mock_results = [
user_factory.user_public_factory(name="test 1", id=1),
user_factory.user_public_factory(name="test 2", id=2),
user_factory.user_public_factory(name="test 3", id=3),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/users')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 1
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
[],
[],
)
def test_get_all_filters(self, client, mocker, mock_session, mock_user):
mock_results = [
user_factory.user_public_factory(name="test 2", id=2),
]
mock = mocker.patch.object(
service,
'get_all',
return_value=mock_results
)
response = client.get('/api/users?emails=test@test.test&names=test 2')
response_data = response.json()
assert response.status_code == 200
assert response_data[0]['id'] == 2
assert len(response_data) == len(mock_results)
mock.assert_called_once_with(
mock_session,
['test 2'],
['test@test.test'],
)
def test_get_all_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.users.service.get_all')
response = client.get('/api/users')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_get_one(self, client, mocker, mock_session, mock_user):
mock_result = user_factory.user_public_factory(name="test 2", id=2)
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/users/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['id'] == 2
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_notfound(self, client, mocker, mock_session, mock_user):
mock_result = None
mock = mocker.patch.object(
service,
'get_one',
return_value=mock_result
)
response = client.get('/api/users/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2
)
def test_get_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.users.service.get_one')
response = client.get('/api/users/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_create_one(self, client, mocker, mock_session, mock_user):
user_body = user_factory.user_body_factory(name='test user create')
user_create = user_factory.user_create_factory(name='test user create')
user_result = user_factory.user_public_factory(name='test user create')
mock = mocker.patch.object(
service,
'create_one',
return_value=user_result
)
response = client.post('/api/users', json=user_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test user create'
mock.assert_called_once_with(
mock_session,
user_create
)
def test_create_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
user_body = user_factory.user_body_factory(name='test user create')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.users.service.create_one')
response = client.post('/api/users', json=user_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_update_one(self, client, mocker, mock_session, mock_user):
user_body = user_factory.user_body_factory(name='test user update')
user_update = user_factory.user_update_factory(name='test user update')
user_result = user_factory.user_public_factory(name='test user update')
mock = mocker.patch.object(
service,
'update_one',
return_value=user_result
)
response = client.put('/api/users/2', json=user_body)
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test user update'
mock.assert_called_once_with(
mock_session,
2,
user_update
)
def test_update_one_notfound(self, client, mocker, mock_session, mock_user):
user_body = user_factory.user_body_factory(name='test user update')
user_update = user_factory.user_update_factory(name='test user update')
user_result = None
mock = mocker.patch.object(
service,
'update_one',
return_value=user_result
)
response = client.put('/api/users/2', json=user_body)
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
user_update
)
def test_update_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
user_body = user_factory.user_body_factory(name='test user update')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.users.service.update_one')
response = client.put('/api/users/2', json=user_body)
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()
def test_delete_one(self, client, mocker, mock_session, mock_user):
user_result = user_factory.user_public_factory(name='test user delete')
mock = mocker.patch.object(
service,
'delete_one',
return_value=user_result
)
response = client.delete('/api/users/2')
response_data = response.json()
assert response.status_code == 200
assert response_data['name'] == 'test user delete'
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_notfound(self, client, mocker, mock_session, mock_user):
user_result = None
mock = mocker.patch.object(
service,
'delete_one',
return_value=user_result
)
response = client.delete('/api/users/2')
response_data = response.json()
assert response.status_code == 404
mock.assert_called_once_with(
mock_session,
2,
)
def test_delete_one_unauthorized(self, client, mocker, mock_session, mock_user):
def unauthorized():
raise HTTPException(status_code=401)
user_body = user_factory.user_body_factory(name='test user delete')
app.dependency_overrides[get_current_user] = unauthorized
mock = mocker.patch('src.users.service.delete_one')
response = client.delete('/api/users/2')
assert response.status_code == 401
mock.assert_not_called()
app.dependency_overrides.clear()

View File

@@ -0,0 +1,154 @@
import pytest
from sqlmodel import Session
import src.models as models
import src.forms.service as forms_service
import src.forms.exceptions as forms_exceptions
import tests.factories.forms as forms_factory
class TestFormsService:
def test_get_all_forms(self, session: Session, forms: list[models.FormPublic]):
result = forms_service.get_all(session, [], [], False)
assert len(result) == 2
assert result == forms
def test_get_all_forms_filter_productors(self, session: Session, forms: list[models.FormPublic]):
result = forms_service.get_all(session, [], ['test productor'], False)
assert len(result) == 2
assert result == forms
def test_get_all_forms_filter_season(self, session: Session, forms: list[models.FormPublic]):
result = forms_service.get_all(session, ['test season 1'], [], False)
assert len(result) == 1
def test_get_all_forms_all_filters(self, session: Session, forms: list[models.FormPublic]):
result = forms_service.get_all(session, ['test season 1'], ['test productor'], True)
assert result == forms
def test_get_one_form(self, session: Session, forms: list[models.FormPublic]):
result = forms_service.get_one(session, forms[0].id)
assert result == forms[0]
def test_get_one_form_notfound(self, session: Session):
result = forms_service.get_one(session, 122)
assert result == None
def test_create_form(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic
):
form_create = forms_factory.form_create_factory(
name="new test form",
productor_id=productor.id,
referer=referer.id,
season="new test season",
)
result = forms_service.create_one(session, form_create)
assert result.id is not None
assert result.name == "new test form"
assert result.productor.name == "test productor"
def test_create_form_invalidinput(
self,
session: Session,
productor: models.Productor
):
form_create = None
with pytest.raises(forms_exceptions.FormCreateError):
result = forms_service.create_one(session, form_create)
form_create = forms_factory.form_create_factory(productor_id=123)
with pytest.raises(forms_exceptions.ProductorNotFoundError):
result = forms_service.create_one(session, form_create)
form_create = forms_factory.form_create_factory(
productor_id=productor.id,
referer_id=123
)
with pytest.raises(forms_exceptions.UserNotFoundError):
result = forms_service.create_one(session, form_create)
def test_update_form(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic,
forms: list[models.FormPublic]
):
form_update = forms_factory.form_update_factory(
name='updated test form',
productor_id=productor.id,
referer_id=referer.id,
season='updated test season'
)
form_id = forms[0].id
result = forms_service.update_one(session, form_id, form_update)
assert result.id == form_id
assert result.name == 'updated test form'
assert result.season == 'updated test season'
def test_update_form_notfound(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic,
):
form_update = forms_factory.form_update_factory(
name='updated test form',
productor_id=productor.id,
referer_id=referer.id,
season='updated test season'
)
form_id = 123
with pytest.raises(forms_exceptions.FormNotFoundError):
result = forms_service.update_one(session, form_id, form_update)
def test_update_form_invalidinput(
self,
session: Session,
productor: models.ProductorPublic,
forms: list[models.FormPublic]
):
form_id = forms[0].id
form_update = forms_factory.form_update_factory(productor_id=123)
with pytest.raises(forms_exceptions.ProductorNotFoundError):
result = forms_service.update_one(session, form_id, form_update)
form_update = forms_factory.form_update_factory(
productor_id=productor.id,
referer_id=123
)
with pytest.raises(forms_exceptions.UserNotFoundError):
result = forms_service.update_one(session, form_id, form_update)
def test_delete_form(
self,
session: Session,
forms: list[models.FormPublic]
):
form_id = forms[0].id
result = forms_service.delete_one(session, form_id)
check = forms_service.get_one(session, form_id)
assert check == None
def test_delete_form_notfound(
self,
session: Session,
forms: list[models.FormPublic]
):
form_id = 123
with pytest.raises(forms_exceptions.FormNotFoundError):
result = forms_service.delete_one(session, form_id)

View File

@@ -0,0 +1,143 @@
import pytest
from sqlmodel import Session
import src.models as models
import src.productors.service as productors_service
import src.productors.exceptions as productors_exceptions
import tests.factories.productors as productors_factory
class TestProductorsService:
def test_get_all_productors(
self,
session: Session,
productors: list[models.ProductorPublic],
user: models.UserPublic
):
result = productors_service.get_all(session, user, [], [])
assert len(result) == 1
assert result == [productors[0]]
def test_get_all_productors_filter_names(
self,
session: Session,
productors: list[models.ProductorPublic],
user: models.UserPublic
):
result = productors_service.get_all(
session,
user,
['test productor 1'],
[]
)
assert len(result) == 1
def test_get_all_productors_filter_types(
self,
session: Session,
productors: list[models.ProductorPublic],
user: models.UserPublic
):
result = productors_service.get_all(
session,
user,
[],
['Légumineuses'],
)
assert len(result) == 1
def test_get_all_productors_all_filters(
self,
session: Session,
productors: list[models.ProductorPublic],
user: models.UserPublic
):
result = productors_service.get_all(
session,
user,
['test productor 1'],
['Légumineuses'],
)
assert len(result) == 1
def test_get_one_productor(self, session: Session, productors: list[models.ProductorPublic]):
result = productors_service.get_one(session, productors[0].id)
assert result == productors[0]
def test_get_one_productor_notfound(self, session: Session):
result = productors_service.get_one(session, 122)
assert result == None
def test_create_productor(
self,
session: Session,
referer: models.ProductorPublic
):
productor_create = productors_factory.productor_create_factory(
name="new test productor",
)
result = productors_service.create_one(session, productor_create)
assert result.id is not None
assert result.name == "new test productor"
def test_create_productor_invalidinput(
self,
session: Session,
):
productor_create = None
with pytest.raises(productors_exceptions.ProductorCreateError):
result = productors_service.create_one(session, productor_create)
def test_update_productor(
self,
session: Session,
referer: models.ProductorPublic,
productors: list[models.ProductorPublic]
):
productor_update = productors_factory.productor_update_factory(
name='updated test productor',
)
productor_id = productors[0].id
result = productors_service.update_one(session, productor_id, productor_update)
assert result.id == productor_id
assert result.name == 'updated test productor'
def test_update_productor_notfound(
self,
session: Session,
referer: models.ProductorPublic,
):
productor_update = productors_factory.productor_update_factory(
name='updated test productor',
)
productor_id = 123
with pytest.raises(productors_exceptions.ProductorNotFoundError):
result = productors_service.update_one(session, productor_id, productor_update)
def test_delete_productor(
self,
session: Session,
productors: list[models.ProductorPublic]
):
productor_id = productors[0].id
result = productors_service.delete_one(session, productor_id)
check = productors_service.get_one(session, productor_id)
assert check == None
def test_delete_productor_notfound(
self,
session: Session,
productors: list[models.ProductorPublic]
):
productor_id = 123
with pytest.raises(productors_exceptions.ProductorNotFoundError):
result = productors_service.delete_one(session, productor_id)

View File

@@ -0,0 +1,191 @@
import pytest
from sqlmodel import Session
import src.models as models
import src.products.service as products_service
import src.products.exceptions as products_exceptions
import tests.factories.products as products_factory
class TestProductsService:
def test_get_all_products(
self,
session: Session,
products: list[models.ProductPublic],
user: models.UserPublic
):
result = products_service.get_all(session, user, [], [], [])
assert len(result) == 2
assert result == products
def test_get_all_products_filter_productors(
self,
session: Session,
products: list[models.ProductPublic],
user: models.UserPublic
):
result = products_service.get_all(
session,
user,
[],
['test productor'],
[]
)
assert len(result) == 2
assert result == products
def test_get_all_products_filter_names(
self,
session: Session,
products: list[models.ProductPublic],
user: models.UserPublic
):
result = products_service.get_all(
session,
user,
['product 1 occasionnal'],
[],
[]
)
assert len(result) == 1
def test_get_all_products_filter_types(
self,
session: Session,
products: list[models.ProductPublic],
user: models.UserPublic
):
result = products_service.get_all(
session,
user,
[],
[],
['1']
)
assert len(result) == 1
def test_get_all_products_all_filters(
self,
session: Session,
products: list[models.ProductPublic],
user: models.UserPublic
):
result = products_service.get_all(
session,
user,
['product 1 occasionnal'],
['test productor'],
['1']
)
assert len(result) == 1
def test_get_one_product(self, session: Session, products: list[models.ProductPublic]):
result = products_service.get_one(session, products[0].id)
assert result == products[0]
def test_get_one_product_notfound(self, session: Session):
result = products_service.get_one(session, 122)
assert result == None
def test_create_product(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic
):
product_create = products_factory.product_create_factory(
name="new test product",
productor_id=productor.id,
)
result = products_service.create_one(session, product_create)
assert result.id is not None
assert result.name == "new test product"
assert result.productor.name == "test productor"
def test_create_product_invalidinput(
self,
session: Session,
productor: models.Productor
):
product_create = None
with pytest.raises(products_exceptions.ProductCreateError):
result = products_service.create_one(session, product_create)
product_create = products_factory.product_create_factory(productor_id=123)
with pytest.raises(products_exceptions.ProductorNotFoundError):
result = products_service.create_one(session, product_create)
def test_update_product(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic,
products: list[models.ProductPublic]
):
product_update = products_factory.product_update_factory(
name='updated test product',
productor_id=productor.id,
)
product_id = products[0].id
result = products_service.update_one(session, product_id, product_update)
assert result.id == product_id
assert result.name == 'updated test product'
def test_update_product_notfound(
self,
session: Session,
productor: models.ProductorPublic,
referer: models.ProductorPublic,
):
product_update = products_factory.product_update_factory(
name='updated test product',
productor_id=productor.id,
)
product_id = 123
with pytest.raises(products_exceptions.ProductNotFoundError):
result = products_service.update_one(session, product_id, product_update)
def test_update_product_invalidinput(
self,
session: Session,
productor: models.ProductorPublic,
products: list[models.ProductPublic]
):
product_id = products[0].id
product_update = products_factory.product_update_factory(productor_id=123)
with pytest.raises(products_exceptions.ProductorNotFoundError):
result = products_service.update_one(session, product_id, product_update)
product_update = products_factory.product_update_factory(
productor_id=productor.id,
referer_id=123
)
def test_delete_product(
self,
session: Session,
products: list[models.ProductPublic]
):
product_id = products[0].id
result = products_service.delete_one(session, product_id)
check = products_service.get_one(session, product_id)
assert check == None
def test_delete_product_notfound(
self,
session: Session,
products: list[models.ProductPublic]
):
product_id = 123
with pytest.raises(products_exceptions.ProductNotFoundError):
result = products_service.delete_one(session, product_id)