Skip to content

Commit 503462d

Browse files
level120DoHoon Kim
authored and
DoHoon Kim
committed
fixed that fails to use a model with a property named Aliases (Azure#218)
1 parent ea84da4 commit 503462d

File tree

15 files changed

+248
-5
lines changed

15 files changed

+248
-5
lines changed

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ public override void Visit(IAcceptor acceptor, KeyValuePair<string, Type> type,
8181

8282
// Adds schemas to the root.
8383
var schemasToBeAdded = subAcceptor.Schemas
84-
.Where(p => !instance.Schemas.Keys.Contains(p.Key))
8584
.Where(p => p.Value.IsOpenApiSchemaObject()
8685
|| p.Value.IsOpenApiSchemaArray()
8786
|| p.Value.IsOpenApiSchemaDictionary()

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
54
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
65
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
76

@@ -81,7 +80,6 @@ public override void Visit(IAcceptor acceptor, KeyValuePair<string, Type> type,
8180

8281
// Adds schemas to the root.
8382
var schemasToBeAdded = subAcceptor.Schemas
84-
.Where(p => !instance.Schemas.Keys.Contains(p.Key))
8583
.Where(p => p.Value.IsOpenApiSchemaObject()
8684
|| p.Value.IsOpenApiSchemaArray()
8785
|| p.Value.IsOpenApiSchemaDictionary()

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaNam
207207

208208
// Adds schemas to the root.
209209
var schemasToBeAdded = subAcceptor.Schemas
210-
.Where(p => !instance.Schemas.Keys.Contains(p.Key))
211210
.Where(p => p.Value.IsOpenApiSchemaObject())
212211
.GroupBy(p => p.Value.Title)
213212
.Select(p => p.First())

test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_ArrayObject_Tests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @
7575
[DataRow("arrayObjectModel", "object", "decimalValue", "array")]
7676
[DataRow("arrayObjectModel", "object", "stringObjectValue", "array")]
7777
[DataRow("arrayObjectModel", "object", "int32ObjectValue", "array")]
78+
[DataRow("arrayObjectModel", "object", "stringObjectModel", "array")]
7879
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string refType, string propertyName, string propertyType)
7980
{
8081
var properties = this._doc["components"]["schemas"][@ref]["properties"];
@@ -105,6 +106,7 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyI
105106
[DataTestMethod]
106107
[DataRow("arrayObjectModel", "object", "stringObjectValue", "array", "stringObjectModel")]
107108
[DataRow("arrayObjectModel", "object", "int32ObjectValue", "array", "int32ObjectModel")]
109+
[DataRow("arrayObjectModel", "object", "stringObjectModel", "array", "stringObjectModel")]
108110
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyItemReference(string @ref, string refType, string propertyName, string propertyType, string itemRef)
109111
{
110112
var items = this._doc["components"]["schemas"][@ref]["properties"][propertyName]["items"];
@@ -113,6 +115,8 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyI
113115

114116
itemReference.Should().NotBeNull();
115117
itemReference.Value<string>().Should().Be($"#/components/schemas/{itemRef}");
118+
119+
this._doc["components"]["schemas"][itemRef].Should().NotBeNullOrEmpty();
116120
}
117121
}
118122
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System.Net.Http;
2+
using System.Threading.Tasks;
3+
4+
using FluentAssertions;
5+
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
8+
using Newtonsoft.Json;
9+
using Newtonsoft.Json.Linq;
10+
11+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
12+
{
13+
[TestClass]
14+
[TestCategory(Constants.TestCategory)]
15+
public class Get_ApplicationJson_DictionaryObject_Tests
16+
{
17+
private static HttpClient http = new HttpClient();
18+
19+
private JObject _doc;
20+
21+
[TestInitialize]
22+
public async Task Init()
23+
{
24+
var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
25+
this._doc = JsonConvert.DeserializeObject<JObject>(json);
26+
}
27+
28+
[DataTestMethod]
29+
[DataRow("/get-applicationjson-dictionary", "get", "200")]
30+
public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
31+
{
32+
var responses = this._doc["paths"][path][operationType]["responses"];
33+
34+
responses[responseCode].Should().NotBeNull();
35+
}
36+
37+
[DataTestMethod]
38+
[DataRow("/get-applicationjson-dictionary", "get", "200", "application/json")]
39+
public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
40+
{
41+
var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
42+
43+
content[contentType].Should().NotBeNull();
44+
}
45+
46+
[DataTestMethod]
47+
[DataRow("/get-applicationjson-dictionary", "get", "200", "application/json", "dictionaryObjectModel")]
48+
public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
49+
{
50+
var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
51+
52+
var @ref = content[contentType]["schema"]["$ref"];
53+
54+
@ref.Value<string>().Should().Be($"#/components/schemas/{reference}");
55+
}
56+
57+
[DataTestMethod]
58+
[DataRow("dictionaryObjectModel", "object", "boolValue", "object", "boolean")]
59+
[DataRow("dictionaryObjectModel", "object", "stringValue", "object", "string")]
60+
[DataRow("dictionaryObjectModel", "object", "floatValue", "object", "number")]
61+
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType, string propertyName, string propertyType, string itemType)
62+
{
63+
var items = this._doc["components"]["schemas"][@ref]["properties"][propertyName];
64+
65+
var type = items["additionalProperties"]["type"];
66+
67+
type.Should().NotBeNull();
68+
type.Value<string>().Should().Be(itemType);
69+
}
70+
71+
[DataTestMethod]
72+
[DataRow("dictionaryObjectModel", "int32ObjectValue", "object", "int32ObjectModel")]
73+
[DataRow("dictionaryObjectModel", "stringObjectModel", "object", "stringObjectModel")]
74+
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType, string itemRef)
75+
{
76+
var properties = this._doc["components"]["schemas"][@ref]["properties"];
77+
78+
var value = properties[propertyName];
79+
80+
value.Should().NotBeNull();
81+
value.Value<string>("type").Should().Be(propertyType);
82+
value["additionalProperties"].Should().NotBeNullOrEmpty();
83+
value["additionalProperties"].Value<string>("$ref").Should().Be($"#/components/schemas/{itemRef}");
84+
85+
this._doc["components"]["schemas"][itemRef].Should().NotBeNullOrEmpty();
86+
}
87+
}
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Net;
2+
using System.Threading.Tasks;
3+
4+
using Microsoft.AspNetCore.Http;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.Azure.WebJobs.Extensions.Http;
7+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
8+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
9+
using Microsoft.Extensions.Logging;
10+
11+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
12+
{
13+
public class Get_ApplicationJson_DictionaryObject_HttpTrigger
14+
{
15+
[FunctionName(nameof(Get_ApplicationJson_DictionaryObject_HttpTrigger))]
16+
[OpenApiOperation(operationId: nameof(Get_ApplicationJson_DictionaryObject_HttpTrigger.Get_ApplicationJson_DictionaryObjectType), tags: new[] { "dictionary" })]
17+
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DictionaryObjectModel), Description = "The OK response")]
18+
public static async Task<IActionResult> Get_ApplicationJson_DictionaryObjectType(
19+
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-applicationjson-dictionary")] HttpRequest req,
20+
ILogger log)
21+
{
22+
var result = new OkResult();
23+
24+
return await Task.FromResult(result).ConfigureAwait(false);
25+
}
26+
}
27+
}

