Make all test passed

This commit is contained in:
Sam Xu 2019-06-27 17:06:02 -07:00
parent 4d8264dfb1
commit bc405aa8ac
61 changed files with 2369 additions and 1164 deletions

View file

@ -4,6 +4,7 @@
// ------------------------------------------------------------
using System;
using Microsoft.OpenApi.OData.Vocabulary;
namespace Microsoft.OpenApi.OData.Common
{
@ -12,6 +13,23 @@ namespace Microsoft.OpenApi.OData.Common
/// </summary>
public static class Utils
{
/// <summary>
/// Get the term qualified name when using the type of <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type of the term.</typeparam>
/// <returns>The qualified name.</returns>
public static string GetTermQualifiedName<T>()
{
object[] attributes = typeof(T).GetCustomAttributes(typeof(TermAttribute), false);
if (attributes == null && attributes.Length == 0)
{
return null;
}
TermAttribute term = (TermAttribute)attributes[0];
return term.QualifiedName;
}
/// <summary>
/// Upper the first character of the string.
/// </summary>

View file

@ -24,20 +24,6 @@ namespace Microsoft.OpenApi.OData.Edm
private static IEdmModel _savedModel = null; // if diffenent model, the cache will be cleaned.
private static object _objectLock = new object();
/// <summary>
/// Get the term qualified name when using the type of <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type of the term.</typeparam>
/// <returns>The qualified name.</returns>
public static string GetTermQualifiedName<T>()
{
object[] attributes = typeof(T).GetCustomAttributes(typeof(TermAttribute), false);
Debug.Assert(attributes != null && attributes.Length == 1);
TermAttribute term = (TermAttribute)attributes[0];
return term.QualifiedName;
}
/// <summary>
/// Gets the boolean term value for the given <see cref="IEdmVocabularyAnnotatable"/>.
/// </summary>
@ -129,7 +115,7 @@ namespace Microsoft.OpenApi.OData.Edm
public static T GetRecord<T>(this IEdmModel model, IEdmVocabularyAnnotatable target)
where T : IRecord, new()
{
string qualifiedName = GetTermQualifiedName<T>();
string qualifiedName = Utils.GetTermQualifiedName<T>();
return model.GetRecord<T>(target, qualifiedName);
}
@ -226,7 +212,7 @@ namespace Microsoft.OpenApi.OData.Edm
Utils.CheckArgumentNull(model, nameof(model));
Utils.CheckArgumentNull(target, nameof(target));
string qualifiedName = GetTermQualifiedName<T>();
string qualifiedName = Utils.GetTermQualifiedName<T>();
return GetCollection<T>(model, target, qualifiedName);
}
@ -386,7 +372,7 @@ namespace Microsoft.OpenApi.OData.Edm
Debug.Assert(term != null);
IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, term).FirstOrDefault();
if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.StringConstant)
if (annotation != null && annotation.Value != null && annotation.Value.ExpressionKind == EdmExpressionKind.BooleanConstant)
{
IEdmBooleanConstantExpression boolConstant = (IEdmBooleanConstantExpression)annotation.Value;
if (boolConstant != null)
@ -481,7 +467,6 @@ namespace Microsoft.OpenApi.OData.Edm
}
private static Type GetTypeInfo<T>(string fullTypeName) where T : IRecord
{
object[] attributes = typeof(T).GetCustomAttributes(typeof(SubTypeAttribute), false);

View file

@ -4,7 +4,6 @@
// ------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm;

View file

@ -36,6 +36,11 @@ namespace Microsoft.OpenApi.OData.Generator
IDictionary<string, OpenApiSecurityScheme> securitySchemes = new Dictionary<string, OpenApiSecurityScheme>();
var authorizations = context.Model.GetAuthorizations(context.EntityContainer);
if (authorizations == null)
{
return securitySchemes;
}
foreach (var authorization in authorizations)
{
OpenApiSecurityScheme scheme = new OpenApiSecurityScheme

View file

@ -154,14 +154,14 @@ namespace Microsoft.OpenApi.OData.Operation
/// <inheritdoc/>
protected override void SetSecurity(OpenApiOperation operation)
{
IEnumerable<OperationRestriction> restrictions = Context.Model.GetCollection<OperationRestriction>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
IEnumerable<OperationRestrictionType> restrictions = Context.Model.GetCollection<OperationRestrictionType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
if (restrictions == null || !restrictions.Any())
{
return;
}
// TODO: how to use the collection?
OperationRestriction operationRestriction = restrictions.First();
OperationRestrictionType operationRestriction = restrictions.First();
// the Permission should be collection, however current ODL supports the single permission.
// Will update after ODL change.
@ -171,14 +171,14 @@ namespace Microsoft.OpenApi.OData.Operation
/// <inheritdoc/>
protected override void AppendCustomParameters(OpenApiOperation operation)
{
IEnumerable<OperationRestriction> restrictions = Context.Model.GetCollection<OperationRestriction>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
IEnumerable<OperationRestrictionType> restrictions = Context.Model.GetCollection<OperationRestrictionType>(EdmOperation, CapabilitiesConstants.OperationRestrictions);
if (restrictions == null || !restrictions.Any())
{
return;
}
// TODO: how to use the collection?
OperationRestriction operationRestriction = restrictions.First();
OperationRestrictionType operationRestriction = restrictions.First();
if (operationRestriction.CustomHeaders != null)
{

View file

@ -20,7 +20,7 @@ namespace Microsoft.OpenApi.OData.PathItem
/// <inheritdoc/>
protected override void SetOperations(OpenApiPathItem item)
{
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(EntitySet);
if (read == null ||
(read.ReadByKeyRestrictions == null && read.IsReadable) ||
(read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable))
@ -29,13 +29,13 @@ namespace Microsoft.OpenApi.OData.PathItem
AddOperation(item, OperationType.Get);
}
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(EntitySet, CapabilitiesConstants.UpdateRestrictions);
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(EntitySet);
if (update == null || update.IsUpdatable)
{
AddOperation(item, OperationType.Patch);
}
DeleteRestrictionsType delete = Context.Model.GetRecord<DeleteRestrictionsType>(EntitySet, CapabilitiesConstants.DeleteRestrictions);
DeleteRestrictionsType delete = Context.Model.GetRecord<DeleteRestrictionsType>(EntitySet);
if (delete == null || delete.IsDeletable)
{
AddOperation(item, OperationType.Delete);

View file

@ -26,13 +26,13 @@ namespace Microsoft.OpenApi.OData.PathItem
/// <inheritdoc/>
protected override void SetOperations(OpenApiPathItem item)
{
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(EntitySet);
if (read == null || read.IsReadable)
{
AddOperation(item, OperationType.Get);
}
InsertRestrictionsType insert = Context.Model.GetRecord<InsertRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions);
InsertRestrictionsType insert = Context.Model.GetRecord<InsertRestrictionsType>(EntitySet);
if (insert == null || insert.IsInsertable)
{
AddOperation(item, OperationType.Post);

View file

@ -27,14 +27,14 @@ namespace Microsoft.OpenApi.OData.PathItem
protected override void SetOperations(OpenApiPathItem item)
{
// Retrieve a singleton.
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(Singleton, CapabilitiesConstants.ReadRestrictions);
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(Singleton);
if (read == null || read.IsReadable)
{
AddOperation(item, OperationType.Get);
}
// Update a singleton
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(Singleton, CapabilitiesConstants.UpdateRestrictions);
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(Singleton);
if (update == null || update.IsUpdatable)
{
AddOperation(item, OperationType.Patch);

View file

@ -23,62 +23,62 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Org.OData.Capabilities.V1.FilterRestrictions
/// </summary>
public const string FilterRestrictions = "Org.OData.Capabilities.V1..FilterRestrictions";
public const string FilterRestrictions = "Org.OData.Capabilities.V1.FilterRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.SortRestrictions
/// </summary>
public const string SortRestrictions = "Org.OData.Capabilities.V1..SortRestrictions";
public const string SortRestrictions = "Org.OData.Capabilities.V1.SortRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.NavigationRestrictions
/// </summary>
public const string NavigationRestrictions = "Org.OData.Capabilities.V1..NavigationRestrictions";
public const string NavigationRestrictions = "Org.OData.Capabilities.V1.NavigationRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.SearchRestrictions
/// </summary>
public const string SearchRestrictions = "Org.OData.Capabilities.V1..SearchRestrictions";
public const string SearchRestrictions = "Org.OData.Capabilities.V1.SearchRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.CountRestrictions
/// </summary>
public const string CountRestrictions = "Org.OData.Capabilities.V1..CountRestrictions";
public const string CountRestrictions = "Org.OData.Capabilities.V1.CountRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.ExpandRestrictions
/// </summary>
public const string ExpandRestrictions = "Org.OData.Capabilities.V1..ExpandRestrictions";
public const string ExpandRestrictions = "Org.OData.Capabilities.V1.ExpandRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.DeleteRestrictions
/// </summary>
public const string DeleteRestrictions = "Org.OData.Capabilities.V1..DeleteRestrictions";
public const string DeleteRestrictions = "Org.OData.Capabilities.V1.DeleteRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.DeleteRestrictions
/// </summary>
public const string UpdateRestrictions = "Org.OData.Capabilities.V1..UpdateRestrictions";
public const string UpdateRestrictions = "Org.OData.Capabilities.V1.UpdateRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.InsertRestrictions
/// </summary>
public const string InsertRestrictions = "Org.OData.Capabilities.V1..InsertRestrictions";
public const string InsertRestrictions = "Org.OData.Capabilities.V1.InsertRestrictions";
/// <summary>
/// Org.OData.Capabilities.V1.TopSupported
/// </summary>
public const string TopSupported = "Org.OData.Capabilities.V1..TopSupported";
public const string TopSupported = "Org.OData.Capabilities.V1.TopSupported";
/// <summary>
/// Org.OData.Capabilities.V1.SkipSupported
/// </summary>
public const string SkipSupported = "Org.OData.Capabilities.V1..SkipSupported";
public const string SkipSupported = "Org.OData.Capabilities.V1.SkipSupported";
/// <summary>
/// Term: Org.OData.Capabilities.V1.BatchSupported
/// </summary>
public const string BatchSupported = "Org.OData.Capabilities.V1..BatchSupported";
public const string BatchSupported = "Org.OData.Capabilities.V1.BatchSupported";
/// <summary>
/// Term: rg.OData.Capabilities.V1.OperationRestrictions
@ -88,11 +88,11 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Org.OData.Capabilities.V1.IndexableByKey
/// </summary>
public const string IndexableByKey = "Org.OData.Capabilities.V1..IndexableByKey";
public const string IndexableByKey = "Org.OData.Capabilities.V1.IndexableByKey";
/// <summary>
/// Org.OData.Capabilities.V1.KeyAsSegmentSupported
/// </summary>
public const string KeyAsSegmentSupported = "Org.OData.Capabilities.V1..KeyAsSegmentSupported";
public const string KeyAsSegmentSupported = "Org.OData.Capabilities.V1.KeyAsSegmentSupported";
}
}

View file

@ -1,163 +0,0 @@
// ------------------------------------------------------------
// 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.Vocabulary.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>
/// Deep Insert Support of the annotated resource (the whole service, an entity set, or a collection-valued resource
/// </summary>
DeepInsertSupport,
/// <summary>
/// Restrictions on update operations
/// </summary>
UpdateRestrictions,
/// <summary>
/// Deep Update Support of the annotated resource (the whole service, an entity set, or a collection-valued resource)
/// </summary>
DeepUpdateSupported,
/// <summary>
/// Restrictions on delete operations
/// </summary>
DeleteRestrictions,
/// <summary>
/// Describes restrictions on operations applied to collection-valued structural properties.
/// </summary>
CollectionPropertyRestrictions,
/// <summary>
/// Restrictions for function or action operation.
/// </summary>
OperationRestrictions,
/// <summary>
/// Restrictions for retrieving a collection of entities, retrieving a singleton instance, invoking a function
/// </summary>
ReadRestrictions,
/// <summary>
/// Custom headers that are supported/required for the annotated resource
/// </summary>
CustomHeaders,
/// <summary>
/// Custom query options that are supported/required for the annotated resource
/// </summary>
CustomQueryOptions
}
}

View file

@ -13,6 +13,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.CollectionPropertyRestrictionsType
/// </summary>
[Term("Org.OData.Capabilities.V1.CollectionPropertyRestrictions")]
internal class CollectionPropertyRestrictionsType : IRecord
{
/// <summary>
@ -70,13 +71,46 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// </summary>
public bool? Deletable { get; private set; }
/// <summary>
/// Init the <see cref="CollectionPropertyRestrictionsType"/>.
/// </summary>
/// <param name="record">The input record.</param>
public virtual void Initialize(IEdmRecordExpression record)
{
Utils.CheckArgumentNull(record, nameof(record));
// CollectionProperty
CollectionProperty = record.GetPropertyPath("CollectionProperty");
// FilterFunctions
FilterFunctions = record.GetCollection("FilterFunctions");
// FilterRestrictions
FilterRestrictions = record.GetRecord<FilterRestrictionsType>("FilterRestrictions");
// SearchRestrictions
SearchRestrictions = record.GetRecord<SearchRestrictionsType>("SearchRestrictions");
// SortRestrictions
SortRestrictions = record.GetRecord<SortRestrictionsType>("SortRestrictions");
// TopSupported
TopSupported = record.GetBoolean("TopSupported");
// SkipSupported
SkipSupported = record.GetBoolean("SkipSupported");
// SelectSupport
SelectSupport = record.GetRecord<SelectSupportType>("SelectSupport");
// Insertable
Insertable = record.GetBoolean("Insertable");
// Updatable
Updatable = record.GetBoolean("Updatable");
// Deletable
Deletable = record.GetBoolean("Deletable");
}
}
}

View file

@ -14,6 +14,8 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Complex type: Org.OData.Capabilities.V1.CustomParameter
/// </summary>
// [Term("Org.OData.Capabilities.V1.CustomHeaders")]
// [Term("Org.OData.Capabilities.V1.CustomQueryOptions")]
internal class CustomParameter : IRecord
{
/// <summary>

View file

@ -12,6 +12,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.DeepInsertSupport
/// </summary>
[Term("Org.OData.Capabilities.V1.DeepInsertSupport")]
internal class DeepInsertSupportType : IRecord
{
/// <summary>

View file

@ -12,6 +12,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.DeepUpdateSupportType
/// </summary>
[Term("Org.OData.Capabilities.V1.DeepUpdateSupport")]
internal class DeepUpdateSupportType : IRecord
{
/// <summary>

View file

@ -43,7 +43,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
public IList<CustomParameter> CustomHeaders { get; private set; }
/// <summary>
/// Gets the Supported or required custom headers.
/// Gets the Supported or required custom query options.
/// </summary>
public IList<CustomParameter> CustomQueryOptions { get; private set; }
@ -76,11 +76,20 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
// Deletable
Deletable = record.GetBoolean("Deletable");
// NonDeletableNavigationProperties
NonDeletableNavigationProperties = record.GetCollectionPropertyPath("NonDeletableNavigationProperties");
// MaxLevels
MaxLevels = (int?)record.GetInteger("MaxLevels");
// NonDeletableNavigationProperties
NonDeletableNavigationProperties = record.GetCollectionPropertyPath("NonDeletableNavigationProperties");
// Permission
Permission = record.GetRecord<PermissionType>("Permission");
// CustomHeaders
CustomHeaders = record.GetCollection<CustomParameter>("CustomHeaders");
// CustomQueryOptions
CustomQueryOptions = record.GetCollection<CustomParameter>("CustomQueryOptions");
}
}
}

View file

@ -14,7 +14,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Org.OData.Capabilities.V1.ExpandRestrictions
/// </summary>
[Term("Org.OData.Capabilities.V1.DeleteRestrictions")]
[Term("Org.OData.Capabilities.V1.ExpandRestrictions")]
internal class ExpandRestrictionsType : IRecord
{
/// <summary>
@ -30,7 +30,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Gets the maximum number of levels that can be expanded in a expand expression.
/// </summary>
public int? MaxLevles { get; private set; }
public long? MaxLevels { get; private set; }
/// <summary>
/// Test the target supports $expand.
@ -57,6 +57,9 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
// NonExpandableProperties
NonExpandableProperties = record.GetCollectionPropertyPath("NonExpandableProperties");
// MaxLevels
MaxLevels = record.GetInteger("MaxLevels");
}
}
}

View file

@ -0,0 +1,44 @@
// ------------------------------------------------------------
// 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.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.FilterExpressionRestrictionType
/// </summary>
internal class FilterExpressionRestrictionType : IRecord
{
/// <summary>
/// Gets the Path to the restricted property.
/// </summary>
public string Property { get; private set; }
/// <summary>
/// Gets the RequiresFilter value.
/// <Property Name="AllowedExpressions" Type="Capabilities.FilterExpressionType">
/// <TypeDefinition Name="FilterExpressionType" UnderlyingType="Edm.String">
/// </summary>
public string AllowedExpressions { get; private set; }
/// <summary>
/// Init the <see cref="FilterExpressionRestrictionType"/>.
/// </summary>
/// <param name="record">The input record.</param>
public void Initialize(IEdmRecordExpression record)
{
Utils.CheckArgumentNull(record, nameof(record));
// Property
Property = record.GetPropertyPath("Property");
// AllowedExpressions
AllowedExpressions = record.GetString("AllowedExpressions");
}
}
}

View file

@ -37,6 +37,17 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// </summary>
public IList<string> NonFilterableProperties { get; private set; }
/// <summary>
/// Gets The maximum number of levels (including recursion) that can be traversed in a filter expression. A value of -1 indicates there is no restriction.
/// </summary>
public long? MaxLevels { get; private set; }
/// <summary>
/// Gets These properties only allow a subset of filter expressions.
/// A valid filter expression for a single property can be enclosed in parentheses and combined by `and` with valid expressions for other properties.
/// </summary>
public IList<FilterExpressionRestrictionType> FilterExpressionRestrictions { get; private set; }
/// <summary>
/// Test the target supports filter.
/// </summary>
@ -82,6 +93,12 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
// NonFilterableProperties
NonFilterableProperties = record.GetCollectionPropertyPath("NonFilterableProperties");
// MaxLevels
MaxLevels = record.GetInteger("MaxLevels");
// FilterExpressionRestrictions
FilterExpressionRestrictions = record.GetCollection<FilterExpressionRestrictionType>("FilterExpressionRestrictions");
}
}
}

