< Summary - Code Coverage

Information
Class: Plainquire.Filter.EntityFilterExtensions
Assembly: Plainquire.Filter
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/Extensions/EntityFilterExtensions.cs
Tag: 66_15485642072
Line coverage
97%
Covered lines: 75
Uncovered lines: 2
Coverable lines: 77
Total lines: 228
Line coverage: 97.4%
Branch coverage
93%
Covered branches: 41
Total branches: 44
Branch coverage: 93.1%
Method coverage
100%
Covered methods: 10
Total methods: 10
Method coverage: 100%

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Add(...)100%22100%
Add(...)100%44100%
Add(...)100%11100%
Add(...)100%1010100%
Replace(...)100%22100%
Replace(...)100%44100%
Replace(...)100%11100%
Replace(...)100%1010100%
ToQueryParams(...)100%11100%
ToQueryParams(...)75%121289.47%

File(s)

/home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/Extensions/EntityFilterExtensions.cs

#LineLine coverage
 1using Plainquire.Filter.Abstractions;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5using System.Linq.Expressions;
 6using System.Reflection;
 7using System.Web;
 8
 9namespace Plainquire.Filter;
 10
 11/// <summary>
 12/// Extension methods for <see cref="EntityFilter{TEntity}"/>
 13/// </summary>
 14public static class EntityFilterExtensions
 15{
 16    /// <summary>
 17    /// Adds a filter for the given property. Existing filters for the same property are preserved.
 18    /// </summary>
 19    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 20    /// <typeparam name="TProperty">The type of the property.</typeparam>
 21    /// <param name="entityFilter">The entity filter.</param>
 22    /// <param name="property">The property to filter.</param>
 23    /// <param name="filterSyntax">Description of the filter using micro syntax.</param>
 24    public static EntityFilter<TEntity> Add<TEntity, TProperty>(this EntityFilter<TEntity> entityFilter, Expression<Func
 25    {
 7426        if (filterSyntax == null)
 127            return entityFilter;
 28
 7329        var filters = ValueFiltersFactory.Create(filterSyntax, entityFilter.Configuration);
 7330        entityFilter.Add(property, filters);
 7231        return entityFilter;
 32    }
 33
 34    /// <summary>
 35    /// Adds a filter for the given property using the default filter operator. Existing filters for the same property a
 36    /// </summary>
 37    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 38    /// <typeparam name="TProperty">The type of the property.</typeparam>
 39    /// <typeparam name="TValue">The type of the value.</typeparam>
 40    /// <param name="entityFilter">The entity filter.</param>
 41    /// <param name="property">The property to filter.</param>
 42    /// <param name="values">The values to filter for. Multiple values are combined with conditional OR.</param>
 43    public static EntityFilter<TEntity> Add<TEntity, TProperty, TValue>(this EntityFilter<TEntity> entityFilter, Express
 44    {
 2545        if (values == null || values.Length == 0)
 446            return entityFilter;
 47
 2148        var valueFilters = values
 2149            .Select(value => ValueFilter.Create(
 2150                FilterOperator.Default,
 2151                value,
 2152                entityFilter.Configuration
 2153            ))
 2154            .ToArray();
 55
 2056        return entityFilter.Add(property, valueFilters);
 57    }
 58
 59    /// <summary>
 60    /// Adds a filter for the given property. Existing filters for the same property are preserved.
 61    /// </summary>
 62    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 63    /// <typeparam name="TProperty">The type of the property.</typeparam>
 64    /// <param name="entityFilter">The entity filter.</param>
 65    /// <param name="property">The property to filter.</param>
 66    /// <param name="filterOperator">The filter operator to use.</param>
 67    public static EntityFilter<TEntity> Add<TEntity, TProperty>(this EntityFilter<TEntity> entityFilter, Expression<Func
 668        => entityFilter.Add(property, ValueFilter.Create(filterOperator, entityFilter.Configuration));
 69
 70    /// <summary>
 71    /// Adds a filter for the given property. Existing filters for the same property are preserved.
 72    /// </summary>
 73    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 74    /// <typeparam name="TProperty">The type of the property.</typeparam>
 75    /// <typeparam name="TValue">The type of the value.</typeparam>
 76    /// <param name="entityFilter">The entity filter.</param>
 77    /// <param name="property">The property to filter.</param>
 78    /// <param name="filterOperator">The filter operator to use.</param>
 79    /// <param name="values">The values to filter for. Multiple values are combined with conditional OR.</param>
 80    public static EntityFilter<TEntity> Add<TEntity, TProperty, TValue>(this EntityFilter<TEntity> entityFilter, Express
 81    {
 1582        var isNullableFilterOperator = filterOperator is FilterOperator.IsNull or FilterOperator.NotNull;
 1583        if ((values == null || values.Length == 0) && !isNullableFilterOperator)
 284            return entityFilter;
 85
 1386        var valueFilters = values?
 1387            .Select(value => ValueFilter.Create(
 1388                filterOperator,
 1389                value,
 1390                entityFilter.Configuration
 1391            ))
 1392            .ToArray();
 93
 1394        entityFilter.Add(property, valueFilters);
 1395        return entityFilter;
 96    }
 97
 98    /// <summary>
 99    /// Replaces the filter for the given property. Existing filters for the same property are removed.
 100    /// </summary>
 101    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 102    /// <typeparam name="TProperty">The type of the property.</typeparam>
 103    /// <param name="entityFilter">The entity filter.</param>
 104    /// <param name="property">The property to filter.</param>
 105    /// <param name="filterSyntax">Description of the filter using micro syntax.</param>
 106    public static EntityFilter<TEntity> Replace<TEntity, TProperty>(this EntityFilter<TEntity> entityFilter, Expression<
 107    {
 6504108        if (filterSyntax == null)
 1109            return entityFilter.Remove(property);
 110
 6503111        var valueFilters = ValueFiltersFactory.Create(filterSyntax, entityFilter.Configuration);
 6503112        entityFilter.Replace(property, valueFilters);
 6503113        return entityFilter;
 114    }
 115
 116    /// <summary>
 117    /// Replaces the filter for the given property using the default filter operator. Existing filters for the same prop
 118    /// </summary>
 119    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 120    /// <typeparam name="TProperty">The type of the t property.</typeparam>
 121    /// <typeparam name="TValue">The type of the t value.</typeparam>
 122    /// <param name="entityFilter">The entity filter.</param>
 123    /// <param name="property">The property to filter.</param>
 124    /// <param name="values">The values to filter for. Multiple values are combined with conditional OR.</param>
 125    public static EntityFilter<TEntity> Replace<TEntity, TProperty, TValue>(this EntityFilter<TEntity> entityFilter, Exp
 126    {
 4127        if (values == null || values.Length == 0)
 2128            return entityFilter.Remove(property);
 129
 2130        var valueFilters = values
 2131            .Select(value => ValueFilter.Create(
 2132                FilterOperator.Default,
 2133                value,
 2134                entityFilter.Configuration
 2135                ))
 2136            .ToArray();
 137
 2138        return entityFilter.Replace(property, valueFilters);
 139    }
 140
 141    /// <summary>
 142    /// Replaces the filter for the given property. Existing filters for the same property are removed.
 143    /// </summary>
 144    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 145    /// <typeparam name="TProperty">The type of the property.</typeparam>
 146    /// <param name="entityFilter">The entity filter.</param>
 147    /// <param name="property">The property to filter.</param>
 148    /// <param name="filterOperator">The filter operator to use.</param>
 149    public static EntityFilter<TEntity> Replace<TEntity, TProperty>(this EntityFilter<TEntity> entityFilter, Expression<
 6150        => entityFilter.Replace(property, ValueFilter.Create(filterOperator, entityFilter.Configuration));
 151
 152    /// <summary>
 153    /// Replaces the filter for the given property. Existing filters for the same property are removed.
 154    /// </summary>
 155    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 156    /// <typeparam name="TProperty">The type of the property.</typeparam>
 157    /// <typeparam name="TValue">The type of the value.</typeparam>
 158    /// <param name="entityFilter">The entity filter.</param>
 159    /// <param name="property">The property to filter.</param>
 160    /// <param name="filterOperator">The filter operator to use.</param>
 161    /// <param name="values">The values to filter for. Multiple values are combined with conditional OR.</param>
 162    public static EntityFilter<TEntity> Replace<TEntity, TProperty, TValue>(this EntityFilter<TEntity> entityFilter, Exp
 163    {
 3549164        var isNullableFilterOperator = filterOperator is FilterOperator.IsNull or FilterOperator.NotNull;
 3549165        if ((values == null || values.Length == 0) && !isNullableFilterOperator)
 2166            return entityFilter.Remove(property);
 167
 3547168        var valueFilters = values?
 3547169            .Select(value => ValueFilter.Create(
 3547170                filterOperator,
 3547171                value,
 3547172                entityFilter.Configuration
 3547173                ))
 3547174            .ToArray();
 175
 3546176        entityFilter.Replace(property, valueFilters);
 3546177        return entityFilter;
 178    }
 179
 180    /// <summary>
 181    /// Converts an entity filter to it's corresponding HTTP query parameters.
 182    /// </summary>
 183    /// <typeparam name="TEntity">Type of the entity.</typeparam>
 184    /// <param name="entityFilter">The filter to act on.</param>
 185    public static string ToQueryParams<TEntity>(this EntityFilter<TEntity>? entityFilter)
 186    {
 2187        var queryParams = ToQueryParams((EntityFilter?)entityFilter);
 2188        return string.Join('&', queryParams);
 189    }
 190
 191    /// <summary>
 192    /// Converts an entity filter to it's corresponding HTTP query parameters.
 193    /// </summary>
 194    /// <param name="entityFilter">The filter to act on.</param>
 195    private static List<string> ToQueryParams(this EntityFilter? entityFilter)
 196    {
 3197        if (entityFilter == null)
 0198            return [];
 199
 3200        var entityFilterType = entityFilter.GetType();
 3201        if (!entityFilterType.IsGenericType)
 0202            throw new ArgumentException($"Given filter must be a generic {nameof(EntityFilter)}", nameof(entityFilter));
 203
 3204        var filteredType = entityFilterType.GenericTypeArguments[0];
 3205        var filterableProperties = filteredType.GetFilterableProperties().ToList();
 3206        var entityFilterAttribute = filteredType.GetCustomAttribute<EntityFilterAttribute>();
 207
 3208        var queryParams = new List<string>();
 22209        foreach (var property in filterableProperties)
 210        {
 8211            var parameterName = HttpUtility.UrlEncode(property.GetFilterParameterName(entityFilterAttribute?.Prefix));
 8212            var propertyFilters = entityFilter.PropertyFilters.Where(x => x.PropertyName.EqualsOrdinal(property.Name));
 28213            foreach (var filter in propertyFilters)
 214            {
 6215                var values = string.Join(',', filter.ValueFilters.Select(v => HttpUtility.UrlEncode(v.ToString())));
 6216                queryParams.Add($"{parameterName}={values}");
 217            }
 218        }
 219
 8220        foreach (var nestedFilter in entityFilter.NestedFilters)
 221        {
 1222            var nestedQueryParams = nestedFilter.EntityFilter.ToQueryParams();
 1223            queryParams.AddRange(nestedQueryParams);
 224        }
 225
 3226        return queryParams;
 227    }
 228}