Beispiel #1
0
    def test_validate_invalid_int_value_name(self):
        self.test_input['name'] = 30
        with self.assertRaisesRegex(Invalid, 'key: "name" contains invalid item "30" with type "int": not of type string'):
            _ = maat_scale(self.test_input, self.test_validation)

        # test validator of name to make the previous invalid value valid.
        self.test_validation['name'] = {'validator': 'int'}
        validated_items = maat_scale(self.test_input, self.test_validation)
        difference = ddiff(validated_items, self.test_input)
        self.assertEqual(difference, {})
Beispiel #2
0
    def test_non_dictionary_function(self):
        """a helpfull message is shown when trying to use post transformation that is not registered"""
        test_input_list = ['id', float(23)]
        test_input_tuple = ('id', float(23))
        test_validation = {'id': {'validator': 'int', 'transform': 'int'}}
        with self.assertRaisesRegex(Invalid, "\['id', 23.0\] not a dictionary but is of type list"):
            _ = maat_scale(test_input_list, test_validation)

        with self.assertRaisesRegex(Invalid, "\('id', 23.0\) not a dictionary but is of type tuple"):
            _ = maat_scale(test_input_tuple, test_validation)
Beispiel #3
0
    def test_item_nullable(self):
        """a helpfull message is shown when trying to use post transformation that is not registered"""
        test_input = {'id': None}
        test_validation = {'id': {'validator': 'float'}}
        with self.assertRaisesRegex(Invalid, 'key: \"id\" contains invalid item \"None\" with type \"NoneType\": not of type float'):
            _ = maat_scale(test_input, test_validation)

        test_validation = {'id': {'validator': 'float', 'null_able': True}}
        validated_items = maat_scale(test_input, test_validation)
        difference = ddiff(validated_items, test_input)
        self.assertEqual(difference, {})
Beispiel #4
0
    def test_validation_test_invalid_keys_exception(self):
        """Test invalid keys exception"""

        del self.test_input['type']

        with self.assertRaisesRegex(Invalid, 'key:"type" is not set'):
            _ = maat_scale(self.test_input, self.test_validation)
Beispiel #5
0
    def test_validate_fail_within_nested_list_dicts_with_custom_validation(self):
        from maat import registered_functions
        def blacklist_address(key, val):
            """Since this is a example blacklisted is hardcoded.
            It could come from config or an key value store at runtime
            Either within this function or given as argument.
            """
            blacklist = ['blacklisted', 'black_listed', 'BLACKLISTED']
            if val in blacklist:
                raise Invalid('{0} is in blacklist of {1}'.format(key, val))
            return val

        registered_functions['valid_address'] = blacklist_address
        test_input = {
            'id': 23,
            'addresses': [
                {'street': 'valid adress'},
                {'street': 'blacklisted'},
            ]
        }
        test_validation = {
            'id': {'validator': 'int', 'min_amount': 1},
            'addresses': {'validator': 'list', 'list_dicts': True, 'nested': {
              'street': {'validator': 'valid_address'}}
            }
        }
        with self.assertRaisesRegex(Invalid, "street is in blacklist of blacklisted"):
            _ = maat_scale(test_input, test_validation)
Beispiel #6
0
    def test_validation(self):
        """Happy path test"""
        validated_items = maat_scale(self.test_input, self.test_validation)
        difference = ddiff(validated_items, self.test_input)

        # if the differ finds no difference a empty dictionary is returned
        self.assertEqual(difference, {})
Beispiel #7
0
 def test_pre_post_transformation(self):
     """Input dict has item with type float, transform to int, validate as int, tranform back to int"""
     test_input = {'id': float(23)}
     test_validation = {'id': {'validator': 'int', 'transform': 'float', 'pre_transform': 'int'}}
     validated_items = maat_scale(test_input, test_validation)
     difference = ddiff(validated_items, test_input)
     self.assertEqual(difference, {})
Beispiel #8
0
    def test_not_set_validator(self):
        """Approriate message shown when trying to use a validator that is not registered"""
        test_input = {'id': 23}
        test_validation = {'id': {'validator': 'integer'}}

        with self.assertRaisesRegex(Invalid, 'integer is not registered as validator'):
            _ = maat_scale(test_input, test_validation)
Beispiel #9
0
    def test_validate_programming_error_trying_to_validate_non_dict(self):
        
        test_input = [1, 2, 4]
        with self.assertRaisesRegex(Invalid, "\[1, 2, 4\] not a dictionary but is of type list"):
            _ = maat_scale(test_input, self.test_validation)

        test_input = set([1, 2, 3])
        with self.assertRaisesRegex(Invalid, "\{1, 2, 3\} not a dictionary but is of type set"):
            _ = maat_scale(test_input, self.test_validation)

        test_input = 1
        with self.assertRaisesRegex(Invalid, "1 not a dictionary but is of type int"):
            _ = maat_scale(test_input, self.test_validation)

        test_input = None
        with self.assertRaisesRegex(Invalid, "None not a dictionary but is of type None"):
            _ = maat_scale(test_input, self.test_validation)
Beispiel #10
0
    def test_validation_test_remove_key_and_set_optional(self):
        """Test remove key and set optional"""

        del self.test_input['type']
        self.test_validation['type']['optional'] = True

        validated_items = maat_scale(self.test_input, self.test_validation)
        difference = ddiff(validated_items, self.test_input)
        self.assertEqual(difference, {})
Beispiel #11
0
    def test_missing_key_validation(self):
        """Items that will raise an exception"""
        del(self.test_validation['name'])

        expected_expection_msg = 'invalid keys: name :expected keys: id, type'
        if sys.version_info[1] < 6:
            expected_expection_msg = 'invalid keys: name'

        with self.assertRaisesRegex(Invalid, expected_expection_msg):
            _ = maat_scale(self.test_input, self.test_validation)
Beispiel #12
0
    def test_validation_test_remove_key_and_set_default(self):
        """Test remove key and set optional"""

        del self.test_input['type']
        excepted_value = 'banana'
        self.test_validation['type']['default_value'] = excepted_value

        validated_items = maat_scale(self.test_input, self.test_validation)
        difference = ddiff(validated_items, self.test_input)
        self.assertEqual(difference, {'dictionary_item_removed': set(["root['type']"])})
        self.assertEqual(validated_items['type'], excepted_value)
Beispiel #13
0
 def test_validate_nested_dict(self):
     self.test_input = {
         'id': 23,
         'addresses': {
             'street': 'John Doe Street',
             'number': 123,
         }
     }
     self.test_validation = {
         'id': {'validator': 'int', 'min_amount': 1},
         'addresses': {'validator': 'dict', 'key_regex': r'(\w+ )', 'nested': {
             'street': {'validator': 'str', 'min_length': 5, 'max_length': 99},
             'number': {'validator': 'int', 'min_amount': 1},
             }
         }
     }
     validated_items = maat_scale(self.test_input, self.test_validation)
     difference = ddiff(validated_items, self.test_input)
     self.assertEqual(difference, {})
Beispiel #14
0
    def test_validate_nested_list(self):
        self.test_input = {
            'id': 23,
            'addresses': [
                {'street': 'John Doe Street'},
                {'street': 'John Doe Street'},
                {'street': 'John Doe Street'},
                {'street': 'John Doe Street'},
            ]
        }
        self.test_validation = {
            'id': {'validator': 'int', 'min_amount': 1},
            'addresses': {'validator': 'list',
                'list_dicts': {
                    'street': {'validator': 'str', 'min_length': 5, 'max_length': 99},
                }
            }
        }

        validated_items = maat_scale(self.test_input, self.test_validation)
        difference = ddiff(validated_items, self.test_input)
        self.assertEqual(difference, {})
Beispiel #15
0
    def test_validate_skip_instead_of_fail_within_nested_list_with_custom_validation(self):
        from maat import registered_functions
        def blacklist_address(key, val):
            """Since this is a example blacklisted is hardcoded.
            It could come from config or an key value store at runtime
            Either within this function or given as argument.
            """
            blacklist = ['blacklisted', 'black_listed', 'BLACKLISTED']
            if val in blacklist:
                raise Invalid('{0} is in blacklist of {1}'.format(key, val))
            return val

        registered_functions['valid_address'] = blacklist_address
        test_input = {
            'id': 23,
            'addresses': [
                'blacklisted',
                'valid adress',
                'also valid address',
                'black_listed',
                'valid again',
                'BLACKLISTED',
            ]
        }
        test_validation = {
            'id': {'validator': 'int', 'min_amount': 1},
            'addresses': {'validator': 'valid_address', 'skip_failed': True, 'list': True, 'nested': True}
        }
        expected_result = {
            'id': 23,
            'addresses': [
                'valid adress',
                'also valid address',
                'valid again',
            ]
        }
        validated_items = maat_scale(test_input, test_validation)
        difference = ddiff(validated_items, expected_result)
        self.assertEqual(difference, {})
Beispiel #16
0
    def test_validate_item_800_deep_invalid_item(self):
        input_dict = current = {}
        counter_dict = counter_current = {}

        times = 800
        for _ in range(times):
            current['nested_dic'] = {}
            current = current['nested_dic']

        # set last item
        current['last'] = 4

        counter_current['nested_dic'] = {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}
        for _ in range(times - 1):
            counter_current['nested_dic']['nested'] = {'nested_dic': {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}}
            counter_current = counter_current['nested_dic']['nested']

        # increase minimal amount to 5
        counter_current['nested_dic']['nested'] = {'last': {'validator': 'int', 'min_amount': 5, 'max_amount': 10}}

        with self.assertRaisesRegex(Invalid, 'key: "last" contains invalid item "4": integer is less then 5'):
            _ = maat_scale(input_dict, counter_dict)
Beispiel #17
0
    def test_validate_invalid_depth(self):
        input_dict = current = {}
        counter_dict = counter_current = {}

        times = sys.getrecursionlimit()
        for _ in range(times):
            current['nested_dic'] = {}
            current = current['nested_dic']

        # set last item
        current['last'] = 4

        counter_current['nested_dic'] = {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}
        for _ in range(times - 1):
            counter_current['nested_dic']['nested'] = {'nested_dic': {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}}
            counter_current = counter_current['nested_dic']['nested']

        counter_current['nested_dic']['nested'] = {'last': {'validator': 'int', 'min_amount': 1, 'max_amount': 10}}

        error_msg = sys.getrecursionlimit() - 49
        with self.assertRaisesRegex(Invalid, '{}: invalid depth of dict'.format(error_msg)):
            _ = maat_scale(input_dict, counter_dict)
Beispiel #18
0
    def test_validate_item_200_deep(self):
        """Lower depth for deepdiff limits, then later tests"""
        input_dict = current = {}
        counter_dict = counter_current = {}

        times = 200
        for _ in range(times):
            current['nested_dic'] = {}
            current = current['nested_dic']

        # set last item
        current['last'] = 4

        counter_current['nested_dic'] = {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}
        for _ in range(times - 1):
            counter_current['nested_dic']['nested'] = {'nested_dic': {'validator': 'dict', 'min_amount': 0, 'max_amount': 10, 'nested': {}}}
            counter_current = counter_current['nested_dic']['nested']

        counter_current['nested_dic']['nested'] = {'last': {'validator': 'int', 'min_amount': 1, 'max_amount': 10}}

        validated_items = maat_scale(input_dict, counter_dict)
        difference = ddiff(validated_items, input_dict)
        self.assertEqual(difference, {})
Beispiel #19
0
 def test_validation_new_syntax_str_cast(self):
     test_input = {'id': 23}
     expected = {'id': '23'}
     counter_dict = {'id': {'validator': 'str', 'cast': True}}
     result = maat.maat_scale(test_input, counter_dict)
     self.assertEqual(expected, result)
Beispiel #20
0
    def test_validate_very_nested_dict(self):
        nested_dict = {
            'data': {
                'people': {
                    '7': {
                        'id': 7,
                        'name': 'John Doe',
                        'type': 'mimic',
                        'x': 823.6228647149701,
                        'y': 157.57736006592654,
                        'address': {
                            'id': 23,
                            'addresses': {
                                'street': {
                                    'two': 'deep',
                                    '222': 'deep',
                                }
                            }
                        }
                    },
                    '208': {
                        'id': 208,
                        'name': 'John Doe Too',
                        'type': 'person',
                        'x': 434.9446032612515,
                        'y': 580.0,
                        'address': {
                            'id': 23,
                            'addresses': {
                                'street': {
                                    'two': 'deep',
                                    '222': 'deep',
                                }
                            }
                        }
                    }
                },
                'streets': {
                    'id': 23,
                    'addresses': [
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                    ]
                }
            }
        }
        addresses_item = {
            'id': {'validator': 'int', 'min_amount': 1},
            'addresses': {'validator': 'list', 'nested': {
                'street': {'validator': 'dict', 'min_amount': 5, 'max_length': 99, 'nested': {
                    'two': {'validator': 'str', 'min_length': 3, 'max_length': 99},
                    '222': {'validator': 'str', 'min_length': 3, 'max_length': 99},
                        }
                    }
                }
            }
        }

        geo_item = {
            'id': {'validator': 'int', 'min_amount': 1},
            'name': {'validator': 'str', 'min_length': 1, 'max_length': 35, 'regex': '([^\s]+)'},
            'type': {'validator': 'str', 'min_length': 1, 'max_length': 25, 'regex': r'([^\s]+)'},
            'x': {'validator': 'float'},
            'y': {'validator': 'float'},
            'address': {'validator': 'dict',
                'nested': addresses_item}
        }

        nested_dict_validation = {
            'data': {'validator': 'dict', 'nested': {
                'people': {'validator': 'dict', 'min_amount': 1, 'max_amount': 99, 'aso_array': True,
                    'nested': geo_item},
                'streets': {'validator': 'dict', 'nested': {
                    'id': {'validator': 'int', 'min_amount': 1},
                    'addresses': {'validator': 'list', 'list_dicts': True, 'nested': {
                        'street': {'validator': 'str', 'min_length': 1, 'max_length': 99}
                                }
                            }
                        }
                    }
                }
            }
        }
        validated_items = maat_scale(nested_dict, nested_dict_validation)
        difference = ddiff(validated_items, nested_dict)
        self.assertEqual(difference, {})
