def test_children_have_their_errors_dicts_built(self): e1, e2 = ( ValidationError("message 1", validator="foo", path=["bar", 0]), ValidationError("message 2", validator="quux", path=["bar", 0]), ) tree = ErrorTree([e1, e2]) self.assertEqual(tree["bar"][0].errors, {"foo" : e1, "quux" : e2})
def validate_request_body(flask_request): with open(file_name, encoding='utf-8') as f: json_content = json.load(f) user_schema = json_content['components']['schemas']['User'] # try: # result = validate(flask_request.get_json(), user_schema, format_checker=FormatChecker()) # except Exception as ex: # # return ex.__repr__() #or # error_param = ex.context[-1].instance if hasattr(ex, 'context') and len(ex.context) > 0 else ex # return ex.message # v = Draft4Validator(user_schema) cls = validator_for(user_schema) cls.check_schema(user_schema) tree = ErrorTree( cls(user_schema, format_checker=FormatChecker()).iter_errors(json_content)) # tree = ErrorTree(v.iter_errors(flask_request.get_json())) if tree.total_errors > 0: print(tree.total_errors) error_list = parse_tree_errors(tree) pprint.pprint(error_list) return ', '.join(e['message'] for e in error_list) if error_list else None
def test_it_creates_a_child_tree_for_each_nested_path(self): errors = [ ValidationError("a bar message", path=["bar"]), ValidationError("a bar -> 0 message", path=["bar", 0]), ] tree = ErrorTree(errors) self.assertIn(0, tree["bar"]) self.assertNotIn(1, tree["bar"])
def test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error(self): """ If a validator is dumb (like :validator:`required` in draft 3) and refers to a path that isn't in the instance, the tree still properly returns a subtree for that path. """ error = ValidationError( "a message", validator="foo", instance={}, path=["foo"], ) tree = ErrorTree([error]) self.assertIsInstance(tree["foo"], ErrorTree)
def validate(schema, data): """ Validates JSON schema (Draft 7 Validator) and tests data (dictionary) against it\n Returns True if schema and data is valid, or otherwise a dictionary with well formatted errors """ errors = {} # If schema is a file try: if type(schema) is not dict: schema = _load_json_file(schema) except FileNotFoundError as file_not_found: errors["schema"] = "schema file does not exist" return errors try: validator = load_validator(schema) except SchemaError as schema_error: errors["schema"] = schema_error.message return errors # Check that data is a dictionary if type(data) is not dict: errors["data"] = "data is not a dictionary" return errors # Check required fields try: validator.validate(instance=data) except Error as validate_errors: errors["fields"] = {} # if any required field is missing if validate_errors.validator == "required": # check all fields for required in schema["required"]: if required not in data: errors["fields"][required] = required + " is required" # Build error tree tree = ErrorTree(validator.iter_errors(instance=data)) if tree.total_errors > 0: for errorItem in tree: for requirementType in tree[errorItem].errors: errors["fields"][errorItem] = tree[errorItem].errors[ requirementType].message if not validator.is_valid(instance=data): return errors return True
def test_tree(self): instance = [1, {"foo": 2, "bar": {"baz": [1]}}, "quux"] schema = { "type": "string", "items": { "type": ["string", "object"], "properties": { "foo": { "enum": [1, 3] }, "bar": { "type": "array", "properties": { "bar": { "required": True }, "baz": { "minItems": 2 }, } } } } } errors = sorted_errors(self.validator.iter_errors(instance, schema)) e1, e2, e3, e4, e5, e6 = errors tree = ErrorTree(errors) self.assertEqual(len(tree), 6) self.assertIn(0, tree) self.assertIn(1, tree) self.assertIn("bar", tree[1]) self.assertIn("foo", tree[1]) self.assertIn("baz", tree[1]["bar"]) self.assertEqual(tree.errors["type"], e1) self.assertEqual(tree[0].errors["type"], e2) self.assertEqual(tree[1]["bar"].errors["type"], e3) self.assertEqual(tree[1]["bar"]["bar"].errors["required"], e4) self.assertEqual(tree[1]["bar"]["baz"].errors["minItems"], e5) self.assertEqual(tree[1]["foo"].errors["enum"], e6)
def validate(schema, value): validator = Draft4Validator(schema) if validator.is_valid(value): return {} tree = ErrorTree(validator.iter_errors(value)) result_errors = {} for key, value in tree.errors.items(): result_errors[key] = value.message for key in tree: errors = {} for error in tree[key].errors: errors[error] = tree[key].errors[error].message if errors: result_errors[key] = errors return result_errors
def error_tree(self, errors): return ErrorTree(errors=errors)
def validate(cls, data): errors = ErrorTree(Draft4Validator( cls.schema).iter_errors(data)).errors if errors: raise HTTPException(400, msg=str(errors)) return data
def test_it_does_not_contain_subtrees_that_are_not_in_the_instance(self): error = ValidationError("a message", validator="foo", instance=[]) tree = ErrorTree([error]) with self.assertRaises(IndexError): tree[0]
def test_validators_that_failed_appear_in_errors_dict(self): error = ValidationError("a message", validator="foo") tree = ErrorTree([error]) self.assertEqual(tree.errors, {"foo" : error})
def test_it_does_not_contain_an_item_if_the_item_had_no_error(self): errors = [ValidationError("a message", path=["bar"])] tree = ErrorTree(errors) self.assertNotIn("foo", tree)
def test_it_contains_an_item_if_the_item_had_an_error(self): errors = [ValidationError("a message", path=["bar"])] tree = ErrorTree(errors) self.assertIn("bar", tree)
def test_it_knows_how_many_total_errors_it_contains(self): errors = [mock.MagicMock() for _ in range(8)] tree = ErrorTree(errors) self.assertEqual(tree.total_errors, 8)