diff --git a/orders_service/app/api/v1/health.py b/orders_service/app/api/v1/health.py index cad2247..4c894d5 100644 --- a/orders_service/app/api/v1/health.py +++ b/orders_service/app/api/v1/health.py @@ -18,16 +18,15 @@ def get_health(): def get_health_db(db: Annotated[Session, Depends(get_db)]): try: db.execute(text("SELECT 1")) - print("✅ DB connection OK") - finally: - db.close() - return {"status": "OK"} + return {"status": "OK"} + except Exception as e: + return {"status": "ERROR", "detail": str(e)} + @router.get("/db/orders") def get_health_orders(db: Annotated[Session, Depends(get_db)]): try: - r = db.execute(text("SELECT * FROM orders")).fetchall() - print("Data output: ", r) - finally: - db.close() - return {"status": "OK"} + db.execute(text("SELECT * FROM orders")).fetchall() + return {"status": "OK"} + except Exception as e: + return {"status": "ERROR", "detail": str(e)} diff --git a/orders_service/app/api/v1/orders.py b/orders_service/app/api/v1/orders.py index a3e8805..eeb5ecd 100644 --- a/orders_service/app/api/v1/orders.py +++ b/orders_service/app/api/v1/orders.py @@ -19,9 +19,11 @@ def post_order(order : OrderCreate, db: Annotated[Session, Depends(get_db)]): @router.get("/", response_model=OrderListResponse) def get_orders(db: Annotated[Session, Depends(get_db)], name: str | None = None, - product: str | None = None): - orders = crud.get_orders(db ,name, product) - return {"items": orders} + product: str | None = None, + offset: int = 0, + limit: int = 10): + orders, total = crud.get_orders(db ,name, product, offset, limit) + return {"items": orders, "total": total, "limit": limit, "offset": offset} @router.get("/{order_id}", response_model=OrderResponse) def get_order_from_id(order_id: int, db: Annotated[Session, Depends(get_db)]) -> OrderResponse: diff --git a/orders_service/app/db_logic/crud.py b/orders_service/app/db_logic/crud.py index 0421df2..a1928f5 100644 --- a/orders_service/app/db_logic/crud.py +++ b/orders_service/app/db_logic/crud.py @@ -20,8 +20,11 @@ def get_order_by_id(db: Session, order_id: int): return db.query(Order).filter(Order.id == order_id).first() -# TODO: implement pagination -def get_orders(db: Session, name: str | None = None, product: str | None = None): +def get_orders(db: Session, + name: str | None = None, + product: str | None = None, + offset=0, + limit=10): query = db.query(Order) if name: @@ -29,12 +32,14 @@ def get_orders(db: Session, name: str | None = None, product: str | None = None) if product: query = query.filter(Order.product == product) - return query.all() + orders = query.offset(offset).limit(limit).all() + total = query.count() + return orders, total def delete_by_id(db: Session, order_id: int): try: - result = get_order_by_id(db, order_id) + result = get_order_by_id(db, order_id) if not result: return None db.delete(result) diff --git a/orders_service/app/schemas/order.py b/orders_service/app/schemas/order.py index a4d7c0c..12d605a 100644 --- a/orders_service/app/schemas/order.py +++ b/orders_service/app/schemas/order.py @@ -23,6 +23,9 @@ class OrderResponse(OrderBase): class OrderListResponse(BaseModel): items: list[OrderResponse] + total: int + limit: int + offset: int class OrderUpdate(BaseModel): name: str | None = Field(default=None, min_length=2) diff --git a/orders_service/tests/unit/crud/orders_table_test.py b/orders_service/tests/unit/crud/orders_table_test.py index 345ff2d..0b5d1e1 100644 --- a/orders_service/tests/unit/crud/orders_table_test.py +++ b/orders_service/tests/unit/crud/orders_table_test.py @@ -1,4 +1,4 @@ -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session from orders_service.app.db_logic import crud from orders_service.app.models.order import Order @@ -6,7 +6,7 @@ from orders_service.tests.factories.order_factory import OrderFactory -### CREATE TESTS ### +### CREATE TESTS ### def test_create_order(db: Session) -> None: data: Order = OrderFactory.build() new_order = OrderCreate( @@ -57,55 +57,77 @@ def test_get_order_by_id_not_found(db: Session) -> None: def test_get_orders_all(db: Session) -> None: OrderFactory.create_batch(50) - retrieved_orders = crud.get_orders(db=db) - assert len(retrieved_orders) == 50 + orders, total = crud.get_orders(db=db, limit=50) + assert len(orders) == 50 + assert total == 50 + +def test_get_orders_paginated_fetches_all(db: Session) -> None: + OrderFactory.create_batch(25) + page_size = 10 + offset = 0 + all_orders = [] + + while True: + orders, total = crud.get_orders(db, limit=page_size, offset=offset) + all_orders.extend(orders) + offset += page_size + if offset >= total: + break + + assert len(all_orders) == 25 + assert len(set(order.id for order in all_orders)) == 25 def test_get_orders_empty_db(db: Session) -> None: - retrieved_orders = crud.get_orders(db=db) - assert retrieved_orders == [] + orders, total = crud.get_orders(db=db) + assert orders == [] + assert total == 0 def test_get_orders_by_name(db: Session) -> None: target = "target_customer" OrderFactory.create_batch(15, name="buffer customer") OrderFactory.create_batch(10, name=target) - retrieved_orders = crud.get_orders(db=db, name=target) - assert len(retrieved_orders) == 10 - assert all(order.name == target for order in retrieved_orders) + orders, total = crud.get_orders(db=db, name=target) + assert len(orders) == 10 + assert total == 10 + assert all(order.name == target for order in orders) def test_get_orders_by_product(db: Session) -> None: target = "target_product" OrderFactory.create_batch(15, product="buffer product") OrderFactory.create_batch(10, product=target) - retrieved_orders = crud.get_orders(db=db, product=target) - assert len(retrieved_orders) == 10 - assert all(order.product == target for order in retrieved_orders) + orders, total = crud.get_orders(db=db, product=target) + assert len(orders) == 10 + assert total == 10 + assert all(order.product == target for order in orders) def test_get_orders_by_all_filters(db: Session) -> None: target_name = "target_customer" target_product = "target_product" - + OrderFactory.create_batch(5, name="temp customer", product="temp product") OrderFactory.create_batch(10, name=target_name, product="temp product 2") OrderFactory.create_batch(12, name="temp customer 2", product=target_product) OrderFactory.create_batch(6, name=target_name, product=target_product) - retrieved_orders = crud.get_orders(db=db, name=target_name, product=target_product) - assert len(retrieved_orders) == 6 - assert all(order.name == target_name for order in retrieved_orders) - assert all(order.product == target_product for order in retrieved_orders) + orders, total = crud.get_orders(db=db, name=target_name, product=target_product) + assert len(orders) == 6 + assert total == 6 + assert all(order.name == target_name for order in orders) + assert all(order.product == target_product for order in orders) def test_get_orders_by_filters_no_match(db: Session) -> None: target_name = "target_customer" target_product = "target_product" - + OrderFactory.create_batch(5, name="temp customer", product="temp product") OrderFactory.create_batch(10, name=target_name, product="temp product 2") OrderFactory.create_batch(12, name="temp customer 2", product=target_product) - retrieved_orders = crud.get_orders(db=db, name=target_name, product=target_product) - assert retrieved_orders == [] + orders, total = crud.get_orders(db=db, name=target_name, product=target_product) + assert orders == [] + assert total == 0 @@ -178,7 +200,7 @@ def test_delete_by_id(db: Session, fixture_order: Order) -> None: result = crud.delete_by_id(db, order_id=fixture_order.id) assert result assert result.id == fixture_order.id - + deleted = db.query(Order).filter(Order.id == fixture_order.id).first() assert deleted is None