From 64cf5d25707fbc2c22f6641bee3a5c3f01eafc1c Mon Sep 17 00:00:00 2001
From: Lenka Segura <lenka@sepu.cz>
Date: Jan 30 2019 13:47:33 +0000
Subject: add validators and tests


---

diff --git a/pagure/forms.py b/pagure/forms.py
index f57eac2..d2ba507 100644
--- a/pagure/forms.py
+++ b/pagure/forms.py
@@ -29,10 +29,10 @@ import six
 import wtforms
 
 import pagure.lib.query
+import pagure.validators
 from pagure.config import config as pagure_config
 from pagure.utils import urlpattern, is_admin
 
-
 STRICT_REGEX = "^[a-zA-Z0-9-_]+$"
 TAGS_REGEX = "^[a-zA-Z0-9-_, .:]+$"
 FALSE_VALUES = ("false", "", False, "False", 0, "0")
@@ -141,7 +141,11 @@ class ProjectFormSimplified(PagureForm):
         ],
     )
     avatar_email = wtforms.StringField(
-        "Avatar email", [wtforms.validators.optional()]
+        "Avatar email",
+        [
+            pagure.validators.EmailValidator("avatar_email must be an email"),
+            wtforms.validators.optional(),
+        ],
     )
     tags = wtforms.StringField(
         "Project tags",
diff --git a/pagure/validators.py b/pagure/validators.py
new file mode 100644
index 0000000..20ee1c5
--- /dev/null
+++ b/pagure/validators.py
@@ -0,0 +1,21 @@
+import re
+
+import six
+from wtforms import validators
+
+
+class EmailValidator(object):
+    """Validates wtform email field"""
+
+    def __init__(self, message="The field data was not an email"):
+        self._message = message
+
+    def __call__(self, form, email):
+        if not isinstance(email.data, six.text_type):
+            raise validators.ValidationError(
+                "Email fields should be of text type. Found {0}".format(
+                    type(email.data)
+                )
+            )
+        elif not re.match(r"[^@]+@[^@]+\.[^@]+", email.data):
+            raise validators.ValidationError(self._message)
diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py
index 7dbbb12..d0a906c 100644
--- a/tests/test_pagure_flask_api_project.py
+++ b/tests/test_pagure_flask_api_project.py
@@ -2102,6 +2102,78 @@ class PagureFlaskApiProjecttests(tests.Modeltests):
         )
 
         data = {
+             'name': 'api1',
+             'description': 'Mighty mighty description',
+             'avatar_email': 123
+        }
+
+        # invalid avatar_email - number
+        output = self.app.post(
+                '/api/0/new/', data=data, headers=headers)
+        self.assertEqual(output.status_code, 400)
+        data = json.loads(output.get_data(as_text=True))
+        self.assertDictEqual(data,
+                {"error": "Invalid or incomplete input submitted",
+                    "error_code": "EINVALIDREQ",
+                    "errors":
+                    {"avatar_email": ['avatar_email must be an email']}
+                }
+        )
+
+        data = {
+             'name': 'api1',
+             'description': 'Mighty mighty description',
+             'avatar_email': [1,2,3]
+        }
+
+        # invalid avatar_email - list
+        output = self.app.post(
+                '/api/0/new/', data=data, headers=headers)
+        self.assertEqual(output.status_code, 400)
+        data = json.loads(output.get_data(as_text=True))
+        self.assertDictEqual(data,
+                {"error": "Invalid or incomplete input submitted",
+                    "error_code": "EINVALIDREQ",
+                    "errors":
+                    {"avatar_email": ['avatar_email must be an email']}
+                }
+        )
+
+        data = {
+             'name': 'api1',
+             'description': 'Mighty mighty description',
+             'avatar_email': True
+        }
+
+        # invalid avatar_email - boolean
+        output = self.app.post(
+                '/api/0/new/', data=data, headers=headers)
+        self.assertEqual(output.status_code, 400)
+        data = json.loads(output.get_data(as_text=True))
+        self.assertDictEqual(data,
+                {"error": "Invalid or incomplete input submitted",
+                    "error_code": "EINVALIDREQ",
+                    "errors":
+                    {"avatar_email": ['avatar_email must be an email']}
+                }
+        )
+
+        data = {
+             'name': 'api1',
+             'description': 'Mighty mighty description',
+             'avatar_email': 'mighty@email.com'
+        }
+
+        # valid avatar_email
+        output = self.app.post(
+                '/api/0/new/', data=data, headers=headers)
+        self.assertEqual(output.status_code, 200)
+        data = json.loads(output.get_data(as_text=True))
+        self.assertDictEqual(
+                data,
+                {'message': 'Project "api1" created'})
+
+        data = {
             'name': 'test_42',
             'description': 'Just another small test project',
         }

