modify FilterRestrictions and add unit tests
This commit is contained in:
parent
29b8a910ed
commit
b00cd0ee26
|
@ -15,11 +15,6 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// </summary>
|
||||
internal class FilterRestrictions : CapabilitiesRestrictions
|
||||
{
|
||||
private bool _filterable = true;
|
||||
private bool? _requiresFilter;
|
||||
private IList<string> _requiredProperties = new List<string>();
|
||||
private IList<string> _nonFilterableProperties = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// </summary>
|
||||
|
@ -28,50 +23,22 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <summary>
|
||||
/// Gets the Filterable value.
|
||||
/// </summary>
|
||||
public bool Filterable
|
||||
{
|
||||
get
|
||||
{
|
||||
Initialize();
|
||||
return _filterable;
|
||||
}
|
||||
}
|
||||
public bool? Filterable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RequiresFilter value.
|
||||
/// </summary>
|
||||
public bool? RequiresFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
Initialize();
|
||||
return _requiresFilter;
|
||||
}
|
||||
}
|
||||
public bool? RequiresFilter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties which must be specified in the $filter clause.
|
||||
/// </summary>
|
||||
public IList<string> RequiredProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
Initialize();
|
||||
return _requiredProperties;
|
||||
}
|
||||
}
|
||||
public IList<string> RequiredProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties which cannot be used in $filter expressions.
|
||||
/// </summary>
|
||||
public IList<string> NonFilterableProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
Initialize();
|
||||
return _nonFilterableProperties;
|
||||
}
|
||||
}
|
||||
public IList<string> NonFilterableProperties { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="FilterRestrictions"/> class.
|
||||
|
@ -90,7 +57,7 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <returns>True/False.</returns>
|
||||
public bool IsRequiredProperty(IEdmProperty property)
|
||||
{
|
||||
return RequiredProperties.Any(a => a == property.Name);
|
||||
return RequiredProperties != null ? RequiredProperties.Any(a => a == property.Name) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,7 +67,7 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
/// <returns>True/False.</returns>
|
||||
public bool IsNonFilterableProperty(IEdmProperty property)
|
||||
{
|
||||
return NonFilterableProperties.Any(a => a == property.Name);
|
||||
return NonFilterableProperties != null ? NonFilterableProperties.Any(a => a == property.Name) : false;
|
||||
}
|
||||
|
||||
protected override void Initialize(IEdmVocabularyAnnotation annotation)
|
||||
|
@ -114,13 +81,17 @@ namespace Microsoft.OpenApi.OData.Capabilities
|
|||
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)annotation.Value;
|
||||
|
||||
_filterable = SetBoolProperty(record, "Filterable", true);
|
||||
// Filterable
|
||||
Filterable = record.GetBoolean("Filterable");
|
||||
|
||||
_requiresFilter = SetBoolProperty(record, "RequiresFilter");
|
||||
// RequiresFilter
|
||||
RequiresFilter = record.GetBoolean("RequiresFilter");
|
||||
|
||||
_requiredProperties = GetCollectProperty(record, "RequiredProperties");
|
||||
// RequiredProperties
|
||||
RequiredProperties = record.GetCollectionPropertyPath("RequiredProperties");
|
||||
|
||||
_nonFilterableProperties = GetCollectNavigationProperty(record, "NonFilterableProperties");
|
||||
// NonFilterableProperties
|
||||
NonFilterableProperties = record.GetCollectionPropertyPath("NonFilterableProperties");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
FilterRestrictions filter = new FilterRestrictions(context.Model, target);
|
||||
if (filter.Filterable)
|
||||
if (filter.Filterable == null || filter.Filterable.Value)
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
// ------------------------------------------------------------
|
||||
// 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 Microsoft.OpenApi.OData.Capabilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
||||
{
|
||||
public class FilterRestrictionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void UnknownAnnotatableTargetReturnsDefaultFilterRestrictionsValues()
|
||||
{
|
||||
// Arrange
|
||||
EdmEntityType entityType = new EdmEntityType("NS", "Entity");
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(EdmCoreModel.Instance, entityType);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(CapabilitiesConstants.FilterRestrictions, filter.QualifiedName);
|
||||
Assert.Null(filter.Filterable);
|
||||
Assert.Null(filter.RequiresFilter);
|
||||
Assert.Null(filter.RequiredProperties);
|
||||
Assert.Null(filter.NonFilterableProperties);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnEntityTypeReturnsCorrectfilterRestrictionsValue(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
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnEntitySetReturnsCorrectFilterRestrictionsValue(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
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendars);
|
||||
|
||||
// Assert
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void TargetOnNavigationPropertyReturnsCorrectFilterRestrictionsValue(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar/RelatedEvents"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location, true);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // guard
|
||||
|
||||
IEdmNavigationProperty navigationProperty = calendar.DeclaredNavigationProperties().First(c => c.Name == "RelatedEvents");
|
||||
Assert.NotNull(navigationProperty); // guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, navigationProperty);
|
||||
|
||||
// Assert
|
||||
VerifyFilterRestrictions(filter);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.Inline)]
|
||||
[InlineData(EdmVocabularyAnnotationSerializationLocation.OutOfLine)]
|
||||
public void IsNonExpandablePropertyReturnsCorrectForProperty(EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
// Arrange
|
||||
const string template = @"
|
||||
<Annotations Target=""NS.Calendar"">
|
||||
{0}
|
||||
</Annotations>";
|
||||
|
||||
IEdmModel model = GetEdmModel(template, location);
|
||||
Assert.NotNull(model); // guard
|
||||
|
||||
IEdmEntityType calendar = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Calendar");
|
||||
Assert.NotNull(calendar); // Guard
|
||||
|
||||
IEdmProperty id = calendar.DeclaredStructuralProperties().First(c => c.Name == "Id");
|
||||
Assert.NotNull(id); // Guard
|
||||
|
||||
IEdmProperty emails = calendar.DeclaredStructuralProperties().First(c => c.Name == "Emails");
|
||||
Assert.NotNull(emails); // Guard
|
||||
|
||||
// Act
|
||||
FilterRestrictions filter = new FilterRestrictions(model, calendar);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(filter.Filterable);
|
||||
Assert.False(filter.Filterable.Value);
|
||||
Assert.NotNull(filter.RequiresFilter);
|
||||
Assert.False(filter.RequiresFilter.Value);
|
||||
|
||||
Assert.True(filter.IsRequiredProperty(id));
|
||||
Assert.True(filter.IsNonFilterableProperty(emails));
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location, bool navInLine = false)
|
||||
{
|
||||
string countAnnotation = @"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.FilterRestrictions"" >
|
||||
<Record>
|
||||
<PropertyValue Property=""Filterable"" Bool=""false"" />
|
||||
<PropertyValue Property=""RequiresFilter"" Bool=""false"" />
|
||||
<PropertyValue Property=""RequiredProperties"" >
|
||||
<Collection>
|
||||
<PropertyPath>Id</PropertyPath>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""NonFilterableProperties"" >
|
||||
<Collection>
|
||||
<PropertyPath>Emails</PropertyPath>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>";
|
||||
|
||||
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
|
||||
{
|
||||
countAnnotation = string.Format(template, countAnnotation);
|
||||
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (navInLine)
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelNavInline(countAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void VerifyFilterRestrictions(FilterRestrictions filter)
|
||||
{
|
||||
Assert.NotNull(filter);
|
||||
|
||||
Assert.NotNull(filter.Filterable);
|
||||
Assert.False(filter.Filterable.Value);
|
||||
|
||||
Assert.NotNull(filter.RequiresFilter);
|
||||
Assert.False(filter.RequiresFilter.Value);
|
||||
|
||||
Assert.NotNull(filter.RequiredProperties);
|
||||
Assert.Single(filter.RequiredProperties);
|
||||
Assert.Equal("Id", filter.RequiredProperties.First());
|
||||
|
||||
Assert.NotNull(filter.NonFilterableProperties);
|
||||
Assert.Single(filter.NonFilterableProperties);
|
||||
Assert.Equal("Emails", filter.NonFilterableProperties.First());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue