Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions src/Microsoft.OpenApi.Hidi/OpenApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,24 +397,47 @@ public static Dictionary<string, List<string>> ParseJsonCollectionFile(Stream st
logger.LogTrace("Parsing the json collection file into a JsonDocument");
using var document = JsonDocument.Parse(stream);
var root = document.RootElement;
var itemElement = root.GetProperty("item");
foreach (var requestObject in itemElement.EnumerateArray().Select(item => item.GetProperty("request")))
{
// Fetch list of methods and urls from collection, store them in a dictionary
var path = requestObject.GetProperty("url").GetProperty("raw").ToString();
var method = requestObject.GetProperty("method").ToString();

if (!requestUrls.ContainsKey(path))
requestUrls = EnumerateJsonDocument(root, requestUrls);
logger.LogTrace("Finished fetching the list of paths and Http methods defined in the Postman collection.");

return requestUrls;
}

private static Dictionary<string, List<string>> EnumerateJsonDocument(JsonElement itemElement, Dictionary<string, List<string>> paths)
{
var itemsArray = itemElement.GetProperty("item");

foreach (var item in itemsArray.EnumerateArray())
{
if(item.ValueKind == JsonValueKind.Object)
{
requestUrls.Add(path, new List<string> { method });
if(item.TryGetProperty("request", out var request))
{
// Fetch list of methods and urls from collection, store them in a dictionary
var path = request.GetProperty("url").GetProperty("raw").ToString();
var method = request.GetProperty("method").ToString();
if (!paths.ContainsKey(path))
{
paths.Add(path, new List<string> { method });
}
else
{
paths[path].Add(method);
}
}
else
{
EnumerateJsonDocument(item, paths);
}
}
else
{
requestUrls[path].Add(method);
EnumerateJsonDocument(item, paths);
}
}
logger.LogTrace("Finished fetching the list of paths and Http methods defined in the Postman collection.");
return requestUrls;

return paths;
}

/// <summary>
Expand Down
17 changes: 9 additions & 8 deletions src/Microsoft.OpenApi/Services/OpenApiFilterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,24 @@ public static class OpenApiFilterService
var rootNode = CreateOpenApiUrlTreeNode(sources);

// Iterate through urls dictionary and fetch operations for each url
foreach (var path in requestUrls)
foreach (var url in requestUrls)
{
var serverList = source.Servers;
var url = FormatUrlString(path.Key, serverList);
var path = ExtractPath(url.Key, serverList);

var openApiOperations = GetOpenApiOperations(rootNode, url, apiVersion);
var openApiOperations = GetOpenApiOperations(rootNode, path, apiVersion);
if (openApiOperations == null)
{
Console.WriteLine($"The url {url.Key} could not be found in the OpenApi description");
continue;
}

// Add the available ops if they are in the postman collection. See path.Value
foreach (var ops in openApiOperations)
{
if (path.Value.Contains(ops.Key.ToString().ToUpper()))
if (url.Value.Contains(ops.Key.ToString().ToUpper()))
{
operationTypes.Add(ops.Key + url);
operationTypes.Add(ops.Key + path);
}
}
}
Expand Down Expand Up @@ -322,7 +323,7 @@ private static bool AddReferences(OpenApiComponents newComponents, OpenApiCompon
return moreStuff;
}

private static string FormatUrlString(string url, IList<OpenApiServer> serverList)
private static string ExtractPath(string url, IList<OpenApiServer> serverList)
{
var queryPath = string.Empty;
foreach (var server in serverList)
Expand All @@ -333,8 +334,8 @@ private static string FormatUrlString(string url, IList<OpenApiServer> serverLis
continue;
}

var querySegments = url.Split(new[]{ serverUrl }, StringSplitOptions.None);
queryPath = querySegments[1];
var urlComponents = url.Split(new[]{ serverUrl }, StringSplitOptions.None);
queryPath = urlComponents[1];
}

return queryPath;
Expand Down
6 changes: 6 additions & 0 deletions test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
<None Update="UtilityFiles\postmanCollection_ver2.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="UtilityFiles\postmanCollection_ver3.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="UtilityFiles\postmanCollection_ver4.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="UtilityFiles\Todo.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
39 changes: 39 additions & 0 deletions test/Microsoft.OpenApi.Tests/Services/OpenApiFilterServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ public void ReturnFilteredOpenApiDocumentBasedOnPostmanCollection()
Assert.Equal(3, subsetOpenApiDocument.Paths.Count);
}

[Fact]
public void ShouldParseNestedPostmanCollection()
{
// Arrange
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver3.json");
var fileInput = new FileInfo(filePath);
var stream = fileInput.OpenRead();

// Act
var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger);
var pathCount = requestUrls.Count;

// Assert
Assert.NotNull(requestUrls);
Assert.Equal(30, pathCount);
}

[Fact]
public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument()
{
Expand All @@ -86,6 +103,28 @@ public void ThrowsExceptionWhenUrlsInCollectionAreMissingFromSourceDocument()
Assert.Equal("The urls in the Postman collection supplied could not be found.", message);
}

[Fact]
public void ContinueProcessingWhenUrlsInCollectionAreMissingFromSourceDocument()
{
// Arrange
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles\\postmanCollection_ver4.json");
var fileInput = new FileInfo(filePath);
var stream = fileInput.OpenRead();

// Act
var requestUrls = OpenApiService.ParseJsonCollectionFile(stream, _logger);
var pathCount = requestUrls.Count;
var predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: _openApiDocumentMock);
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(_openApiDocumentMock, predicate);
var subsetPathCount = subsetOpenApiDocument.Paths.Count;

// Assert
Assert.NotNull(subsetOpenApiDocument);
Assert.NotEmpty(subsetOpenApiDocument.Paths);
Assert.Equal(2, subsetPathCount);
Assert.NotEqual(pathCount, subsetPathCount);
}

[Fact]
public void ThrowsInvalidOperationExceptionInCreatePredicateWhenInvalidArgumentsArePassed()
{
Expand Down
Loading