Skip to content

Commit

Permalink
add email field (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
aminalaee committed Oct 4, 2021
1 parent 851b60f commit 202bb14
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 0 deletions.
11 changes: 11 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Date,
DateTime,
Decimal,
Email,
Float,
Integer,
Number,
Expand Down Expand Up @@ -835,6 +836,16 @@ def test_validation_error_is_hashable():
hash(error)


def test_email():
validator = Email()
value, error = validator.validate_or_error("[email protected]")
assert value == "[email protected]"

validator = Email()
value, error = validator.validate_or_error("example.com")
assert error == ValidationError(text="Must be a valid email format.", code="format")


def test_password():
validator = Password()
value, _ = validator.validate_or_error("secret")
Expand Down
2 changes: 2 additions & 0 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
choices=[("abc", "Abc"), ("def", "Def"), ("ghi", "Ghi")]
),
"extra": typesystem.Boolean(default=True, read_only=True),
"email": typesystem.Email(),
"password": typesystem.Password(),
}
)
Expand All @@ -30,6 +31,7 @@ def test_form_rendering():
assert html.count('<input type="text" ') == 1
assert html.count("<textarea ") == 1
assert html.count("<select ") == 1
assert html.count('<input type="email" ') == 1
assert html.count('<input type="password" ') == 1


Expand Down
8 changes: 8 additions & 0 deletions tests/test_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,11 @@ def test_definitions_to_json_schema():
},
}
}


def test_schema_email_serialization():
user = typesystem.Schema(fields={"email": typesystem.Email()})

item = {"email": "[email protected]"}
data = user.serialize(item)
assert data == {"email": "[email protected]"}
2 changes: 2 additions & 0 deletions typesystem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Date,
DateTime,
Decimal,
Email,
Field,
Float,
Integer,
Expand Down Expand Up @@ -35,6 +36,7 @@
"Date",
"DateTime",
"Decimal",
"Email",
"Integer",
"Jinja2Forms",
"Field",
Expand Down
6 changes: 6 additions & 0 deletions typesystem/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"time": formats.TimeFormat(),
"datetime": formats.DateTimeFormat(),
"uuid": formats.UUIDFormat(),
"email": formats.EmailFormat(),
}


Expand Down Expand Up @@ -769,6 +770,11 @@ def __init__(self, **kwargs: typing.Any) -> None:
super().__init__(format="uuid", **kwargs)


class Email(String):
def __init__(self, **kwargs: typing.Any) -> None:
super().__init__(format="email", **kwargs)


class Password(String):
def __init__(self, **kwargs: typing.Any) -> None:
super().__init__(format="password", **kwargs)
24 changes: 24 additions & 0 deletions typesystem/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
r"[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"
)

EMAIL_REGEX = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*'
r")@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,63}(?<!-)\.?$",
re.IGNORECASE,
)


class BaseFormat:
errors: typing.Dict[str, str] = {}
Expand Down Expand Up @@ -169,3 +176,20 @@ def validate(self, value: typing.Any) -> uuid.UUID:

def serialize(self, obj: typing.Any) -> str:
return str(obj)


class EmailFormat(BaseFormat):
errors = {"format": "Must be a valid email format."}

def is_native_type(self, value: typing.Any) -> bool:
return False

def validate(self, value: typing.Any) -> uuid.UUID:
match = EMAIL_REGEX.match(value)
if not match:
raise self.validation_error("format")

return value

def serialize(self, obj: typing.Any) -> str:
return str(obj)

0 comments on commit 202bb14

Please sign in to comment.