public void InvalidDocumentationShouldYieldFailure(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile,
            DocumentGenerationDiagnostic expectedDocumentGenerationResult,
            IList <OperationGenerationDiagnostic> expectedFailureOperationGenerationResults)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var input = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1);

            GenerationDiagnostic result;

            var generator = new OpenApiGenerator();

            var openApiDocuments = generator.GenerateDocuments(input, out result);

            openApiDocuments.Should().NotBeNull();

            result.DocumentGenerationDiagnostic.Should().BeEquivalentTo(expectedDocumentGenerationResult);
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();

            var failurePaths = result.OperationGenerationDiagnostics.Where(
                p => p.Errors.Count > 0)
                               .ToList();

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);


            _output.WriteLine(actualDocument);

            failurePaths.Should().BeEquivalentTo(expectedFailureOperationGenerationResults);

            // We are doing serialization and deserialization to force the resulting actual document
            // to have the exact fields we will see in the resulting document based on the contract resolver.
            // Without serialization and deserialization, the actual document may have fields that should
            // not be present, such as empty list fields.
            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(openApiStringReader.Read(expectedDocument, out var _));
        }
Beispiel #2
0
        public void GenerateDocumentWithOperationConfigShouldSucceed(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string configXmlFile,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));
            var configDocument = XDocument.Load(configXmlFile);

            var generator = new OpenApiGenerator();
            var input     = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1)
            {
                AdvancedConfigurationXmlDocument = configDocument
            };

            GenerationDiagnostic result;

            var openApiDocuments = generator.GenerateDocuments(
                input,
                out result);

            result.Should().NotBeNull();
            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);
            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);

            _output.WriteLine(actualDocument);

            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(
                openApiStringReader.Read(expectedDocument, out var _),
                o => o.WithStrictOrdering());
        }
        public void ValidDocumentationShouldReturnCorrectDocument(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string openApiDocumentVersion,
            int expectedOperationGenerationResultsCount,
            string expectedJsonFile)
        {
            _output.WriteLine(testCaseName);

            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var input = new OpenApiGeneratorConfig(
                documents,
                inputBinaryFiles,
                openApiDocumentVersion,
                FilterSetVersion.V1);

            GenerationDiagnostic result;

            var generator        = new OpenApiGenerator();
            var openApiDocuments = generator.GenerateDocuments(input, out result);

            result.Should().NotBeNull();

            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);

            openApiDocuments[DocumentVariantInfo.Default].Should().NotBeNull();

            result.OperationGenerationDiagnostics.Count(p => p.Errors.Count > 0).Should().Be(0);
            result.OperationGenerationDiagnostics.Count.Should().Be(expectedOperationGenerationResultsCount);

            var actualDocument = openApiDocuments[DocumentVariantInfo.Default]
                                 .SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            var expectedDocument = File.ReadAllText(expectedJsonFile);

            _output.WriteLine(actualDocument);

            var openApiStringReader = new OpenApiStringReader();

            var actualDeserializedDocument = openApiStringReader.Read(
                actualDocument,
                out OpenApiDiagnostic diagnostic);

            diagnostic.Errors.Count.Should().Be(0);

            actualDeserializedDocument
            .Should()
            .BeEquivalentTo(openApiStringReader.Read(expectedDocument, out var _));
        }
Beispiel #4
0
        public void BadSchema()
        {
            var input = @"openapi: 3.0.0
info:
  title: foo
  version: bar
paths:
  '/foo':
    get:
      responses:
        200: 
          description: ok
          content:
            application/json:  
              schema: asdasd
";

            var reader = new OpenApiStringReader();

            reader.Read(input, out var diagnostic);

            diagnostic.Errors.Should().BeEquivalentTo(new List <OpenApiError>()
            {
                new OpenApiError(new OpenApiReaderException("schema must be a map/object")
                {
                    Pointer = "#/paths/~1foo/get/responses/200/content/application~1json/schema"
                })
            });
        }
Beispiel #5
0
        public OpenApiDocument ConvertToOpenAPISpec(string json)
        {
            OpenApiStringReader reader = new OpenApiStringReader();
            OpenApiDocument     doc    = reader.Read(json, out var diagnostic);

            return(doc);
        }
        private static OpenApiDocument LoadOpenApiDocument(string json)
        {
            var             reader   = new OpenApiStringReader();
            OpenApiDocument document = reader.Read(json, out OpenApiDiagnostic _);

            return(document);
        }
