From decde9db830ecd5ddc5d0d7c49cd2d626c324fd0 Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sat, 9 Apr 2022 14:57:09 -0400 Subject: [PATCH 01/10] Added support for Validation to produce warnings as well as errors --- .../OpenApiDiagnostic.cs | 5 +++ .../OpenApiYamlDocumentReader.cs | 11 ++++- .../Extensions/OpenApiElementExtensions.cs | 3 +- .../Validations/IValidationContext.cs | 6 +++ .../Validations/OpenApiValidatiorWarning.cs | 28 +++++++++++++ .../Validations/OpenApiValidator.cs | 25 ++++++++++++ .../Validations/Rules/OpenApiHeaderRules.cs | 1 + .../Rules/OpenApiMediaTypeRules.cs | 2 +- .../Validations/Rules/OpenApiSchemaRules.cs | 1 + .../Validations/Rules/RuleHelpers.cs | 28 ++++++------- .../Validations/ValidationExtensions.cs | 10 +++++ .../PublicApi/PublicApi.approved.txt | 10 +++++ .../OpenApiHeaderValidationTests.cs | 17 ++++---- .../OpenApiMediaTypeValidationTests.cs | 22 +++++----- .../OpenApiParameterValidationTests.cs | 20 +++++----- .../OpenApiSchemaValidationTests.cs | 40 +++++++++---------- .../Validations/ValidationRuleSetTests.cs | 2 +- 17 files changed, 162 insertions(+), 69 deletions(-) create mode 100644 src/Microsoft.OpenApi/Validations/OpenApiValidatiorWarning.cs diff --git a/src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs b/src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs index ea11c7939..c3178ccfb 100644 --- a/src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs +++ b/src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs @@ -17,6 +17,11 @@ public class OpenApiDiagnostic : IDiagnostic /// public IList Errors { get; set; } = new List(); + /// + /// List of all warnings + /// + public IList Warnings { get; set; } = new List(); + /// /// Open API specification version of the document parsed. /// diff --git a/src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs b/src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs index 6cf64a5bb..aae09ec86 100644 --- a/src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs +++ b/src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; using Microsoft.OpenApi.Exceptions; using Microsoft.OpenApi.Extensions; @@ -12,6 +13,7 @@ using Microsoft.OpenApi.Readers.Interface; using Microsoft.OpenApi.Readers.Services; using Microsoft.OpenApi.Services; +using Microsoft.OpenApi.Validations; using SharpYaml.Serialization; namespace Microsoft.OpenApi.Readers @@ -68,11 +70,16 @@ public OpenApiDocument Read(YamlDocument input, out OpenApiDiagnostic diagnostic // Validate the document if (_settings.RuleSet != null && _settings.RuleSet.Rules.Count > 0) { - var errors = document.Validate(_settings.RuleSet); - foreach (var item in errors) + var openApiErrors = document.Validate(_settings.RuleSet); + foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorError)) { diagnostic.Errors.Add(item); } + foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorWarning)) + { + diagnostic.Warnings.Add(item); + } + } return document; diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs index 81893a3b2..a047c066d 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System.Collections.Generic; +using System.Linq; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; @@ -25,7 +26,7 @@ public static IEnumerable Validate(this IOpenApiElement element, V var validator = new OpenApiValidator(ruleSet); var walker = new OpenApiWalker(validator); walker.Walk(element); - return validator.Errors; + return validator.Errors.Cast().Union(validator.Warnings); } } } diff --git a/src/Microsoft.OpenApi/Validations/IValidationContext.cs b/src/Microsoft.OpenApi/Validations/IValidationContext.cs index 58f324bab..7ab4d08e7 100644 --- a/src/Microsoft.OpenApi/Validations/IValidationContext.cs +++ b/src/Microsoft.OpenApi/Validations/IValidationContext.cs @@ -14,6 +14,12 @@ public interface IValidationContext /// Error to register. void AddError(OpenApiValidatorError error); + /// + /// Register a warning with the validation context. + /// + /// Warning to register. + void AddWarning(OpenApiValidatorWarning warning); + /// /// Allow Rule to indicate validation error occured at a deeper context level. /// diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidatiorWarning.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidatiorWarning.cs new file mode 100644 index 000000000..77480584d --- /dev/null +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidatiorWarning.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.OpenApi.Exceptions; +using Microsoft.OpenApi.Models; + +namespace Microsoft.OpenApi.Validations +{ + /// + /// Warnings detected when validating an OpenAPI Element + /// + public class OpenApiValidatorWarning : OpenApiError + { + /// + /// Initializes the class. + /// + public OpenApiValidatorWarning(string ruleName, string pointer, string message) : base(pointer, message) + { + RuleName = ruleName; + } + + /// + /// Name of rule that detected the error. + /// + public string RuleName { get; set; } + } + +} diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs index 69bcda93d..ba2ed4129 100644 --- a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs @@ -17,6 +17,7 @@ public class OpenApiValidator : OpenApiVisitorBase, IValidationContext { private readonly ValidationRuleSet _ruleSet; private readonly IList _errors = new List(); + private readonly IList _warnings = new List(); /// /// Create a vistor that will validate an OpenAPIDocument @@ -38,6 +39,17 @@ public IEnumerable Errors } } + /// + /// Gets the validation warnings. + /// + public IEnumerable Warnings + { + get + { + return _warnings; + } + } + /// /// Register an error with the validation context. /// @@ -52,6 +64,19 @@ public void AddError(OpenApiValidatorError error) _errors.Add(error); } + /// + /// Register an error with the validation context. + /// + /// Error to register. + public void AddWarning(OpenApiValidatorWarning warning) + { + if (warning == null) + { + throw Error.ArgumentNull(nameof(warning)); + } + + _warnings.Add(warning); + } /// /// Execute validation rules against an diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiHeaderRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiHeaderRules.cs index f2b036457..9ffbc38f4 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiHeaderRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiHeaderRules.cs @@ -10,6 +10,7 @@ namespace Microsoft.OpenApi.Validations.Rules /// /// The validation rules for . /// + //Removed from Default Rules as this is not a MUST in OpenAPI [OpenApiRule] public static class OpenApiHeaderRules { diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiMediaTypeRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiMediaTypeRules.cs index c86b5e79e..21ad4ef72 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiMediaTypeRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiMediaTypeRules.cs @@ -17,7 +17,7 @@ namespace Microsoft.OpenApi.Validations.Rules /// Future versions of the example parsers should not try an infer types. /// Example validation should be done as a separate post reading step so all schemas can be fully available. /// - //[OpenApiRule] + [OpenApiRule] public static class OpenApiMediaTypeRules { /// diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs index 8c45c8ff9..1639e6248 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs @@ -11,6 +11,7 @@ namespace Microsoft.OpenApi.Validations.Rules /// /// The validation rules for . /// + [OpenApiRule] public static class OpenApiSchemaRules { diff --git a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs index 05cce7fbc..630dc8e65 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs @@ -77,7 +77,7 @@ public static void ValidateDataTypeMismatch( // If value is not a string and also not an object, there is a data mismatch. if (!(value is OpenApiObject)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); return; @@ -117,7 +117,7 @@ public static void ValidateDataTypeMismatch( // If value is not a string and also not an array, there is a data mismatch. if (!(value is OpenApiArray)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); return; @@ -141,7 +141,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiInteger)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -153,7 +153,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiLong)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -165,7 +165,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiInteger)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -177,7 +177,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiFloat)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -189,7 +189,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiDouble)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -201,7 +201,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiDouble)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -213,7 +213,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiByte)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -225,7 +225,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiDate)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -237,7 +237,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiDateTime)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -249,7 +249,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiPassword)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -261,7 +261,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiString)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } @@ -273,7 +273,7 @@ public static void ValidateDataTypeMismatch( { if (!(value is OpenApiBoolean)) { - context.CreateError( + context.CreateWarning( ruleName, DataTypeMismatchedErrorMessage); } diff --git a/src/Microsoft.OpenApi/Validations/ValidationExtensions.cs b/src/Microsoft.OpenApi/Validations/ValidationExtensions.cs index a66d085c3..195df89cd 100644 --- a/src/Microsoft.OpenApi/Validations/ValidationExtensions.cs +++ b/src/Microsoft.OpenApi/Validations/ValidationExtensions.cs @@ -23,5 +23,15 @@ public static void CreateError(this IValidationContext context, string ruleName, OpenApiValidatorError error = new OpenApiValidatorError(ruleName, context.PathString, message); context.AddError(error); } + + /// + /// Helper method to simplify validation rules + /// + public static void CreateWarning(this IValidationContext context, string ruleName, string message) + { + OpenApiValidatorWarning warning = new OpenApiValidatorWarning(ruleName, context.PathString, message); + context.AddWarning(warning); + } + } } diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 0b1dc1a11..a6299a644 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1085,6 +1085,7 @@ namespace Microsoft.OpenApi.Validations { string PathString { get; } void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error); + void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning); void Enter(string segment); void Exit(); } @@ -1092,7 +1093,9 @@ namespace Microsoft.OpenApi.Validations { public OpenApiValidator(Microsoft.OpenApi.Validations.ValidationRuleSet ruleSet) { } public System.Collections.Generic.IEnumerable Errors { get; } + public System.Collections.Generic.IEnumerable Warnings { get; } public void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error) { } + public void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning) { } public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtensible item) { } public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtension item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiCallback item) { } @@ -1119,9 +1122,15 @@ namespace Microsoft.OpenApi.Validations public OpenApiValidatorError(string ruleName, string pointer, string message) { } public string RuleName { get; set; } } + public class OpenApiValidatorWarning : Microsoft.OpenApi.Models.OpenApiError + { + public OpenApiValidatorWarning(string ruleName, string pointer, string message) { } + public string RuleName { get; set; } + } public static class ValidationContextExtensions { public static void CreateError(this Microsoft.OpenApi.Validations.IValidationContext context, string ruleName, string message) { } + public static void CreateWarning(this Microsoft.OpenApi.Validations.IValidationContext context, string ruleName, string message) { } } public abstract class ValidationRule { @@ -1188,6 +1197,7 @@ namespace Microsoft.OpenApi.Validations.Rules { public static Microsoft.OpenApi.Validations.ValidationRule LicenseRequiredFields { get; } } + [Microsoft.OpenApi.Validations.Rules.OpenApiRule] public static class OpenApiMediaTypeRules { public static Microsoft.OpenApi.Validations.ValidationRule MediaTypeMismatchedDataType { get; } diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiHeaderValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiHeaderValidationTests.cs index 62fc2d1ce..6a082ec0f 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiHeaderValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiHeaderValidationTests.cs @@ -38,15 +38,16 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() walker.Walk(header); errors = validator.Errors; - bool result = !errors.Any(); + var warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/example", }); @@ -56,7 +57,7 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var header = new OpenApiHeader() { @@ -108,18 +109,18 @@ public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() var walker = new OpenApiWalker(validator); walker.Walk(header); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { // #enum/0 is not an error since the spec allows // representing an object using a string. diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiMediaTypeValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiMediaTypeValidationTests.cs index fe36bb8c2..bdffaff28 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiMediaTypeValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiMediaTypeValidationTests.cs @@ -21,7 +21,7 @@ public class OpenApiMediaTypeValidationTests public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var mediaType = new OpenApiMediaType() { Example = new OpenApiInteger(55), @@ -33,21 +33,20 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() // Act var ruleset = ValidationRuleSet.GetDefaultRuleSet(); - ruleset.Add(OpenApiMediaTypeRules.MediaTypeMismatchedDataType); var validator = new OpenApiValidator(ruleset); var walker = new OpenApiWalker(validator); walker.Walk(mediaType); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/example", }); @@ -57,7 +56,7 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var mediaType = new OpenApiMediaType() { @@ -105,23 +104,22 @@ public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() // Act var ruleset = ValidationRuleSet.GetDefaultRuleSet(); - ruleset.Add(OpenApiMediaTypeRules.MediaTypeMismatchedDataType); var validator = new OpenApiValidator(ruleset); var walker = new OpenApiWalker(validator); walker.Walk(mediaType); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { // #enum/0 is not an error since the spec allows // representing an object using a string. diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiParameterValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiParameterValidationTests.cs index a7abfd9d8..89be676c5 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiParameterValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiParameterValidationTests.cs @@ -65,7 +65,7 @@ public void ValidateRequiredIsTrueWhenInIsPathInParameter() public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var parameter = new OpenApiParameter() { Name = "parameter1", @@ -84,16 +84,16 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() var walker = new OpenApiWalker(validator); walker.Walk(parameter); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/{parameter1}/example", }); @@ -103,7 +103,7 @@ public void ValidateExampleShouldNotHaveDataTypeMismatchForSimpleSchema() public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var parameter = new OpenApiParameter() { @@ -158,18 +158,18 @@ public void ValidateExamplesShouldNotHaveDataTypeMismatchForSimpleSchema() var walker = new OpenApiWalker(validator); walker.Walk(parameter); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { // #enum/0 is not an error since the spec allows // representing an object using a string. diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs index 91b1643fa..d239e15a1 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs @@ -21,7 +21,7 @@ public class OpenApiSchemaValidationTests public void ValidateDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var schema = new OpenApiSchema() { Default = new OpenApiInteger(55), @@ -33,16 +33,16 @@ public void ValidateDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() var walker = new OpenApiWalker(validator); walker.Walk(schema); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/default", }); @@ -52,7 +52,7 @@ public void ValidateDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() public void ValidateExampleAndDefaultShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var schema = new OpenApiSchema() { Example = new OpenApiLong(55), @@ -65,17 +65,17 @@ public void ValidateExampleAndDefaultShouldNotHaveDataTypeMismatchForSimpleSchem var walker = new OpenApiWalker(validator); walker.Walk(schema); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/default", "#/example", @@ -86,7 +86,7 @@ public void ValidateExampleAndDefaultShouldNotHaveDataTypeMismatchForSimpleSchem public void ValidateEnumShouldNotHaveDataTypeMismatchForSimpleSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var schema = new OpenApiSchema() { Enum = @@ -120,18 +120,18 @@ public void ValidateEnumShouldNotHaveDataTypeMismatchForSimpleSchema() var walker = new OpenApiWalker(validator); walker.Walk(schema); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { // #enum/0 is not an error since the spec allows // representing an object using a string. @@ -145,7 +145,7 @@ public void ValidateEnumShouldNotHaveDataTypeMismatchForSimpleSchema() public void ValidateDefaultShouldNotHaveDataTypeMismatchForComplexSchema() { // Arrange - IEnumerable errors; + IEnumerable warnings; var schema = new OpenApiSchema() { Type = "object", @@ -210,12 +210,12 @@ public void ValidateDefaultShouldNotHaveDataTypeMismatchForComplexSchema() var walker = new OpenApiWalker(validator); walker.Walk(schema); - errors = validator.Errors; - bool result = !errors.Any(); + warnings = validator.Warnings; + bool result = !warnings.Any(); // Assert result.Should().BeFalse(); - errors.Select(e => e.Message).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Message).Should().BeEquivalentTo(new[] { RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, @@ -223,7 +223,7 @@ public void ValidateDefaultShouldNotHaveDataTypeMismatchForComplexSchema() RuleHelpers.DataTypeMismatchedErrorMessage, RuleHelpers.DataTypeMismatchedErrorMessage, }); - errors.Select(e => e.Pointer).Should().BeEquivalentTo(new[] + warnings.Select(e => e.Pointer).Should().BeEquivalentTo(new[] { "#/default/property1/0", "#/default/property1/2", diff --git a/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs b/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs index af259cf1b..8153e6054 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/ValidationRuleSetTests.cs @@ -43,7 +43,7 @@ public void DefaultRuleSetPropertyReturnsTheCorrectRules() Assert.NotEmpty(rules); // Update the number if you add new default rule(s). - Assert.Equal(21, rules.Count); + Assert.Equal(22, rules.Count); } } } From e990ca537b0da1547841b407a09fb369a54dc75f Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 10 Apr 2022 16:55:19 -0400 Subject: [PATCH 02/10] Made ResolveReference public again as it is used by Swashbuckle --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 2 +- test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 6ffc260d1..317cdab25 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -351,7 +351,7 @@ internal T ResolveReferenceTo(OpenApiReference reference) where T : class, IO /// /// Load the referenced object from a object /// - internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) + public IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) { if (reference == null) { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 0b1dc1a11..90e9d8f1a 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -508,6 +508,7 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IList Servers { get; set; } public System.Collections.Generic.IList Tags { get; set; } public Microsoft.OpenApi.Services.OpenApiWorkspace Workspace { get; set; } + public Microsoft.OpenApi.Interfaces.IOpenApiReferenceable ResolveReference(Microsoft.OpenApi.Models.OpenApiReference reference, bool useExternal) { } public System.Collections.Generic.IEnumerable ResolveReferences() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } From eb2189d08502574741dd997be06a09c8033a63fa Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 10 Apr 2022 16:58:25 -0400 Subject: [PATCH 03/10] Made ResolveReference public again as it is used by Swashbuckle --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 2 +- test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 6ffc260d1..317cdab25 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -351,7 +351,7 @@ internal T ResolveReferenceTo(OpenApiReference reference) where T : class, IO /// /// Load the referenced object from a object /// - internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) + public IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) { if (reference == null) { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 0b1dc1a11..90e9d8f1a 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -508,6 +508,7 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IList Servers { get; set; } public System.Collections.Generic.IList Tags { get; set; } public Microsoft.OpenApi.Services.OpenApiWorkspace Workspace { get; set; } + public Microsoft.OpenApi.Interfaces.IOpenApiReferenceable ResolveReference(Microsoft.OpenApi.Models.OpenApiReference reference, bool useExternal) { } public System.Collections.Generic.IEnumerable ResolveReferences() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } From 3f19293f23bee4c2c2c674f5314e42b8eb8866f6 Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 10 Apr 2022 17:03:38 -0400 Subject: [PATCH 04/10] Revert "Made ResolveReference public again as it is used by Swashbuckle" This reverts commit e990ca537b0da1547841b407a09fb369a54dc75f. --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 2 +- test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 317cdab25..6ffc260d1 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -351,7 +351,7 @@ internal T ResolveReferenceTo(OpenApiReference reference) where T : class, IO /// /// Load the referenced object from a object /// - public IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) + internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) { if (reference == null) { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 90e9d8f1a..0b1dc1a11 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -508,7 +508,6 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IList Servers { get; set; } public System.Collections.Generic.IList Tags { get; set; } public Microsoft.OpenApi.Services.OpenApiWorkspace Workspace { get; set; } - public Microsoft.OpenApi.Interfaces.IOpenApiReferenceable ResolveReference(Microsoft.OpenApi.Models.OpenApiReference reference, bool useExternal) { } public System.Collections.Generic.IEnumerable ResolveReferences() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } From 7e99738c2417f8af6957afebd414e57175408d2b Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 10 Apr 2022 18:17:26 -0400 Subject: [PATCH 05/10] Remove unnecessary reference that made netcoreapp2.1 incompatible --- src/Microsoft.OpenApi/Microsoft.OpenApi.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 7f3671942..4f7775d87 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -38,7 +38,6 @@ - From 85367f539870658015110f8d42f6f52a66a51d40 Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Sun, 10 Apr 2022 20:12:20 -0400 Subject: [PATCH 06/10] Fixed resolveReference properly this time --- src/Microsoft.OpenApi/Models/OpenApiDocument.cs | 10 +++++++++- .../PublicApi/PublicApi.approved.txt | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 317cdab25..59b8da16c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -351,7 +351,15 @@ internal T ResolveReferenceTo(OpenApiReference reference) where T : class, IO /// /// Load the referenced object from a object /// - public IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) + public IOpenApiReferenceable ResolveReference(OpenApiReference reference) + { + return ResolveReference(reference, false); + } + + /// + /// Load the referenced object from a object + /// + internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool useExternal) { if (reference == null) { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 90e9d8f1a..e7ba33dca 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -508,7 +508,7 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IList Servers { get; set; } public System.Collections.Generic.IList Tags { get; set; } public Microsoft.OpenApi.Services.OpenApiWorkspace Workspace { get; set; } - public Microsoft.OpenApi.Interfaces.IOpenApiReferenceable ResolveReference(Microsoft.OpenApi.Models.OpenApiReference reference, bool useExternal) { } + public Microsoft.OpenApi.Interfaces.IOpenApiReferenceable ResolveReference(Microsoft.OpenApi.Models.OpenApiReference reference) { } public System.Collections.Generic.IEnumerable ResolveReferences() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } From fce10efa2efa1917aeeeb7425c7588ef0c36fef4 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Mon, 11 Apr 2022 15:19:49 +0300 Subject: [PATCH 07/10] Update ci-build.yml for Azure Pipelines --- .azure-pipelines/ci-build.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 31af5bd24..1cb35abe1 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -270,11 +270,13 @@ stages: inputs: source: current - pwsh: | - $artifactName = Get-ChildItem -Path $(Pipeline.Workspace) -Filter Microsoft.OpenApi.Hidi-* -recurse | select -First 1 - $artifactVersion= $artifactName -replace "Microsoft.OpenApi.Hidi-", "" + $artifactName = Get-ChildItem -Path $(Pipeline.Workspace)\Nugets -Filter Microsoft.OpenApi.*.nupkg -recurse | select -First 1 + $artifactVersion= $artifactName -replace "Microsoft.OpenApi.", "" -replace ".nupkg", "" #Set Variable $artifactName and $artifactVersion Write-Host "##vso[task.setvariable variable=artifactVersion; isSecret=false; isOutput=true]$artifactVersion" Write-Host "##vso[task.setvariable variable=artifactName; isSecret=false; isOutput=true]$artifactName.FullName" + echo $artifactName + echo $artifactVersion displayName: 'Fetch Artifact Name' - task: NuGetCommand@2 @@ -290,7 +292,7 @@ stages: gitHubConnection: 'Github-MaggieKimani1' tagSource: userSpecifiedTag tag: '$(artifactVersion)' - title: '$(artifactName)' + title: '$(artifactVersion)' releaseNotesSource: inline assets: '$(Pipeline.Workspace)\**\*.exe' changeLogType: issueBased From 2fa91a81bc01bfeac0e66e3fa0b76f2852f6ffbf Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Mon, 11 Apr 2022 15:50:23 +0300 Subject: [PATCH 08/10] Update ci-build.yml for Azure Pipelines --- .azure-pipelines/ci-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 1cb35abe1..9c163ea17 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -275,8 +275,8 @@ stages: #Set Variable $artifactName and $artifactVersion Write-Host "##vso[task.setvariable variable=artifactVersion; isSecret=false; isOutput=true]$artifactVersion" Write-Host "##vso[task.setvariable variable=artifactName; isSecret=false; isOutput=true]$artifactName.FullName" - echo $artifactName - echo $artifactVersion + echo "$artifactName" + echo "$artifactVersion" displayName: 'Fetch Artifact Name' - task: NuGetCommand@2 From 27dd1e9b0fcc73ee1bbcd28efbe060a104014967 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Mon, 11 Apr 2022 15:59:38 +0300 Subject: [PATCH 09/10] Update ci-build.yml for Azure Pipelines --- .azure-pipelines/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 9c163ea17..616776585 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -271,7 +271,7 @@ stages: source: current - pwsh: | $artifactName = Get-ChildItem -Path $(Pipeline.Workspace)\Nugets -Filter Microsoft.OpenApi.*.nupkg -recurse | select -First 1 - $artifactVersion= $artifactName -replace "Microsoft.OpenApi.", "" -replace ".nupkg", "" + $artifactVersion= $artifactName.Name -replace "Microsoft.OpenApi.", "" -replace ".nupkg", "" #Set Variable $artifactName and $artifactVersion Write-Host "##vso[task.setvariable variable=artifactVersion; isSecret=false; isOutput=true]$artifactVersion" Write-Host "##vso[task.setvariable variable=artifactName; isSecret=false; isOutput=true]$artifactName.FullName" From 274acb583a7d04f90ae66410ef0fdbd967e745d7 Mon Sep 17 00:00:00 2001 From: Darrel Miller Date: Mon, 11 Apr 2022 22:45:23 -0400 Subject: [PATCH 10/10] Updated version numbers --- src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj | 2 +- src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj | 2 +- src/Microsoft.OpenApi/Microsoft.OpenApi.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj index 72ec16c0b..52d0b3c1e 100644 --- a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj +++ b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj @@ -15,7 +15,7 @@ Microsoft.OpenApi.Hidi hidi ./../../artifacts - 0.5.0-preview6 + 1.0.0-preview1 OpenAPI.NET CLI tool for slicing OpenAPI documents © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index 62da19f40..440180d88 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -10,7 +10,7 @@ Microsoft Microsoft.OpenApi.Readers Microsoft.OpenApi.Readers - 1.3.1-preview6 + 1.3.1 OpenAPI.NET Readers for JSON and YAML documents © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 8c699e023..cbdcde393 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -11,7 +11,7 @@ Microsoft Microsoft.OpenApi Microsoft.OpenApi - 1.3.1-preview6 + 1.3.1 .NET models with JSON and YAML writers for OpenAPI specification © Microsoft Corporation. All rights reserved. OpenAPI .NET