Repository: codingedward/flask-sieve

Issue:
Boolean is showing required if pass value false or 0
Hi Team,

Boolean is showing validation fail if I pass the value false or zero. 

Please try to resolve these bug ASAP or please also make me the contributor. so that i can fix these too.

My Request Data :

{
  "UUID": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "adminLeadRecruiter": false,
  "adminAsDcm": false,
  "leadRecruiters": [
    "abc@gmail.com",
    "xyz@abc.com"
  ],
  "recruiters": [
    "abc@gmail.com",
    "xyz@abc.com"
  ],
  "dcm": "abc@gmail.com"
}

**Response :-**

"errors": {
    "adminAsDcm": [
      "The adminAsDcm field is required."
    ],
    "adminLeadRecruiter": [
      "The adminLeadRecruiter field is required."
    ]
  },



Comments:

Patch:
diff --git a/flask_sieve/rules_processor.py b/flask_sieve/rules_processor.py
index a850531..1ebae7a 100644
--- a/flask_sieve/rules_processor.py
+++ b/flask_sieve/rules_processor.py
@@ -246,10 +246,6 @@ class RulesProcessor:
     def validate_file(value, **kwargs):
         return isinstance(value, FileStorage)
 
-    @staticmethod
-    def validate_empty(value, **kwargs):
-        return value == ''
-
     def validate_filled(self, value, attribute, nullable, **kwargs):
         if self.validate_present(attribute):
             return self.validate_required(value, attribute, nullable)
@@ -368,7 +364,7 @@ class RulesProcessor:
 
     def validate_lt(self, value, params, **kwargs):
         self._assert_params_size(size=1, params=params, rule='lt')
-        if value == '':
+        if self._is_value_empty(value):
             return False
         value = self._get_size(value)
         lower = self._get_size(self._attribute_value(params[0]))
@@ -376,7 +372,7 @@ class RulesProcessor:
 
     def validate_lte(self, value, params, **kwargs):
         self._assert_params_size(size=1, params=params, rule='lte')
-        if value == '':
+        if self._is_value_empty(value):
             return False
         value = self._get_size(value)
         lower = self._get_size(self._attribute_value(params[0]))
@@ -384,7 +380,7 @@ class RulesProcessor:
 
     def validate_max(self, value, params, **kwargs):
         self._assert_params_size(size=1, params=params, rule='max')
-        if value == '':
+        if self._is_value_empty(value):
             return False
         value = self._get_size(value)
         upper = self._get_size(params[0])
@@ -437,7 +433,7 @@ class RulesProcessor:
         return re.match(params[0], value)
 
     def validate_required(self, value, attribute, nullable, **kwargs):
-        if not value and not nullable:
+        if (not value and value != False and value != 0) and not nullable:
             return False
         return self.validate_present(attribute)
 
@@ -636,7 +632,7 @@ class RulesProcessor:
             return 'array'
         elif self.validate_file(value):
             return 'file'
-        elif self.validate_empty(value):
+        elif self._is_value_empty(value):
             return 'empty'
         return 'string'
 
@@ -655,6 +651,10 @@ class RulesProcessor:
             request_param = request_param[accessor]
         return request_param
 
+    @staticmethod
+    def _is_value_empty(value, **kwargs):
+        return (not value and value != 0)
+
     @staticmethod
     def _assert_params_size(size, params, rule):
         if size > len(params):


Test patch:
diff --git a/tests/test_rules_processor.py b/tests/test_rules_processor.py
index 15cf856..0e0f939 100644
--- a/tests/test_rules_processor.py
+++ b/tests/test_rules_processor.py
@@ -549,6 +549,14 @@ class TestRulesProcessor(unittest.TestCase):
             rules={'field': ['lt:field_2']},
             request={'field': 10, 'field_2': 1}
         )
+        self.assert_fails(
+            rules={'field': ['lt:field_2']},
+            request={'field': None, 'field_2': 1}
+        )
+        self.assert_fails(
+            rules={'field': ['lt:field_2']},
+            request={'field': '', 'field_2': 1}
+        )
 
     def test_validates_lte(self):
         self.assert_passes(
@@ -563,6 +571,10 @@ class TestRulesProcessor(unittest.TestCase):
             rules={'field': ['lte:field_2']},
             request={'field': 10, 'field_2': 1}
         )
+        self.assert_fails(
+            rules={'field': ['lte:field_2']},
+            request={'field': None, 'field_2': 1}
+        )
 
     def test_validates_max(self):
         self.assert_passes(
@@ -573,6 +585,14 @@ class TestRulesProcessor(unittest.TestCase):
             rules={'field': ['max:10']},
             request={'field': 30}
         )
+        self.assert_passes(
+            rules={'field': ['max:10']},
+            request={'field': 0}
+        )
+        self.assert_fails(
+            rules={'field': ['max:10']},
+            request={'field': None}
+        )
 
     def test_validates_mime_types(self):
         self.assert_passes(
@@ -685,6 +705,14 @@ class TestRulesProcessor(unittest.TestCase):
             rules={'field': ['required']},
             request={'field': None}
         )
+        self.assert_passes(
+            rules={'field': ['required']},
+            request={'field': False}
+        )
+        self.assert_passes(
+            rules={'field': ['required']},
+            request={'field': 0}
+        )
 
     def test_validates_required_if(self):
         self.assert_passes(
@@ -935,45 +963,6 @@ class TestRulesProcessor(unittest.TestCase):
             request={}
         )
 
-    def test_validates_sometimes(self):
-        self.assert_passes(
-            rules={'number': ['sometimes', 'max:5']},
-            request={}
-        )
-        self.assert_passes(
-            rules={'number': ['sometimes', 'max:5']},
-            request={'number': 2}
-        )
-        self.assert_fails(
-            rules={'number': ['sometimes', 'max:5']},
-            request={'number': ''}
-        )
-        self.assert_fails(
-            rules={'number': ['sometimes', 'max:5']},
-            request={'number': 10}
-        )
-        self.assert_passes(
-            rules={
-                'zipCode': ['sometimes', 'numeric'],
-                'website': ['sometimes', 'url']
-            },
-            request={}
-        )
-        self.assert_passes(
-            rules={
-                'zipCode': ['sometimes', 'numeric'],
-                'website': ['sometimes', 'url']
-            },
-            request={'website': 'https://google.com'}
-        )
-        self.assert_fails(
-            rules={
-                'zipCode': ['sometimes', 'numeric'],
-                'website': ['sometimes', 'url']
-            },
-            request={'website': 'ogle.com'}
-        )
-
 
     def test_validates_uuid(self):
         self.assert_passes(