Beispiel #7
0
        public void ParseCustomExtension()
        {
            var description = @"
openapi: 3.0.0
info: 
    title: A doc with an extension
    version: 1.0.0
    x-foo: 
        bar: hey
        baz: hi!
paths: {}
";
            var settings    = new OpenApiReaderSettings()
            {
                ExtensionParsers = { { "x-foo", (a, v) => {
                                           var fooNode = (OpenApiObject)a;
                                           return(new FooExtension()
                            {
                                Bar = (fooNode["bar"] as OpenApiString)?.Value,
                                Baz = (fooNode["baz"] as OpenApiString)?.Value
                            });
                                       } } }
            };

            var reader = new OpenApiStringReader(settings);

            var diag = new OpenApiDiagnostic();
            var doc  = reader.Read(description, out diag);

            var fooExtension = doc.Info.Extensions["x-foo"] as FooExtension;

            fooExtension.Should().NotBeNull();
            fooExtension.Bar.Should().Be("hey");
            fooExtension.Baz.Should().Be("hi!");
        }
        public void ShouldThrowWhenReferenceDoesNotExist()
        {
            var input = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
paths: 
  '/':
    get:
      produces: ['application/json']
      responses:
        '200':
          description: ok
          schema:
            $ref: '#/definitions/doesnotexist'
";

            var reader = new OpenApiStringReader();

            var doc = reader.Read(input, out var diagnostic);

            diagnostic.Errors.ShouldBeEquivalentTo(new List <OpenApiError> {
                new OpenApiError(new OpenApiException("Invalid Reference identifier 'doesnotexist'."))
            });
            doc.Should().NotBeNull();
        }
        public void ShouldThrowWhenReferenceTypeIsInvalid()
        {
            var input = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
paths: 
  '/':
    get:
      responses:
        '200':
          description: ok
          schema:
            $ref: '#/defi888nition/does/notexist'
";

            var reader = new OpenApiStringReader();
            var doc    = reader.Read(input, out var diagnostic);

            diagnostic.Errors.ShouldBeEquivalentTo(new List <OpenApiError> {
                new OpenApiError(new OpenApiException("Unknown reference type 'defi888nition'"))
            });
            doc.Should().NotBeNull();
        }
Beispiel #10
0
        public void MultipleServers()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
schemes:
  - http
  - https
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
                BaseUrl = new Uri("https://dev.bing.com/api")
            });

            var doc = reader.Read(input, out var diagnostic);

            var server = doc.Servers.First();

            Assert.Equal(2, doc.Servers.Count);
            Assert.Equal("http://dev.bing.com/api", server.Url);
            Assert.Equal("https://dev.bing.com/api", doc.Servers.Last().Url);
        }
Beispiel #11
0
        public void InvalidHostShouldYieldError()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
host: http://test.microsoft.com
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
                BaseUrl = new Uri("https://bing.com")
            });

            var doc = reader.Read(input, out var diagnostic);

            doc.Servers.Count.Should().Be(0);
            diagnostic.Should().BeEquivalentTo(
                new OpenApiDiagnostic
            {
                Errors =
                {
                    new OpenApiError("#/", "Invalid host")
                },
                SpecificationVersion = OpenApiSpecVersion.OpenApi2_0
            });
        }
Beispiel #12
0
        private static OpenApiDocument Deserialize(string data)
        {
            var reader = new OpenApiStringReader(new OpenApiReaderSettings().AddTypedRest());
            var doc    = reader.Read(data, out _);

            doc.GetTypedRest(); // Resolves references
            return(doc);
        }
        /// <summary>
        /// Reads json into an OpenApiDocument Object using the OpenApiStringReader from Microsoft.OpenApi.Readers
        /// </summary>
        /// <param name="reader">The JsonReader that reads the incoming json</param>
        /// <returns></returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var openApiStringReader = new OpenApiStringReader();
            var openApiString       = JObject.Load(reader).ToString();
            var openApiDocument     = openApiStringReader.Read(openApiString, out var diagnostic);

            openApiDocument.Tags.Add(new OpenApiTag()
            {
                Name = "openapi", Description = diagnostic.SpecificationVersion.ToString()
            });
            return(openApiDocument);
        }
        /// <summary>
        /// Deserializes the json to a<see cref="OpenApiDocument"/>
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static OpenApiDocument ReadFromJson(string json)
        {
            var openApiReader = new OpenApiStringReader();
            var document      = openApiReader.Read(json, out var diagnostic);

            if (diagnostic.Errors.Count > 0)
            {
                throw new JsonReaderException("Error reading OpenApi document. " + string.Join(Environment.NewLine, diagnostic.Errors.Select(e => e.Message)));
            }

            return(document);
        }
        public void Read(string filename, List <ITransferObject> transferObjects)
        {
            if (!FileSystem.FileExists(filename))
            {
                return;
            }
            string json = FileSystem.ReadAllText(filename);
            OpenApiStringReader reader   = new OpenApiStringReader();
            OpenApiDocument     document = reader.Read(json, out OpenApiDiagnostic diagnostic);

            diagnostic.Errors?.ForEach(error => Logger.Error(error.Message));
            transferObjects.Add(TransferObject.Create(document));
        }
Beispiel #16
0
        public void Can_Write_OpenApiDocument_To_Json()
        {
            var document = new ApiDocumentBuilder().Build();
            var json     = JsonConvert.SerializeObject(document, new OpenApiDocumentJsonConverter());

            var reader      = new OpenApiStringReader();
            var newDocument = reader.Read(json, out var diagnostic);

            diagnostic.Errors.Should().BeEmpty();

            newDocument.Should().NotBeNull();
            newDocument.Info.Should().NotBeNull();
            newDocument.Info.Title.Should().Be("My Api");
        }
Beispiel #17
0
        public async Task CanConvertSpec()
        {
            var swaggerJson = await GetSwaggerJson();

            var reader       = new OpenApiStringReader();
            var document     = reader.Read(swaggerJson, out _);
            var openApi3Yaml = document.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Yaml);
            var openApi3Json = document.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json);
            var openApi2Yaml = document.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Json);

            File.WriteAllText("openapi3-spec.yaml", openApi3Yaml, Encoding.UTF8);
            File.WriteAllText("openapi3-spec.json", openApi3Json, Encoding.UTF8);
            File.WriteAllText("openapi2-spec.yaml", openApi2Yaml, Encoding.UTF8);
            Assert.IsFalse(string.IsNullOrWhiteSpace(openApi3Yaml));
            Assert.IsFalse(string.IsNullOrWhiteSpace(openApi2Yaml));
            Assert.IsFalse(string.IsNullOrWhiteSpace(openApi3Json));
        }
Beispiel #18
0
        public void NoServer()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
            });

            var doc = reader.Read(input, out var diagnostic);

            Assert.Empty(doc.Servers);
        }
Beispiel #19
0
        public void JustSchemeNoDefault()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
schemes:
  - http
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
            });

            var doc = reader.Read(input, out var diagnostic);

            Assert.Equal(0, doc.Servers.Count);
        }
Beispiel #20
0
        public async Task CanReadSpec()
        {
            var swaggerJson = await GetSwaggerJson();

            var reader   = new OpenApiStringReader();
            var document = reader.Read(swaggerJson, out var diagnostic);

            if (diagnostic.Errors.Count > 0)
            {
                TestContext.WriteLine("Dignostic errors:");
                foreach (var openApiError in diagnostic.Errors)
                {
                    TestContext.WriteLine($"{openApiError.Message} ({openApiError.Pointer})");
                }
                Assert.Fail("diagnostic errors");
            }
            Assert.AreEqual(OpenApiSpecVersion.OpenApi2_0, diagnostic.SpecificationVersion);
            Assert.IsTrue(document.Paths.Count > 0);
        }
Beispiel #21
0
        public void JustBasePathNoDefault()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
basePath: /baz
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
            });

            var doc = reader.Read(input, out var diagnostic);

            var server = doc.Servers.First();

            Assert.Equal(1, doc.Servers.Count);
            Assert.Equal("/baz", server.Url);
        }
Beispiel #22
0
        public void BrokenSimpleList()
        {
            var input = @"swagger: 2.0
info:
  title: hey
  version: 1.0.0
schemes: [ { ""hello"" }]
paths: { }";

            var reader = new OpenApiStringReader();

            reader.Read(input, out var diagnostic);

            diagnostic.Errors.Should().BeEquivalentTo(new List <OpenApiError>()
            {
                new OpenApiError(new OpenApiReaderException("Expected a value.")
                {
                    Pointer = "#line=4"
                })
            });
        }
Beispiel #23
0
        public void LocalHostWithCustomHost()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
host: localhost:23232
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
                BaseUrl = new Uri("https://bing.com")
            });

            var doc = reader.Read(input, out var diagnostic);

            var server = doc.Servers.First();

            Assert.Equal(1, doc.Servers.Count);
            Assert.Equal("https://localhost:23232", server.Url);
        }
        public void Read(string url)
        {
            HttpWebRequest request = WebRequest.CreateHttp(url);

            request.CookieContainer = new CookieContainer();
            transferObjects.OfType <TransferObject <Cookie> >().ForEach(x => request.CookieContainer.Add(x.Value));
            WebResponse response = request.GetResponse();

            string json;

            using (Stream responseStream = response.GetResponseStream())
                using (StreamReader streamReader = new StreamReader(responseStream))
                {
                    json = streamReader.ReadToEnd();
                }
            OpenApiStringReader reader   = new OpenApiStringReader();
            OpenApiDocument     document = reader.Read(json, out OpenApiDiagnostic diagnostic);

            diagnostic.Errors?.ForEach(error => Logger.Error(error.Message));

            transferObjects.Add(TransferObject.Create(document));
        }
Beispiel #25
0
        public void JustSchemeWithCustomHostWithEmptyPath()
        {
            var input  = @"
swagger: 2.0
info: 
  title: test
  version: 1.0.0
schemes:
  - http
paths: {}
";
            var reader = new OpenApiStringReader(new OpenApiReaderSettings()
            {
                BaseUrl = new Uri("https://bing.com")
            });

            var doc = reader.Read(input, out var diagnostic);

            var server = doc.Servers.First();

            Assert.Equal(1, doc.Servers.Count);
            Assert.Equal("http://bing.com", server.Url);
        }
Beispiel #26
0
        public static OpenApiDocument ReadSpec(string spec)
        {
            try
            {
                var doc = Reader.Read(spec, out var diag);
                if (diag.Errors.Any())
                {
                    throw new AggregateException(diag.Errors.Select(x => new OpenApiFormatException(x)));
                }

                return(doc);
            }
            catch (ArgumentException)
            {
                // Cannot read file.
                // Probably spec version is not specified.
                // Each spec must contain either `openapi: \"x.x.x\"` or `swagger: 2.0`
                return(null);
            }
            catch (NullReferenceException)
            {
                throw new OpenApiFormatException("Cannot read file. Probably some refs point nowhere.");
            }
        }