Beispiel #21
0
    def test_validate_invalid_id(self):
        """Set id to invalid value, expect Exception"""
        self.test_input['id'] = -1

        with self.assertRaisesRegex(Invalid, 'key: "id" contains invalid item "-1": integer is less then 1'):
            _ = maat_scale(self.test_input, self.test_validation)
Beispiel #22
0
    def test_validate_very_nested_dict_fail_lowest_item(self):
        nested_dict = {
            'data': {
                'people': {
                    '7': {
                        'id': 7,
                        'name': 'John Doe',
                        'type': 'mimic',
                        'x': 823.6228647149701,
                        'y': 157.57736006592654,
                        'address': {
                            'id': 23,
                            'addresses': {
                                'street': {
                                    'two': 'deep',
                                    '222': 'deep',
                                }
                            }
                        }
                    },
                    '208': {
                        'id': 208,
                        'name': 'John Doe Too',
                        'type': 'person',
                        'x': 434.9446032612515,
                        'y': 580.0,
                        'address': {
                            'id': 23,
                            'addresses': {
                                'street': {
                                    'two': 'deep',
                                    '222': 'deep',
                                }
                            }
                        }
                    }
                },
                'streets': {
                    'id': 23,
                    'addresses': [
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                        {'street': 'John Doe Street'},
                    ]
                }
            }
        }
        addresses_item = {
            'id': {'validator': 'int', 'min_amount': 1},
            'addresses': {'validator': 'list', 'nested': {
                'street': {'validator': 'dict', 'min_amount': 5, 'max_length': 99, 'nested': {
                    'two': {'validator': 'str', 'min_length': 3, 'max_length': 99},
                    '222': {'validator': 'str', 'min_length': 3, 'max_length': 99, 'choices': [
                        'not_part_of_choices',
                        'fail_here']},
                        }
                    }
                }
            }
        }

        geo_item = {
            'id': {'validator': 'int', 'min_amount': 1},
            'name': {'validator': 'str', 'min_length': 1, 'max_length': 35, 'regex': '([^\s]+)'},
            'type': {'validator': 'str', 'min_length': 1, 'max_length': 25, 'regex': r'([^\s]+)'},
            'x': {'validator': 'float'},
            'y': {'validator': 'float'},
            'address': {'validator': 'dict',
                'nested': addresses_item}
        }

        nested_dict_validation = {
            'data': {'validator': 'dict', 'nested': {
                'people': {'validator': 'dict', 'min_amount': 1, 'max_amount': 99, 'aso_array': True,
                    'nested': geo_item},
                'streets': {'validator': 'dict', 'nested': {
                    'id': {'validator': 'int', 'min_amount': 1},
                    'addresses': {'validator': 'list', 'list_dicts': True, 'nested': {
                        'street': {'validator': 'str', 'min_length': 1, 'max_length': 99}
                                }
                            }
                        }
                    }
                }
            }
        }
        exp_exc_msg = "key: \"222\" contains invalid item \"deep\": not in valid choices \['not_part_of_choices', 'fail_here'\]"
        with self.assertRaisesRegex(Invalid, exp_exc_msg):
            _ = maat_scale(nested_dict, nested_dict_validation)
Beispiel #23
0
 def test_not_set_post_transformation_function(self):
     """a helpfull message is shown when trying to use post transformation that is not registered"""
     test_input = {'id': 23}
     test_validation = {'id': {'validator': 'float', 'transform': 'integer'}}
     with self.assertRaisesRegex(Invalid, 'integer is not registered as transformation'):
         _ = maat_scale(test_input, test_validation)
Beispiel #24
0
 def test_not_set_pre_transformation_function(self):
     """Approriate message shown when trying to use pre transformation that is not registered"""
     test_input = {'id': float(23)}
     test_validation = {'id': {'validator': 'int', 'pre_transform': 'integer'}}
     with self.assertRaisesRegex(Invalid, 'integer is not registered as transformation'):
         _ = maat_scale(test_input, test_validation)
Beispiel #25
0
    def test_missing_input_key_validation(self):
        """Items that will raise an exception"""
        del(self.test_input['id'])

        with self.assertRaisesRegex(Invalid, 'key:"id" is not set'):
            _ = maat_scale(self.test_input, self.test_validation)