Skip to content

Commit a08439e

Browse files
committed
feat: ensure name/organization are not both null on update
1 parent 8ca80e1 commit a08439e

4 files changed

Lines changed: 86 additions & 1 deletion

File tree

api/contact.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,41 @@ async def update_contact(
307307
:param session: Database session
308308
:return: Updated contact response
309309
"""
310+
contact = simple_get_by_id(session, Contact, contact_id)
311+
312+
if (
313+
contact.name is None
314+
and contact_data.name is None
315+
and contact_data.organization is None
316+
):
317+
raise PydanticStyleException(
318+
status_code=status.HTTP_409_CONFLICT,
319+
detail=[
320+
{
321+
"loc": ["body", "organization"],
322+
"msg": "organization cannot be None if name is None.",
323+
"type": "value_error",
324+
"input": {"organization": contact_data.organization},
325+
}
326+
],
327+
)
328+
elif (
329+
contact.organization is None
330+
and contact_data.organization is None
331+
and contact_data.name is None
332+
):
333+
raise PydanticStyleException(
334+
status_code=status.HTTP_409_CONFLICT,
335+
detail=[
336+
{
337+
"loc": ["body", "name"],
338+
"msg": "name cannot be None if organization is None.",
339+
"type": "value_error",
340+
"input": {"name": contact_data.name},
341+
}
342+
],
343+
)
344+
310345
return model_patcher(session, Contact, contact_id, contact_data, user=user)
311346

312347

schemas/contact.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class UpdateContact(BaseUpdateModel):
206206
name: str | None = None
207207
role: str | None = None
208208
thing_id: int | None = None
209+
organization: str | None = None
209210
# email: str | None = None
210211
# phone: str | None = None
211212
# address: str | None = None

tests/conftest.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ def second_contact():
335335
release_status="private",
336336
name="Test Second Contact",
337337
role="Owner",
338-
organization="Test Second Organization",
338+
organization=None,
339339
)
340340
session.add(contact)
341341
session.commit()
@@ -403,6 +403,25 @@ def second_address(second_contact):
403403
session.commit()
404404

405405

406+
@pytest.fixture(scope="function")
407+
def third_contact():
408+
with session_ctx() as session:
409+
contact = Contact(
410+
release_status="private",
411+
name=None,
412+
role="Owner",
413+
organization="Third Organization",
414+
)
415+
session.add(contact)
416+
session.commit()
417+
session.refresh(contact)
418+
419+
yield contact
420+
421+
session.delete(contact)
422+
session.commit()
423+
424+
406425
@pytest.fixture(scope="session")
407426
def asset():
408427
with session_ctx() as session:

tests/test_contact.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,36 @@ def test_patch_contact_404_not_found(contact):
725725
assert data["detail"] == f"Contact with ID {bad_contact_id} not found."
726726

727727

728+
def test_patch_contact_409_null_name(second_contact):
729+
payload = {"name": None}
730+
response = client.patch(
731+
f"/contact/{second_contact.id}",
732+
json=payload,
733+
)
734+
735+
assert response.status_code == 409
736+
data = response.json()
737+
assert data["detail"][0]["loc"] == ["body", "name"]
738+
assert data["detail"][0]["msg"] == "name cannot be None if organization is None."
739+
assert data["detail"][0]["type"] == "value_error"
740+
assert data["detail"][0]["input"] == {"name": None}
741+
742+
743+
def test_patch_contact_409_null_organization(third_contact):
744+
payload = {"organization": None}
745+
response = client.patch(
746+
f"/contact/{third_contact.id}",
747+
json=payload,
748+
)
749+
750+
assert response.status_code == 409
751+
data = response.json()
752+
assert data["detail"][0]["loc"] == ["body", "organization"]
753+
assert data["detail"][0]["msg"] == "organization cannot be None if name is None."
754+
assert data["detail"][0]["type"] == "value_error"
755+
assert data["detail"][0]["input"] == {"organization": None}
756+
757+
728758
def test_patch_email(email):
729759
payload = {"email": "boo@bar.com", "release_status": "archived"}
730760
response = client.patch(f"/contact/email/{email.id}", json=payload)

0 commit comments

Comments
 (0)