public void GetApiResponseTypes_HandlesActionWithMultipleContentTypesAndProduces()
        {
            // Arrange
            var actionDescriptor = GetControllerActionDescriptor(typeof(TestController), nameof(TestController.GetUser));

            actionDescriptor.FilterDescriptors.Add(new FilterDescriptor(new ProducesAttribute("text/xml")
            {
                Type = typeof(BaseModel)
            }, FilterScope.Action));
            actionDescriptor.FilterDescriptors.Add(new FilterDescriptor(new ProducesResponseTypeAttribute(typeof(ValidationProblemDetails), 400, "application/problem+json"), FilterScope.Action));
            actionDescriptor.FilterDescriptors.Add(new FilterDescriptor(new ProducesResponseTypeAttribute(typeof(ProblemDetails), 404, "application/problem+json"), FilterScope.Action));
            actionDescriptor.FilterDescriptors.Add(new FilterDescriptor(new ProducesResponseTypeAttribute(409), FilterScope.Action));

            var provider = new ApiResponseTypeProvider(new EmptyModelMetadataProvider(), new ActionResultTypeMapper(), new MvcOptions());

            // Act
            var result = provider.GetApiResponseTypes(actionDescriptor);

            // Assert
            Assert.Collection(
                result.OrderBy(r => r.StatusCode),
                responseType =>
            {
                Assert.Equal(typeof(BaseModel), responseType.Type);
                Assert.Equal(200, responseType.StatusCode);
                Assert.Equal(new[] { "text/xml" }, GetSortedMediaTypes(responseType));
            },
                responseType =>
            {
                Assert.Equal(typeof(ValidationProblemDetails), responseType.Type);
                Assert.Equal(400, responseType.StatusCode);
                Assert.Equal(new[] { "application/problem+json" }, GetSortedMediaTypes(responseType));
            },
                responseType =>
            {
                Assert.Equal(typeof(ProblemDetails), responseType.Type);
                Assert.Equal(404, responseType.StatusCode);
                Assert.Equal(new[] { "application/problem+json" }, GetSortedMediaTypes(responseType));
            },
                responseType =>
            {
                Assert.Equal(typeof(void), responseType.Type);
                Assert.Equal(409, responseType.StatusCode);
                Assert.Empty(GetSortedMediaTypes(responseType));
            });
        }
        private ApiDescription CreateApiDescription(
            ControllerActionDescriptor action,
            string httpMethod,
            string groupName)
        {
            var parsedTemplate = ParseTemplate(action);

            var apiDescription = new ApiDescription()
            {
                ActionDescriptor = action,
                GroupName        = groupName,
                HttpMethod       = httpMethod,
                RelativePath     = GetRelativePath(parsedTemplate),
            };

            var templateParameters = parsedTemplate?.Parameters?.ToList() ?? new List <TemplatePart>();

            var parameterContext = new ApiParameterContext(_modelMetadataProvider, action, templateParameters);

            foreach (var parameter in GetParameters(parameterContext))
            {
                apiDescription.ParameterDescriptions.Add(parameter);
            }

            var requestMetadataAttributes = GetRequestMetadataAttributes(action);

            var apiResponseTypes = _responseTypeProvider.GetApiResponseTypes(action);

            foreach (var apiResponseType in apiResponseTypes)
            {
                apiDescription.SupportedResponseTypes.Add(apiResponseType);
            }

            // It would be possible here to configure an action with multiple body parameters, in which case you
            // could end up with duplicate data.
            if (apiDescription.ParameterDescriptions.Count > 0)
            {
                var contentTypes = GetDeclaredContentTypes(requestMetadataAttributes);
                foreach (var parameter in apiDescription.ParameterDescriptions)
                {
                    if (parameter.Source == BindingSource.Body)
                    {
                        // For request body bound parameters, determine the content types supported
                        // by input formatters.
                        var requestFormats = GetSupportedFormats(contentTypes, parameter.Type);
                        foreach (var format in requestFormats)
                        {
                            apiDescription.SupportedRequestFormats.Add(format);
                        }
                    }
                    else if (parameter.Source == BindingSource.FormFile)
                    {
                        // Add all declared media types since FormFiles do not get processed by formatters.
                        foreach (var contentType in contentTypes)
                        {
                            apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat
                            {
                                MediaType = contentType,
                            });
                        }
                    }
                }
            }

            return(apiDescription);
        }