Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions models/player_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
- `PlayerRequestModel`: Represents player data for Create and Update operations.
- `PlayerResponseModel`: Represents player data including UUID for Retrieve operations.

Design decision — single request model vs split models:
A single `PlayerRequestModel` is intentionally shared by both POST (Create)
and PUT (Update). Per-operation differences are handled at the route layer
rather than by duplicating the model:
- POST checks that `squad_number` does not already exist (→ 409 Conflict).
- PUT checks that `squad_number` in the body matches the path parameter
(→ 400 Bad Request), ensuring the request is unambiguous. The path
parameter is always the authoritative source of identity on PUT.

These models are used for data validation and serialization in the API.
"""

Expand Down
5 changes: 5 additions & 0 deletions routes/player_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,14 @@ async def put_async(
async_session (AsyncSession): The async version of a SQLAlchemy ORM session.

Raises:
HTTPException: HTTP 400 Bad Request if squad_number in the request body does
not match the path parameter. The path parameter is the authoritative source
of identity on PUT; a mismatch makes the request ambiguous.
HTTPException: HTTP 404 Not Found error if the Player with the specified Squad
Number does not exist.
"""
if player_model.squad_number != squad_number:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
player = await player_service.retrieve_by_squad_number_async(
async_session, squad_number
)
Expand Down
14 changes: 14 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,20 @@ def test_request_put_player_squadnumber_existing_response_status_no_content(clie
assert response.status_code == 204


def test_request_put_player_squadnumber_mismatch_response_status_bad_request(client):
"""PUT /players/squadnumber/{squad_number} with mismatched squad number in body returns 400 Bad Request"""
# Arrange
squad_number = existing_player().squad_number
player = existing_player()
player.squad_number = unknown_player().squad_number
# Act
response = client.put(
PATH + "squadnumber/" + str(squad_number), json=player.__dict__
)
# Assert
assert response.status_code == 400


# DELETE /players/squadnumber/{squad_number} -----------------------------------


Expand Down
Loading