Skip to content

Commit

Permalink
feat(prices): allow moderators to edit prices (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphodn committed Mar 18, 2024
1 parent 68f0b6c commit dcb463b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
9 changes: 6 additions & 3 deletions app/routers/prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ def update_price(
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:
# Check if the price belongs to the current user,
# if it doesn't, the user needs to be a moderator
if db_price.owner != current_user.user_id and not current_user.is_moderator:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Price does not belong to current user",
Expand All @@ -163,8 +164,9 @@ def delete_price(
This endpoint requires authentication.
A user can delete only owned prices.
"""
# fetch price with id = price_id
db_price = crud.get_price_by_id(db, id=price_id)
# get price

if not db_price:
raise HTTPException(
status_code=404,
Expand All @@ -176,6 +178,7 @@ def delete_price(
status_code=status.HTTP_403_FORBIDDEN,
detail="Price does not belong to current user",
)

# delete price
crud.delete_price(db, db_price=db_price)
return None
13 changes: 8 additions & 5 deletions app/routers/proofs.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,22 @@ def get_user_proof_by_id(
current_user: schemas.UserCreate = Depends(get_current_user),
db: Session = Depends(get_db),
) -> Proof:
# get proof
# fetch proof with id = proof_id
db_proof = crud.get_proof_by_id(db, id=proof_id)

if not db_proof:
raise HTTPException(
status_code=404,
detail=f"Proof with id {proof_id} not found",
)
# Check if the proof belongs to the current user,
# if it doesn't, the user needs to be moderator
# if it doesn't, the user needs to be a moderator
if db_proof.owner != current_user.user_id and not current_user.is_moderator:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Proof does not belong to current user",
)

return db_proof


Expand Down Expand Up @@ -119,7 +121,7 @@ def update_proof(
detail=f"Proof with id {proof_id} not found",
)
# Check if the proof belongs to the current user,
# if it doesn't, the user needs to be moderator
# if it doesn't, the user needs to be a moderator
if db_proof.owner != current_user.user_id and not current_user.is_moderator:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
Expand Down Expand Up @@ -147,15 +149,16 @@ def delete_proof(
Can delete only proofs that are not associated with prices.
A moderator can delete not owned proofs.
"""
# get proof
# fetch proof with id = proof_id
db_proof = crud.get_proof_by_id(db, id=proof_id)

if not db_proof:
raise HTTPException(
status_code=404,
detail=f"Proof with code {proof_id} not found",
)
# Check if the proof belongs to the current user,
# if it doesn't, the user needs to be moderator
# if it doesn't, the user needs to be a moderator
if db_proof.owner != current_user.user_id and not current_user.is_moderator:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
Expand Down
64 changes: 58 additions & 6 deletions tests/integration/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,18 +654,22 @@ def test_get_prices_orders(db_session, user_session: SessionModel, clean_prices)
assert (response.json()["items"][0]["date"]) == "2023-10-31"


def test_update_price(db_session, user_session: SessionModel):
def test_update_price(
db_session, user_session: SessionModel, user_session_1: SessionModel, clean_prices
):
# create price
db_price = crud.create_price(db_session, PRICE_1, user_session.user)

new_price = 5.5
PRICE_UPDATE_PARTIAL = {"price": new_price}
# without authentication
response = client.patch(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)
crud.update_user_moderator(db_session, user_session_1.user_id, False)
response = client.patch(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_1_session.token}"},
headers={"Authorization": f"Bearer {user_session_1.token}"},
json=jsonable_encoder(PRICE_UPDATE_PARTIAL),
)
assert response.status_code == 403
Expand Down Expand Up @@ -713,16 +717,39 @@ def test_update_price(db_session, user_session: SessionModel):
assert response.status_code == 422


def test_delete_price(db_session, user_session: SessionModel, clean_prices):
def test_update_price_moderator(
db_session, user_session: SessionModel, user_session_1: SessionModel, clean_prices
):
# create price
db_price = crud.create_price(db_session, PRICE_1, user_session.user)

new_price = 5.5
PRICE_UPDATE_PARTIAL = {"price": new_price}

# user_1 is moderator, not owner
crud.update_user_moderator(db_session, USER_1.user_id, True)
response = client.patch(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_session_1.token}"},
json=jsonable_encoder(PRICE_UPDATE_PARTIAL),
)
assert response.status_code == 200
assert response.json()["price"] == new_price
assert response.json()["price_is_discounted"] == PRICE_1.price_is_discounted
assert response.json()["price_without_discount"] == PRICE_1.price_without_discount


def test_delete_price(
db_session, user_session: SessionModel, user_session_1: SessionModel, clean_prices
):
db_price = crud.create_price(db_session, PRICE_1, user_session.user)
# without authentication
response = client.delete(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.delete(
f"/api/v1/prices/{db_price.id}",
headers={"Authorization": f"Bearer {user_1_session.token}"},
headers={"Authorization": f"Bearer {user_session_1.token}"},
)
assert response.status_code == 403
# with authentication but price unknown
Expand Down Expand Up @@ -975,6 +1002,31 @@ def test_update_proof(
assert response.status_code == 422


def test_update_proof_moderator(
db_session, user_session: SessionModel, user_session_1: SessionModel, clean_proofs
):
# create proof
response = client.post(
"/api/v1/proofs/upload",
files={"file": ("filename", (io.BytesIO(b"test")), "image/webp")},
data={"type": "PRICE_TAG"},
headers={"Authorization": f"Bearer {user_session.token}"},
)
assert response.status_code == 201
proof = crud.get_proof_by_id(db_session, response.json().get("id"))

PROOF_UPDATE_PARTIAL = {"is_public": False}

# user_1 is moderator, not owner
crud.update_user_moderator(db_session, USER_1.user_id, True)
response = client.patch(
f"/api/v1/proofs/{proof.id}",
headers={"Authorization": f"Bearer {user_session_1.token}"},
json=jsonable_encoder(PROOF_UPDATE_PARTIAL),
)
assert response.status_code == 200


def test_delete_proof(
db_session,
user_session: SessionModel,
Expand Down

0 comments on commit dcb463b

Please sign in to comment.