< Summary - Code Coverage

Information
Class: Plainquire.Filter.Swashbuckle.Filters.EntityFilterParameterReplacer
Assembly: Plainquire.Filter.Swashbuckle
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter.Swashbuckle/Filters/EntityFilterParameterReplacer.cs
Tag: 74_23635074410
Line coverage
100%
Covered lines: 27
Uncovered lines: 0
Coverable lines: 27
Total lines: 70
Line coverage: 100%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
Method coverage
100%
Covered methods: 3
Total methods: 3
Method coverage: 100%

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)75%44100%
Apply(...)75%44100%
GetEntityFilterReplacements(...)50%22100%

File(s)

/home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter.Swashbuckle/Filters/EntityFilterParameterReplacer.cs

#LineLine coverage
 1using LoxSmoke.DocXml;
 2using Microsoft.OpenApi;
 3using Plainquire.Filter.Swashbuckle.Models;
 4using Swashbuckle.AspNetCore.SwaggerGen;
 5using System;
 6using System.Collections.Generic;
 7using System.Diagnostics.CodeAnalysis;
 8using System.Linq;
 9using System.Text.Json.Nodes;
 10
 11namespace Plainquire.Filter.Swashbuckle.Filters;
 12
 13/// <summary>
 14/// Replaces action parameters of type <see cref="EntityFilter"/> with filterable properties of type <c>TEntity</c>.
 15/// Implements <see cref="IOperationFilter" />
 16/// </summary>
 17/// <seealso cref="IOperationFilter" />
 18[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Instantiated via reflection.")]
 19public class EntityFilterParameterReplacer : IOperationFilter
 20{
 21    private readonly List<DocXmlReader> _docXmlReaders;
 22
 23    /// <summary>
 24    /// Initializes a new instance of the <see cref="EntityFilterParameterReplacer"/> class.
 25    /// </summary>
 26    /// <param name="xmlDocumentationFilePaths">Paths to XML documentation files. Used to provide parameter descriptions
 27    public EntityFilterParameterReplacer(IEnumerable<string>? xmlDocumentationFilePaths)
 828        => _docXmlReaders = xmlDocumentationFilePaths?.Select(x => new DocXmlReader(x)).ToList() ?? [];
 29
 30    /// <summary>
 31    /// Replaces all parameters of type <see cref="EntityFilter{TEntity}"/> with their applicable filter properties.
 32    /// </summary>
 33    /// <param name="operation">The operation.</param>
 34    /// <param name="context">The context.</param>
 35    public void Apply(OpenApiOperation operation, OperationFilterContext context)
 36    {
 637        operation.Parameters ??= new List<IOpenApiParameter>();
 638        operation.AddOriginalIndexExtensionIfMissing(context);
 639        var parameterReplacements = GetEntityFilterReplacements(operation, context);
 640        operation.Parameters.ReplaceFilterParameters(parameterReplacements, _docXmlReaders);
 41
 642        var hasParametersFromEntityFilter = parameterReplacements.Any();
 643        operation.Extensions ??= new Dictionary<string, IOpenApiExtension>(StringComparer.OrdinalIgnoreCase);
 644        operation.Extensions[OpenApiParameterExtensions.ENTITY_EXTENSION_PREFIX + "has-filter-parameters"] = new JsonNod
 645    }
 46
 47    private static List<FilterParameterReplaceInfo> GetEntityFilterReplacements(OpenApiOperation operation, OperationFil
 48    {
 649        operation.Parameters ??= new List<IOpenApiParameter>();
 50
 651        var parameterReplacements = context.ApiDescription.ParameterDescriptions
 652            .Join(
 653                operation.Parameters,
 654                description => context.ApiDescription.ParameterDescriptions.IndexOf(description),
 655                parameter => parameter.GetOriginalIndex(),
 656                (description, parameter) => (Parameter: parameter, Description: description)
 657             )
 658            .Where(openApi => openApi.Description.IsEntityFilterParameter())
 659            .GroupBy(openApi => openApi.Description.ParameterDescriptor.ParameterType)
 660            .Select(parameterGroup =>
 661            {
 662                var parametersToRemove = parameterGroup.Select(x => x.Parameter).ToList();
 663                var filteredTypesToAdd = new[] { parameterGroup.Key }.ToList();
 664                return new FilterParameterReplaceInfo(parametersToRemove, filteredTypesToAdd);
 665            })
 666            .ToList();
 67
 668        return parameterReplacements;
 69    }
 70}