def test_decrypt_validate_and_encrypt(self): """This test takes encrypted data, validates and then encrypt""" test_input = { 'name': 'LcyInWDZsUv22ocRHM3+yg7QO9ArjlhP2R9v5CSZIRc=', 'address': 'LcyInWDZsUv22ocRHM3+yryn2OYg2jesvpgClxA/sdQ=', } counter_dict = { 'name': { 'validator': 'str', 'regex': 'John Doe', 'pre_transform': 'decode', 'transform': 'encode' }, 'address': { 'validator': 'str', 'regex': 'John Doe Street', 'pre_transform': 'decode', 'transform': 'encode' }, } validated_items = maat.scale(test_input, counter_dict) difference = ddiff(validated_items, self.expected_encoded) # if the differ finds no difference a empty dictionary is returned self.assertEqual(difference, {})
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, {})
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, {})
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, {})
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, {})
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, {})
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)
def test_validation_of_arguments(self): """Happy path test""" @validate_args(self.test_validation) def foo(number, name, kind): return locals() result = foo(**self.test_input) difference = ddiff(result, self.test_input) # if the differ finds no difference a empty dictionary is returned self.assertEqual(difference, {})
def test_validation_of_arguments_diffirent_input(self): @validate_args(self.test_validation) def foo(number, name, kind): return locals() number = self.test_input['number'] name = self.test_input['name'] kind = self.test_input['kind'] # all arguments are part of kwargs result = foo(number=number, name=name, kind=kind) difference = ddiff(result, self.test_input) self.assertEqual(difference, {}) # all arguments all part of args result = foo(number, name, kind) difference = ddiff(result, self.test_input) self.assertEqual(difference, {}) # mixed arg, kwargs arguments result = foo(number, name, kind=kind) difference = ddiff(result, self.test_input) self.assertEqual(difference, {})
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, {})
def test_validation_of_argument_fail_returns_none(self): """Test with validation failures handle them and return None""" @validate_args(self.test_validation, fail_is_none=True) def foo(number, name, kind): return locals() # change type of number from int to str result = foo(number='2', name='foo bar', kind='apple') self.assertEqual(result, None) # let's remove an argument result = foo(number=2, name='foo bar') self.assertEqual(result, None) # tests that functions still works result = foo(**self.test_input) difference = ddiff(result, self.test_input) self.assertEqual(difference, {})
def test_validation_of_argument_fail_with_custom_exception(self): """Test with validation failures raises an custom exception""" @validate_args(self.test_validation, custom_exception=KeyError) def foo(number, name, kind): return locals() # change type of number from int to str with self.assertRaisesRegex(KeyError, ''): result = foo(number='2', name='foo bar', kind='apple') # let's remove an argument with self.assertRaisesRegex(KeyError, ''): result = foo(number=2, name='foo bar') # tests that functions still works result = foo(**self.test_input) difference = ddiff(result, self.test_input) self.assertEqual(difference, {})
def test_validation_of_argument_fail(self): """Test with validation failures""" @validate_args(self.test_validation) def foo(number, name, kind): return locals() # change type of number from int to str with self.assertRaisesRegex(Invalid, 'key: "number" contains invalid item "2" with type "str": not of type int'): result = foo(number='2', name='foo bar', kind='apple') # let's remove an argument with self.assertRaisesRegex(Invalid, 'key:"kind" is not set'): result = foo(number=2, name='foo bar') # tests that functions still works result = foo(**self.test_input) difference = ddiff(result, self.test_input) self.assertEqual(difference, {})
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, {})
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, {})
def test_validate_and_transform_incoming_data(self): """This test takes data, validates and then encrypt""" test_input = { 'name': 'John Doe', 'address': 'John Doe Street', } counter_dict = { 'name': { 'validator': 'str', 'regex': 'John Doe', 'transform': 'encode' }, 'address': { 'validator': 'str', 'regex': 'John Doe Street', 'transform': 'encode' }, } validated_items = maat.scale(test_input, counter_dict) difference = ddiff(validated_items, self.expected_encoded) # if the differ finds no difference a empty dictionary is returned self.assertEqual(difference, {})
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, {})
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, {})
def test_dict_validation_valid_regex_test(self): dict_with_valid_keys = {str(i): i for i in range(5)} result = dict_validation(val=dict_with_valid_keys, key_regex='[0-9]') difference = ddiff(dict_with_valid_keys, result) self.assertEqual(difference, {})