refactor for the capabilities and modify the test cases
This commit is contained in:
parent
91f8fb371a
commit
13ca340cc0
|
@ -3,8 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -13,18 +11,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class BatchSupported : SupportedRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.BatchSupported;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="BatchSupported"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The annotation target <see cref="IEdmEntityContainer"/>.</param>
|
||||
public BatchSupported(IEdmModel model, IEdmEntityContainer target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.BatchSupported;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,318 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Properties;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// The class provides the functionality for the capabilities annotation.
|
||||
/// </summary>
|
||||
internal static class CapabilitiesExtensions
|
||||
{
|
||||
private static IDictionary<IEdmVocabularyAnnotatable, IDictionary<CapabilitesTermKind, ICapablitiesRestrictions>> _capabilitesRestrictions;
|
||||
private static IEdmModel _savedModel = null;
|
||||
private static object _objectLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.SearchRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.SearchRestrictions or null.</returns>
|
||||
public static SearchRestrictions GetSearchRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.SearchRestrictions) as SearchRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.FilterRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.FilterRestrictions or null.</returns>
|
||||
public static FilterRestrictions GetFilterRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.FilterRestrictions) as FilterRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.NavigationRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.NavigationRestrictions or null.</returns>
|
||||
public static NavigationRestrictions GetNavigationRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.NavigationRestrictions) as NavigationRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.ExpandRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.ExpandRestrictions or null.</returns>
|
||||
public static ExpandRestrictions GetExpandRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.ExpandRestrictions) as ExpandRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.DeleteRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.DeleteRestrictions or null.</returns>
|
||||
public static DeleteRestrictions GetDeleteRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.DeleteRestrictions) as DeleteRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.UpdateRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.UpdateRestrictions or null.</returns>
|
||||
public static UpdateRestrictions GetUpdateRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.UpdateRestrictions) as UpdateRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.InsertRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.InsertRestrictions or null.</returns>
|
||||
public static InsertRestrictions GetInsertRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.InsertRestrictions) as InsertRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.SortRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.SortRestrictions or null.</returns>
|
||||
public static SortRestrictions GetSortRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.SortRestrictions) as SortRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.CountRestrictions.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.CountRestrictions or null.</returns>
|
||||
public static CountRestrictions GetCountRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.CountRestrictions) as CountRestrictions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.BatchSupported.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.BatchSupported or null.</returns>
|
||||
public static BatchSupported GetBatchSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.BatchSupported) as BatchSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.SkipSupported.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.SkipSupported or null.</returns>
|
||||
public static SkipSupported GetSkipSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.SkipSupported) as SkipSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.TopSupported.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.TopSupported or null.</returns>
|
||||
public static TopSupported GetTopSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.TopSupported) as TopSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.KeyAsSegmentSupported.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.KeyAsSegmentSupported or null.</returns>
|
||||
public static KeyAsSegmentSupported GetKeyAsSegmentSupported(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.KeyAsSegmentSupported) as KeyAsSegmentSupported;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Capabilities.V1.IndexableByKey.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The Org.OData.Capabilities.V1.IndexableByKey or null.</returns>
|
||||
public static IndexableByKey GetIndexableByKey(this IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
return model.GetCapabilities(target, CapabilitesTermKind.IndexableByKey) as IndexableByKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the capablities from the <see cref="IEdmModel"/> for the given <see cref="IEdmVocabularyAnnotatable"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <param name="kind">Thye Capabilites kind.</param>
|
||||
/// <returns>The capabilities restrictions or null.</returns>
|
||||
public static ICapablitiesRestrictions GetCapabilities(this IEdmModel model, IEdmVocabularyAnnotatable target, CapabilitesTermKind kind)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
lock (_objectLock)
|
||||
{
|
||||
if (!ReferenceEquals(_savedModel, model))
|
||||
{
|
||||
if (_capabilitesRestrictions != null)
|
||||
{
|
||||
_capabilitesRestrictions.Clear();
|
||||
}
|
||||
_savedModel = model;
|
||||
}
|
||||
|
||||
if (_capabilitesRestrictions == null)
|
||||
{
|
||||
_capabilitesRestrictions = new Dictionary<IEdmVocabularyAnnotatable, IDictionary<CapabilitesTermKind, ICapablitiesRestrictions>>();
|
||||
}
|
||||
|
||||
ICapablitiesRestrictions restriction;
|
||||
if (_capabilitesRestrictions.TryGetValue(target, out IDictionary<CapabilitesTermKind, ICapablitiesRestrictions> value))
|
||||
{
|
||||
// Here means we visited target before and we are sure that the value is not null.
|
||||
if (value.TryGetValue(kind, out restriction))
|
||||
{
|
||||
return restriction;
|
||||
}
|
||||
else
|
||||
{
|
||||
restriction = CreateCapabilitesRestrictions(model, target, kind);
|
||||
value[kind] = restriction;
|
||||
return restriction;
|
||||
}
|
||||
}
|
||||
|
||||
// It's first time to query this target, create new dictionary and restriction.
|
||||
value = new Dictionary<CapabilitesTermKind, ICapablitiesRestrictions>();
|
||||
_capabilitesRestrictions[target] = value;
|
||||
restriction = CreateCapabilitesRestrictions(model, target, kind);
|
||||
value[kind] = restriction;
|
||||
return restriction;
|
||||
}
|
||||
}
|
||||
|
||||
private static ICapablitiesRestrictions CreateCapabilitesRestrictions(this IEdmModel model, IEdmVocabularyAnnotatable target, CapabilitesTermKind kind)
|
||||
{
|
||||
Debug.Assert(model != null);
|
||||
Debug.Assert(target != null);
|
||||
|
||||
ICapablitiesRestrictions capabilitiesRestrictions = null;
|
||||
switch(kind)
|
||||
{
|
||||
case CapabilitesTermKind.DeleteRestrictions: // DeleteRestrictions
|
||||
capabilitiesRestrictions = new DeleteRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.UpdateRestrictions: // UpdateRestrictions
|
||||
capabilitiesRestrictions = new UpdateRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.InsertRestrictions: // InsertRestrictions
|
||||
capabilitiesRestrictions = new InsertRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.SearchRestrictions: // SearchRestrictions
|
||||
capabilitiesRestrictions = new SearchRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.ExpandRestrictions: // ExpandRestrictions
|
||||
capabilitiesRestrictions = new ExpandRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.SortRestrictions: // SortRestrictions
|
||||
capabilitiesRestrictions = new SortRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.FilterRestrictions: // FilterRestrictions
|
||||
capabilitiesRestrictions = new FilterRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.NavigationRestrictions: // NavigationRestrictions
|
||||
capabilitiesRestrictions = new NavigationRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.CountRestrictions: // CountRestrictions
|
||||
capabilitiesRestrictions = new CountRestrictions();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.BatchSupported: // BatchSupported
|
||||
capabilitiesRestrictions = new BatchSupported();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.SkipSupported: // SkipSupported
|
||||
capabilitiesRestrictions = new SkipSupported();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.TopSupported: // TopSupported
|
||||
capabilitiesRestrictions = new TopSupported();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.KeyAsSegmentSupported: // KeyAsSegmentSupported
|
||||
capabilitiesRestrictions = new KeyAsSegmentSupported();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.IndexableByKey: // IndexableByKey
|
||||
capabilitiesRestrictions = new IndexableByKey();
|
||||
break;
|
||||
|
||||
case CapabilitesTermKind.ChangeTracking: // ChangeTracking
|
||||
case CapabilitesTermKind.CrossJoinSupported: // CrossJoinSupported
|
||||
case CapabilitesTermKind.CallbackSupported: // CallbackSupported
|
||||
case CapabilitesTermKind.FilterFunctions: // FilterFunctions
|
||||
case CapabilitesTermKind.BatchContinueOnErrorSupported: // BatchContinueOnErrorSupported
|
||||
case CapabilitesTermKind.AsynchronousRequestsSupported: // AsynchronousRequestsSupported
|
||||
case CapabilitesTermKind.Isolation: // Isolation
|
||||
case CapabilitesTermKind.AcceptableEncodings: // AcceptableEncodings
|
||||
case CapabilitesTermKind.SupportedFormats: // SupportedFormats
|
||||
default:
|
||||
throw Error.NotSupported(String.Format(SRResource.CapabilitiesKindNotSupported, kind));
|
||||
}
|
||||
|
||||
// load the annotation value
|
||||
if (!capabilitiesRestrictions.Load(model, target))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return capabilitiesRestrictions;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
internal static class CapabilitiesHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets boolean value for term Org.OData.Core.V1.KeyAsSegmentSupported
|
||||
/// </summary>
|
||||
/// <param name="model">The model referenced to.</param>
|
||||
/// <returns>Boolean for term Org.OData.Core.V1.KeyAsSegmentSupported</returns>
|
||||
public static bool GetKeyAsSegmentSupported(this IEdmModel model)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
|
||||
if (model.EntityContainer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyAsSegmentSupported keyAsSegment = new KeyAsSegmentSupported(model, model.EntityContainer);
|
||||
return keyAsSegment.Supported ?? false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,60 +13,44 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// The base class of Capabilities
|
||||
/// </summary>
|
||||
internal abstract class CapabilitiesRestrictions
|
||||
internal abstract class CapabilitiesRestrictions : ICapablitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IEdmModel"/>.
|
||||
/// The Capablities Kind.
|
||||
/// </summary>
|
||||
public IEdmModel Model { get; }
|
||||
public abstract CapabilitesTermKind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IEdmVocabularyAnnotatable"/>.
|
||||
/// </summary>
|
||||
public IEdmVocabularyAnnotatable Target { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Term qualified name.
|
||||
/// </summary>
|
||||
public virtual string QualifiedName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CapabilitiesRestrictions"/> class.
|
||||
/// Load the annotation value.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm vocabulary annotatable.</param>
|
||||
public CapabilitiesRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
/// <param name="target">The target.</param>
|
||||
public virtual bool Load(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
Model = model;
|
||||
Target = target;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected void Initialize()
|
||||
{
|
||||
IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(Target, QualifiedName);
|
||||
string termQualifiedName = CapabilitiesConstants.Namespace + "." + Kind.ToString();
|
||||
IEdmVocabularyAnnotation annotation = model.GetVocabularyAnnotation(target, termQualifiedName);
|
||||
if (annotation == null)
|
||||
{
|
||||
IEdmNavigationSource navigationSource = Target as IEdmNavigationSource;
|
||||
IEdmNavigationSource navigationSource = target as IEdmNavigationSource;
|
||||
|
||||
// if not, search the entity type.
|
||||
if (navigationSource != null)
|
||||
{
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
annotation = Model.GetVocabularyAnnotation(entityType, QualifiedName);
|
||||
annotation = model.GetVocabularyAnnotation(entityType, termQualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
Initialize(annotation);
|
||||
return Initialize(annotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the capabilities with the vocabulary annotation.
|
||||
/// </summary>
|
||||
/// <param name="annotation">The input vocabulary annotation.</param>
|
||||
protected abstract void Initialize(IEdmVocabularyAnnotation annotation);
|
||||
protected abstract bool Initialize(IEdmVocabularyAnnotation annotation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// The Enum kind for Capabiliites annotation
|
||||
/// </summary>
|
||||
internal enum CapabilitesTermKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Media types of supported formats, including format parameters
|
||||
/// </summary>
|
||||
SupportedFormats,
|
||||
|
||||
/// <summary>
|
||||
/// List of acceptable compression methods for ($batch) requests, e.g. gzip
|
||||
/// </summary>
|
||||
AcceptableEncodings,
|
||||
|
||||
/// <summary>
|
||||
/// Supports key values according to OData URL conventions
|
||||
/// </summary>
|
||||
IndexableByKey,
|
||||
|
||||
/// <summary>
|
||||
/// Supported odata.isolation levels
|
||||
/// </summary>
|
||||
Isolation,
|
||||
|
||||
/// <summary>
|
||||
/// Supports key as segment
|
||||
/// </summary>
|
||||
KeyAsSegmentSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Supports $top
|
||||
/// </summary>
|
||||
TopSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Supports $skip
|
||||
/// </summary>
|
||||
SkipSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Service supports the asynchronous request preference
|
||||
/// </summary>
|
||||
AsynchronousRequestsSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Supports $batch requests
|
||||
/// </summary>
|
||||
BatchSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Service supports the continue on error preference
|
||||
/// </summary>
|
||||
BatchContinueOnErrorSupported,
|
||||
|
||||
/// <summary>
|
||||
/// List of functions supported in $filter
|
||||
/// </summary>
|
||||
FilterFunctions,
|
||||
|
||||
/// <summary>
|
||||
/// Supports callbacks for the specified protocols
|
||||
/// </summary>
|
||||
CallbackSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Supports cross joins for the entity sets in this container
|
||||
/// </summary>
|
||||
CrossJoinSupported,
|
||||
|
||||
/// <summary>
|
||||
/// Change tracking capabilities of this service or entity set
|
||||
/// </summary>
|
||||
ChangeTracking,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on /$count path suffix and $count=true system query option
|
||||
/// </summary>
|
||||
CountRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on navigating properties according to OData URL conventions
|
||||
/// </summary>
|
||||
NavigationRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on $filter expressions
|
||||
/// </summary>
|
||||
FilterRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on $orderby expressions
|
||||
/// </summary>
|
||||
SortRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on $expand expressions
|
||||
/// </summary>
|
||||
ExpandRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on $search expressions
|
||||
/// </summary>
|
||||
SearchRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on insert operations
|
||||
/// </summary>
|
||||
InsertRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on update operations
|
||||
/// </summary>
|
||||
UpdateRestrictions,
|
||||
|
||||
/// <summary>
|
||||
/// Restrictions on delete operations
|
||||
/// </summary>
|
||||
DeleteRestrictions,
|
||||
}
|
||||
}
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class CountRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.CountRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.CountRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Countable value.
|
||||
|
@ -35,16 +35,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonCountableNavigationProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CountRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public CountRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports count.
|
||||
/// </summary>
|
||||
|
@ -52,36 +42,34 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
public bool IsCountable => Countable == null || Countable.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Test the input property which do not allow /$count segments.
|
||||
/// Test the input property path which do not allow /$count segments.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path. "property1/property2"</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonCountableProperty(IEdmProperty property)
|
||||
public bool IsNonCountableProperty(string propertyPath)
|
||||
{
|
||||
return NonCountableProperties != null ?
|
||||
NonCountableProperties.Any(a => a == property.Name) :
|
||||
false;
|
||||
return NonCountableProperties != null ? NonCountableProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the input navigation property which do not allow /$count segments.
|
||||
/// </summary>
|
||||
/// <param name="property">The input navigation property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonCountableNavigationProperty(IEdmNavigationProperty property)
|
||||
public bool IsNonCountableNavigationProperty(string navigationPropertyPath)
|
||||
{
|
||||
return NonCountableNavigationProperties != null ?
|
||||
NonCountableNavigationProperties.Any(a => a == property.Name) :
|
||||
NonCountableNavigationProperties.Any(a => a == navigationPropertyPath) :
|
||||
false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -94,6 +82,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonCountableNavigationProperties
|
||||
NonCountableNavigationProperties = record.GetCollectionPropertyPath("NonCountableNavigationProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class DeleteRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.DeleteRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.DeleteRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Deletable value.
|
||||
|
@ -30,16 +30,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonDeletableNavigationProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="DeleteRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public DeleteRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports delete.
|
||||
/// </summary>
|
||||
|
@ -49,22 +39,22 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input navigation property do not allow DeleteLink requests.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonDeletableNavigationProperty(IEdmNavigationProperty property)
|
||||
public bool IsNonDeletableNavigationProperty(string navigationPropertyPath)
|
||||
{
|
||||
return NonDeletableNavigationProperties != null ?
|
||||
NonDeletableNavigationProperties.Any(a => a == property.Name) :
|
||||
NonDeletableNavigationProperties.Any(a => a == navigationPropertyPath) :
|
||||
false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -74,6 +64,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonDeletableNavigationProperties
|
||||
NonDeletableNavigationProperties = record.GetCollectionPropertyPath("NonDeletableNavigationProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class ExpandRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.ExpandRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.ExpandRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Expandable value.
|
||||
|
@ -30,16 +30,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonExpandableProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ExpandRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="entityStargetet">The Edm annotation target.</param>
|
||||
public ExpandRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports $expand.
|
||||
/// </summary>
|
||||
|
@ -49,20 +39,20 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input property cannot be used in $orderby expressions.
|
||||
/// </summary>
|
||||
/// <param name="property">The input navigation property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonExpandableProperty(IEdmNavigationProperty property)
|
||||
public bool IsNonExpandableProperty(string navigationPropertyPath)
|
||||
{
|
||||
return NonExpandableProperties != null ? NonExpandableProperties.Any(a => a == property.Name) : false;
|
||||
return NonExpandableProperties != null ? NonExpandableProperties.Any(a => a == navigationPropertyPath) : false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -72,6 +62,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonExpandableProperties
|
||||
NonExpandableProperties = record.GetCollectionPropertyPath("NonExpandableProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class FilterRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.FilterRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.FilterRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Filterable value.
|
||||
|
@ -40,16 +40,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonFilterableProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="FilterRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public FilterRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports filter.
|
||||
/// </summary>
|
||||
|
@ -59,30 +49,30 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input property which must be specified in the $filter clause.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsRequiredProperty(IEdmProperty property)
|
||||
public bool IsRequiredProperty(string propertyPath)
|
||||
{
|
||||
return RequiredProperties != null ? RequiredProperties.Any(a => a == property.Name) : false;
|
||||
return RequiredProperties != null ? RequiredProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the input property which cannot be used in $filter expressions.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonFilterableProperty(IEdmProperty property)
|
||||
public bool IsNonFilterableProperty(string propertyPath)
|
||||
{
|
||||
return NonFilterableProperties != null ? NonFilterableProperties.Any(a => a == property.Name) : false;
|
||||
return NonFilterableProperties != null ? NonFilterableProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -98,6 +88,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonFilterableProperties
|
||||
NonFilterableProperties = record.GetCollectionPropertyPath("NonFilterableProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
internal interface ICapablitiesRestrictions
|
||||
{
|
||||
CapabilitesTermKind Kind { get; }
|
||||
|
||||
bool Load(IEdmModel model, IEdmVocabularyAnnotatable target);
|
||||
}
|
||||
}
|
|
@ -14,18 +14,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class IndexableByKey : SupportedRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.IndexableByKey;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="IndexableByKey"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public IndexableByKey(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.IndexableByKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class InsertRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.InsertRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.InsertRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Insertable value.
|
||||
|
@ -30,16 +30,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonInsertableNavigationProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="InsertRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public InsertRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports insert.
|
||||
/// </summary>
|
||||
|
@ -49,22 +39,22 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input navigation property do not allow deep insert.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonINsertableNavigationProperty(IEdmNavigationProperty property)
|
||||
public bool IsNonInsertableNavigationProperty(string navigationPropertyPath)
|
||||
{
|
||||
return NonInsertableNavigationProperties != null ?
|
||||
NonInsertableNavigationProperties.Any(a => a == property.Name) :
|
||||
NonInsertableNavigationProperties.Any(a => a == navigationPropertyPath) :
|
||||
false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -74,6 +64,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonInsertableNavigationProperties
|
||||
NonInsertableNavigationProperties = record.GetCollectionPropertyPath("NonInsertableNavigationProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -13,18 +11,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class KeyAsSegmentSupported : SupportedRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.KeyAsSegmentSupported;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="TopSupported"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public KeyAsSegmentSupported(IEdmModel model, IEdmEntityContainer target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.KeyAsSegmentSupported;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.NavigationRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.NavigationRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Navigability value.
|
||||
|
@ -67,16 +67,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<NavigationPropertyRestriction> RestrictedProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="NavigationRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public NavigationRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating the target is navigable or not.
|
||||
/// </summary>
|
||||
|
@ -85,23 +75,23 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input navigation property which has navigation restrictions.
|
||||
/// </summary>
|
||||
/// <param name="property">The input navigation property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsRestrictedProperty(IEdmNavigationProperty property)
|
||||
public bool IsRestrictedProperty(string navigationPropertyPath)
|
||||
{
|
||||
return RestrictedProperties != null ?
|
||||
RestrictedProperties.Where(a => a.NavigationProperty == property.Name)
|
||||
RestrictedProperties.Where(a => a.NavigationProperty == navigationPropertyPath)
|
||||
.Any(a => a.Navigability != null && a.Navigability.Value == NavigationType.None) :
|
||||
true;
|
||||
false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -111,6 +101,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// RestrictedProperties
|
||||
RestrictedProperties = GetRestrictedProperties(record);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static IList<NavigationPropertyRestriction> GetRestrictedProperties(IEdmRecordExpression record)
|
||||
|
|
|
@ -53,9 +53,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class SearchRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.SearchRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.SearchRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Searchable value.
|
||||
|
@ -67,29 +67,39 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public SearchExpressions? UnsupportedExpressions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SearchRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public SearchRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports search.
|
||||
/// </summary>
|
||||
/// <returns>True/false.</returns>
|
||||
public bool IsSearchable => Searchable == null || Searchable.Value == true;
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
/// <summary>
|
||||
/// Test the input expression supported or not.
|
||||
/// </summary>
|
||||
/// <param name="expression">The input expression</param>
|
||||
/// <returns>True/false.</returns>
|
||||
public bool IsUnsupportedExpressions(SearchExpressions expression)
|
||||
{
|
||||
if (UnsupportedExpressions == null || UnsupportedExpressions.Value == SearchExpressions.none)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((UnsupportedExpressions.Value & expression) == expression)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -121,6 +131,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -14,18 +11,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class SkipSupported : SupportedRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.SkipSupported;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SkipSupported"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public SkipSupported(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.SkipSupported;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.SortRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.SortRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Sortable value.
|
||||
|
@ -40,16 +40,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonSortableProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SortRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public SortRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating whether the target supports $orderby.
|
||||
/// </summary>
|
||||
|
@ -58,40 +48,40 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Test the input property is Ascending only.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsAscendingOnlyProperty(IEdmProperty property)
|
||||
public bool IsAscendingOnlyProperty(string propertyPath)
|
||||
{
|
||||
return AscendingOnlyProperties != null ? AscendingOnlyProperties.Any(a => a == property.Name) : false;
|
||||
return AscendingOnlyProperties != null ? AscendingOnlyProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the input property is Descending only.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsDescendingOnlyProperty(IEdmProperty property)
|
||||
public bool IsDescendingOnlyProperty(string propertyPath)
|
||||
{
|
||||
return DescendingOnlyProperties != null ? DescendingOnlyProperties.Any(a => a == property.Name) : false;
|
||||
return DescendingOnlyProperties != null ? DescendingOnlyProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the input property cannot be used in $orderby expressions.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="propertyPath">The input property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonSortableProperty(IEdmProperty property)
|
||||
public bool IsNonSortableProperty(string propertyPath)
|
||||
{
|
||||
return NonSortableProperties != null ? NonSortableProperties.Any(a => a == property.Name) : false;
|
||||
return NonSortableProperties != null ? NonSortableProperties.Any(a => a == propertyPath) : false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -107,6 +97,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonSortablePropeties
|
||||
NonSortableProperties = record.GetCollectionPropertyPath("NonSortableProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,29 +18,19 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public bool? Supported { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SupportedRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public SupportedRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports the corresponding restriction.
|
||||
/// </summary>
|
||||
/// <returns>True/false.</returns>
|
||||
public bool IsSupported => Supported == null || Supported.Value == true;
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.BooleanConstant)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// supported
|
||||
|
@ -49,6 +39,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
{
|
||||
Supported = boolConstant.Value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -14,18 +11,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class TopSupported : SupportedRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type Kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.TopSupported;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="TopSupported"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public TopSupported(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.TopSupported;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
internal class UpdateRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// The Term type kind.
|
||||
/// </summary>
|
||||
public override string QualifiedName => CapabilitiesConstants.UpdateRestrictions;
|
||||
public override CapabilitesTermKind Kind => CapabilitesTermKind.UpdateRestrictions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Updatable value.
|
||||
|
@ -30,41 +30,31 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
public IList<string> NonUpdatableNavigationProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="UpdateRestrictions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public UpdateRestrictions(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
: base(model, target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the target supports update.
|
||||
/// </summary>
|
||||
/// <returns>True/false.</returns>
|
||||
public bool IsUpdatable => Updatable == null || Updatable.Value == true;
|
||||
public bool IsUpdatable => Updatable == null || Updatable.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Test the input navigation property do not allow rebinding.
|
||||
/// </summary>
|
||||
/// <param name="property">The input property.</param>
|
||||
/// <param name="navigationPropertyPath">The input navigation property path.</param>
|
||||
/// <returns>True/False.</returns>
|
||||
public bool IsNonUpdatableNavigationProperty(IEdmNavigationProperty property)
|
||||
public bool IsNonUpdatableNavigationProperty(string navigationPropertyPath)
|
||||
{
|
||||
return NonUpdatableNavigationProperties != null ?
|
||||
NonUpdatableNavigationProperties.Any(a => a == property.Name) :
|
||||
NonUpdatableNavigationProperties.Any(a => a == navigationPropertyPath) :
|
||||
false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
protected override bool Initialize(IEdmVocabularyAnnotation annotation)
|
||||
{
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Record)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
@ -74,6 +64,8 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
// NonUpdatableNavigationProperties
|
||||
NonUpdatableNavigationProperties = record.GetCollectionPropertyPath("NonUpdatableNavigationProperties");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
visitor.Visit(model);
|
||||
IsSpatialTypeUsed = visitor.IsSpatialTypeUsed;
|
||||
|
||||
_keyAsSegmentSupported = settings.EnableKeyAsSegment ?? model.GetKeyAsSegmentSupported();
|
||||
|
||||
_pathHandler = new ODataPathHandler(this);
|
||||
|
||||
|
@ -61,6 +60,24 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
PathItemHanderProvider = new PathItemHandlerProvider();
|
||||
|
||||
AuthorizationProvider = new AuthorizationProvider();
|
||||
|
||||
if (settings.EnableKeyAsSegment != null)
|
||||
{
|
||||
// We have the global setting, use the global setting
|
||||
_keyAsSegmentSupported = settings.EnableKeyAsSegment.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_keyAsSegmentSupported = false;
|
||||
if (model.EntityContainer != null)
|
||||
{
|
||||
var keyAsSegment = model.GetKeyAsSegmentSupported(model.EntityContainer);
|
||||
if (keyAsSegment != null)
|
||||
{
|
||||
_keyAsSegmentSupported = keyAsSegment.IsSupported;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IPathItemHandlerProvider PathItemHanderProvider { get; }
|
||||
|
@ -72,6 +89,8 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// </summary>
|
||||
public AuthorizationProvider AuthorizationProvider { get; }
|
||||
|
||||
//public CapabilitiesProvider CapabilitiesProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm model.
|
||||
/// </summary>
|
||||
|
|
|
@ -154,8 +154,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
TopSupported top = new TopSupported(context.Model, target);
|
||||
if (top.IsSupported)
|
||||
TopSupported top = context.Model.GetTopSupported(target);
|
||||
if (top == null || top.IsSupported)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
@ -177,8 +177,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
SkipSupported skip = new SkipSupported(context.Model, target);
|
||||
if (skip.IsSupported)
|
||||
SkipSupported skip = context.Model.GetSkipSupported(target);
|
||||
if (skip == null || skip.IsSupported)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
@ -200,8 +200,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
SearchRestrictions search = new SearchRestrictions(context.Model, target);
|
||||
if (search.IsSearchable)
|
||||
SearchRestrictions search = context.Model.GetSearchRestrictions(target);
|
||||
if (search == null || search.IsSearchable)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
@ -223,8 +223,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
CountRestrictions count = new CountRestrictions(context.Model, target);
|
||||
if (count.IsCountable)
|
||||
CountRestrictions count = context.Model.GetCountRestrictions(target);
|
||||
if (count == null || count.IsCountable)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
@ -246,8 +246,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
FilterRestrictions filter = new FilterRestrictions(context.Model, target);
|
||||
if (filter.IsFilterable)
|
||||
FilterRestrictions filter = context.Model.GetFilterRestrictions(target);
|
||||
if (filter == null || filter.IsFilterable)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
@ -294,8 +294,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
Utils.CheckArgumentNull(entityType, nameof(entityType));
|
||||
|
||||
SortRestrictions sort = new SortRestrictions(context.Model, target);
|
||||
if (sort.Sortable != null && sort.Sortable.Value == false)
|
||||
SortRestrictions sort = context.Model.GetSortRestrictions(target);
|
||||
if (sort != null && !sort.IsSortable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -303,13 +303,13 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
IList<IOpenApiAny> orderByItems = new List<IOpenApiAny>();
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
if (sort.IsNonSortableProperty(property))
|
||||
if (sort != null && sort.IsNonSortableProperty(property.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isAscOnly = sort.IsAscendingOnlyProperty(property);
|
||||
bool isDescOnly = sort.IsDescendingOnlyProperty(property);
|
||||
bool isAscOnly = sort != null ? sort.IsAscendingOnlyProperty(property.Name) : false ;
|
||||
bool isDescOnly = sort != null ? sort.IsDescendingOnlyProperty(property.Name) : false;
|
||||
if (isAscOnly || isDescOnly)
|
||||
{
|
||||
if (isAscOnly)
|
||||
|
@ -382,8 +382,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
Utils.CheckArgumentNull(entityType, nameof(entityType));
|
||||
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(context.Model, target);
|
||||
if (navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
|
||||
NavigationRestrictions navigation = context.Model.GetNavigationRestrictions(target);
|
||||
if (navigation != null && !navigation.IsNavigable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
|
||||
foreach (var property in entityType.NavigationProperties())
|
||||
{
|
||||
if (navigation.IsRestrictedProperty(property))
|
||||
if (navigation != null && navigation.IsRestrictedProperty(property.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -460,8 +460,8 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
Utils.CheckArgumentNull(entityType, nameof(entityType));
|
||||
|
||||
ExpandRestrictions expand = new ExpandRestrictions(context.Model, target);
|
||||
if (expand.Expandable != null && expand.Expandable.Value == false)
|
||||
ExpandRestrictions expand = context.Model.GetExpandRestrictions(target);
|
||||
if (expand != null && !expand.IsExpandable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
|
||||
foreach (var property in entityType.NavigationProperties())
|
||||
{
|
||||
if (expand.IsNonExpandableProperty(property))
|
||||
if (expand != null && expand.IsNonExpandableProperty(property.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Capabilities\CapabilitiesTermKind.cs~RF91fb26a.TMP" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OData.Edm" Version="7.5.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.0" />
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem
|
||||
{
|
||||
|
@ -13,23 +14,26 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class EntityPathItemHandler : EntitySetPathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.Entity;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetOperations(OpenApiPathItem item)
|
||||
{
|
||||
IndexableByKey index = new IndexableByKey(Context.Model, EntitySet);
|
||||
if (index.IsSupported)
|
||||
IndexableByKey index = Context.Model.GetIndexableByKey(EntitySet);
|
||||
if (index == null || index.IsSupported)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
|
||||
UpdateRestrictions update = new UpdateRestrictions(Context.Model, EntitySet);
|
||||
if (update.IsUpdatable)
|
||||
UpdateRestrictions update = Context.Model.GetUpdateRestrictions(EntitySet);
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
|
||||
DeleteRestrictions delete = new DeleteRestrictions(Context.Model, EntitySet);
|
||||
if (delete.IsDeletable)
|
||||
DeleteRestrictions delete = Context.Model.GetDeleteRestrictions(EntitySet);
|
||||
if (delete == null || delete.IsDeletable)
|
||||
{
|
||||
AddOperation(item, OperationType.Delete);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class EntitySetPathItemHandler : PathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.EntitySet;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity set.
|
||||
/// </summary>
|
||||
|
@ -23,14 +26,14 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void SetOperations(OpenApiPathItem item)
|
||||
{
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(Context.Model, EntitySet);
|
||||
if (navigation.IsNavigable)
|
||||
NavigationRestrictions navigation = Context.Model.GetNavigationRestrictions(EntitySet);
|
||||
if (navigation == null || navigation.IsNavigable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
|
||||
InsertRestrictions insert = new InsertRestrictions(Context.Model, EntitySet);
|
||||
if (insert.IsInsertable)
|
||||
InsertRestrictions insert = Context.Model.GetInsertRestrictions(EntitySet);
|
||||
if (insert == null || insert.IsInsertable)
|
||||
{
|
||||
AddOperation(item, OperationType.Post);
|
||||
}
|
||||
|
@ -39,11 +42,11 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
base.Initialize(context, path);
|
||||
|
||||
// The first segment should be the entity set segment.
|
||||
ODataNavigationSourceSegment navigationSourceSegment = path.FirstSegment as ODataNavigationSourceSegment;
|
||||
EntitySet = navigationSourceSegment.NavigationSource as IEdmEntitySet;
|
||||
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using Microsoft.OpenApi.OData.Capabilities;
|
|||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem
|
||||
{
|
||||
|
@ -19,6 +20,9 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class NavigationPropertyPathItemHandler : PathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.NavigationProperty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the navigation property.
|
||||
/// </summary>
|
||||
|
@ -37,9 +41,20 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void SetOperations(OpenApiPathItem item)
|
||||
{
|
||||
IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet;
|
||||
IEdmVocabularyAnnotatable target = entitySet;
|
||||
if (target == null)
|
||||
{
|
||||
target = NavigationSource as IEdmSingleton;
|
||||
}
|
||||
|
||||
// contaiment: Get / (Post - Collection | Patch - Single)
|
||||
// non-containment: only Get
|
||||
AddOperation(item, OperationType.Get);
|
||||
NavigationRestrictions navigation = Context.Model.GetNavigationRestrictions(target);
|
||||
if (navigation == null || navigation.IsNavigable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
|
||||
if (NavigationProperty.ContainsTarget)
|
||||
{
|
||||
|
@ -47,16 +62,16 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
{
|
||||
if (LastSegmentIsKeySegment)
|
||||
{
|
||||
UpdateRestrictions update = new UpdateRestrictions(Context.Model, NavigationProperty);
|
||||
if (update.IsUpdatable)
|
||||
UpdateRestrictions update = Context.Model.GetUpdateRestrictions(target);
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertRestrictions insert = new InsertRestrictions(Context.Model, NavigationProperty);
|
||||
if (insert.IsInsertable)
|
||||
InsertRestrictions insert = Context.Model.GetInsertRestrictions(target);
|
||||
if (insert == null || insert.IsInsertable)
|
||||
{
|
||||
AddOperation(item, OperationType.Post);
|
||||
}
|
||||
|
@ -64,8 +79,8 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
}
|
||||
else
|
||||
{
|
||||
UpdateRestrictions update = new UpdateRestrictions(Context.Model, NavigationProperty);
|
||||
if (update.IsUpdatable)
|
||||
UpdateRestrictions update = Context.Model.GetUpdateRestrictions(target);
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
|
@ -76,6 +91,8 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
base.Initialize(context, path);
|
||||
|
||||
ODataNavigationSourceSegment navigationSourceSegment = path.FirstSegment as ODataNavigationSourceSegment;
|
||||
NavigationSource = navigationSourceSegment.NavigationSource;
|
||||
|
||||
|
@ -86,8 +103,6 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
npSegment = path.Segments[path.Count - 2] as ODataNavigationPropertySegment;
|
||||
}
|
||||
NavigationProperty = npSegment.NavigationProperty;
|
||||
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -14,6 +14,9 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class OperationImportPathItemHandler : PathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.OperationImport;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the operation import.
|
||||
/// </summary>
|
||||
|
@ -43,10 +46,10 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
base.Initialize(context, path);
|
||||
|
||||
ODataOperationImportSegment operationImportSegment = path.FirstSegment as ODataOperationImportSegment;
|
||||
EdmOperationImport = operationImportSegment.OperationImport;
|
||||
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class OperationPathItemHandler : PathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.Operation;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm operation.
|
||||
/// </summary>
|
||||
|
@ -43,9 +46,10 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
base.Initialize(context, path);
|
||||
|
||||
ODataOperationSegment operationSegment = path.LastSegment as ODataOperationSegment;
|
||||
EdmOperation = operationSegment.Operation;
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Operation;
|
||||
using Microsoft.OpenApi.OData.Properties;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem
|
||||
{
|
||||
|
@ -15,6 +17,11 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal abstract class PathItemHandler : IPathItemHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the handler path kind.
|
||||
/// </summary>
|
||||
protected abstract ODataPathKind HandleKind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the OData Context.
|
||||
/// </summary>
|
||||
|
@ -55,7 +62,12 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <param name="context">The context.</param>
|
||||
/// <param name="path">The path.</param>
|
||||
protected virtual void Initialize(ODataContext context, ODataPath path)
|
||||
{ }
|
||||
{
|
||||
if (HandleKind != path.Kind)
|
||||
{
|
||||
throw Error.InvalidOperation(String.Format(SRResource.InvalidPathKindForPathItemHandler, GetType().Name, path.Kind));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the extensions for the path item.
|
||||
|
|
|
@ -3,13 +3,10 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Properties;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem
|
||||
{
|
||||
|
@ -18,6 +15,9 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// </summary>
|
||||
internal class SingletonPathItemHandler : PathItemHandler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
protected override ODataPathKind HandleKind { get; } = ODataPathKind.Singleton;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton.
|
||||
/// </summary>
|
||||
|
@ -27,15 +27,15 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
protected override void SetOperations(OpenApiPathItem item)
|
||||
{
|
||||
// Retrieve a singleton.
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(Context.Model, Singleton);
|
||||
if (navigation.IsNavigable)
|
||||
NavigationRestrictions navigation = Context.Model.GetNavigationRestrictions(Singleton);
|
||||
if (navigation == null || navigation.IsNavigable)
|
||||
{
|
||||
AddOperation(item, OperationType.Get);
|
||||
}
|
||||
|
||||
// Update a singleton
|
||||
UpdateRestrictions update = new UpdateRestrictions(Context.Model, Singleton);
|
||||
if (update.IsUpdatable)
|
||||
UpdateRestrictions update = Context.Model.GetUpdateRestrictions(Singleton);
|
||||
if (update == null || update.IsUpdatable)
|
||||
{
|
||||
AddOperation(item, OperationType.Patch);
|
||||
}
|
||||
|
@ -44,14 +44,10 @@ namespace Microsoft.OpenApi.OData.PathItem
|
|||
/// <inheritdoc/>
|
||||
protected override void Initialize(ODataContext context, ODataPath path)
|
||||
{
|
||||
if (path.Kind != ODataPathKind.Singleton)
|
||||
{
|
||||
throw Error.InvalidOperation(String.Format(SRResource.InvalidPathKindForPathItemHandler, nameof(SingletonPathItemHandler), path.Kind));
|
||||
}
|
||||
base.Initialize(context, path);
|
||||
|
||||
ODataNavigationSourceSegment navigationSourceSegment = path.FirstSegment as ODataNavigationSourceSegment;
|
||||
Singleton = navigationSourceSegment.NavigationSource as IEdmSingleton;
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,15 @@ namespace Microsoft.OpenApi.OData.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The capabilities term kind '{0}' is not supported now..
|
||||
/// </summary>
|
||||
internal static string CapabilitiesKindNotSupported {
|
||||
get {
|
||||
return ResourceManager.GetString("CapabilitiesKindNotSupported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The filed name of extension doesn't begin with x-..
|
||||
/// </summary>
|
||||
|
|
|
@ -123,6 +123,9 @@
|
|||
<data name="AuthorizationRecordTypeNameNotCorrect" xml:space="preserve">
|
||||
<value>The authorization record type name '{0}' is not correct.</value>
|
||||
</data>
|
||||
<data name="CapabilitiesKindNotSupported" xml:space="preserve">
|
||||
<value>The capabilities term kind '{0}' is not supported now.</value>
|
||||
</data>
|
||||
<data name="ExtensionFieldNameMustBeginWithXMinus" xml:space="preserve">
|
||||
<value>The filed name of extension doesn't begin with x-.</value>
|
||||
</data>
|
||||
|
|
|
@ -13,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class BatchSupportedTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsBatchSupportedEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
BatchSupported batch = new BatchSupported();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.BatchSupported, batch.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultBatchSupportedValues()
|
||||
{
|
||||
// Arrange
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
BatchSupported batch = new BatchSupported();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
BatchSupported batch = new BatchSupported(EdmCoreModel.Instance, container);
|
||||
// Act
|
||||
bool result = batch.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.BatchSupported, batch.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(batch.IsSupported);
|
||||
Assert.Null(batch.Supported);
|
||||
}
|
||||
|
||||
|
@ -39,11 +51,14 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(model); // guard
|
||||
|
||||
// Act
|
||||
BatchSupported batch = new BatchSupported(model, model.EntityContainer);
|
||||
BatchSupported batch = new BatchSupported();
|
||||
bool result = batch.Load(model, model.EntityContainer);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(batch.Supported);
|
||||
Assert.Equal(support, batch.Supported.Value);
|
||||
Assert.Equal(support, batch.IsSupported);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(EdmVocabularyAnnotationSerializationLocation location, bool supported)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
|
@ -15,16 +14,28 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
public class CountRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
|
||||
public void KindPropertyReturnsCountRestrictionEnumMember()
|
||||
{
|
||||
// Arrange
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
CountRestrictions count = new CountRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Arrange & Act
|
||||
CountRestrictions count = new CountRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.CountRestrictions, count.QualifiedName);
|
||||
Assert.Equal(CapabilitesTermKind.CountRestrictions, count.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
|
||||
{
|
||||
// Arrange & Act
|
||||
CountRestrictions count = new CountRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
bool result = count.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.True(count.IsCountable);
|
||||
Assert.Null(count.Countable);
|
||||
Assert.Null(count.NonCountableProperties);
|
||||
Assert.Null(count.NonCountableNavigationProperties);
|
||||
|
@ -44,13 +55,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
CountRestrictions count = new CountRestrictions(model, calendar);
|
||||
CountRestrictions count = new CountRestrictions();
|
||||
bool result = count.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyCountRestrictions(count);
|
||||
}
|
||||
|
||||
|
@ -72,77 +85,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
CountRestrictions count = new CountRestrictions(model, calendars);
|
||||
CountRestrictions count = new CountRestrictions();
|
||||
bool result = count.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyCountRestrictions(count);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectCountRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
CountRestrictions count = new CountRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyCountRestrictions(count);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonCountablePropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmProperty id = calendar.DeclaredStructuralProperties().First(c => c.Name == "Id");
|
||||
Assert.NotNull(id); // Guard
|
||||
|
||||
IEdmProperty property = calendar.DeclaredStructuralProperties().First(c => c.Name == "Emails");
|
||||
Assert.NotNull(property); // Guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // Guard
|
||||
|
||||
// Act
|
||||
CountRestrictions count = new CountRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(count.Countable);
|
||||
Assert.False(count.Countable.Value);
|
||||
Assert.False(count.IsNonCountableProperty(id));
|
||||
Assert.True(count.IsNonCountableProperty(property));
|
||||
Assert.True(count.IsNonCountableNavigationProperty(navigationProperty));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.CountRestrictions"" >
|
||||
|
@ -170,14 +121,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +131,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
|
||||
Assert.NotNull(count.Countable);
|
||||
Assert.False(count.Countable.Value);
|
||||
Assert.False(count.IsCountable);
|
||||
|
||||
Assert.NotNull(count.NonCountableProperties);
|
||||
Assert.Equal(2, count.NonCountableProperties.Count);
|
||||
|
@ -195,6 +140,10 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(count.NonCountableNavigationProperties);
|
||||
Assert.Equal(2, count.NonCountableNavigationProperties.Count);
|
||||
Assert.Equal("RelatedEvents,abc", String.Join(",", count.NonCountableNavigationProperties));
|
||||
|
||||
Assert.False(count.IsNonCountableProperty("id"));
|
||||
Assert.True(count.IsNonCountableProperty("Emails"));
|
||||
Assert.True(count.IsNonCountableNavigationProperty("RelatedEvents"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class DeleteRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsDeleteRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.DeleteRestrictions, delete.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultDeleteRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
DeleteRestrictions delete = new DeleteRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = delete.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.DeleteRestrictions, delete.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(delete.IsDeletable);
|
||||
Assert.Null(delete.Deletable);
|
||||
Assert.Null(delete.NonDeletableNavigationProperties);
|
||||
}
|
||||
|
@ -43,13 +55,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions(model, calendar);
|
||||
DeleteRestrictions delete = new DeleteRestrictions();
|
||||
bool result = delete.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyDeleteRestrictions(delete);
|
||||
}
|
||||
|
||||
|
@ -71,69 +85,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions(model, calendars);
|
||||
DeleteRestrictions delete = new DeleteRestrictions();
|
||||
bool result = delete.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyDeleteRestrictions(delete);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectDeleteRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyDeleteRestrictions(delete);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonDeletableNavigationPropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // Guard
|
||||
|
||||
// Act
|
||||
DeleteRestrictions delete = new DeleteRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(delete.Deletable);
|
||||
Assert.False(delete.Deletable.Value);
|
||||
Assert.True(delete.IsNonDeletableNavigationProperty(navigationProperty));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.DeleteRestrictions"" >
|
||||
|
@ -155,14 +115,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +129,8 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(delete.NonDeletableNavigationProperties);
|
||||
Assert.Equal(2, delete.NonDeletableNavigationProperties.Count);
|
||||
Assert.Equal("abc|RelatedEvents", String.Join("|", delete.NonDeletableNavigationProperties));
|
||||
|
||||
Assert.True(delete.IsNonDeletableNavigationProperty("RelatedEvents"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
|
@ -14,17 +13,30 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class ExpandRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsExpandRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.ExpandRestrictions, expand.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultExpandRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
ExpandRestrictions expand = new ExpandRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = expand.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.ExpandRestrictions, expand.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.Equal(CapabilitesTermKind.ExpandRestrictions, expand.Kind);
|
||||
Assert.True(expand.IsExpandable);
|
||||
Assert.Null(expand.Expandable);
|
||||
Assert.Null(expand.NonExpandableProperties);
|
||||
}
|
||||
|
@ -43,13 +55,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions(model, calendar);
|
||||
ExpandRestrictions expand = new ExpandRestrictions();
|
||||
bool result = expand.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyExpandRestrictions(expand);
|
||||
}
|
||||
|
||||
|
@ -71,69 +85,16 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions(model, calendars);
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions();
|
||||
bool result = expand.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyExpandRestrictions(expand);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectExpandRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyExpandRestrictions(expand);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonExpandablePropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // Guard
|
||||
|
||||
// Act
|
||||
ExpandRestrictions expand = new ExpandRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(expand.Expandable);
|
||||
Assert.False(expand.Expandable.Value);
|
||||
Assert.True(expand.IsNonExpandableProperty(navigationProperty));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.ExpandRestrictions"" >
|
||||
|
@ -155,14 +116,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +130,8 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(expand.NonExpandableProperties);
|
||||
Assert.Equal(2, expand.NonExpandableProperties.Count);
|
||||
Assert.Equal("abc|RelatedEvents", String.Join("|", expand.NonExpandableProperties));
|
||||
|
||||
Assert.True(expand.IsNonExpandableProperty("RelatedEvents"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class FilterRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsFilterRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
FilterRestrictions filter = new FilterRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.FilterRestrictions, filter.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultFilterRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
FilterRestrictions filter = new FilterRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = filter.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.FilterRestrictions, filter.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(filter.IsFilterable);
|
||||
Assert.Null(filter.Filterable);
|
||||
Assert.Null(filter.RequiresFilter);
|
||||
Assert.Null(filter.RequiredProperties);
|
||||
|
@ -44,13 +56,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendar);
|
||||
FilterRestrictions filter = new FilterRestrictions();
|
||||
bool result = filter.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
|
@ -72,76 +86,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendars);
|
||||
FilterRestrictions filter = new FilterRestrictions();
|
||||
bool result = filter.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectFilterRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonExpandablePropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmProperty id = calendar.DeclaredStructuralProperties().First(c => c.Name == "Id");
|
||||
Assert.NotNull(id); // Guard
|
||||
|
||||
IEdmProperty emails = calendar.DeclaredStructuralProperties().First(c => c.Name == "Emails");
|
||||
Assert.NotNull(emails); // Guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(filter.Filterable);
|
||||
Assert.False(filter.Filterable.Value);
|
||||
Assert.NotNull(filter.RequiresFilter);
|
||||
Assert.False(filter.RequiresFilter.Value);
|
||||
|
||||
Assert.True(filter.IsRequiredProperty(id));
|
||||
Assert.True(filter.IsNonFilterableProperty(emails));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.FilterRestrictions"" >
|
||||
|
@ -168,14 +121,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,6 +142,12 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(filter.NonFilterableProperties);
|
||||
Assert.Single(filter.NonFilterableProperties);
|
||||
Assert.Equal("Emails", filter.NonFilterableProperties.First());
|
||||
|
||||
Assert.True(filter.IsRequiredProperty("Id"));
|
||||
Assert.False(filter.IsRequiredProperty("ID"));
|
||||
|
||||
Assert.True(filter.IsNonFilterableProperty("Emails"));
|
||||
Assert.False(filter.IsNonFilterableProperty("ID"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
|
@ -13,17 +12,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class IndexableByKeyTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsIndexableByKeyEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
IndexableByKey index = new IndexableByKey();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.IndexableByKey, index.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultIndexableByKeyValues()
|
||||
{
|
||||
// Arrange
|
||||
IndexableByKey index = new IndexableByKey();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
IndexableByKey index = new IndexableByKey(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = index.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.IndexableByKey, index.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(index.IsSupported);
|
||||
Assert.Null(index.Supported);
|
||||
}
|
||||
|
||||
|
@ -41,13 +52,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
IndexableByKey index = new IndexableByKey(model, calendar);
|
||||
IndexableByKey index = new IndexableByKey();
|
||||
bool result = index.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(index.Supported);
|
||||
Assert.False(index.Supported.Value);
|
||||
}
|
||||
|
@ -70,42 +83,16 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
IndexableByKey index = new IndexableByKey(model, calendars);
|
||||
IndexableByKey index = new IndexableByKey();
|
||||
bool result = index.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(index.Supported);
|
||||
Assert.False(index.Supported.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectIndexableByKeyValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
IndexableByKey index = new IndexableByKey(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(index.Supported);
|
||||
Assert.False(index.Supported.Value);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.IndexableByKey"" Bool=""false"" />";
|
||||
|
||||
|
@ -116,14 +103,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
|
@ -14,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class InsertRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsInsertRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
InsertRestrictions insert = new InsertRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.InsertRestrictions, insert.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultInsertRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
InsertRestrictions insert = new InsertRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
InsertRestrictions insert = new InsertRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = insert.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.InsertRestrictions, insert.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(insert.IsInsertable);
|
||||
Assert.Null(insert.Insertable);
|
||||
Assert.Null(insert.NonInsertableNavigationProperties);
|
||||
}
|
||||
|
@ -43,13 +54,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
InsertRestrictions insert = new InsertRestrictions(model, calendar);
|
||||
InsertRestrictions insert = new InsertRestrictions();
|
||||
bool result = insert.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyInsertRestrictions(insert);
|
||||
}
|
||||
|
||||
|
@ -71,69 +84,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
InsertRestrictions insert = new InsertRestrictions(model, calendars);
|
||||
InsertRestrictions insert = new InsertRestrictions();
|
||||
bool result = insert.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyInsertRestrictions(insert);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectInsertRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
InsertRestrictions insert = new InsertRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyInsertRestrictions(insert);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonINsertableNavigationPropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // Guard
|
||||
|
||||
// Act
|
||||
InsertRestrictions insert = new InsertRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(insert.Insertable);
|
||||
Assert.False(insert.Insertable.Value);
|
||||
Assert.True(insert.IsNonINsertableNavigationProperty(navigationProperty));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"" >
|
||||
|
@ -155,14 +114,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +128,9 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(insert.NonInsertableNavigationProperties);
|
||||
Assert.Equal(2, insert.NonInsertableNavigationProperties.Count);
|
||||
Assert.Equal("abc|RelatedEvents", String.Join("|", insert.NonInsertableNavigationProperties));
|
||||
|
||||
Assert.True(insert.IsNonInsertableNavigationProperty("RelatedEvents"));
|
||||
Assert.False(insert.IsNonInsertableNavigationProperty("MyUnknownNavigationProperty"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,28 +3,39 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OpenApi.OData.Capabilities;
|
||||
using Xunit;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
||||
{
|
||||
public class KeyAsSegmentSupportedTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsKeyAsSegmentSupportedEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
KeyAsSegmentSupported keyAsSegment = new KeyAsSegmentSupported();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.KeyAsSegmentSupported, keyAsSegment.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultTopSupportedValues()
|
||||
{
|
||||
// Arrange
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
KeyAsSegmentSupported keyAsSegment = new KeyAsSegmentSupported();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
KeyAsSegmentSupported keyAsSegment = new KeyAsSegmentSupported(EdmCoreModel.Instance, container);
|
||||
// Act
|
||||
bool result = keyAsSegment.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.KeyAsSegmentSupported, keyAsSegment.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(keyAsSegment.IsSupported);
|
||||
Assert.Null(keyAsSegment.Supported);
|
||||
}
|
||||
|
||||
|
@ -40,9 +51,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(model); // guard
|
||||
|
||||
// Act
|
||||
KeyAsSegmentSupported KeyAsSegmentSupported = new KeyAsSegmentSupported(model, model.EntityContainer);
|
||||
KeyAsSegmentSupported KeyAsSegmentSupported = new KeyAsSegmentSupported();
|
||||
bool result = KeyAsSegmentSupported.Load(model, model.EntityContainer);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(KeyAsSegmentSupported.Supported);
|
||||
Assert.Equal(support, KeyAsSegmentSupported.Supported.Value);
|
||||
}
|
||||
|
@ -53,13 +66,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
model.AddElement(container);
|
||||
IEdmTerm term = model.FindTerm(CapabilitiesConstants.KeyAsSegmentSupported);
|
||||
if (term == null)
|
||||
{
|
||||
// NOTE: KeyAsSegmentSupported annotation term is not included in OData Spec 4.0.
|
||||
// Please remove the codes here once it's supported in the latest OData lib.
|
||||
term = new EdmTerm(CapabilitiesConstants.Namespace, "KeyAsSegmentSupported", EdmPrimitiveTypeKind.Boolean);
|
||||
model.AddElement(term);
|
||||
}
|
||||
Assert.NotNull(term);
|
||||
|
||||
IEdmBooleanConstantExpression boolean = new EdmBooleanConstant(supported);
|
||||
EdmVocabularyAnnotation annotation = new EdmVocabularyAnnotation(container, term, boolean);
|
||||
|
|
|
@ -13,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class NavigationRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsNavigationRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.NavigationRestrictions, navigation.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
|
||||
{
|
||||
// Arrange
|
||||
NavigationRestrictions navigation = new NavigationRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = navigation.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.NavigationRestrictions, navigation.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(navigation.IsNavigable);
|
||||
Assert.Null(navigation.Navigability);
|
||||
Assert.Null(navigation.RestrictedProperties);
|
||||
}
|
||||
|
@ -69,12 +81,14 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
model = CapabilitiesModelHelper.GetEdmModelTypeInline(navigationAnnotation);
|
||||
}
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(model, calendar);
|
||||
NavigationRestrictions navigation = new NavigationRestrictions();
|
||||
bool result = navigation.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(navigation.Navigability);
|
||||
Assert.Equal(NavigationType.Recursive, navigation.Navigability.Value);
|
||||
|
||||
|
@ -135,121 +149,18 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(navigation.Navigability);
|
||||
Assert.Equal(NavigationType.Recursive, navigation.Navigability.Value);
|
||||
|
||||
Assert.NotNull(navigation.RestrictedProperties);
|
||||
Assert.Equal(2, navigation.RestrictedProperties.Count);
|
||||
|
||||
NavigationPropertyRestriction navRestriction = navigation.RestrictedProperties.First();
|
||||
Assert.NotNull(navRestriction.Navigability);
|
||||
Assert.Equal(NavigationType.Single, navRestriction.Navigability.Value);
|
||||
Assert.Equal("abc", navRestriction.NavigationProperty);
|
||||
|
||||
navRestriction = navigation.RestrictedProperties.Last();
|
||||
Assert.NotNull(navRestriction.Navigability);
|
||||
Assert.Equal(NavigationType.None, navRestriction.Navigability.Value);
|
||||
Assert.Equal("xyz", navRestriction.NavigationProperty);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectNavigationRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string outOfLineTemplate = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
string navigationAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"" >
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/Recursive</EnumMember>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
IEdmModel model;
|
||||
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
|
||||
{
|
||||
navigationAnnotation = string.Format(outOfLineTemplate, navigationAnnotation);
|
||||
model = CapabilitiesModelHelper.GetEdmModelOutline(navigationAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = CapabilitiesModelHelper.GetEdmModelNavInline(navigationAnnotation);
|
||||
}
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(navigation.Navigability);
|
||||
Assert.Equal(NavigationType.Recursive, navigation.Navigability.Value);
|
||||
Assert.Null(navigation.RestrictedProperties);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsRestrictedPropertyReturnsCorrectForNavigationProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string outOfLineTemplate = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
string navigationAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"" >
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/Recursive</EnumMember>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""RestrictedProperties"" >
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"" >
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/None</EnumMember>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""RelatedEvents"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
IEdmModel model;
|
||||
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
|
||||
{
|
||||
navigationAnnotation = string.Format(outOfLineTemplate, navigationAnnotation);
|
||||
model = CapabilitiesModelHelper.GetEdmModelOutline(navigationAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = CapabilitiesModelHelper.GetEdmModelTypeInline(navigationAnnotation);
|
||||
}
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(model, calendar);
|
||||
Assert.NotNull(navigation.Navigability); // Guard
|
||||
|
||||
bool result = navigation.IsRestrictedProperty(navigationProperty);
|
||||
NavigationRestrictions navigation = new NavigationRestrictions();
|
||||
bool result = navigation.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyNavigationRestrictions(navigation);
|
||||
|
||||
NavigationPropertyRestriction navRestriction = navigation.RestrictedProperties.Last();
|
||||
Assert.NotNull(navRestriction.Navigability);
|
||||
Assert.Equal(NavigationType.None, navRestriction.Navigability.Value);
|
||||
Assert.Equal("xyz", navRestriction.NavigationProperty);
|
||||
Assert.True(navigation.IsRestrictedProperty("xyz"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -271,11 +182,32 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
|
||||
// Act
|
||||
NavigationRestrictions navigation = new NavigationRestrictions(model, calendar);
|
||||
NavigationRestrictions navigation = new NavigationRestrictions();
|
||||
bool result = navigation.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Null(navigation.Navigability);
|
||||
Assert.Null(navigation.RestrictedProperties);
|
||||
}
|
||||
|
||||
private static void VerifyNavigationRestrictions(NavigationRestrictions navigation)
|
||||
{
|
||||
Assert.NotNull(navigation);
|
||||
Assert.True(navigation.IsNavigable);
|
||||
|
||||
Assert.NotNull(navigation.Navigability);
|
||||
Assert.Equal(NavigationType.Recursive, navigation.Navigability.Value);
|
||||
|
||||
Assert.NotNull(navigation.RestrictedProperties);
|
||||
Assert.Equal(2, navigation.RestrictedProperties.Count);
|
||||
|
||||
NavigationPropertyRestriction navRestriction = navigation.RestrictedProperties.First();
|
||||
Assert.NotNull(navRestriction.Navigability);
|
||||
Assert.Equal(NavigationType.Single, navRestriction.Navigability.Value);
|
||||
Assert.Equal("abc", navRestriction.NavigationProperty);
|
||||
Assert.False(navigation.IsRestrictedProperty("abc"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,17 +12,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class SearchRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsSearchRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.SearchRestrictions, search.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
|
||||
{
|
||||
// Arrange
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = search.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.SearchRestrictions, search.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(search.IsSearchable);
|
||||
Assert.Null(search.Searchable);
|
||||
Assert.Null(search.UnsupportedExpressions);
|
||||
}
|
||||
|
@ -47,12 +59,17 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendar);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.phrase, search.UnsupportedExpressions.Value);
|
||||
|
||||
Assert.False(search.IsUnsupportedExpressions(SearchExpressions.AND));
|
||||
Assert.True(search.IsUnsupportedExpressions(SearchExpressions.phrase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -75,41 +92,17 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendars);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.group, search.UnsupportedExpressions.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AnnotatableTargetOnNavigationPropertyReturnsCorrectPropertyValue()
|
||||
{
|
||||
// Arrange
|
||||
const string searchAnnotation = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"" >
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.SearchRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Searchable"" Bool=""false"" />
|
||||
<PropertyValue Property=""UnsupportedExpressions"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.SearchExpressions/AND</EnumMember>
|
||||
</PropertyValue >
|
||||
</Record>
|
||||
</Annotation>
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = CapabilitiesModelHelper.GetModelOutline(searchAnnotation);
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmNavigationProperty property = calendar.DeclaredNavigationProperties().First(d => d.Name == "RelatedEvents");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, property);
|
||||
|
||||
// Assert
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.AND, search.UnsupportedExpressions.Value);
|
||||
Assert.False(search.IsUnsupportedExpressions(SearchExpressions.AND));
|
||||
Assert.True(search.IsUnsupportedExpressions(SearchExpressions.group));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -132,9 +125,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendar);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.Null(search.UnsupportedExpressions);
|
||||
}
|
||||
|
@ -159,36 +154,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.False(search.Searchable);
|
||||
Assert.Null(search.UnsupportedExpressions);
|
||||
}
|
||||
[Fact]
|
||||
public void AnnotatableTargetOnNavigationPropertyWithUnknownEnumMemberDoesnotReturnsUnsupportedExpressions()
|
||||
{
|
||||
// Arrange
|
||||
const string searchAnnotation = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"" >
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.SearchRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Searchable"" Bool=""false"" />
|
||||
<PropertyValue Property=""UnsupportedExpressions"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.SearchExpressions/Unknown</EnumMember>
|
||||
</PropertyValue >
|
||||
</Record>
|
||||
</Annotation>
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = CapabilitiesModelHelper.GetModelOutline(searchAnnotation);
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmNavigationProperty property = calendar.DeclaredNavigationProperties().First(d => d.Name == "RelatedEvents");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, property);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.Null(search.UnsupportedExpressions);
|
||||
}
|
||||
|
@ -213,9 +183,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendar);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.AND | SearchExpressions.OR, search.UnsupportedExpressions.Value);
|
||||
|
@ -241,41 +213,18 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, calendars);
|
||||
SearchRestrictions search = new SearchRestrictions();
|
||||
bool result = search.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.AND | SearchExpressions.OR, search.UnsupportedExpressions.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AnnotatableTargetOnNavigationPropertyWithMultipleEnumMemberReturnsCorrectPropertyValue()
|
||||
{
|
||||
// Arrange
|
||||
const string searchAnnotation = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"" >
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.SearchRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Searchable"" Bool=""false"" />
|
||||
<PropertyValue Property=""UnsupportedExpressions"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.SearchExpressions/AND Org.OData.Capabilities.V1.SearchExpressions/OR</EnumMember>
|
||||
</PropertyValue >
|
||||
</Record>
|
||||
</Annotation>
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = CapabilitiesModelHelper.GetModelOutline(searchAnnotation);
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
IEdmNavigationProperty property = calendar.DeclaredNavigationProperties().First(d => d.Name == "RelatedEvents");
|
||||
|
||||
// Act
|
||||
SearchRestrictions search = new SearchRestrictions(model, property);
|
||||
|
||||
// Assert
|
||||
Assert.False(search.Searchable);
|
||||
Assert.NotNull(search.UnsupportedExpressions);
|
||||
Assert.Equal(SearchExpressions.AND | SearchExpressions.OR, search.UnsupportedExpressions.Value);
|
||||
Assert.True(search.IsUnsupportedExpressions(SearchExpressions.AND));
|
||||
Assert.True(search.IsUnsupportedExpressions(SearchExpressions.OR));
|
||||
Assert.False(search.IsUnsupportedExpressions(SearchExpressions.group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
|
@ -14,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class SkipSupportedTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsSkipSupportedEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
SkipSupported skip = new SkipSupported();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.SkipSupported, skip.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultSkipSupportedValues()
|
||||
{
|
||||
// Arrange
|
||||
SkipSupported skip = new SkipSupported();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
SkipSupported skip = new SkipSupported(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = skip.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.SkipSupported, skip.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(skip.IsSupported);
|
||||
Assert.Null(skip.Supported);
|
||||
}
|
||||
|
||||
|
@ -46,9 +57,12 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendar); // guard
|
||||
|
||||
// Act
|
||||
SkipSupported skip = new SkipSupported(model, calendar);
|
||||
SkipSupported skip = new SkipSupported();
|
||||
bool result = skip.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(skip.IsSupported);
|
||||
Assert.NotNull(skip.Supported);
|
||||
Assert.False(skip.Supported.Value);
|
||||
}
|
||||
|
@ -71,42 +85,16 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
SkipSupported skip = new SkipSupported(model, calendars);
|
||||
SkipSupported skip = new SkipSupported();
|
||||
bool result = skip.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(skip.Supported);
|
||||
Assert.False(skip.Supported.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectSkipSupportedValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
SkipSupported skip = new SkipSupported(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(skip.Supported);
|
||||
Assert.False(skip.Supported.Value);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.SkipSupported"" Bool=""false"" />";
|
||||
|
||||
|
@ -117,14 +105,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,16 +14,28 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
public class SortRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultSortRestrictionsValues()
|
||||
public void KindPropertyReturnsSortRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
SortRestrictions sort = new SortRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Arrange & Act
|
||||
SortRestrictions sort = new SortRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.SortRestrictions, sort.QualifiedName);
|
||||
Assert.Equal(CapabilitesTermKind.SortRestrictions, sort.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultSortRestrictionsValues()
|
||||
{
|
||||
// Arrange & Act
|
||||
SortRestrictions sort = new SortRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
bool result = sort.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.True(sort.IsSortable);
|
||||
Assert.Null(sort.Sortable);
|
||||
Assert.Null(sort.AscendingOnlyProperties);
|
||||
Assert.Null(sort.DescendingOnlyProperties);
|
||||
|
@ -48,9 +60,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendar); // guard
|
||||
|
||||
// Act
|
||||
SortRestrictions sort = new SortRestrictions(model, calendar);
|
||||
SortRestrictions sort = new SortRestrictions();
|
||||
bool result = sort.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifySortRestrictions(sort);
|
||||
}
|
||||
|
||||
|
@ -72,68 +86,14 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
SortRestrictions sort = new SortRestrictions(model, calendars);
|
||||
SortRestrictions sort = new SortRestrictions();
|
||||
bool result = sort.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifySortRestrictions(sort);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectSortRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
SortRestrictions sort = new SortRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifySortRestrictions(sort);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonSortablePropertiesReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmProperty emails = calendar.DeclaredStructuralProperties().First(c => c.Name == "Emails");
|
||||
Assert.NotNull(emails); // Guard
|
||||
|
||||
// Act
|
||||
SortRestrictions sort = new SortRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(sort.Sortable);
|
||||
Assert.False(sort.Sortable.Value);
|
||||
Assert.True(sort.IsNonSortableProperty(emails));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
|
@ -165,14 +125,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +147,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(sort.NonSortableProperties);
|
||||
Assert.Single(sort.NonSortableProperties);
|
||||
Assert.Equal("Emails", sort.NonSortableProperties.First());
|
||||
|
||||
Assert.True(sort.IsAscendingOnlyProperty("abc"));
|
||||
Assert.False(sort.IsAscendingOnlyProperty("rst"));
|
||||
|
||||
Assert.False(sort.IsDescendingOnlyProperty("abc"));
|
||||
Assert.True(sort.IsDescendingOnlyProperty("rst"));
|
||||
|
||||
Assert.False(sort.IsNonSortableProperty("abc"));
|
||||
Assert.True(sort.IsNonSortableProperty("Emails"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class TopSupportedTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsTopSupportedEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
TopSupported top = new TopSupported();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.TopSupported, top.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultTopSupportedValues()
|
||||
{
|
||||
// Arrange
|
||||
TopSupported top = new TopSupported();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
TopSupported top = new TopSupported(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = top.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.TopSupported, top.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(top.IsSupported);
|
||||
Assert.Null(top.Supported);
|
||||
}
|
||||
|
||||
|
@ -45,9 +57,12 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendar); // guard
|
||||
|
||||
// Act
|
||||
TopSupported top = new TopSupported(model, calendar);
|
||||
TopSupported top = new TopSupported();
|
||||
bool result = top.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(top.IsSupported);
|
||||
Assert.NotNull(top.Supported);
|
||||
Assert.False(top.Supported.Value);
|
||||
}
|
||||
|
@ -70,42 +85,17 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
TopSupported top = new TopSupported(model, calendars);
|
||||
TopSupported top = new TopSupported();
|
||||
bool result = top.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.False(top.IsSupported);
|
||||
Assert.NotNull(top.Supported);
|
||||
Assert.False(top.Supported.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectTopSupportedValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
TopSupported top = new TopSupported(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(top.Supported);
|
||||
Assert.False(top.Supported.Value);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.TopSupported"" Bool=""false"" />";
|
||||
|
||||
|
@ -116,14 +106,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,29 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
{
|
||||
public class UpdateRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void KindPropertyReturnsUpdateRestrictionsEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
UpdateRestrictions update = new UpdateRestrictions();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitesTermKind.UpdateRestrictions, update.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultUpdateRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
UpdateRestrictions update = new UpdateRestrictions();
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
UpdateRestrictions update = new UpdateRestrictions(EdmCoreModel.Instance, entityType);
|
||||
// Act
|
||||
bool result = update.Load(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.UpdateRestrictions, update.QualifiedName);
|
||||
Assert.False(result);
|
||||
Assert.True(update.IsUpdatable);
|
||||
Assert.Null(update.Updatable);
|
||||
Assert.Null(update.NonUpdatableNavigationProperties);
|
||||
}
|
||||
|
@ -47,9 +59,11 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendar); // guard
|
||||
|
||||
// Act
|
||||
UpdateRestrictions update = new UpdateRestrictions(model, calendar);
|
||||
UpdateRestrictions update = new UpdateRestrictions();
|
||||
bool result = update.Load(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyUpdateRestrictions(update);
|
||||
}
|
||||
|
||||
|
@ -71,69 +85,15 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(calendars); // guard
|
||||
|
||||
// Act
|
||||
UpdateRestrictions update = new UpdateRestrictions(model, calendars);
|
||||
UpdateRestrictions update = new UpdateRestrictions();
|
||||
bool result = update.Load(model, calendars);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
VerifyUpdateRestrictions(update);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectUpdateRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
UpdateRestrictions update = new UpdateRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyUpdateRestrictions(update);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonUpdatableNavigationPropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // Guard
|
||||
|
||||
// Act
|
||||
UpdateRestrictions update = new UpdateRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(update.Updatable);
|
||||
Assert.False(update.Updatable.Value);
|
||||
Assert.True(update.IsNonUpdatableNavigationProperty(navigationProperty));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"" >
|
||||
|
@ -155,14 +115,7 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +129,10 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
Assert.NotNull(update.NonUpdatableNavigationProperties);
|
||||
Assert.Equal(2, update.NonUpdatableNavigationProperties.Count);
|
||||
Assert.Equal("abc|RelatedEvents", String.Join("|", update.NonUpdatableNavigationProperties));
|
||||
|
||||
Assert.True(update.IsNonUpdatableNavigationProperty("abc"));
|
||||
Assert.True(update.IsNonUpdatableNavigationProperty("RelatedEvents"));
|
||||
Assert.False(update.IsNonUpdatableNavigationProperty("Others"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,26 +3,62 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Microsoft.OpenApi.OData.Properties;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
{
|
||||
public class EntityPathItemGeneratorTests
|
||||
public class EntityPathItemHandlerTests
|
||||
{
|
||||
private EntityPathItemHandler _pathItemHandler = new EntityPathItemHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullContext()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("context",
|
||||
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullPath()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("path",
|
||||
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNonEntityPath()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation: "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
var path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
Assert.Equal(ODataPathKind.EntitySet, path.Kind); // guard
|
||||
|
||||
// Act
|
||||
Action test = () => _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(test);
|
||||
Assert.Equal(String.Format(SRResource.InvalidPathKindForPathItemHandler, "EntityPathItemHandler", path.Kind), exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateEntityPathItemReturnsCorrectPathItem()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation: "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
|
@ -38,5 +74,91 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
Assert.Equal(new OperationType[] { OperationType.Get, OperationType.Patch, OperationType.Delete },
|
||||
pathItem.Operations.Select(o => o.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Patch, OperationType.Delete })]
|
||||
[InlineData(false, new OperationType[] { OperationType.Patch, OperationType.Delete })]
|
||||
public void CreateEntityPathItemWorksForIndexableByKeyRestrictionsCapablities(bool indexableByKey, OperationType[] expected)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.IndexableByKey"" Bool=""{0}"" />", indexableByKey);
|
||||
|
||||
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation);
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Equal(expected, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Patch, OperationType.Delete })]
|
||||
[InlineData(false, new OperationType[] { OperationType.Get, OperationType.Delete })]
|
||||
public void CreateEntityPathItemWorksForUpdateRestrictionsCapablities(bool updatable, OperationType[] expected)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Updatable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", updatable);
|
||||
|
||||
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation);
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Equal(expected, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Patch, OperationType.Delete })]
|
||||
[InlineData(false, new OperationType[] { OperationType.Get, OperationType.Patch })]
|
||||
public void CreateEntityPathItemWorksForDeleteRestrictionsCapablities(bool deletable, OperationType[] expected)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.DeleteRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Deletable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", deletable);
|
||||
|
||||
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation);
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Equal(expected, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
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.Models;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Microsoft.OpenApi.OData.Properties;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
|
@ -16,13 +21,48 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
{
|
||||
private EntitySetPathItemHandler _pathItemHandler = new EntitySetPathItemHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullContext()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("context",
|
||||
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullPath()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("path",
|
||||
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNonEntitySetPath()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(annotation: "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
var entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
var path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
Assert.Equal(ODataPathKind.Entity, path.Kind); // guard
|
||||
|
||||
// Act
|
||||
Action test = () => _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(test);
|
||||
Assert.Equal(String.Format(SRResource.InvalidPathKindForPathItemHandler, "EntitySetPathItemHandler", path.Kind), exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateEntitySetPathItemReturnsCorrectPathItem()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmModel model = GetEdmModel(annotation: "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
|
||||
|
@ -38,5 +78,107 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
Assert.Equal(new OperationType[] { OperationType.Get, OperationType.Post },
|
||||
pathItem.Operations.Select(o => o.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("None")]
|
||||
[InlineData("Single")]
|
||||
[InlineData("Recursive")]
|
||||
public void CreateEntitySetPathItemWorksForNavigationRestrictionsCapablities(string navigationType)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/{0}</EnumMember>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>", navigationType);
|
||||
|
||||
IEdmModel model = GetEdmModel(annotation);
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Contains(OperationType.Post, pathItem.Operations.Select(e => e.Key));
|
||||
|
||||
if (navigationType == "None")
|
||||
{
|
||||
Assert.DoesNotContain(OperationType.Get, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Contains(OperationType.Get, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Post })]
|
||||
[InlineData(false, new OperationType[] { OperationType.Get })]
|
||||
public void CreateEntitySetPathItemWorksForInsertRestrictionsCapablities(bool insertable, OperationType[] expected)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Insertable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", insertable);
|
||||
|
||||
IEdmModel model = GetEdmModel(annotation);
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
|
||||
// Act
|
||||
var pathItem = _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(pathItem);
|
||||
|
||||
Assert.NotNull(pathItem.Operations);
|
||||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Equal(expected, pathItem.Operations.Select(e => e.Key));
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
<EntityContainer Name =""Default"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"" />
|
||||
</EntityContainer>
|
||||
<Annotations Target=""NS.Default/Customers"">
|
||||
{0}
|
||||
</Annotations>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>";
|
||||
string modelText = string.Format(template, annotation);
|
||||
|
||||
IEdmModel model;
|
||||
IEnumerable<EdmError> errors;
|
||||
|
||||
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out errors);
|
||||
Assert.True(result);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
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.Models;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
|
@ -12,10 +17,45 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
{
|
||||
public class NavigationPropertyPathItemGeneratorTest
|
||||
public class NavigationPropertyPathItemHandlerTest
|
||||
{
|
||||
private NavigationPropertyPathItemHandler _pathItemHandler = new NavigationPropertyPathItemHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullContext()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("context",
|
||||
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullPath()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("path",
|
||||
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
|
||||
}
|
||||
/*
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNonNavigationPropertyPath()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(annotation: "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
var entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(entitySet); // guard
|
||||
var path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
Assert.Equal(ODataPathKind.Entity, path.Kind); // guard
|
||||
|
||||
// Act
|
||||
Action test = () => _pathItemHandler.CreatePathItem(context, path);
|
||||
|
||||
// Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(test);
|
||||
Assert.Equal(String.Format(SRResource.InvalidPathKindForPathItemHandler, "EntitySetPathItemHandler", path.Kind), exception.Message);
|
||||
}*/
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, true, new OperationType[] { OperationType.Get, OperationType.Patch })]
|
||||
[InlineData(true, false, new OperationType[] { OperationType.Get, OperationType.Post })]
|
||||
|
@ -84,5 +124,43 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
Assert.NotEmpty(pathItem.Operations);
|
||||
Assert.Equal(expected, pathItem.Operations.Select(o => o.Key));
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
<NavigationProperty Name=""DirectOrders"" Type=""Collection(NS.Order)"" />
|
||||
</EntityType>
|
||||
<EntityType Name=""Order"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
<EntityContainer Name =""Default"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"" />
|
||||
<EntitySet Name=""Orders"" EntityType=""NS.Order"" />
|
||||
</EntityContainer>
|
||||
<Annotations Target=""NS.Default/Customers"">
|
||||
{0}
|
||||
</Annotations>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>";
|
||||
string modelText = string.Format(template, annotation);
|
||||
|
||||
IEdmModel model;
|
||||
IEnumerable<EdmError> errors;
|
||||
|
||||
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out errors);
|
||||
Assert.True(result);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
@ -12,10 +13,26 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
{
|
||||
public class OperationImportPathItemGeneratorTest
|
||||
public class OperationImportPathItemHandlerTest
|
||||
{
|
||||
private OperationImportPathItemHandler _pathItemHandler = new OperationImportPathItemHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullContext()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("context",
|
||||
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullPath()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("path",
|
||||
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GetNearestAirport", OperationType.Get)]
|
||||
[InlineData("ResetDataSource", OperationType.Post)]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
@ -12,10 +13,26 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
{
|
||||
public class OperationPathItemGeneratorTest
|
||||
public class OperationPathItemHandlerTest
|
||||
{
|
||||
private OperationPathItemHandler _pathItemHandler = new OperationPathItemHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullContext()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("context",
|
||||
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatePathItemThrowsForNullPath()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("path",
|
||||
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GetFriendsTrips", "People", OperationType.Get)]
|
||||
[InlineData("ShareTrip", "People", OperationType.Post)]
|
||||
|
|
|
@ -18,7 +18,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.OpenApi.OData.PathItem.Tests
|
||||
{
|
||||
public class SingletonPathItemGeneratorTest
|
||||
public class SingletonPathItemHandlerTest
|
||||
{
|
||||
private SingletonPathItemHandler _pathItemHandler = new SingletonPathItemHandler();
|
||||
|
||||
|
|
|
@ -89,7 +89,10 @@
|
|||
"AddressInfo",
|
||||
"HomeAddress",
|
||||
"FavoriteFeature",
|
||||
"Features"
|
||||
"Features",
|
||||
"Friends",
|
||||
"BestFriend",
|
||||
"Trips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -212,7 +215,10 @@
|
|||
"AddressInfo",
|
||||
"HomeAddress",
|
||||
"FavoriteFeature",
|
||||
"Features"
|
||||
"Features",
|
||||
"Friends",
|
||||
"BestFriend",
|
||||
"Trips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -1183,7 +1189,10 @@
|
|||
"AddressInfo",
|
||||
"HomeAddress",
|
||||
"FavoriteFeature",
|
||||
"Features"
|
||||
"Features",
|
||||
"Friends",
|
||||
"BestFriend",
|
||||
"Trips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -1306,7 +1315,10 @@
|
|||
"AddressInfo",
|
||||
"HomeAddress",
|
||||
"FavoriteFeature",
|
||||
"Features"
|
||||
"Features",
|
||||
"Friends",
|
||||
"BestFriend",
|
||||
"Trips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -1664,7 +1676,10 @@
|
|||
"AddressInfo",
|
||||
"HomeAddress",
|
||||
"FavoriteFeature",
|
||||
"Features"
|
||||
"Features",
|
||||
"Friends",
|
||||
"BestFriend",
|
||||
"Trips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
|
|
|
@ -68,6 +68,9 @@ paths:
|
|||
- HomeAddress
|
||||
- FavoriteFeature
|
||||
- Features
|
||||
- Friends
|
||||
- BestFriend
|
||||
- Trips
|
||||
type: string
|
||||
- name: $expand
|
||||
in: query
|
||||
|
@ -153,6 +156,9 @@ paths:
|
|||
- HomeAddress
|
||||
- FavoriteFeature
|
||||
- Features
|
||||
- Friends
|
||||
- BestFriend
|
||||
- Trips
|
||||
type: string
|
||||
- name: $expand
|
||||
in: query
|
||||
|
@ -792,6 +798,9 @@ paths:
|
|||
- HomeAddress
|
||||
- FavoriteFeature
|
||||
- Features
|
||||
- Friends
|
||||
- BestFriend
|
||||
- Trips
|
||||
type: string
|
||||
- name: $expand
|
||||
in: query
|
||||
|
@ -877,6 +886,9 @@ paths:
|
|||
- HomeAddress
|
||||
- FavoriteFeature
|
||||
- Features
|
||||
- Friends
|
||||
- BestFriend
|
||||
- Trips
|
||||
type: string
|
||||
- name: $expand
|
||||
in: query
|
||||
|
@ -1114,6 +1126,9 @@ paths:
|
|||
- HomeAddress
|
||||
- FavoriteFeature
|
||||
- Features
|
||||
- Friends
|
||||
- BestFriend
|
||||
- Trips
|
||||
type: string
|
||||
- name: $expand
|
||||
in: query
|
||||
|
|
Loading…
Reference in a new issue