Skip to content

Commit 976b5cc

Browse files
authored
Merge pull request #794 from microsoft/enhancement/nested-postman-collection
Parse Nested postman collections
2 parents 79c271e + 53c56f7 commit 976b5cc

File tree

6 files changed

+1615
-19
lines changed

6 files changed

+1615
-19
lines changed

src/Microsoft.OpenApi.Hidi/OpenApiService.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -397,24 +397,47 @@ public static Dictionary<string, List<string>> ParseJsonCollectionFile(Stream st
397397
logger.LogTrace("Parsing the json collection file into a JsonDocument");
398398
using var document = JsonDocument.Parse(stream);
399399
var root = document.RootElement;
400-
var itemElement = root.GetProperty("item");
401-
foreach (var requestObject in itemElement.EnumerateArray().Select(item => item.GetProperty("request")))
402-
{
403-
// Fetch list of methods and urls from collection, store them in a dictionary
404-
var path = requestObject.GetProperty("url").GetProperty("raw").ToString();
405-
var method = requestObject.GetProperty("method").ToString();
406400

407-
if (!requestUrls.ContainsKey(path))
401+
requestUrls = EnumerateJsonDocument(root, requestUrls);
402+
logger.LogTrace("Finished fetching the list of paths and Http methods defined in the Postman collection.");
403+
404+
return requestUrls;
405+
}
406+
407+
private static Dictionary<string, List<string>> EnumerateJsonDocument(JsonElement itemElement, Dictionary<string, List<string>> paths)
408+
{
409+
var itemsArray = itemElement.GetProperty("item");
410+
411+
foreach (var item in itemsArray.EnumerateArray())
412+
{
413+
if(item.ValueKind == JsonValueKind.Object)
408414
{
409-
requestUrls.Add(path, new List<string> { method });
415+
if(item.TryGetProperty("request", out var request))
416+
{
417+
// Fetch list of methods and urls from collection, store them in a dictionary
418+
var path = request.GetProperty("url").GetProperty("raw").ToString();
419+
var method = request.GetProperty("method").ToString();
420+
if (!paths.ContainsKey(path))
421+
{
422+
paths.Add(path, new List<string> { method });
423+
}
424+
else
425+
{
426+
paths[path].Add(method);
427+
}
428+
}
429+
else
430+
{
431+
EnumerateJsonDocument(item, paths);
432+
}
410433
}
411434
else
412435
{
413-
requestUrls[path].Add(method);
436+
EnumerateJsonDocument(item, paths);
414437
}
415438
}
416-
logger.LogTrace("Finished fetching the list of paths and Http methods defined in the Postman collection.");
417-
return requestUrls;
439+
440+
return paths;
418441
}
419442

420443
/// <summary>

src/Microsoft.OpenApi/Services/OpenApiFilterService.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,24 @@ public static class OpenApiFilterService
7373
var rootNode = CreateOpenApiUrlTreeNode(sources);
7474

7575
// Iterate through urls dictionary and fetch operations for each url
76-
foreach (var path in requestUrls)
76+
foreach (var url in requestUrls)
7777
{
7878
var serverList = source.Servers;
79-
var url = FormatUrlString(path.Key, serverList);
79+
var path = ExtractPath(url.Key, serverList);
8080

81-
var openApiOperations = GetOpenApiOperations(rootNode, url, apiVersion);
81+
var openApiOperations = GetOpenApiOperations(rootNode, path, apiVersion);
8282
if (openApiOperations == null)
8383
{
84+
Console.WriteLine($"The url {url.Key} could not be found in the OpenApi description");
8485
continue;
8586
}
8687

8788
// Add the available ops if they are in the postman collection. See path.Value
8889
foreach (var ops in openApiOperations)
8990
{
90-
if (path.Value.Contains(ops.Key.ToString().ToUpper()))
91+
if (url.Value.Contains(ops.Key.ToString().ToUpper()))
9192
{
92-
operationTypes.Add(ops.Key + url);
93+
operationTypes.Add(ops.Key + path);
9394
}
9495
}
9596
}
@@ -322,7 +323,7 @@ private static bool AddReferences(OpenApiComponents newComponents, OpenApiCompon
322323
return moreStuff;
323324
}
324325

325-
private static string FormatUrlString(string url, IList<OpenApiServer> serverList)
326+
private static string ExtractPath(string url, IList<OpenApiServer> serverList)
326327
{
327328
var queryPath = string.Empty;
328329
foreach (var server in serverList)
@@ -333,8 +334,8 @@ private static string FormatUrlString(string url, IList<OpenApiServer> serverLis
333334
continue;
334335
}
335336

336-
var querySegments = url.Split(new[]{ serverUrl }, StringSplitOptions.None);
337-
queryPath = querySegments[1];
337+
var urlComponents = url.Split(new[]{ serverUrl }, StringSplitOptions.None);
338+
queryPath = urlComponents[1];
338339
}
339340

340341
return queryPath;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
<None Update="UtilityFiles\postmanCollection_ver2.json">
4545
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
4646
</None>
47+
<None Update="UtilityFiles\postmanCollection_ver3.json">
48+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
49+
</None>
50+
<None Update="UtilityFiles\postmanCollection_ver4.json">
51+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
52+
</None>
4753
<None Update="UtilityFiles\Todo.xml">
4854
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
4955
</None>

test/Microsoft.OpenApi.Tests/Services/OpenApiFilterServiceTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,23 @@ public void ReturnFilteredOpenApiDocumentBasedOnPostmanCollection()
6969
Assert.Equal(3, subsetOpenApiDocument.Paths.Count);
7070
}
7171

72+
[Fact]
73+
public void ShouldParseNestedPostmanCollection()
74+
{
75+
// Arrange
76+
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver3.json");
77+
var fileInput = new FileInfo(filePath);
78+
var stream = fileInput.OpenRead();
79+
80+
// Act
81+
var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger);
82+
var pathCount = requestUrls.Count;
83+
84+
// Assert
85+
Assert.NotNull(requestUrls);
86+
Assert.Equal(30, pathCount);
87+
}
88+
7289
[Fact]
7390
public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument()
7491
{
@@ -86,6 +103,28 @@ public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument()
86103
Assert.Equal("The urls in the Postman collection supplied could not be found.", message);
87104
}
88105

106+
[Fact]
107+
public void ContinueProcessingWhenUrlsInCollectionAreMissingFromSourceDocument()
108+
{
109+
// Arrange
110+
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver4.json");
111+
var fileInput = new FileInfo(filePath);
112+
var stream = fileInput.OpenRead();
113+
114+
// Act
115+
var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger);
116+
var pathCount = requestUrls.Count;
117+
var predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: _openApiDocumentMock);
118+
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(_openApiDocumentMock, predicate);
119+
var subsetPathCount = subsetOpenApiDocument.Paths.Count;
120+
121+
// Assert
122+
Assert.NotNull(subsetOpenApiDocument);
123+
Assert.NotEmpty(subsetOpenApiDocument.Paths);
124+
Assert.Equal(2, subsetPathCount);
125+
Assert.NotEqual(pathCount, subsetPathCount);
126+
}
127+
89128
[Fact]
90129
public void ThrowsInvalidOperationExceptionInCreatePredicateWhenInvalidArgumentsArePassed()
91130
{

0 commit comments

Comments
 (0)