Пример #1
0
        private void Initialize(Assembly functionsAssembly, string routePrefix)
        {
            var methods = functionsAssembly.GetTypes()
                          .SelectMany(t => t.GetMethods())
                          .Where(m => m.GetCustomAttributes(typeof(FunctionNameAttribute), false).Any())
                          .ToList();

            IList <ApiDescriptionGroup> apiDescrGroup = new List <ApiDescriptionGroup>();

            foreach (MethodInfo methodInfo in methods)
            {
                if (!TryGetHttpTrigger(methodInfo, out var triggerAttribute))
                {
                    continue;
                }

                var functionAttr = (FunctionNameAttribute)methodInfo.GetCustomAttribute(typeof(FunctionNameAttribute), false);
                var prefix       = string.IsNullOrWhiteSpace(routePrefix) ? "" : $"{routePrefix.TrimEnd('/')}/";
                var route        = $"{prefix}{(!string.IsNullOrWhiteSpace(triggerAttribute.Route) ? triggerAttribute.Route : functionAttr.Name)}";
                var verbs        = triggerAttribute.Methods ?? new[] { "get", "post", "delete", "head", "patch", "put", "options" };
                var items        = new List <ApiDescription>();
                foreach (string verb in verbs)
                {
                    var description = CreateDescription(methodInfo, route, functionAttr, verb);
                    items.Add(description);
                }

                var group = new ApiDescriptionGroup(functionAttr.Name, items);
                apiDescrGroup.Add(group);
            }

            // TODO: is Version necessery?
            ApiDescriptionGroups = new ApiDescriptionGroupCollection(new ReadOnlyCollection <ApiDescriptionGroup>(apiDescrGroup), 1);
        }
Пример #2
0
        private void AddActionScript(StringBuilder script, ApiDescriptionGroup controller, ApiDescription action)
        {
            script.AppendLine($"    //action {action.ActionDescriptor.DisplayName}");

            AddCallParameters(script, controller, action);
            script.AppendLine("        }");
        }
        private IApiDescriptionGroupCollectionProvider CreateApiDescriptionProvider(MethodInfo methodInfo)
        {
            var descriptionGroup = new ApiDescriptionGroup(
                "MyGroup",
                new List <ApiDescription>()
            {
                new ApiDescription()
                {
                    HttpMethod       = MvcUrlTemplate.HttpMethod,
                    ActionDescriptor = new ControllerActionDescriptor()
                    {
                        MethodInfo         = methodInfo,
                        AttributeRouteInfo = new AttributeRouteInfo()
                        {
                            Template = MvcUrlTemplate.Url
                        }
                    }
                }
            });

            var groupProvider = new Mock <IApiDescriptionGroupCollectionProvider>(MockBehavior.Strict);

            groupProvider
            .SetupGet(p => p.ApiDescriptionGroups)
            .Returns(new ApiDescriptionGroupCollection(new[] { descriptionGroup }, 1));

            return(groupProvider.Object);
        }
Пример #4
0
 private void AddControllerScript(StringBuilder script, ApiDescriptionGroup controller)
 {
     foreach (var action in controller.Items)
     {
         script.AppendLine();
         AddActionScript(script, controller, action);
     }
 }
Пример #5
0
 IEnumerable <Item> CreateGroupItem(ApiDescriptionGroup group, XmlDocument documentation)
 {
     foreach (IGrouping <string, ApiDescription> controller in group.Items.GroupBy(Settings.GroupExtractor))
     {
         yield return(new Folder
         {
             Name = controller.Key,
             Item = controller.Select(i => CreateItem(i, documentation)).ToArray()
         });
     }
 }
Пример #6
0
        private static bool TryGetControllerType(ApiDescriptionGroup apiDescriptionGroup, out Type controllerType)
        {
            controllerType = null;

            var controllerActionDescriptor = apiDescriptionGroup.Items.Select(o => o.ActionDescriptor).OfType <ControllerActionDescriptor>().FirstOrDefault();

            if (controllerActionDescriptor != null)
            {
                controllerType = controllerActionDescriptor.ControllerTypeInfo.AsType();
            }
            return(controllerType != null);
        }
        private void FindAllModelsFromGetResponses(List <string> models, ApiDescriptionGroup versionGroup)
        {
            // items in current API Version
            foreach (ApiDescription description in GetAllGetMethods(versionGroup))
            {
                var response = description.SupportedResponseTypes.SingleOrDefault(x => x.StatusCode == 200 && x.Type.Namespace.ToLower().Contains("x.pagedlist"));

                if (response != null)
                {
                    models.Add(response.Type.GenericTypeArguments.First().Name);
                }
            }
        }
