/// <summary>
        /// Validates the value of json according to an implicit schmea defined by expectedJson
        /// </summary>
        /// <returns></returns>
        public bool ValidateJsonExample(CodeBlockAnnotation expectedResponseAnnotation, string actualResponseBodyJson, IssueLogger issues, ValidationOptions options = null)
        {
            List <ValidationError> newErrors = new List <ValidationError>();

            var resourceType = expectedResponseAnnotation.ResourceType;

            if (resourceType == "stream")
            {
                // No validation since we're streaming data
                return(true);
            }
            else
            {
                JsonSchema schema;
                if (string.IsNullOrEmpty(resourceType))
                {
                    schema = JsonSchema.EmptyResponseSchema;
                }
                else if (!this.registeredSchema.TryGetValue(resourceType, out schema))
                {
                    newErrors.Add(new ValidationWarning(ValidationErrorCode.ResponseResourceTypeMissing, null, "Missing required resource: {0}. Validation limited to basics only.", resourceType));
                    // Create a new schema based on what's available in the json
                    schema = new JsonSchema(actualResponseBodyJson, new CodeBlockAnnotation {
                        ResourceType = expectedResponseAnnotation.ResourceType
                    });
                }

                this.ValidateJsonCompilesWithSchema(schema, new JsonExample(actualResponseBodyJson, expectedResponseAnnotation), issues, options: options);
                return(issues.Issues.Count() == 0);
            }
        }
        public ValidationOptions(CodeBlockAnnotation annotation)
        {
            if (null == annotation)
                return;

            this.CollectionPropertyName = annotation.CollectionPropertyName;
            this.AllowTruncatedResponses = annotation.TruncatedResult;
        }
Beispiel #3
0
        private void ValidateCollectionObject(JContainer obj, CodeBlockAnnotation annotation, Dictionary <string, JsonSchema> otherSchemas, string collectionPropertyName, List <ValidationError> detectedErrors, ValidationOptions options)
        {
            // TODO: also validate additional properties on the collection, like nextDataLink
            var collection = obj[collectionPropertyName];

            if (null == collection)
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.MissingCollectionProperty, null, "Failed to locate collection property '{0}' in response.", collectionPropertyName));
            }
            else
            {
                var collectionMembers = obj[collectionPropertyName];
                if (!collectionMembers.Any())
                {
                    if (!annotation.IsEmpty)
                    {
                        detectedErrors.Add(
                            new ValidationWarning(
                                ValidationErrorCode.CollectionArrayEmpty,
                                null,
                                "Property contained an empty array that was not validated: {0}",
                                collectionPropertyName));
                    }
                }
                else if (annotation.IsEmpty)
                {
                    detectedErrors.Add(
                        new ValidationWarning(
                            ValidationErrorCode.CollectionArrayNotEmpty,
                            null,
                            "Property contained a non-empty array that was expected to be empty: {0}",
                            collectionPropertyName));
                }

                foreach (var jToken in collectionMembers)
                {
                    var container = jToken as JContainer;
                    if (null != container)
                    {
                        List <ValidationError> containerErrors = new List <ValidationError>();

                        var deeperOptions = new ValidationOptions(options)
                        {
                            AllowTruncatedResponses = annotation.TruncatedResult
                        };

                        this.ValidateContainerObject(
                            container,
                            deeperOptions,
                            otherSchemas,
                            containerErrors);

                        detectedErrors.AddUniqueErrors(containerErrors);
                    }
                }
            }
        }
Beispiel #4
0
        public ValidationOptions(CodeBlockAnnotation annotation)
        {
            if (null == annotation)
            {
                return;
            }

            this.CollectionPropertyName  = annotation.CollectionPropertyName;
            this.AllowTruncatedResponses = annotation.TruncatedResult;
        }
Beispiel #5
0
        private static ResourceDefinition ResourceDefinitionFromType(Schema schema, IEnumerable <Schema> otherSchema, ComplexType ct, IssueLogger issues)
        {
            var annotation = new CodeBlockAnnotation()
            {
                ResourceType = string.Concat(schema.Namespace, ".", ct.Name), BlockType = CodeBlockType.Resource
            };
            var json = BuildJsonExample(ct, otherSchema);
            ResourceDefinition rd = new JsonResourceDefinition(annotation, json, null, issues);

            return(rd);
        }
        public JsonSchema SchemaForNullTest(bool expectNulls)
        {
            var schemaObject = new
            {
                prop1 = "string",
                prop2 = 12345
            };

            string json = JsonConvert.SerializeObject(schemaObject);

            var annotation = new CodeBlockAnnotation {
                NullableProperties = expectNulls ? new string[] { "prop1", "prop2" } : new string[0]
            };

            return(new JsonSchema(json, annotation));
        }
Beispiel #7
0
        private static ResourceDefinition ResourceDefinitionFromType(Schema schema, IEnumerable <Schema> otherSchema, ComplexType ct, IssueLogger issues, MetadataValidationConfigs metadataValidationConfigs)
        {
            var resourceType = BuildResourceTypeIdentifer(
                schema.Namespace,
                metadataValidationConfigs?.ModelConfigs?.AliasNamespace,
                ct.Name,
                metadataValidationConfigs?.ModelConfigs?.ValidateNamespace);

            var annotation = new CodeBlockAnnotation()
            {
                ResourceType = resourceType, BlockType = CodeBlockType.Resource
            };
            var json = BuildJsonExample(ct, otherSchema, metadataValidationConfigs);
            ResourceDefinition rd = new JsonResourceDefinition(annotation, json, null, issues);

            return(rd);
        }
Beispiel #8
0
 public JsonSchema(string json, CodeBlockAnnotation annotation)
 {
     this.Metadata           = annotation;
     this.ExpectedProperties = this.BuildSchemaFromJson(json);
 }
Beispiel #9
0
        private void ValidateCollectionObject(JContainer obj, CodeBlockAnnotation annotation, Dictionary <string, JsonSchema> otherSchemas, string collectionPropertyName, IssueLogger issues, ValidationOptions options)
        {
            // TODO: also validate additional properties on the collection, like nextDataLink
            JToken collection = null;

            if (obj is JArray)
            {
                collection = obj;
            }
            else
            {
                try
                {
                    collection = obj[collectionPropertyName];
                }
                catch (Exception ex)
                {
                    issues.Error(ValidationErrorCode.JsonErrorObjectExpected, $"Unable to find collection parameter or array to validate: {ex.Message}");
                    return;
                }
            }

            if (null == collection)
            {
                issues.Error(ValidationErrorCode.MissingCollectionProperty, $"Failed to locate collection property '{collectionPropertyName}' in response.");
            }
            else
            {
                if (!collection.Any())
                {
                    if (!annotation.IsEmpty)
                    {
                        issues.Warning(
                            ValidationErrorCode.CollectionArrayEmpty,
                            $"Property contained an empty array that was not validated: {collectionPropertyName}");
                    }
                }
                else if (annotation.IsEmpty)
                {
                    issues.Warning(
                        ValidationErrorCode.CollectionArrayNotEmpty,
                        $"Property contained a non-empty array that was expected to be empty: {collectionPropertyName}");
                }

                foreach (var jToken in collection)
                {
                    var container = jToken as JContainer;
                    if (null != container)
                    {
                        var deeperOptions = new ValidationOptions(options)
                        {
                            AllowTruncatedResponses = annotation.TruncatedResult
                        };

                        this.ValidateContainerObject(
                            container,
                            deeperOptions,
                            otherSchemas,
                            issues.For("container", onlyKeepUniqueErrors: true));
                    }
                }
            }
        }
        /// <summary>
        /// Validates the value of json according to an implicit schmea defined by expectedJson
        /// </summary>
        /// <param name="expectedResponseAnnotation"></param>
        /// <param name="actualResponseBodyJson"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        public bool ValidateJsonExample(CodeBlockAnnotation expectedResponseAnnotation, string actualResponseBodyJson, out ValidationError[] errors, ValidationOptions options = null)
        {
            List<ValidationError> newErrors = new List<ValidationError>();

            var resourceType = expectedResponseAnnotation.ResourceType;
            if (resourceType == "stream")
            {
                // No validation since we're streaming data
                errors = null;
                return true;
            }
            else
            {
                JsonSchema schema;
                if (string.IsNullOrEmpty(resourceType))
                {
                    schema = JsonSchema.EmptyResponseSchema;
                }
                else if (!this.registeredSchema.TryGetValue(resourceType, out schema))
                {
                    newErrors.Add(new ValidationWarning(ValidationErrorCode.ResponseResourceTypeMissing, null, "Missing required resource: {0}. Validation limited to basics only.", resourceType));
                    // Create a new schema based on what's avaiable in the json
                    schema = new JsonSchema(actualResponseBodyJson, new CodeBlockAnnotation { ResourceType = expectedResponseAnnotation.ResourceType });
                }

                ValidationError[] validationJsonOutput;
                this.ValidateJsonCompilesWithSchema(schema, new JsonExample(actualResponseBodyJson, expectedResponseAnnotation), out validationJsonOutput, options: options);

                newErrors.AddRange(validationJsonOutput);
                errors = newErrors.ToArray();
                return errors.Length == 0;
            }
        }
Beispiel #11
0
 public JsonSchema(string json, CodeBlockAnnotation annotation)
 {
     this.Metadata = annotation;
     this.ExpectedProperties = this.BuildSchemaFromJson(json);
 }
Beispiel #12
0
        private void ValidateCollectionObject(JContainer obj, CodeBlockAnnotation annotation, Dictionary<string, JsonSchema> otherSchemas, string collectionPropertyName, List<ValidationError> detectedErrors)
        {
            // TODO: also validate additional properties on the collection, like nextDataLink
            var collection = obj[collectionPropertyName];
            if (null == collection)
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.MissingCollectionProperty, null, "Failed to locate collection property '{0}' in response.", collectionPropertyName));
            }
            else
            {
                var collectionMembers = obj[collectionPropertyName];
                if (!collectionMembers.Any())
                {
                    if (!annotation.IsEmpty)
                    {
                        detectedErrors.Add(
                            new ValidationWarning(
                                ValidationErrorCode.CollectionArrayEmpty,
                                null,
                                "Property contained an empty array that was not validated: {0}",
                                collectionPropertyName));
                    }
                }
                else if (annotation.IsEmpty)
                {
                    detectedErrors.Add(
                        new ValidationWarning(
                            ValidationErrorCode.CollectionArrayNotEmpty,
                            null,
                            "Property contained a non-empty array that was expected to be empty: {0}",
                            collectionPropertyName));
                }

                foreach (var jToken in collectionMembers)
                {
                    var container = jToken as JContainer;
                    if (null != container)
                    {
                        this.ValidateContainerObject(
                            container,
                            new ValidationOptions { AllowTruncatedResponses = annotation.TruncatedResult },
                            otherSchemas,
                            detectedErrors);
                    }
                }
            }
        }
Beispiel #13
0
 public JsonExample(string json, CodeBlockAnnotation annotation = null)
 {
     this.JsonData   = json;
     this.Annotation = annotation ?? new CodeBlockAnnotation();
 }
Beispiel #14
0
 private static ResourceDefinition ResourceDefinitionFromType(Schema schema, IEnumerable<Schema> otherSchema, ComplexType ct)
 {
     var annotation = new CodeBlockAnnotation() { ResourceType = string.Concat(schema.Namespace, ".", ct.Name), BlockType = CodeBlockType.Resource };
     var json = BuildJsonExample(ct, otherSchema);
     ResourceDefinition rd = new JsonResourceDefinition(annotation, json, null);
     return rd;
 }
Beispiel #15
0
 public JsonExample(string json, CodeBlockAnnotation annotation = null)
 {
     this.JsonData = json;
     this.Annotation = annotation ?? new CodeBlockAnnotation();
 }
        public JsonSchema SchemaForNullTest(bool expectNulls)
        {
            var schemaObject = new
            {
                prop1 = "string",
                prop2 = 12345
            };

            string json = JsonConvert.SerializeObject(schemaObject);

            var annotation = new CodeBlockAnnotation {
                NullableProperties = expectNulls ? new string[] { "prop1", "prop2" } : new string[0]
            };

            return new JsonSchema(json, annotation);
        }