View file

@ -12,6 +12,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Complex type: Org.OData.Capabilities.V1.ModificationQueryOptionsType
/// </summary>
[Term("Org.OData.Capabilities.V1.ModificationQueryOptions")]
internal class ModificationQueryOptionsType : IRecord
{
/// <summary>

View file

@ -143,7 +143,43 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
FilterRestrictions = record.GetRecord<FilterRestrictionsType>("FilterRestrictions");
// SearchRestrictions
//SearchRestrictions = record.GetRecord<SearchRestrictions>("SearchRestrictions", (r, t) => r.Init(t));
SearchRestrictions = record.GetRecord<SearchRestrictionsType>("SearchRestrictions");
// SortRestrictions
SortRestrictions = record.GetRecord<SortRestrictionsType>("SortRestrictions");
// TopSupported
TopSupported = record.GetBoolean("TopSupported");
// SkipSupported
SkipSupported = record.GetBoolean("SkipSupported");
// SelectSupport
SelectSupport = record.GetRecord<SelectSupportType>("SelectSupport");
// IndexableByKey
IndexableByKey = record.GetBoolean("IndexableByKey");
// InsertRestrictions
InsertRestrictions = record.GetRecord<InsertRestrictionsType>("InsertRestrictions");
// DeepInsertSupport
DeepInsertSupport = record.GetRecord<DeepInsertSupportType>("DeepInsertSupport");
// UpdateRestrictions
UpdateRestrictions = record.GetRecord<UpdateRestrictionsType>("UpdateRestrictions");
// DeepUpdateSupport
DeepUpdateSupport = record.GetRecord<DeepUpdateSupportType>("DeepUpdateSupport");
// DeleteRestrictions
DeleteRestrictions = record.GetRecord<DeleteRestrictionsType>("DeleteRestrictions");
// IndexableByKey
OptimisticConcurrencyControl = record.GetBoolean("OptimisticConcurrencyControl");
// ReadRestrictions
ReadRestrictions = record.GetRecord<ReadRestrictionsType>("ReadRestrictions");
}
}
@ -182,7 +218,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
}
/// <summary>
/// Init the <see cref="SearchRestrictionsType"/>.
/// Init the <see cref="NavigationRestrictionsType"/>.
/// </summary>
/// <param name="record">The input record.</param>
public void Initialize(IEdmRecordExpression record)
@ -195,35 +231,5 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
// RestrictedProperties
RestrictedProperties = record.GetCollection<NavigationPropertyRestriction>("RestrictedProperties");
}
private static IList<NavigationPropertyRestriction> GetRestrictedProperties(IEdmRecordExpression record)
{
if (record != null && record.Properties != null)
{
IEdmPropertyConstructor property = record.Properties.FirstOrDefault(p => p.Name == "RestrictedProperties");
if (property != null)
{
IEdmCollectionExpression value = property.Value as IEdmCollectionExpression;
if (value != null && value.Elements != null)
{
IList<NavigationPropertyRestriction> restrictedProperties = new List<NavigationPropertyRestriction>();
foreach (var item in value.Elements.OfType<IEdmRecordExpression>())
{
NavigationPropertyRestriction restriction = new NavigationPropertyRestriction();
restriction.Navigability = item.GetEnum<NavigationType>("Navigability");
restriction.NavigationProperty = item.GetPropertyPath("NavigationProperty");
restrictedProperties.Add(restriction);
}
if (restrictedProperties.Any())
{
return restrictedProperties;
}
}
}
}
return null;
}
}
}

View file