Пример #8
0
        private ApiDescriptionGroupModel CreateApiDescriptionGroupModel(ApiDescriptionGroup apiDescriptionGroup)
        {
            var apiDescriptionGroupModel = new ApiDescriptionGroupModel(
                apiDescriptionGroup.GroupName,
                apiDescriptionGroup.Items
                .Select(CreateApiDescriptionModel)
                .ToList()
                .AsReadOnly());
            Type controllerType;

            if (TryGetControllerType(apiDescriptionGroup, out controllerType))
            {
                apiDescriptionGroupModel.Description = _documentationProvider.GetDocumentation(controllerType.GetTypeInfo());
            }
            return(apiDescriptionGroupModel);
        }
        private ApiDescriptionGroupCollection BuildGroup()
        {
            var apis = new List <ApiDescription>();

            foreach (var endpoint in manifest)
            {
                var actionDescriptor = new ActionDescriptor
                {
                    DisplayName = endpoint.Name,
                    RouteValues = GetRouteValues(endpoint)
                };
                apis.AddRange(GetApiDescriptions(endpoint, actionDescriptor));
            }

            var group = new ApiDescriptionGroup(groupName, apis);

            return(new ApiDescriptionGroupCollection(new[] { group }, 1));
        }
Пример #10
0
        /// <summary>
        /// get a ApiDescriptionGroup from your dependency injection and use it to query all used types
        /// </summary>
        /// <param name="apiDescription"></param>
        /// <param name="mediaTypesToCheck"></param>
        /// <returns></returns>
        public DistinctTypeList GetUsedContractTypes(ApiDescriptionGroup apiDescription, string?mediaTypesToCheck = null)
        {
            var apiDescriptions = apiDescription.Items
                                  .Where(w => w is not null)
            ;
            var usedTypes = new DistinctTypeList();

            foreach (var description in apiDescriptions !)
            {
                var bodyParameter = description.ParameterDescriptions.Where(IsBodyParameter);
                usedTypes.AddRange(bodyParameter.Select(s => s.Type));
                //TODO option to check for default Asp.net classes
                var responseParameter = description.SupportedResponseTypes.Where(w => w.Type != null && IsCorrectMediaType(mediaTypesToCheck, w));
                usedTypes.AddRange(responseParameter.Select(s => s.Type));
            }

            return(usedTypes);
        }
Пример #11
0
        private RAMLDocument GenerateDocument(ApiDescriptionGroup group)
        {
            var doc = new RAMLDocument
            {
                Title = group.GroupName
            };

            foreach (var item in group.Items)
            {
                var key      = "/" + item.RelativePath;
                var resource = doc.GetOrAddResource(key);
                SetUriPatameters(item, resource);
                SetMethod(item, resource);
            }

            OtherHandle(doc);

            return(doc);
        }
Пример #12
0
        private JToken Handle(ApiDescriptionGroup group)
        {
            var items = group.Items.AsEnumerable();

            // Remove the obsolete
            if (_options.IgnoreObsoleteApi)
            {
                items = items.Where(item => !item.IsObsolete());
            }

            var json = new JObject();

            foreach (var item in items)
            {
                json.Add($"{item.HttpMethod} {item.RelativePath}", Handle(item));
            }

            return(json);
        }
        public void ApiDescriptionGroups_ReturnsAllApiDescriptionGroups()
        {
            var expectedApiDescriptions = new List <ApiDescriptionGroup>();

            A.CallTo(() => _functionProcessor.ProcessHttpFunction(A <MethodInfo> ._))
            .ReturnsLazily(() =>
            {
                var returnValue = new ApiDescriptionGroup("a", new List <ApiDescription>());
                expectedApiDescriptions.Add(returnValue);
                return(returnValue);
            });


            var result = _sut.ApiDescriptionGroups;

            result.Should().NotBeNull();
            A.CallTo(() => _functionProcessor.ProcessHttpFunction(A <MethodInfo> ._))
            .MustHaveHappened(_expectedMethodNames.Length, Times.Exactly);
            result.Items.Should().BeEquivalentTo(expectedApiDescriptions);
        }
