diff --git a/src/Microsoft.OpenApi.Readers/Interface/IOpenApiVersionService.cs b/src/Microsoft.OpenApi.Readers/Interface/IOpenApiVersionService.cs index a7a98d781..1be9541cd 100644 --- a/src/Microsoft.OpenApi.Readers/Interface/IOpenApiVersionService.cs +++ b/src/Microsoft.OpenApi.Readers/Interface/IOpenApiVersionService.cs @@ -19,8 +19,10 @@ internal interface IOpenApiVersionService /// /// The reference string. /// The type of the reference. + /// The summary of the reference. + /// A reference description /// The object or null. - OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type); + OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type, string summary = null, string description = null); /// /// Loads an OpenAPI Element from a document fragment @@ -36,5 +38,13 @@ internal interface IOpenApiVersionService /// RootNode containing the information to be converted into an OpenAPI Document /// Instance of OpenApiDocument populated with data from rootNode OpenApiDocument LoadDocument(RootNode rootNode); + + /// + /// Gets the description and summary scalar values in a reference object for V3.1 support + /// + /// A YamlMappingNode. + /// The scalar value we're parsing. + /// The resulting node value. + string GetReferenceScalarValues(MapNode mapNode, string scalarValue); } } diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index d21c300eb..0f9564c2a 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -1,6 +1,7 @@  netstandard2.0 + 9.0 true http://go.microsoft.com/fwlink/?LinkID=288890 https://github.com/Microsoft/OpenAPI.NET diff --git a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs index 0ee5934ce..c06184677 100644 --- a/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs +++ b/src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs @@ -181,13 +181,13 @@ public override string GetRaw() return x.Serialize(_node); } - public T GetReferencedObject(ReferenceType referenceType, string referenceId) + public T GetReferencedObject(ReferenceType referenceType, string referenceId, string summary = null, string description = null) where T : IOpenApiReferenceable, new() { return new T() { UnresolvedReference = true, - Reference = Context.VersionService.ConvertToOpenApiReference(referenceId, referenceType) + Reference = Context.VersionService.ConvertToOpenApiReference(referenceId, referenceType, summary, description) }; } diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs index 33c9d7c6f..41e860aeb 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs @@ -134,7 +134,7 @@ private static ReferenceType GetReferenceTypeV2FromName(string referenceType) /// /// Parse the string to a object. /// - public OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type) + public OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type, string summary = null, string description = null) { if (!string.IsNullOrWhiteSpace(reference)) { @@ -221,5 +221,11 @@ public T LoadElement(ParseNode node) where T : IOpenApiElement { return (T)_loaders[typeof(T)](node); } + + /// + public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) + { + throw new InvalidOperationException(); + } } } diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiExampleDeserializer.cs index 1e114ad73..58f1a317c 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiExampleDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -55,7 +56,10 @@ public static OpenApiExample LoadExample(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Example, pointer); + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.Example, pointer, summary, description); } var example = new OpenApiExample(); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiHeaderDeserializer.cs index 1616d67f0..91b149db0 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiHeaderDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -89,7 +90,10 @@ public static OpenApiHeader LoadHeader(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Header, pointer); + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.Header, pointer, summary, description); } var header = new OpenApiHeader(); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiLinkDeserializer.cs index 7bf4c650b..c5419b483 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiLinkDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -61,7 +62,10 @@ public static OpenApiLink LoadLink(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Link, pointer); + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.Link, pointer, summary, description); } ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiParameterDeserializer.cs index e8fad07a5..2dd7ac1f4 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiParameterDeserializer.cs @@ -146,7 +146,10 @@ public static OpenApiParameter LoadParameter(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Parameter, pointer); + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.Parameter, pointer, summary, description); } var parameter = new OpenApiParameter(); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiPathItemDeserializer.cs index 2c4fae46b..e29a4735c 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiPathItemDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -60,10 +61,13 @@ public static OpenApiPathItem LoadPathItem(ParseNode node) if (pointer != null) { + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + return new OpenApiPathItem() { UnresolvedReference = true, - Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.PathItem) + Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.PathItem, summary, description) }; } diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiRequestBodyDeserializer.cs index a2633028e..226183b00 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiRequestBodyDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -49,7 +50,10 @@ public static OpenApiRequestBody LoadRequestBody(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.RequestBody, pointer); + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.RequestBody, pointer, summary, description); } var requestBody = new OpenApiRequestBody(); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiResponseDeserializer.cs index 9034a407b..f795ae7fd 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiResponseDeserializer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System.Collections.Generic; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -55,7 +56,11 @@ public static OpenApiResponse LoadResponse(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Response, pointer); + + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return mapNode.GetReferencedObject(ReferenceType.Response, pointer, summary, description); } var response = new OpenApiResponse(); diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiSchemaDeserializer.cs index 60727c4bb..8f465e38e 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiSchemaDeserializer.cs @@ -7,6 +7,7 @@ using Microsoft.OpenApi.Readers.ParseNodes; using System.Collections.Generic; using System.Globalization; +using System.Linq; namespace Microsoft.OpenApi.Readers.V3 { @@ -277,16 +278,18 @@ public static OpenApiSchema LoadSchema(ParseNode node) var mapNode = node.CheckMapNode(OpenApiConstants.Schema); var pointer = mapNode.GetReferencePointer(); - if (pointer != null) - { - return new OpenApiSchema() + { + var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + + return new OpenApiSchema { UnresolvedReference = true, - Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.Schema) + Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.Schema, summary, description) }; } - + var schema = new OpenApiSchema(); foreach (var propertyNode in mapNode) diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecurityRequirementDeserializer.cs index b6b80cf7b..bbc442c79 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers.ParseNodes; @@ -15,14 +16,20 @@ internal static partial class OpenApiV3Deserializer public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) { var mapNode = node.CheckMapNode("security"); - + string description = null; + string summary = null; + var securityRequirement = new OpenApiSecurityRequirement(); foreach (var property in mapNode) { - var scheme = LoadSecuritySchemeByReference( - mapNode.Context, - property.Name); + if(property.Name.Equals("description") || property.Name.Equals("summary")) + { + description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); + summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); + } + + var scheme = LoadSecuritySchemeByReference(mapNode.Context, property.Name, summary, description); var scopes = property.Value.CreateSimpleList(value => value.GetScalarValue()); @@ -42,13 +49,17 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) private static OpenApiSecurityScheme LoadSecuritySchemeByReference( ParsingContext context, - string schemeName) + string schemeName, + string summary = null, + string description = null) { var securitySchemeObject = new OpenApiSecurityScheme() { UnresolvedReference = true, Reference = new OpenApiReference() { + Summary = summary, + Description = description, Id = schemeName, Type = ReferenceType.SecurityScheme } diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs index bbea70b35..8b454bf68 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Exceptions; using Microsoft.OpenApi.Extensions; @@ -67,9 +68,13 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic) /// /// The URL of the reference /// The type of object refefenced based on the context of the reference + /// The summary of the reference + /// A reference description public OpenApiReference ConvertToOpenApiReference( string reference, - ReferenceType? type) + ReferenceType? type, + string summary = null, + string description = null) { if (!string.IsNullOrWhiteSpace(reference)) { @@ -80,6 +85,8 @@ public OpenApiReference ConvertToOpenApiReference( { return new OpenApiReference { + Summary = summary, + Description = description, Type = type, Id = reference }; @@ -89,6 +96,8 @@ public OpenApiReference ConvertToOpenApiReference( // or a simple string-style reference for tag and security scheme. return new OpenApiReference { + Summary = summary, + Description = description, Type = type, ExternalResource = segments[0] }; @@ -100,7 +109,7 @@ public OpenApiReference ConvertToOpenApiReference( // "$ref": "#/components/schemas/Pet" try { - return ParseLocalReference(segments[1]); + return ParseLocalReference(segments[1], summary, description); } catch (OpenApiException ex) { @@ -131,6 +140,8 @@ public OpenApiReference ConvertToOpenApiReference( return new OpenApiReference { + Summary = summary, + Description = description, ExternalResource = segments[0], Type = type, Id = id @@ -151,7 +162,22 @@ public T LoadElement(ParseNode node) where T : IOpenApiElement return (T)_loaders[typeof(T)](node); } - private OpenApiReference ParseLocalReference(string localReference) + + /// + public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) + { + if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase))) + { + var valueNode = mapNode.Where(x => x.Name.Equals(scalarValue)) + .Select(static x => x.Value).OfType().FirstOrDefault(); + + return valueNode.GetScalarValue(); + } + + return null; + } + + private OpenApiReference ParseLocalReference(string localReference, string summary = null, string description = null) { if (string.IsNullOrWhiteSpace(localReference)) { @@ -170,7 +196,16 @@ private OpenApiReference ParseLocalReference(string localReference) { refId = "/" + segments[3]; }; - return new OpenApiReference { Type = referenceType, Id = refId }; + + var parsedReference = new OpenApiReference + { + Summary = summary, + Description = description, + Type = referenceType, + Id = refId + }; + + return parsedReference; } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index abc36ab6c..2e94f6e8a 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -504,31 +504,51 @@ internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool switch (reference.Type) { case ReferenceType.Schema: - return this.Components.Schemas[reference.Id]; + var resolvedSchema = this.Components.Schemas[reference.Id]; + resolvedSchema.Description = reference.Description != null ? reference.Description : resolvedSchema.Description; + return resolvedSchema; case ReferenceType.PathItem: - return this.Components.PathItems[reference.Id]; + var resolvedPathItem = this.Components.PathItems[reference.Id]; + resolvedPathItem.Description = reference.Description != null ? reference.Description : resolvedPathItem.Description; + resolvedPathItem.Summary = reference.Summary != null ? reference.Summary : resolvedPathItem.Summary; + return resolvedPathItem; case ReferenceType.Response: - return this.Components.Responses[reference.Id]; + var resolvedResponse = this.Components.Responses[reference.Id]; + resolvedResponse.Description = reference.Description != null ? reference.Description : resolvedResponse.Description; + return resolvedResponse; case ReferenceType.Parameter: - return this.Components.Parameters[reference.Id]; + var resolvedParameter = this.Components.Parameters[reference.Id]; + resolvedParameter.Description = reference.Description != null ? reference.Description : resolvedParameter.Description; + return resolvedParameter; case ReferenceType.Example: - return this.Components.Examples[reference.Id]; + var resolvedExample = this.Components.Examples[reference.Id]; + resolvedExample.Summary = reference.Summary != null ? reference.Summary : resolvedExample.Summary; + resolvedExample.Description = reference.Description != null ? reference.Description : resolvedExample.Description; + return resolvedExample; case ReferenceType.RequestBody: - return this.Components.RequestBodies[reference.Id]; - + var resolvedRequestBody = this.Components.RequestBodies[reference.Id]; + resolvedRequestBody.Description = reference.Description != null ? reference.Description : resolvedRequestBody.Description; + return resolvedRequestBody; + case ReferenceType.Header: - return this.Components.Headers[reference.Id]; - + var resolvedHeader = this.Components.Headers[reference.Id]; + resolvedHeader.Description = reference.Description != null ? reference.Description : resolvedHeader.Description; + return resolvedHeader; + case ReferenceType.SecurityScheme: - return this.Components.SecuritySchemes[reference.Id]; - + var resolvedSecurityScheme = this.Components.SecuritySchemes[reference.Id]; + resolvedSecurityScheme.Description = reference.Description != null ? reference.Description : resolvedSecurityScheme.Description; + return resolvedSecurityScheme; + case ReferenceType.Link: - return this.Components.Links[reference.Id]; + var resolvedLink = this.Components.Links[reference.Id]; + resolvedLink.Description = reference.Description != null ? reference.Description : resolvedLink.Description; + return resolvedLink; case ReferenceType.Callback: return this.Components.Callbacks[reference.Id]; diff --git a/src/Microsoft.OpenApi/Models/OpenApiReference.cs b/src/Microsoft.OpenApi/Models/OpenApiReference.cs index ecc643dc3..a558e4394 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiReference.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiReference.cs @@ -12,6 +12,19 @@ namespace Microsoft.OpenApi.Models /// public class OpenApiReference : IOpenApiSerializable { + /// + /// A short summary which by default SHOULD override that of the referenced component. + /// If the referenced object-type does not allow a summary field, then this field has no effect. + /// + public string Summary { get; set; } + + /// + /// A description which by default SHOULD override that of the referenced component. + /// CommonMark syntax MAY be used for rich text representation. + /// If the referenced object-type does not allow a description field, then this field has no effect. + /// + public string Description { get; set; } + /// /// External resource in the reference. /// It maybe: @@ -122,6 +135,8 @@ public OpenApiReference() {} /// public OpenApiReference(OpenApiReference reference) { + Summary = reference?.Summary; + Description = reference?.Description; ExternalResource = reference?.ExternalResource; Type = reference?.Type; Id = reference?.Id; @@ -153,6 +168,12 @@ public void SerializeAsV3(IOpenApiWriter writer) } writer.WriteStartObject(); + + // summary + writer.WriteProperty(OpenApiConstants.Summary, Summary); + + // description + writer.WriteProperty(OpenApiConstants.Description, Description); // $ref writer.WriteProperty(OpenApiConstants.DollarRef, ReferenceV3); 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 ed5e4dcd8..73aeeac9f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -128,6 +128,9 @@ Never + + Never + Never diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs index 1636b0747..15b08166e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs @@ -16,6 +16,8 @@ using Microsoft.OpenApi.Writers; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; +using static System.Net.Mime.MediaTypeNames; namespace Microsoft.OpenApi.Readers.Tests.V3Tests { @@ -1777,5 +1779,22 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }); } + + [Fact] + public void ParseDocumentWithDescriptionInDollarRefsShouldSucceed() + { + // Arrange + using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "documentWithSummaryAndDescriptionInReference.yaml")); + + // Act + var actual = new OpenApiStreamReader().Read(stream, out var diagnostic); + var schema = actual.Paths["/pets"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema; + var header = actual.Components.Responses["Test"].Headers["X-Test"]; + + // Assert + Assert.True(header.Description == "A referenced X-Test header"); /*response header #ref's description overrides the header's description*/ + Assert.True(schema.UnresolvedReference == false && schema.Type == "object"); /*schema reference is resolved*/ + Assert.Equal("A pet in a petstore", schema.Description); /*The reference object's description overrides that of the referenced component*/ + } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml new file mode 100644 index 000000000..0d061203d --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml @@ -0,0 +1,46 @@ +openapi: '3.1.0' +info: + version: '1.0.0' + title: Swagger Petstore (Simple) +paths: + /pets: + get: + description: Returns all pets from the system that the user has access to + responses: + '200': + description: pet response + content: + application/json: + schema: + "$ref": '#/components/schemas/pet' + summary: A pet + description: A pet in a petstore +components: + headers: + X-Test: + description: Test + schema: + type: string + responses: + Test: + description: Test Repsonse + headers: + X-Test: + $ref: '#/components/headers/X-Test' + summary: X-Test header + description: A referenced X-Test header + schemas: + pet: + description: A referenced pet in a petstore + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs index 4f00525e9..e9acbd486 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiInfoTests.cs @@ -110,7 +110,6 @@ public static IEnumerable AdvanceInfoJsonExpect() specVersion, @"{ ""title"": ""Sample Pet Store App"", - ""summary"": ""This is a sample server for a pet store."", ""description"": ""This is a sample server for a pet store."", ""termsOfService"": ""http://example.com/terms/"", ""contact"": { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index ca5de6680..b42325207 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1,7 +1,7 @@ [assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Microsoft/OpenAPI.NET")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Microsoft.OpenApi.Readers.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Microsoft.OpenApi.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100957cb48387b2a5f54f5ce39255f18f26d32a39990db27cf48737afc6bc62759ba996b8a2bfb675d4e39f3d06ecb55a178b1b4031dcb2a767e29977d88cce864a0d16bfc1b3bebb0edf9fe285f10fffc0a85f93d664fa05af07faa3aad2e545182dbf787e3fd32b56aca95df1a3c4e75dec164a3f1a4c653d971b01ffc39eb3c4")] -[assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName="")] +[assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")] namespace Microsoft.OpenApi.Any { public enum AnyType @@ -424,6 +424,7 @@ namespace Microsoft.OpenApi.Models public const string Head = "head"; public const string Headers = "headers"; public const string Host = "host"; + public const string Identifier = "identifier"; public const string Implicit = "implicit"; public const string In = "in"; public const string Info = "info"; @@ -644,6 +645,7 @@ namespace Microsoft.OpenApi.Models public OpenApiLicense() { } public OpenApiLicense(Microsoft.OpenApi.Models.OpenApiLicense license) { } public System.Collections.Generic.IDictionary Extensions { get; set; } + public string Identifier { get; set; } public string Name { get; set; } public System.Uri Url { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -780,6 +782,7 @@ namespace Microsoft.OpenApi.Models { public OpenApiReference() { } public OpenApiReference(Microsoft.OpenApi.Models.OpenApiReference reference) { } + public string Description { get; set; } public string ExternalResource { get; set; } public Microsoft.OpenApi.Models.OpenApiDocument HostDocument { get; set; } public string Id { get; set; } @@ -787,6 +790,7 @@ namespace Microsoft.OpenApi.Models public bool IsLocal { get; } public string ReferenceV2 { get; } public string ReferenceV3 { get; } + public string Summary { get; set; } public Microsoft.OpenApi.Models.ReferenceType? Type { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { }