< Summary

Information
Class: Elsa.Identity.Services.UserDeletionCoordinator
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Services/UserDeletionCoordinator.cs
Line coverage
66%
Covered lines: 18
Uncovered lines: 9
Coverable lines: 27
Total lines: 60
Line coverage: 66.6%
Branch coverage
50%
Covered branches: 5
Total branches: 10
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
DeleteAsync()33.33%10652.94%
InspectDependenciesAsync()75%4485.71%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Services/UserDeletionCoordinator.cs

#LineLine coverage
 1using Elsa.Identity.Contracts;
 2using Elsa.Identity.Entities;
 3using Elsa.Identity.Models;
 4
 5namespace Elsa.Identity.Services;
 6
 7/// <inheritdoc />
 68public sealed class UserDeletionCoordinator(
 69    IUserStore userStore,
 610    IEnumerable<IUserDeletionDependencyContributor> contributors) : IUserDeletionCoordinator
 11{
 12    /// <inheritdoc />
 13    public async ValueTask<UserDeletionOperationResult> DeleteAsync(string userId, CancellationToken cancellationToken =
 14    {
 115        var user = await userStore.FindAsync(new() { Id = userId }, cancellationToken);
 116        if (user is null)
 017            return new UserDeletionOperationResult.NotFound();
 18
 119        var dependencies = await InspectDependenciesAsync(user, cancellationToken);
 20
 121        if (dependencies.Count > 0)
 022            return new UserDeletionOperationResult.Blocked(dependencies);
 23
 124        await userStore.DeleteAsync(new() { Id = user.Id }, cancellationToken);
 25
 26        // A link writer can race the first inspection when Identity and the contributing module use different stores.
 27        // Recheck after deletion and restore the aggregate if that writer committed first. Link writers perform the
 28        // complementary post-commit user check, so either ordering converges without a dangling reference.
 29        try
 30        {
 131            dependencies = await InspectDependenciesAsync(user, cancellationToken);
 032        }
 133        catch
 34        {
 135            await userStore.SaveAsync(user, CancellationToken.None);
 136            throw;
 37        }
 38
 039        if (dependencies.Count > 0)
 40        {
 041            await userStore.SaveAsync(user, CancellationToken.None);
 042            return new UserDeletionOperationResult.Blocked(dependencies);
 43        }
 44
 045        return new UserDeletionOperationResult.Deleted();
 046    }
 47
 48    private async ValueTask<List<UserDeletionDependency>> InspectDependenciesAsync(User user, CancellationToken cancella
 49    {
 250        var dependencies = new List<UserDeletionDependency>();
 751        foreach (var contributor in contributors)
 52        {
 253            var dependency = await contributor.InspectAsync(user, cancellationToken);
 154            if (dependency is not null)
 055                dependencies.Add(dependency);
 56        }
 57
 158        return dependencies;
 159    }
 60}