From bba8d163097b777387054b67268145696ed2005a Mon Sep 17 00:00:00 2001 From: Kevin Deldycke Date: Wed, 20 Jul 2016 19:06:08 +0200 Subject: [PATCH] Check string length range constraints. --- cassandra/cqlengine/columns.py | 6 ++ .../cqlengine/columns/test_validation.py | 60 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/cassandra/cqlengine/columns.py b/cassandra/cqlengine/columns.py index 407596eb..36996a86 100644 --- a/cassandra/cqlengine/columns.py +++ b/cassandra/cqlengine/columns.py @@ -343,6 +343,12 @@ class Text(Column): raise ValueError( 'Maximum length is not allowed to be negative.') + if self.min_length is not None and self.max_length is not None: + if self.max_length < self.min_length: + raise ValueError( + 'Maximum length must be greater or equal ' + 'to minimum length.') + super(Text, self).__init__(**kwargs) def validate(self, value): diff --git a/tests/integration/cqlengine/columns/test_validation.py b/tests/integration/cqlengine/columns/test_validation.py index b3ba4547..fefa9efb 100644 --- a/tests/integration/cqlengine/columns/test_validation.py +++ b/tests/integration/cqlengine/columns/test_validation.py @@ -392,6 +392,18 @@ class TestAscii(BaseCassEngTestCase): with self.assertRaises(ValueError): Ascii(max_length=-1) + def test_length_range(self): + Ascii(min_length=0, max_length=0) + Ascii(min_length=0, max_length=1) + Ascii(min_length=10, max_length=10) + Ascii(min_length=10, max_length=11) + + with self.assertRaises(ValueError): + Ascii(min_length=10, max_length=9) + + with self.assertRaises(ValueError): + Ascii(min_length=1, max_length=0) + def test_type_checking(self): Ascii().validate('string') Ascii().validate(u'unicode') @@ -416,12 +428,30 @@ class TestAscii(BaseCassEngTestCase): def test_required_validation(self): """ Tests that validation raise on none and blank values if value required. """ + Ascii(required=True).validate('k') + with self.assertRaises(ValidationError): Ascii(required=True).validate('') with self.assertRaises(ValidationError): Ascii(required=True).validate(None) + # With min_length set. + Ascii(required=True, min_length=0).validate('k') + Ascii(required=True, min_length=1).validate('k') + + with self.assertRaises(ValidationError): + Ascii(required=True, min_length=2).validate('k') + + # With max_length set. + Ascii(required=True, max_length=1).validate('k') + + with self.assertRaises(ValidationError): + Ascii(required=True, max_length=2).validate('kevin') + + with self.assertRaises(ValueError): + Ascii(required=True, max_length=0) + class TestText(BaseCassEngTestCase): @@ -477,6 +507,18 @@ class TestText(BaseCassEngTestCase): with self.assertRaises(ValueError): Text(max_length=-1) + def test_length_range(self): + Text(min_length=0, max_length=0) + Text(min_length=0, max_length=1) + Text(min_length=10, max_length=10) + Text(min_length=10, max_length=11) + + with self.assertRaises(ValueError): + Text(min_length=10, max_length=9) + + with self.assertRaises(ValueError): + Text(min_length=1, max_length=0) + def test_type_checking(self): Text().validate('string') Text().validate(u'unicode') @@ -501,12 +543,30 @@ class TestText(BaseCassEngTestCase): def test_required_validation(self): """ Tests that validation raise on none and blank values if value required. """ + Text(required=True).validate('b') + with self.assertRaises(ValidationError): Text(required=True).validate('') with self.assertRaises(ValidationError): Text(required=True).validate(None) + # With min_length set. + Text(required=True, min_length=0).validate('b') + Text(required=True, min_length=1).validate('b') + + with self.assertRaises(ValidationError): + Text(required=True, min_length=2).validate('b') + + # With max_length set. + Text(required=True, max_length=1).validate('b') + + with self.assertRaises(ValidationError): + Text(required=True, max_length=2).validate('blake') + + with self.assertRaises(ValueError): + Text(required=True, max_length=0) + class TestExtraFieldsRaiseException(BaseCassEngTestCase): class TestModel(Model):