test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/ArrayObjectModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ public class ArrayObjectModel
1212
public IReadOnlyCollection<decimal> DecimalValue { get; set; }
1313
public HashSet<StringObjectModel> StringObjectValue { get; set; }
1414
public ISet<Int32ObjectModel> Int32ObjectValue { get; set; }
15+
16+
public IEnumerable<StringObjectModel> StringObjectModel { get; set; }
1517
}
1618
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
3+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
4+
{
5+
public class DictionaryObjectModel
6+
{
7+
public Dictionary<string, bool> BoolValue { get; set; }
8+
public IDictionary<string, string> StringValue { get; set; }
9+
public IReadOnlyDictionary<string, float> FloatValue { get; set; }
10+
public KeyValuePair<string, Int32ObjectModel> Int32ObjectValue { get; set; }
11+
12+
public IDictionary<string, StringObjectModel> StringObjectModel { get; set; }
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
5+
{
6+
public class FakeAliasCollectionModel
7+
{
8+
[JsonRequired]
9+
public string @String { get; set; }
10+
11+
public ICollection<FakeAliasSubModel> FakeAliasSubModel { get; set; }
12+
public ICollection<FakeSubModel> FakeSubModel { get; set; }
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
5+
{
6+
public class FakeAliasDictionaryModel
7+
{
8+
[JsonRequired]
9+
public string @String { get; set; }
10+
11+
public IDictionary<string, FakeAliasSubModel> FakeAliasSubModel { get; set; }
12+
public IDictionary<string, FakeSubModel> FakeSubModel { get; set; }
13+
}
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
4+
{
5+
public class FakeAliasSubModel
6+
{
7+
[JsonRequired]
8+
public string @String { get; set; }
9+
10+
public FakeSubModel FakeSubModel { get; set; }
11+
public FakeDummyModel FakeDummyModel { get; set; }
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
2+
{
3+
public class FakeDummyModel
4+
{
5+
}
6+
}

test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,27 @@ public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Ty
187187
result.AdditionalProperties.Reference.Should().BeNull();
188188
}
189189
}
190+
191+
[DataTestMethod]
192+
[DataRow(typeof(Dictionary<string, FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
193+
[DataRow(typeof(IDictionary<string, FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
194+
[DataRow(typeof(IReadOnlyDictionary<string, FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
195+
[DataRow(typeof(KeyValuePair<string, FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
196+
public void Given_Alias_Type_When_Visit_Invoked_Then_It_Should_Return_All_Sub_Schemas(Type type, params Type[] schemaTypes)
197+
{
198+
var acceptor = new OpenApiSchemaAcceptor();
199+
var key = type.GetOpenApiReferenceId(type.IsOpenApiDictionary(), type.IsOpenApiArray(), this._strategy);
200+
201+
this._visitor.Visit(acceptor, new KeyValuePair<string, Type>(key, type), this._strategy);
202+
203+
acceptor.RootSchemas.Count.Should().Be(schemaTypes.Length);
204+
205+
foreach (var schemaType in schemaTypes)
206+
{
207+
var subKey = schemaType.GetOpenApiReferenceId(schemaType.IsOpenApiDictionary(), schemaType.IsOpenApiArray(), this._strategy);
208+
209+
acceptor.RootSchemas.Should().ContainKey(subKey);
210+
}
211+
}
190212
}
191213
}

test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/ListObjectTypeVisitorTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.ComponentModel.DataAnnotations;
44
using System.Linq;
5-
65
using FluentAssertions;
76

87
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
@@ -297,5 +296,29 @@ public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Ty
297296
result.Items.Reference.Should().BeNull();
298297
}
299298
}
299+
300+
[DataTestMethod]
301+
[DataRow(typeof(List<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
302+
[DataRow(typeof(IList<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
303+
[DataRow(typeof(ICollection<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
304+
[DataRow(typeof(IEnumerable<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
305+
[DataRow(typeof(IReadOnlyList<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
306+
[DataRow(typeof(IReadOnlyCollection<FakeAliasCollectionModel>), typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
307+
public void Given_Alias_Type_When_Visit_Invoked_Then_It_Should_Return_All_Sub_Schemas(Type type, params Type[] schemaTypes)
308+
{
309+
var acceptor = new OpenApiSchemaAcceptor();
310+
var key = type.GetOpenApiReferenceId(type.IsOpenApiDictionary(), type.IsOpenApiArray(), this._strategy);
311+
312+
this._visitor.Visit(acceptor, new KeyValuePair<string, Type>(key, type), this._strategy);
313+
314+
acceptor.RootSchemas.Count.Should().Be(schemaTypes.Length);
315+
316+
foreach (var schemaType in schemaTypes)
317+
{
318+
var subKey = schemaType.GetOpenApiReferenceId(schemaType.IsOpenApiDictionary(), schemaType.IsOpenApiArray(), this._strategy);
319+
320+
acceptor.RootSchemas.Should().ContainKey(subKey);
321+
}
322+
}
300323
}
301324
}

test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/ObjectTypeVisitorTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,25 @@ public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Result(Ty
155155
result.Type.Should().Be(dataType);
156156
result.Format.Should().Be(dataFormat);
157157
}
158+
159+
[DataTestMethod]
160+
[DataRow(typeof(FakeAliasCollectionModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
161+
[DataRow(typeof(FakeAliasDictionaryModel), typeof(FakeAliasSubModel), typeof(FakeSubModel), typeof(FakeDummyModel))]
162+
public void Given_Alias_Type_When_Visit_Invoked_Then_It_Should_Return_All_Sub_Schemas(Type type, params Type[] schemaTypes)
163+
{
164+
var acceptor = new OpenApiSchemaAcceptor();
165+
var key = type.GetOpenApiReferenceId(type.IsOpenApiDictionary(), type.IsOpenApiArray(), this._strategy);
166+
167+
this._visitor.Visit(acceptor, new KeyValuePair<string, Type>(key, type), this._strategy);
168+
169+
acceptor.RootSchemas.Count.Should().Be(schemaTypes.Length);
170+
171+
foreach (var schemaType in schemaTypes)
172+
{
173+
var subKey = schemaType.GetOpenApiReferenceId(schemaType.IsOpenApiDictionary(), schemaType.IsOpenApiArray(), this._strategy);
174+
175+
acceptor.RootSchemas.Should().ContainKey(subKey);
176+
}
177+
}
158178
}
159179
}

0 commit comments

Comments
 (0)