Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4acaa2086 | |||
| 00e38a7149 | |||
| 04e14f32bf | |||
| 56795bbcba | |||
| 03bbe79320 | |||
| 9ef0de4848 | |||
| 4e4e3ef659 | |||
| 43cdaec895 | |||
| fde6de3fcf | |||
| 33d3e032b3 |
@@ -7,16 +7,31 @@ from plane.utils.url import contains_url
|
||||
|
||||
from .base import BaseSerializer
|
||||
|
||||
# Django import
|
||||
import re
|
||||
|
||||
|
||||
class UserSerializer(BaseSerializer):
|
||||
def validate_first_name(self, value):
|
||||
if contains_url(value):
|
||||
raise serializers.ValidationError("First name cannot contain a URL.")
|
||||
|
||||
if not re.match(r"^[a-zA-Z0-9_\- ]+$", value):
|
||||
raise serializers.ValidationError(
|
||||
"first name can only contain letters, numbers, hyphens (-), and underscores (_)"
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
def validate_last_name(self, value):
|
||||
if contains_url(value):
|
||||
raise serializers.ValidationError("Last name cannot contain a URL.")
|
||||
|
||||
if not re.match(r"^[a-zA-Z0-9_\- ]+$", value) and not value == "":
|
||||
raise serializers.ValidationError(
|
||||
"last name can only contain letters, numbers, hyphens (-), and underscores (_)"
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import pytest
|
||||
from rest_framework import serializers
|
||||
|
||||
from plane.app.serializers.user import UserSerializer
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestUserSerializer:
|
||||
"""Test the UserSerializer"""
|
||||
|
||||
def test_validate_first_name_valid(self):
|
||||
"""Test that valid first names are accepted"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
valid_names = [
|
||||
"John",
|
||||
"John Doe",
|
||||
"John-Doe",
|
||||
"John_Doe",
|
||||
"John123",
|
||||
]
|
||||
|
||||
for name in valid_names:
|
||||
result = serializer.validate_first_name(name)
|
||||
|
||||
assert result == name
|
||||
|
||||
def test_validate_first_name_with_url(self):
|
||||
"""Test that first names containing URLs are rejected"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
invalid_names = [
|
||||
"http://example.com",
|
||||
"John https://test.com",
|
||||
"www.test.com",
|
||||
]
|
||||
|
||||
for name in invalid_names:
|
||||
with pytest.raises(serializers.ValidationError) as exc_info:
|
||||
serializer.validate_first_name(name)
|
||||
|
||||
assert str(exc_info.value.detail[0]) == "First name cannot contain a URL."
|
||||
|
||||
def test_validate_first_name_with_special_chars(self):
|
||||
"""Test that first names with special characters are rejected"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
invalid_names = [
|
||||
"John@Doe",
|
||||
"John#Doe",
|
||||
"John$Doe",
|
||||
"John!Doe",
|
||||
"John&Doe",
|
||||
]
|
||||
|
||||
for name in invalid_names:
|
||||
with pytest.raises(serializers.ValidationError) as exc_info:
|
||||
serializer.validate_first_name(name)
|
||||
|
||||
assert str(exc_info.value.detail[0]) == (
|
||||
"first name can only contain letters, numbers, "
|
||||
"hyphens (-), and underscores (_)"
|
||||
)
|
||||
|
||||
def test_validate_last_name_valid(self):
|
||||
"""Test that valid last names are accepted"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
valid_names = [
|
||||
"Smith",
|
||||
"Smith Jr",
|
||||
"Smith-Jr",
|
||||
"Smith_Jr",
|
||||
"Smith123",
|
||||
"",
|
||||
]
|
||||
|
||||
for name in valid_names:
|
||||
result = serializer.validate_last_name(name)
|
||||
|
||||
assert result == name
|
||||
|
||||
def test_validate_last_name_with_url(self):
|
||||
"""Test that last names containing URLs are rejected"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
invalid_names = [
|
||||
"http://example.com",
|
||||
"Smith https://test.com",
|
||||
"www.test.com",
|
||||
]
|
||||
|
||||
for name in invalid_names:
|
||||
with pytest.raises(serializers.ValidationError) as exc_info:
|
||||
serializer.validate_last_name(name)
|
||||
|
||||
assert str(exc_info.value.detail[0]) == "Last name cannot contain a URL."
|
||||
|
||||
def test_validate_last_name_with_special_chars(self):
|
||||
"""Test that last names with special characters are rejected"""
|
||||
|
||||
serializer = UserSerializer()
|
||||
invalid_names = [
|
||||
"Smith@Jr",
|
||||
"Smith#Jr",
|
||||
"Smith$Jr",
|
||||
"Smith!Jr",
|
||||
"Smith&Jr",
|
||||
]
|
||||
|
||||
for name in invalid_names:
|
||||
with pytest.raises(serializers.ValidationError) as exc_info:
|
||||
serializer.validate_last_name(name)
|
||||
|
||||
assert str(exc_info.value.detail[0]) == (
|
||||
"last name can only contain letters, numbers, "
|
||||
"hyphens (-), and underscores (_)"
|
||||
)
|
||||
@@ -213,6 +213,11 @@ export const ProfileSetupStep: FC<Props> = observer(({ handleStepChange }) => {
|
||||
value: 24,
|
||||
message: "Name must be within 24 characters.",
|
||||
},
|
||||
validate: (value) => {
|
||||
if (!/^[a-zA-Z0-9 _-]+$/.test(value))
|
||||
return "First name can only contain letters, numbers, hyphens, and underscores.";
|
||||
return true;
|
||||
},
|
||||
}}
|
||||
render={({ field: { value, onChange, ref } }) => (
|
||||
<input
|
||||
|
||||
@@ -247,6 +247,11 @@ export const ProfileForm = observer((props: TProfileFormProps) => {
|
||||
name="first_name"
|
||||
rules={{
|
||||
required: "Please enter first name",
|
||||
validate: (value) => {
|
||||
if (!/^[a-zA-Z0-9 _-]+$/.test(value))
|
||||
return "First name can only contain letters, numbers, hyphens, and underscores.";
|
||||
return true;
|
||||
},
|
||||
}}
|
||||
render={({ field: { value, onChange, ref } }) => (
|
||||
<Input
|
||||
@@ -271,6 +276,14 @@ export const ProfileForm = observer((props: TProfileFormProps) => {
|
||||
<Controller
|
||||
control={control}
|
||||
name="last_name"
|
||||
rules={{
|
||||
validate: (value) => {
|
||||
if (value === "") return true;
|
||||
if (!/^[a-zA-Z0-9 _-]+$/.test(value))
|
||||
return "Last name can only contain letters, numbers, hyphens, and underscores.";
|
||||
return true;
|
||||
},
|
||||
}}
|
||||
render={({ field: { value, onChange, ref } }) => (
|
||||
<Input
|
||||
id="last_name"
|
||||
@@ -287,6 +300,7 @@ export const ProfileForm = observer((props: TProfileFormProps) => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors?.last_name && <span className="text-xs text-red-500">{errors?.last_name?.message}</span>}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<h4 className="text-sm font-medium text-custom-text-200">
|
||||
|
||||
Reference in New Issue
Block a user