From e89af5bcf5acea8339fe3a97f505dd598b702cad Mon Sep 17 00:00:00 2001 From: PerthCharern Date: Tue, 30 Jan 2018 11:54:20 -0800 Subject: [PATCH 1/4] - Handle URI parsing. Allows relative URI where allowed by the spec. Ensure that the reader doesn't error out when parsing absolute URI fails. - Validator should take care of validating whether the URI conforms to the spec. XML.Namespace is the only place the spec indicates the the URI must be absolute. This will be a handled in a separate PR. - formParameters temp variable is set to empty at the beginning of each operation processing. --- .../ParseNodes/JsonPointerExtensions.cs | 10 +- .../ParsingContext.cs | 3 +- .../Properties/SRResource.Designer.cs | 9 + .../Properties/SRResource.resx | 3 + .../V2/OpenApiContactDeserializer.cs | 6 +- .../V2/OpenApiDocumentDeserializer.cs | 4 +- .../V2/OpenApiExternalDocsDeserializer.cs | 6 +- .../V2/OpenApiInfoDeserializer.cs | 6 +- .../V2/OpenApiLicenseDeserializer.cs | 6 +- .../V2/OpenApiOperationDeserializer.cs | 23 +- .../V2/OpenApiParameterDeserializer.cs | 1 + .../V2/OpenApiResponseDeserializer.cs | 22 +- .../OpenApiSecurityRequirementDeserializer.cs | 4 +- .../V2/OpenApiSecuritySchemeDeserializer.cs | 12 +- .../V2/OpenApiV2VersionService.cs | 8 + .../V2/OpenApiXmlDeserializer.cs | 6 +- .../V3/OpenApiContactDeserializer.cs | 6 +- .../V3/OpenApiExternalDocsDeserializer.cs | 6 +- .../V3/OpenApiInfoDeserializer.cs | 6 +- .../V3/OpenApiLicenseDeserializer.cs | 6 +- .../V3/OpenApiOAuthFlowDeserializer.cs | 33 ++- .../V3/OpenApiSecuritySchemeDeserializer.cs | 6 +- .../V3/OpenApiV3VersionService.cs | 8 + .../V3/OpenApiXmlDeserializer.cs | 6 +- .../Extensions/OpenApiElementExtensions.cs | 10 +- .../Microsoft.OpenApi.csproj | 2 +- src/Microsoft.OpenApi/Models/OpenApiXml.cs | 2 +- .../Microsoft.OpenApi.Readers.Tests.csproj | 7 + .../V2Tests/OpenApiPathItemTests.cs | 247 ++++++++++++++++++ .../basicPathItemWithFormData.yaml | 80 ++++++ .../V3Tests/OpenApiInfoTests.cs | 40 +++ .../V3Tests/OpenApiXmlTests.cs | 30 +++ .../OpenApiInfo/basicInfoWithBrokenUrl.yaml | 15 ++ .../OpenApiXml/basicXmlWithBrokenUrl.yaml | 4 + 34 files changed, 589 insertions(+), 54 deletions(-) create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/OpenApiPathItem/basicPathItemWithFormData.yaml create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/JsonPointerExtensions.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/JsonPointerExtensions.cs index 7c8fb93d9..de4d14aa3 100644 --- a/src/Microsoft.OpenApi.Readers/ParseNodes/JsonPointerExtensions.cs +++ b/src/Microsoft.OpenApi.Readers/ParseNodes/JsonPointerExtensions.cs @@ -14,9 +14,9 @@ public static class JsonPointerExtensions /// /// Finds the YAML node that corresponds to this JSON pointer based on the base YAML node. /// - public static YamlNode Find(this JsonPointer currentpointer, YamlNode baseYamlNode) + public static YamlNode Find(this JsonPointer currentPointer, YamlNode baseYamlNode) { - if (currentpointer.Tokens.Length == 0) + if (currentPointer.Tokens.Length == 0) { return baseYamlNode; } @@ -24,7 +24,7 @@ public static YamlNode Find(this JsonPointer currentpointer, YamlNode baseYamlNo try { var pointer = baseYamlNode; - foreach (var token in currentpointer.Tokens) + foreach (var token in currentPointer.Tokens) { var sequence = pointer as YamlSequenceNode; @@ -47,9 +47,9 @@ public static YamlNode Find(this JsonPointer currentpointer, YamlNode baseYamlNo return pointer; } - catch (Exception ex) + catch (Exception) { - throw new ArgumentException("Failed to dereference pointer", ex); + return null; } } } diff --git a/src/Microsoft.OpenApi.Readers/ParsingContext.cs b/src/Microsoft.OpenApi.Readers/ParsingContext.cs index 400aad511..a79ba425f 100644 --- a/src/Microsoft.OpenApi.Readers/ParsingContext.cs +++ b/src/Microsoft.OpenApi.Readers/ParsingContext.cs @@ -27,7 +27,6 @@ public class ParsingContext internal RootNode RootNode { get; set; } internal List Tags { get; private set; } = new List(); - /// /// Initiates the parsing process. Not thread safe and should only be called once on a parsing context /// @@ -143,7 +142,7 @@ public IOpenApiReferenceable GetReferencedObject( } var reference = VersionService.ConvertToOpenApiReference(referenceString, referenceType); - + var isReferencedObjectFound = VersionService.TryLoadReference(this, reference, out referencedObject); if (isReferencedObjectFound) diff --git a/src/Microsoft.OpenApi.Readers/Properties/SRResource.Designer.cs b/src/Microsoft.OpenApi.Readers/Properties/SRResource.Designer.cs index a651f7a15..894e1da24 100644 --- a/src/Microsoft.OpenApi.Readers/Properties/SRResource.Designer.cs +++ b/src/Microsoft.OpenApi.Readers/Properties/SRResource.Designer.cs @@ -69,6 +69,15 @@ internal static string ArgumentNullOrWhiteSpace { } } + /// + /// Looks up a localized string similar to JSON pointer '{0}' does not point to an object in the document.. + /// + internal static string JsonPointerCannotBeResolved { + get { + return ResourceManager.GetString("JsonPointerCannotBeResolved", resourceCulture); + } + } + /// /// Looks up a localized string similar to Not implemented to find referenced element from external resource.. /// diff --git a/src/Microsoft.OpenApi.Readers/Properties/SRResource.resx b/src/Microsoft.OpenApi.Readers/Properties/SRResource.resx index 04a0edaca..406fada89 100644 --- a/src/Microsoft.OpenApi.Readers/Properties/SRResource.resx +++ b/src/Microsoft.OpenApi.Readers/Properties/SRResource.resx @@ -120,6 +120,9 @@ The argument '{0}' is null, empty or consists only of white-space. + + JSON pointer '{0}' does not point to an object in the document. + Not implemented to find referenced element from external resource. diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs index 7b06fa7a1..3ccd0ebfa 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs @@ -25,7 +25,11 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs index c3875c71a..d9d23e421 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs @@ -32,11 +32,11 @@ internal static partial class OpenApiV2Deserializer }, { "consumes", - (o, n) => n.Context.SetTempStorage("globalconsumes", n.CreateSimpleList(s => s.GetScalarValue())) + (o, n) => n.Context.SetTempStorage("globalConsumes", n.CreateSimpleList(s => s.GetScalarValue())) }, { "produces", - (o, n) => n.Context.SetTempStorage("globalproduces", n.CreateSimpleList(s => s.GetScalarValue())) + (o, n) => n.Context.SetTempStorage("globalProduces", n.CreateSimpleList(s => s.GetScalarValue())) }, {"paths", (o, n) => o.Paths = LoadPaths(n)}, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs index dd4b2a945..7cd1d91dc 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs @@ -26,7 +26,11 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs index d58f9771e..16e2e0b6e 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs @@ -32,7 +32,11 @@ internal static partial class OpenApiV2Deserializer { "termsOfService", (o, n) => { - o.TermsOfService = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.TermsOfService = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs index 963c572a5..6a0f80b7e 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs @@ -25,7 +25,11 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs index c7c6336bf..a04e72b69 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System; using System.Collections.Generic; using System.Linq; using Microsoft.OpenApi.Extensions; @@ -58,12 +59,12 @@ internal static partial class OpenApiV2Deserializer }, { "consumes", (o, n) => n.Context.SetTempStorage( - "operationconsumes", + "operationConsumes", n.CreateSimpleList(s => s.GetScalarValue())) }, { "produces", (o, n) => n.Context.SetTempStorage( - "operationproduces", + "operationProduces", n.CreateSimpleList(s => s.GetScalarValue())) }, { @@ -104,6 +105,12 @@ internal static partial class OpenApiV2Deserializer internal static OpenApiOperation LoadOperation(ParseNode node) { + // Reset these temp storage parameters for each operation. + node.Context.SetTempStorage("bodyParameter", null); + node.Context.SetTempStorage("formParameters", null); + node.Context.SetTempStorage("operationProduces", null); + node.Context.SetTempStorage("operationConsumes", null); + var mapNode = node.CheckMapNode("OpenApiOperation"); var operation = new OpenApiOperation(); @@ -124,7 +131,7 @@ internal static OpenApiOperation LoadOperation(ParseNode node) operation.RequestBody = CreateFormBody(node.Context, formParameters); } } - + return operation; } @@ -156,9 +163,9 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List p.Required).Select(p => p.Name).ToList() } }; - - var consumes = context.GetFromTempStorage>("operationconsumes") ?? - context.GetFromTempStorage>("globalconsumes") ?? + + var consumes = context.GetFromTempStorage>("operationConsumes") ?? + context.GetFromTempStorage>("globalConsumes") ?? new List {"application/x-www-form-urlencoded"}; var formBody = new OpenApiRequestBody @@ -175,8 +182,8 @@ private static OpenApiRequestBody CreateRequestBody( ParsingContext context, OpenApiParameter bodyParameter) { - var consumes = context.GetFromTempStorage>("operationconsumes") ?? - context.GetFromTempStorage>("globalconsumes") ?? new List {"application/json"}; + var consumes = context.GetFromTempStorage>("operationConsumes") ?? + context.GetFromTempStorage>("globalConsumes") ?? new List {"application/json"}; var requestBody = new OpenApiRequestBody { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs index 8799a13f5..d0817b011 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs @@ -154,6 +154,7 @@ private static void LoadStyle(OpenApiParameter p, string v) { switch (v) { + // TODO: Handle "csv" for query / form parameter. The style should be Form, not Simple. case "csv": p.Style = ParameterStyle.Simple; return; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs index c8c94f002..8f781c8a3 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs @@ -14,6 +14,8 @@ namespace Microsoft.OpenApi.Readers.V2 /// internal static partial class OpenApiV2Deserializer { + private static OpenApiSchema _responseSchema; + private static readonly FixedFieldMap _responseFixedFields = new FixedFieldMap { { @@ -37,7 +39,7 @@ internal static partial class OpenApiV2Deserializer { "schema", (o, n) => { - n.Context.SetTempStorage("operationschema", LoadSchema(n)); + _responseSchema = LoadSchema(n); } }, }; @@ -50,22 +52,20 @@ internal static partial class OpenApiV2Deserializer private static void ProcessProduces(OpenApiResponse response, ParsingContext context) { - var produces = context.GetFromTempStorage>("operationproduces") ?? - context.GetFromTempStorage>("globalproduces") ?? new List {"application/json"}; + var produces = context.GetFromTempStorage>("operationProduces") ?? + context.GetFromTempStorage>("globalProduces") ?? new List {"application/json"}; response.Content = new Dictionary(); - foreach (var mt in produces) + foreach (var produce in produces) { - var schema = context.GetFromTempStorage("operationschema"); - OpenApiMediaType mediaType = null; - if (schema != null) + if (_responseSchema != null) { - mediaType = new OpenApiMediaType + var mediaType = new OpenApiMediaType { - Schema = schema + Schema = _responseSchema }; - response.Content.Add(mt, mediaType); + response.Content.Add(produce, mediaType); } } } @@ -102,6 +102,8 @@ private static void LoadExample(OpenApiResponse response, string mediaType, Pars public static OpenApiResponse LoadResponse(ParseNode node) { + _responseSchema = null; + var mapNode = node.CheckMapNode("response"); var pointer = mapNode.GetReferencePointer(); diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs index 62f840e4a..65c50b642 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs @@ -33,8 +33,8 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) } else { - node.Diagnostic.Errors.Add( - new OpenApiError(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); + //node.Diagnostic.Errors.Add( + // new OpenApiError(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); } } diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs index 73d4a9fe3..55f9be412 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs @@ -56,14 +56,22 @@ internal static partial class OpenApiV2Deserializer "authorizationUrl", (o, n) => { - _flow.AuthorizationUrl = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + _flow.AuthorizationUrl = uri; + } } }, { "tokenUrl", (o, n) => { - _flow.TokenUrl = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + _flow.TokenUrl = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs index 3b2e155c2..f57922cd0 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs @@ -66,6 +66,14 @@ public bool TryLoadReference(ParsingContext context, OpenApiReference reference, var node = context.RootNode.Find(jsonPointer); + if (node == null) + { + throw new OpenApiException( + string.Format( + SRResource.JsonPointerCannotBeResolved, + jsonPointer)); + } + switch (reference.Type) { case ReferenceType.Schema: diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs index 4ae15fa15..b6e957bf7 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs @@ -25,7 +25,11 @@ internal static partial class OpenApiV2Deserializer { "namespace", (o, n) => { - o.Namespace = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Namespace = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs index 95c907243..5a8d51a99 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs @@ -31,7 +31,11 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs index a7c4ac80c..d6a17e669 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs @@ -26,7 +26,11 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs index bbcc464c3..d0c6c599c 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs @@ -38,7 +38,11 @@ internal static partial class OpenApiV3Deserializer { "termsOfService", (o, n) => { - o.TermsOfService = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.TermsOfService = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs index d5472ddcd..ff95c98bc 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs @@ -25,7 +25,11 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - o.Url = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Url = uri; + } } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs index dce3a4c14..c56ad6b00 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs @@ -17,9 +17,36 @@ internal static partial class OpenApiV3Deserializer private static readonly FixedFieldMap _oAuthFlowFixedFileds = new FixedFieldMap { - {"authorizationUrl", (o, n) => o.AuthorizationUrl = new Uri(n.GetScalarValue())}, - {"tokenUrl", (o, n) => o.TokenUrl = new Uri(n.GetScalarValue())}, - {"refreshUrl", (o, n) => o.RefreshUrl = new Uri(n.GetScalarValue())}, + { + "authorizationUrl", (o, n) => + { + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.AuthorizationUrl = uri; + } + } + }, + { + "tokenUrl", (o, n) => + { + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.TokenUrl = uri; + } + } + }, + { + "refreshUrl", (o, n) => + { + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.RefreshUrl = uri; + } + } + }, {"scopes", (o, n) => o.Scopes = n.CreateSimpleMap(LoadString)} }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs index 6779750d1..76c299aee 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs @@ -56,7 +56,11 @@ internal static partial class OpenApiV3Deserializer { "openIdConnectUrl", (o, n) => { - o.OpenIdConnectUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.OpenIdConnectUrl = uri; + } } }, { diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs index 0fe2a926a..7c0ade7b0 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs @@ -124,6 +124,14 @@ public bool TryLoadReference(ParsingContext context, OpenApiReference reference, var node = context.RootNode.Find(componentJsonPointer); + if (node == null) + { + throw new OpenApiException( + string.Format( + SRResource.JsonPointerCannotBeResolved, + componentJsonPointer)); + } + switch (reference.Type) { case ReferenceType.Schema: diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs index adca29ad5..ff95e68e5 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs @@ -25,7 +25,11 @@ internal static partial class OpenApiV3Deserializer { "namespace", (o, n) => { - o.Namespace = new Uri(n.GetScalarValue()); + Uri uri; + if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) + { + o.Namespace = uri; + } } }, { diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs index 757f419df..71e9c42d1 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs @@ -1,10 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; using Microsoft.OpenApi.Validations; @@ -18,14 +16,12 @@ public static class OpenApiElementExtensions /// /// Validate element and all child elements /// - /// - /// - /// - public static IEnumerable Validate(this IOpenApiElement element) { + public static IEnumerable Validate(this IOpenApiElement element) + { var validator = new OpenApiValidator(); var walker = new OpenApiWalker(validator); walker.Walk(element); return validator.Errors; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 0e3245741..0f0f2ca41 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -24,7 +24,7 @@ bin\$(Configuration)\$(TargetFramework)\Microsoft.OpenApi.xml ..\Microsoft.OpenApi.snk - + True diff --git a/src/Microsoft.OpenApi/Models/OpenApiXml.cs b/src/Microsoft.OpenApi/Models/OpenApiXml.cs index 1dbd8e310..b33731f65 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiXml.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiXml.cs @@ -20,7 +20,7 @@ public class OpenApiXml : IOpenApiSerializable, IOpenApiExtensible public string Name { get; set; } /// - /// The URI of the namespace definition. + /// The URI of the namespace definition. Value MUST be in the form of an absolute URI. /// public Uri Namespace { get; set; } diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index c4f403d07..da89551a6 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -55,6 +55,9 @@ Never + + Never + Never @@ -139,6 +142,7 @@ Never + @@ -202,6 +206,9 @@ Never + + Never + PreserveNewest diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs new file mode 100644 index 000000000..8eaec440b --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs @@ -0,0 +1,247 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Text; +using FluentAssertions; +using Microsoft.OpenApi.Extensions; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Readers.ParseNodes; +using Microsoft.OpenApi.Readers.V2; +using Xunit; + +namespace Microsoft.OpenApi.Readers.Tests.V2Tests +{ + [Collection("DefaultSettings")] + public class OpenApiPathItemTests + { + private const string SampleFolderPath = "V2Tests/Samples/OpenApiPathItem/"; + + private static readonly OpenApiPathItem _basicPathItemWithFormData = new OpenApiPathItem() + { + Parameters = new List + { + new OpenApiParameter() + { + Name = "id", + In = ParameterLocation.Path, + Description = "ID of pet to use", + Required = true, + Schema = new OpenApiSchema() + { + Type = "array", + Items = new OpenApiSchema() + { + Type = "string" + } + }, + Style = ParameterStyle.Simple + } + }, + Operations = + { + [OperationType.Put] = new OpenApiOperation + { + Summary = "Puts a pet in the store with form data", + Description = "", + OperationId = "putPetWithForm", + Parameters = new List + { + new OpenApiParameter + { + Name = "petId", + In = ParameterLocation.Path, + Description = "ID of pet that needs to be updated", + Required = true, + Schema = new OpenApiSchema + { + Type = "string" + } + } + }, + RequestBody = new OpenApiRequestBody + { + Content = + { + ["application/x-www-form-urlencoded"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { + Properties = + { + ["name"] = new OpenApiSchema + { + Description = "Updated name of the pet", + Type = "string" + }, + ["status"] = new OpenApiSchema + { + Description = "Updated status of the pet", + Type = "string" + } + }, + Required = new List + { + "name" + } + } + }, + ["multipart/form-data"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { + Properties = + { + ["name"] = new OpenApiSchema + { + Description = "Updated name of the pet", + Type = "string" + }, + ["status"] = new OpenApiSchema + { + Description = "Updated status of the pet", + Type = "string" + } + }, + Required = new List + { + "name" + } + } + } + } + }, + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Description = "Pet updated." + }, + ["405"] = new OpenApiResponse + { + Description = "Invalid input" + } + } + }, + [OperationType.Post] = new OpenApiOperation + { + Summary = "Posts a pet in the store with form data", + Description = "", + OperationId = "postPetWithForm", + Parameters = new List + { + new OpenApiParameter + { + Name = "petId", + In = ParameterLocation.Path, + Description = "ID of pet that needs to be updated", + Required = true, + Schema = new OpenApiSchema + { + Type = "string" + } + }, + new OpenApiParameter + { + Name = "petName", + In = ParameterLocation.Path, + Description = "Name of pet that needs to be updated", + Required = true, + Schema = new OpenApiSchema + { + Type = "string" + } + } + }, + RequestBody = new OpenApiRequestBody + { + Content = + { + ["application/x-www-form-urlencoded"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { + Properties = + { + ["name"] = new OpenApiSchema + { + Description = "Updated name of the pet", + Type = "string" + }, + ["status"] = new OpenApiSchema + { + Description = "Updated status of the pet", + Type = "string" + }, + ["skill"] = new OpenApiSchema + { + Description = "Updated skill of the pet", + Type = "string" + } + }, + Required = new List + { + "name" + } + } + }, + ["multipart/form-data"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { + Properties = + { + ["name"] = new OpenApiSchema + { + Description = "Updated name of the pet", + Type = "string" + }, + ["status"] = new OpenApiSchema + { + Description = "Updated status of the pet", + Type = "string" + }, + ["skill"] = new OpenApiSchema + { + Description = "Updated skill of the pet", + Type = "string" + } + }, + Required = new List + { + "name" + } + } + } + } + }, + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Description = "Pet updated." + } + } + } + } + }; + + [Fact] + public void ParseBasicPathItemWithFormDataShouldSucceed() + { + // Arrange + MapNode node; + using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicPathItemWithFormData.yaml"))) + { + node = TestHelper.CreateYamlMapNode(stream); + } + + // Act + var operation = OpenApiV2Deserializer.LoadPathItem(node); + + // Assert + operation.ShouldBeEquivalentTo(_basicPathItemWithFormData); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/OpenApiPathItem/basicPathItemWithFormData.yaml b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/OpenApiPathItem/basicPathItemWithFormData.yaml new file mode 100644 index 000000000..a174494bd --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/Samples/OpenApiPathItem/basicPathItemWithFormData.yaml @@ -0,0 +1,80 @@ +# Modified from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#path-item-object-example +put: + summary: Puts a pet in the store with form data + description: "" + operationId: putPetWithForm + consumes: + - application/x-www-form-urlencoded + - multipart/form-data + produces: + - application/json + - application/xml + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + type: string + - name: name + in: formData + description: Updated name of the pet + required: true + type: string + - name: status + in: formData + description: Updated status of the pet + required: false + type: string + responses: + '200': + description: Pet updated. + '405': + description: Invalid input +post: + summary: Posts a pet in the store with form data + description: "" + operationId: postPetWithForm + consumes: + - application/x-www-form-urlencoded + - multipart/form-data + produces: + - application/json + - application/xml + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + type: string + - name: petName + in: path + description: Name of pet that needs to be updated + required: true + type: string + - name: name + in: formData + description: Updated name of the pet + required: true + type: string + - name: status + in: formData + description: Updated status of the pet + required: false + type: string + - name: skill + in: formData + description: Updated skill of the pet + required: false + type: string + responses: + '200': + description: Pet updated. +parameters: +- name: id + in: path + description: ID of pet to use + required: true + type: array + items: + type: string + collectionFormat: csv \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs index b031e6f86..31631e2f5 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs @@ -119,6 +119,46 @@ public void ParseBasicInfoShouldSucceed() } } + [Fact] + public void ParseBasicInfoWithBrokenUrlShouldSucceed() + { + using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicInfoWithBrokenUrl.yaml"))) + { + var yamlStream = new YamlStream(); + yamlStream.Load(new StreamReader(stream)); + var yamlNode = yamlStream.Documents.First().RootNode; + + var context = new ParsingContext(); + var diagnostic = new OpenApiDiagnostic(); + + var node = new MapNode(context, diagnostic, (YamlMappingNode)yamlNode); + + // Act + var openApiInfo = OpenApiV3Deserializer.LoadInfo(node); + + // Assert + openApiInfo.ShouldBeEquivalentTo( + new OpenApiInfo + { + Title = "Basic Info", + Description = "Sample Description", + Version = "1.0.1", + TermsOfService = new Uri("relativeUrl/ShouldWork", UriKind.RelativeOrAbsolute), + Contact = new OpenApiContact + { + Email = "support@swagger.io", + Name = "API Support", + Url = new Uri("http://www.swagger.io/support") + }, + License = new OpenApiLicense + { + Name = "Apache 2.0", + Url = new Uri("http://www.apache.org/licenses/LICENSE-2.0.html") + } + }); + } + } + [Fact] public void ParseMinimalInfoShouldSucceed() { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs index 15218ac77..bdfd1c908 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs @@ -46,5 +46,35 @@ public void ParseBasicXmlShouldSucceed() }); } } + + [Fact] + public void ParseBasicXmlWithBrokenUrlShouldSucceed() + { + using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicXmlWithBrokenUrl.yaml"))) + { + var yamlStream = new YamlStream(); + yamlStream.Load(new StreamReader(stream)); + var yamlNode = yamlStream.Documents.First().RootNode; + + var context = new ParsingContext(); + var diagnostic = new OpenApiDiagnostic(); + + var node = new MapNode(context, diagnostic, (YamlMappingNode)yamlNode); + + // Act + var xml = OpenApiV3Deserializer.LoadXml(node); + + // Assert + xml.ShouldBeEquivalentTo( + new OpenApiXml + { + Name = "name1", + // TODO: Verify that the URL caused a parsing error. + Namespace = new Uri("brokenUrl/ShouldFail", UriKind.RelativeOrAbsolute), + Prefix = "samplePrefix", + Wrapped = true + }); + } + } } } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml new file mode 100644 index 000000000..ba71e0cb8 --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml @@ -0,0 +1,15 @@ +{ + "title": "Basic Info", + "description": "Sample Description", + "termsOfService": "relativeUrl/ShouldWork", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0.1" +} diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml new file mode 100644 index 000000000..56c69a106 --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml @@ -0,0 +1,4 @@ +name: name1 +namespace: brokenUrl/ShouldFail +prefix: samplePrefix +wrapped: true \ No newline at end of file From 55778da7f914d55830ea1df6df279b04dc902c6d Mon Sep 17 00:00:00 2001 From: PerthCharern Date: Wed, 14 Feb 2018 15:29:54 -0800 Subject: [PATCH 2/4] - Remove Url try-parse changes. URL changes will be handled separately given that we might want to change the properties to strings. - Allow relative URL where allowed by the spec. - Use constants for temp storage variable name. --- .../V2/OpenApiContactDeserializer.cs | 6 +-- .../V2/OpenApiDocumentDeserializer.cs | 4 +- .../V2/OpenApiExternalDocsDeserializer.cs | 6 +-- .../V2/OpenApiInfoDeserializer.cs | 6 +-- .../V2/OpenApiLicenseDeserializer.cs | 6 +-- .../V2/OpenApiOperationDeserializer.cs | 27 ++++++------ .../V2/OpenApiResponseDeserializer.cs | 11 +++-- .../OpenApiSecurityRequirementDeserializer.cs | 5 ++- .../V2/OpenApiSecuritySchemeDeserializer.cs | 13 ++---- .../V2/OpenApiXmlDeserializer.cs | 6 +-- .../V2/TempStorageKeys.cs | 19 +++++++++ .../V3/OpenApiContactDeserializer.cs | 6 +-- .../V3/OpenApiExternalDocsDeserializer.cs | 6 +-- .../V3/OpenApiInfoDeserializer.cs | 6 +-- .../V3/OpenApiLicenseDeserializer.cs | 6 +-- .../V3/OpenApiOAuthFlowDeserializer.cs | 18 ++------ .../V3/OpenApiSecuritySchemeDeserializer.cs | 6 +-- .../V3/OpenApiXmlDeserializer.cs | 6 +-- .../Microsoft.OpenApi.Readers.Tests.csproj | 4 -- .../V3Tests/OpenApiInfoTests.cs | 41 +------------------ .../V3Tests/OpenApiXmlTests.cs | 30 -------------- .../OpenApiInfo/basicInfoWithBrokenUrl.yaml | 15 ------- .../OpenApiXml/basicXmlWithBrokenUrl.yaml | 4 -- 23 files changed, 61 insertions(+), 196 deletions(-) create mode 100644 src/Microsoft.OpenApi.Readers/V2/TempStorageKeys.cs delete mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml delete mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs index 3ccd0ebfa..3bcddffc0 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiContactDeserializer.cs @@ -25,11 +25,7 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs index d9d23e421..82bdad7d4 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs @@ -32,11 +32,11 @@ internal static partial class OpenApiV2Deserializer }, { "consumes", - (o, n) => n.Context.SetTempStorage("globalConsumes", n.CreateSimpleList(s => s.GetScalarValue())) + (o, n) => n.Context.SetTempStorage(TempStorageKeys.GlobalConsumes, n.CreateSimpleList(s => s.GetScalarValue())) }, { "produces", - (o, n) => n.Context.SetTempStorage("globalProduces", n.CreateSimpleList(s => s.GetScalarValue())) + (o, n) => n.Context.SetTempStorage(TempStorageKeys.GlobalProduces, n.CreateSimpleList(s => s.GetScalarValue())) }, {"paths", (o, n) => o.Paths = LoadPaths(n)}, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs index 7cd1d91dc..0db7c7e6c 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiExternalDocsDeserializer.cs @@ -26,11 +26,7 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs index 16e2e0b6e..30313207d 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiInfoDeserializer.cs @@ -32,11 +32,7 @@ internal static partial class OpenApiV2Deserializer { "termsOfService", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.TermsOfService = uri; - } + o.TermsOfService = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs index 6a0f80b7e..963c572a5 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiLicenseDeserializer.cs @@ -25,11 +25,7 @@ internal static partial class OpenApiV2Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs index a04e72b69..e03b93017 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs @@ -59,12 +59,12 @@ internal static partial class OpenApiV2Deserializer }, { "consumes", (o, n) => n.Context.SetTempStorage( - "operationConsumes", + TempStorageKeys.OperationConsumes, n.CreateSimpleList(s => s.GetScalarValue())) }, { "produces", (o, n) => n.Context.SetTempStorage( - "operationProduces", + TempStorageKeys.OperationProduces, n.CreateSimpleList(s => s.GetScalarValue())) }, { @@ -106,10 +106,10 @@ internal static partial class OpenApiV2Deserializer internal static OpenApiOperation LoadOperation(ParseNode node) { // Reset these temp storage parameters for each operation. - node.Context.SetTempStorage("bodyParameter", null); - node.Context.SetTempStorage("formParameters", null); - node.Context.SetTempStorage("operationProduces", null); - node.Context.SetTempStorage("operationConsumes", null); + node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null); + node.Context.SetTempStorage(TempStorageKeys.FormParameters, null); + node.Context.SetTempStorage(TempStorageKeys.OperationProduces, null); + node.Context.SetTempStorage(TempStorageKeys.OperationConsumes, null); var mapNode = node.CheckMapNode("OpenApiOperation"); @@ -118,14 +118,14 @@ internal static OpenApiOperation LoadOperation(ParseNode node) ParseMap(mapNode, operation, _operationFixedFields, _operationPatternFields); // Build request body based on information determined while parsing OpenApiOperation - var bodyParameter = node.Context.GetFromTempStorage("bodyParameter"); + var bodyParameter = node.Context.GetFromTempStorage(TempStorageKeys.BodyParameter); if (bodyParameter != null) { operation.RequestBody = CreateRequestBody(node.Context, bodyParameter); } else { - var formParameters = node.Context.GetFromTempStorage>("formParameters"); + var formParameters = node.Context.GetFromTempStorage>(TempStorageKeys.FormParameters); if (formParameters != null) { operation.RequestBody = CreateFormBody(node.Context, formParameters); @@ -164,8 +164,8 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List>("operationConsumes") ?? - context.GetFromTempStorage>("globalConsumes") ?? + var consumes = context.GetFromTempStorage>(TempStorageKeys.OperationConsumes) ?? + context.GetFromTempStorage>(TempStorageKeys.GlobalConsumes) ?? new List {"application/x-www-form-urlencoded"}; var formBody = new OpenApiRequestBody @@ -182,8 +182,9 @@ private static OpenApiRequestBody CreateRequestBody( ParsingContext context, OpenApiParameter bodyParameter) { - var consumes = context.GetFromTempStorage>("operationConsumes") ?? - context.GetFromTempStorage>("globalConsumes") ?? new List {"application/json"}; + var consumes = context.GetFromTempStorage>(TempStorageKeys.OperationConsumes) ?? + context.GetFromTempStorage>(TempStorageKeys.GlobalConsumes) ?? + new List {"application/json"}; var requestBody = new OpenApiRequestBody { @@ -193,7 +194,7 @@ private static OpenApiRequestBody CreateRequestBody( k => k, v => new OpenApiMediaType { - Schema = bodyParameter.Schema // Should we clone this? + Schema = bodyParameter.Schema }) }; diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs index 8f781c8a3..46ac33608 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs @@ -14,8 +14,6 @@ namespace Microsoft.OpenApi.Readers.V2 /// internal static partial class OpenApiV2Deserializer { - private static OpenApiSchema _responseSchema; - private static readonly FixedFieldMap _responseFixedFields = new FixedFieldMap { { @@ -39,7 +37,7 @@ internal static partial class OpenApiV2Deserializer { "schema", (o, n) => { - _responseSchema = LoadSchema(n); + n.Context.SetTempStorage(TempStorageKeys.ResponseSchema, LoadSchema(n)); } }, }; @@ -58,11 +56,12 @@ private static void ProcessProduces(OpenApiResponse response, ParsingContext con response.Content = new Dictionary(); foreach (var produce in produces) { - if (_responseSchema != null) + var responseSchema = context.GetFromTempStorage(TempStorageKeys.ResponseSchema); + if (responseSchema != null) { var mediaType = new OpenApiMediaType { - Schema = _responseSchema + Schema = responseSchema }; response.Content.Add(produce, mediaType); @@ -102,7 +101,7 @@ private static void LoadExample(OpenApiResponse response, string mediaType, Pars public static OpenApiResponse LoadResponse(ParseNode node) { - _responseSchema = null; + node.Context.SetTempStorage(TempStorageKeys.ResponseSchema, null); var mapNode = node.CheckMapNode("response"); diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs index 65c50b642..0bcc3056f 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecurityRequirementDeserializer.cs @@ -33,8 +33,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) } else { - //node.Diagnostic.Errors.Add( - // new OpenApiError(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); + node.Diagnostic.Errors.Add( + new OpenApiError(node.Context.GetLocation(), + $"Scheme {property.Name} is not found")); } } diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs index 55f9be412..5b88f33a8 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs @@ -56,22 +56,14 @@ internal static partial class OpenApiV2Deserializer "authorizationUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - _flow.AuthorizationUrl = uri; - } + _flow.AuthorizationUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { "tokenUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - _flow.TokenUrl = uri; - } + _flow.TokenUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { @@ -91,6 +83,7 @@ internal static partial class OpenApiV2Deserializer public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node) { // Reset the local variables every time this method is called. + // TODO: Change _flow to a tempStorage variable to make the deserializer thread-safe. _flowValue = null; _flow = new OpenApiOAuthFlow(); diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs index b6e957bf7..75c7d4658 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiXmlDeserializer.cs @@ -25,11 +25,7 @@ internal static partial class OpenApiV2Deserializer { "namespace", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Namespace = uri; - } + o.Namespace = new Uri(n.GetScalarValue(), UriKind.Absolute); } }, { diff --git a/src/Microsoft.OpenApi.Readers/V2/TempStorageKeys.cs b/src/Microsoft.OpenApi.Readers/V2/TempStorageKeys.cs new file mode 100644 index 000000000..ef1bbf219 --- /dev/null +++ b/src/Microsoft.OpenApi.Readers/V2/TempStorageKeys.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +namespace Microsoft.OpenApi.Readers.V2 +{ + /// + /// Strings to be used as keys for the temporary storage. + /// + internal static class TempStorageKeys + { + public const string ResponseSchema = "responseSchema"; + public const string BodyParameter = "bodyParameter"; + public const string FormParameters = "formParameters"; + public const string OperationProduces = "operationProduces"; + public const string OperationConsumes = "operationConsumes"; + public const string GlobalConsumes = "globalConsumes"; + public const string GlobalProduces = "globalProduces"; + } +} \ No newline at end of file diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs index 5a8d51a99..2d873461a 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiContactDeserializer.cs @@ -31,11 +31,7 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs index d6a17e669..ec2c16ff1 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiExternalDocsDeserializer.cs @@ -26,11 +26,7 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs index d0c6c599c..e88b698be 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs @@ -38,11 +38,7 @@ internal static partial class OpenApiV3Deserializer { "termsOfService", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.TermsOfService = uri; - } + o.TermsOfService = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs index ff95c98bc..35e11c243 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiLicenseDeserializer.cs @@ -25,11 +25,7 @@ internal static partial class OpenApiV3Deserializer { "url", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Url = uri; - } + o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, }; diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs index c56ad6b00..96cd9af8d 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiOAuthFlowDeserializer.cs @@ -20,31 +20,19 @@ internal static partial class OpenApiV3Deserializer { "authorizationUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.AuthorizationUrl = uri; - } + o.AuthorizationUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { "tokenUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.TokenUrl = uri; - } + o.TokenUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { "refreshUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.RefreshUrl = uri; - } + o.RefreshUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, {"scopes", (o, n) => o.Scopes = n.CreateSimpleMap(LoadString)} diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs index 76c299aee..6779750d1 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs @@ -56,11 +56,7 @@ internal static partial class OpenApiV3Deserializer { "openIdConnectUrl", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.OpenIdConnectUrl = uri; - } + o.OpenIdConnectUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); } }, { diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs index ff95e68e5..0ce7ea2eb 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiXmlDeserializer.cs @@ -25,11 +25,7 @@ internal static partial class OpenApiV3Deserializer { "namespace", (o, n) => { - Uri uri; - if (Uri.TryCreate(n.GetScalarValue(), UriKind.RelativeOrAbsolute, out uri)) - { - o.Namespace = uri; - } + o.Namespace = new Uri(n.GetScalarValue(), UriKind.Absolute); } }, { diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index da89551a6..e18f07fab 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -142,7 +142,6 @@ Never - @@ -206,9 +205,6 @@ Never - - Never - PreserveNewest diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs index 31631e2f5..68e1b7e07 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs @@ -118,46 +118,7 @@ public void ParseBasicInfoShouldSucceed() }); } } - - [Fact] - public void ParseBasicInfoWithBrokenUrlShouldSucceed() - { - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicInfoWithBrokenUrl.yaml"))) - { - var yamlStream = new YamlStream(); - yamlStream.Load(new StreamReader(stream)); - var yamlNode = yamlStream.Documents.First().RootNode; - - var context = new ParsingContext(); - var diagnostic = new OpenApiDiagnostic(); - - var node = new MapNode(context, diagnostic, (YamlMappingNode)yamlNode); - - // Act - var openApiInfo = OpenApiV3Deserializer.LoadInfo(node); - - // Assert - openApiInfo.ShouldBeEquivalentTo( - new OpenApiInfo - { - Title = "Basic Info", - Description = "Sample Description", - Version = "1.0.1", - TermsOfService = new Uri("relativeUrl/ShouldWork", UriKind.RelativeOrAbsolute), - Contact = new OpenApiContact - { - Email = "support@swagger.io", - Name = "API Support", - Url = new Uri("http://www.swagger.io/support") - }, - License = new OpenApiLicense - { - Name = "Apache 2.0", - Url = new Uri("http://www.apache.org/licenses/LICENSE-2.0.html") - } - }); - } - } + [Fact] public void ParseMinimalInfoShouldSucceed() diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs index bdfd1c908..15218ac77 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiXmlTests.cs @@ -46,35 +46,5 @@ public void ParseBasicXmlShouldSucceed() }); } } - - [Fact] - public void ParseBasicXmlWithBrokenUrlShouldSucceed() - { - using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicXmlWithBrokenUrl.yaml"))) - { - var yamlStream = new YamlStream(); - yamlStream.Load(new StreamReader(stream)); - var yamlNode = yamlStream.Documents.First().RootNode; - - var context = new ParsingContext(); - var diagnostic = new OpenApiDiagnostic(); - - var node = new MapNode(context, diagnostic, (YamlMappingNode)yamlNode); - - // Act - var xml = OpenApiV3Deserializer.LoadXml(node); - - // Assert - xml.ShouldBeEquivalentTo( - new OpenApiXml - { - Name = "name1", - // TODO: Verify that the URL caused a parsing error. - Namespace = new Uri("brokenUrl/ShouldFail", UriKind.RelativeOrAbsolute), - Prefix = "samplePrefix", - Wrapped = true - }); - } - } } } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml deleted file mode 100644 index ba71e0cb8..000000000 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiInfo/basicInfoWithBrokenUrl.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{ - "title": "Basic Info", - "description": "Sample Description", - "termsOfService": "relativeUrl/ShouldWork", - "contact": { - "name": "API Support", - "url": "http://www.swagger.io/support", - "email": "support@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "1.0.1" -} diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml deleted file mode 100644 index 56c69a106..000000000 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiXml/basicXmlWithBrokenUrl.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: name1 -namespace: brokenUrl/ShouldFail -prefix: samplePrefix -wrapped: true \ No newline at end of file From ca8af7251e59ab755f01bf952e81ffb279c5d6a7 Mon Sep 17 00:00:00 2001 From: PerthCharern Date: Wed, 14 Feb 2018 16:12:08 -0800 Subject: [PATCH 3/4] Remove outdated TODO comments --- .../V2/OpenApiParameterDeserializer.cs | 2 -- .../V3Tests/OpenApiInfoTests.cs | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs index d0817b011..1542bddd9 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiParameterDeserializer.cs @@ -198,8 +198,6 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n) var value = n.GetScalarValue(); switch (value) { - // TODO: There could be multiple body/form parameters, so setting it to a global storage - // will overwrite the old parameter. Need to handle this on a per-parameter basis. case "body": n.Context.SetTempStorage("bodyParameter", o); break; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs index 68e1b7e07..c9e53f8c9 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiInfoTests.cs @@ -56,7 +56,7 @@ public void ParseAdvancedInfoShouldSucceed() }, License = new OpenApiLicense { - Extensions = { ["x-disclaimer"] = new OpenApiString("Sample Extension String Disclaimer") }, + Extensions = {["x-disclaimer"] = new OpenApiString("Sample Extension String Disclaimer")}, Name = "licenseName", Url = new Uri("http://www.example.com/url2") }, @@ -118,7 +118,6 @@ public void ParseBasicInfoShouldSucceed() }); } } - [Fact] public void ParseMinimalInfoShouldSucceed() From 58c2f84b8ed1e321baf674244db5440f0025aefa Mon Sep 17 00:00:00 2001 From: PerthCharern Date: Wed, 14 Feb 2018 16:41:54 -0800 Subject: [PATCH 4/4] missed constant assignment --- .../V2/OpenApiOperationDeserializer.cs | 2 +- .../V2/OpenApiResponseDeserializer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs index 0f604ee13..334eef646 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiOperationDeserializer.cs @@ -111,7 +111,7 @@ internal static OpenApiOperation LoadOperation(ParseNode node) node.Context.SetTempStorage(TempStorageKeys.OperationProduces, null); node.Context.SetTempStorage(TempStorageKeys.OperationConsumes, null); - var mapNode = node.CheckMapNode("OpenApiOperation"); + var mapNode = node.CheckMapNode("Operation"); var operation = new OpenApiOperation(); diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs index 46ac33608..aac2c4948 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiResponseDeserializer.cs @@ -50,8 +50,8 @@ internal static partial class OpenApiV2Deserializer private static void ProcessProduces(OpenApiResponse response, ParsingContext context) { - var produces = context.GetFromTempStorage>("operationProduces") ?? - context.GetFromTempStorage>("globalProduces") ?? new List {"application/json"}; + var produces = context.GetFromTempStorage>(TempStorageKeys.OperationProduces) ?? + context.GetFromTempStorage>(TempStorageKeys.GlobalProduces) ?? new List {"application/json"}; response.Content = new Dictionary(); foreach (var produce in produces)