Commit a68f3257 authored by Andrew Godwin's avatar Andrew Godwin
Browse files

Fixed #21638: Validators are now comparable, stops infinite user mig'ns

parent 3f1a0082
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ class RegexValidator(object):
        if not self.regex.search(force_text(value)):
            raise ValidationError(self.message, code=self.code)

    def __eq__(self, other):
        return isinstance(other, RegexValidator) and (self.regex == other.regex) and (self.message == other.message) and (self.code == other.code)


@deconstructible
class URLValidator(RegexValidator):
@@ -139,6 +142,9 @@ class EmailValidator(object):
                pass
            raise ValidationError(self.message, code=self.code)

    def __eq__(self, other):
        return isinstance(other, EmailValidator) and (self.domain_whitelist == other.domain_whitelist) and (self.message == other.message) and (self.code == other.code)

validate_email = EmailValidator()

slug_re = re.compile(r'^[-a-zA-Z0-9_]+$')
@@ -205,6 +211,9 @@ class BaseValidator(object):
        if self.compare(cleaned, self.limit_value):
            raise ValidationError(self.message, code=self.code, params=params)

    def __eq__(self, other):
        return isinstance(other, self.__class__) and (self.limit_value == other.limit_value) and (self.message == other.message) and (self.code == other.code)


@deconstructible
class MaxValueValidator(BaseValidator):
+56 −0
Original line number Diff line number Diff line
@@ -244,3 +244,59 @@ for validator, value, expected in TEST_DATA:
    name, method = create_simple_test_method(validator, expected, value, test_counter)
    setattr(TestSimpleValidators, name, method)
    test_counter += 1


class TestValidatorEquality(TestCase):
    """
    Tests that validators have valid equality operators (#21638)
    """

    def test_regex_equality(self):
        self.assertEqual(
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://'),
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://'),
        )
        self.assertNotEqual(
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://'),
            RegexValidator(r'^(?:[0-9\.\-]*)://'),
        )
        self.assertEqual(
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://', "oh noes", "invalid"),
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://', "oh noes", "invalid"),
        )
        self.assertNotEqual(
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://', "oh", "invalid"),
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://', "oh noes", "invalid"),
        )
        self.assertNotEqual(
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://', "oh noes", "invalid"),
            RegexValidator(r'^(?:[a-z0-9\.\-]*)://'),
        )

    def test_email_equality(self):
        self.assertEqual(
            EmailValidator(),
            EmailValidator(),
        )
        self.assertNotEqual(
            EmailValidator(message="BAD EMAIL"),
            EmailValidator(),
        )
        self.assertEqual(
            EmailValidator(message="BAD EMAIL", code="bad"),
            EmailValidator(message="BAD EMAIL", code="bad"),
        )

    def test_basic_equality(self):
        self.assertEqual(
            MaxValueValidator(44),
            MaxValueValidator(44),
        )
        self.assertNotEqual(
            MaxValueValidator(44),
            MinValueValidator(44),
        )
        self.assertNotEqual(
            MinValueValidator(45),
            MinValueValidator(11),
        )