Skip to content

Commit

Permalink
Add editing of meal donations. (#126)
Browse files Browse the repository at this point in the history

Co-authored-by: Shahan Neda <[email protected]>
  • Loading branch information
jho426 and shahanneda authored May 18, 2024
1 parent 8d7ddf7 commit e7254e4
Show file tree
Hide file tree
Showing 17 changed files with 783 additions and 1,514 deletions.
53 changes: 53 additions & 0 deletions backend/app/graphql/meal_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,58 @@ def mutate(
return CreateMealRequests(meal_requests=result)


class UpdateMealRequestDonation(Mutation):
class Arguments:
requestor_id = graphene.ID(required=True)
meal_request_id = graphene.ID(required=True)
meal_description = graphene.String()
additional_info = graphene.String()
donor_onsite_contacts = graphene.List(graphene.String)

meal_request = graphene.Field(MealRequestResponse)

def mutate(
self,
info,
requestor_id: str,
meal_request_id,
meal_description,
additional_info,
donor_onsite_contacts,
):
user_service = services["user_service"]
requestor_auth_id = user_service.get_auth_id_by_user_id(requestor_id)
requestor_role = user_service.get_user_role_by_auth_id(requestor_auth_id)

try:
meal_request = services["meal_request_service"].get_meal_request_by_id(
meal_request_id
)

if not meal_request:
raise Exception("Meal request not found")

if (
requestor_role != "Admin"
and meal_request.donation_info["donor"]["id"] != requestor_id
):
raise Exception(
"Requestor is not an admin or the donor of the meal request."
)

result = services["meal_request_service"].update_meal_request_donation(
requestor_id=requestor_id,
meal_request_id=meal_request_id,
meal_description=meal_description,
additional_info=additional_info,
donor_onsite_contacts=donor_onsite_contacts,
)
except Exception as e:
raise GraphQLError(str(e))

return UpdateMealRequest(meal_request=result)


class UpdateMealRequest(Mutation):
class Arguments:
meal_request_id = graphene.ID(required=True)
Expand Down Expand Up @@ -237,6 +289,7 @@ def mutate(self, info, meal_request_id, requestor_id):
class MealRequestMutations(MutationList):
create_meal_request = CreateMealRequests.Field()
update_meal_request = UpdateMealRequest.Field()
update_meal_request_donation = UpdateMealRequestDonation.Field()
commit_to_meal_request = CommitToMealRequest.Field()
cancel_donation = CancelDonation.Field()
delete_meal_request = DeleteMealRequest.Field()
Expand Down
10 changes: 2 additions & 8 deletions backend/app/models/meal_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,14 @@ def to_serializable_dict(self):
id = meal_request_dict.pop("_id", None)
meal_request_dict["id"] = str(id)

contacts = [contact.to_mongo().to_dict() for contact in self.onsite_contacts]
for contact in contacts:
id = contact.pop("_id")
contact["id"] = id
contacts = [contact.to_serializable_dict() for contact in self.onsite_contacts]
meal_request_dict["onsite_contacts"] = contacts

if self.donation_info and self.donation_info.donor_onsite_contacts:
contacts = [
contact.to_mongo().to_dict()
contact.to_serializable_dict()
for contact in self.donation_info.donor_onsite_contacts
]
for contact in contacts:
id = contact.pop("_id")
contact["id"] = id
meal_request_dict["donation_info"]["donor_onsite_contacts"] = contacts

return meal_request_dict
Expand Down
31 changes: 31 additions & 0 deletions backend/app/services/implementations/meal_request_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,37 @@ def update_meal_request(

return meal_request_dto

def update_meal_request_donation(
self,
requestor_id: str,
meal_request_id,
meal_description: str,
additional_info: str,
donor_onsite_contacts: List[str],
):
original_meal_request = MealRequest.objects(id=meal_request_id).first()
if not original_meal_request:
raise Exception(f'Meal request "{meal_request_id}" not found')

if not original_meal_request.donation_info:
raise Exception("No donation info found")

original_meal_request.donation_info = DonationInfo(
donor=original_meal_request.donation_info.donor,
commitment_date=original_meal_request.donation_info.commitment_date,
meal_description=meal_description,
additional_info=additional_info,
donor_onsite_contacts=donor_onsite_contacts,
)

# Does validation,
meal_request_dto = original_meal_request.to_dto()

original_meal_request.validate_onsite_contacts()
original_meal_request.save()

return meal_request_dto

def commit_to_meal_request(
self,
donor_id: str,
Expand Down
11 changes: 11 additions & 0 deletions backend/app/services/interfaces/meal_request_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ def update_meal_request(
):
pass

@abstractmethod
def update_meal_request_donation(
self,
requestor_id: str,
meal_request_id,
meal_description: str,
additional_info: str,
donor_onsite_contacts: List[str],
):
pass

@abstractmethod
def commit_to_meal_request(
self,
Expand Down
6 changes: 0 additions & 6 deletions backend/package-lock.json

This file was deleted.

17 changes: 13 additions & 4 deletions backend/tests/graphql/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,34 @@ def meal_request_setup(user_setup):
def onsite_contact_setup(user_setup):
asp, donor, _ = user_setup
asp_onsite_contact = OnsiteContact(
name="Sample Contact",
name="Sample ASP Contact",
email="[email protected]",
phone="123-456-7890",
organization_id=asp.id,
).save()
asp_onsite_contact2 = OnsiteContact(
name="Sample Contact 2",
name="Sample ASP Contact 2",
email="[email protected]",
phone="123-456-7890",
organization_id=asp.id,
).save()
donor_onsite_contact = OnsiteContact(
name="Sample Contact 2",
name="Sample Donor Contact 1",
email="[email protected]",
phone="123-333-7890",
organization_id=donor.id,
).save()
donor_onsite_contact2 = OnsiteContact(
name="Sample Donor 2",
email="[email protected]",
phone="123-333-7890",
organization_id=donor.id,
).save()

yield asp, donor, [asp_onsite_contact, asp_onsite_contact2], donor_onsite_contact
yield asp, donor, [asp_onsite_contact, asp_onsite_contact2], [
donor_onsite_contact,
donor_onsite_contact2,
]
asp_onsite_contact.delete()
donor_onsite_contact.delete()

Expand Down
106 changes: 100 additions & 6 deletions backend/tests/graphql/test_meal_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_create_meal_request(meal_request_setup, onsite_contact_setup):
asp,
donor,
[asp_onsite_contact, asp_onsite_contact2],
donor_onsite_contact,
[donor_onsite_contact, donor_onsite_contact2],
) = onsite_contact_setup

mutation = f"""
Expand Down Expand Up @@ -110,7 +110,12 @@ def test_create_meal_request(meal_request_setup, onsite_contact_setup):
def test_create_meal_request_fails_invalid_onsite_contact(
meal_request_setup, onsite_contact_setup
):
asp, donor, asp_onsite_contact, donor_onsite_contact = onsite_contact_setup
(
asp,
donor,
[asp_onsite_contact, asp_onsite_contact2],
[donor_onsite_contact, donor_onsite_contact2],
) = onsite_contact_setup

counter_before = MealRequest.objects().count()
mutation = f"""
Expand Down Expand Up @@ -153,6 +158,90 @@ def test_create_meal_request_fails_invalid_onsite_contact(
assert counter_before == counter_after


def test_update_meal_request_donation(meal_request_setup, onsite_contact_setup):
_, donor, meal_request = meal_request_setup

test_commit_to_meal_request(meal_request_setup)
(
_,
donor,
[asp_onsite_contact, asp_onsite_contact2],
[donor_onsite_contact, donor_onsite_contact2],
) = onsite_contact_setup

mutation = f"""
mutation testUpdateMealRequestDonation {{
updateMealRequestDonation(
requestorId: "{str(donor.id)}",
mealRequestId: "{str(meal_request.id)}",
mealDescription: "potato chicken nugget",
additionalInfo: "kimchi fried rice"
donorOnsiteContacts: ["{str(donor_onsite_contact.id)}", "{str(donor_onsite_contact2.id)}"]
)
{{
mealRequest {{
id
requestor {{
id
}}
status
dropOffDatetime
dropOffLocation
mealInfo {{
portions
dietaryRestrictions
}}
onsiteContacts {{
name
email
phone
}}
dateCreated
dateUpdated
deliveryInstructions
donationInfo {{
donor {{
id
}}
commitmentDate
mealDescription
additionalInfo
}}
}}
}}
}}
"""

result = graphql_schema.execute(mutation)

assert result.errors is None

meal_request_in_db = (
MealRequest.objects(id=meal_request.id).first().to_serializable_dict()
)

assert (
meal_request_in_db["donation_info"]["meal_description"]
== "potato chicken nugget"
)
assert meal_request_in_db["donation_info"]["additional_info"] == "kimchi fried rice"
assert meal_request_in_db["donation_info"]["donor"] == donor.id
meal_request_donor_onsite_contacts = meal_request_in_db["donation_info"][
"donor_onsite_contacts"
]
in_db_contacts_sorted_by_id = sorted(
meal_request_donor_onsite_contacts, key=lambda x: x["id"]
)
expected_contacts_sorted_by_id = sorted(
[
donor_onsite_contact.to_serializable_dict(),
donor_onsite_contact2.to_serializable_dict(),
],
key=lambda x: x["id"],
)
assert in_db_contacts_sorted_by_id == expected_contacts_sorted_by_id


# If a meal request is created with a date that is the
# same as a previous meal request, an error is thrown
def test_create_meal_request_fails_repeat_date(
Expand All @@ -162,7 +251,7 @@ def test_create_meal_request_fails_repeat_date(
asp,
donor,
[asp_onsite_contact, asp_onsite_contact2],
donor_onsite_contact,
[donor_onsite_contact, donor_onsite_contact2],
) = onsite_contact_setup
_, _, meal_request = meal_request_setup

Expand Down Expand Up @@ -347,7 +436,7 @@ def test_commit_to_meal_request_fails_for_non_donor(
meal_request_setup, onsite_contact_setup
):
_, donor, meal_request = meal_request_setup
requestor, _, asp_onsite_contacts, donor_onsite_contact = onsite_contact_setup
requestor, _, asp_onsite_contacts, donor_onsite_contacts = onsite_contact_setup

# All user info roles except for "Donor"
INVALID_USERINFO_ROLES = [UserInfoRole.ADMIN.value, UserInfoRole.ASP.value]
Expand Down Expand Up @@ -418,7 +507,7 @@ def test_commit_to_meal_request_fails_if_not_open(meal_request_setup):


def test_update_meal_request(onsite_contact_setup, meal_request_setup):
requestor, _, asp_onsite_contacts, donor_onsite_contact = onsite_contact_setup
requestor, _, asp_onsite_contacts, donor_onsite_contacts = onsite_contact_setup
_, _, meal_request = meal_request_setup

onsite_contact1 = asp_onsite_contacts[0]
Expand Down Expand Up @@ -862,7 +951,12 @@ def test_delete_meal_request_as_non_admin_fails_if_donor(meal_request_setup):
def test_get_meal_request_by_donor_id(meal_request_setup, onsite_contact_setup):
_, donor, meal_request = meal_request_setup

asp, donor, asp_onsite_contact, donor_onsite_contact = onsite_contact_setup
(
asp,
donor,
[asp_onsite_contact, asp_onsite_contact2],
[donor_onsite_contact, donor_onsite_contact2],
) = onsite_contact_setup

commit = graphql_schema.execute(
f"""mutation testCommitToMealRequest {{
Expand Down
6 changes: 3 additions & 3 deletions backend/tests/graphql/test_onsite_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ def test_create_onsite_contact(onsite_contact_setup):


def test_update_onsite_contact(onsite_contact_setup):
asp, donor, asp_onsite_contacts, donor_onsite_contact = onsite_contact_setup
asp, donor, asp_onsite_contacts, donor_onsite_contacts = onsite_contact_setup

# Test for the update mutation
mutation = f"""
mutation u{{
updateOnsiteContact(
id: "{donor_onsite_contact.id}",
id: "{donor_onsite_contacts[0].id}",
name: "Updated Bob Cat",
email: "[email protected]",
phone: "604-433-2222",
Expand All @@ -78,7 +78,7 @@ def test_update_onsite_contact(onsite_contact_setup):
result = graphql_schema.execute(mutation)
assert result.errors is None
updated_result_contact = result.data["updateOnsiteContact"]["onsiteContact"]
updated_db_result = OnsiteContact.objects(id=donor_onsite_contact["id"]).first()
updated_db_result = OnsiteContact.objects(id=donor_onsite_contacts[0]["id"]).first()

for contact in [updated_result_contact, updated_db_result]:
assert contact["name"] == "Updated Bob Cat"
Expand Down
Loading

0 comments on commit e7254e4

Please sign in to comment.