Skip to content

Commit 1d9b54b

Browse files
authored
Adds OData query parameters to $count endpoints (#320)
* Set parameters for DollarCount operations * Update tests * Update integration test files * Update release note * Move declaration near use; fix comment * Append only $select and $filter to /$count paths * Update test and integration tests * Simplify conditional; remove cast to IEdmSingleton
1 parent e7bad11 commit 1d9b54b

15 files changed

+1542
-30
lines changed

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.2.0-preview8</Version>
18+
<Version>1.2.0-preview9</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>
@@ -30,6 +30,7 @@
3030
- Expands navigation properties of derived types only if declaring navigation property is a containment #269
3131
- Adds custom parameters to $count and ODataTypeCast paths' Get operations #207
3232
- Adds support for configuring the default value of derived types' @odata.type property #304
33+
- Adds OData query parameters to $count endpoints #313
3334
</PackageReleaseNotes>
3435
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
3536
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

src/Microsoft.OpenApi.OData.Reader/Operation/DollarCountGetOperationHandler.cs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.OpenApi.Models;
1010
using Microsoft.OpenApi.OData.Common;
1111
using Microsoft.OpenApi.OData.Edm;
12+
using Microsoft.OpenApi.OData.Generator;
1213
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
1314

1415
namespace Microsoft.OpenApi.OData.Operation
@@ -27,6 +28,8 @@ internal class DollarCountGetOperationHandler : OperationHandler
2728
/// </summary>
2829
internal ODataSegment LastSecondSegment { get; set; }
2930
private const int SecondLastSegmentIndex = 2;
31+
private IEdmVocabularyAnnotatable annotatable;
32+
3033
/// <inheritdoc/>
3134
protected override void Initialize(ODataContext context, ODataPath path)
3235
{
@@ -36,6 +39,15 @@ protected override void Initialize(ODataContext context, ODataPath path)
3639
int count = path.Segments.Count;
3740
if(count >= SecondLastSegmentIndex)
3841
LastSecondSegment = path.Segments.ElementAt(count - SecondLastSegmentIndex);
42+
43+
if (LastSecondSegment is ODataNavigationSourceSegment sourceSegment)
44+
{
45+
annotatable = sourceSegment.NavigationSource as IEdmEntitySet;
46+
}
47+
else if (LastSecondSegment is ODataNavigationPropertySegment navigationPropertySegment)
48+
{
49+
annotatable = navigationPropertySegment.NavigationProperty;
50+
}
3951
}
4052

4153
/// <inheritdoc/>
@@ -75,19 +87,33 @@ protected override void SetResponses(OpenApiOperation operation)
7587
base.SetResponses(operation);
7688
}
7789

78-
protected override void AppendCustomParameters(OpenApiOperation operation)
90+
/// <inheritdoc/>
91+
protected override void SetParameters(OpenApiOperation operation)
7992
{
80-
IEdmVocabularyAnnotatable annotatable = null;
81-
if (LastSecondSegment is ODataNavigationSourceSegment sourceSegment)
93+
base.SetParameters(operation);
94+
95+
if (annotatable == null)
8296
{
83-
annotatable = sourceSegment.NavigationSource as IEdmEntitySet;
84-
annotatable ??= sourceSegment.NavigationSource as IEdmSingleton;
97+
return;
8598
}
86-
else if (LastSecondSegment is ODataNavigationPropertySegment navigationPropertySegment)
99+
100+
OpenApiParameter parameter;
101+
102+
parameter = Context.CreateSearch(annotatable);
103+
if (parameter != null)
87104
{
88-
annotatable = navigationPropertySegment.NavigationProperty;
105+
operation.Parameters.Add(parameter);
89106
}
90107

108+
parameter = Context.CreateFilter(annotatable);
109+
if (parameter != null)
110+
{
111+
operation.Parameters.Add(parameter);
112+
}
113+
}
114+
115+
protected override void AppendCustomParameters(OpenApiOperation operation)
116+
{
91117
if (annotatable == null)
92118
{
93119
return;

test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/DollarCountGetOperationHandlerTests.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,10 @@ public void CreateDollarCountGetOperationForNavigationPropertyReturnsCorrectOper
4949
Assert.Equal("Get the number of the resource", operation.Summary);
5050

5151
Assert.NotNull(operation.Parameters);
52-
Assert.Equal(2, operation.Parameters.Count);
53-
Assert.Collection(operation.Parameters,
54-
item =>
55-
{
56-
Assert.Equal("UserName", item.Name);
57-
Assert.Equal(ParameterLocation.Path, item.In);
58-
},
59-
item =>
60-
{
61-
Assert.Equal("ConsistencyLevel", item.Name);
62-
Assert.Equal(ParameterLocation.Header, item.In);
63-
});
64-
52+
Assert.Equal(4, operation.Parameters.Count);
53+
Assert.Equal(new[] { "UserName", "ConsistencyLevel", "search", "filter"},
54+
operation.Parameters.Select(x => x.Name ?? x.Reference.Id).ToList());
55+
6556
Assert.Null(operation.RequestBody);
6657

6758
Assert.Equal(2, operation.Responses.Count);
@@ -105,18 +96,12 @@ public void CreateDollarCountGetOperationForNavigationSourceReturnsCorrectOperat
10596
// Assert
10697
Assert.NotNull(operation);
10798
Assert.Equal("Get the number of the resource", operation.Summary);
108-
10999
Assert.NotNull(operation.Parameters);
110-
Assert.Equal(1, operation.Parameters.Count);
111-
Assert.Collection(operation.Parameters,
112-
item =>
113-
{
114-
Assert.Equal("ConsistencyLevel", item.Name);
115-
Assert.Equal(ParameterLocation.Header, item.In);
116-
});
100+
Assert.Equal(3, operation.Parameters.Count);
101+
Assert.Equal(new[] { "ConsistencyLevel", "search", "filter" },
102+
operation.Parameters.Select(x => x.Name ?? x.Reference.Id).ToList());
117103

118104
Assert.Null(operation.RequestBody);
119-
120105
Assert.Equal(2, operation.Responses.Count);
121106
var statusCode = useHTTPStatusCodeClass2XX ? "2XX" : "200";
122107
Assert.Equal(new string[] { statusCode, "default" }, operation.Responses.Select(e => e.Key));

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@
251251
"get": {
252252
"summary": "Get the number of the resource",
253253
"operationId": "Get.Count.City-8728",
254+
"parameters": [
255+
{
256+
"$ref": "#/parameters/search"
257+
},
258+
{
259+
"$ref": "#/parameters/filter"
260+
}
261+
],
254262
"responses": {
255263
"200": {
256264
"$ref": "#/responses/ODataCountResponse"
@@ -503,6 +511,14 @@
503511
"get": {
504512
"summary": "Get the number of the resource",
505513
"operationId": "Get.Count.CountryOrRegion-daf5",
514+
"parameters": [
515+
{
516+
"$ref": "#/parameters/search"
517+
},
518+
{
519+
"$ref": "#/parameters/filter"
520+
}
521+
],
506522
"responses": {
507523
"200": {
508524
"$ref": "#/responses/ODataCountResponse"
@@ -852,6 +868,14 @@
852868
"get": {
853869
"summary": "Get the number of the resource",
854870
"operationId": "Get.Count.People-dd8d",
871+
"parameters": [
872+
{
873+
"$ref": "#/parameters/search"
874+
},
875+
{
876+
"$ref": "#/parameters/filter"
877+
}
878+
],
855879
"responses": {
856880
"200": {
857881
"$ref": "#/responses/ODataCountResponse"

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.V2.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ paths:
166166
get:
167167
summary: Get the number of the resource
168168
operationId: Get.Count.City-8728
169+
parameters:
170+
- $ref: '#/parameters/search'
171+
- $ref: '#/parameters/filter'
169172
responses:
170173
'200':
171174
$ref: '#/responses/ODataCountResponse'
@@ -331,6 +334,9 @@ paths:
331334
get:
332335
summary: Get the number of the resource
333336
operationId: Get.Count.CountryOrRegion-daf5
337+
parameters:
338+
- $ref: '#/parameters/search'
339+
- $ref: '#/parameters/filter'
334340
responses:
335341
'200':
336342
$ref: '#/responses/ODataCountResponse'
@@ -566,6 +572,9 @@ paths:
566572
get:
567573
summary: Get the number of the resource
568574
operationId: Get.Count.People-dd8d
575+
parameters:
576+
- $ref: '#/parameters/search'
577+
- $ref: '#/parameters/filter'
569578
responses:
570579
'200':
571580
$ref: '#/responses/ODataCountResponse'

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,14 @@
284284
"get": {
285285
"summary": "Get the number of the resource",
286286
"operationId": "Get.Count.City-8728",
287+
"parameters": [
288+
{
289+
"$ref": "#/components/parameters/search"
290+
},
291+
{
292+
"$ref": "#/components/parameters/filter"
293+
}
294+
],
287295
"responses": {
288296
"200": {
289297
"$ref": "#/components/responses/ODataCountResponse"
@@ -567,6 +575,14 @@
567575
"get": {
568576
"summary": "Get the number of the resource",
569577
"operationId": "Get.Count.CountryOrRegion-daf5",
578+
"parameters": [
579+
{
580+
"$ref": "#/components/parameters/search"
581+
},
582+
{
583+
"$ref": "#/components/parameters/filter"
584+
}
585+
],
570586
"responses": {
571587
"200": {
572588
"$ref": "#/components/responses/ODataCountResponse"
@@ -955,6 +971,14 @@
955971
"get": {
956972
"summary": "Get the number of the resource",
957973
"operationId": "Get.Count.People-dd8d",
974+
"parameters": [
975+
{
976+
"$ref": "#/components/parameters/search"
977+
},
978+
{
979+
"$ref": "#/components/parameters/filter"
980+
}
981+
],
958982
"responses": {
959983
"200": {
960984
"$ref": "#/components/responses/ODataCountResponse"

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/Basic.OpenApi.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ paths:
187187
get:
188188
summary: Get the number of the resource
189189
operationId: Get.Count.City-8728
190+
parameters:
191+
- $ref: '#/components/parameters/search'
192+
- $ref: '#/components/parameters/filter'
190193
responses:
191194
'200':
192195
$ref: '#/components/responses/ODataCountResponse'
@@ -373,6 +376,9 @@ paths:
373376
get:
374377
summary: Get the number of the resource
375378
operationId: Get.Count.CountryOrRegion-daf5
379+
parameters:
380+
- $ref: '#/components/parameters/search'
381+
- $ref: '#/components/parameters/filter'
376382
responses:
377383
'200':
378384
$ref: '#/components/responses/ODataCountResponse'
@@ -635,6 +641,9 @@ paths:
635641
get:
636642
summary: Get the number of the resource
637643
operationId: Get.Count.People-dd8d
644+
parameters:
645+
- $ref: '#/components/parameters/search'
646+
- $ref: '#/components/parameters/filter'
638647
responses:
639648
'200':
640649
$ref: '#/components/responses/ODataCountResponse'

0 commit comments

Comments
 (0)