Skip to content

Commit 72bba88

Browse files
authored
Use directly annotated CountRestriction annotations when creating $count segments for col-valued navigation properties (#374)
* Get the directly annotated restriction annotation of the navigation property * Update tests and integration file * Update release notes * Add unit test
1 parent 59455f8 commit 72bba88

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,18 +484,28 @@ private void RetrieveNavigationPropertyPaths(
484484
{
485485
IEdmEntityType navEntityType = navigationProperty.ToEntityType();
486486
var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many;
487-
var propertyPath = navigationProperty.GetPartnerPath()?.Path;
488-
var propertyPathIsEmpty = string.IsNullOrEmpty(propertyPath);
489-
490-
if (targetsMany)
487+
488+
if (targetsMany)
491489
{
492-
if(propertyPathIsEmpty ||
493-
(count?.IsNonCountableNavigationProperty(propertyPath) ?? true))
490+
bool? createCountPath = null;
491+
if (count == null)
492+
{
493+
// First, get the directly annotated restriction annotation of the navigation property
494+
count = _model.GetRecord<CountRestrictionsType>(navigationProperty, CapabilitiesConstants.CountRestrictions);
495+
createCountPath = count?.Countable;
496+
}
497+
498+
var propertyPath = navigationProperty.GetPartnerPath()?.Path;
499+
createCountPath ??= string.IsNullOrEmpty(propertyPath)
500+
|| (count?.IsNonCountableNavigationProperty(propertyPath) ?? true);
501+
502+
if (createCountPath.Value)
494503
{
495504
// ~/entityset/{key}/collection-valued-Nav/$count
496505
CreateCountPath(currentPath, convertSettings);
497506
}
498507
}
508+
499509
// ~/entityset/{key}/collection-valued-Nav/subtype
500510
// ~/entityset/{key}/single-valued-Nav/subtype
501511
CreateTypeCastPaths(currentPath, convertSettings, navEntityType, navigationProperty, targetsMany);

src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<TargetFrameworks>netstandard2.0</TargetFrameworks>
1616
<PackageId>Microsoft.OpenApi.OData</PackageId>
1717
<SignAssembly>true</SignAssembly>
18-
<Version>1.4.0-preview3</Version>
18+
<Version>1.4.0-preview4</Version>
1919
<Description>This package contains the codes you need to convert OData CSDL to Open API Document of Model.</Description>
2020
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
2121
<PackageTags>Microsoft OpenApi OData EDM</PackageTags>
@@ -24,6 +24,7 @@
2424
- DELETE methods should always return response status code #204
2525
- Aliases or strips namespace prefixes from segment names when and where applicable #365
2626
- Adds support for all Org.OData.Core.V1.RevisionKind enum values #372
27+
- Use directly annotated CountRestriction annotations when creating $count segments for collection-valued navigation properties #328
2728
</PackageReleaseNotes>
2829
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
2930
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void GetPathsForGraphBetaModelReturnsAllPaths()
5252

5353
// Assert
5454
Assert.NotNull(paths);
55-
Assert.Equal(18054, paths.Count());
55+
Assert.Equal(18050, paths.Count());
5656
AssertGraphBetaModelPaths(paths);
5757
}
5858

@@ -64,6 +64,9 @@ private void AssertGraphBetaModelPaths(IEnumerable<ODataPath> paths)
6464

6565
// Test that $value segments are created for entity types with base types with HasStream="true"
6666
Assert.NotNull(paths.FirstOrDefault(p => p.GetPathItemName().Equals("/me/chats({id})/messages({id1})/hostedContents({id2})/$value")));
67+
68+
// Test that count restrictions annotations for navigation properties work
69+
Assert.Null(paths.FirstOrDefault(p => p.GetPathItemName().Equals("/me/drives/$count")));
6770
}
6871

6972
[Fact]
@@ -84,7 +87,50 @@ public void GetPathsForGraphBetaModelWithDerivedTypesConstraintReturnsAllPaths()
8487

8588
// Assert
8689
Assert.NotNull(paths);
87-
Assert.Equal(18705, paths.Count());
90+
Assert.Equal(18701, paths.Count());
91+
}
92+
93+
[Theory]
94+
[InlineData(true, true)]
95+
[InlineData(true, false)]
96+
[InlineData(false, false)]
97+
public void UseCountRestrictionsAnnotationsToAppendDollarCountSegmentsToNavigationPropertyPaths(bool useCountRestrictionsAnnotation, bool countable)
98+
{
99+
// Arrange
100+
string countRestrictionAnnotation = @"
101+
<Annotation Term=""Org.OData.Capabilities.V1.CountRestrictions"">
102+
<Record>
103+
<PropertyValue Property=""Countable"" Bool=""{0}"" />
104+
</Record>
105+
</Annotation>";
106+
countRestrictionAnnotation = string.Format(countRestrictionAnnotation, countable);
107+
IEdmModel model = useCountRestrictionsAnnotation ? GetNavPropModel(countRestrictionAnnotation)
108+
: GetNavPropModel(string.Empty);
109+
ODataPathProvider provider = new();
110+
var settings = new OpenApiConvertSettings();
111+
112+
// Act
113+
var paths = provider.GetPaths(model, settings);
114+
115+
// Assert
116+
Assert.NotNull(paths);
117+
var testPath = paths.FirstOrDefault(p => p.GetPathItemName().Equals("/Root/Customers/$count"));
118+
119+
if (useCountRestrictionsAnnotation)
120+
{
121+
if (countable)
122+
{
123+
Assert.NotNull(testPath);
124+
}
125+
else
126+
{
127+
Assert.Null(testPath);
128+
}
129+
}
130+
else
131+
{
132+
Assert.NotNull(testPath);
133+
}
88134
}
89135

90136
[Fact]

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Graph.Beta.OData.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112362,6 +112362,13 @@
112362112362
<Term Name="teamCreationMode" Type="Edm.String" AppliesTo="microsoft.graph.team">
112363112363
<Annotation Term="Org.OData.Core.V1.LongDescription" String="Indicates that the team is in migration state and is currently being used for migration purposes. It accepts one value: migration. Note: In the future, Microsoft may require you or your customers to pay additional fees based on the amount of data imported." />
112364112364
</Term>
112365+
<Annotations Target="microsoft.graph.user/drives">
112366+
<Annotation Term="Org.OData.Capabilities.V1.CountRestrictions">
112367+
<Record>
112368+
<PropertyValue Property="Countable" Bool="false" />
112369+
</Record>
112370+
</Annotation>
112371+
</Annotations>
112365112372
<Annotations Target="microsoft.graph.user/joinedGroups">
112366112373
<Annotation Term="Org.OData.Capabilities.V1.NavigationRestrictions">
112367112374
<Record>

0 commit comments

Comments
 (0)