@ -11,9 +11,11 @@ using Microsoft.OpenApi.OData.Edm;
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.OperationRestriction
/// Complex Type: Org.OData.Capabilities.V1.OperationRestrictionType
/// Be note: in ODL 7.6, it's named as "OperationRestriction", after that, it will be changed as "OperationRestrictionType"
/// </summary>
internal class OperationRestriction : IRecord
[Term("Org.OData.Capabilities.V1.OperationRestrictions")]
internal class OperationRestrictionType : IRecord
{
/// <summary>
/// Gets the List of required scopes to invoke an action or function.

View file

@ -10,6 +10,9 @@ using Microsoft.OpenApi.OData.Edm;
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.ReadRestrictionsBase
/// </summary>
internal abstract class ReadRestrictionsBase : IRecord
{
/// <summary>
@ -38,6 +41,10 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <returns>True/false.</returns>
public bool IsReadable => Readable == null || Readable.Value;
/// <summary>
/// Init the <see cref="ReadRestrictionsBase"/>.
/// </summary>
/// <param name="record">The input record.</param>
public virtual void Initialize(IEdmRecordExpression record)
{
Utils.CheckArgumentNull(record, nameof(record));
@ -57,10 +64,12 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
}
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.ReadByKeyRestrictionsType
/// Restrictions for retrieving an entity by key
/// </summary>
internal class ReadByKeyRestrictions : ReadRestrictionsBase
{
// nothing here
}
/// <summary>
@ -69,8 +78,15 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
[Term("Org.OData.Capabilities.V1.ReadRestrictions")]
internal class ReadRestrictionsType : ReadRestrictionsBase
{
/// <summary>
/// Gets the Restrictions for retrieving an entity by key
/// </summary>
public ReadByKeyRestrictions ReadByKeyRestrictions { get; set; }
/// <summary>
/// Init the <see cref="ReadRestrictionsType"/>.
/// </summary>
/// <param name="record">The input record.</param>
public override void Initialize(IEdmRecordExpression record)
{
// Load base

View file

@ -5,12 +5,14 @@
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
/// <summary>
/// Complex type: Org.OData.Capabilities.V1.SelectSupportType
/// </summary>
[Term("Org.OData.Capabilities.V1.SelectSupport")]
internal class SelectSupportType : IRecord
{
/// <summary>
@ -66,6 +68,32 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
Utils.CheckArgumentNull(record, nameof(record));
// Supported
Supported = record.GetBoolean("Supported");
// Expandable
Expandable = record.GetBoolean("Expandable");
// Filterable
Filterable = record.GetBoolean("Filterable");
// Searchable
Searchable = record.GetBoolean("Searchable");
// TopSupported
TopSupported = record.GetBoolean("TopSupported");
// SkipSupported
SkipSupported = record.GetBoolean("SkipSupported");
// ComputeSupported
ComputeSupported = record.GetBoolean("ComputeSupported");
// Countable
Countable = record.GetBoolean("Countable");
// Sortable
Sortable = record.GetBoolean("Sortable");
}
}
}

View file

@ -3,7 +3,6 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using Microsoft.OData.Edm.Vocabularies;
using System;
using System.Collections.Generic;
@ -12,7 +11,7 @@ namespace Microsoft.OpenApi.OData.Vocabulary
/// <summary>
///
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
internal class TermAttribute : Attribute
{
public TermAttribute(string qualifiedName)

View file

@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
@ -192,39 +193,40 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
// Assert
Assert.NotNull(counts1);
Assert.NotNull(counts2);
Assert.Same(counts1, counts2);
Assert.Equal(2, counts1.Count());
// #1
CountRestrictionsType count = counts1.First();
foreach (var countItem in new[] { counts1, counts2 })
{
CountRestrictionsType count = countItem.First();
// Countable
Assert.NotNull(count.Countable);
Assert.True(count.Countable.Value);
// Countable
Assert.NotNull(count.Countable);
Assert.True(count.Countable.Value);
// NonCountableProperties
Assert.NotNull(count.NonCountableProperties);
Assert.Equal(new[] { "123", "abc" }, count.NonCountableProperties);
// NonCountableProperties
Assert.NotNull(count.NonCountableProperties);
Assert.Equal(new[] { "123", "abc" }, count.NonCountableProperties);
// NonCountableNavigationProperties
Assert.NotNull(count.NonCountableNavigationProperties);
Assert.Equal(new[] { "234", "xyz" }, count.NonCountableNavigationProperties);
// NonCountableNavigationProperties
Assert.NotNull(count.NonCountableNavigationProperties);
Assert.Equal(new[] { "234", "xyz" }, count.NonCountableNavigationProperties);
// #2
count = counts1.Last();
// #2
count = countItem.Last();
// Countable
Assert.NotNull(count.Countable);
Assert.False(count.Countable.Value);
// Countable
Assert.NotNull(count.Countable);
Assert.False(count.Countable.Value);
// NonCountableProperties
Assert.NotNull(count.NonCountableProperties);
Assert.Equal(new[] { "567", "mij" }, count.NonCountableProperties);
// NonCountableProperties
Assert.NotNull(count.NonCountableProperties);
Assert.Equal(new[] { "567", "mij" }, count.NonCountableProperties);
// NonCountableNavigationProperties
Assert.NotNull(count.NonCountableNavigationProperties);
Assert.Equal(new[] { "789", "rst" }, count.NonCountableNavigationProperties);
// NonCountableNavigationProperties
Assert.NotNull(count.NonCountableNavigationProperties);
Assert.Equal(new[] { "789", "rst" }, count.NonCountableNavigationProperties);
}
}
private IEdmModel GetEdmModel(string annotation)

View file

@ -132,7 +132,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
if (enableOperationId)
{
Assert.Equal("Customers.VipCustomer.MyAction", operation.OperationId);
Assert.Equal("Customers.NS.VipCustomer.MyAction", operation.OperationId);
}
else
{

View file

@ -136,7 +136,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
if (enableOperationId)
{
Assert.Equal("Customers.VipCustomer.MyFunction.1e00", operation.OperationId);
Assert.Equal("Customers.NS.VipCustomer.MyFunction.1e00", operation.OperationId);
}
else
{

View file

@ -81,16 +81,16 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntityPathItemWorksForReadByKeyRestrictionsCapablities(bool readable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
<Record>
<PropertyValue Property=""ReadByKeyRestrictions"" >
<Record>
<PropertyValue Property=""Readable"" Bool=""{0}"" />
<PropertyValue Property=""Readable"" Bool=""{readable}"" />
</Record>
</PropertyValue>
</Record>
</Annotation>", readable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -102,12 +102,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntityPathItemWorksForReadRestrictionsCapablities(bool readable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
<Record>
<PropertyValue Property=""Readable"" Bool=""{0}"" />
<PropertyValue Property=""Readable"" Bool=""{readable}"" />
</Record>
</Annotation>", readable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -119,12 +119,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntityPathItemWorksForUpdateRestrictionsCapablities(bool updatable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
<Record>
<PropertyValue Property=""Updatable"" Bool=""{0}"" />
<PropertyValue Property=""Updatable"" Bool=""{updatable}"" />
</Record>
</Annotation>", updatable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -136,12 +136,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntityPathItemWorksForDeleteRestrictionsCapablities(bool deletable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.DeleteRestrictions"">
<Record>
<PropertyValue Property=""Deletable"" Bool=""{0}"" />
<PropertyValue Property=""Deletable"" Bool=""{deletable}"" />
</Record>
</Annotation>", deletable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);

View file

@ -85,12 +85,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntitySetPathItemWorksForReadRestrictionsCapablities(bool readable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
<Record>
<PropertyValue Property=""Readable"" Bool=""{0}"" />
<PropertyValue Property=""Readable"" Bool=""{readable}"" />
</Record>
</Annotation>", readable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -102,12 +102,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateEntitySetPathItemWorksForInsertRestrictionsCapablities(bool insertable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"">
<Record>
<PropertyValue Property=""Insertable"" Bool=""{0}"" />
<PropertyValue Property=""Insertable"" Bool=""{insertable}"" />
</Record>
</Annotation>", insertable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);

View file

@ -85,12 +85,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateSingletonPathItemWorksForReadRestrictionsCapablities(bool readable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
<Record>
<PropertyValue Property=""Readable"" Bool=""{0}"" />
<PropertyValue Property=""Readable"" Bool=""{readable}"" />
</Record>
</Annotation>", readable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -102,12 +102,12 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
public void CreateSingletonPathItemWorksForUpdateRestrictionsCapablities(bool updatable, OperationType[] expected)
{
// Arrange
string annotation = String.Format(@"
string annotation = $@"
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
<Record>
<PropertyValue Property=""Updatable"" Bool=""{0}"" />
<PropertyValue Property=""Updatable"" Bool=""{updatable}"" />
</Record>
</Annotation>", updatable);
</Annotation>";
// Assert
VerifyPathItemOperations(annotation, expected);
@ -148,16 +148,7 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
<Singleton Name=""Me"" Type=""NS.Customer"" />
</EntityContainer>
<Annotations Target=""NS.Default/Me"">
<Annotation Term=""Org.OData.Capabilities.V1.UpdateRestrictions"">
<Record>
<PropertyValue Property=""Updatable"" Bool=""{0}"" />
</Record>
</Annotation>
<Annotation Term=""Org.OData.Capabilities.V1.afdasf"">
<Record>
<PropertyValue Property=""Updatable"" Bool=""{0}"" />
</Record>
</Annotation>
{0}
</Annotations>
</Schema>
</edmx:DataServices>

View file

@ -9,6 +9,7 @@ using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
@ -17,6 +18,16 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class ApiKeyTests
{
[Fact]
public void SchemeTypeKindSetCorrectly()
{
// Arrange
ApiKey apiKey = new ApiKey();
// Act & Assert
Assert.Equal(SecuritySchemeType.ApiKey, apiKey.SchemeType);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{

View file

@ -3,121 +3,77 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Xml.Linq;
using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.OData.Properties;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class Authorization1Tests
public class AuthorizationTests
{
[Fact]
public void TermAttributeAttachedOnSecurityScheme()
public void CreateAuthorizationReturnsNullWithNullRecord()
{
OData.Vocabulary.Authorization.Authorization a = new Http();
// Arrange & Act
string qualifiedName = EdmVocabularyAnnotationExtensions.GetTermQualifiedName<Authorization>();
var authorization = OData.Vocabulary.Authorization.Authorization.CreateAuthorization(record: null);
// Assert
Assert.Equal("Org.OData.Authorization.V1.SecuritySchemes", qualifiedName);
Assert.Null(authorization);
}
[Fact]
public void InitializeSecuritySchemeWithRecordSuccess()
public void CreateAuthorizationThrowsForOAuthAuthorizationRecord()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Authorization", new EdmStringConstant("DelegatedWork")),
new EdmPropertyConstructor("RequiredScopes", new EdmCollectionExpression(
new EdmStringConstant("User.ReadAll"),
new EdmStringConstant("User.WriteAll"))));
// Arrange & Act
IEdmStructuredTypeReference structuredTypeRef = GetType("Org.OData.Authorization.V1.OAuthAuthorization");
IEdmRecordExpression record = new EdmRecordExpression(structuredTypeRef,
new EdmPropertyConstructor("Name", new EdmStringConstant("temp")));
SecurityScheme securityScheme = new SecurityScheme();
Assert.Null(securityScheme.Authorization);
Assert.Null(securityScheme.RequiredScopes);
// Act
securityScheme.Initialize(record);
Action test = () => OData.Vocabulary.Authorization.Authorization.CreateAuthorization(record);
// Assert
Assert.NotNull(securityScheme.Authorization);
Assert.Equal("DelegatedWork", securityScheme.Authorization);
Assert.NotNull(securityScheme.RequiredScopes);
Assert.Equal(2, securityScheme.RequiredScopes.Count);
Assert.Equal(new[] { "User.ReadAll", "User.WriteAll" }, securityScheme.RequiredScopes);
OpenApiException exception = Assert.Throws<OpenApiException>(test);
Assert.Equal(String.Format(SRResource.AuthorizationRecordTypeNameNotCorrect, structuredTypeRef.FullName()), exception.Message);
}
[Fact]
public void InitializeSecuritySchemeWorksWithCsdl()
[Theory]
[InlineData(typeof(OpenIDConnect))]
[InlineData(typeof(Http))]
[InlineData(typeof(ApiKey))]
[InlineData(typeof(OAuth2ClientCredentials))]
[InlineData(typeof(OAuth2Implicit))]
[InlineData(typeof(OAuth2Password))]
[InlineData(typeof(OAuth2AuthCode))]
public void CreateAuthorizationReturnsOpenIDConnect(Type type)
{
// Arrange
string annotation = @"<Annotation Term=""Org.OData.Authorization.V1.SecuritySchemes"">
<Collection>
<Record>
<PropertyValue Property=""Authorization"" String=""DelegatedWork"" />
<PropertyValue Property=""RequiredScopes"" >
<Collection>
<String>User.ReadAll</String>
<String>User.WriteAll</String>
</Collection>
</PropertyValue>
</Record>
<Record>
<PropertyValue Property=""Authorization"" String=""DelegatedPersonal"" />
<PropertyValue Property=""RequiredScopes"" >
<Collection>
<String>Directory.ReadAll</String>
<String>Directory.WriteAll</String>
</Collection>
</PropertyValue>
</Record>
</Collection>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
SecurityScheme[] schemes = model.GetCollection<SecurityScheme>(model.EntityContainer).ToArray();
// Arrange & Act
string qualifiedName = AuthorizationConstants.Namespace + "." + type.Name;
IEdmRecordExpression record = new EdmRecordExpression(GetType(qualifiedName),
new EdmPropertyConstructor("Name", new EdmStringConstant("temp")));
// Assert
Assert.NotNull(schemes);
Assert.Equal(2, schemes.Length);
var authorization = OData.Vocabulary.Authorization.Authorization.CreateAuthorization(record);
Assert.NotNull(authorization);
Assert.Equal(type, authorization.GetType());
// #1
Assert.Equal("DelegatedWork", schemes[0].Authorization);
Assert.Equal(2, schemes[0].RequiredScopes.Count);
Assert.Equal(new[] { "User.ReadAll", "User.WriteAll" }, schemes[0].RequiredScopes);
// #2
Assert.Equal("DelegatedPersonal", schemes[1].Authorization);
Assert.Equal(2, schemes[1].RequiredScopes.Count);
Assert.Equal(new[] { "Directory.ReadAll", "Directory.WriteAll" }, schemes[1].RequiredScopes);
Assert.Equal("temp", authorization.Name);
Assert.Null(authorization.Description);
}
private IEdmModel GetEdmModel(string annotation)
private static IEdmStructuredTypeReference GetType(string qualifiedName)
{
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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
EdmModel model = new EdmModel();
IEdmType edmType = model.FindType(qualifiedName);
Assert.NotNull(edmType);
IEdmModel model;
IEdmComplexType complexType = edmType as IEdmComplexType;
Assert.NotNull(complexType);
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
return new EdmComplexTypeReference(complexType, true);
}
}
}

View file

@ -24,7 +24,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
EdmEntityContainer container = new EdmEntityContainer("NS", "Container");
model.AddElement(container);
// Act & Assert
// Act
var authorizations = model.GetAuthorizations(container);
// Assert

View file

@ -0,0 +1,111 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class HttpTests
{
[Fact]
public void SchemeTypeKindSetCorrectly()
{
// Arrange
Http http = new Http();
// Act & Assert
Assert.Equal(SecuritySchemeType.Http, http.SchemeType);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new Http().Initialize(record: null));
}
[Fact]
public void InitializeHttpWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("HttpWork")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Description of the scheme")),
new EdmPropertyConstructor("Scheme", new EdmStringConstant("Authorization scheme")),
new EdmPropertyConstructor("BearerFormat", new EdmStringConstant("Format of the bearer token")));
Http http = new Http();
Assert.Null(http.Name);
Assert.Null(http.Description);
Assert.Null(http.Scheme);
Assert.Null(http.BearerFormat);
// Act
http.Initialize(record);
// Assert
Assert.Equal("HttpWork", http.Name);
Assert.Equal("Description of the scheme", http.Description);
Assert.Equal("Authorization scheme", http.Scheme);
Assert.Equal("Format of the bearer token", http.BearerFormat);
}
[Fact]
public void InitializeHttpWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyHttp"">
<Record >
<PropertyValue Property=""Name"" String=""HttpWork"" />
<PropertyValue Property=""Scheme"" String=""Authorization scheme"" />
<PropertyValue Property=""BearerFormat"" String=""Format of the bearer token"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
Http http = model.GetRecord<Http>(model.EntityContainer, "NS.MyHttp");
// Assert
Assert.NotNull(http);
Assert.Equal("HttpWork", http.Name);
Assert.Null(http.Description);
Assert.Equal("Authorization scheme", http.Scheme);
Assert.Equal("Format of the bearer token", http.BearerFormat);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyHttp"" Type=""Org.OData.Authorization.V1.Http"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,110 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class OAuth2AuthCodeTests
{
[Fact]
public void SchemeTypeKindAndOAuthTypeSetCorrectly()
{
// Arrange
OAuth2AuthCode authCode = new OAuth2AuthCode();
// Act & Assert
Assert.Equal(SecuritySchemeType.OAuth2, authCode.SchemeType);
Assert.Equal(OAuth2Type.AuthCode, authCode.OAuth2Type);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new OAuth2AuthCode().Initialize(record: null));
}
[Fact]
public void InitializeOAuth2AuthCodeWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("TokenUrl", new EdmStringConstant("http://tokenUrl")),
new EdmPropertyConstructor("AuthorizationUrl", new EdmStringConstant("http://authorizationUrl")));
OAuth2AuthCode authCode = new OAuth2AuthCode();
Assert.Null(authCode.Name);
Assert.Null(authCode.Description);
Assert.Null(authCode.Scopes);
Assert.Null(authCode.AuthorizationUrl);
Assert.Null(authCode.TokenUrl);
// Act
authCode.Initialize(record);
// Assert
Assert.Null(authCode.Name);
Assert.Null(authCode.Description);
Assert.Null(authCode.Scopes);
Assert.Equal("http://authorizationUrl", authCode.AuthorizationUrl);
Assert.Equal("http://tokenUrl", authCode.TokenUrl);
}
[Fact]
public void InitializeOAuth2AuthCodeWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOAuth2AuthCode"">
<Record >
<PropertyValue Property=""TokenUrl"" String=""http://tokenUrl"" />
<PropertyValue Property=""AuthorizationUrl"" String=""http://authorizationUrl"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
OAuth2AuthCode authoCode = model.GetRecord<OAuth2AuthCode>(model.EntityContainer, "NS.MyOAuth2AuthCode");
// Assert
Assert.Null(authoCode.Name);
Assert.Null(authoCode.Description);
Assert.Null(authoCode.Scopes);
Assert.Equal("http://tokenUrl", authoCode.TokenUrl);
Assert.Equal("http://authorizationUrl", authoCode.AuthorizationUrl);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyOAuth2AuthCode"" Type=""Org.OData.Authorization.V1.OAuth2AuthCode"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,105 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class OAuth2ClientCredentialsTests
{
[Fact]
public void SchemeTypeKindAndOAuthTypeSetCorrectly()
{
// Arrange
OAuth2ClientCredentials credentials = new OAuth2ClientCredentials();
// Act & Assert
Assert.Equal(SecuritySchemeType.OAuth2, credentials.SchemeType);
Assert.Equal(OAuth2Type.ClientCredentials, credentials.OAuth2Type);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new OAuth2ClientCredentials().Initialize(record: null));
}
[Fact]
public void InitializeOAuth2ClientCredentialsWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("TokenUrl", new EdmStringConstant("http://tokenUrl")));
OAuth2ClientCredentials credentials = new OAuth2ClientCredentials();
Assert.Null(credentials.Name);
Assert.Null(credentials.Description);
Assert.Null(credentials.Scopes);
Assert.Null(credentials.TokenUrl);
// Act
credentials.Initialize(record);
// Assert
Assert.Null(credentials.Name);
Assert.Null(credentials.Description);
Assert.Null(credentials.Scopes);
Assert.Equal("http://tokenUrl", credentials.TokenUrl);
}
[Fact]
public void InitializeOAuth2ClientCredentialsWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOAuth2ClientCredentials"">
<Record >
<PropertyValue Property=""TokenUrl"" String=""http://tokenUrl"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
OAuth2ClientCredentials credentials = model.GetRecord<OAuth2ClientCredentials>(model.EntityContainer, "NS.MyOAuth2ClientCredentials");
// Assert
Assert.Null(credentials.Name);
Assert.Null(credentials.Description);
Assert.Null(credentials.Scopes);
Assert.Equal("http://tokenUrl", credentials.TokenUrl);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyOAuth2ClientCredentials"" Type=""Org.OData.Authorization.V1.OAuth2ClientCredentials"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,105 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class OAuth2ImplicitTests
{
[Fact]
public void SchemeTypeKindAndOAuthTypeSetCorrectly()
{
// Arrange
OAuth2Implicit oAuthImplicit = new OAuth2Implicit();
// Act & Assert
Assert.Equal(SecuritySchemeType.OAuth2, oAuthImplicit.SchemeType);
Assert.Equal(OAuth2Type.Implicit, oAuthImplicit.OAuth2Type);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new OAuth2Implicit().Initialize(record: null));
}
[Fact]
public void InitializeOAuth2ImplicitWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("AuthorizationUrl", new EdmStringConstant("http://authorizationUrl")));
OAuth2Implicit oAuthImplicit = new OAuth2Implicit();
Assert.Null(oAuthImplicit.Name);
Assert.Null(oAuthImplicit.Description);
Assert.Null(oAuthImplicit.Scopes);
Assert.Null(oAuthImplicit.AuthorizationUrl);
// Act
oAuthImplicit.Initialize(record);
// Assert
Assert.Null(oAuthImplicit.Name);
Assert.Null(oAuthImplicit.Description);
Assert.Null(oAuthImplicit.Scopes);
Assert.Equal("http://authorizationUrl", oAuthImplicit.AuthorizationUrl);
}
[Fact]
public void InitializeOAuth2ImplicitWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOAuth2Implicit"">
<Record >
<PropertyValue Property=""AuthorizationUrl"" String=""http://authorizationUrl"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
OAuth2Implicit oAuthImplicit = model.GetRecord<OAuth2Implicit>(model.EntityContainer, "NS.MyOAuth2Implicit");
// Assert
Assert.Null(oAuthImplicit.Name);
Assert.Null(oAuthImplicit.Description);
Assert.Null(oAuthImplicit.Scopes);
Assert.Equal("http://authorizationUrl", oAuthImplicit.AuthorizationUrl);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyOAuth2Implicit"" Type=""Org.OData.Authorization.V1.OAuth2Implicit"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,110 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class OAuth2PasswordTests
{
[Fact]
public void SchemeTypeKindAndOAuthTypeSetCorrectly()
{
// Arrange
OAuth2Password password = new OAuth2Password();
// Act & Assert
Assert.Equal(SecuritySchemeType.OAuth2, password.SchemeType);
Assert.Equal(OAuth2Type.Pasword, password.OAuth2Type);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new OAuth2Password().Initialize(record: null));
}
[Fact]
public void InitializeOAuth2PasswordWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("RefreshUrl", new EdmStringConstant("http://refreshUrl")),
new EdmPropertyConstructor("TokenUrl", new EdmStringConstant("http://tokenUrl")));
OAuth2Password password = new OAuth2Password();
Assert.Null(password.Name);
Assert.Null(password.Description);
Assert.Null(password.Scopes);
Assert.Null(password.RefreshUrl);
Assert.Null(password.TokenUrl);
// Act
password.Initialize(record);
// Assert
Assert.Null(password.Name);
Assert.Null(password.Description);
Assert.Null(password.Scopes);
Assert.Equal("http://refreshUrl", password.RefreshUrl);
Assert.Equal("http://tokenUrl", password.TokenUrl);
}
[Fact]
public void InitializeOAuth2PasswordWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOAuth2Password"">
<Record >
<PropertyValue Property=""RefreshUrl"" String=""http://refreshUrl"" />
<PropertyValue Property=""TokenUrl"" String=""http://tokenUrl"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
OAuth2Password password = model.GetRecord<OAuth2Password>(model.EntityContainer, "NS.MyOAuth2Password");
// Assert
Assert.Null(password.Name);
Assert.Null(password.Description);
Assert.Null(password.Scopes);
Assert.Equal("http://refreshUrl", password.RefreshUrl);
Assert.Equal("http://tokenUrl", password.TokenUrl);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyOAuth2Password"" Type=""Org.OData.Authorization.V1.OAuth2Password"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,102 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
{
public class OpenIDConnectTests
{
[Fact]
public void SchemeTypeKindSetCorrectly()
{
// Arrange
OpenIDConnect openIDConnect = new OpenIDConnect();
// Act & Assert
Assert.Equal(SecuritySchemeType.OpenIdConnect, openIDConnect.SchemeType);
}
[Fact]
public void InitializeThrowArgumentNullRecord()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("record", () => new OpenIDConnect().Initialize(record: null));
}
[Fact]
public void InitializeOpenIDConnectWithRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("OpenIDConnectWork")),
new EdmPropertyConstructor("IssuerUrl", new EdmStringConstant("http://any")));
OpenIDConnect idConnection = new OpenIDConnect();
Assert.Null(idConnection.Name);
Assert.Null(idConnection.Description);
Assert.Null(idConnection.IssuerUrl);
// Act
idConnection.Initialize(record);
// Assert
Assert.Equal("OpenIDConnectWork", idConnection.Name);
Assert.Null(idConnection.Description);
Assert.Equal("http://any", idConnection.IssuerUrl);
}
[Fact]
public void InitializeOpenIDConnectWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOpenIDConnect"">
<Record >
<PropertyValue Property=""IssuerUrl"" String=""http://any"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
OpenIDConnect idConnection = model.GetRecord<OpenIDConnect>(model.EntityContainer, "NS.MyOpenIDConnect");
// Assert
Assert.Null(idConnection.Name);
Assert.Null(idConnection.Description);
Assert.Equal("http://any", idConnection.IssuerUrl);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyOpenIDConnect"" Type=""Org.OData.Authorization.V1.OpenIDConnect"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -9,6 +9,7 @@ using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Authorization;
using Xunit;
@ -28,7 +29,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Authorization.Tests
public void TermAttributeAttachedOnSecurityScheme()
{
// Arrange & Act
string qualifiedName = EdmVocabularyAnnotationExtensions.GetTermQualifiedName<SecurityScheme>();
string qualifiedName = Utils.GetTermQualifiedName<SecurityScheme>();
// Assert
Assert.Equal("Org.OData.Authorization.V1.SecuritySchemes", qualifiedName);

View file

@ -0,0 +1,78 @@
// ------------------------------------------------------------
// 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.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class CollectionPropertyRestrictionsTypeTests
{
[Fact]
public void TermAttributeAttachedOnCollectionPropertyRestrictionsType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<CollectionPropertyRestrictionsType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.CollectionPropertyRestrictions", qualifiedName);
}
[Fact]
public void InitializeCollectionPropertyRestrictionsTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("CollectionProperty", new EdmPropertyPathExpression("abc/xyz")),
new EdmPropertyConstructor("FilterFunctions", new EdmCollectionExpression(new EdmStringConstant("div"))),
new EdmPropertyConstructor("FilterRestrictions", new EdmRecordExpression(new EdmPropertyConstructor("Filterable", new EdmBooleanConstant(true)))),
new EdmPropertyConstructor("SearchRestrictions", new EdmRecordExpression(new EdmPropertyConstructor("Searchable", new EdmBooleanConstant(false)))),
new EdmPropertyConstructor("SortRestrictions", new EdmRecordExpression(new EdmPropertyConstructor("Sortable", new EdmBooleanConstant(false)))),
new EdmPropertyConstructor("TopSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("Deletable", new EdmBooleanConstant(false))
// SkipSupported
// SelectSupport
// Insertable
// Updatable
);
// Act
CollectionPropertyRestrictionsType collectionPropertyRestrictions = new CollectionPropertyRestrictionsType();
collectionPropertyRestrictions.Initialize(record);
// Assert
Assert.Null(collectionPropertyRestrictions.SkipSupported);
Assert.Null(collectionPropertyRestrictions.SelectSupport);
Assert.Null(collectionPropertyRestrictions.Insertable);
Assert.Null(collectionPropertyRestrictions.Updatable);
Assert.Equal("abc/xyz", collectionPropertyRestrictions.CollectionProperty);
Assert.NotNull(collectionPropertyRestrictions.FilterFunctions);
string function = Assert.Single(collectionPropertyRestrictions.FilterFunctions);
Assert.Equal("div", function);
Assert.NotNull(collectionPropertyRestrictions.FilterRestrictions);
Assert.NotNull(collectionPropertyRestrictions.FilterRestrictions.Filterable);
Assert.True(collectionPropertyRestrictions.FilterRestrictions.Filterable.Value);
Assert.NotNull(collectionPropertyRestrictions.SearchRestrictions);
Assert.NotNull(collectionPropertyRestrictions.SearchRestrictions.Searchable);
Assert.False(collectionPropertyRestrictions.SearchRestrictions.Searchable.Value);
Assert.NotNull(collectionPropertyRestrictions.SortRestrictions);
Assert.NotNull(collectionPropertyRestrictions.SortRestrictions.Sortable);
Assert.False(collectionPropertyRestrictions.SortRestrictions.Sortable.Value);
Assert.NotNull(collectionPropertyRestrictions.TopSupported);
Assert.True(collectionPropertyRestrictions.TopSupported.Value);
Assert.NotNull(collectionPropertyRestrictions.Deletable);
Assert.False(collectionPropertyRestrictions.Deletable.Value);
}
}
}

View file

@ -5,7 +5,8 @@
using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -15,87 +16,41 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class CountRestrictionsTypeTests
{
[Fact]
public void CountRestrictionsTypeAsTermQualifiedName()
public void TermAttributeAttachedOnCountRestrictionsType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<CountRestrictionsType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.CountRestrictions", qualifiedName);
}
[Fact]
public void PropertiesAsNullForDefaultCountRestrictionsType()
public void InitializeCountRestrictionsTypeWithRecordSuccess()
{
// Arrange & Act
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Countable", new EdmBooleanConstant(false) ),
new EdmPropertyConstructor("NonCountableProperties", new EdmCollectionExpression(
new EdmPropertyPathExpression("Emails"),
new EdmPropertyPathExpression("mij"))),
new EdmPropertyConstructor("NonCountableNavigationProperties", new EdmCollectionExpression(
new EdmNavigationPropertyPathExpression("RelatedEvents"),
new EdmNavigationPropertyPathExpression("abc")))
);
// Act
CountRestrictionsType count = new CountRestrictionsType();
count.Initialize(record);
// Assert
Assert.Null(count.Countable);
Assert.Null(count.NonCountableProperties);
Assert.Null(count.NonCountableNavigationProperties);
VerifyCountRestrictions(count);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
{
// Arrange & Act
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Act
CountRestrictionsType count = EdmCoreModel.Instance.GetRecord<CountRestrictionsType>(entityType);
// Assert
Assert.Null(count);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectCountRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
public void InitializeCountRestrictionsWorksWithCsdl()
{
// Arrange
const string template = @"
<Annotations Target=""NS.Calendar"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
CountRestrictionsType count = model.GetRecord<CountRestrictionsType>(calendars);
// Assert
VerifyCountRestrictions(count);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntitySetReturnsCorrectCountRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
CountRestrictionsType count = model.GetRecord<CountRestrictionsType>(calendars);
// Assert
VerifyCountRestrictions(count);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string countAnnotation = @"
<Annotation Term=""Org.OData.Capabilities.V1.CountRestrictions"" >
<Record>
@ -115,15 +70,17 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
</Record>
</Annotation>";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
countAnnotation = string.Format(template, countAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
}
IEdmModel model = CapabilitiesModelHelper.GetEdmModelSetInline(countAnnotation);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
CountRestrictionsType count = model.GetRecord<CountRestrictionsType>(calendars);
// Assert
VerifyCountRestrictions(count);
}
private static void VerifyCountRestrictions(CountRestrictionsType count)

View file

@ -0,0 +1,126 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.IO;
using System.Xml;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Microsoft.OpenApi.OData.Vocabulary.Core;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class CustomParameterTests
{
[Fact]
public void InitializeCustomParameterWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("odata-debug")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Debug support for OData services")),
new EdmPropertyConstructor("DocumentationURL", new EdmStringConstant("https://debug.html")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("ExampleValues",
new EdmCollectionExpression(
new EdmRecordExpression(new EdmPropertyConstructor("Value", new EdmStringConstant("html"))),
new EdmRecordExpression(new EdmPropertyConstructor("Value", new EdmTimeOfDayConstant(new TimeOfDay(3, 4, 5, 6)))))));
// Act
CustomParameter parameter = new CustomParameter();
parameter.Initialize(record);
// Assert
VerifyCustomParameter(parameter);
}
[Fact]
public void InitializeCountRestrictionsWorksWithCsdl()
{
// Arrange
string annotation = @"
<Annotation Term=""NS.MyCustomParameter"" >
<Record>
<PropertyValue Property=""Name"" String=""odata-debug"" />
<PropertyValue Property=""Description"" String=""Debug support for OData services"" />
<PropertyValue Property=""DocumentationURL"" String=""https://debug.html"" />
<PropertyValue Property=""Required"" Bool=""false"" />
<PropertyValue Property=""ExampleValues"">
<Collection>
<Record>
<PropertyValue Property=""Value"" String=""html"" />
</Record>
<Record>
<PropertyValue Property=""Value"" TimeOfDay=""3:4:5.006"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
// Act
CustomParameter count = model.GetRecord<CustomParameter>(model.EntityContainer, "NS.MyCustomParameter");
// Assert
VerifyCustomParameter(count);
}
private static void VerifyCustomParameter(CustomParameter parameter)
{
Assert.NotNull(parameter);
Assert.NotNull(parameter.Name);
Assert.Equal("odata-debug", parameter.Name);
Assert.NotNull(parameter.Description);
Assert.Equal("Debug support for OData services", parameter.Description);
Assert.NotNull(parameter.DocumentationURL);
Assert.Equal("https://debug.html", parameter.DocumentationURL);
Assert.NotNull(parameter.Required);
Assert.False(parameter.Required.Value);
Assert.NotNull(parameter.ExampleValues);
Assert.Equal(2, parameter.ExampleValues.Count);
// #1
PrimitiveExampleValue value = parameter.ExampleValues[0];
Assert.Null(value.Description);
Assert.NotNull(value.Value);
Assert.Equal("html", value.Value.Value);
// #2
value = parameter.ExampleValues[1];
Assert.Null(value.Description);
Assert.NotNull(value.Value);
Assert.Equal(new TimeOfDay(3, 4, 5, 6), value.Value.Value);
}
private IEdmModel GetEdmModel(string annotation)
{
const string template = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
<Term Name=""MyCustomParameter"" Type=""Org.OData.Capabilities.V1.CustomParameter"" />
</Schema>
";
string schema = string.Format(template, annotation);
IEdmModel model;
bool result = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(schema)) }, out model, out _);
Assert.True(result);
return model;
}
}
}

View file

@ -0,0 +1,79 @@
// ------------------------------------------------------------
// 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;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class DeepInsertSupportTypeTests
{
[Fact]
public void TermAttributeAttachedOnDeepInsertSupportType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<DeepInsertSupportType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.DeepInsertSupport", qualifiedName);
}
[Fact]
public void InitializeDeepInsertSupportTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Supported", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("ContentIDSupported", new EdmBooleanConstant(true)));
// Act
DeepInsertSupportType deepInsert = new DeepInsertSupportType();
deepInsert.Initialize(record);
// Assert
VerifyDeepInsertSupportType(deepInsert);
}
[Fact]
public void InitializeDeepInsertSupportTypeWorksWithCsdl()
{
// Arrange
string annotation = @"
<Annotation Term=""Org.OData.Capabilities.V1.DeepInsertSupport"" >
<Record>
<PropertyValue Property=""Supported"" Bool=""false"" />
<PropertyValue Property=""ContentIDSupported"" Bool=""true"" />
</Record>
</Annotation>";
IEdmModel model = CapabilitiesModelHelper.GetEdmModelSetInline(annotation);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
DeepInsertSupportType deepInsert = model.GetRecord<DeepInsertSupportType>(calendars);
// Assert
VerifyDeepInsertSupportType(deepInsert);
}
private static void VerifyDeepInsertSupportType(DeepInsertSupportType deepInsert)
{
Assert.NotNull(deepInsert);
Assert.NotNull(deepInsert.Supported);
Assert.False(deepInsert.Supported.Value);
Assert.NotNull(deepInsert.ContentIDSupported);
Assert.True(deepInsert.ContentIDSupported.Value);
}
}
}

View file

@ -0,0 +1,79 @@
// ------------------------------------------------------------
// 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;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class DeepUpdateSupportTypeTests
{
[Fact]
public void TermAttributeAttachedOnDeepUpdateSupportType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<DeepUpdateSupportType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.DeepUpdateSupport", qualifiedName);
}
[Fact]
public void InitializeDeepUpdateSupportTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Supported", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("ContentIDSupported", new EdmBooleanConstant(true)));
// Act
DeepUpdateSupportType deepUpdate = new DeepUpdateSupportType();
deepUpdate.Initialize(record);
// Assert
VerifyDeepUpdateSupportType(deepUpdate);
}
[Fact]
public void InitializeDeepUpdateSupportTypeWorksWithCsdl()
{
// Arrange
string annotation = @"
<Annotation Term=""Org.OData.Capabilities.V1.DeepUpdateSupport"" >
<Record>
<PropertyValue Property=""Supported"" Bool=""false"" />
<PropertyValue Property=""ContentIDSupported"" Bool=""true"" />
</Record>
</Annotation>";
IEdmModel model = CapabilitiesModelHelper.GetEdmModelSetInline(annotation);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
DeepUpdateSupportType deepUpdate = model.GetRecord<DeepUpdateSupportType>(calendars);
// Assert
VerifyDeepUpdateSupportType(deepUpdate);
}
private static void VerifyDeepUpdateSupportType(DeepUpdateSupportType deepUpdate)
{
Assert.NotNull(deepUpdate);
Assert.NotNull(deepUpdate.Supported);
Assert.False(deepUpdate.Supported.Value);
Assert.NotNull(deepUpdate.ContentIDSupported);
Assert.True(deepUpdate.ContentIDSupported.Value);
}
}
}

View file

@ -6,6 +6,8 @@
using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -15,26 +17,39 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class DeleteRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsDeleteRestrictionsEnumMember()
public void TermAttributeAttachedOnDeleteRestrictionsType()
{
// Arrange & Act
DeleteRestrictionsType delete = new DeleteRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<DeleteRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.DeleteRestrictions, delete.Kind);
Assert.Equal("Org.OData.Capabilities.V1.DeleteRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultDeleteRestrictionsValues()
public void InitializeDeleteRestrictionsTypeWithRecordSuccess()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Deletable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("NonDeletableNavigationProperties",
new EdmCollectionExpression(new EdmNavigationPropertyPathExpression("abc"), new EdmNavigationPropertyPathExpression("RelatedEvents"))),
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(42)),
new EdmPropertyConstructor("Permission", new EdmRecordExpression(
new EdmPropertyConstructor("Scheme", new EdmRecordExpression(new EdmPropertyConstructor("Authorization", new EdmStringConstant("schemeName")))))),
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(
new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("odata-debug")),
new EdmPropertyConstructor("DocumentationURL", new EdmStringConstant("https://debug.html")))))
// CustomHeaders
);
// Act
DeleteRestrictionsType delete = EdmCoreModel.Instance.GetRecord<DeleteRestrictionsType>(entityType);
// Act
DeleteRestrictionsType delete = new DeleteRestrictionsType();
delete.Initialize(record);
// Assert
Assert.Null(delete);
VerifyDeleteRestrictionsType(delete);
}
[Theory]
@ -58,7 +73,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
DeleteRestrictionsType delete = model.GetRecord<DeleteRestrictionsType>(calendars);
// Assert
VerifyDeleteRestrictions(delete);
VerifyDeleteRestrictionsType(delete);
}
[Theory]
@ -82,12 +97,12 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
DeleteRestrictionsType delete = model.GetRecord<DeleteRestrictionsType>(calendars);
// Assert
VerifyDeleteRestrictions(delete);
VerifyDeleteRestrictionsType(delete);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string countAnnotation = @"
string annotation = @"
<Annotation Term=""Org.OData.Capabilities.V1.DeleteRestrictions"" >
<Record>
<PropertyValue Property=""Deletable"" Bool=""false"" />
@ -97,21 +112,39 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
<NavigationPropertyPath>RelatedEvents</NavigationPropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property=""MaxLevels"" Int=""42"" />
<PropertyValue Property=""Permission"">
<Record>
<PropertyValue Property=""Scheme"" >
<Record>
<PropertyValue Property=""Authorization"" String=""schemeName"" />
</Record>
</PropertyValue>
</Record>
</PropertyValue>
<PropertyValue Property=""CustomQueryOptions"" >
<Collection>
<Record>
<PropertyValue Property=""Name"" String=""odata-debug"" />
<PropertyValue Property=""DocumentationURL"" String=""https://debug.html"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
countAnnotation = string.Format(template, countAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
annotation = string.Format(template, annotation);
return CapabilitiesModelHelper.GetEdmModelOutline(annotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
return CapabilitiesModelHelper.GetEdmModelTypeInline(annotation);
}
}
private static void VerifyDeleteRestrictions(DeleteRestrictionsType delete)
private static void VerifyDeleteRestrictionsType(DeleteRestrictionsType delete)
{
Assert.NotNull(delete);
@ -123,6 +156,16 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.Equal("abc|RelatedEvents", String.Join("|", delete.NonDeletableNavigationProperties));
Assert.True(delete.IsNonDeletableNavigationProperty("RelatedEvents"));
Assert.NotNull(delete.Permission);
Assert.Equal("schemeName", delete.Permission.Scheme.Authorization);
Assert.Null(delete.CustomHeaders);
Assert.NotNull(delete.CustomQueryOptions);
CustomParameter parameter = Assert.Single(delete.CustomQueryOptions);
Assert.Equal("odata-debug", parameter.Name);
Assert.Equal("https://debug.html", parameter.DocumentationURL);
}
}
}

View file

@ -6,6 +6,8 @@
using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -15,26 +17,32 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class ExpandRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsExpandRestrictionsEnumMember()
public void TermAttributeAttachedOnExpandRestrictionsType()
{
// Arrange & Act
ExpandRestrictionsType expand = new ExpandRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<ExpandRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.ExpandRestrictions, expand.Kind);
Assert.Equal("Org.OData.Capabilities.V1.ExpandRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultExpandRestrictionsValues()
public void InitializeExpandRestrictionsTypeWithRecordSuccess()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Expandable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("NonExpandableProperties",
new EdmCollectionExpression(new EdmNavigationPropertyPathExpression("abc"), new EdmNavigationPropertyPathExpression("RelatedEvents"))),
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(42))
);
// Act
ExpandRestrictionsType expand = EdmCoreModel.Instance.GetRecord<ExpandRestrictionsType>(entityType);
// Act
ExpandRestrictionsType expand = new ExpandRestrictionsType();
expand.Initialize(record);
// Assert
Assert.Null(expand);
VerifyExpandRestrictions(expand);
}
[Theory]
@ -91,6 +99,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
<Annotation Term=""Org.OData.Capabilities.V1.ExpandRestrictions"" >
<Record>
<PropertyValue Property=""Expandable"" Bool=""false"" />
<PropertyValue Property=""MaxLevels"" Int=""42"" />
<PropertyValue Property=""NonExpandableProperties"" >
<Collection>
<NavigationPropertyPath>abc</NavigationPropertyPath>
@ -118,6 +127,9 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.NotNull(expand.Expandable);
Assert.False(expand.Expandable.Value);
Assert.NotNull(expand.MaxLevels);
Assert.Equal(42, expand.MaxLevels.Value);
Assert.NotNull(expand.NonExpandableProperties);
Assert.Equal(2, expand.NonExpandableProperties.Count);
Assert.Equal("abc|RelatedEvents", String.Join("|", expand.NonExpandableProperties));

