feat: add ProfileUpdate pydantic model with email and phone validation
This commit is contained in:
parent
428c17c4e3
commit
7c9e426bb8
4 changed files with 156 additions and 0 deletions
93
tests/test_validation.py
Normal file
93
tests/test_validation.py
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from porchlight.validation import ProfileUpdate
|
||||
|
||||
|
||||
class TestProfileUpdateEmail:
|
||||
def test_valid_email(self) -> None:
|
||||
p = ProfileUpdate(email="user@example.com")
|
||||
assert p.email == "user@example.com"
|
||||
|
||||
def test_empty_email_becomes_none(self) -> None:
|
||||
p = ProfileUpdate(email="")
|
||||
assert p.email is None
|
||||
|
||||
def test_invalid_email_no_at(self) -> None:
|
||||
with pytest.raises(ValidationError, match="email"):
|
||||
ProfileUpdate(email="not-an-email")
|
||||
|
||||
def test_invalid_email_no_domain(self) -> None:
|
||||
with pytest.raises(ValidationError, match="email"):
|
||||
ProfileUpdate(email="user@")
|
||||
|
||||
|
||||
class TestProfileUpdatePhone:
|
||||
def test_valid_e164(self) -> None:
|
||||
p = ProfileUpdate(phone_number="+46701234567")
|
||||
assert p.phone_number == "+46701234567"
|
||||
|
||||
def test_valid_e164_with_spaces_normalized(self) -> None:
|
||||
p = ProfileUpdate(phone_number="+46 70 123 45 67")
|
||||
assert p.phone_number == "+46701234567"
|
||||
|
||||
def test_empty_phone_becomes_none(self) -> None:
|
||||
p = ProfileUpdate(phone_number="")
|
||||
assert p.phone_number is None
|
||||
|
||||
def test_invalid_phone(self) -> None:
|
||||
with pytest.raises(ValidationError, match="phone"):
|
||||
ProfileUpdate(phone_number="not-a-phone")
|
||||
|
||||
def test_invalid_phone_no_plus(self) -> None:
|
||||
with pytest.raises(ValidationError, match="phone"):
|
||||
ProfileUpdate(phone_number="46701234567")
|
||||
|
||||
|
||||
class TestProfileUpdatePicture:
|
||||
def test_valid_https_url(self) -> None:
|
||||
p = ProfileUpdate(picture="https://example.com/pic.jpg")
|
||||
assert p.picture == "https://example.com/pic.jpg"
|
||||
|
||||
def test_valid_http_url(self) -> None:
|
||||
p = ProfileUpdate(picture="http://example.com/pic.jpg")
|
||||
assert p.picture == "http://example.com/pic.jpg"
|
||||
|
||||
def test_empty_picture_becomes_none(self) -> None:
|
||||
p = ProfileUpdate(picture="")
|
||||
assert p.picture is None
|
||||
|
||||
def test_invalid_picture_not_url(self) -> None:
|
||||
with pytest.raises(ValidationError, match="picture"):
|
||||
ProfileUpdate(picture="not-a-url")
|
||||
|
||||
def test_invalid_picture_ftp_scheme(self) -> None:
|
||||
with pytest.raises(ValidationError, match="picture"):
|
||||
ProfileUpdate(picture="ftp://example.com/pic.jpg")
|
||||
|
||||
|
||||
class TestProfileUpdateFieldLengths:
|
||||
def test_given_name_too_long(self) -> None:
|
||||
with pytest.raises(ValidationError, match="given_name"):
|
||||
ProfileUpdate(given_name="x" * 256)
|
||||
|
||||
def test_phone_number_max_length(self) -> None:
|
||||
"""E.164 max is 15 digits + plus sign = 16 chars."""
|
||||
p = ProfileUpdate(phone_number="+431234567890123")
|
||||
assert p.phone_number == "+431234567890123"
|
||||
|
||||
def test_locale_too_long(self) -> None:
|
||||
with pytest.raises(ValidationError, match="locale"):
|
||||
ProfileUpdate(locale="x" * 21)
|
||||
|
||||
|
||||
class TestProfileUpdateDefaults:
|
||||
def test_all_defaults(self) -> None:
|
||||
p = ProfileUpdate()
|
||||
assert p.given_name == ""
|
||||
assert p.family_name == ""
|
||||
assert p.preferred_username == ""
|
||||
assert p.email is None
|
||||
assert p.phone_number is None
|
||||
assert p.picture is None
|
||||
assert p.locale == ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue