Skip to content

Commit d4f0db4

Browse files
committed
Added testing for correct error message
1 parent 273c15e commit d4f0db4

File tree

51 files changed

+313
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+313
-432
lines changed

README.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
flask-inputfilter
22
=================
33

4-
The ``InputFilter`` class is used to validate and filter input data in Flask applications.
5-
It provides a modular way to clean and ensure that incoming data meets expected format
6-
and type requirements before being processed.
4+
This library is a Flask extension that provides a simple way to validate and filter input data.
5+
It allows you to define a set of rules for each field in your input data, including filters and validators.
6+
The library also supports conditions that can be used to enforce complex validation rules.
7+
It is designed to be easy to use and flexible, allowing you to create custom filters and validators as needed.
78

89
Thank you for using ``flask-inputfilter``!
910
==========================================

flask_inputfilter/validators/array_element_validator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from copy import deepcopy
4-
from typing import TYPE_CHECKING, Any, Optional
4+
from typing import TYPE_CHECKING, Any, Dict, Optional
55

66
from flask_inputfilter.exceptions import ValidationError
77
from flask_inputfilter.validators import BaseValidator
@@ -31,6 +31,9 @@ def validate(self, value: Any) -> None:
3131

3232
for i, element in enumerate(value):
3333
try:
34+
if not isinstance(element, Dict):
35+
raise ValidationError
36+
3437
value[i] = deepcopy(self.elementFilter.validateData(element))
3538

3639
except ValidationError:

flask_inputfilter/validators/is_horizontal_image_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def validate(self, value):
3939
if value.width < value.height:
4040
raise ValidationError
4141

42-
except (binascii.Error, OSError):
42+
except (ValidationError, binascii.Error, OSError):
4343
raise ValidationError(
4444
self.error_message or "The image is not horizontally oriented."
4545
)

flask_inputfilter/validators/is_vertical_image_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def validate(self, value: Any) -> None:
4040
if value.width > value.height:
4141
raise ValidationError
4242

43-
except (binascii.Error, OSError):
43+
except (ValidationError, binascii.Error, OSError):
4444
raise ValidationError(
4545
self.error_message or "The image is not vertically oriented."
4646
)

tests/validators/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .base_validator_test import BaseValidatorTest
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import unittest
2+
from typing import Any, Optional
3+
4+
from flask_inputfilter import InputFilter
5+
from flask_inputfilter.exceptions import ValidationError
6+
7+
8+
class BaseValidatorTest(unittest.TestCase):
9+
"""
10+
Base class for all validator tests.
11+
12+
Provides common setup logic and helper methods that can be used
13+
in all validator test classes.
14+
"""
15+
16+
def setUp(self) -> None:
17+
"""Initialize an InputFilter for each test."""
18+
self.input_filter = InputFilter()
19+
20+
def assertValidationError(
21+
self,
22+
field_name: str,
23+
invalid_value: Any,
24+
expected_message: Optional[str] = None,
25+
) -> None:
26+
"""
27+
Helper method to check if an invalid value raises a ValidationError.
28+
29+
Args:
30+
field_name (str): Name of the field to validate
31+
invalid_value (Any): The invalid value that should trigger a
32+
ValidationError
33+
expected_message (Optional[str]): Optional expected error message
34+
"""
35+
with self.assertRaises(ValidationError) as context:
36+
self.input_filter.validateData({field_name: invalid_value})
37+
38+
errors = context.exception.args[0]
39+
40+
self.assertIn(field_name, errors, expected_message)
41+
42+
if expected_message:
43+
self.assertEqual(errors[field_name], expected_message)

tests/validators/test_and_validator.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
import unittest
2-
3-
from flask_inputfilter import InputFilter
41
from flask_inputfilter.exceptions import ValidationError
52
from flask_inputfilter.validators import (
63
AndValidator,
74
IsIntegerValidator,
85
RangeValidator,
96
)
7+
from tests.validators import BaseValidatorTest
108

119

12-
class TestAndValidator(unittest.TestCase):
13-
def setUp(self) -> None:
14-
self.input_filter = InputFilter()
15-
10+
class TestAndValidator(BaseValidatorTest):
1611
def test_valid_when_all_validators_pass(self) -> None:
1712
self.input_filter.add(
1813
"age",
@@ -58,5 +53,6 @@ def test_custom_error_message(self) -> None:
5853
)
5954
],
6055
)
61-
with self.assertRaises(ValidationError):
62-
self.input_filter.validateData({"age": "not a number"})
56+
self.assertValidationError(
57+
"age", "not a number", "Custom error message"
58+
)

tests/validators/test_array_element_validator.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import unittest
2-
31
from flask_inputfilter import InputFilter
42
from flask_inputfilter.exceptions import ValidationError
53
from flask_inputfilter.filters import ToIntegerFilter
64
from flask_inputfilter.validators import (
75
ArrayElementValidator,
86
IsIntegerValidator,
97
)
8+
from tests.validators import BaseValidatorTest
109

1110

12-
class TestArrayElementValidator(unittest.TestCase):
11+
class TestArrayElementValidator(BaseValidatorTest):
1312
def setUp(self) -> None:
14-
self.input_filter = InputFilter()
13+
super().setUp()
1514
self.element_filter = InputFilter()
1615
self.element_filter.add(
1716
"id",
@@ -41,5 +40,19 @@ def test_invalid_non_array_input(self) -> None:
4140
self.input_filter.add(
4241
"items", validators=[ArrayElementValidator(self.element_filter)]
4342
)
44-
with self.assertRaises(ValidationError):
45-
self.input_filter.validateData({"items": "not an array"})
43+
self.assertValidationError(
44+
"items", "not an array", "Value 'not an array' is not an array"
45+
)
46+
47+
def test_custom_error_message(self) -> None:
48+
self.input_filter.add(
49+
"items",
50+
validators=[
51+
ArrayElementValidator(
52+
self.element_filter, error_message="Custom error message"
53+
)
54+
],
55+
)
56+
self.assertValidationError(
57+
"items", ["not an array"], "Custom error message"
58+
)

tests/validators/test_array_length_validator.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import unittest
2-
3-
from flask_inputfilter import InputFilter
41
from flask_inputfilter.exceptions import ValidationError
52
from flask_inputfilter.validators import ArrayLengthValidator
3+
from tests.validators import BaseValidatorTest
64

75

8-
class TestArrayLengthValidator(unittest.TestCase):
6+
class TestArrayLengthValidator(BaseValidatorTest):
97
def setUp(self) -> None:
10-
self.input_filter = InputFilter()
8+
super().setUp()
119

1210
def test_valid_array_length(self) -> None:
1311
self.input_filter.add(
@@ -37,5 +35,21 @@ def test_invalid_non_array_input(self) -> None:
3735
"items",
3836
validators=[ArrayLengthValidator(min_length=2, max_length=5)],
3937
)
40-
with self.assertRaises(ValidationError):
41-
self.input_filter.validateData({"items": "not an array"})
38+
self.assertValidationError(
39+
"items", "not an array", "Value 'not an array' must be a list."
40+
)
41+
42+
def test_custom_error_message(self) -> None:
43+
self.input_filter.add(
44+
"items",
45+
validators=[
46+
ArrayLengthValidator(
47+
min_length=2,
48+
max_length=5,
49+
error_message="Custom error message",
50+
)
51+
],
52+
)
53+
self.assertValidationError(
54+
"items", ["not an array"], "Custom error message"
55+
)

tests/validators/test_custom_json_validator.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import unittest
2-
3-
from flask_inputfilter import InputFilter
41
from flask_inputfilter.exceptions import ValidationError
52
from flask_inputfilter.validators import CustomJsonValidator
3+
from tests.validators import BaseValidatorTest
64

75

8-
class TestCustomJsonValidator(unittest.TestCase):
6+
class TestCustomJsonValidator(BaseValidatorTest):
97
def setUp(self) -> None:
10-
self.input_filter = InputFilter()
8+
super().setUp()
119

1210
def test_valid_json_structure(self) -> None:
1311
self.input_filter.add(
@@ -59,3 +57,18 @@ def test_invalid_not_json(self) -> None:
5957
)
6058
with self.assertRaises(ValidationError):
6159
self.input_filter.validateData({"data": "not a json"})
60+
61+
def test_custom_error_message(self) -> None:
62+
self.input_filter.add(
63+
"data",
64+
validators=[
65+
CustomJsonValidator(
66+
required_fields=["age"],
67+
schema={"age": int},
68+
error_message="Custom error message",
69+
)
70+
],
71+
)
72+
self.assertValidationError(
73+
"data", {"age": "invalid"}, "Custom error message"
74+
)

0 commit comments

Comments
 (0)