Skip to content

Commit

Permalink
feat: add endpoint to update price (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sudhanva-Nadiger committed Feb 23, 2024
1 parent f401777 commit a4b66a6
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
37 changes: 37 additions & 0 deletions app/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,43 @@ def delete_price(
return


@app.put(
path="/api/v1/prices/{price_id}",
response_model=schemas.PriceFull,
status_code=status.HTTP_200_OK,
tags=["Prices"],
)
def update_price(
price_id: int,
new_price: schemas.PriceBasicUpdatableFields,
current_user: schemas.UserCreate = Depends(get_current_user),
db: Session = Depends(get_db),
):
"""
Update a price.
This endpoint requires authentication.
A user can update only owned prices.
"""
# fetch price with id = price_id
db_price = crud.get_price_by_id(db, id=price_id)

if not db_price:
raise HTTPException(
status_code=404,
detail=f"Price with code {price_id} not found",
)
# Check if the price belongs to the current user
if db_price.owner != current_user.user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Price does not belong to current user",
)

# updated price
return crud.update_price(db, db_price, new_price)


# Routes: Proofs
# ------------------------------------------------------------------------------
@app.get("/api/v1/proofs", response_model=Page[schemas.ProofFull], tags=["Proofs"])
Expand Down
9 changes: 9 additions & 0 deletions app/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
LocationCreate,
LocationFilter,
LocationFull,
PriceBasicUpdatableFields,
PriceCreate,
PriceFilter,
PriceFull,
Expand Down Expand Up @@ -331,6 +332,14 @@ def delete_price(db: Session, db_price: PriceFull) -> bool:
return True


def update_price(db: Session, price: Price, new_values: PriceBasicUpdatableFields):
for [key, value] in new_values:
setattr(price, key, value)
db.commit()
db.refresh(price)
return price


# Proofs
# ------------------------------------------------------------------------------
def get_proofs_query(filters: ProofFilter | None = None):
Expand Down
9 changes: 9 additions & 0 deletions app/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,15 @@ def check_price_discount(self):
return self


class PriceBasicUpdatableFields(BaseModel):
price: float | None
price_is_discounted: bool | None
price_without_discount: float | None
price_per: PricePerEnum | None
currency: CurrencyEnum | None
date: datetime.date | None


class PriceFull(PriceCreate):
id: int
product_id: int | None
Expand Down
52 changes: 52 additions & 0 deletions tests/integration/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from app.models import Session as SessionModel
from app.schemas import (
LocationCreate,
PriceBasicUpdatableFields,
PriceCreate,
ProductCreate,
ProofFilter,
Expand Down Expand Up @@ -608,6 +609,57 @@ def test_delete_price(db_session, user_session: SessionModel, clean_prices):
assert response.status_code == 204


def test_update_price(db_session, user_session: SessionModel):
db_price = crud.create_price(db_session, PRICE_1, user_session.user)
# without authentication
response = client.put(f"/api/v1/prices/{db_price.id}")
assert response.status_code == 401

# with authentication but not price owner
user_1_session, *_ = crud.create_session(db_session, USER_1.user_id, USER_1.token)
response = client.put(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_1_session.token}"},
)
assert response.status_code == 403
# with authentication but price unknown
response = client.put(
f"/api/v1/prices/{db_price.id+1}",
headers={"Authorization": f"Bearer {user_session.token}"},
)
assert response.status_code == 404

# with authentication and price owner

# if any field which is not is basic updatable field provided
# it should throw an error
price_fields = {
"proof_id": 1,
"new_price": 5.5,
}

response = client.put(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_session.token}"},
json=jsonable_encoder(price_fields),
)

assert response.status_code == 422 # Unprocessable Entity

new_price = 5.5
price_updatable_fields = PriceBasicUpdatableFields(price=new_price)

response = client.put(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_session.token}"},
json=jsonable_encoder(price_updatable_fields),
)

assert response.status_code == 200

assert response.json()["price"] == new_price


# Test proofs
# ------------------------------------------------------------------------------
def test_create_proof(user_session: SessionModel, clean_proofs):
Expand Down

0 comments on commit a4b66a6

Please sign in to comment.