From 260d8124babba8d86735ba81933c5568f18da4e9 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Mon, 28 Sep 2020 23:41:16 +0200 Subject: [PATCH 01/12] add 'different' validation rule --- src/masonite/validation/Validator.py | 17 +++++++++++++++++ src/masonite/validation/__init__.py | 1 + tests/test_validation.py | 24 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 2a3ebbe..c090302 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1029,6 +1029,22 @@ def negated_message(self, attribute): return "The {} is a valid {} postal code.".format(attribute, self.locale) +class different(BaseValidation): + def __init__(self, validations, other_field, messages={}, raises={}): + super().__init__(validations, messages=messages, raises=raises) + self.other_field = other_field + + def passes(self, attribute, key, dictionary): + other_value = dictionary.get(self.other_field, None) + return attribute != other_value + + def message(self, attribute): + return "The {} value must be different than {} value.".format(attribute, self.other_field) + + def negated_message(self, attribute): + return "The {} value be the same as {} value.".format(attribute, self.other_field) + + def flatten(iterable): flat_list = [] @@ -1139,6 +1155,7 @@ def __init__(self): contains, date, does_not, + different, equals, email, exists, diff --git a/src/masonite/validation/__init__.py b/src/masonite/validation/__init__.py index c14ecc9..746b319 100644 --- a/src/masonite/validation/__init__.py +++ b/src/masonite/validation/__init__.py @@ -11,6 +11,7 @@ confirmed, contains, date, + different, does_not, email, equals, diff --git a/tests/test_validation.py b/tests/test_validation.py index 93d4a35..4c05718 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -20,6 +20,7 @@ confirmed, contains, date, + different, does_not, email, equals, @@ -860,6 +861,29 @@ def test_video_validation(self): self.assertEqual(len(validate), 0) + def test_different(self): + validate = Validator().validate({ + "field_1": "value_1", + "field_2": "value_2" + }, different(["field_1"], "field_2")) + self.assertEqual(len(validate), 0) + + validate = Validator().validate({ + "field_1": "value_1", + "field_2": "value_1" + }, different(["field_1"], "field_2")) + self.assertEqual( + validate.get("field_1"), ["The field_1 value must be different than field_2 value."] + ) + + validate = Validator().validate({ + "field_1": None, + "field_2": None + }, different(["field_1"], "field_2")) + self.assertEqual( + validate.get("field_1"), ["The field_1 value must be different than field_2 value."] + ) + class TestDotNotationValidation(unittest.TestCase): def setUp(self): From b836c5de8e71e30684537c2812b0028b361bf7c0 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 00:33:19 +0200 Subject: [PATCH 02/12] add uuid validation rule --- src/masonite/validation/Validator.py | 27 ++++++++++++++ src/masonite/validation/__init__.py | 1 + tests/test_validation.py | 55 ++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index c090302..3e6b293 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1045,6 +1045,32 @@ def negated_message(self, attribute): return "The {} value be the same as {} value.".format(attribute, self.other_field) +class uuid(BaseValidation): + def __init__(self, validations, version=None, messages={}, raises={}): + super().__init__(validations, messages=messages, raises=raises) + self.version = version + self.uuid_type = "UUID" + if version: + self.uuid_type = "UUID {0}".format(self.version) + + def passes(self, attribute, key, dictionary): + from uuid import UUID + try: + uuid_value = UUID(str(attribute)) + if self.version: + return uuid_value.version == int(self.version) + else: + return True + except ValueError: + return False + + def message(self, attribute): + return "The {} value must be a valid {}.".format(attribute, self.uuid_type) + + def negated_message(self, attribute): + return "The {} value must not be a valid {}.".format(attribute, self.uuid_type) + + def flatten(iterable): flat_list = [] @@ -1184,6 +1210,7 @@ def __init__(self): strong, timezone, truthy, + uuid, video, when, ) diff --git a/src/masonite/validation/__init__.py b/src/masonite/validation/__init__.py index 746b319..e13b19c 100644 --- a/src/masonite/validation/__init__.py +++ b/src/masonite/validation/__init__.py @@ -39,6 +39,7 @@ strong, timezone, truthy, + uuid, video, when, ) diff --git a/tests/test_validation.py b/tests/test_validation.py index 4c05718..5af7aeb 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -3,6 +3,7 @@ import pytest import platform import pendulum +from uuid import uuid1, uuid3, uuid4, uuid5 from masonite.app import App from masonite.drivers import SessionCookieDriver from masonite.managers import SessionManager @@ -38,6 +39,7 @@ postal_code, strong, regex, + uuid, video, ) from src.masonite.validation.Validator import json as vjson @@ -884,6 +886,59 @@ def test_different(self): validate.get("field_1"), ["The field_1 value must be different than field_2 value."] ) + def test_all_uuid_versions_are_considered_valid(self): + from uuid import NAMESPACE_DNS + u3 = uuid3(NAMESPACE_DNS, "domain.com") + u5 = uuid5(NAMESPACE_DNS, "domain.com") + for uuid_value in [uuid1(), u3, uuid4(), u5]: + validate = Validator().validate({ + "document_id": uuid_value, + }, uuid(["document_id"])) + self.assertEqual(len(validate), 0) + + def test_unvalid_uuid_values(self): + for uuid_value in [None, [], True, "", "uuid", {"uuid": "nope"}, 3, ()]: + validate = Validator().validate({ + "document_id": uuid_value, + }, uuid(["document_id"])) + self.assertEqual( + validate.get("document_id"), ["The document_id value must be a valid UUID."] + ) + + def test_uuid_rule_with_specified_versions(self): + from uuid import NAMESPACE_DNS + u3 = uuid3(NAMESPACE_DNS, "domain.com") + u5 = uuid5(NAMESPACE_DNS, "domain.com") + for version, uuid_value in [(1, uuid1()), (3, u3), (4, uuid4()), (5, u5)]: + validate = Validator().validate({ + "document_id": uuid_value, + }, uuid(["document_id"], version)) + self.assertEqual(len(validate), 0) + + def test_invalid_uuid_rule_with_specified_versions(self): + for version in [1, 2, 3, 5]: + validate = Validator().validate({ + "document_id": uuid4(), + }, uuid(["document_id"], version)) + self.assertEqual( + validate.get("document_id"), ["The document_id value must be a valid UUID {0}.".format(version)] + ) + + def test_uuid_version_can_be_str_or_int(self): + uuid_value = uuid4() + for version in [4, "4"]: + validate = Validator().validate({ + "document_id": uuid_value, + }, uuid(["document_id"], version)) + self.assertEqual(len(validate), 0) + for version in [3, "3"]: + validate = Validator().validate({ + "document_id": uuid_value, + }, uuid(["document_id"], version)) + self.assertEqual( + validate.get("document_id"), ["The document_id value must be a valid UUID 3."] + ) + class TestDotNotationValidation(unittest.TestCase): def setUp(self): From 8b78b691962c75249a638785b30bc1f46bb87900 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 01:22:12 +0200 Subject: [PATCH 03/12] add required_if rule and edit required rule --- src/masonite/validation/Validator.py | 28 +++++++++++++++++++++++- src/masonite/validation/__init__.py | 1 + tests/test_validation.py | 32 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 3e6b293..2ff8a5d 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -96,7 +96,8 @@ def passes(self, attribute, key, dictionary): Returns: bool """ - return attribute or key in dictionary + # return attribute or key in dictionary + return key in dictionary and attribute def message(self, key): """A message to show when this rule fails @@ -1071,6 +1072,30 @@ def negated_message(self, attribute): return "The {} value must not be a valid {}.".format(attribute, self.uuid_type) +class required_if(BaseValidation): + + def __init__(self, validations, other_field, value, messages={}, raises={}): + super().__init__(validations, messages=messages, raises=raises) + self.other_field = other_field + self.value = value + + def passes(self, attribute, key, dictionary): + if dictionary.get(self.other_field, None) == self.value: + import pdb + pdb.set_trace() + return required.passes(self, attribute, key, dictionary) + else: + return True + + def message(self, attribute): + return "The {} is required because {}={}.".format(attribute, self.other_field, self.value) + + def negated_message(self, attribute): + return "The {} is not required because {}={} or {} is not present.".format( + attribute, self.other_field, self.value, self.other_field + ) + + def flatten(iterable): flat_list = [] @@ -1206,6 +1231,7 @@ def __init__(self): postal_code, regex, required, + required_if, string, strong, timezone, diff --git a/src/masonite/validation/__init__.py b/src/masonite/validation/__init__.py index e13b19c..a11d06b 100644 --- a/src/masonite/validation/__init__.py +++ b/src/masonite/validation/__init__.py @@ -35,6 +35,7 @@ postal_code, regex, required, + required_if, string, strong, timezone, diff --git a/tests/test_validation.py b/tests/test_validation.py index 5af7aeb..98467a5 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -52,6 +52,7 @@ one_of, phone, required, + required_if, string, timezone, truthy, @@ -939,6 +940,37 @@ def test_uuid_version_can_be_str_or_int(self): validate.get("document_id"), ["The document_id value must be a valid UUID 3."] ) + def test_required_if_rule_when_other_field_is_present(self): + validate = Validator().validate({ + "first_name": "Sam", + "last_name": "Gamji" + }, required_if(["last_name"], "first_name", "Sam")) + self.assertEqual(len(validate), 0) + validate = Validator().validate({ + "first_name": "Sam", + "last_name": "" + }, required_if(["last_name"], "first_name", "Sam")) + self.assertEqual( + validate.get("last_name"), ["The last_name is required because first_name=Sam."] + ) + validate = Validator().validate({ + "first_name": "Sam", + "last_name": "" + }, required_if(["last_name"], "first_name", "Joe")) + self.assertEqual(len(validate), 0) + + def test_required_if_rule_when_other_field_is_not_present(self): + validate = Validator().validate({ + "first_name": "Sam", + }, required_if(["last_name"], "first_name", "Sam")) + self.assertEqual( + validate.get("last_name"), ["The last_name is required because first_name=Sam."] + ) + validate = Validator().validate({ + "first_name": "Sam", + }, required_if(["last_name"], "first_name", "Joe")) + self.assertEqual(len(validate), 0) + class TestDotNotationValidation(unittest.TestCase): def setUp(self): From 6a636702c0cd062bdb09dde331bc7c0cd4bfc386 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 01:24:32 +0200 Subject: [PATCH 04/12] add new test for edit required rule --- tests/test_validation.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_validation.py b/tests/test_validation.py index 98467a5..dba435b 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -74,6 +74,11 @@ def test_required(self): self.assertEqual(len(validate), 0) + def test_required_with_non_truthy_values(self): + for falsy_value in [[], {}, "", False, 0]: + validate = Validator().validate({"user": falsy_value}, required(["user"])) + self.assertEqual(validate.get("user"), ["The user field is required."]) + def test_can_validate_null_values(self): validate = Validator().validate({"test": None}, length(["test"], min=2, max=5)) From adff69f39a4c9689546b0ffcef0ca9d6e55784c7 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 01:56:42 +0200 Subject: [PATCH 05/12] add required_with rule --- src/masonite/validation/Validator.py | 39 +++++++++++++++- src/masonite/validation/__init__.py | 1 + tests/test_validation.py | 70 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 2ff8a5d..6838539 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1081,8 +1081,6 @@ def __init__(self, validations, other_field, value, messages={}, raises={}): def passes(self, attribute, key, dictionary): if dictionary.get(self.other_field, None) == self.value: - import pdb - pdb.set_trace() return required.passes(self, attribute, key, dictionary) else: return True @@ -1096,6 +1094,42 @@ def negated_message(self, attribute): ) +class required_with(BaseValidation): + """The field under validation must be present and not empty only + if any of the other specified fields are present.""" + + def __init__(self, validations, other_fields, messages={}, raises={}): + super().__init__(validations, messages=messages, raises=raises) + if not isinstance(other_fields, list): + if "," in other_fields: + self.other_fields = other_fields.split(",") + else: + self.other_fields = [other_fields] + else: + self.other_fields = other_fields + + def passes(self, attribute, key, dictionary): + for field in self.other_fields: + if field in dictionary: + return required.passes(self, attribute, key, dictionary) + else: + return True + + def message(self, attribute): + fields = ",".join(self.other_fields) + return "The {} is required because {} is present.".format( + attribute, + "one in {}".format(fields) if len(self.other_fields) > 1 else self.other_fields[0], + ) + + def negated_message(self, attribute): + return "The {} is not required because {} {} is not present.".format( + attribute, + "none of" if len(self.other_fields) > 1 else "", + ",".join(self.other_fields) + ) + + def flatten(iterable): flat_list = [] @@ -1232,6 +1266,7 @@ def __init__(self): regex, required, required_if, + required_with, string, strong, timezone, diff --git a/src/masonite/validation/__init__.py b/src/masonite/validation/__init__.py index a11d06b..a303790 100644 --- a/src/masonite/validation/__init__.py +++ b/src/masonite/validation/__init__.py @@ -36,6 +36,7 @@ regex, required, required_if, + required_with, string, strong, timezone, diff --git a/tests/test_validation.py b/tests/test_validation.py index dba435b..6b0711b 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -53,6 +53,7 @@ phone, required, required_if, + required_with, string, timezone, truthy, @@ -976,6 +977,46 @@ def test_required_if_rule_when_other_field_is_not_present(self): }, required_if(["last_name"], "first_name", "Joe")) self.assertEqual(len(validate), 0) + def test_required_with_rule(self): + validate = Validator().validate({ + "first_name": "Sam", + "last_name": "Gamji", + "email": "samgamji@loftr.com" + }, required_with(["email"], ["first_name", "last_name" "nick_name"])) + self.assertEqual(len(validate), 0) + validate = Validator().validate({ + "first_name": "Sam", + "email": "samgamji@loftr.com" + }, required_with(["email"], "first_name")) + self.assertEqual(len(validate), 0) + validate = Validator().validate({ + "first_name": "Sam", + "email": "" + }, required_with(["email"], "first_name")) + self.assertEqual( + validate.get("email"), ["The email is required because first_name is present."] + ) + validate = Validator().validate({ + "first_name": "Sam", + "email": "" + }, required_with(["email"], "first_name,nick_name")) + self.assertEqual( + validate.get("email"), ["The email is required because one in first_name,nick_name is present."] + ) + + def test_required_with_rule_with_comma_separated_fields(self): + validate = Validator().validate({ + "nick_name": "Sam", + "email": "samgamji@loftr.com" + }, required_with(["email"], "first_name,last_name,nick_name")) + self.assertEqual(len(validate), 0) + validate = Validator().validate({ + "nick_name": "Sam", + }, required_with(["email"], "first_name,nick_name")) + self.assertEqual( + validate.get("email"), ["The email is required because one in first_name,nick_name is present."] + ) + class TestDotNotationValidation(unittest.TestCase): def setUp(self): @@ -1405,3 +1446,32 @@ def test_dictionary(self): ) self.assertEqual(len(validate), 0) + + def test_required_with_string_validation(self): + validate = Validator().validate({ + "first_name": "Sam", + "email": "samgamji@loftr.com" + }, + { + "email": "required_with:first_name,last_name" + }) + self.assertEqual(len(validate), 0) + # with one argument + validate = Validator().validate({ + "email": "" + }, + { + "email": "required_with:first_name" + }) + self.assertEqual(len(validate), 0) + validate = Validator().validate({ + "first_name": "Sam", + "email": "" + }, + { + "email": "required_with:first_name,nick_name" + }) + self.assertIn( + "The email is required because one in first_name,nick_name is present.", + validate.get("email"), + ) \ No newline at end of file From 3b7d47a09ac42e029b0b5c47ed16f4a30096cb2e Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 02:10:13 +0200 Subject: [PATCH 06/12] fix tests --- src/masonite/validation/Validator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 6838539..5b472c9 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -85,19 +85,18 @@ class required(BaseValidation): def passes(self, attribute, key, dictionary): """The passing criteria for this rule. - This should return a True boolean value. + The key must exist in the dictionary and return a True boolean value. + The key can use * notation. Arguments: attribute {mixed} -- The value found within the dictionary key {string} -- The key in the dictionary being searched for. - This key may or may not exist in the dictionary. dictionary {dict} -- The dictionary being searched Returns: bool """ - # return attribute or key in dictionary - return key in dictionary and attribute + return self.find(key, dictionary) and attribute def message(self, key): """A message to show when this rule fails @@ -1073,7 +1072,8 @@ def negated_message(self, attribute): class required_if(BaseValidation): - + """The field under validation must be present and not empty only + if an other field has a given value.""" def __init__(self, validations, other_field, value, messages={}, raises={}): super().__init__(validations, messages=messages, raises=raises) self.other_field = other_field From 764554c36c07567c1cd2fb7e2c11f0ed2bd34c23 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Tue, 29 Sep 2020 02:13:05 +0200 Subject: [PATCH 07/12] add docstrings for all new rules --- src/masonite/validation/Validator.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 5b472c9..f113a82 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1030,6 +1030,7 @@ def negated_message(self, attribute): class different(BaseValidation): + """The field under validation must be different than an other given field.""" def __init__(self, validations, other_field, messages={}, raises={}): super().__init__(validations, messages=messages, raises=raises) self.other_field = other_field @@ -1046,6 +1047,8 @@ def negated_message(self, attribute): class uuid(BaseValidation): + """The field under validation must be a valid UUID. The UUID version standard + can be precised (1,3,4,5).""" def __init__(self, validations, version=None, messages={}, raises={}): super().__init__(validations, messages=messages, raises=raises) self.version = version @@ -1072,7 +1075,7 @@ def negated_message(self, attribute): class required_if(BaseValidation): - """The field under validation must be present and not empty only + """The field under validation must be present and not empty only if an other field has a given value.""" def __init__(self, validations, other_field, value, messages={}, raises={}): super().__init__(validations, messages=messages, raises=raises) @@ -1095,7 +1098,7 @@ def negated_message(self, attribute): class required_with(BaseValidation): - """The field under validation must be present and not empty only + """The field under validation must be present and not empty only if any of the other specified fields are present.""" def __init__(self, validations, other_fields, messages={}, raises={}): From 03624326a7b9b8feea2387fba32b881abba51e26 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Wed, 30 Sep 2020 00:46:34 +0200 Subject: [PATCH 08/12] add distinct rule validation --- src/masonite/validation/Validator.py | 19 ++++++++++++++ src/masonite/validation/__init__.py | 1 + tests/test_validation.py | 39 ++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index f113a82..6f90f15 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1133,6 +1133,24 @@ def negated_message(self, attribute): ) +class distinct(BaseValidation): + """When working with list, the field under validation must not have any + duplicate values.""" + + def passes(self, attribute, key, dictionary): + # check if list contains duplicates + if len(set(attribute)) != len(attribute): + return False + else: + return True + + def message(self, attribute): + return "The {} field has duplicate values.".format(attribute) + + def negated_message(self, attribute): + return "The {} field has only different values.".format(attribute) + + def flatten(iterable): flat_list = [] @@ -1244,6 +1262,7 @@ def __init__(self): date, does_not, different, + distinct, equals, email, exists, diff --git a/src/masonite/validation/__init__.py b/src/masonite/validation/__init__.py index a303790..1b907c2 100644 --- a/src/masonite/validation/__init__.py +++ b/src/masonite/validation/__init__.py @@ -12,6 +12,7 @@ contains, date, different, + distinct, does_not, email, equals, diff --git a/tests/test_validation.py b/tests/test_validation.py index 6b0711b..95c53f5 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -22,6 +22,7 @@ contains, date, different, + distinct, does_not, email, equals, @@ -1017,6 +1018,44 @@ def test_required_with_rule_with_comma_separated_fields(self): validate.get("email"), ["The email is required because one in first_name,nick_name is present."] ) + def test_distinct(self): + validate = Validator().validate({ + "users": [ + { + "first_name": "John", + "last_name": "Masonite", + }, + { + "first_name": "Joe", + "last_name": "Masonite", + } + ] + }, distinct(["users.*.last_name"])) + self.assertEqual( + validate.get("users.*.last_name"), ["The users.*.last_name field has duplicate values."] + ) + validate = Validator().validate({ + "users": [ + { + "id": 1, + "name": "John", + }, + { + "id": 2, + "name": "Nick", + } + ] + }, distinct(["users.*.id"])) + self.assertEqual(len(validate), 0) + + def test_distinct_with_simple_list(self): + validate = Validator().validate({ + "emails": ["john@masonite.com", "joe@masonite.com", "john@masonite.com"] + }, distinct(["emails"])) + self.assertEqual( + validate.get("emails"), ["The emails field has duplicate values."] + ) + class TestDotNotationValidation(unittest.TestCase): def setUp(self): From a9efbd7247af632f3d1462356f97b00c2c59900d Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Mon, 19 Oct 2020 14:27:30 +0200 Subject: [PATCH 09/12] add corrections --- src/masonite/validation/Validator.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 6f90f15..85fca50 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1049,7 +1049,7 @@ def negated_message(self, attribute): class uuid(BaseValidation): """The field under validation must be a valid UUID. The UUID version standard can be precised (1,3,4,5).""" - def __init__(self, validations, version=None, messages={}, raises={}): + def __init__(self, validations, version=4, messages={}, raises={}): super().__init__(validations, messages=messages, raises=raises) self.version = version self.uuid_type = "UUID" @@ -1060,10 +1060,7 @@ def passes(self, attribute, key, dictionary): from uuid import UUID try: uuid_value = UUID(str(attribute)) - if self.version: - return uuid_value.version == int(self.version) - else: - return True + return uuid_value.version == int(self.version) except ValueError: return False @@ -1139,10 +1136,7 @@ class distinct(BaseValidation): def passes(self, attribute, key, dictionary): # check if list contains duplicates - if len(set(attribute)) != len(attribute): - return False - else: - return True + return len(set(attribute)) == len(attribute) def message(self, attribute): return "The {} field has duplicate values.".format(attribute) From 90320f78f1bc81a0f38d04ba51a65dabfb7d2d28 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Mon, 19 Oct 2020 14:28:19 +0200 Subject: [PATCH 10/12] fix typo in test name --- tests/test_validation.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 95c53f5..33f23b1 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -904,7 +904,7 @@ def test_all_uuid_versions_are_considered_valid(self): }, uuid(["document_id"])) self.assertEqual(len(validate), 0) - def test_unvalid_uuid_values(self): + def test_invalid_uuid_values(self): for uuid_value in [None, [], True, "", "uuid", {"uuid": "nope"}, 3, ()]: validate = Validator().validate({ "document_id": uuid_value, @@ -951,31 +951,31 @@ def test_required_if_rule_when_other_field_is_present(self): validate = Validator().validate({ "first_name": "Sam", "last_name": "Gamji" - }, required_if(["last_name"], "first_name", "Sam")) + }, required_if(["last_name"], "first_name", "Sam")) self.assertEqual(len(validate), 0) validate = Validator().validate({ "first_name": "Sam", "last_name": "" - }, required_if(["last_name"], "first_name", "Sam")) + }, required_if(["last_name"], "first_name", "Sam")) self.assertEqual( validate.get("last_name"), ["The last_name is required because first_name=Sam."] ) validate = Validator().validate({ "first_name": "Sam", "last_name": "" - }, required_if(["last_name"], "first_name", "Joe")) + }, required_if(["last_name"], "first_name", "Joe")) self.assertEqual(len(validate), 0) def test_required_if_rule_when_other_field_is_not_present(self): validate = Validator().validate({ "first_name": "Sam", - }, required_if(["last_name"], "first_name", "Sam")) + }, required_if(["last_name"], "first_name", "Sam")) self.assertEqual( validate.get("last_name"), ["The last_name is required because first_name=Sam."] ) validate = Validator().validate({ "first_name": "Sam", - }, required_if(["last_name"], "first_name", "Joe")) + }, required_if(["last_name"], "first_name", "Joe")) self.assertEqual(len(validate), 0) def test_required_with_rule(self): @@ -983,17 +983,17 @@ def test_required_with_rule(self): "first_name": "Sam", "last_name": "Gamji", "email": "samgamji@loftr.com" - }, required_with(["email"], ["first_name", "last_name" "nick_name"])) + }, required_with(["email"], ["first_name", "last_name" "nick_name"])) self.assertEqual(len(validate), 0) validate = Validator().validate({ "first_name": "Sam", "email": "samgamji@loftr.com" - }, required_with(["email"], "first_name")) + }, required_with(["email"], "first_name")) self.assertEqual(len(validate), 0) validate = Validator().validate({ "first_name": "Sam", "email": "" - }, required_with(["email"], "first_name")) + }, required_with(["email"], "first_name")) self.assertEqual( validate.get("email"), ["The email is required because first_name is present."] ) From 69690325a5a4dc8f9696edf4705aaee16c31cb86 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Mon, 19 Oct 2020 14:32:44 +0200 Subject: [PATCH 11/12] update tests now that default uuid is uuid4 --- tests/test_validation.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 33f23b1..8f3e73a 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -894,15 +894,22 @@ def test_different(self): validate.get("field_1"), ["The field_1 value must be different than field_2 value."] ) - def test_all_uuid_versions_are_considered_valid(self): + def test_that_default_uuid_must_be_uuid4(self): from uuid import NAMESPACE_DNS u3 = uuid3(NAMESPACE_DNS, "domain.com") u5 = uuid5(NAMESPACE_DNS, "domain.com") - for uuid_value in [uuid1(), u3, uuid4(), u5]: + for uuid_value in [uuid1(), u3, u5]: validate = Validator().validate({ "document_id": uuid_value, }, uuid(["document_id"])) - self.assertEqual(len(validate), 0) + self.assertEqual( + validate.get("document_id"), ["The document_id value must be a valid UUID 4."] + ) + + validate = Validator().validate({ + "document_id": uuid4(), + }, uuid(["document_id"], 4)) + self.assertEqual(len(validate), 0) def test_invalid_uuid_values(self): for uuid_value in [None, [], True, "", "uuid", {"uuid": "nope"}, 3, ()]: @@ -910,7 +917,7 @@ def test_invalid_uuid_values(self): "document_id": uuid_value, }, uuid(["document_id"])) self.assertEqual( - validate.get("document_id"), ["The document_id value must be a valid UUID."] + validate.get("document_id"), ["The document_id value must be a valid UUID 4."] ) def test_uuid_rule_with_specified_versions(self): From 258dacec9b64bc38f77adcd0607e1fb330cab1c7 Mon Sep 17 00:00:00 2001 From: Samuel Girardin Date: Mon, 19 Oct 2020 14:36:33 +0200 Subject: [PATCH 12/12] add last correction --- src/masonite/validation/Validator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/masonite/validation/Validator.py b/src/masonite/validation/Validator.py index 85fca50..1c72374 100644 --- a/src/masonite/validation/Validator.py +++ b/src/masonite/validation/Validator.py @@ -1082,8 +1082,8 @@ def __init__(self, validations, other_field, value, messages={}, raises={}): def passes(self, attribute, key, dictionary): if dictionary.get(self.other_field, None) == self.value: return required.passes(self, attribute, key, dictionary) - else: - return True + + return True def message(self, attribute): return "The {} is required because {}={}.".format(attribute, self.other_field, self.value)