From 81be30622ebb43b72bb12d13934f27a9c4042e70 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Wed, 16 Feb 2022 02:02:24 +0300 Subject: [PATCH 01/25] Update retrieving descriptions for stream properties --- .../MediaEntityGetOperationHandler.cs | 9 +++--- .../MediaEntityOperationalHandler.cs | 28 ++++++++----------- .../MediaEntityPutOperationHandler.cs | 9 +++--- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs index 86afaa06..e5a25dce 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs @@ -26,13 +26,14 @@ internal class MediaEntityGetOperationHandler : MediaEntityOperationalHandler protected override void SetBasicInfo(OpenApiOperation operation) { // Summary + string placeholderValue = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "media content"; operation.Summary = IsNavigationPropertyPath - ? $"Get media content for the navigation property {NavigationProperty.Name} from {NavigationSource.Name}" - : $"Get media content for {NavigationSourceSegment.EntityType.Name} from {NavigationSourceSegment.Identifier}"; + ? $"Get {placeholderValue} for the navigation property {NavigationProperty.Name} from {NavigationSource.Name}" + : $"Get {placeholderValue} for {NavigationSourceSegment.EntityType.Name} from {NavigationSourceSegment.Identifier}"; // Description IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement(); - if (annotatableElement != null) + if (LastSegmentIsStreamPropertySegment) { operation.Description = Context.Model.GetDescriptionAnnotation(annotatableElement); } @@ -40,7 +41,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) // OperationId if (Context.Settings.EnableOperationId) { - string identifier = Path.LastSegment.Kind == ODataSegmentKind.StreamContent ? "Content" : Path.LastSegment.Identifier; + string identifier = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "Content"; operation.OperationId = GetOperationId("Get", identifier); } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs index 81de6562..4ab8fd5c 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs @@ -30,6 +30,8 @@ internal abstract class MediaEntityOperationalHandler : NavigationPropertyOperat /// protected bool IsNavigationPropertyPath { get; private set; } + protected bool LastSegmentIsStreamPropertySegment { get; private set; } + /// protected override void Initialize(ODataContext context, ODataPath path) { @@ -40,6 +42,8 @@ protected override void Initialize(ODataContext context, ODataPath path) IsNavigationPropertyPath = Path.Segments.Contains( Path.Segments.Where(segment => segment is ODataNavigationPropertySegment).FirstOrDefault()); + LastSegmentIsStreamPropertySegment = Path.LastSegment.Kind == ODataSegmentKind.StreamProperty; + if (IsNavigationPropertyPath) { // Initialize navigation property paths from base @@ -169,29 +173,19 @@ protected IDictionary GetContentDescription() } /// - /// Determines the annotatable element from the segments of a path. + /// Gets the annotatable stream property from the path segments. /// - /// The annotable element. + /// The annotatable stream property. protected IEdmVocabularyAnnotatable GetAnnotatableElement() { - IEdmEntityType entityType = NavigationSourceSegment.EntityType; - ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment); - - if (lastSegmentProp == null) - { - int pathCount = Path.Segments.Count; + // Only StreamProperty ODataSegmentKind is annotatable + if (!LastSegmentIsStreamPropertySegment) return null; - // Retrieve the segment before the stream content segment - lastSegmentProp = Path.Segments.ElementAtOrDefault(pathCount - 2); + // Retrieve the entity type of the segment before the stream property segment + var entityType = Path.Segments.ElementAtOrDefault(Path.Segments.Count - 2).EntityType; - if (lastSegmentProp == null) - { - return null; - } - } - - // Get the annotatable stream property // The stream property can either be a structural type or navigation type property + ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment); IEdmProperty property = GetStructuralProperty(entityType, lastSegmentProp.Identifier); if (property == null) { diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs index d9138518..bcba39a4 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs @@ -1,4 +1,4 @@ -// ------------------------------------------------------------ +// ------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. // ------------------------------------------------------------ @@ -26,9 +26,10 @@ internal class MediaEntityPutOperationHandler : MediaEntityOperationalHandler protected override void SetBasicInfo(OpenApiOperation operation) { // Summary + string placeholderValue = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "media content"; operation.Summary = IsNavigationPropertyPath - ? $"Update media content for the navigation property {NavigationProperty.Name} in {NavigationSource.Name}" - : $"Update media content for {NavigationSourceSegment.EntityType.Name} in {NavigationSourceSegment.Identifier}"; + ? $"Update {placeholderValue} for the navigation property {NavigationProperty.Name} in {NavigationSource.Name}" + : $"Update {placeholderValue} for {NavigationSourceSegment.EntityType.Name} in {NavigationSourceSegment.Identifier}"; // Description IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement(); @@ -40,7 +41,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) // OperationId if (Context.Settings.EnableOperationId) { - string identifier = Path.LastSegment.Kind == ODataSegmentKind.StreamContent ? "Content" : Path.LastSegment.Identifier; + string identifier = LastSegmentIsStreamPropertySegment ? Path.LastSegment.Identifier : "Content"; operation.OperationId = GetOperationId("Update", identifier); } } From f7300aa32ff725599539f24544d809dd678e0ae8 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Wed, 16 Feb 2022 02:03:24 +0300 Subject: [PATCH 02/25] Use restrictions annotations to retrieve operations descriptions --- .../Operation/EntityDeleteOperationHandler.cs | 30 ++++++++++------ .../Operation/EntityGetOperationHandler.cs | 36 ++++++++++++------- .../Operation/EntitySetGetOperationHandler.cs | 34 ++++++++++++------ .../EntitySetPostOperationHandler.cs | 31 +++++++++++----- .../Operation/EntityUpdateOperationHandler.cs | 30 ++++++++++------ .../NavigationPropertyGetOperationHandler.cs | 6 ++++ .../NavigationPropertyOperationHandler.cs | 9 ----- .../NavigationPropertyPostOperationHandler.cs | 3 ++ ...avigationPropertyUpdateOperationHandler.cs | 3 ++ .../Operation/SingletonGetOperationHandler.cs | 33 ++++++++++++----- .../SingletonPatchOperationHandler.cs | 31 +++++++++++----- 11 files changed, 168 insertions(+), 78 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs index 53ff6d98..963d27ff 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs @@ -23,6 +23,18 @@ internal class EntityDeleteOperationHandler : EntitySetOperationHandler /// public override OperationType OperationType => OperationType.Delete; + /// + /// Gets/Sets the + /// + private DeleteRestrictionsType DeleteRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + DeleteRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.DeleteRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -32,7 +44,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = DeleteRestrictions?.Description; // OperationId if (Context.Settings.EnableOperationId) @@ -68,31 +80,29 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - DeleteRestrictionsType delete = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.DeleteRestrictions); - if (delete == null || delete.Permissions == null) + if (DeleteRestrictions == null || DeleteRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(delete.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(DeleteRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - DeleteRestrictionsType delete = Context.Model.GetRecord< DeleteRestrictionsType>(EntitySet, CapabilitiesConstants.DeleteRestrictions); - if (delete == null) + if (DeleteRestrictions == null) { return; } - if (delete.CustomHeaders != null) + if (DeleteRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, delete.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, DeleteRestrictions.CustomHeaders, ParameterLocation.Header); } - if (delete.CustomQueryOptions != null) + if (DeleteRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, delete.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, DeleteRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs index 3c7ef76c..394d930d 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs @@ -24,6 +24,18 @@ internal class EntityGetOperationHandler : EntitySetOperationHandler /// public override OperationType OperationType => OperationType.Get; + /// + /// Gets/Sets the + /// + private ReadRestrictionsType ReadRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + ReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -33,7 +45,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = ReadRestrictions?.ReadByKeyRestrictions?.Description != null + ? ReadRestrictions.ReadByKeyRestrictions.Description + : Context.Model.GetDescriptionAnnotation(entityType); // OperationId if (Context.Settings.EnableOperationId) @@ -120,17 +134,16 @@ protected override void SetResponses(OpenApiOperation operation) } protected override void SetSecurity(OpenApiOperation operation) - { - ReadRestrictionsType read = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); - if (read == null) + { + if (ReadRestrictions == null) { return; } - ReadRestrictionsBase readBase = read; - if (read.ReadByKeyRestrictions != null) + ReadRestrictionsBase readBase = ReadRestrictions; + if (ReadRestrictions.ReadByKeyRestrictions != null) { - readBase = read.ReadByKeyRestrictions; + readBase = ReadRestrictions.ReadByKeyRestrictions; } if (readBase == null && readBase.Permissions == null) @@ -143,16 +156,15 @@ protected override void SetSecurity(OpenApiOperation operation) protected override void AppendCustomParameters(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); - if (read == null) + if (ReadRestrictions == null) { return; } - ReadRestrictionsBase readBase = read; - if (read.ReadByKeyRestrictions != null) + ReadRestrictionsBase readBase = ReadRestrictions; + if (ReadRestrictions.ReadByKeyRestrictions != null) { - readBase = read.ReadByKeyRestrictions; + readBase = ReadRestrictions.ReadByKeyRestrictions; } if (readBase.CustomHeaders != null) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs index 60b466c0..9d1fc453 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs @@ -3,7 +3,6 @@ // Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. // ------------------------------------------------------------ -using System.Collections.Generic; using System.Linq; using Microsoft.OData.Edm; using Microsoft.OpenApi.Any; @@ -26,6 +25,18 @@ internal class EntitySetGetOperationHandler : EntitySetOperationHandler /// public override OperationType OperationType => OperationType.Get; + /// + /// Gets/Sets the + /// + private ReadRestrictionsType ReadRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + ReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -39,6 +50,11 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = EntitySet.Name + "." + typeName + ".List" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = ReadRestrictions?.Description != null + ? ReadRestrictions.Description + : Context.Model.GetDescriptionAnnotation(EntitySet); + base.SetBasicInfo(operation); } @@ -153,31 +169,29 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); - if (read == null || read.Permissions == null) + if (ReadRestrictions == null || ReadRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(ReadRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions); - if (read == null) + if (ReadRestrictions == null) { return; } - if (read.CustomHeaders != null) + if (ReadRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, read.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, ReadRestrictions.CustomHeaders, ParameterLocation.Header); } - if (read.CustomQueryOptions != null) + if (ReadRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, read.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, ReadRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs index 9af8c9de..b8530771 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs @@ -24,6 +24,18 @@ internal class EntitySetPostOperationHandler : EntitySetOperationHandler /// public override OperationType OperationType => OperationType.Post; + /// + /// Gets/Sets the + /// + private InsertRestrictionsType InsertRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + InsertRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.InsertRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -37,6 +49,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = EntitySet.Name + "." + typeName + ".Create" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = InsertRestrictions?.Description; + base.SetBasicInfo(operation); } @@ -77,31 +92,29 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - InsertRestrictionsType insert = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.InsertRestrictions); - if (insert == null || insert.Permissions == null) + if (InsertRestrictions == null || InsertRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(insert.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(InsertRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - InsertRestrictionsType insert = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.InsertRestrictions); - if (insert == null) + if (InsertRestrictions == null) { return; } - if (insert.CustomQueryOptions != null) + if (InsertRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, insert.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, InsertRestrictions.CustomQueryOptions, ParameterLocation.Query); } - if (insert.CustomHeaders != null) + if (InsertRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, insert.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, InsertRestrictions.CustomHeaders, ParameterLocation.Header); } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs index 98b25eaa..8e98711c 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs @@ -19,6 +19,18 @@ namespace Microsoft.OpenApi.OData.Operation /// internal abstract class EntityUpdateOperationHandler : EntitySetOperationHandler { + /// + /// Gets/Sets the + /// + private UpdateRestrictionsType UpdateRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + UpdateRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.UpdateRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -28,7 +40,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = UpdateRestrictions?.Description; // OperationId if (Context.Settings.EnableOperationId) @@ -88,31 +100,29 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.UpdateRestrictions); - if (update == null || update.Permissions == null) + if (UpdateRestrictions == null || UpdateRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(UpdateRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.UpdateRestrictions); - if (update == null) + if (UpdateRestrictions == null) { return; } - if (update.CustomHeaders != null) + if (UpdateRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, UpdateRestrictions.CustomHeaders, ParameterLocation.Header); } - if (update.CustomQueryOptions != null) + if (UpdateRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, UpdateRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs index ca0a3147..a2f27e09 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs @@ -42,6 +42,12 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } + // Description + ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions; + operation.Description = readRestriction != null + ? LastSegmentIsKeySegment ? readRestriction.ReadByKeyRestrictions?.Description : readRestriction.Description + : Context.Model.GetDescriptionAnnotation(NavigationProperty); + base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs index 4503a9cb..580bf12d 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs @@ -84,15 +84,6 @@ protected override void Initialize(ODataContext context, ODataPath path) } } - /// - protected override void SetBasicInfo(OpenApiOperation operation) - { - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(NavigationProperty); - - base.SetBasicInfo(operation); - } - /// protected override void SetTags(OpenApiOperation operation) { diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs index 6e3fd826..3535138c 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs @@ -35,6 +35,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } + // Description + operation.Description = Restriction?.InsertRestrictions?.Description; + base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs index 480c3f98..7c4e7454 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs @@ -32,6 +32,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } + // Description + operation.Description = Restriction?.UpdateRestrictions?.Description; + base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs index 40f0c757..4b5e5ad1 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs @@ -24,6 +24,18 @@ internal class SingletonGetOperationHandler : SingletonOperationHandler /// public override OperationType OperationType => OperationType.Get; + /// + /// Gets/Sets the + /// + private ReadRestrictionsType ReadRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + ReadRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.ReadRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -37,6 +49,11 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = Singleton.Name + "." + typeName + ".Get" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = ReadRestrictions?.Description != null ? + ReadRestrictions.Description : + Context.Model.GetDescriptionAnnotation(Singleton); + base.SetBasicInfo(operation); } @@ -120,32 +137,30 @@ protected override void SetResponses(OpenApiOperation operation) /// protected override void SetSecurity(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(Singleton, CapabilitiesConstants.ReadRestrictions); - if (read == null || read.Permissions == null) + if (ReadRestrictions == null || ReadRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(ReadRestrictions.Permissions).ToList(); } /// protected override void AppendCustomParameters(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(Singleton, CapabilitiesConstants.ReadRestrictions); - if (read == null) + if (ReadRestrictions == null) { return; } - if (read.CustomHeaders != null) + if (ReadRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, read.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, ReadRestrictions.CustomHeaders, ParameterLocation.Header); } - if (read.CustomQueryOptions != null) + if (ReadRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, read.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, ReadRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs index d6303a48..5eaf7981 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs @@ -24,6 +24,18 @@ internal class SingletonPatchOperationHandler : SingletonOperationHandler /// public override OperationType OperationType => OperationType.Patch; + /// + /// Gets/Sets the + /// + private UpdateRestrictionsType UpdateRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + UpdateRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.UpdateRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -37,6 +49,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = Singleton.Name + "." + typeName + ".Update" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = UpdateRestrictions?.Description; + base.SetBasicInfo(operation); } @@ -91,32 +106,30 @@ protected override void SetResponses(OpenApiOperation operation) /// protected override void SetSecurity(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(Singleton, CapabilitiesConstants.UpdateRestrictions); - if (update == null || update.Permissions == null) + if (UpdateRestrictions == null || UpdateRestrictions.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(UpdateRestrictions.Permissions).ToList(); } /// protected override void AppendCustomParameters(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(Singleton, CapabilitiesConstants.UpdateRestrictions); - if (update == null) + if (UpdateRestrictions == null) { return; } - if (update.CustomHeaders != null) + if (UpdateRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, UpdateRestrictions.CustomHeaders, ParameterLocation.Header); } - if (update.CustomQueryOptions != null) + if (UpdateRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, UpdateRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } From 15d5ef0460a2eb8729876ad373cf8965f004155b Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Wed, 16 Feb 2022 12:07:17 +0300 Subject: [PATCH 03/25] Update capturing of operation descriptions --- .../Operation/ComplexPropertyGetOperationHandler.cs | 3 +++ .../Operation/ComplexPropertyPostOperationHandler.cs | 3 +++ .../Operation/EntityDeleteOperationHandler.cs | 2 +- .../Operation/EntityGetOperationHandler.cs | 4 +--- .../Operation/EntitySetGetOperationHandler.cs | 8 ++------ .../Operation/EntitySetOperationHandler.cs | 9 --------- .../Operation/EntitySetPostOperationHandler.cs | 4 +--- .../Operation/EntityUpdateOperationHandler.cs | 2 +- .../Operation/MediaEntityGetOperationHandler.cs | 3 +-- .../Operation/MediaEntityOperationalHandler.cs | 2 +- .../Operation/MediaEntityPutOperationHandler.cs | 5 ++--- .../NavigationPropertyDeleteOperationHandler.cs | 4 ++++ .../Operation/NavigationPropertyPostOperationHandler.cs | 2 +- .../NavigationPropertyUpdateOperationHandler.cs | 2 +- .../Operation/SingletonGetOperationHandler.cs | 6 +----- .../Operation/SingletonOperationHandler.cs | 9 --------- .../Operation/SingletonPatchOperationHandler.cs | 4 +--- 17 files changed, 24 insertions(+), 48 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs index a5ed9b66..2d66d2a4 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs @@ -33,6 +33,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = ComplexPropertySegment.Property.Name + "." + typeName + listOrGet + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); + base.SetBasicInfo(operation); } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs index 3c6ba325..51175a4d 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs @@ -42,6 +42,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = ComplexPropertySegment.Property.Name + "." + typeName + ".Set" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); + base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs index 963d27ff..5384c775 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs @@ -44,7 +44,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = DeleteRestrictions?.Description; + operation.Description = DeleteRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(entityType); // OperationId if (Context.Settings.EnableOperationId) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs index 394d930d..7f1f51b5 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs @@ -45,9 +45,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = ReadRestrictions?.ReadByKeyRestrictions?.Description != null - ? ReadRestrictions.ReadByKeyRestrictions.Description - : Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = ReadRestrictions?.ReadByKeyRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(entityType); // OperationId if (Context.Settings.EnableOperationId) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs index 9d1fc453..863cb48a 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs @@ -50,12 +50,8 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = EntitySet.Name + "." + typeName + ".List" + Utils.UpperFirstChar(typeName); } - // Description - operation.Description = ReadRestrictions?.Description != null - ? ReadRestrictions.Description - : Context.Model.GetDescriptionAnnotation(EntitySet); - - base.SetBasicInfo(operation); + // Description + operation.Description = ReadRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(EntitySet); } protected override void SetExtensions(OpenApiOperation operation) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetOperationHandler.cs index e241ec65..750d11b7 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetOperationHandler.cs @@ -32,15 +32,6 @@ protected override void Initialize(ODataContext context, ODataPath path) EntitySet = navigationSourceSegment.NavigationSource as IEdmEntitySet; } - /// - protected override void SetBasicInfo(OpenApiOperation operation) - { - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(EntitySet); - - base.SetBasicInfo(operation); - } - /// protected override void SetTags(OpenApiOperation operation) { diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs index b8530771..f6fcd52b 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs @@ -50,9 +50,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = InsertRestrictions?.Description; - - base.SetBasicInfo(operation); + operation.Description = InsertRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(EntitySet); } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs index 8e98711c..e8d96e37 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs @@ -40,7 +40,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = UpdateRestrictions?.Description; + operation.Description = UpdateRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(entityType); // OperationId if (Context.Settings.EnableOperationId) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs index e5a25dce..4ecff7c9 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs @@ -32,10 +32,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) : $"Get {placeholderValue} for {NavigationSourceSegment.EntityType.Name} from {NavigationSourceSegment.Identifier}"; // Description - IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement(); if (LastSegmentIsStreamPropertySegment) { - operation.Description = Context.Model.GetDescriptionAnnotation(annotatableElement); + operation.Description = Context.Model.GetDescriptionAnnotation(GetAnnotatableElement()); } // OperationId diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs index 4ab8fd5c..dbe75150 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs @@ -184,7 +184,7 @@ protected IEdmVocabularyAnnotatable GetAnnotatableElement() // Retrieve the entity type of the segment before the stream property segment var entityType = Path.Segments.ElementAtOrDefault(Path.Segments.Count - 2).EntityType; - // The stream property can either be a structural type or navigation type property + // The stream property can either be a structural type or a navigation property type ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment); IEdmProperty property = GetStructuralProperty(entityType, lastSegmentProp.Identifier); if (property == null) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs index bcba39a4..ca9e4d33 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs @@ -32,10 +32,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) : $"Update {placeholderValue} for {NavigationSourceSegment.EntityType.Name} in {NavigationSourceSegment.Identifier}"; // Description - IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement(); - if (annotatableElement != null) + if (LastSegmentIsStreamPropertySegment) { - operation.Description = Context.Model.GetDescriptionAnnotation(annotatableElement); + operation.Description = Context.Model.GetDescriptionAnnotation(GetAnnotatableElement()); } // OperationId diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs index 376aa1a3..6f25da51 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs @@ -4,6 +4,7 @@ // ------------------------------------------------------------ using System.Linq; +using Microsoft.OData.Edm; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.OData.Common; using Microsoft.OpenApi.OData.Generator; @@ -33,6 +34,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } + // Description + operation.Description = Restriction?.DeleteRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); + base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs index 3535138c..abe7ff03 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs @@ -36,7 +36,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Restriction?.InsertRestrictions?.Description; + operation.Description = Restriction?.InsertRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs index 7c4e7454..058ed7b4 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs @@ -33,7 +33,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Restriction?.UpdateRestrictions?.Description; + operation.Description = Restriction?.UpdateRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs index 4b5e5ad1..c0f9febc 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs @@ -50,11 +50,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = ReadRestrictions?.Description != null ? - ReadRestrictions.Description : - Context.Model.GetDescriptionAnnotation(Singleton); - - base.SetBasicInfo(operation); + operation.Description = ReadRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(Singleton); } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonOperationHandler.cs index e57e9ed6..ff1b049a 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonOperationHandler.cs @@ -32,15 +32,6 @@ protected override void Initialize(ODataContext context, ODataPath path) Singleton = navigationSourceSegment.NavigationSource as IEdmSingleton; } - /// - protected override void SetBasicInfo(OpenApiOperation operation) - { - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(Singleton); - - base.SetBasicInfo(operation); - } - /// protected override void SetTags(OpenApiOperation operation) { diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs index 5eaf7981..4da18cb7 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs @@ -50,9 +50,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = UpdateRestrictions?.Description; - - base.SetBasicInfo(operation); + operation.Description = UpdateRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(Singleton); } /// From 12cda0f35ca0a5e6bac66de65b810edaca1ae7ad Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Thu, 17 Feb 2022 02:40:03 +0300 Subject: [PATCH 04/25] Update tests; add further descriptions; remove invalid descriptions; fix bug --- .../Edm/ODataPathProvider.cs | 10 ++- .../ComplexPropertyPostOperationHandler.cs | 3 - .../ComplexPropertyUpdateOperationHandler.cs | 3 - .../Operation/EntityDeleteOperationHandler.cs | 2 +- .../EntitySetPostOperationHandler.cs | 2 +- .../Operation/EntityUpdateOperationHandler.cs | 2 +- .../MediaEntityGetOperationHandler.cs | 21 +++++- .../MediaEntityPutOperationHandler.cs | 18 +++++- ...avigationPropertyDeleteOperationHandler.cs | 2 +- .../NavigationPropertyOperationHandler.cs | 6 ++ .../NavigationPropertyPostOperationHandler.cs | 2 +- ...avigationPropertyUpdateOperationHandler.cs | 2 +- .../Operation/RefDeleteOperationHandler.cs | 3 +- .../Operation/RefGetOperationHandler.cs | 6 +- .../Operation/RefPostOperationHandler.cs | 3 +- .../Operation/RefPutOperationHandler.cs | 2 +- .../EntityDeleteOperationHandlerTests.cs | 2 +- .../EntityGetOperationHandlerTests.cs | 2 +- .../EntityPatchOperationHandlerTests.cs | 2 +- .../EntityPutOperationHandlerTests.cs | 2 +- .../EntitySetGetOperationHandlerTests.cs | 30 +++++++-- .../EntitySetPostOperationHandlerTests.cs | 11 +++- .../MediaEntityGetOperationHandlerTests.cs | 5 +- .../MediaEntityPutOperationHandlerTests.cs | 3 +- ...tionPropertyDeleteOperationHandlerTests.cs | 2 +- ...igationPropertyGetOperationHandlerTests.cs | 2 +- ...ationPropertyPatchOperationHandlerTests.cs | 2 +- ...gationPropertyPostOperationHandlerTests.cs | 2 +- ...igationPropertyPutOperationHandlerTests.cs | 2 +- .../RefDeleteOperationHandlerTests.cs | 2 +- .../Operation/RefGetOperationHandlerTests.cs | 2 +- .../Operation/RefPostOperationHandlerTests.cs | 2 +- .../Operation/RefPutOperationHandlerTests.cs | 2 +- .../SingletonGetOperationHandlerTests.cs | 10 ++- .../SingletonPatchOperationHandlerTests.cs | 9 ++- .../Resources/Basic.OpenApi.V2.json | 1 - .../Resources/Basic.OpenApi.V2.yaml | 1 - .../Resources/Basic.OpenApi.json | 1 - .../Resources/Basic.OpenApi.yaml | 1 - .../Resources/TripService.OData.xml | 64 +++++++++++++++++-- .../Resources/TripService.OpenApi.V2.json | 41 ++++++------ .../Resources/TripService.OpenApi.V2.yaml | 41 ++++++------ .../Resources/TripService.OpenApi.json | 41 ++++++------ .../Resources/TripService.OpenApi.yaml | 41 ++++++------ 44 files changed, 262 insertions(+), 151 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 77324149..2b93a44f 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -348,8 +348,12 @@ private void RetrieveNavigationPropertyPaths( return; } + // Get the NavigationRestrictions + IEdmVocabularyAnnotatable annotatableNavigationSource = currentPath.FirstSegment.GetAnnotables().FirstOrDefault(); + NavigationRestrictionsType navigation = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions) + ?? _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); + // Check whether the navigation property should be part of the path - NavigationRestrictionsType navigation = _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); if (navigation != null && !navigation.IsNavigable) { return; @@ -364,9 +368,9 @@ private void RetrieveNavigationPropertyPaths( visitedNavigationProperties.Push(navPropFullyQualifiedName); // Check whether a collection-valued navigation property should be indexed by key value(s). - NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(); + bool? indexableByKey = navigation?.RestrictedProperties?.FirstOrDefault()?.IndexableByKey; - if (restriction == null || restriction.IndexableByKey == true) + if (indexableByKey == null || indexableByKey == true) { IEdmEntityType navEntityType = navigationProperty.ToEntityType(); var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many; diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs index 51175a4d..3c6ba325 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs @@ -42,9 +42,6 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = ComplexPropertySegment.Property.Name + "." + typeName + ".Set" + Utils.UpperFirstChar(typeName); } - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); - base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs index ad4487e9..2ebaaa13 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs @@ -22,9 +22,6 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Summary operation.Summary = $"Update property {ComplexPropertySegment.Property.Name} value."; - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); - // OperationId if (Context.Settings.EnableOperationId) { diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs index 5384c775..37a444dc 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs @@ -44,7 +44,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = DeleteRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = DeleteRestrictions?.Description; // OperationId if (Context.Settings.EnableOperationId) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs index f6fcd52b..9ebff116 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs @@ -50,7 +50,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = InsertRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(EntitySet); + operation.Description = InsertRestrictions?.Description; } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs index e8d96e37..8e98711c 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs @@ -40,7 +40,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) IEdmEntityType entityType = EntitySet.EntityType(); // Description - operation.Description = UpdateRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(entityType); + operation.Description = UpdateRestrictions?.Description; // OperationId if (Context.Settings.EnableOperationId) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs index 4ecff7c9..33571695 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs @@ -34,7 +34,26 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Description if (LastSegmentIsStreamPropertySegment) { - operation.Description = Context.Model.GetDescriptionAnnotation(GetAnnotatableElement()); + IEdmVocabularyAnnotatable annotatable = GetAnnotatableElement(); + string description; + + if (annotatable is IEdmNavigationProperty) + { + ReadRestrictionsType readRestriction = Context.Model.GetRecord(annotatable, CapabilitiesConstants.NavigationRestrictions)? + .RestrictedProperties?.FirstOrDefault()?.ReadRestrictions; + + description = LastSegmentIsKeySegment + ? readRestriction?.ReadByKeyRestrictions?.Description + : readRestriction?.Description + ?? Context.Model.GetDescriptionAnnotation(annotatable); + } + else + { + // Structural property + description = Context.Model.GetDescriptionAnnotation(annotatable); + } + + operation.Description = description; } // OperationId diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs index ca9e4d33..9430a468 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs @@ -34,7 +34,23 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Description if (LastSegmentIsStreamPropertySegment) { - operation.Description = Context.Model.GetDescriptionAnnotation(GetAnnotatableElement()); + IEdmVocabularyAnnotatable annotatable = GetAnnotatableElement(); + string description; + + if (annotatable is IEdmNavigationProperty) + { + UpdateRestrictionsType updateRestriction = Context.Model.GetRecord(annotatable, CapabilitiesConstants.NavigationRestrictions)? + .RestrictedProperties?.FirstOrDefault()?.UpdateRestrictions; + + description = updateRestriction?.Description ?? Context.Model.GetDescriptionAnnotation(annotatable); + } + else + { + // Structural property + description = Context.Model.GetDescriptionAnnotation(annotatable); + } + + operation.Description = description; } // OperationId diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs index 6f25da51..01238038 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyDeleteOperationHandler.cs @@ -35,7 +35,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Restriction?.DeleteRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = Restriction?.DeleteRestrictions?.Description; base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs index 580bf12d..2d2eb08d 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs @@ -82,6 +82,12 @@ protected override void Initialize(ODataContext context, ODataPath path) { Restriction = navigation.RestrictedProperties.FirstOrDefault(r => r.NavigationProperty != null && r.NavigationProperty == NavigationPropertyPath); } + else + { + // Navigation restrictions annotation can be defined in-line + Restriction = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.NavigationRestrictions)? + .RestrictedProperties?.FirstOrDefault(); + } } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs index abe7ff03..3535138c 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyPostOperationHandler.cs @@ -36,7 +36,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Restriction?.InsertRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = Restriction?.InsertRestrictions?.Description; base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs index 058ed7b4..7c4e7454 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyUpdateOperationHandler.cs @@ -33,7 +33,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Restriction?.UpdateRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = Restriction?.UpdateRestrictions?.Description; base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefDeleteOperationHandler.cs index a217a74b..97c0e250 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefDeleteOperationHandler.cs @@ -32,7 +32,8 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } - base.SetBasicInfo(operation); + // Description + operation.Description = Restriction?.DeleteRestrictions?.Description; } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs index 0f6b6ac0..8916f954 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs @@ -40,7 +40,11 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } - base.SetBasicInfo(operation); + // Description + ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions; + operation.Description = readRestriction != null + ? LastSegmentIsKeySegment ? readRestriction.ReadByKeyRestrictions?.Description : readRestriction.Description + : Context.Model.GetDescriptionAnnotation(NavigationProperty); } protected override void SetExtensions(OpenApiOperation operation) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefPostOperationHandler.cs index f2b08ba2..d5759037 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefPostOperationHandler.cs @@ -32,7 +32,8 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } - base.SetBasicInfo(operation); + // Description + operation.Description = Restriction?.InsertRestrictions?.Description; } /// diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefPutOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefPutOperationHandler.cs index 12c29b38..f221bc54 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefPutOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefPutOperationHandler.cs @@ -32,7 +32,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = GetOperationId(prefix); } - base.SetBasicInfo(operation); + operation.Description = Restriction?.UpdateRestrictions?.Description; } /// diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityDeleteOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityDeleteOperationHandlerTests.cs index 479a2e64..21824d9a 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityDeleteOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityDeleteOperationHandlerTests.cs @@ -37,7 +37,7 @@ public void CreateEntityDeleteOperationReturnsCorrectOperation(bool enableOperat // Assert Assert.NotNull(delete); Assert.Equal("Delete entity from Customers", delete.Summary); - Assert.Equal("A business customer.", delete.Description); + Assert.Equal("Delete a customer.", delete.Description); Assert.NotNull(delete.Tags); var tag = Assert.Single(delete.Tags); Assert.Equal("Customers.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityGetOperationHandlerTests.cs index b669a12e..a23f7492 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityGetOperationHandlerTests.cs @@ -38,7 +38,7 @@ public void CreateEntityGetOperationReturnsCorrectOperation(bool enableOperation // Assert Assert.NotNull(get); Assert.Equal("Get entity from Customers by key", get.Summary); - Assert.Equal("A business customer.", get.Description); + Assert.Equal("Get a customer.", get.Description); Assert.NotNull(get.Tags); var tag = Assert.Single(get.Tags); Assert.Equal("Customers.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPatchOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPatchOperationHandlerTests.cs index e4c71685..6e7fa515 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPatchOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPatchOperationHandlerTests.cs @@ -37,7 +37,7 @@ public void CreateEntityPatchOperationReturnsCorrectOperation(bool enableOperati // Assert Assert.NotNull(patch); Assert.Equal("Update entity in Customers", patch.Summary); - Assert.Equal("A business customer.", patch.Description); + Assert.Equal("Update a customer.", patch.Description); Assert.NotNull(patch.Tags); var tag = Assert.Single(patch.Tags); Assert.Equal("Customers.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPutOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPutOperationHandlerTests.cs index 08951a03..8aba198f 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPutOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntityPutOperationHandlerTests.cs @@ -37,7 +37,7 @@ public void CreateEntityPutOperationReturnsCorrectOperation(bool enableOperation // Assert Assert.NotNull(putOperation); Assert.Equal("Update entity in Customers", putOperation.Summary); - Assert.Equal("A business customer.", putOperation.Description); + Assert.Equal("Update a customer.", putOperation.Description); Assert.NotNull(putOperation.Tags); var tag = Assert.Single(putOperation.Tags); Assert.Equal("Customers.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs index a27d8b4e..dc00fb73 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs @@ -4,12 +4,10 @@ // ------------------------------------------------------------ using System; -using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Microsoft.OData.Edm; using Microsoft.OData.Edm.Csdl; -using Microsoft.OData.Edm.Validation; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.OData.Common; using Microsoft.OpenApi.OData.Edm; @@ -46,6 +44,7 @@ public void CreateEntitySetGetOperationReturnsCorrectOperation(bool enableOperat // Assert Assert.NotNull(get); Assert.Equal("Get entities from " + entitySet.Name, get.Summary); + Assert.Equal("List customers.", get.Description); Assert.NotNull(get.Tags); var tag = Assert.Single(get.Tags); Assert.Equal("Customers.Customer", tag.Name); @@ -54,10 +53,7 @@ public void CreateEntitySetGetOperationReturnsCorrectOperation(bool enableOperat Assert.Equal(8, get.Parameters.Count); Assert.NotNull(get.Responses); - Assert.Equal(2, get.Responses.Count); - - //Assert.NotNull(get.Extensions); - //Assert.True(get.Extensions.ContainsKey(Constants.xMsPageable)); + Assert.Equal(2, get.Responses.Count); if (enableOperationId) { @@ -352,6 +348,28 @@ public static IEdmModel GetEdmModel(string annotation) {0} + + + + + + + + + + + + + + + + + + + + + + "; diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs index 2e9bba7f..019f56d2 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs @@ -59,7 +59,7 @@ private void VerifyEntitySetPostOperation(string annotation, bool enableOperatio // Assert Assert.NotNull(post); Assert.Equal("Add new entity to " + entitySet.Name, post.Summary); - Assert.Equal("Collection of business customers.", post.Description); + Assert.Equal("Create a new customer.", post.Description); Assert.NotNull(post.Tags); var tag = Assert.Single(post.Tags); Assert.Equal("Customers.Customer", tag.Name); @@ -252,8 +252,15 @@ internal static IEdmModel GetEdmModel(string annotation, bool hasStream = false) - {1} + {1} + + + + + + + "; diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs index 198a5aed..7779ce49 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs @@ -73,9 +73,8 @@ private void VerifyMediaEntityGetOperation(string annotation, bool enableOperati // Assert Assert.NotNull(getOperation); Assert.NotNull(getOperation2); - Assert.Equal("Get media content for Todo from Todos", getOperation.Summary); + Assert.Equal("Get Logo for Todo from Todos", getOperation.Summary); Assert.Equal("Get media content for the navigation property photo from me", getOperation2.Summary); - Assert.Equal("The user's profile photo.", getOperation2.Description); Assert.NotNull(getOperation.Tags); Assert.NotNull(getOperation2.Tags); @@ -135,7 +134,7 @@ public static IEdmModel GetEdmModel(string annotation) - + diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityPutOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityPutOperationHandlerTests.cs index 7016aa51..2a1690ba 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityPutOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityPutOperationHandlerTests.cs @@ -70,9 +70,8 @@ private void VerifyMediaEntityPutOperation(string annotation, bool enableOperati // Assert Assert.NotNull(putOperation); Assert.NotNull(putOperation2); - Assert.Equal("Update media content for Todo in Todos", putOperation.Summary); + Assert.Equal("Update Logo for Todo in Todos", putOperation.Summary); Assert.Equal("Update media content for the navigation property photo in me", putOperation2.Summary); - Assert.Equal("The user's profile photo.", putOperation2.Description); Assert.NotNull(putOperation.Tags); Assert.NotNull(putOperation2.Tags); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyDeleteOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyDeleteOperationHandlerTests.cs index 57df5f88..9c04259f 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyDeleteOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyDeleteOperationHandlerTests.cs @@ -40,7 +40,7 @@ public void CreateNavigationDeleteOperationReturnsCorrectOperation(bool enableOp // Assert Assert.NotNull(operation); Assert.Equal("Delete navigation property Trips for People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("Delete a trip.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs index 2a6dcaf5..c4c1cb6b 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs @@ -42,7 +42,7 @@ public void CreateNavigationGetOperationReturnsCorrectOperation(bool enableOpera // Assert Assert.NotNull(operation); Assert.Equal("Get Trips from People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("List trips.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPatchOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPatchOperationHandlerTests.cs index 5c087ce9..0c1d0a39 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPatchOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPatchOperationHandlerTests.cs @@ -42,7 +42,7 @@ public void CreateNavigationPatchOperationReturnsCorrectOperation(bool enableOpe // Assert Assert.NotNull(operation); Assert.Equal("Update the navigation property BestFriend in People", operation.Summary); - Assert.Equal("The best friend.", operation.Description); + Assert.Equal("Update the best friend.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Person", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPostOperationHandlerTests.cs index 31c9dcd7..0298508f 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPostOperationHandlerTests.cs @@ -42,7 +42,7 @@ public void CreateNavigationPostOperationReturnsCorrectOperation(bool enableOper // Assert Assert.NotNull(operation); Assert.Equal("Create new navigation property to Trips for People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("Create a trip.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPutOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPutOperationHandlerTests.cs index e954493b..f8bab680 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPutOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyPutOperationHandlerTests.cs @@ -42,7 +42,7 @@ public void CreateNavigationPutOperationReturnsCorrectOperation(bool enableOpera // Assert Assert.NotNull(operation); Assert.Equal("Update the navigation property BestFriend in People", operation.Summary); - Assert.Equal("The best friend.", operation.Description); + Assert.Equal("Update the best friend.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Person", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefDeleteOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefDeleteOperationHandlerTests.cs index 7efeb35b..705c0186 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefDeleteOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefDeleteOperationHandlerTests.cs @@ -43,7 +43,7 @@ public void CreateNavigationRefDeleteOperationReturnsCorrectOperation(bool enabl // Assert Assert.NotNull(operation); Assert.Equal("Delete ref of navigation property Trips for People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("Delete a trip.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefGetOperationHandlerTests.cs index b547ff32..4748fcb5 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefGetOperationHandlerTests.cs @@ -43,7 +43,7 @@ public void CreateNavigationRefGetOperationReturnsCorrectOperation(bool enableOp // Assert Assert.NotNull(operation); Assert.Equal("Get ref of Trips from People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("List trips.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPostOperationHandlerTests.cs index b042befe..e2169e90 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPostOperationHandlerTests.cs @@ -43,7 +43,7 @@ public void CreateNavigationRefPostOperationReturnsCorrectOperation(bool enableO // Assert Assert.NotNull(operation); Assert.Equal("Create new navigation property ref to Trips for People", operation.Summary); - Assert.Equal("Collection of trips.", operation.Description); + Assert.Equal("Create a trip.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Trip", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPutOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPutOperationHandlerTests.cs index e57ab21c..35591bff 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPutOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/RefPutOperationHandlerTests.cs @@ -43,7 +43,7 @@ public void CreateNavigationRefPutOperationReturnsCorrectOperation(bool enableOp // Assert Assert.NotNull(operation); Assert.Equal("Update the ref of navigation property BestFriend in People", operation.Summary); - Assert.Equal("The best friend.", operation.Description); + Assert.Equal("Update the best friend.", operation.Description); Assert.NotNull(operation.Tags); var tag = Assert.Single(operation.Tags); Assert.Equal("People.Person", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonGetOperationHandlerTests.cs index e545a11b..5d51a46d 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonGetOperationHandlerTests.cs @@ -27,7 +27,13 @@ public class SingletonGetOperationHandlerTests public void CreateSingletonGetOperationReturnsCorrectOperation(bool enableOperationId) { // Arrange - IEdmModel model = GetEdmModel(""); + string annotation = @" + + + + + "; + IEdmModel model = GetEdmModel(annotation); IEdmSingleton singleton = model.EntityContainer.FindSingleton("Me"); OpenApiConvertSettings settings = new OpenApiConvertSettings { @@ -42,7 +48,7 @@ public void CreateSingletonGetOperationReturnsCorrectOperation(bool enableOperat // Assert Assert.NotNull(get); Assert.Equal("Get Me", get.Summary); - Assert.Equal("My signed-in instance.", get.Description); + Assert.Equal("Get the signed-in user.", get.Description); Assert.NotNull(get.Tags); var tag = Assert.Single(get.Tags); Assert.Equal("Me.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonPatchOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonPatchOperationHandlerTests.cs index 16ac5ee4..52f90062 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonPatchOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/SingletonPatchOperationHandlerTests.cs @@ -24,7 +24,13 @@ public class SingletonPatchOperationHandlerTests public void CreateSingletonPatchOperationReturnsCorrectOperation(bool enableOperationId) { // Arrange - IEdmModel model = SingletonGetOperationHandlerTests.GetEdmModel(""); + string annotation = @" + + + + + "; + IEdmModel model = SingletonGetOperationHandlerTests.GetEdmModel(annotation); IEdmSingleton singleton = model.EntityContainer.FindSingleton("Me"); OpenApiConvertSettings settings = new OpenApiConvertSettings { @@ -39,6 +45,7 @@ public void CreateSingletonPatchOperationReturnsCorrectOperation(bool enableOper // Assert Assert.NotNull(patch); Assert.Equal("Update Me", patch.Summary); + Assert.Equal("Update the signed-in user.", patch.Description); Assert.NotNull(patch.Tags); var tag = Assert.Single(patch.Tags); Assert.Equal("Me.Customer", tag.Name); diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.json b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.json index 4161aaff..eddc4117 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.json +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.json @@ -1088,7 +1088,6 @@ "People.Person" ], "summary": "Add new entity to People", - "description": "People's description.", "operationId": "People.Person.CreatePerson", "consumes": [ "application/json" diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.yaml b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.yaml index d44bad6a..0eadf066 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.yaml +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.yaml @@ -714,7 +714,6 @@ paths: tags: - People.Person summary: Add new entity to People - description: People's description. operationId: People.Person.CreatePerson consumes: - application/json diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.json b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.json index b81aa1c6..342ae9c4 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.json +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.json @@ -1226,7 +1226,6 @@ "People.Person" ], "summary": "Add new entity to People", - "description": "People's description.", "operationId": "People.Person.CreatePerson", "requestBody": { "description": "New entity", diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.yaml b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.yaml index b55ba6c5..f81490a8 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.yaml +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.yaml @@ -812,7 +812,6 @@ paths: tags: - People.Person summary: Add new entity to People - description: People's description. operationId: People.Person.CreatePerson requestBody: description: New entity diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OData.xml b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OData.xml index 409ff690..db312270 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OData.xml +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OData.xml @@ -67,11 +67,23 @@ - - - - - + + + + + + + + + + + + + + + + + @@ -336,6 +348,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.json b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.json index 357a1544..66e38fc9 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.json +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.json @@ -751,7 +751,6 @@ "Airports.Person" ], "summary": "Update the ref of navigation property EmergencyAuthority in Airports", - "description": "The person to contact in case of a crisis at this location.", "operationId": "Airports.UpdateRefEmergencyAuthority", "consumes": [ "application/json" @@ -790,7 +789,6 @@ "Airports.Person" ], "summary": "Delete ref of navigation property EmergencyAuthority for Airports", - "description": "The person to contact in case of a crisis at this location.", "operationId": "Airports.DeleteRefEmergencyAuthority", "parameters": [ { @@ -1784,7 +1782,7 @@ "Me.Person" ], "summary": "Update the ref of navigation property BestFriend in Me", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "Me.UpdateRefBestFriend", "consumes": [ "application/json" @@ -1822,7 +1820,6 @@ "Me.Person" ], "summary": "Delete ref of navigation property BestFriend for Me", - "description": "The best friend.", "operationId": "Me.DeleteRefBestFriend", "parameters": [ { @@ -9257,7 +9254,7 @@ "Me.Trip" ], "summary": "Get Trips from Me", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "Me.ListTrips", "parameters": [ { @@ -9358,7 +9355,7 @@ "Me.Trip" ], "summary": "Create new navigation property to Trips for Me", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "Me.CreateTrips", "consumes": [ "application/json" @@ -9405,7 +9402,7 @@ "Me.Trip" ], "summary": "Get Trips from Me", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "Me.GetTrips", "produces": [ "application/json" @@ -9481,7 +9478,7 @@ "Me.Trip" ], "summary": "Update the navigation property Trips in Me", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "Me.UpdateTrips", "consumes": [ "application/json" @@ -9530,7 +9527,7 @@ "Me.Trip" ], "summary": "Delete navigation property Trips for Me", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "Me.DeleteTrips", "parameters": [ { @@ -10661,7 +10658,7 @@ "NewComePeople.Person" ], "summary": "Update the ref of navigation property BestFriend in NewComePeople", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "NewComePeople.UpdateRefBestFriend", "consumes": [ "application/json" @@ -10707,7 +10704,6 @@ "NewComePeople.Person" ], "summary": "Delete ref of navigation property BestFriend for NewComePeople", - "description": "The best friend.", "operationId": "NewComePeople.DeleteRefBestFriend", "parameters": [ { @@ -16855,7 +16851,7 @@ "NewComePeople.Trip" ], "summary": "Get Trips from NewComePeople", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "NewComePeople.ListTrips", "parameters": [ { @@ -16957,7 +16953,7 @@ "NewComePeople.Trip" ], "summary": "Create new navigation property to Trips for NewComePeople", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "NewComePeople.CreateTrips", "consumes": [ "application/json" @@ -17005,7 +17001,7 @@ "NewComePeople.Trip" ], "summary": "Get Trips from NewComePeople", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "NewComePeople.GetTrips", "produces": [ "application/json" @@ -17082,7 +17078,7 @@ "NewComePeople.Trip" ], "summary": "Update the navigation property Trips in NewComePeople", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "NewComePeople.UpdateTrips", "consumes": [ "application/json" @@ -17132,7 +17128,7 @@ "NewComePeople.Trip" ], "summary": "Delete navigation property Trips for NewComePeople", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "NewComePeople.DeleteTrips", "parameters": [ { @@ -18372,7 +18368,7 @@ "People.Person" ], "summary": "Update the ref of navigation property BestFriend in People", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "People.UpdateRefBestFriend", "consumes": [ "application/json" @@ -18418,7 +18414,6 @@ "People.Person" ], "summary": "Delete ref of navigation property BestFriend for People", - "description": "The best friend.", "operationId": "People.DeleteRefBestFriend", "parameters": [ { @@ -27031,7 +27026,7 @@ "People.Trip" ], "summary": "Get Trips from People", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "People.ListTrips", "parameters": [ { @@ -27140,7 +27135,7 @@ "People.Trip" ], "summary": "Create new navigation property to Trips for People", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "People.CreateTrips", "consumes": [ "application/json" @@ -27195,7 +27190,7 @@ "People.Trip" ], "summary": "Get Trips from People", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "People.GetTrips", "produces": [ "application/json" @@ -27279,7 +27274,7 @@ "People.Trip" ], "summary": "Update the navigation property Trips in People", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "People.UpdateTrips", "consumes": [ "application/json" @@ -27336,7 +27331,7 @@ "People.Trip" ], "summary": "Delete navigation property Trips for People", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "People.DeleteTrips", "parameters": [ { diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.yaml b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.yaml index 48293eb2..43ea5703 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.yaml +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.yaml @@ -511,7 +511,6 @@ paths: tags: - Airports.Person summary: Update the ref of navigation property EmergencyAuthority in Airports - description: The person to contact in case of a crisis at this location. operationId: Airports.UpdateRefEmergencyAuthority consumes: - application/json @@ -538,7 +537,6 @@ paths: tags: - Airports.Person summary: Delete ref of navigation property EmergencyAuthority for Airports - description: The person to contact in case of a crisis at this location. operationId: Airports.DeleteRefEmergencyAuthority parameters: - in: path @@ -1223,7 +1221,7 @@ paths: tags: - Me.Person summary: Update the ref of navigation property BestFriend in Me - description: The best friend. + description: Update the best friend. operationId: Me.UpdateRefBestFriend consumes: - application/json @@ -1250,7 +1248,6 @@ paths: tags: - Me.Person summary: Delete ref of navigation property BestFriend for Me - description: The best friend. operationId: Me.DeleteRefBestFriend parameters: - in: header @@ -6530,7 +6527,7 @@ paths: tags: - Me.Trip summary: Get Trips from Me - description: Collection of trips. + description: List trips. operationId: Me.ListTrips parameters: - $ref: '#/parameters/top' @@ -6602,7 +6599,7 @@ paths: tags: - Me.Trip summary: Create new navigation property to Trips for Me - description: Collection of trips. + description: Create a trip. operationId: Me.CreateTrips consumes: - application/json @@ -6635,7 +6632,7 @@ paths: tags: - Me.Trip summary: Get Trips from Me - description: Collection of trips. + description: Get a trip. operationId: Me.GetTrips produces: - application/json @@ -6692,7 +6689,7 @@ paths: tags: - Me.Trip summary: Update the navigation property Trips in Me - description: Collection of trips. + description: Update a trip. operationId: Me.UpdateTrips consumes: - application/json @@ -6728,7 +6725,7 @@ paths: tags: - Me.Trip summary: Delete navigation property Trips for Me - description: Collection of trips. + description: Delete a trip. operationId: Me.DeleteTrips parameters: - in: path @@ -7526,7 +7523,7 @@ paths: tags: - NewComePeople.Person summary: Update the ref of navigation property BestFriend in NewComePeople - description: The best friend. + description: Update the best friend. operationId: NewComePeople.UpdateRefBestFriend consumes: - application/json @@ -7559,7 +7556,6 @@ paths: tags: - NewComePeople.Person summary: Delete ref of navigation property BestFriend for NewComePeople - description: The best friend. operationId: NewComePeople.DeleteRefBestFriend parameters: - in: path @@ -11890,7 +11886,7 @@ paths: tags: - NewComePeople.Trip summary: Get Trips from NewComePeople - description: Collection of trips. + description: List trips. operationId: NewComePeople.ListTrips parameters: - in: path @@ -11962,7 +11958,7 @@ paths: tags: - NewComePeople.Trip summary: Create new navigation property to Trips for NewComePeople - description: Collection of trips. + description: Create a trip. operationId: NewComePeople.CreateTrips consumes: - application/json @@ -11995,7 +11991,7 @@ paths: tags: - NewComePeople.Trip summary: Get Trips from NewComePeople - description: Collection of trips. + description: Get a trip. operationId: NewComePeople.GetTrips produces: - application/json @@ -12052,7 +12048,7 @@ paths: tags: - NewComePeople.Trip summary: Update the navigation property Trips in NewComePeople - description: Collection of trips. + description: Update a trip. operationId: NewComePeople.UpdateTrips consumes: - application/json @@ -12088,7 +12084,7 @@ paths: tags: - NewComePeople.Trip summary: Delete navigation property Trips for NewComePeople - description: Collection of trips. + description: Delete a trip. operationId: NewComePeople.DeleteTrips parameters: - in: path @@ -12969,7 +12965,7 @@ paths: tags: - People.Person summary: Update the ref of navigation property BestFriend in People - description: The best friend. + description: Update the best friend. operationId: People.UpdateRefBestFriend consumes: - application/json @@ -13002,7 +12998,6 @@ paths: tags: - People.Person summary: Delete ref of navigation property BestFriend for People - description: The best friend. operationId: People.DeleteRefBestFriend parameters: - in: path @@ -19159,7 +19154,7 @@ paths: tags: - People.Trip summary: Get Trips from People - description: Collection of trips. + description: List trips. operationId: People.ListTrips parameters: - in: path @@ -19237,7 +19232,7 @@ paths: tags: - People.Trip summary: Create new navigation property to Trips for People - description: Collection of trips. + description: Create a trip. operationId: People.CreateTrips consumes: - application/json @@ -19276,7 +19271,7 @@ paths: tags: - People.Trip summary: Get Trips from People - description: Collection of trips. + description: Get a trip. operationId: People.GetTrips produces: - application/json @@ -19339,7 +19334,7 @@ paths: tags: - People.Trip summary: Update the navigation property Trips in People - description: Collection of trips. + description: Update a trip. operationId: People.UpdateTrips consumes: - application/json @@ -19381,7 +19376,7 @@ paths: tags: - People.Trip summary: Delete navigation property Trips for People - description: Collection of trips. + description: Delete a trip. operationId: People.DeleteTrips parameters: - in: path diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.json b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.json index e29aaa66..16604b33 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.json +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.json @@ -848,7 +848,6 @@ "Airports.Person" ], "summary": "Update the ref of navigation property EmergencyAuthority in Airports", - "description": "The person to contact in case of a crisis at this location.", "operationId": "Airports.UpdateRefEmergencyAuthority", "parameters": [ { @@ -888,7 +887,6 @@ "Airports.Person" ], "summary": "Delete ref of navigation property EmergencyAuthority for Airports", - "description": "The person to contact in case of a crisis at this location.", "operationId": "Airports.DeleteRefEmergencyAuthority", "parameters": [ { @@ -2018,7 +2016,7 @@ "Me.Person" ], "summary": "Update the ref of navigation property BestFriend in Me", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "Me.UpdateRefBestFriend", "requestBody": { "description": "New navigation property ref values", @@ -2053,7 +2051,6 @@ "Me.Person" ], "summary": "Delete ref of navigation property BestFriend for Me", - "description": "The best friend.", "operationId": "Me.DeleteRefBestFriend", "parameters": [ { @@ -10237,7 +10234,7 @@ "Me.Trip" ], "summary": "Get Trips from Me", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "Me.ListTrips", "parameters": [ { @@ -10353,7 +10350,7 @@ "Me.Trip" ], "summary": "Create new navigation property to Trips for Me", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "Me.CreateTrips", "requestBody": { "description": "New navigation property", @@ -10398,7 +10395,7 @@ "Me.Trip" ], "summary": "Get Trips from Me", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "Me.GetTrips", "parameters": [ { @@ -10487,7 +10484,7 @@ "Me.Trip" ], "summary": "Update the navigation property Trips in Me", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "Me.UpdateTrips", "parameters": [ { @@ -10537,7 +10534,7 @@ "Me.Trip" ], "summary": "Delete navigation property Trips for Me", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "Me.DeleteTrips", "parameters": [ { @@ -11794,7 +11791,7 @@ "NewComePeople.Person" ], "summary": "Update the ref of navigation property BestFriend in NewComePeople", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "NewComePeople.UpdateRefBestFriend", "parameters": [ { @@ -11841,7 +11838,6 @@ "NewComePeople.Person" ], "summary": "Delete ref of navigation property BestFriend for NewComePeople", - "description": "The best friend.", "operationId": "NewComePeople.DeleteRefBestFriend", "parameters": [ { @@ -18804,7 +18800,7 @@ "NewComePeople.Trip" ], "summary": "Get Trips from NewComePeople", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "NewComePeople.ListTrips", "parameters": [ { @@ -18923,7 +18919,7 @@ "NewComePeople.Trip" ], "summary": "Create new navigation property to Trips for NewComePeople", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "NewComePeople.CreateTrips", "parameters": [ { @@ -18973,7 +18969,7 @@ "NewComePeople.Trip" ], "summary": "Get Trips from NewComePeople", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "NewComePeople.GetTrips", "parameters": [ { @@ -19065,7 +19061,7 @@ "NewComePeople.Trip" ], "summary": "Update the navigation property Trips in NewComePeople", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "NewComePeople.UpdateTrips", "parameters": [ { @@ -19118,7 +19114,7 @@ "NewComePeople.Trip" ], "summary": "Delete navigation property Trips for NewComePeople", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "NewComePeople.DeleteTrips", "parameters": [ { @@ -20500,7 +20496,7 @@ "People.Person" ], "summary": "Update the ref of navigation property BestFriend in People", - "description": "The best friend.", + "description": "Update the best friend.", "operationId": "People.UpdateRefBestFriend", "parameters": [ { @@ -20547,7 +20543,6 @@ "People.Person" ], "summary": "Delete ref of navigation property BestFriend for People", - "description": "The best friend.", "operationId": "People.DeleteRefBestFriend", "parameters": [ { @@ -30219,7 +30214,7 @@ "People.Trip" ], "summary": "Get Trips from People", - "description": "Collection of trips.", + "description": "List trips.", "operationId": "People.ListTrips", "parameters": [ { @@ -30345,7 +30340,7 @@ "People.Trip" ], "summary": "Create new navigation property to Trips for People", - "description": "Collection of trips.", + "description": "Create a trip.", "operationId": "People.CreateTrips", "parameters": [ { @@ -30402,7 +30397,7 @@ "People.Trip" ], "summary": "Get Trips from People", - "description": "Collection of trips.", + "description": "Get a trip.", "operationId": "People.GetTrips", "parameters": [ { @@ -30501,7 +30496,7 @@ "People.Trip" ], "summary": "Update the navigation property Trips in People", - "description": "Collection of trips.", + "description": "Update a trip.", "operationId": "People.UpdateTrips", "parameters": [ { @@ -30561,7 +30556,7 @@ "People.Trip" ], "summary": "Delete navigation property Trips for People", - "description": "Collection of trips.", + "description": "Delete a trip.", "operationId": "People.DeleteTrips", "parameters": [ { diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.yaml b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.yaml index faeb041c..16ab4ad8 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.yaml +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.yaml @@ -573,7 +573,6 @@ paths: tags: - Airports.Person summary: Update the ref of navigation property EmergencyAuthority in Airports - description: The person to contact in case of a crisis at this location. operationId: Airports.UpdateRefEmergencyAuthority parameters: - name: IcaoCode @@ -600,7 +599,6 @@ paths: tags: - Airports.Person summary: Delete ref of navigation property EmergencyAuthority for Airports - description: The person to contact in case of a crisis at this location. operationId: Airports.DeleteRefEmergencyAuthority parameters: - name: IcaoCode @@ -1363,7 +1361,7 @@ paths: tags: - Me.Person summary: Update the ref of navigation property BestFriend in Me - description: The best friend. + description: Update the best friend. operationId: Me.UpdateRefBestFriend requestBody: description: New navigation property ref values @@ -1388,7 +1386,6 @@ paths: tags: - Me.Person summary: Delete ref of navigation property BestFriend for Me - description: The best friend. operationId: Me.DeleteRefBestFriend parameters: - name: If-Match @@ -7142,7 +7139,7 @@ paths: tags: - Me.Trip summary: Get Trips from Me - description: Collection of trips. + description: List trips. operationId: Me.ListTrips parameters: - $ref: '#/components/parameters/top' @@ -7226,7 +7223,7 @@ paths: tags: - Me.Trip summary: Create new navigation property to Trips for Me - description: Collection of trips. + description: Create a trip. operationId: Me.CreateTrips requestBody: description: New navigation property @@ -7257,7 +7254,7 @@ paths: tags: - Me.Trip summary: Get Trips from Me - description: Collection of trips. + description: Get a trip. operationId: Me.GetTrips parameters: - name: TripId @@ -7323,7 +7320,7 @@ paths: tags: - Me.Trip summary: Update the navigation property Trips in Me - description: Collection of trips. + description: Update a trip. operationId: Me.UpdateTrips parameters: - name: TripId @@ -7359,7 +7356,7 @@ paths: tags: - Me.Trip summary: Delete navigation property Trips for Me - description: Collection of trips. + description: Delete a trip. operationId: Me.DeleteTrips parameters: - name: TripId @@ -8235,7 +8232,7 @@ paths: tags: - NewComePeople.Person summary: Update the ref of navigation property BestFriend in NewComePeople - description: The best friend. + description: Update the best friend. operationId: NewComePeople.UpdateRefBestFriend parameters: - name: UserName @@ -8268,7 +8265,6 @@ paths: tags: - NewComePeople.Person summary: Delete ref of navigation property BestFriend for NewComePeople - description: The best friend. operationId: NewComePeople.DeleteRefBestFriend parameters: - name: UserName @@ -13080,7 +13076,7 @@ paths: tags: - NewComePeople.Trip summary: Get Trips from NewComePeople - description: Collection of trips. + description: List trips. operationId: NewComePeople.ListTrips parameters: - name: UserName @@ -13165,7 +13161,7 @@ paths: tags: - NewComePeople.Trip summary: Create new navigation property to Trips for NewComePeople - description: Collection of trips. + description: Create a trip. operationId: NewComePeople.CreateTrips parameters: - name: UserName @@ -13198,7 +13194,7 @@ paths: tags: - NewComePeople.Trip summary: Get Trips from NewComePeople - description: Collection of trips. + description: Get a trip. operationId: NewComePeople.GetTrips parameters: - name: UserName @@ -13265,7 +13261,7 @@ paths: tags: - NewComePeople.Trip summary: Update the navigation property Trips in NewComePeople - description: Collection of trips. + description: Update a trip. operationId: NewComePeople.UpdateTrips parameters: - name: UserName @@ -13302,7 +13298,7 @@ paths: tags: - NewComePeople.Trip summary: Delete navigation property Trips for NewComePeople - description: Collection of trips. + description: Delete a trip. operationId: NewComePeople.DeleteTrips parameters: - name: UserName @@ -14269,7 +14265,7 @@ paths: tags: - People.Person summary: Update the ref of navigation property BestFriend in People - description: The best friend. + description: Update the best friend. operationId: People.UpdateRefBestFriend parameters: - name: UserName @@ -14302,7 +14298,6 @@ paths: tags: - People.Person summary: Delete ref of navigation property BestFriend for People - description: The best friend. operationId: People.DeleteRefBestFriend parameters: - name: UserName @@ -21088,7 +21083,7 @@ paths: tags: - People.Trip summary: Get Trips from People - description: Collection of trips. + description: List trips. operationId: People.ListTrips parameters: - name: UserName @@ -21179,7 +21174,7 @@ paths: tags: - People.Trip summary: Create new navigation property to Trips for People - description: Collection of trips. + description: Create a trip. operationId: People.CreateTrips parameters: - name: UserName @@ -21218,7 +21213,7 @@ paths: tags: - People.Trip summary: Get Trips from People - description: Collection of trips. + description: Get a trip. operationId: People.GetTrips parameters: - name: UserName @@ -21291,7 +21286,7 @@ paths: tags: - People.Trip summary: Update the navigation property Trips in People - description: Collection of trips. + description: Update a trip. operationId: People.UpdateTrips parameters: - name: UserName @@ -21334,7 +21329,7 @@ paths: tags: - People.Trip summary: Delete navigation property Trips for People - description: Collection of trips. + description: Delete a trip. operationId: People.DeleteTrips parameters: - name: UserName From 3dbdbeae64cb1549283aecd5e86086ea95b3a964 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Thu, 17 Feb 2022 02:41:02 +0300 Subject: [PATCH 05/25] Update comment --- src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 2b93a44f..ce7cb5f4 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -348,7 +348,7 @@ private void RetrieveNavigationPropertyPaths( return; } - // Get the NavigationRestrictions + // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined IEdmVocabularyAnnotatable annotatableNavigationSource = currentPath.FirstSegment.GetAnnotables().FirstOrDefault(); NavigationRestrictionsType navigation = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions) ?? _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); From 8208d726d1f6f2bf41996170c1cdf788d1d9d59e Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Fri, 18 Feb 2022 02:16:17 +0300 Subject: [PATCH 06/25] Factor out common code into helper classes --- .../Common/EdmModelHelper.cs | 31 +++++++++++++++++++ .../Common/Utils.cs | 15 +++++++++ .../NavigationPropertyOperationHandler.cs | 21 ++----------- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs index dde0b187..cb0f0cf5 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs @@ -8,6 +8,7 @@ using System.Linq; using Microsoft.OData.Edm; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.OData.Vocabulary.Capabilities; namespace Microsoft.OpenApi.OData.Common { @@ -61,6 +62,36 @@ internal static OpenApiSchema GetDerivedTypesReferenceSchema(IEdmStructuredType }; return schema; + } + + /// + /// Verifies whether the provided navigation restrictions allow for navigability of a navigation property. + /// + /// The . + /// The . + /// + internal static bool NavigationRestrictionsAllowsNavigability( + NavigationRestrictionsType restrictionType, + NavigationPropertyRestriction restrictionProperty) + { + // Verify using individual navigation restriction first + if (restrictionProperty != null && restrictionProperty.Navigability != null && restrictionProperty.Navigability.Value == NavigationType.None) + { + return false; + } + + if (restrictionProperty == null || restrictionProperty.Navigability == null) + { + // if the individual has no navigability setting, use the global navigability setting + if (restrictionType != null && !restrictionType.IsNavigable) + { + // Default navigability for all navigation properties of the annotation target. + // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. + return false; + } + } + + return true; } } } \ No newline at end of file diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/Utils.cs b/src/Microsoft.OpenApi.OData.Reader/Common/Utils.cs index 4f821154..20378fd1 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/Utils.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/Utils.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.OpenApi.OData.Edm; using Microsoft.OpenApi.OData.Vocabulary; namespace Microsoft.OpenApi.OData.Common @@ -115,5 +116,19 @@ internal static string CheckArgumentNullOrEmpty(string value, string parameterNa /// The changed string. internal static string ToFirstCharacterLowerCase(this string input) => string.IsNullOrEmpty(input) ? input : $"{char.ToLowerInvariant(input.FirstOrDefault())}{input.Substring(1)}"; + + /// + /// Gets the navigation path. + /// + /// The . + /// Optional: The navigation property name. + internal static string NavigationPropertyPath(this ODataPath path, string navigationPropertyName = null) + { + string value = string.Join("/", + path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment + || s is ODataStreamContentSegment || s is ODataStreamPropertySegment)).Select(e => e.Identifier)); + + return navigationPropertyName == null ? value : $"{value}/{navigationPropertyName}"; + } } } \ No newline at end of file diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs index 2d2eb08d..67b4e85b 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs @@ -29,11 +29,6 @@ internal abstract class NavigationPropertyOperationHandler : OperationHandler /// protected IEdmNavigationSource NavigationSource { get; private set; } - /// - /// Gets the navigation path. - /// - protected string NavigationPropertyPath { get; private set; } - /// /// Gets the navigation restriction. /// @@ -61,10 +56,6 @@ protected override void Initialize(ODataContext context, ODataPath path) LastSegmentIsRefSegment = path.LastSegment is ODataRefSegment; NavigationProperty = path.OfType().Last().NavigationProperty; - NavigationPropertyPath = string.Join("/", - Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment - || s is ODataStreamContentSegment || s is ODataStreamPropertySegment)).Select(e => e.Identifier)); - IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmSingleton singleton = NavigationSource as IEdmSingleton; @@ -78,16 +69,8 @@ protected override void Initialize(ODataContext context, ODataPath path) navigation = Context.Model.GetRecord(singleton, CapabilitiesConstants.NavigationRestrictions); } - if (navigation != null && navigation.RestrictedProperties != null) - { - Restriction = navigation.RestrictedProperties.FirstOrDefault(r => r.NavigationProperty != null && r.NavigationProperty == NavigationPropertyPath); - } - else - { - // Navigation restrictions annotation can be defined in-line - Restriction = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.NavigationRestrictions)? - .RestrictedProperties?.FirstOrDefault(); - } + Restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty != null && r.NavigationProperty == Path.NavigationPropertyPath()) + ?? Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.NavigationRestrictions)?.RestrictedProperties?.FirstOrDefault(); } /// From 7a19e47d68ba2ba291f6bdda4ccb02e95132d855 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Fri, 18 Feb 2022 02:17:24 +0300 Subject: [PATCH 07/25] Get navigation restrictions from nav. sources and in-lined nav. properties --- .../Edm/ODataPathProvider.cs | 32 +++++++++++------- .../NavigationPropertyPathItemHandler.cs | 33 +++++++------------ 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index ce7cb5f4..fdcb78eb 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -316,7 +316,7 @@ private void RetrieveMediaEntityStreamPaths(IEdmEntityType entityType, ODataPath currentPath.Pop(); } } - + /// /// Retrieve the path for . /// @@ -337,7 +337,7 @@ private void RetrieveNavigationPropertyPaths( if (visitedNavigationProperties == null) { - visitedNavigationProperties = new (); + visitedNavigationProperties = new(); } var navPropFullyQualifiedName = $"{navigationProperty.DeclaringType.FullTypeName()}/{navigationProperty.Name}"; @@ -348,27 +348,34 @@ private void RetrieveNavigationPropertyPaths( return; } - // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined - IEdmVocabularyAnnotatable annotatableNavigationSource = currentPath.FirstSegment.GetAnnotables().FirstOrDefault(); - NavigationRestrictionsType navigation = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions) - ?? _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); + // Get the navigation source for this navigation property + IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)(currentPath.FirstSegment as ODataNavigationSourceSegment).NavigationSource; + + // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined in the navigation property + NavigationRestrictionsType navSourceRestrictionType = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions); + NavigationRestrictionsType navPropRestrictionType = _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); + + NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? + .FirstOrDefault(r => r.NavigationProperty == currentPath.NavigationPropertyPath(navigationProperty.Name)) + ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); // Check whether the navigation property should be part of the path - if (navigation != null && !navigation.IsNavigable) - { - return; + if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || + EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) + { + return; } // Whether to expand the navigation property bool shouldExpand = navigationProperty.ContainsTarget; - // append a navigation property. + // Append a navigation property. currentPath.Push(new ODataNavigationPropertySegment(navigationProperty)); AppendPath(currentPath.Clone()); visitedNavigationProperties.Push(navPropFullyQualifiedName); // Check whether a collection-valued navigation property should be indexed by key value(s). - bool? indexableByKey = navigation?.RestrictedProperties?.FirstOrDefault()?.IndexableByKey; + bool? indexableByKey = restriction?.IndexableByKey; if (indexableByKey == null || indexableByKey == true) { @@ -390,7 +397,8 @@ private void RetrieveNavigationPropertyPaths( // ~/entityset/{key}/single-valued-Nav/subtype CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, targetsMany); - if (navigation?.Referenceable == true) + if (navSourceRestrictionType?.Referenceable == true || + navPropRestrictionType?.Referenceable == true) { // Referenceable navigation properties // Single-Valued: ~/entityset/{key}/single-valued-Nav/$ref diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs index e2d75c12..114ca131 100644 --- a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs @@ -53,31 +53,22 @@ protected override void SetOperations(OpenApiPathItem item) if (target == null) { target = NavigationSource as IEdmSingleton; - } - - string navigationPropertyPath = String.Join("/", - Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier)); - - NavigationRestrictionsType navigation = Context.Model.GetRecord(target, CapabilitiesConstants.NavigationRestrictions); - NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath); - - // verify using individual first - if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None) + } + + NavigationRestrictionsType navSourceRestrictionType = Context.Model.GetRecord(target, CapabilitiesConstants.NavigationRestrictions); + NavigationRestrictionsType navPropRestrictionType = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.NavigationRestrictions); + + NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? + .FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath()) + ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); + + // Check whether the navigation property should be part of the path + if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || + EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) { return; } - if (restriction == null || restriction.Navigability == null) - { - // if the individual has not navigability setting, use the global navigability setting - if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None) - { - // Default navigability for all navigation properties of the annotation target. - // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. - return; - } - } - // containment: Get / (Post - Collection | Patch - Single) // non-containment: Get AddGetOperation(item, restriction); From edff362e90a5d3661be67a12b78fdc8e3d5bf420 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Fri, 18 Feb 2022 15:33:32 +0300 Subject: [PATCH 08/25] Minor formatting changes --- src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs | 6 +++--- .../Operation/MediaEntityOperationalHandler.cs | 2 +- .../Operation/EntitySetPostOperationHandlerTests.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index fdcb78eb..705905c7 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -316,7 +316,7 @@ private void RetrieveMediaEntityStreamPaths(IEdmEntityType entityType, ODataPath currentPath.Pop(); } } - + /// /// Retrieve the path for . /// @@ -362,8 +362,8 @@ private void RetrieveNavigationPropertyPaths( // Check whether the navigation property should be part of the path if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) - { - return; + { + return; } // Whether to expand the navigation property diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs index dbe75150..a14c75de 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityOperationalHandler.cs @@ -178,7 +178,7 @@ protected IDictionary GetContentDescription() /// The annotatable stream property. protected IEdmVocabularyAnnotatable GetAnnotatableElement() { - // Only StreamProperty ODataSegmentKind is annotatable + // Only ODataStreamPropertySegment is annotatable if (!LastSegmentIsStreamPropertySegment) return null; // Retrieve the entity type of the segment before the stream property segment diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs index 019f56d2..064f91ea 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs @@ -252,7 +252,7 @@ internal static IEdmModel GetEdmModel(string annotation, bool hasStream = false) - {1} + {1} From a04f9e190b9c86c9747fa158bea8526f91246fe2 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Fri, 18 Feb 2022 16:58:02 +0300 Subject: [PATCH 09/25] Remove description The description is basically just a description of the element and doesn't really add any more info. about the operation --- .../Operation/ComplexPropertyDeleteOperationHandler.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyDeleteOperationHandler.cs index 3b25b527..f2127066 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyDeleteOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyDeleteOperationHandler.cs @@ -24,9 +24,6 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Summary operation.Summary = $"Delete {ComplexPropertySegment.Property.Name} property value"; - // Description - operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); - // OperationId if (Context.Settings.EnableOperationId) { From 36758ddb445f6990f1d94d16dcc34c96230ea60d Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 10:57:20 +0300 Subject: [PATCH 10/25] Update src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs Co-authored-by: Vincent Biret --- src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs index cb0f0cf5..e42634e9 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs @@ -80,7 +80,7 @@ internal static bool NavigationRestrictionsAllowsNavigability( return false; } - if (restrictionProperty == null || restrictionProperty.Navigability == null) + if (restrictionProperty?.Navigability == null) { // if the individual has no navigability setting, use the global navigability setting if (restrictionType != null && !restrictionType.IsNavigable) From f3f225c2c3637532207dbbcda7e07a82c4082dcf Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 10:57:58 +0300 Subject: [PATCH 11/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/SingletonPatchOperationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs index 4da18cb7..fff63c17 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs @@ -104,7 +104,7 @@ protected override void SetResponses(OpenApiOperation operation) /// protected override void SetSecurity(OpenApiOperation operation) { - if (UpdateRestrictions == null || UpdateRestrictions.Permissions == null) + if (UpdateRestrictions?.Permissions == null) { return; } From 66f577143a3d9291743360b9045af5cec8dc2a6a Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 10:58:11 +0300 Subject: [PATCH 12/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/SingletonGetOperationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs index c0f9febc..a3d2a5c7 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs @@ -133,7 +133,7 @@ protected override void SetResponses(OpenApiOperation operation) /// protected override void SetSecurity(OpenApiOperation operation) { - if (ReadRestrictions == null || ReadRestrictions.Permissions == null) + if (ReadRestrictions?.Permissions == null) { return; } From 10a5ddce899e5617e6ef268c8547b35309caa2e6 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 10:58:41 +0300 Subject: [PATCH 13/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/EntityUpdateOperationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs index 8e98711c..70749507 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs @@ -100,7 +100,7 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - if (UpdateRestrictions == null || UpdateRestrictions.Permissions == null) + if (UpdateRestrictions?.Permissions == null) { return; } From f2efebb2a95e787a1dcfafc8c998ae00fc9dd263 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 10:59:01 +0300 Subject: [PATCH 14/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/EntitySetGetOperationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs index 863cb48a..ab54ea89 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs @@ -165,7 +165,7 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - if (ReadRestrictions == null || ReadRestrictions.Permissions == null) + if (ReadRestrictions?.Permissions == null) { return; } From efa8d0dd8b6c56525f8dd05818e1d7a5a04ee199 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 11:51:15 +0300 Subject: [PATCH 15/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/EntitySetPostOperationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs index 9ebff116..cfb2ace8 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs @@ -90,7 +90,7 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - if (InsertRestrictions == null || InsertRestrictions.Permissions == null) + if (InsertRestrictions?.Permissions == null) { return; } From 83adb6bdcd0908787a5ce4218a417efed5f8fa80 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Mon, 21 Feb 2022 11:54:15 +0300 Subject: [PATCH 16/25] Update src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs Co-authored-by: Vincent Biret --- .../Operation/RefGetOperationHandler.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs index 8916f954..8c3107f9 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs @@ -42,9 +42,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Description ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions; - operation.Description = readRestriction != null - ? LastSegmentIsKeySegment ? readRestriction.ReadByKeyRestrictions?.Description : readRestriction.Description - : Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); } protected override void SetExtensions(OpenApiOperation operation) From 10686a88fc4908559ecfba6612ac68e8998e245a Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Mon, 21 Feb 2022 12:33:32 +0300 Subject: [PATCH 17/25] Minor refactoring --- .../Edm/ODataPathProvider.cs | 10 +++++----- .../Operation/NavigationPropertyGetOperationHandler.cs | 5 ++--- .../Operation/RefGetOperationHandler.cs | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 705905c7..f4800460 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -339,8 +339,8 @@ private void RetrieveNavigationPropertyPaths( { visitedNavigationProperties = new(); } - - var navPropFullyQualifiedName = $"{navigationProperty.DeclaringType.FullTypeName()}/{navigationProperty.Name}"; + + string navPropFullyQualifiedName = $"{navigationProperty.DeclaringType.FullTypeName()}/{navigationProperty.Name}"; // Check whether the navigation property has already been navigated in the path if (visitedNavigationProperties.Contains(navPropFullyQualifiedName)) @@ -349,7 +349,7 @@ private void RetrieveNavigationPropertyPaths( } // Get the navigation source for this navigation property - IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)(currentPath.FirstSegment as ODataNavigationSourceSegment).NavigationSource; + IEdmVocabularyAnnotatable annotatableNavigationSource = (currentPath.FirstSegment as ODataNavigationSourceSegment).NavigationSource as IEdmVocabularyAnnotatable; // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined in the navigation property NavigationRestrictionsType navSourceRestrictionType = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions); @@ -375,9 +375,9 @@ private void RetrieveNavigationPropertyPaths( visitedNavigationProperties.Push(navPropFullyQualifiedName); // Check whether a collection-valued navigation property should be indexed by key value(s). - bool? indexableByKey = restriction?.IndexableByKey; + bool indexableByKey = restriction?.IndexableByKey ?? true; - if (indexableByKey == null || indexableByKey == true) + if (indexableByKey) { IEdmEntityType navEntityType = navigationProperty.ToEntityType(); var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many; diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs index a2f27e09..60ed171f 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs @@ -44,9 +44,8 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Description ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions; - operation.Description = readRestriction != null - ? LastSegmentIsKeySegment ? readRestriction.ReadByKeyRestrictions?.Description : readRestriction.Description - : Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) + ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); base.SetBasicInfo(operation); } diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs index 8c3107f9..a8e2f837 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs @@ -42,7 +42,8 @@ protected override void SetBasicInfo(OpenApiOperation operation) // Description ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions; - operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); + operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) + ?? Context.Model.GetDescriptionAnnotation(NavigationProperty); } protected override void SetExtensions(OpenApiOperation operation) From caa55161af19b206735cd714b41fb04568059ab2 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Tue, 22 Feb 2022 15:49:46 +0300 Subject: [PATCH 18/25] Get descriptions for complex properties Use CRUD restrictions annotations to get the descriptions --- .../ComplexPropertyGetOperationHandler.cs | 33 ++++++++++++------- .../ComplexPropertyPostOperationHandler.cs | 26 ++++++++++----- .../ComplexPropertyUpdateOperationHandler.cs | 31 ++++++++++++----- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs index 2d66d2a4..c152705a 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs @@ -19,6 +19,19 @@ internal class ComplexPropertyGetOperationHandler : ComplexPropertyBaseOperation { /// public override OperationType OperationType => OperationType.Get; + + /// + /// Gets/Sets the + /// + private ReadRestrictionsType ReadRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + ReadRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.ReadRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -34,7 +47,7 @@ protected override void SetBasicInfo(OpenApiOperation operation) } // Description - operation.Description = Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); + operation.Description = ReadRestrictions?.Description ?? Context.Model.GetDescriptionAnnotation(ComplexPropertySegment.Property); base.SetBasicInfo(operation); } @@ -195,31 +208,29 @@ private void SetSingleResponse(OpenApiOperation operation) } protected override void SetSecurity(OpenApiOperation operation) { - ReadRestrictionsType read = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.ReadRestrictions); - if (read == null || read.Permissions == null) + if (ReadRestrictions?.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(read.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(ReadRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) - { - ReadRestrictionsType read = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.ReadRestrictions); - if (read == null) + { + if (ReadRestrictions == null) { return; } - if (read.CustomHeaders != null) + if (ReadRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, read.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, ReadRestrictions.CustomHeaders, ParameterLocation.Header); } - if (read.CustomQueryOptions != null) + if (ReadRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, read.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, ReadRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } \ No newline at end of file diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs index 3c6ba325..6df41872 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs @@ -25,10 +25,17 @@ protected override void Initialize(ODataContext context, ODataPath path) { throw new InvalidOperationException("OData conventions do not support POSTing to a complex property that is not a collection."); } + + InsertRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.InsertRestrictions); } /// public override OperationType OperationType => OperationType.Post; + /// + /// Gets/Sets the + /// + private InsertRestrictionsType InsertRestrictions { get; set; } + /// protected override void SetBasicInfo(OpenApiOperation operation) { @@ -42,6 +49,9 @@ protected override void SetBasicInfo(OpenApiOperation operation) operation.OperationId = ComplexPropertySegment.Property.Name + "." + typeName + ".Set" + Utils.UpperFirstChar(typeName); } + // Description + operation.Description = InsertRestrictions?.Description; + base.SetBasicInfo(operation); } @@ -103,31 +113,29 @@ protected override void SetResponses(OpenApiOperation operation) protected override void SetSecurity(OpenApiOperation operation) { - InsertRestrictionsType insert = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.InsertRestrictions); - if (insert == null || insert.Permissions == null) + if (InsertRestrictions?.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(insert.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(InsertRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - InsertRestrictionsType insert = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.InsertRestrictions); - if (insert == null) + if (InsertRestrictions == null) { return; } - if (insert.CustomQueryOptions != null) + if (InsertRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, insert.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, InsertRestrictions.CustomQueryOptions, ParameterLocation.Query); } - if (insert.CustomHeaders != null) + if (InsertRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, insert.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, InsertRestrictions.CustomHeaders, ParameterLocation.Header); } } } \ No newline at end of file diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs index 2ebaaa13..b726257a 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs @@ -16,12 +16,27 @@ namespace Microsoft.OpenApi.OData.Operation; internal abstract class ComplexPropertyUpdateOperationHandler : ComplexPropertyBaseOperationHandler { + /// + /// Gets/Sets the + /// + private UpdateRestrictionsType UpdateRestrictions { get; set; } + + protected override void Initialize(ODataContext context, ODataPath path) + { + base.Initialize(context, path); + + UpdateRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.UpdateRestrictions); + } + /// protected override void SetBasicInfo(OpenApiOperation operation) { // Summary operation.Summary = $"Update property {ComplexPropertySegment.Property.Name} value."; + // Description + operation.Description = UpdateRestrictions?.Description; + // OperationId if (Context.Settings.EnableOperationId) { @@ -84,31 +99,29 @@ protected override void SetResponses(OpenApiOperation operation) } protected override void SetSecurity(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.UpdateRestrictions); - if (update == null || update.Permissions == null) + if (UpdateRestrictions?.Permissions == null) { return; } - operation.Security = Context.CreateSecurityRequirements(update.Permissions).ToList(); + operation.Security = Context.CreateSecurityRequirements(UpdateRestrictions.Permissions).ToList(); } protected override void AppendCustomParameters(OpenApiOperation operation) { - UpdateRestrictionsType update = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.UpdateRestrictions); - if (update == null) + if (UpdateRestrictions == null) { return; } - if (update.CustomHeaders != null) + if (UpdateRestrictions.CustomHeaders != null) { - AppendCustomParameters(operation, update.CustomHeaders, ParameterLocation.Header); + AppendCustomParameters(operation, UpdateRestrictions.CustomHeaders, ParameterLocation.Header); } - if (update.CustomQueryOptions != null) + if (UpdateRestrictions.CustomQueryOptions != null) { - AppendCustomParameters(operation, update.CustomQueryOptions, ParameterLocation.Query); + AppendCustomParameters(operation, UpdateRestrictions.CustomQueryOptions, ParameterLocation.Query); } } } \ No newline at end of file From 01a84f91aed7d6af703dd4ef5991df6a7b8c088f Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Tue, 22 Feb 2022 15:50:29 +0300 Subject: [PATCH 19/25] Update tests to validate retrieving descriptions for complex properties --- .../ComplexPropertyGetOperationHandlerTests.cs | 2 ++ ...ComplexPropertyPatchOperationHandlerTests.cs | 2 ++ .../ComplexPropertyPostOperationHandlerTests.cs | 1 + .../EntitySetGetOperationHandlerTests.cs | 17 +++++++++++++++-- .../EntitySetPostOperationHandlerTests.cs | 8 +++++++- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyGetOperationHandlerTests.cs index 23529743..74e9deb4 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyGetOperationHandlerTests.cs @@ -37,6 +37,7 @@ public void CreateComplexPropertyGetOperationReturnsCorrectOperationForSingle(bo // Assert Assert.NotNull(get); Assert.Equal("Get BillingAddress property value", get.Summary); + Assert.Equal("Get the BillingAddress.", get.Description); Assert.NotNull(get.Parameters); Assert.Equal(3, get.Parameters.Count); //id, select, expand @@ -77,6 +78,7 @@ public void CreateComplexPropertyGetOperationReturnsCorrectOperationForCollectio // Assert Assert.NotNull(get); Assert.Equal("Get AlternativeAddresses property value", get.Summary); + Assert.Equal("The AlternativeAddresses.", get.Description); Assert.NotNull(get.Parameters); Assert.Equal(9, get.Parameters.Count); //id, select, expand, order, top, skip, count, search, filter diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPatchOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPatchOperationHandlerTests.cs index 59decb48..61b4a36a 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPatchOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPatchOperationHandlerTests.cs @@ -37,6 +37,7 @@ public void CreateComplexPropertyDeleteOperationReturnsCorrectOperationForSingle // Assert Assert.NotNull(patch); Assert.Equal("Update property BillingAddress value.", patch.Summary); + Assert.Equal("Update the BillingAddress.", patch.Description); Assert.NotNull(patch.Parameters); Assert.Equal(1, patch.Parameters.Count); //id @@ -77,6 +78,7 @@ public void CreateComplexPropertyPostOperationReturnsCorrectOperationForCollecti // Assert Assert.NotNull(patch); Assert.Equal("Update property AlternativeAddresses value.", patch.Summary); + Assert.Null(patch.Description); Assert.NotNull(patch.Parameters); Assert.Equal(1, patch.Parameters.Count); //id diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPostOperationHandlerTests.cs index 2ef0d880..87042a32 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/ComplexPropertyPostOperationHandlerTests.cs @@ -52,6 +52,7 @@ public void CreateComplexPropertyPostOperationReturnsCorrectOperationForCollecti // Assert Assert.NotNull(post); Assert.Equal("Sets a new value for the collection of Address.", post.Summary); + Assert.Equal("Create a new AlternativeAddress.", post.Description); Assert.NotNull(post.Parameters); Assert.Equal(2, post.Parameters.Count); //id, etag diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs index dc00fb73..935f963c 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetGetOperationHandlerTests.cs @@ -336,9 +336,22 @@ public static IEdmModel GetEdmModel(string annotation) - + + + + + + + + + + + + - + + + diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs index 064f91ea..ca2c28a1 100644 --- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs +++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EntitySetPostOperationHandlerTests.cs @@ -244,7 +244,13 @@ internal static IEdmModel GetEdmModel(string annotation, bool hasStream = false) - + + + + + + + From fb7beafc098edb2af9dc44535b877aee97ef778b Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:25:07 +0300 Subject: [PATCH 20/25] Update src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs Co-authored-by: Vincent Biret --- src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs index e42634e9..f3c72bda 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs @@ -75,7 +75,7 @@ internal static bool NavigationRestrictionsAllowsNavigability( NavigationPropertyRestriction restrictionProperty) { // Verify using individual navigation restriction first - if (restrictionProperty != null && restrictionProperty.Navigability != null && restrictionProperty.Navigability.Value == NavigationType.None) + if (restrictionProperty?.Navigability?.Value == NavigationType.None) { return false; } From c6483d477f8fa000fa97e2757dffefc1a51adcec Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:29:37 +0300 Subject: [PATCH 21/25] Update src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs Co-authored-by: Vincent Biret --- src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 950d1995..6114acb7 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -383,7 +383,7 @@ private void RetrieveNavigationPropertyPaths( ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); // Check whether the navigation property should be part of the path - if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || + if (!EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) || EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) { return; From 6dd41ef47b05720c0996e6aa129357fee44e7b6b Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:30:56 +0300 Subject: [PATCH 22/25] Update src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs Co-authored-by: Vincent Biret --- src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 6114acb7..1c201a25 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -384,7 +384,7 @@ private void RetrieveNavigationPropertyPaths( // Check whether the navigation property should be part of the path if (!EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) || - EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) + !EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction)) { return; } From 6f40299905054b8c832b99b867fe74b7012c2f15 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:32:02 +0300 Subject: [PATCH 23/25] Update src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs Co-authored-by: Vincent Biret --- src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index 1c201a25..aef9c145 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -420,7 +420,7 @@ private void RetrieveNavigationPropertyPaths( // ~/entityset/{key}/single-valued-Nav/subtype CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, targetsMany); - if (navSourceRestrictionType?.Referenceable == true || + if (navSourceRestrictionType?.Referenceable ?? false || navPropRestrictionType?.Referenceable == true) { // Referenceable navigation properties From 1a936aeb3f400138613c28adb053f2628837c802 Mon Sep 17 00:00:00 2001 From: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:08:08 +0300 Subject: [PATCH 24/25] Update src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs Co-authored-by: Vincent Biret --- .../Common/EdmModelHelper.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs index f3c72bda..02c9a925 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs @@ -80,18 +80,10 @@ internal static bool NavigationRestrictionsAllowsNavigability( return false; } - if (restrictionProperty?.Navigability == null) - { - // if the individual has no navigability setting, use the global navigability setting - if (restrictionType != null && !restrictionType.IsNavigable) - { - // Default navigability for all navigation properties of the annotation target. - // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. - return false; - } - } - - return true; + return restrictionProperty?.Navigability != null || restrictionType == null || restrictionType.IsNavigable; + // if the individual has no navigability setting, use the global navigability setting + // Default navigability for all navigation properties of the annotation target. + // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. } } } \ No newline at end of file From 10dfc4bf677e6ea2206848bf1221920c902a9686 Mon Sep 17 00:00:00 2001 From: Irvine Sunday Date: Wed, 23 Feb 2022 19:29:00 +0300 Subject: [PATCH 25/25] Apply PR review suggestions --- .../Common/EdmModelHelper.cs | 4 ++-- .../Edm/ODataPathProvider.cs | 23 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs index 02c9a925..e518a3d8 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Common/EdmModelHelper.cs @@ -75,15 +75,15 @@ internal static bool NavigationRestrictionsAllowsNavigability( NavigationPropertyRestriction restrictionProperty) { // Verify using individual navigation restriction first - if (restrictionProperty?.Navigability?.Value == NavigationType.None) + if (restrictionProperty?.Navigability != null && restrictionProperty.Navigability.Value == NavigationType.None) { return false; } - return restrictionProperty?.Navigability != null || restrictionType == null || restrictionType.IsNavigable; // if the individual has no navigability setting, use the global navigability setting // Default navigability for all navigation properties of the annotation target. // Individual navigation properties can override this value via `RestrictedProperties/Navigability`. + return restrictionProperty?.Navigability != null || restrictionType == null || restrictionType.IsNavigable; } } } \ No newline at end of file diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs index aef9c145..676c64dd 100644 --- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs +++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs @@ -365,18 +365,23 @@ private void RetrieveNavigationPropertyPaths( string navPropFullyQualifiedName = $"{navigationProperty.DeclaringType.FullTypeName()}/{navigationProperty.Name}"; - // Check whether the navigation property has already been navigated in the path + // Check whether the navigation property has already been navigated in the path. if (visitedNavigationProperties.Contains(navPropFullyQualifiedName)) { return; } - // Get the navigation source for this navigation property - IEdmVocabularyAnnotatable annotatableNavigationSource = (currentPath.FirstSegment as ODataNavigationSourceSegment).NavigationSource as IEdmVocabularyAnnotatable; + // Get the annotatable navigation source for this navigation property. + IEdmVocabularyAnnotatable annotatableNavigationSource = (currentPath.FirstSegment as ODataNavigationSourceSegment)?.NavigationSource as IEdmVocabularyAnnotatable; + NavigationRestrictionsType navSourceRestrictionType = null; + NavigationRestrictionsType navPropRestrictionType = null; - // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined in the navigation property - NavigationRestrictionsType navSourceRestrictionType = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions); - NavigationRestrictionsType navPropRestrictionType = _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); + // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined in the navigation property. + if (annotatableNavigationSource != null) + { + navSourceRestrictionType = _model.GetRecord(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions); + navPropRestrictionType = _model.GetRecord(navigationProperty, CapabilitiesConstants.NavigationRestrictions); + } NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? .FirstOrDefault(r => r.NavigationProperty == currentPath.NavigationPropertyPath(navigationProperty.Name)) @@ -389,7 +394,7 @@ private void RetrieveNavigationPropertyPaths( return; } - // Whether to expand the navigation property + // Whether to expand the navigation property. bool shouldExpand = navigationProperty.ContainsTarget; // Append a navigation property. @@ -420,8 +425,8 @@ private void RetrieveNavigationPropertyPaths( // ~/entityset/{key}/single-valued-Nav/subtype CreateTypeCastPaths(currentPath, convertSettings, navigationProperty.DeclaringType, navigationProperty, targetsMany); - if (navSourceRestrictionType?.Referenceable ?? false || - navPropRestrictionType?.Referenceable == true) + if ((navSourceRestrictionType?.Referenceable ?? false) || + (navPropRestrictionType?.Referenceable ?? false)) { // Referenceable navigation properties // Single-Valued: ~/entityset/{key}/single-valued-Nav/$ref