diff --git a/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs b/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs index d1f6f7f64..a0dc1ae0e 100644 --- a/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs +++ b/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Services; namespace Microsoft.OpenApi.Hidi @@ -68,7 +69,7 @@ public override void Visit(OpenApiLink link) public int CallbackCount { get; set; } - public override void Visit(OpenApiCallback callback) + public override void Visit(IOpenApiCallback callback) { CallbackCount++; } diff --git a/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs b/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs index fafbc8188..db9f1add9 100644 --- a/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs +++ b/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Services; namespace Microsoft.OpenApi.Workbench @@ -68,7 +69,7 @@ public override void Visit(OpenApiLink link) public int CallbackCount { get; set; } - public override void Visit(OpenApiCallback callback) + public override void Visit(IOpenApiCallback callback) { CallbackCount++; } diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs index 99b5dde2d..74a38e04a 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs @@ -38,6 +38,7 @@ public interface IOpenApiReferenceHolder : IOpenApiSerializable /// Indicates if object is populated with data or is just a reference to the data /// bool UnresolvedReference { get; set; } + //TODO the UnresolvedReference property setter should be removed and a default implementation that checks whether the target is null for the getter should be provided instead /// /// Reference object. diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs new file mode 100644 index 000000000..a8fde7697 --- /dev/null +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs @@ -0,0 +1,18 @@ + +using System.Collections.Generic; +using Microsoft.OpenApi.Expressions; +using Microsoft.OpenApi.Interfaces; + +namespace Microsoft.OpenApi.Models.Interfaces; + +/// +/// Defines the base properties for the callback object. +/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. +/// +public interface IOpenApiCallback : IOpenApiSerializable, IOpenApiReadOnlyExtensible +{ + /// + /// A Path Item Object used to define a callback request and expected responses. + /// + public Dictionary PathItems { get; } +} diff --git a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs index f538d90c0..953792a79 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models @@ -12,28 +13,17 @@ namespace Microsoft.OpenApi.Models /// /// Callback Object: A map of possible out-of band callbacks related to the parent operation. /// - public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible + public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiCallback { - /// - /// A Path Item Object used to define a callback request and expected responses. - /// - public virtual Dictionary PathItems { get; set; } - = new(); + /// + public Dictionary PathItems { get; set; } + = []; - /// - /// Indicates if object is populated with data or is just a reference to the data - /// - public virtual bool UnresolvedReference { get; set; } - - /// - /// Reference pointer. - /// - public OpenApiReference Reference { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public virtual IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -43,11 +33,9 @@ public OpenApiCallback() { } /// /// Initializes a copy of an object /// - public OpenApiCallback(OpenApiCallback callback) + public OpenApiCallback(IOpenApiCallback callback) { PathItems = callback?.PathItems != null ? new(callback?.PathItems) : null; - UnresolvedReference = callback?.UnresolvedReference ?? UnresolvedReference; - Reference = callback?.Reference != null ? new(callback?.Reference) : null; Extensions = callback?.Extensions != null ? new Dictionary(callback.Extensions) : null; } @@ -71,7 +59,7 @@ public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem) /// /// /// - public virtual void SerializeAsV31(IOpenApiWriter writer) + public void SerializeAsV31(IOpenApiWriter writer) { SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer)); } @@ -79,7 +67,7 @@ public virtual void SerializeAsV31(IOpenApiWriter writer) /// /// Serialize to Open Api v3.0 /// - public virtual void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV3(IOpenApiWriter writer) { SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs index 6ca0089b4..686ed1326 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs @@ -25,55 +25,55 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Responses { get; set; } = new Dictionary(); + public IDictionary? Responses { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Parameters { get; set; } = + public IDictionary? Parameters { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Examples { get; set; } = new Dictionary(); + public IDictionary? Examples { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? RequestBodies { get; set; } = + public IDictionary? RequestBodies { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Headers { get; set; } = new Dictionary(); + public IDictionary? Headers { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? SecuritySchemes { get; set; } = + public IDictionary? SecuritySchemes { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Links { get; set; } = new Dictionary(); + public IDictionary? Links { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. /// - public virtual IDictionary? Callbacks { get; set; } = new Dictionary(); + public IDictionary? Callbacks { get; set; } = new Dictionary(); /// /// An object to hold reusable Object. /// - public virtual IDictionary? PathItems { get; set; } = new Dictionary(); + public IDictionary? PathItems { get; set; } = new Dictionary(); /// /// This object MAY be extended with Specification Extensions. /// - public virtual IDictionary? Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -93,7 +93,7 @@ public OpenApiComponents(OpenApiComponents? components) Headers = components?.Headers != null ? new Dictionary(components.Headers) : null; SecuritySchemes = components?.SecuritySchemes != null ? new Dictionary(components.SecuritySchemes) : null; Links = components?.Links != null ? new Dictionary(components.Links) : null; - Callbacks = components?.Callbacks != null ? new Dictionary(components.Callbacks) : null; + Callbacks = components?.Callbacks != null ? new Dictionary(components.Callbacks) : null; PathItems = components?.PathItems != null ? new Dictionary(components.PathItems) : null; Extensions = components?.Extensions != null ? new Dictionary(components.Extensions) : null; } diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 9b7099f56..0e9f510ea 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -608,7 +608,7 @@ public bool AddComponent(string id, T componentToRegister) Components.Links.Add(id, openApiLink); break; case OpenApiCallback openApiCallback: - Components.Callbacks ??= new Dictionary(); + Components.Callbacks ??= new Dictionary(); Components.Callbacks.Add(id, openApiCallback); break; case OpenApiPathItem openApiPathItem: diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs index 7e3b5d712..beeb1c7e2 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; @@ -80,7 +81,7 @@ public class OpenApiOperation : IOpenApiSerializable, IOpenApiExtensible, IOpenA /// The key value used to identify the callback object is an expression, evaluated at runtime, /// that identifies a URL to use for the callback operation. /// - public IDictionary? Callbacks { get; set; } = new Dictionary(); + public IDictionary? Callbacks { get; set; } = new Dictionary(); /// /// Declares this operation to be deprecated. Consumers SHOULD refrain from usage of the declared operation. @@ -129,7 +130,7 @@ public OpenApiOperation(OpenApiOperation? operation) Parameters = operation?.Parameters != null ? new List(operation.Parameters) : null; RequestBody = operation?.RequestBody != null ? new(operation?.RequestBody) : null; Responses = operation?.Responses != null ? new(operation?.Responses) : null; - Callbacks = operation?.Callbacks != null ? new Dictionary(operation.Callbacks) : null; + Callbacks = operation?.Callbacks != null ? new Dictionary(operation.Callbacks) : null; Deprecated = operation?.Deprecated ?? Deprecated; Security = operation?.Security != null ? new List(operation.Security) : null; Servers = operation?.Servers != null ? new List(operation.Servers) : null; diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs index 13cea041a..bc75e8e5c 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,11 +13,15 @@ namespace Microsoft.OpenApi.Models.References /// /// Callback Object Reference: A reference to a map of possible out-of band callbacks related to the parent operation. /// - public class OpenApiCallbackReference : OpenApiCallback, IOpenApiReferenceHolder + public class OpenApiCallbackReference : IOpenApiCallback, IOpenApiReferenceHolder { #nullable enable internal OpenApiCallback _target; - private readonly OpenApiReference _reference; + /// + public OpenApiReference Reference { get; set; } + + /// + public bool UnresolvedReference { get; set; } /// /// Gets the target callback. @@ -29,7 +34,7 @@ public OpenApiCallback Target { get { - _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(Reference); return _target; } } @@ -48,22 +53,31 @@ public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument { Utils.CheckArgumentNullOrEmpty(referenceId); - _reference = new OpenApiReference() + Reference = new OpenApiReference() { Id = referenceId, HostDocument = hostDocument, Type = ReferenceType.Callback, ExternalResource = externalResource }; + } - Reference = _reference; + /// + /// Copy constructor + /// + /// The callback reference to copy + public OpenApiCallbackReference(OpenApiCallbackReference callback) + { + Utils.CheckArgumentNull(callback); + Reference = callback?.Reference != null ? new(callback.Reference) : null; + UnresolvedReference = callback?.UnresolvedReference ?? false; } internal OpenApiCallbackReference(OpenApiCallback target, string referenceId) { _target = target; - _reference = new OpenApiReference() + Reference = new OpenApiReference() { Id = referenceId, Type = ReferenceType.Callback, @@ -71,18 +85,17 @@ internal OpenApiCallbackReference(OpenApiCallback target, string referenceId) } /// - public override Dictionary PathItems { get => Target.PathItems; set => Target.PathItems = value; } + public Dictionary PathItems { get => Target.PathItems; } /// - public override IDictionary Extensions { get => Target.Extensions; set => Target.Extensions = value; } + public IDictionary Extensions { get => Target.Extensions; } /// - public override void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV3(IOpenApiWriter writer) { - if (!writer.GetSettings().ShouldInlineReference(_reference)) + if (!writer.GetSettings().ShouldInlineReference(Reference)) { - _reference.SerializeAsV3(writer); - return; + Reference.SerializeAsV3(writer); } else { @@ -91,12 +104,11 @@ public override void SerializeAsV3(IOpenApiWriter writer) } /// - public override void SerializeAsV31(IOpenApiWriter writer) + public void SerializeAsV31(IOpenApiWriter writer) { - if (!writer.GetSettings().ShouldInlineReference(_reference)) + if (!writer.GetSettings().ShouldInlineReference(Reference)) { - _reference.SerializeAsV31(writer); - return; + Reference.SerializeAsV31(writer); } else { @@ -104,6 +116,21 @@ public override void SerializeAsV31(IOpenApiWriter writer) } } + /// + public IOpenApiCallback CopyReferenceAsTargetElementWithOverrides(IOpenApiCallback openApiExample) + { + // the copy here is never called since callbacks do not have any overridable fields. + // if the spec evolves to include overridable fields for callbacks, the serialize methods will need to call this copy method. + return openApiExample is OpenApiCallback ? new OpenApiCallback(this) : openApiExample; + } + + /// + public void SerializeAsV2(IOpenApiWriter writer) + { + // examples components are not supported in OAS 2.0 + Reference.SerializeAsV2(writer); + } + /// private void SerializeInternal(IOpenApiWriter writer, Action action) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs index 0f8638c3e..dc1a22ee9 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs @@ -19,7 +19,7 @@ public class OpenApiExampleReference : IOpenApiReferenceHolder - public bool UnresolvedReference { get; set; } = false; + public bool UnresolvedReference { get; set; } internal OpenApiExample _target; /// @@ -68,7 +68,7 @@ public OpenApiExampleReference(OpenApiExampleReference example) { Utils.CheckArgumentNull(example); Reference = example?.Reference != null ? new(example.Reference) : null; - UnresolvedReference = example?.UnresolvedReference ?? UnresolvedReference; + UnresolvedReference = example?.UnresolvedReference ?? false; //no need to copy summary and description as if they are not overridden, they will be fetched from the target //if they are, the reference copy will handle it } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs index bdf4a8716..adab9ccab 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs @@ -4,6 +4,7 @@ using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; @@ -24,7 +25,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) { var mapNode = node.CheckMapNode("callback"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs index c0d4c5951..49407e339 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs @@ -4,6 +4,7 @@ using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; using Microsoft.OpenApi.Models.References; +using Microsoft.OpenApi.Models.Interfaces; namespace Microsoft.OpenApi.Reader.V31 { @@ -23,7 +24,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-", StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) { var mapNode = node.CheckMapNode("callback"); diff --git a/src/Microsoft.OpenApi/Services/CopyReferences.cs b/src/Microsoft.OpenApi/Services/CopyReferences.cs index 086961a94..944fabe87 100644 --- a/src/Microsoft.OpenApi/Services/CopyReferences.cs +++ b/src/Microsoft.OpenApi/Services/CopyReferences.cs @@ -136,9 +136,9 @@ private void AddCallbackToComponents(OpenApiCallback callback, string referenceI { EnsureComponentsExist(); EnsureCallbacksExist(); - if (!Components.Callbacks.ContainsKey(referenceId ?? callback.Reference.Id)) + if (!Components.Callbacks.ContainsKey(referenceId)) { - Components.Callbacks.Add(referenceId ?? callback.Reference.Id, callback); + Components.Callbacks.Add(referenceId, callback); } } private void AddHeaderToComponents(OpenApiHeader header, string referenceId = null) @@ -230,7 +230,7 @@ private void EnsureHeadersExist() private void EnsureCallbacksExist() { - _target.Components.Callbacks ??= new Dictionary(); + _target.Components.Callbacks ??= new Dictionary(); } private void EnsureLinksExist() diff --git a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs index 8f0c24de5..1bd202ff7 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs @@ -169,7 +169,7 @@ public virtual void Visit(IDictionary headers) /// /// Visits callbacks. /// - public virtual void Visit(IDictionary callbacks) + public virtual void Visit(IDictionary callbacks) { } @@ -251,9 +251,9 @@ public virtual void Visit(OpenApiLink link) } /// - /// Visits + /// Visits /// - public virtual void Visit(OpenApiCallback callback) + public virtual void Visit(IOpenApiCallback callback) { } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs index 94a263bd0..47a4f4c2e 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs @@ -406,9 +406,9 @@ internal void Walk(OpenApiContact contact) } /// - /// Visits and child objects + /// Visits and child objects /// - internal void Walk(OpenApiCallback callback, bool isComponent = false) + internal void Walk(IOpenApiCallback callback, bool isComponent = false) { if (callback == null) { @@ -760,9 +760,9 @@ internal void Walk(IDictionary headers) } /// - /// Visits dictionary of + /// Visits dictionary of /// - internal void Walk(IDictionary callbacks) + internal void Walk(IDictionary callbacks) { if (callbacks == null) { @@ -1191,7 +1191,7 @@ internal void Walk(IOpenApiElement element) case OpenApiInfo e: Walk(e); break; case OpenApiComponents e: Walk(e); break; case OpenApiContact e: Walk(e); break; - case OpenApiCallback e: Walk(e); break; + case IOpenApiCallback e: Walk(e); break; case OpenApiEncoding e: Walk(e); break; case IOpenApiExample e: Walk(e); break; case IDictionary e: Walk(e); break; diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs index 0cc7ade2b..8ec8d4ca0 100644 --- a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs @@ -117,7 +117,7 @@ public void AddWarning(OpenApiValidatorWarning warning) public override void Visit(OpenApiEncoding encoding) => Validate(encoding); /// - public override void Visit(OpenApiCallback callback) => Validate(callback); + public override void Visit(IOpenApiCallback callback) => Validate(callback); /// public override void Visit(IOpenApiExtensible openApiExtensible) => Validate(openApiExtensible); @@ -159,7 +159,7 @@ public void AddWarning(OpenApiValidatorWarning warning) /// public override void Visit(IDictionary headers) => Validate(headers, headers.GetType()); /// - public override void Visit(IDictionary callbacks) => Validate(callbacks, callbacks.GetType()); + public override void Visit(IDictionary callbacks) => Validate(callbacks, callbacks.GetType()); /// public override void Visit(IDictionary content) => Validate(content, content.GetType()); /// diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs index 7a1b43f2f..4476d23a8 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader; using Xunit; @@ -79,7 +80,7 @@ public async Task ParseCallbackWithReferenceShouldSucceed() new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, result.Diagnostic); Assert.Equivalent( - new OpenApiCallback + new OpenApiCallbackReference("simpleHook", result.Document) { PathItems = { @@ -110,12 +111,6 @@ public async Task ParseCallbackWithReferenceShouldSucceed() } } }, - Reference = new OpenApiReference - { - Type = ReferenceType.Callback, - Id = "simpleHook", - HostDocument = result.Document - } }, callback); } @@ -135,7 +130,7 @@ public async Task ParseMultipleCallbacksWithReferenceShouldSucceed() var callback1 = subscribeOperation.Callbacks["simpleHook"]; Assert.Equivalent( - new OpenApiCallback + new OpenApiCallbackReference("simpleHook", result.Document) { PathItems = { @@ -166,12 +161,6 @@ public async Task ParseMultipleCallbacksWithReferenceShouldSucceed() } } }, - Reference = new OpenApiReference - { - Type = ReferenceType.Callback, - Id = "simpleHook", - HostDocument = result.Document - } }, callback1); var callback2 = subscribeOperation.Callbacks["callback2"]; diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 9ad9336d3..69d509df5 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -337,6 +337,10 @@ namespace Microsoft.OpenApi.MicrosoftExtensions } namespace Microsoft.OpenApi.Models.Interfaces { + public interface IOpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + { + System.Collections.Generic.Dictionary PathItems { get; } + } public interface IOpenApiDescribedElement : Microsoft.OpenApi.Interfaces.IOpenApiElement { string Description { get; set; } @@ -361,34 +365,32 @@ namespace Microsoft.OpenApi.Models Object = 32, Array = 64, } - public class OpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback { public OpenApiCallback() { } - public OpenApiCallback(Microsoft.OpenApi.Models.OpenApiCallback callback) { } - public Microsoft.OpenApi.Models.OpenApiReference Reference { get; set; } - public virtual System.Collections.Generic.IDictionary Extensions { get; set; } - public virtual System.Collections.Generic.Dictionary PathItems { get; set; } - public virtual bool UnresolvedReference { get; set; } + public OpenApiCallback(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback callback) { } + public System.Collections.Generic.IDictionary Extensions { get; set; } + public System.Collections.Generic.Dictionary PathItems { get; set; } public void AddPathItem(Microsoft.OpenApi.Expressions.RuntimeExpression expression, Microsoft.OpenApi.Models.OpenApiPathItem pathItem) { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiComponents : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiComponents() { } public OpenApiComponents(Microsoft.OpenApi.Models.OpenApiComponents? components) { } + public System.Collections.Generic.IDictionary? Callbacks { get; set; } + public System.Collections.Generic.IDictionary? Examples { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.IDictionary? Headers { get; set; } + public System.Collections.Generic.IDictionary? Links { get; set; } + public System.Collections.Generic.IDictionary? Parameters { get; set; } + public System.Collections.Generic.IDictionary? PathItems { get; set; } + public System.Collections.Generic.IDictionary? RequestBodies { get; set; } + public System.Collections.Generic.IDictionary? Responses { get; set; } public System.Collections.Generic.IDictionary? Schemas { get; set; } - public virtual System.Collections.Generic.IDictionary? Callbacks { get; set; } - public virtual System.Collections.Generic.IDictionary? Examples { get; set; } - public virtual System.Collections.Generic.IDictionary? Extensions { get; set; } - public virtual System.Collections.Generic.IDictionary? Headers { get; set; } - public virtual System.Collections.Generic.IDictionary? Links { get; set; } - public virtual System.Collections.Generic.IDictionary? Parameters { get; set; } - public virtual System.Collections.Generic.IDictionary? PathItems { get; set; } - public virtual System.Collections.Generic.IDictionary? RequestBodies { get; set; } - public virtual System.Collections.Generic.IDictionary? Responses { get; set; } - public virtual System.Collections.Generic.IDictionary? SecuritySchemes { get; set; } + public System.Collections.Generic.IDictionary? SecuritySchemes { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -770,7 +772,7 @@ namespace Microsoft.OpenApi.Models public OpenApiOperation() { } public OpenApiOperation(Microsoft.OpenApi.Models.OpenApiOperation? operation) { } public System.Collections.Generic.IDictionary? Annotations { get; set; } - public System.Collections.Generic.IDictionary? Callbacks { get; set; } + public System.Collections.Generic.IDictionary? Callbacks { get; set; } public bool Deprecated { get; set; } public string? Description { get; set; } public System.Collections.Generic.IDictionary? Extensions { get; set; } @@ -1120,14 +1122,19 @@ namespace Microsoft.OpenApi.Models } namespace Microsoft.OpenApi.Models.References { - public class OpenApiCallbackReference : Microsoft.OpenApi.Models.OpenApiCallback, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiCallbackReference : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback { + public OpenApiCallbackReference(Microsoft.OpenApi.Models.References.OpenApiCallbackReference callback) { } public OpenApiCallbackReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public System.Collections.Generic.IDictionary Extensions { get; } + public System.Collections.Generic.Dictionary PathItems { get; } + public Microsoft.OpenApi.Models.OpenApiReference Reference { get; set; } public Microsoft.OpenApi.Models.OpenApiCallback Target { get; } - public override System.Collections.Generic.IDictionary Extensions { get; set; } - public override System.Collections.Generic.Dictionary PathItems { get; set; } - public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public bool UnresolvedReference { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback openApiExample) { } + public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiExampleReference : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiExample { @@ -1506,8 +1513,8 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtensible openApiExtensible) { } public virtual void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtension openApiExtension) { } public virtual void Visit(Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder referenceHolder) { } + public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback callback) { } public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiExample example) { } - public virtual void Visit(Microsoft.OpenApi.Models.OpenApiCallback callback) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiComponents components) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiContact contact) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiDocument doc) { } @@ -1534,8 +1541,8 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(Microsoft.OpenApi.Models.OpenApiTag tag) { } public virtual void Visit(Microsoft.OpenApi.Models.References.OpenApiTagReference tag) { } public virtual void Visit(System.Collections.Generic.IDictionary operations) { } + public virtual void Visit(System.Collections.Generic.IDictionary callbacks) { } public virtual void Visit(System.Collections.Generic.IDictionary examples) { } - public virtual void Visit(System.Collections.Generic.IDictionary callbacks) { } public virtual void Visit(System.Collections.Generic.IDictionary encodings) { } public virtual void Visit(System.Collections.Generic.IDictionary headers) { } public virtual void Visit(System.Collections.Generic.IDictionary links) { } @@ -1605,8 +1612,8 @@ namespace Microsoft.OpenApi.Validations public void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning) { } public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtensible openApiExtensible) { } public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtension openApiExtension) { } + public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback callback) { } public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiExample example) { } - public override void Visit(Microsoft.OpenApi.Models.OpenApiCallback callback) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiComponents components) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiContact contact) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiDocument doc) { } @@ -1632,8 +1639,8 @@ namespace Microsoft.OpenApi.Validations public override void Visit(Microsoft.OpenApi.Models.OpenApiServerVariable serverVariable) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiTag tag) { } public override void Visit(System.Collections.Generic.IDictionary operations) { } + public override void Visit(System.Collections.Generic.IDictionary callbacks) { } public override void Visit(System.Collections.Generic.IDictionary examples) { } - public override void Visit(System.Collections.Generic.IDictionary callbacks) { } public override void Visit(System.Collections.Generic.IDictionary encodings) { } public override void Visit(System.Collections.Generic.IDictionary headers) { } public override void Visit(System.Collections.Generic.IDictionary links) { } diff --git a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs index 342fb317a..4acb0aadf 100644 --- a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs @@ -34,7 +34,7 @@ public void ExpectedVirtualsInvolved() visitor.Visit(default(OpenApiParameter)); visitor.Visit(default(OpenApiRequestBody)); visitor.Visit(default(IDictionary)); - visitor.Visit(default(IDictionary)); + visitor.Visit(default(IDictionary)); visitor.Visit(default(OpenApiResponse)); visitor.Visit(default(OpenApiResponses)); visitor.Visit(default(IDictionary)); @@ -46,7 +46,7 @@ public void ExpectedVirtualsInvolved() visitor.Visit(default(OpenApiSchema)); visitor.Visit(default(IDictionary)); visitor.Visit(default(OpenApiLink)); - visitor.Visit(default(OpenApiCallback)); + visitor.Visit(default(IOpenApiCallback)); visitor.Visit(default(OpenApiTag)); visitor.Visit(default(OpenApiHeader)); visitor.Visit(default(OpenApiOAuthFlow)); @@ -178,7 +178,7 @@ public override void Visit(IDictionary headers) base.Visit(headers); } - public override void Visit(IDictionary callbacks) + public override void Visit(IDictionary callbacks) { EncodeCall(); base.Visit(callbacks); @@ -250,7 +250,7 @@ public override void Visit(OpenApiLink link) base.Visit(link); } - public override void Visit(OpenApiCallback callback) + public override void Visit(IOpenApiCallback callback) { EncodeCall(); base.Visit(callback);