Beispiel #27
0
        public static RestApi parseToRestApi(string text)
        {
            RestApi             api    = new RestApi();
            OpenApiStringReader reader = new OpenApiStringReader();
            var document = reader.Read(text, out var diagnostic);

            api.Title       = document.Info.Title;
            api.Version     = document.Info.Version;
            api.Description = document.Info.Description;

            if (document.Servers.Count > 0)
            {
                api.ServerUrl = document.Servers[0].Url;
            }

            foreach (KeyValuePair <string, OpenApiPathItem> pairPath in document.Paths)
            {
                foreach (KeyValuePair <OperationType, OpenApiOperation> pairOperation in pairPath.Value.Operations)
                {
                    RestApiPath apiPath = new RestApiPath();
                    apiPath.Path        = pairPath.Key;
                    apiPath.Method      = pairOperation.Key.ToString();
                    apiPath.Description = pairOperation.Value.Description;

                    foreach (OpenApiParameter para in pairOperation.Value.Parameters)
                    {
                        RestApiParameter apiParameter = new RestApiParameter();

                        apiParameter.Id          = para.Name;
                        apiParameter.Description = para.Description;

                        apiPath.Parameters.Add(apiParameter);
                    }

                    if (pairOperation.Value.RequestBody != null && pairOperation.Value.RequestBody.Content.Count > 0)
                    {
                        RestApiBody apiBody = new RestApiBody();

                        foreach (KeyValuePair <string, OpenApiMediaType> bodyContentPair in pairOperation.Value.RequestBody.Content)
                        {
                            apiBody.ContentType = bodyContentPair.Key;

                            var            stream = new MemoryStream();
                            IOpenApiWriter writer = new OpenApiJsonWriter(new StreamWriter(stream));

                            if (bodyContentPair.Value.Example != null)
                            {
                                writer.WriteAny(bodyContentPair.Value.Example);
                            }
                            else
                            {
                                bodyContentPair.Value.Schema.SerializeAsV2WithoutReference(writer);
                            }

                            writer.Flush();
                            stream.Position = 0;

                            var value = new StreamReader(stream).ReadToEnd();

                            apiBody.Example = value;

                            break;
                        }

                        apiPath.Bodys.Add(apiBody);
                    }


                    foreach (KeyValuePair <string, OpenApiResponse> respPair in pairOperation.Value.Responses)
                    {
                        RestApiResponse apiResponse = new RestApiResponse();
                        apiResponse.Status = respPair.Key;


                        if (respPair.Value.Content.Count > 0)
                        {
                            foreach (KeyValuePair <string, OpenApiMediaType> respBodyPair in respPair.Value.Content)
                            {
                                apiResponse.ContentType = respBodyPair.Key;

                                var            stream = new MemoryStream();
                                IOpenApiWriter writer = new OpenApiJsonWriter(new StreamWriter(stream));

                                if (respBodyPair.Value.Example != null)
                                {
                                    writer.WriteAny(respBodyPair.Value.Example);
                                }
                                else if (respBodyPair.Value.Schema != null)
                                {
                                    respBodyPair.Value.Schema.SerializeAsV2WithoutReference(writer);
                                }

                                writer.Flush();
                                stream.Position = 0;

                                var value = new StreamReader(stream).ReadToEnd();

                                apiResponse.Example = value;

                                break;
                            }
                        }

                        apiPath.Responses.Add(apiResponse);
                    }


                    api.Paths.Add(apiPath);
                }
            }

            return(api);
        }
        /// <summary>
        /// Activity function that implements CNCF Serverless workflow RESTful service invocation.
        /// https://github.com/serverlessworkflow/specification/blob/master/specification.md#using-functions-for-restful-service-invocations
        /// </summary>
        public static async Task <JToken> RESTfulServiceInvoker(IDurableActivityContext context, ILogger logger)
        {
            InvokeFunctionArgs?args = context.GetInput <InvokeFunctionArgs>();

            if (!Uri.TryCreate(args?.Operation, UriKind.Absolute, out Uri target))
            {
                throw new ArgumentException($"Function calls must include an '{nameof(args.Operation).ToLowerInvariant()}' field that is in the form of an absolute URI. Given function operation: '{args?.Operation}'.");
            }

            // CONSIDER: Cache the specs to reduce I/O when a particular file is reused multiple times.
            string specContentText;

            if (target.IsFile)
            {
                // file://myapis/greetingapis.json#greeting -> myapis/greetingapis.json
                string path = string.Concat(target.Host, target.AbsolutePath);
                specContentText = await File.ReadAllTextAsync(path);
            }
            // TODO: Add support for HTTP and HTTPS
            else
            {
                throw new NotSupportedException($"The scheme '{target.Scheme}' is not supported for function operations.");
            }

            string          targetOperationId = target.Fragment.TrimStart('#');
            var             openApiSpecReader = new OpenApiStringReader();
            OpenApiDocument?document          = openApiSpecReader.Read(specContentText, out _);

            // TODO: What is the expectation if there are multiple server values?
            Uri baseUrl = new Uri(document.Servers.FirstOrDefault()?.Url ?? "/");
            HttpRequestMessage?request     = null;
            JObject?           jsonContent = null;

            foreach ((string pathKey, OpenApiPathItem pathItem) in document.Paths)
            {
                foreach ((OperationType type, OpenApiOperation operation) in pathItem.Operations)
                {
                    if (targetOperationId.Equals(operation.OperationId, StringComparison.OrdinalIgnoreCase))
                    {
                        string relativePath = pathKey.TrimStart('/');
                        foreach ((string name, object?value) in args !.Parameters ?? ImmutableDictionary <string, object> .Empty)
                        {
                            if (operation.Parameters.Any(p => p.In == ParameterLocation.Path &&
                                                         p.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
                            {
                                // TODO: There are various supported ways of serializing Path parameters
                                //       https://swagger.io/docs/specification/describing-parameters/#path-parameters
                                relativePath = relativePath.Replace($"{{{name}}}", $"{value}");
                            }
                            else
                            {
                                // TODO: Support for more than just JObject
                                if (jsonContent == null)
                                {
                                    jsonContent = new JObject();
                                }

                                jsonContent.Add(name, JToken.FromObject(value));
                            }
                        }

                        var url    = new Uri(baseUrl, relativePath);
                        var method = new HttpMethod(type.ToString());
                        request = new HttpRequestMessage(method, url);
                        request.Headers.Add("x-ms-workflow-instance-id", context.InstanceId);

                        if (jsonContent != null)
                        {
                            request.Content = new StringContent(
                                jsonContent.ToString(Formatting.None),
                                Encoding.UTF8,
                                "application/json");
                        }

                        break;
                    }
                }

                if (request != null)
                {
                    break;
                }
            }

            if (request == null)
            {
                throw new ArgumentException($"Could not find an operation with ID '{targetOperationId}'.");
            }

            using HttpResponseMessage response = await httpClient.SendAsync(request);

            string responseText = await response.Content.ReadAsStringAsync();

            JToken result = JValue.CreateNull();

            if (response.Content?.Headers?.ContentType?.MediaType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) == true &&
                response.Content?.Headers?.ContentLength != 0)
            {
                try
                {
                    result = JToken.Parse(responseText);
                }
                catch (JsonReaderException e)
                {
                    logger.LogError(e, "The HTTP response contained a payload but it was not valid JSON and will be ignored.");
                }
            }

            return(result);
        }
        public void GenerateDocumentMultipleVariantsShouldSucceed(
            string testCaseName,
            IList <string> inputXmlFiles,
            IList <string> inputBinaryFiles,
            string configXmlFile,
            int expectedOperationGenerationResultsCount,
            IDictionary <DocumentVariantInfo, string> documentVariantInfoToExpectedJsonFileMap)
        {
            _output.WriteLine(testCaseName);

            // Arrange
            var documents = new List <XDocument>();

            documents.AddRange(inputXmlFiles.Select(XDocument.Load));

            var configPath     = configXmlFile;
            var configDocument = XDocument.Load(configPath);

            var generator = new OpenApiGenerator();
            var input     = new OpenApiGeneratorConfig(documents, inputBinaryFiles, "1.0.0", FilterSetVersion.V1)
            {
                AdvancedConfigurationXmlDocument = configDocument
            };
            GenerationDiagnostic result;

            // Act
            var openApiDocuments = generator.GenerateDocuments(input, out result);

            result.Should().NotBeNull();
            result.DocumentGenerationDiagnostic.Errors.Count.Should().Be(0);
            result.OperationGenerationDiagnostics.Count(r => r.Errors.Count == 0)
            .Should()
            .Be(expectedOperationGenerationResultsCount);

            openApiDocuments.Keys.Should()
            .BeEquivalentTo(documentVariantInfoToExpectedJsonFileMap.Keys);

            var actualDocuments   = new List <OpenApiDocument>();
            var expectedDocuments = new List <OpenApiDocument>();

            foreach (var documentVariantInfoToExpectedJsonFile in documentVariantInfoToExpectedJsonFileMap)
            {
                // Verify each document variant against a json file content.
                var documentVariantInfo = documentVariantInfoToExpectedJsonFile.Key;
                var expectedJsonFile    = documentVariantInfoToExpectedJsonFile.Value;

                openApiDocuments.TryGetValue(documentVariantInfo, out var specificationDocument);

                var actualDocumentAsString = specificationDocument.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);

                _output.WriteLine(actualDocumentAsString);

                var openApiStringReader = new OpenApiStringReader();

                var actualDeserializedDocument = openApiStringReader.Read(
                    actualDocumentAsString,
                    out OpenApiDiagnostic diagnostic);

                diagnostic.Errors.Count.Should().Be(0);

                actualDeserializedDocument
                .Should()
                .BeEquivalentTo(openApiStringReader.Read(File.ReadAllText(expectedJsonFile), out var _));

                // Bug in fluent assertion method. Comparing the array of documents yields incorrect result.
                // Root cause unknown. This should be enabled once that bug is resolved.
                //actualDocuments.Add(actualDocument);

                //expectedDocuments.Add(expectedDocument);
            }

            //actualDocuments.Should().BeEquivalentTo(expectedDocuments);
        }