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
3 changes: 2 additions & 1 deletion api_schemas/user_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ class StilIdValidationMixin:
@field_validator("stil_id", mode="after")
@classmethod
def validate_stil_id(cls, value: str | None) -> str | None:
if value is None:
if value is None or not value.strip():
return None
value = value.strip()
if not check_stil_id(value):
raise ValueError("Invalid stil-id")
return value
Expand Down
6 changes: 3 additions & 3 deletions services/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ def update_user(user_id: int, data: UserUpdate, db: DB_dependency):
print("ERROR: Multiple users found with the same ID:", user_id)
raise HTTPException(500, detail="Multiple users found with the same ID")

if data.stil_id:
if not check_stil_id(data.stil_id):
if "stil_id" in data.model_fields_set:
if data.stil_id and not check_stil_id(data.stil_id):
raise HTTPException(400, detail="Invalid stil-id")
user.stil_id = data.stil_id
user.stil_id = data.stil_id # Explicitly provided, so allow clearing stil_id

VALID_FOOD_PREFS = set(get_args(FOOD_PREFERENCES))

Expand Down
40 changes: 40 additions & 0 deletions tests/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,46 @@ def test_register_user_invalid_stil_id(client):
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY


def test_register_user_empty_stil_id(client, admin_token):
"""An empty stil_id means the optional field was left blank, and should be stored as None"""
user_data = user_data_factory(email="test2@example.com", stil_id="")
response = client.post("/auth/register", json=user_data)

assert response.status_code == status.HTTP_201_CREATED, response.text
user = client.get(f"/users/admin/{response.json()['id']}", headers=auth_headers(admin_token)).json()
assert user["stil_id"] is None


@pytest.mark.parametrize("sent_stil_id", ["", None])
def test_update_user_clear_stil_id(client, member_token, sent_stil_id):
"""An empty (or null) stil_id on update means the user blanked the optional field, and should clear it"""
set_response = client.patch(
"/users/update/me",
json={"stil_id": "ab1234cd-s"},
headers=auth_headers(member_token),
)
assert set_response.status_code == status.HTTP_200_OK, set_response.text
assert set_response.json()["stil_id"] == "ab1234cd-s"

response = client.patch(
"/users/update/me",
json={"stil_id": sent_stil_id},
headers=auth_headers(member_token),
)

assert response.status_code == status.HTTP_200_OK, response.text
assert response.json()["stil_id"] is None
assert client.get("/users/me", headers=auth_headers(member_token)).json()["stil_id"] is None


def test_register_user_password_containing_email_name(client):
"""The local part of the e-mail may not be used as the password either"""
user_data = user_data_factory(email="somename@example.com", password="somename123")
response = client.post("/auth/register", json=user_data)

assert response.status_code == status.HTTP_400_BAD_REQUEST, response.text


def test_register_duplicate_user(client, user1_data):
"""Test registration with duplicate email fails"""
# Register first user
Expand Down
4 changes: 3 additions & 1 deletion user/user_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ async def validate_password(
if len(password) < 8:
raise InvalidPasswordException(reason="Password should be at least 8 characters")

if user.email.lower() in password.lower():
if (user.email.lower() in password.lower()) or (
user.email.split("@")[0].lower() in password.lower() and len(user.email.split("@")[0]) > 3
):
raise InvalidPasswordException(reason="Password should not contain your e-mail")

if not re.search(r"[A-Za-z]", password) or not re.search(r"\d", password):
Expand Down
Loading