Пример #14
0
        private ControllerDefinition CreateControllerDefinition(ApiDescriptionGroup apiDescriptions)
        {
            var controllerDefinition = new ControllerDefinition();

            // Group further by http method
            //var perMethodGrouping = apiDescriptions
            //    .GroupBy(apiDesc => apiDesc.GroupName);

            var actions = new List <ActionMethodDefinition>();

            foreach (var group in apiDescriptions.Items)
            {
                var httpMethod = group.HttpMethod;

                //if (httpMethod == null)
                //    throw new NotSupportedException(string.Format(
                //        "Unbounded HTTP verbs for path '{0}'. Are you missing an HttpMethodAttribute?",
                //        group.First()
                //        //.RelativePathSansQueryString()
                //        ));

                //if (group.Count() > 1)
                //    throw new NotSupportedException(string.Format(
                //        "Multiple operations with path '{0}' and method '{1}'. Are you overloading action methods?",
                //        group.First()
                //        //.RelativePathSansQueryString()
                //        , httpMethod));

                //var apiDescription = group.Single();

                actions.Add(CreateActionMethodDefinition(group
                                                         //, schemaRegistry
                                                         ));
            }
            controllerDefinition.Name          = apiDescriptions.GroupName;
            controllerDefinition.ActionMethods = actions;
            return(controllerDefinition);
        }