View file

@ -6,6 +6,8 @@
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -15,32 +17,41 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class FilterRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsFilterRestrictionsEnumMember()
public void TermAttributeAttachedOnFilterRestrictionsType()
{
// Arrange & Act
FilterRestrictionsType filter = new FilterRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<FilterRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.FilterRestrictions, filter.Kind);
Assert.Equal("Org.OData.Capabilities.V1.FilterRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultFilterRestrictionsValues()
public void InitializFilterRestrictionsTypeWithRecordSuccess()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Filterable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("RequiresFilter", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("RequiredProperties", new EdmCollectionExpression(new EdmPropertyPathExpression("Id"))),
new EdmPropertyConstructor("NonFilterableProperties", new EdmCollectionExpression(new EdmPropertyPathExpression("Emails"))),
new EdmPropertyConstructor("FilterExpressionRestrictions", new EdmCollectionExpression(
new EdmRecordExpression(new EdmPropertyConstructor("Property", new EdmPropertyPathExpression("RelatedProperty"))))),
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(42))
);
// Act
FilterRestrictionsType filter = EdmCoreModel.Instance.GetRecord<FilterRestrictionsType>(entityType);
// Act
FilterRestrictionsType filter = new FilterRestrictionsType();
filter.Initialize(record);
// Assert
Assert.Null(filter);
VerifyFilterRestrictions(filter);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectfilterRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
public void TargetOnEntityTypeReturnsCorrectFilterRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
@ -92,6 +103,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
<Record>
<PropertyValue Property=""Filterable"" Bool=""false"" />
<PropertyValue Property=""RequiresFilter"" Bool=""false"" />
<PropertyValue Property=""MaxLevels"" Int=""42"" />
<PropertyValue Property=""RequiredProperties"" >
<Collection>
<PropertyPath>Id</PropertyPath>
@ -102,6 +114,13 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
<PropertyPath>Emails</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property=""FilterExpressionRestrictions"" >
<Collection>
<Record>
<PropertyValue Property=""Property"" PropertyPath=""RelatedProperty"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
@ -134,6 +153,13 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.Single(filter.NonFilterableProperties);
Assert.Equal("Emails", filter.NonFilterableProperties.First());
Assert.NotNull(filter.MaxLevels);
Assert.Equal(42, filter.MaxLevels.Value);
Assert.NotNull(filter.FilterExpressionRestrictions);
FilterExpressionRestrictionType express = Assert.Single(filter.FilterExpressionRestrictions);
Assert.Equal("RelatedProperty", express.Property);
Assert.True(filter.IsRequiredProperty("Id"));
Assert.False(filter.IsRequiredProperty("ID"));

View file

@ -1,111 +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.OData.Edm.Csdl;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
{
#if false
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
bool result = index.Load(EdmCoreModel.Instance, entityType);
// Assert
Assert.False(result);
Assert.True(index.IsSupported);
Assert.Null(index.Supported);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectIndexableByKeyValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Calendar"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
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 TargetOnEntitySetReturnsCorrectIndexableByKeyValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
IndexableByKey index = new IndexableByKey();
bool result = index.Load(model, calendars);
// Assert
Assert.True(result);
Assert.NotNull(index.Supported);
Assert.False(index.Supported.Value);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.IndexableByKey"" Bool=""false"" />";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
countAnnotation = string.Format(template, countAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
}
}
}
#endif
}

View file

@ -7,9 +7,10 @@ using System;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Tests;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Microsoft.OpenApi.OData.Vocabulary.Core;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
@ -17,140 +18,46 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class InsertRestrictionsTypeTests
{
[Fact]
public void OkEdmModel()
public void TermAttributeAttachedOnInsertRestrictionsType()
{
// Arrange & Act
EdmModel model = new EdmModel();
EdmEntityType entity = new EdmEntityType("NS", "Entity");
entity.AddKeys(entity.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
model.AddElement(entity);
string qualifiedName = Utils.GetTermQualifiedName<InsertRestrictionsType>();
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
EdmEntitySet set = container.AddEntitySet("Entities", entity);
model.AddElement(container);
IEdmComplexType securitySchemeType = model.FindType("Org.OData.Authorization.V1.SecurityScheme") as IEdmComplexType;
IEdmRecordExpression securityScheme = new EdmRecordExpression(
new EdmComplexTypeReference(securitySchemeType, false),
new EdmPropertyConstructor("Authorization", new EdmStringConstant("authorizationName")),
new EdmPropertyConstructor("RequiredScopes", new EdmCollectionExpression(new EdmStringConstant("RequiredScopes1"), new EdmStringConstant("RequiredScopes2"))));
IEdmComplexType scopeType = model.FindType("Org.OData.Capabilities.V1.ScopeType") as IEdmComplexType;
IEdmRecordExpression scope1 = new EdmRecordExpression(
new EdmComplexTypeReference(scopeType, false),
new EdmPropertyConstructor("Scope", new EdmStringConstant("scopeName1")),
new EdmPropertyConstructor("RestrictedProperties", new EdmStringConstant("p1,p2")));
IEdmRecordExpression scope2 = new EdmRecordExpression(
new EdmComplexTypeReference(scopeType, false),
new EdmPropertyConstructor("Scope", new EdmStringConstant("scopeName2")),
new EdmPropertyConstructor("RestrictedProperties", new EdmStringConstant("p3,p4")));
IEdmComplexType permissionType = model.FindType("Org.OData.Capabilities.V1.PermissionType") as IEdmComplexType;
IEdmRecordExpression permission = new EdmRecordExpression(
new EdmComplexTypeReference(permissionType, false),
new EdmPropertyConstructor("Scheme", securityScheme),
new EdmPropertyConstructor("Scopes", new EdmCollectionExpression(scope1, scope2)));
IEdmComplexType complex = model.FindType("Org.OData.Capabilities.V1.InsertRestrictionsType") as IEdmComplexType;
IEdmCollectionExpression nonInsertableProperties = new EdmCollectionExpression
(
new EdmPathExpression("abc"),
new EdmPathExpression("xyz")
);
IEdmCollectionExpression nonInsertableNavigationProperties = new EdmCollectionExpression
(
new EdmNavigationPropertyPathExpression("nvabc"),
new EdmNavigationPropertyPathExpression("nvxyz")
);
IEdmRecordExpression queryOptions = new EdmRecordExpression(
new EdmPropertyConstructor("ExpandSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SelectSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ComputeSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("FilterSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SearchSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SortSupported", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("SortSupported", new EdmBooleanConstant(false)));
// Assert
Assert.Equal("Org.OData.Capabilities.V1.InsertRestrictions", qualifiedName);
}
[Fact]
public void InitializInsertRestrictionsTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression primitiveExampleValue = new EdmRecordExpression(
new EdmPropertyConstructor("Description", new EdmStringConstant("Description23")),
new EdmPropertyConstructor("Value", new EdmStringConstant("Value1")));
new EdmPropertyConstructor("Description", new EdmStringConstant("example desc")),
new EdmPropertyConstructor("Value", new EdmStringConstant("example value")));
IEdmRecordExpression customHeaders1 = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("HeadName1")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Description1")),
new EdmPropertyConstructor("ComputeSupported", new EdmStringConstant("http://any")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ExampleValues", new EdmCollectionExpression(primitiveExampleValue)));
IEdmRecordExpression customHeaders2 = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("HeadName2")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Description2")),
new EdmPropertyConstructor("ComputeSupported", new EdmStringConstant("http://any")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("ExampleValues", new EdmCollectionExpression(primitiveExampleValue)));
IEdmRecordExpression insertRecord = new EdmRecordExpression(
new EdmComplexTypeReference(complex, false),
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Insertable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("NonInsertableProperties", nonInsertableProperties),
new EdmPropertyConstructor("NonInsertableNavigationProperties", nonInsertableNavigationProperties),
new EdmPropertyConstructor("NonInsertableProperties", new EdmCollectionExpression(new EdmPathExpression("abc/xyz"))),
new EdmPropertyConstructor("NonInsertableNavigationProperties", new EdmCollectionExpression(new EdmNavigationPropertyPathExpression("abc"), new EdmNavigationPropertyPathExpression("RelatedEvents"))),
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(8)),
new EdmPropertyConstructor("Permission", permission),
new EdmPropertyConstructor("QueryOptions", queryOptions),
new EdmPropertyConstructor("CustomHeaders", new EdmCollectionExpression(customHeaders1, customHeaders2)),
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(customHeaders1, customHeaders2))
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(
new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("primitive name")),
new EdmPropertyConstructor("Description", new EdmStringConstant("primitive desc")),
new EdmPropertyConstructor("DocumentationURL", new EdmStringConstant("http://any3")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ExampleValues", new EdmCollectionExpression(primitiveExampleValue)))))
// QueryOptions
// Permission
// CustomHeaders
);
IEdmTerm term = model.FindTerm("Org.OData.Capabilities.V1.InsertRestrictions");
var annotation = new EdmVocabularyAnnotation(set, term, insertRecord);
annotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
model.SetVocabularyAnnotation(annotation);
// Assert
string csdl = EdmModelHelper.GetCsdl(model);
Assert.Equal("", csdl);
}
[Fact]
public void KindPropertyReturnsInsertRestrictionsEnumMember()
{
// Arrange & Act
InsertRestrictionsType insert = new InsertRestrictionsType();
// Assert
// Assert.Equal(CapabilitesTermKind.InsertRestrictions, insert.Kind);
}
[Fact]
public void KindPropertyReturnsInsertRestrictionsEnumMember2()
{
// Arrange
IEdmModel model = GetModelWithInsertRestrictions();
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Entities");
// Act
InsertRestrictionsType insert = model.GetRecord<InsertRestrictionsType>(entitySet);
InsertRestrictionsType insert = new InsertRestrictionsType();
insert.Initialize(record);
// Assert
//Assert.Equal(CapabilitesTermKind.InsertRestrictions, insert.Kind);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultInsertRestrictionsValues()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Act
InsertRestrictionsType insert = EdmCoreModel.Instance.GetRecord<InsertRestrictionsType>(entityType);
// Assert
Assert.Null(insert);
VerifyInsertRestrictions(insert);
}
[Theory]
@ -207,13 +114,36 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
<Annotation Term=""Org.OData.Capabilities.V1.InsertRestrictions"" >
<Record>
<PropertyValue Property=""Insertable"" Bool=""false"" />
<PropertyValue Property=""NonInsertableProperties"" >
<Collection>
<PropertyPath>abc/xyz</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property=""NonInsertableNavigationProperties"" >
<Collection>
<NavigationPropertyPath>abc</NavigationPropertyPath>
<NavigationPropertyPath>RelatedEvents</NavigationPropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property=""Insertable"" Bool=""false"" />
<PropertyValue Property=""MaxLevels"" Int=""8"" />
<PropertyValue Property=""CustomQueryOptions"" >
<Collection>
<Record>
<PropertyValue Property=""Name"" String=""primitive name"" />
<PropertyValue Property=""Description"" String=""primitive desc"" />
<PropertyValue Property=""DocumentationURL"" String=""http://any3"" />
<PropertyValue Property=""Required"" Bool=""true"" />
<PropertyValue Property=""ExampleValues"">
<Collection>
<Record>
<PropertyValue Property=""Description"" String=""example desc"" />
<PropertyValue Property=""Value"" String=""example value"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
@ -228,107 +158,6 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
}
}
public IEdmModel GetModelWithInsertRestrictions()
{
EdmModel model = new EdmModel();
IEdmRecordExpression securityScheme = new EdmRecordExpression(
new EdmPropertyConstructor("Authorization", new EdmStringConstant("authorizationName")),
new EdmPropertyConstructor("RequiredScopes", new EdmCollectionExpression(new EdmStringConstant("RequiredScopes1"), new EdmStringConstant("RequiredScopes2"))));
IEdmRecordExpression scope1 = new EdmRecordExpression(
new EdmPropertyConstructor("Scope", new EdmStringConstant("scopeName1")),
new EdmPropertyConstructor("RestrictedProperties", new EdmStringConstant("p1,p2")));
IEdmRecordExpression scope2 = new EdmRecordExpression(
new EdmPropertyConstructor("Scope", new EdmStringConstant("scopeName2")),
new EdmPropertyConstructor("RestrictedProperties", new EdmStringConstant("p3,p4")));
IEdmRecordExpression permission = new EdmRecordExpression(
new EdmPropertyConstructor("Scheme", securityScheme),
new EdmPropertyConstructor("Scopes", new EdmCollectionExpression(scope1, scope2)));
IEdmCollectionExpression nonInsertableProperties = new EdmCollectionExpression
(
new EdmPathExpression("abc"),
new EdmPathExpression("xyz")
);
IEdmCollectionExpression nonInsertableNavigationProperties = new EdmCollectionExpression
(
new EdmNavigationPropertyPathExpression("nvabc"),
new EdmNavigationPropertyPathExpression("nvxyz")
);
IEdmRecordExpression queryOptions = new EdmRecordExpression(
new EdmPropertyConstructor("ExpandSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SelectSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ComputeSupported", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("FilterSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SearchSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SortSupported", new EdmBooleanConstant(false)));
IEdmRecordExpression primitiveExampleValue = new EdmRecordExpression(
new EdmPropertyConstructor("Description", new EdmStringConstant("Description23")),
new EdmPropertyConstructor("Value", new EdmStringConstant("Value1")));
IEdmRecordExpression customHeaders1 = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("HeadName1")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Description1")),
new EdmPropertyConstructor("ComputeSupported", new EdmStringConstant("http://any")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ExampleValues", new EdmCollectionExpression(primitiveExampleValue)));
IEdmRecordExpression customHeaders2 = new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("HeadName2")),
new EdmPropertyConstructor("Description", new EdmStringConstant("Description2")),
new EdmPropertyConstructor("ComputeSupported", new EdmStringConstant("http://any")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("ExampleValues", new EdmCollectionExpression(primitiveExampleValue)));
/*
<ComplexType Name="InsertRestrictionsType">
<Property Name="Insertable" Type="Edm.Boolean" Nullable="false" DefaultValue="true" />
<Property Name="NonInsertableProperties" Type="Collection(Edm.PropertyPath)" Nullable="false" />
<Property Name="NonInsertableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)" Nullable="false" />
<Property Name="MaxLevels" Type="Edm.Int32" Nullable="false" DefaultValue="-1" />
<Property Name="Permission" Type="Capabilities.PermissionType" Nullable="true" />
<Property Name="QueryOptions" Type="Capabilities.ModificationQueryOptionsType" Nullable="true" />
<Property Name="CustomHeaders" Type="Collection(Capabilities.CustomParameter)" />
<Property Name="CustomQueryOptions" Type="Collection(Capabilities.CustomParameter)" />
</ComplexType>
*/
IEdmComplexType complex = model.FindType("Org.OData.Capabilities.V1.InsertRestrictionsType") as IEdmComplexType;
Assert.NotNull(complex);
EdmRecordExpression record = new EdmRecordExpression(
new EdmComplexTypeReference(complex, false),
new EdmPropertyConstructor("Insertable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("NonInsertableProperties", nonInsertableProperties),
new EdmPropertyConstructor("NonInsertableNavigationProperties", nonInsertableNavigationProperties),
new EdmPropertyConstructor("MaxLevels", new EdmIntegerConstant(8)),
new EdmPropertyConstructor("Permission", permission),
new EdmPropertyConstructor("QueryOptions", queryOptions),
new EdmPropertyConstructor("CustomHeaders", new EdmCollectionExpression(customHeaders1, customHeaders2)),
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(customHeaders2)));
EdmEntityType entity = new EdmEntityType("NS", "Entity");
entity.AddKeys(entity.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
model.AddElement(entity);
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
EdmEntitySet entities = container.AddEntitySet("Entities", entity);
model.AddElement(container);
IEdmTerm term = model.FindTerm("Org.OData.Capabilities.V1.InsertRestrictions");
Assert.NotNull(term);
var annotation = new EdmVocabularyAnnotation(entities, term, record);
annotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
model.SetVocabularyAnnotation(annotation);
return model;
}
private static void VerifyInsertRestrictions(InsertRestrictionsType insert)
{
Assert.NotNull(insert);
@ -342,6 +171,23 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.True(insert.IsNonInsertableNavigationProperty("RelatedEvents"));
Assert.False(insert.IsNonInsertableNavigationProperty("MyUnknownNavigationProperty"));
Assert.Null(insert.QueryOptions);
Assert.Null(insert.Permission);
Assert.Null(insert.CustomHeaders);
Assert.NotNull(insert.MaxLevels);
Assert.Equal(8, insert.MaxLevels.Value);
Assert.NotNull(insert.CustomQueryOptions);
CustomParameter parameter = Assert.Single(insert.CustomQueryOptions);
Assert.Equal("primitive name", parameter.Name);
Assert.Equal("http://any3", parameter.DocumentationURL);
Assert.NotNull(parameter.ExampleValues);
PrimitiveExampleValue example = Assert.Single(parameter.ExampleValues);
Assert.Equal("example desc", example.Description);
Assert.Equal("example value", example.Value.Value);
}
}
}

View file

@ -0,0 +1,114 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class ModificationQueryOptionsTypeTests
{
[Fact]
public void TermAttributeAttachedOnModificationQueryOptionsType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<ModificationQueryOptionsType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.ModificationQueryOptions", qualifiedName);
}
[Fact]
public void InitializInsertRestrictionsTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("ExpandSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("SelectSupported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("ComputeSupported", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("FilterSupported", new EdmBooleanConstant(true))
// SearchSupported
// SortSupported
);
// Act
ModificationQueryOptionsType query = new ModificationQueryOptionsType();
query.Initialize(record);
// Assert
VerifyModificationQueryOptions(query);
}
[Fact]
public void InitializeModificationQueryOptionsTypeWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.ModificationQueryOptions"">
<Record>
<PropertyValue Property=""ExpandSupported"" Bool=""true"" />
<PropertyValue Property=""SelectSupported"" Bool=""true"" />
<PropertyValue Property=""ComputeSupported"" Bool=""false"" />
<PropertyValue Property=""FilterSupported"" Bool=""true"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
ModificationQueryOptionsType query = model.GetRecord<ModificationQueryOptionsType>(model.EntityContainer);
// Assert
VerifyModificationQueryOptions(query);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
private static void VerifyModificationQueryOptions(ModificationQueryOptionsType query)
{
Assert.NotNull(query);
Assert.Null(query.SearchSupported);
Assert.Null(query.SortSupported);
Assert.NotNull(query.ExpandSupported);
Assert.True(query.ExpandSupported);
Assert.NotNull(query.SelectSupported);
Assert.True(query.SelectSupported);
Assert.NotNull(query.ComputeSupported);
Assert.False(query.ComputeSupported); // false
Assert.NotNull(query.FilterSupported);
Assert.True(query.FilterSupported);
}
}
}

View file

@ -6,6 +6,8 @@
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -15,26 +17,44 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class NavigationRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsNavigationRestrictionsEnumMember()
public void TermAttributeAttachedOnNavigationRestrictionsType()
{
// Arrange & Act
NavigationRestrictionsType navigation = new NavigationRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<NavigationRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.NavigationRestrictions, navigation.Kind);
Assert.Equal("Org.OData.Capabilities.V1.NavigationRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
public void InitializNavigationRestrictionsTypeWithRecordSuccess()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Assert
EdmModel model = new EdmModel();
IEdmEnumType navigationType = model.FindType("Org.OData.Capabilities.V1.NavigationType") as IEdmEnumType;
Assert.NotNull(navigationType);
IEdmRecordExpression restriction1 = new EdmRecordExpression(
new EdmPropertyConstructor("NavigationProperty", new EdmNavigationPropertyPathExpression("abc")),
new EdmPropertyConstructor("Navigability", new EdmEnumMemberExpression(navigationType.Members.First(c => c.Name == "Single"))),
new EdmPropertyConstructor("SkipSupported", new EdmBooleanConstant(false)));
IEdmRecordExpression restriction2 = new EdmRecordExpression(
new EdmPropertyConstructor("NavigationProperty", new EdmNavigationPropertyPathExpression("xyz")),
new EdmPropertyConstructor("Navigability", new EdmEnumMemberExpression(navigationType.Members.First(c => c.Name == "None"))),
new EdmPropertyConstructor("OptimisticConcurrencyControl", new EdmBooleanConstant(true)));
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Navigability", new EdmEnumMemberExpression(navigationType.Members.First(c => c.Name == "Recursive"))),
new EdmPropertyConstructor("RestrictedProperties", new EdmCollectionExpression(restriction1, restriction2))
);
// Act
NavigationRestrictionsType navigation = EdmCoreModel.Instance.GetRecord<NavigationRestrictionsType>(entityType);
NavigationRestrictionsType navigation = new NavigationRestrictionsType();
navigation.Initialize(record);
// Assert
Assert.Null(navigation);
VerifyNavigationRestrictions(navigation);
}
[Theory]
@ -43,40 +63,13 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public void TargetOnEntityTypeReturnsCorrectNavigationRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string outOfLineTemplate = @"
const string template = @"
<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/Single</EnumMember>
</PropertyValue>
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""abc"" />
</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);
}
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
@ -84,14 +77,7 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
NavigationRestrictionsType navigation = model.GetRecord<NavigationRestrictionsType>(calendars);
// Assert
Assert.NotNull(navigation.Navigability);
Assert.Equal(NavigationType.Recursive, navigation.Navigability.Value);
Assert.NotNull(navigation.RestrictedProperties);
NavigationPropertyRestriction navRestriction = Assert.Single(navigation.RestrictedProperties);
Assert.NotNull(navRestriction.Navigability);
Assert.Equal(NavigationType.Single, navRestriction.Navigability.Value);
Assert.Equal("abc", navRestriction.NavigationProperty);
VerifyNavigationRestrictions(navigation);
}
[Theory]
@ -100,46 +86,13 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public void TargetOnEntitySetReturnsCorrectNavigationRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string outOfLineTemplate = @"
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{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/Single</EnumMember>
</PropertyValue>
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""abc"" />
</Record>
<Record>
<PropertyValue Property=""Navigability"" >
<EnumMember>Org.OData.Capabilities.V1.NavigationType/None</EnumMember>
</PropertyValue>
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""xyz"" />
</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);
}
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
@ -156,6 +109,46 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.True(navigation.IsRestrictedProperty("xyz"));
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
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/Single</EnumMember>
</PropertyValue>
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""abc"" />
<PropertyValue Property=""SkipSupported"" Bool=""false"" />
</Record>
<Record>
<PropertyValue Property=""Navigability"" >
<EnumMember>Org.OData.Capabilities.V1.NavigationType/None</EnumMember>
</PropertyValue>
<PropertyValue Property=""NavigationProperty"" NavigationPropertyPath=""xyz"" />
<PropertyValue Property=""OptimisticConcurrencyControl"" Bool=""true"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
navigationAnnotation = string.Format(template, navigationAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(navigationAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(navigationAnnotation);
}
}
[Fact]
public void TargetWithUnknownEnumMemberDoesnotReturnsNavigationRestrictionsValue()
{
@ -193,11 +186,32 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
Assert.NotNull(navigation.RestrictedProperties);
Assert.Equal(2, navigation.RestrictedProperties.Count);
Assert.False(navigation.IsRestrictedProperty("abc"));
Assert.True(navigation.IsRestrictedProperty("xyz"));
// #1
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"));
Assert.NotNull(navRestriction.SkipSupported);
Assert.False(navRestriction.SkipSupported.Value);
Assert.Null(navRestriction.TopSupported);
Assert.Null(navRestriction.OptimisticConcurrencyControl);
// #2
navRestriction = navigation.RestrictedProperties.Last();
Assert.NotNull(navRestriction.Navigability);
Assert.Equal(NavigationType.None, navRestriction.Navigability.Value);
Assert.Equal("xyz", navRestriction.NavigationProperty);
Assert.Null(navRestriction.SkipSupported);
Assert.Null(navRestriction.TopSupported);
Assert.NotNull(navRestriction.OptimisticConcurrencyControl);
Assert.True(navRestriction.OptimisticConcurrencyControl.Value);
}
}
}

View file

@ -0,0 +1,123 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Linq;
using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class OperationRestrictionTypeTests
{
[Fact]
public void TermAttributeAttachedOnOperationRestrictionType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<OperationRestrictionType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.OperationRestrictions", qualifiedName);
}
[Fact]
public void InitializOperationRestrictionTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("CustomHeaders", new EdmCollectionExpression(
new EdmRecordExpression(
new EdmPropertyConstructor("Name", new EdmStringConstant("head name")),
new EdmPropertyConstructor("Description", new EdmStringConstant("head desc")),
new EdmPropertyConstructor("DocumentationURL", new EdmStringConstant("http://any3")),
new EdmPropertyConstructor("Required", new EdmBooleanConstant(true)))))
// Permission
// CustomQueryOptions
);
// Act
OperationRestrictionType operation = new OperationRestrictionType();
operation.Initialize(record);
// Assert
VerifyOperationRestrictions(operation);
}
[Fact]
public void InitializeModificationQueryOptionsTypeWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyOperationRestriction"">
<Record>
<PropertyValue Property=""CustomHeaders"" >
<Collection>
<Record>
<PropertyValue Property=""Name"" String=""head name"" />
<PropertyValue Property=""Description"" String=""head desc"" />
<PropertyValue Property=""DocumentationURL"" String=""http://any3"" />
<PropertyValue Property=""Required"" Bool=""true"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
IEdmOperation edmOperation = model.SchemaElements.OfType<IEdmFunction>().First();
Assert.NotNull(edmOperation);
// Act
OperationRestrictionType operation = model.GetRecord<OperationRestrictionType>(edmOperation, "NS.MyOperationRestriction");
// Assert
VerifyOperationRestrictions(operation);
}
private 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"">
<Function Name=""delta"" IsBound=""true"" >
<Parameter Name=""bindingParameter"" Type=""Edm.String"" />
<ReturnType Type=""Edm.String"" />
{0}
</Function>
<Term Name=""MyOperationRestriction"" Type=""Org.OData.Capabilities.V1.OperationRestriction"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
private static void VerifyOperationRestrictions(OperationRestrictionType operation)
{
Assert.NotNull(operation);
Assert.Null(operation.Permission);
Assert.Null(operation.CustomQueryOptions);
Assert.NotNull(operation.CustomHeaders);
CustomParameter parameter = Assert.Single(operation.CustomHeaders);
Assert.Equal("head name", parameter.Name);
Assert.Equal("http://any3", parameter.DocumentationURL);
Assert.Equal("head desc", parameter.Description);
Assert.True(parameter.Required.Value);
Assert.Null(parameter.ExampleValues);
}
}
}

View file

@ -0,0 +1,123 @@
// ------------------------------------------------------------
// 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.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class PermissionTypeTests
{
[Fact]
public void DefaultPropertyAsNull()
{
// Arrange & Act
PermissionType permission = new PermissionType();
// Assert
Assert.Null(permission.Scheme);
Assert.Null(permission.Scopes);
}
[Fact]
public void InitializeWithNullRecordThrows()
{
// Arrange & Act
PermissionType permission = new PermissionType();
// Assert
Assert.Throws<ArgumentNullException>("record", () => permission.Initialize(record: null));
}
[Fact]
public void InitializeWithPermissionTypeRecordSuccess()
{
// Arrange
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Scheme", new EdmRecordExpression(
new EdmPropertyConstructor("Authorization", new EdmStringConstant("scheme name")))),
new EdmPropertyConstructor("Scopes", new EdmCollectionExpression(new EdmRecordExpression(
new EdmPropertyConstructor("Scope", new EdmStringConstant("scope name"))))));
// Act
PermissionType permission = new PermissionType();
permission.Initialize(record);
// Assert
VerifyPermissionType(permission);
}
[Fact]
public void ScopeTypeTermValueInitializeWorksForScopeType()
{
// Arrange
string annotation = @"<Annotation Term=""NS.MyTerm"">
<Record>
<PropertyValue Property=""Scheme"">
<Record>
<PropertyValue Property=""Authorization"" String=""scheme name"" />
</Record>
</PropertyValue>
<PropertyValue Property=""Scopes"">
<Collection>
<Record>
<PropertyValue Property=""Scope"" String=""scope name"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
// Act
PermissionType permission = model.GetRecord<PermissionType>(model.EntityContainer, "NS.MyTerm");
// Assert
VerifyPermissionType(permission);
}
private 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"">
<EntityContainer Name =""Default"">
{0}
</EntityContainer>
<Term Name=""MyTerm"" Type=""Capabilities.PermissionType"" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
private static void VerifyPermissionType(PermissionType permission)
{
Assert.NotNull(permission);
Assert.NotNull(permission.Scheme);
Assert.Equal("scheme name", permission.Scheme.Authorization);
Assert.Null(permission.Scheme.RequiredScopes);
Assert.NotNull(permission.Scopes);
ScopeType scope = Assert.Single(permission.Scopes);
Assert.Equal("scope name", scope.Scope);
Assert.Null(scope.RestrictedProperties);
}
}
}

View file

@ -0,0 +1,173 @@
// ------------------------------------------------------------
// 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.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class ReadRestrictionsTypeTests
{
[Fact]
public void TermAttributeAttachedOnReadRestrictionsType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<ReadRestrictionsType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.ReadRestrictions", qualifiedName);
}
[Fact]
public void InitializReadRestrictionsTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Readable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("CustomQueryOptions", new EdmCollectionExpression(
new EdmRecordExpression(new EdmPropertyConstructor("Name", new EdmStringConstant("root query name"))))),
// Root Permission
// Root CustomHeaders
new EdmPropertyConstructor("ReadByKeyRestrictions", new EdmRecordExpression(
new EdmPropertyConstructor("Readable", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("CustomHeaders", new EdmCollectionExpression(
new EdmRecordExpression(new EdmPropertyConstructor("Name", new EdmStringConstant("by key head name")))))
// ByKey Permission
// ByKey CustomQueryOptions
))
);
// Act
ReadRestrictionsType read = new ReadRestrictionsType();
read.Initialize(record);
// Assert
VerifyReadRestrictions(read);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectReadRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Calendar"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
ReadRestrictionsType read = model.GetRecord<ReadRestrictionsType>(calendars);
// Assert
VerifyReadRestrictions(read);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntitySetReturnsCorrectReadRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
ReadRestrictionsType read = model.GetRecord<ReadRestrictionsType>(calendars);
// Assert
VerifyReadRestrictions(read);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string countAnnotation = @"
<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"" >
<Record>
<PropertyValue Property=""Readable"" Bool=""false"" />
<PropertyValue Property=""CustomQueryOptions"" >
<Collection>
<Record>
<PropertyValue Property=""Name"" String=""root query name"" />
</Record>
</Collection>
</PropertyValue>
<PropertyValue Property=""ReadByKeyRestrictions"">
<Record>
<PropertyValue Property=""Readable"" Bool=""true"" />
<PropertyValue Property=""CustomHeaders"" >
<Collection>
<Record>
<PropertyValue Property=""Name"" String=""by key head name"" />
</Record>
</Collection>
</PropertyValue>
</Record>
</PropertyValue>
</Record>
</Annotation>";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
countAnnotation = string.Format(template, countAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
}
}
private static void VerifyReadRestrictions(ReadRestrictionsType read)
{
Assert.NotNull(read);
Assert.NotNull(read.Readable);
Assert.False(read.Readable.Value);
Assert.Null(read.Permission);
Assert.Null(read.CustomHeaders);
Assert.NotNull(read.CustomQueryOptions);
CustomParameter parameter = Assert.Single(read.CustomQueryOptions);
Assert.Equal("root query name", parameter.Name);
Assert.Null(parameter.DocumentationURL);
Assert.Null(parameter.ExampleValues);
// ReadByKeyRestrictions
Assert.NotNull(read.ReadByKeyRestrictions);
Assert.NotNull(read.ReadByKeyRestrictions.Readable);
Assert.True(read.ReadByKeyRestrictions.Readable.Value);
Assert.Null(read.ReadByKeyRestrictions.Permission);
Assert.Null(read.ReadByKeyRestrictions.CustomQueryOptions);
Assert.NotNull(read.ReadByKeyRestrictions.CustomHeaders);
parameter = Assert.Single(read.ReadByKeyRestrictions.CustomHeaders);
Assert.Equal("by key head name", parameter.Name);
Assert.Null(parameter.DocumentationURL);
Assert.Null(parameter.ExampleValues);
}
}
}

View file

@ -5,6 +5,8 @@
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -14,26 +16,38 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class SearchRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsSearchRestrictionsEnumMember()
public void TermAttributeAttachedOnSearchRestrictionsType()
{
// Arrange & Act
SearchRestrictionsType search = new SearchRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<SearchRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.SearchRestrictions, search.Kind);
Assert.Equal("Org.OData.Capabilities.V1.SearchRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultPropertyValues()
public void InitializSearchRestrictionsTypeWithRecordSuccess()
{
// Arrange
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
// Assert
EdmModel model = new EdmModel();
IEdmEnumType searchExpressions = model.FindType("Org.OData.Capabilities.V1.SearchExpressions") as IEdmEnumType;
Assert.NotNull(searchExpressions);
// Act
SearchRestrictionsType search = EdmCoreModel.Instance.GetRecord<SearchRestrictionsType>(entityType);
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Searchable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("UnsupportedExpressions", new EdmEnumMemberExpression(
searchExpressions.Members.First(c => c.Name == "AND"),
searchExpressions.Members.First(c => c.Name == "OR")))
);
// Act
SearchRestrictionsType search = new SearchRestrictionsType();
search.Initialize(record);
// Assert
Assert.Null(search);
Assert.False(search.Searchable);
Assert.NotNull(search.UnsupportedExpressions);
Assert.Equal(SearchExpressions.AND | SearchExpressions.OR, search.UnsupportedExpressions.Value);
}
[Fact]

View file

@ -0,0 +1,113 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class SelectSupportTypeTests
{
[Fact]
public void TermAttributeAttachedOnSelectSupportType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<SelectSupportType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.SelectSupport", qualifiedName);
}
[Fact]
public void InitializSelectSupportTypeWithRecordSuccess()
{
// Assert
IEdmRecordExpression record = new EdmRecordExpression(
new EdmPropertyConstructor("Supported", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("Filterable", new EdmBooleanConstant(true)),
new EdmPropertyConstructor("Expandable", new EdmBooleanConstant(false)),
new EdmPropertyConstructor("Searchable", new EdmBooleanConstant(true))
// TopSupported
// SkipSupported
// ComputeSupported
// Countable
// Sortable
);
// Act
SelectSupportType select = new SelectSupportType();
select.Initialize(record);
// Assert
VerifySelectSupportType(select);
}
[Fact]
public void InitializeSelectSupportTypeTypeWorksWithCsdl()
{
// Arrange
string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.SelectSupport"">
<Record>
<PropertyValue Property=""Supported"" Bool=""true"" />
<PropertyValue Property=""Filterable"" Bool=""true"" />
<PropertyValue Property=""Expandable"" Bool=""false"" />
<PropertyValue Property=""Searchable"" Bool=""true"" />
</Record>
</Annotation>";
IEdmModel model = GetEdmModel(annotation);
Assert.NotNull(model); // guard
Assert.NotNull(model.EntityContainer);
// Act
SelectSupportType select = model.GetRecord<SelectSupportType>(model.EntityContainer);
// Assert
VerifySelectSupportType(select);
}
private 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"">
<EntityContainer Name=""Container"">
{0}
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out _);
Assert.True(result);
return model;
}
private static void VerifySelectSupportType(SelectSupportType select)
{
Assert.NotNull(select);
Assert.Null(select.TopSupported);
Assert.Null(select.SkipSupported);
Assert.Null(select.ComputeSupported);
Assert.Null(select.Countable);
Assert.Null(select.Sortable);
Assert.True(select.Supported);
Assert.False(select.Expandable);
Assert.True(select.Filterable);
Assert.True(select.Searchable);
}
}
}

View file

@ -1,113 +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 System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
{
#if false
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
bool result = skip.Load(EdmCoreModel.Instance, entityType);
// Assert
Assert.False(result);
Assert.True(skip.IsSupported);
Assert.Null(skip.Supported);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectSkipSupportedValue(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
// Act
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);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntitySetReturnsCorrectSkipSupportedValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
SkipSupported skip = new SkipSupported();
bool result = skip.Load(model, calendars);
// Assert
Assert.True(result);
Assert.NotNull(skip.Supported);
Assert.False(skip.Supported.Value);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.SkipSupported"" Bool=""false"" />";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
countAnnotation = string.Format(template, countAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
}
}
}
#endif
}

View file

@ -6,6 +6,7 @@
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -14,6 +15,16 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
{
public class SortRestrictionsTypeTests
{
[Fact]
public void TermAttributeAttachedOnSortRestrictionsType()
{
// Arrange & Act
string qualifiedName = Utils.GetTermQualifiedName<SortRestrictionsType>();
// Assert
Assert.Equal("Org.OData.Capabilities.V1.SortRestrictions", qualifiedName);
}
[Fact]
public void UnknownAnnotatableTargetReturnsDefaultSortRestrictionsValues()
{

View file

@ -1,114 +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 System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Xunit;
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
{
#if false
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
bool result = top.Load(EdmCoreModel.Instance, entityType);
// Assert
Assert.False(result);
Assert.True(top.IsSupported);
Assert.Null(top.Supported);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntityTypeReturnsCorrectTopSupportedValue(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
// Act
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);
}
[Theory]
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
public void TargetOnEntitySetReturnsCorrectTopSupportedValue(EdmVocabularyAnnotationSerializationLocation location)
{
// Arrange
const string template = @"
<Annotations Target=""NS.Default/Calendars"">
{0}
</Annotations>";
IEdmModel model = GetEdmModel(template, location);
Assert.NotNull(model); // guard
IEdmEntitySet calendars = model.EntityContainer.FindEntitySet("Calendars");
Assert.NotNull(calendars); // guard
// Act
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);
}
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
{
string topAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.TopSupported"" Bool=""false"" />";
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
{
topAnnotation = string.Format(template, topAnnotation);
return CapabilitiesModelHelper.GetEdmModelOutline(topAnnotation);
}
else
{
return CapabilitiesModelHelper.GetEdmModelTypeInline(topAnnotation);
}
}
}
#endif
}

View file

@ -7,6 +7,7 @@ using System;
using System.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
using Xunit;
@ -16,13 +17,13 @@ namespace Microsoft.OpenApi.OData.Reader.Vocabulary.Capabilities.Tests
public class UpdateRestrictionsTypeTests
{
[Fact]
public void KindPropertyReturnsUpdateRestrictionsEnumMember()
public void TermAttributeAttachedOnUpdateRestrictionsType()
{
// Arrange & Act
UpdateRestrictionsType update = new UpdateRestrictionsType();
string qualifiedName = Utils.GetTermQualifiedName<UpdateRestrictionsType>();
// Assert
// Assert.Equal(CapabilitesTermKind.UpdateRestrictions, update.Kind);
Assert.Equal("Org.OData.Capabilities.V1.UpdateRestrictions", qualifiedName);
}
[Fact]