• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / MediatR.CommandQuery / 12567339125

01 Jan 2025 04:52AM UTC coverage: 60.229% (-0.1%) from 60.328%
12567339125

push

github

pwelter34
switch to Testcontainers

402 of 761 branches covered (52.83%)

Branch coverage included in aggregate %.

1282 of 2035 relevant lines covered (63.0%)

19.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/src/MediatR.CommandQuery/Behaviors/DeletedFilterBehaviorBase.cs
1
using System.Security.Claims;
2

3
using MediatR.CommandQuery.Definitions;
4
using MediatR.CommandQuery.Queries;
5

6
using Microsoft.Extensions.Logging;
7

8
namespace MediatR.CommandQuery.Behaviors;
9

10
/// <summary>
11
/// A base behavior for appending soft delete (IsDeleted) filter
12
/// </summary>
13
/// <typeparam name="TEntityModel">The type of the entity model.</typeparam>
14
/// <typeparam name="TRequest">The type of the request.</typeparam>
15
/// <typeparam name="TResponse">The type of the response.</typeparam>
16
public abstract class DeletedFilterBehaviorBase<TEntityModel, TRequest, TResponse>
17
    : PipelineBehaviorBase<TRequest, TResponse>
18
    where TRequest : class, IRequest<TResponse>
19
{
20
    // ReSharper disable once StaticMemberInGenericType
21
    private static readonly Lazy<bool> _supportsDelete = new(SupportsDelete);
8✔
22

23
    /// <summary>
24
    /// Initializes a new instance of the <see cref="DeletedFilterBehaviorBase{TEntityModel, TRequest, TResponse}"/> class.
25
    /// </summary>
26
    /// <param name="loggerFactory">The logger factory.</param>
27
    protected DeletedFilterBehaviorBase(ILoggerFactory loggerFactory) : base(loggerFactory)
20✔
28
    {
29
    }
20✔
30

31
    /// <summary>
32
    /// Rewrites the specified filter to include a soft delete (IsDeleted) filter.
33
    /// </summary>
34
    /// <param name="originalFilter">The original filter.</param>
35
    /// <param name="principal">The principal.</param>
36
    /// <returns></returns>
37
    protected virtual EntityFilter? RewriteFilter(EntityFilter? originalFilter, ClaimsPrincipal? principal)
38
    {
39
        if (!_supportsDelete.Value)
20!
40
            return originalFilter;
×
41

42
        // don't rewrite if already has filter
43
        if (HasDeletedFilter(originalFilter))
20✔
44
            return originalFilter;
8✔
45

46
        var deletedFilter = new EntityFilter
12✔
47
        {
12✔
48
            Name = nameof(ITrackDeleted.IsDeleted),
12✔
49
            Value = false,
12✔
50
            Operator = EntityFilterOperators.Equal,
12✔
51
        };
12✔
52

53
        if (originalFilter == null)
12!
54
            return deletedFilter;
×
55

56
        var boolFilter = new EntityFilter
12✔
57
        {
12✔
58
            Logic = EntityFilterLogic.And,
12✔
59
            Filters = [deletedFilter, originalFilter],
12✔
60
        };
12✔
61

62
        return boolFilter;
12✔
63
    }
64

65
    /// <summary>
66
    /// Determines whether the specified original filter has a soft delete (IsDeleted) filter.
67
    /// </summary>
68
    /// <param name="originalFilter">The original filter.</param>
69
    /// <returns>
70
    ///   <c>true</c> if the specified original filter has a soft delete filter; otherwise, <c>false</c>.
71
    /// </returns>
72
    protected virtual bool HasDeletedFilter(EntityFilter? originalFilter)
73
    {
74
        if (originalFilter == null)
20!
75
            return false;
×
76

77
        var stack = new Stack<EntityFilter>();
20✔
78
        stack.Push(originalFilter);
20✔
79

80
        while (stack.Count > 0)
72✔
81
        {
82
            var filter = stack.Pop();
60✔
83
            if (!string.IsNullOrEmpty(filter.Name) && string.Equals(filter.Name, nameof(ITrackDeleted.IsDeleted), StringComparison.Ordinal))
60✔
84
                return true;
8✔
85

86
            if (filter.Filters == null)
52✔
87
                continue;
88

89
            foreach (var innerFilter in filter.Filters)
144✔
90
                stack.Push(innerFilter);
48✔
91
        }
92

93
        return false;
12✔
94
    }
95

96
    private static bool SupportsDelete()
97
    {
98
        var interfaceType = typeof(ITrackDeleted);
8✔
99
        var entityType = typeof(TEntityModel);
8✔
100

101
        return interfaceType.IsAssignableFrom(entityType);
8✔
102
    }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc