Skip to content

Commit ddee0b2

Browse files
committed
Fixed reading v2 with path parameters that are form data
1 parent a9ca6e9 commit ddee0b2

File tree

4 files changed

+120
-3
lines changed

4 files changed

+120
-3
lines changed

src/Microsoft.OpenApi.Readers/V2/OpenApiPathItemDeserializer.cs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
using System.Collections.Generic;
45
using Microsoft.OpenApi.Extensions;
56
using Microsoft.OpenApi.Models;
67
using Microsoft.OpenApi.Readers.ParseNodes;
@@ -32,7 +33,7 @@ internal static partial class OpenApiV2Deserializer
3233
{
3334
"parameters", (o, n) =>
3435
{
35-
o.Parameters = n.CreateList(LoadParameter);
36+
LoadPathParameters(o,n);
3637
}
3738
},
3839
};
@@ -53,5 +54,57 @@ public static OpenApiPathItem LoadPathItem(ParseNode node)
5354

5455
return pathItem;
5556
}
57+
58+
private static void LoadPathParameters(OpenApiPathItem pathItem, ParseNode node)
59+
{
60+
node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null);
61+
node.Context.SetTempStorage(TempStorageKeys.FormParameters, null);
62+
63+
pathItem.Parameters = node.CreateList(LoadParameter);
64+
65+
// Build request body based on information determined while parsing OpenApiOperation
66+
var bodyParameter = node.Context.GetFromTempStorage<OpenApiParameter>(TempStorageKeys.BodyParameter);
67+
if (bodyParameter != null)
68+
{
69+
var requestBody = CreateRequestBody(node.Context, bodyParameter);
70+
foreach(var opPair in pathItem.Operations)
71+
{
72+
if (opPair.Value.RequestBody == null)
73+
{
74+
switch (opPair.Key)
75+
{
76+
case OperationType.Post:
77+
case OperationType.Put:
78+
case OperationType.Patch:
79+
opPair.Value.RequestBody = requestBody;
80+
break;
81+
}
82+
}
83+
}
84+
}
85+
else
86+
{
87+
var formParameters = node.Context.GetFromTempStorage<List<OpenApiParameter>>(TempStorageKeys.FormParameters);
88+
if (formParameters != null)
89+
{
90+
var requestBody = CreateFormBody(node.Context, formParameters);
91+
foreach (var opPair in pathItem.Operations)
92+
{
93+
if (opPair.Value.RequestBody == null)
94+
{
95+
switch (opPair.Key)
96+
{
97+
case OperationType.Post:
98+
case OperationType.Put:
99+
case OperationType.Patch:
100+
opPair.Value.RequestBody = requestBody;
101+
break;
102+
}
103+
}
104+
}
105+
}
106+
}
107+
108+
}
56109
}
57110
}

test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</PropertyGroup>
1515
<ItemGroup>
1616
<None Remove="V2Tests\Samples\ComponentRootReference.json" />
17+
<None Remove="V2Tests\Samples\OpenApiPathItem\pathItemWithFormDataPathParameter.yaml" />
1718
<None Remove="V3Tests\Samples\OpenApiWorkspace\TodoComponents.yaml" />
1819
<None Remove="V3Tests\Samples\OpenApiWorkspace\TodoMain.yaml" />
1920
</ItemGroup>
@@ -85,6 +86,9 @@
8586
<EmbeddedResource Include="V2Tests\Samples\OpenApiParameter\queryParameter.yaml">
8687
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
8788
</EmbeddedResource>
89+
<EmbeddedResource Include="V2Tests\Samples\OpenApiPathItem\pathItemWithFormDataPathParameter.yaml">
90+
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
91+
</EmbeddedResource>
8892
<EmbeddedResource Include="V2Tests\Samples\OpenApiPathItem\basicPathItemWithFormData.yaml">
8993
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
9094
</EmbeddedResource>

test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.IO;
6+
using System.Linq;
67
using System.Text;
78
using FluentAssertions;
89
using Microsoft.OpenApi.Extensions;
@@ -253,10 +254,28 @@ public void ParseBasicPathItemWithFormDataShouldSucceed()
253254
}
254255

255256
// Act
256-
var operation = OpenApiV2Deserializer.LoadPathItem(node);
257+
var pathItem = OpenApiV2Deserializer.LoadPathItem(node);
257258

258259
// Assert
259-
operation.Should().BeEquivalentTo(_basicPathItemWithFormData);
260+
pathItem.Should().BeEquivalentTo(_basicPathItemWithFormData);
261+
}
262+
263+
[Fact]
264+
public void ParsePathItemWithFormDataPathParameterShouldSucceed()
265+
{
266+
// Arrange
267+
MapNode node;
268+
using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathItemWithFormDataPathParameter.yaml")))
269+
{
270+
node = TestHelper.CreateYamlMapNode(stream);
271+
}
272+
273+
// Act
274+
var pathItem = OpenApiV2Deserializer.LoadPathItem(node);
275+
276+
// Assert
277+
// FormData parameters at in the path level are pushed into Operation request bodies.
278+
Assert.True(pathItem.Operations.All(o => o.Value.RequestBody != null));
260279
}
261280
}
262281
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
put:
2+
summary: Puts a pet in the store with form data
3+
description: ""
4+
responses:
5+
'200':
6+
description: Pet updated.
7+
'405':
8+
description: Invalid input
9+
x-http-tests:
10+
- parameterValues:
11+
petId: 10
12+
name: Milo
13+
status: Happy
14+
expectedRequest:
15+
href: /pathitem-form-parameter/10
16+
headers:
17+
Content-Type: multipart/form-data
18+
content: name=Milo&status=Happy
19+
post:
20+
summary: Posts a pet in the store with form data
21+
description: ""
22+
responses:
23+
'200':
24+
description: Pet updated.
25+
parameters:
26+
- name: petId
27+
in: path
28+
description: ID of pet that needs to be updated
29+
required: true
30+
schema:
31+
type: string
32+
- name: name
33+
in: formData
34+
description: Updated name of the pet
35+
required: true
36+
type: string
37+
- name: status
38+
in: formData
39+
description: Updated status of the pet
40+
required: false
41+
type: string

0 commit comments

Comments
 (0)