Example #1
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);
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Check each member of the actualProperty's array to make sure it matches the resource type specified for the property.
        /// </summary>
        /// <param name="actualProperty"></param>
        /// <param name="schemas"></param>
        /// <param name="detectedErrors"></param>
        /// <param name="options"></param>
        private PropertyValidationOutcome ValidateArrayProperty(ParameterDefinition actualProperty, Dictionary<string, JsonSchema> schemas, List<ValidationError> detectedErrors, ValidationOptions options)
        {
            JArray actualArray = null;
            try
            {
                actualArray = (JArray)JsonConvert.DeserializeObject(actualProperty.OriginalValue);
            }
            catch (InvalidCastException ex)
            {
                throw new InvalidCastException($"Property {actualProperty.Name} expected to be an array, but failed to cast value to an array: {actualProperty.OriginalValue}");
            }

            var expectedPropertyDefinition = this.ExpectedProperties[actualProperty.Name];
            JsonSchema memberSchema = null;
            if (actualProperty.Type.CollectionResourceType == SimpleDataType.Object && expectedPropertyDefinition.Type.CustomTypeName != null)
            {
                // We have an ambigious array, but we know what it's supposed to be so let's use that
                schemas.TryGetValue(expectedPropertyDefinition.Type.CustomTypeName, out memberSchema);
            }

            if (memberSchema == null && string.IsNullOrEmpty(actualProperty.Type.CustomTypeName))
            {
                return this.ValidateSimpleArrayProperty(actualProperty, this.ExpectedProperties[actualProperty.Name], detectedErrors);
            }
            else if (memberSchema == null && !schemas.TryGetValue(actualProperty.Type.CustomTypeName, out memberSchema))
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.ResourceTypeNotFound, null, "Failed to locate resource definition for: {0}", actualProperty.Type.CustomTypeName));
                return PropertyValidationOutcome.MissingResourceType;
            }

            bool hadErrors = false;
            for(int i=0; i<actualArray.Count; i++)
            {
                JContainer member = actualArray[i] as JContainer;
                if (member != null)
                {
                    List<ValidationError> memberErrors = new List<ValidationError>();
                    memberSchema.ValidateContainerObject(member, options, schemas, memberErrors);

                    // TODO: Filter out non-unique errors
                    hadErrors |= memberErrors.Count > 0;
                    detectedErrors.AddUniqueErrors(memberErrors);
                }
            }

            return hadErrors ? PropertyValidationOutcome.GenericError : PropertyValidationOutcome.Ok;
        }