Пример #15
0
        public ApiDescriptionGroupCollection Generate()
        {
            var descriptions = new List <ApiDescription>();

            foreach (var method in _functionDataProvider.GetMethods())
            {
                var route                    = method.TriggerAttribute.Route;
                var routeParameters          = _tokenParser.Parse(route);
                var apiParameterDescriptions = new List <ApiParameterDescription>();
                var apiResponseTypes         = new List <ApiResponseType>();

                // map body if available
                var bodyAttributes = method
                                     .MethodInfo
                                     .GetCustomAttributes(typeof(SwaggerRequestAttribute), false)
                                     .Where(x => (x as SwaggerRequestAttribute)?.In == RequestSource.Body)
                                     .Select(x => x as SwaggerRequestAttribute);

                foreach (var parameterMapping in _parameterMappings)
                {
                    try
                    {
                        apiParameterDescriptions.AddRange(parameterMapping.Map(method.MethodInfo) ?? Enumerable.Empty <ApiParameterDescription>());
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Error mapping parameters in api explorer");
                    }
                }

                foreach (var responseTypeMapping in _responseMappings)
                {
                    try
                    {
                        apiResponseTypes.AddRange(responseTypeMapping.Map(method.MethodInfo) ?? Enumerable.Empty <ApiResponseType>());
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Error mapping parameters in api explorer");
                    }
                }

                foreach (var methodParameter in method.MethodInfo.GetParameters())
                {
                    var matchingRouteParameter = routeParameters.SingleOrDefault(param => string.Equals(param, methodParameter.Name, StringComparison.InvariantCultureIgnoreCase));
                    if (matchingRouteParameter != default &&
                        !apiParameterDescriptions.Any(x => string.Equals(x.Name, matchingRouteParameter, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        var isOptional = matchingRouteParameter.EndsWith("?", StringComparison.InvariantCultureIgnoreCase);
                        apiParameterDescriptions.Add(_parameterDescriptionFactory.Create(
                                                         bindingSource: BindingSource.Path,
                                                         name: matchingRouteParameter,
                                                         type: methodParameter.ParameterType,
                                                         isOptional));
                        continue;
                    }
                }
                foreach (var httpVerb in method.TriggerAttribute.Methods)
                {
                    var description = new FunctionApiDescription(
                        methodInfo: method.MethodInfo,
                        name: method.Name,
                        parameters: apiParameterDescriptions,
                        verb: httpVerb,
                        route: route,
                        responseTypes: apiResponseTypes);

                    foreach (var bodyAttribute in bodyAttributes)
                    {
                        var requestFormats = GetSupportedFormats(bodyAttribute.Type);
                        foreach (var format in requestFormats)
                        {
                            description.SupportedRequestFormats.Add(format);
                        }
                    }

                    descriptions.Add(description);
                }
            }
            var groups = new ApiDescriptionGroup("default", descriptions);

            return(new ApiDescriptionGroupCollection(new[] { groups }, version: 1));
        }
 private IEnumerable <ApiDescription> GetAllGetMethods(ApiDescriptionGroup versionGroup)
 {
     return(versionGroup.Items.Where(x => x.HttpMethod.ToLower() == "get"));
 }
Пример #17
0
        private void AddCallParameters(StringBuilder script, ApiDescriptionGroup controller, ApiDescription action)
        {
            var methodParamNames = action.ParameterDescriptions.Select(p => $"{p.Type.Name} {p.Name}").Distinct().ToList();
            var parameterList    = string.Join(", ", methodParamNames);
            var url        = "/" + BlazorProxyHelper.GenerateUrlWithParameters(action);
            var httpMethod = action.HttpMethod?.ToUpperInvariant() ?? "POST";
            var postPara   = "";

            var addAbpResult = BlazorProxyHelper.AddAbpResult(action);

            if (action.SupportedResponseTypes.Any(f => f.Type == typeof(void)) || !action.SupportedResponseTypes.Any())
            {
                script.AppendLine($"        public async Task {controller.GroupName}{(action.ActionDescriptor as ControllerActionDescriptor).ActionName}({parameterList})");
                script.AppendLine("        {");
            }
            else
            {
                script.AppendLine($"        public async Task<{BlazorProxyHelper.GetCSharpRepresentation(action.SupportedResponseTypes.First().Type, true)}> {controller.GroupName}{(action.ActionDescriptor as ControllerActionDescriptor).ActionName}({parameterList})");
                script.AppendLine("        {");
            }

            if (httpMethod == "POST" || httpMethod == "PUT")
            {
                var bodyParameters = action.ParameterDescriptions.Where(f => f.Source == null || f.Source.Id == "Body");
                if (bodyParameters.Any() && bodyParameters.Count() <= 1)
                {
                    postPara = $", {bodyParameters.FirstOrDefault()?.Name}";
                }
                else if (!bodyParameters.Any())
                {
                    httpMethod = "GET";
                }
                else if (bodyParameters.Count() > 1)
                {
                    script.AppendLine("            throw new Exception(\"Can't have more than 1 parameter.\");");
                }
            }

            var returnType   = $"{BlazorProxyHelper.GetCSharpRepresentation(action.SupportedResponseTypes.First().Type, true)}";
            var returnHandle = new StringBuilder();

            if (!addAbpResult)
            {
                returnHandle.AppendLine("             return result;");
            }
            else
            {
                returnType = $"ABPResult<{returnType}>";
                returnHandle.AppendLine("              if (result.success)");
                returnHandle.AppendLine("              {");
                returnHandle.AppendLine("                   return result.result;");
                returnHandle.AppendLine("              }");
                returnHandle.AppendLine("              else");
                returnHandle.AppendLine("              {");
                returnHandle.AppendLine("                   if (result.unAuthorizedRequest)");
                returnHandle.AppendLine("                   {");
                returnHandle.AppendLine("                       throw new Exception(\"unAuthorizedRequest\");");
                returnHandle.AppendLine("                   }");
                returnHandle.AppendLine("               throw new Exception(result.error.message);");
                returnHandle.AppendLine("               }");
                if (!_isABPResultAdded)
                {
                    script.Insert(88, "using ASO.Shared;");
                    _isABPResultAdded = true;
                }
            }

            if (httpMethod == "DELETE")
            {
                script.AppendLine($"            var resultResponse = await _httpClient.{BlazorProxyHelper.FirstCharToUpper(httpMethod.ToLower())}Async(\"{url}\");");
                if (!action.SupportedResponseTypes.Any(f => f.Type == typeof(void)))
                {
                    script.AppendLine("             var resultString = await resultResponse.Content.ReadAsStringAsync();");
                    script.AppendLine($"            var result = Newtonsoft.Json.JsonConvert.DeserializeObject<{returnType}>(resultString);");
                    script.AppendLine(returnHandle.ToString());
                }
                else
                {
                    script.AppendLine("            return;");
                }
            }
            else
            {
                if (!action.SupportedResponseTypes.Any(f => f.Type == typeof(void)))
                {
                    script.AppendLine($"            var result = await _httpClient.{BlazorProxyHelper.FirstCharToUpper(httpMethod.ToLower())}JsonAsync<{returnType}>(\"{url}\"{postPara});");
                    script.AppendLine(returnHandle.ToString());
                }
                else
                {
                    script.AppendLine($"           await _httpClient.{BlazorProxyHelper.FirstCharToUpper(httpMethod.ToLower())}JsonAsync(\"{url}\"{postPara});");
                    script.AppendLine("            return;");
                }
            }

            ReturnTypes.AddRange(BlazorProxyHelper.GetTypes(action.SupportedResponseTypes.First().Type));
            foreach (var item in action.ParameterDescriptions)
            {
                ReturnTypes.AddRange(BlazorProxyHelper.GetTypes(item.ParameterDescriptor.ParameterType));
            }
        }
Пример #18
0
        private List <ApiDescriptionGroup> CreateDescriptors()
        {
            var groups    = new List <ApiDescriptionGroup>();
            var grainList = DiscoverGrainTypesToMap(grainInterfaceFeature);

            foreach (var grainType in grainList)
            {
                var typeDescription = grainType.GetCustomAttribute <DescriptionAttribute>();
                var groupName       = typeDescription?.Description ?? grainType.Name;
                var apiItems        = new List <ApiDescription>();
                var methods         = grainType.GetMethods().Where(m => m.GetCustomAttributes(true)
                                                                   .Any(attr => attr.GetType() == _routeAttributeType || _methodAttributeTypes.Contains(attr.GetType()))).ToArray();


                foreach (var methodInfo in methods)
                {
                    var methodAttributes = methodInfo.GetCustomAttributes(true)
                                           .Where(attr => attr is Orleans.Http.Abstractions.MethodAttribute).SingleOrDefault() as Orleans.Http.Abstractions.MethodAttribute;
                    if (null == methodAttributes)
                    {
                        continue;
                    }
                    var descriptor = new ControllerActionDescriptor()
                    {
                        ControllerName     = groupName,
                        ActionName         = methodInfo.Name,
                        DisplayName        = methodInfo.Name,
                        MethodInfo         = methodInfo,
                        ControllerTypeInfo = methodInfo.DeclaringType.GetTypeInfo(),
                        RouteValues        = new Dictionary <string, string>()
                        {
                            { "controller", groupName }
                        },
                        AttributeRouteInfo = new AttributeRouteInfo()
                        {
                            Name     = methodInfo.Name,
                            Template = methodAttributes.Pattern
                        },
                        ActionConstraints = new List <IActionConstraintMetadata>()
                        {
                            new HttpMethodActionConstraint(new[] { methodAttributes.Method })
                        },
                        Parameters        = new List <ParameterDescriptor>(),
                        BoundProperties   = new List <ParameterDescriptor>(),
                        FilterDescriptors = new List <FilterDescriptor>(),
                        Properties        = new Dictionary <object, object>()
                    };

                    var description = new ApiDescription()
                    {
                        ActionDescriptor = descriptor,
                        GroupName        = groupName,
                        HttpMethod       = methodAttributes.Method,
                        RelativePath     = $"grains/{methodAttributes.Pattern}"
                    };

                    var methodParams = methodInfo.GetParameters();

                    foreach (var parameter in methodParams)
                    {
                        var bindsource = BindingSource.Path;
                        var attribute  = parameter.GetCustomAttributes()
                                         .Where(attr => _parameterAttributeTypes.Contains(attr.GetType())).FirstOrDefault();
                        if (attribute != null)
                        {
                            if (attribute is Orleans.Http.Abstractions.FromBodyAttribute)
                            {
                                bindsource = BindingSource.Body;
                            }
                            else if (attribute is Orleans.Http.Abstractions.FromQueryAttribute)
                            {
                                bindsource = BindingSource.Query;
                            }
                        }
                        var parameterDescriptor = new ControllerParameterDescriptor()
                        {
                            Name          = parameter.Name,
                            ParameterType = parameter.ParameterType,

                            /* BindingInfo = new BindingInfo()
                             * {
                             *   BinderModelName = parameter.Name,
                             *   BindingSource = bindsource,
                             *   BinderType = parameter.ParameterType
                             * },*/
                            ParameterInfo = parameter
                        };

                        descriptor.Parameters.Add(parameterDescriptor);

                        description.ParameterDescriptions.Add(new ApiParameterDescription()
                        {
                            ModelMetadata = metadataProvider.GetMetadataForType(parameter.ParameterType),
                            Name          = parameter.Name,
                            RouteInfo     = new ApiParameterRouteInfo(),
                            Type          = parameter.ParameterType,
                            Source        = bindsource,
                            IsRequired    = true
                        });
                    }
                    //support path route ?

                    description.SupportedRequestFormats.Add(new ApiRequestFormat()
                    {
                        MediaType = "application/json"
                    });
                    description.SupportedResponseTypes.Add(new ApiResponseType()
                    {
                        ApiResponseFormats = new List <ApiResponseFormat>()
                        {
                            new ApiResponseFormat()
                            {
                                MediaType = "application/json"
                            }
                        },
                        ModelMetadata = metadataProvider
                                        .GetMetadataForType(/*methodInfo.ReturnType*/ typeof(System.Text.Json.JsonElement)),
                        Type       = methodInfo.ReturnType,
                        StatusCode = (int)System.Net.HttpStatusCode.OK
                    });;
                    //InferRequestContentTypes(description);
                    apiItems.Add(description);
                }

                var group = new ApiDescriptionGroup(groupName, new ReadOnlyCollection <ApiDescription>(apiItems));

                groups.Add(group);
            }
            return(groups);
        }
Пример #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="apiDescription"></param>
        /// <param name="attributesToCheck"></param>
        /// <param name="mediaTypesToCheck"></param>
        /// <param name="typesToIgnore"></param>
        /// <returns></returns>
        public List <AttributeCheckResult> CheckAttributesOfApiContractTypes(ApiDescriptionGroup apiDescription, Type[] attributesToCheck, string?mediaTypesToCheck = null, IEnumerable <Type>?typesToIgnore = null)
        {
            var typeList = _apiContractModelsFinder.GetUsedContractTypes(apiDescription, mediaTypesToCheck);

            return(CheckTypeAttributes(typeList, attributesToCheck, typesToIgnore));
        }
        public FunctionApiDescriptionProvider(
            IOptions <Option> functionsOptions,
            SwashBuckleStartupConfig startupConfig,
            IModelMetadataProvider modelMetadataProvider,
            IOutputFormatter outputFormatter,
            IOptions <HttpOptions> httOptions)
        {
            _option = functionsOptions.Value;
            _modelMetadataProvider = modelMetadataProvider;
            _outputFormatter       = outputFormatter;

            var methods = startupConfig.Assembly.GetTypes()
                          .SelectMany(t => t.GetMethods())
                          .Where(m => m.GetCustomAttributes(typeof(FunctionNameAttribute), false).Any())
                          .ToArray();

            IList <ApiDescriptionGroup> apiDescrGroup = new List <ApiDescriptionGroup>();

            foreach (var methodInfo in methods)
            {
                if (!TryGetHttpTrigger(methodInfo, out var triggerAttribute))
                {
                    continue;
                }

                var functionAttr =
                    (FunctionNameAttribute)methodInfo.GetCustomAttribute(typeof(FunctionNameAttribute), false);
                var prefix = string.IsNullOrWhiteSpace(httOptions.Value.RoutePrefix) ? "" : $"{httOptions.Value.RoutePrefix.TrimEnd('/')}/";
                var route  =
                    $"{prefix}{(!string.IsNullOrWhiteSpace(triggerAttribute.Route) ? triggerAttribute.Route : functionAttr.Name)}";

                var routes = new List <(string Route, string RemoveParamName)>();

                var regex = new Regex("/\\{(?<paramName>\\w+)\\?\\}$");
                var match = regex.Match(route);

                if (match.Success && match.Captures.Count == 1)
                {
                    routes.Add((route.Replace(match.Value, "").Replace("//", "/"), match.Groups["paramName"].ToString()));
                    routes.Add((route.Replace(match.Value, match.Value.Replace("?", "")), ""));
                }
                else
                {
                    routes.Add((route, ""));
                }
                var verbs = triggerAttribute.Methods ??
                            new[] { "get", "post", "delete", "head", "patch", "put", "options" };


                for (var index = 0; index < routes.Count; index++)
                {
                    var r       = routes[index];
                    var apiName = functionAttr.Name + (index == 0 ? "" : $"-{index}");
                    var items   = verbs.Select(verb =>
                                               CreateDescription(methodInfo, r.Route, functionAttr, verb, triggerAttribute.AuthLevel, r.RemoveParamName)).ToArray();
                    var group = new ApiDescriptionGroup(apiName, items);
                    apiDescrGroup.Add(@group);
                }
            }

            ApiDescriptionGroups =
                new ApiDescriptionGroupCollection(new ReadOnlyCollection <ApiDescriptionGroup>(apiDescrGroup), 1);
        }
 public FakeApiDescriptionGroupCollectionProvider WithPostsController()
 {
     group = new ApiDescriptionGroup("posts", actions);
     groups.Add(group);
     return(this);
 }