-
Notifications
You must be signed in to change notification settings - Fork 61
Nullable fields fixed, donors special case fixed #194
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spec changes look reasonable to me, but I'm a bit unsure about donor POST representing create or update.
I get the rationale that a 4xx error followed by a PATCH is an extra round trip, but this feels like a snowflake.
Should we document a design philosophy that POST where we specify a unique property that already exists that we treat it like a PUT? If so this seems like it should have a follow-up to cover approvers too.
@engelke request: would you mind splitting this up into two commits - one with your changes, and one with the generated ones? (At least for me, that would make this easier to navigate.) |
For reviewers:
This also incorporates the content-api updates from #109, which I'm going to close unmerged. That PR also has some website fixes that I think Ace has handled in a separate PR. So this isn't as horrible as it looks. |
Committed by mistake
# Tear down test data | ||
db.delete("causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None) | ||
for email_address in [EMAIL, "nobody@example.com"]: | ||
db.delete("campaigns", TEST_CAMPAIGN[email_address]["id"], resource_fields["campaigns"], None, host_url=None) | ||
db.delete("donors", TEST_DONOR[email_address]["id"], resource_fields["donors"], None, host_url=None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Tear down test data | |
db.delete("causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None) | |
for email_address in [EMAIL, "nobody@example.com"]: | |
db.delete("campaigns", TEST_CAMPAIGN[email_address]["id"], resource_fields["campaigns"], None, host_url=None) | |
db.delete("donors", TEST_DONOR[email_address]["id"], resource_fields["donors"], None, host_url=None) | |
# Tear down test data | |
db.delete( | |
"causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None | |
) | |
db.delete( | |
"campaigns", | |
TEST_CAMPAIGN[email_address]["id"], | |
resource_fields["campaigns"], | |
None, | |
host_url=None, | |
) | |
db.delete( | |
"donors", | |
TEST_DONOR[email_address]["id"], | |
resource_fields["donors"], | |
None, | |
host_url=None, | |
) | |
db.delete( | |
"donations", | |
TEST_DONATION[email_address]["id"], | |
resource_fields["causes"], | |
None, | |
host_url=None, | |
) |
r = client.delete("/donations/{}".format(donation["id"]), headers=headers) | ||
assert r.status_code == 204 | ||
r = client.delete("/donors/{}".format(donor["id"]), headers=headers) | ||
assert r.status_code == 204 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert r.status_code == 204 | |
assert r.status_code == 204 |
@grayside There are some clumsy behaviors necessitated by missing functionality in the generated client libraries. However, I will add them to the emblem_api in a future PR, at which time we can eliminate the special POST /donors behavior and provide a way to see "synthetic" fields like the total donations in a campaign. |
# Tear down test data | ||
db.delete("causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None) | ||
for email_address in [EMAIL, "nobody@example.com"]: | ||
db.delete("campaigns", TEST_CAMPAIGN[email_address]["id"], resource_fields["campaigns"], None, host_url=None) | ||
db.delete("donors", TEST_DONOR[email_address]["id"], resource_fields["donors"], None, host_url=None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Tear down test data | |
db.delete("causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None) | |
for email_address in [EMAIL, "nobody@example.com"]: | |
db.delete("campaigns", TEST_CAMPAIGN[email_address]["id"], resource_fields["campaigns"], None, host_url=None) | |
db.delete("donors", TEST_DONOR[email_address]["id"], resource_fields["donors"], None, host_url=None) | |
# Tear down test data | |
db.delete( | |
"causes", TEST_CAUSE["id"], resource_fields["causes"], None, host_url=None | |
) | |
db.delete( | |
"campaigns", | |
TEST_CAMPAIGN[email_address]["id"], | |
resource_fields["campaigns"], | |
None, | |
host_url=None, | |
) | |
db.delete( | |
"donors", | |
TEST_DONOR[email_address]["id"], | |
resource_fields["donors"], | |
None, | |
host_url=None, | |
) | |
db.delete( | |
"donations", | |
TEST_DONATION[email_address]["id"], | |
resource_fields["causes"], | |
None, | |
host_url=None, | |
) |
r = client.delete("/donations/{}".format(donation["id"]), headers=headers) | ||
assert r.status_code == 204 | ||
r = client.delete("/donors/{}".format(donor["id"]), headers=headers) | ||
assert r.status_code == 204 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert r.status_code == 204 | |
assert r.status_code == 204 |
The API server allowed some fields to be Null (None in Python) but the openapi.yaml spec did not note that, so the client libraries threw exceptions. The openapi.yaml spec has been corrected.
The donors resource is a special case: the non-id attribute "email" should be unique in the collection. The "insert" operation for donors now checks to see if there is a donor with a matching email and, if so, updates the existing donor instead of creating a new one.
This helps API clients that want to create a donation, and need to know the donor ID for that. They can just POST a donor and get back the resource representation.