< Summary

Information
Class: Elsa.ExternalAuthentication.Stores.InMemory.InMemoryExternalAuthenticationStateStore
Assembly: Elsa.ExternalAuthentication
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Stores/InMemory/InMemoryExternalAuthenticationStateStore.cs
Line coverage
96%
Covered lines: 25
Uncovered lines: 1
Coverable lines: 26
Total lines: 54
Line coverage: 96.1%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
PutAsync(...)100%22100%
TryTakeAsync(...)75%8890.9%
.ctor(...)100%11100%
get_Value()100%11100%
get_ExpiresAt()100%11100%
get_IsConsumed()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.ExternalAuthentication/Stores/InMemory/InMemoryExternalAuthenticationStateStore.cs

#LineLine coverage
 1using Elsa.Common;
 2using Elsa.ExternalAuthentication.Contracts;
 3using Elsa.ExternalAuthentication.Models;
 4
 5namespace Elsa.ExternalAuthentication.Stores.InMemory;
 6
 337public sealed class InMemoryExternalAuthenticationStateStore(ISystemClock clock) : IExternalAuthenticationStateStore
 8{
 339    private readonly object _syncRoot = new();
 3310    private readonly Dictionary<(string Purpose, string HandleHash), StateEntry> _entries = new();
 11
 12    public ValueTask PutAsync<T>(string purpose, string handleHash, T value, DateTimeOffset expiresAt, CancellationToken
 13    {
 2014        cancellationToken.ThrowIfCancellationRequested();
 2015        var key = (purpose, handleHash);
 16
 2017        lock (_syncRoot)
 18        {
 2019            if (_entries.ContainsKey(key))
 120                throw new InvalidOperationException("A state entry already exists for the supplied purpose and handle.")
 21
 1922            _entries[key] = new StateEntry(value, expiresAt);
 1923        }
 24
 1925        return ValueTask.CompletedTask;
 26    }
 27
 28    public ValueTask<TakeResult<T>> TryTakeAsync<T>(string purpose, string handleHash, CancellationToken cancellationTok
 29    {
 3330        cancellationToken.ThrowIfCancellationRequested();
 31
 3332        lock (_syncRoot)
 33        {
 3334            if (!_entries.TryGetValue((purpose, handleHash), out var entry) || entry.Value is not T value)
 035                return ValueTask.FromResult<TakeResult<T>>(new TakeResult<T>.NotFound());
 36
 3337            if (entry.ExpiresAt <= clock.UtcNow)
 138                return ValueTask.FromResult<TakeResult<T>>(new TakeResult<T>.Expired());
 39
 3240            if (entry.IsConsumed)
 1741                return ValueTask.FromResult<TakeResult<T>>(new TakeResult<T>.AlreadyConsumed());
 42
 1543            entry.IsConsumed = true;
 1544            return ValueTask.FromResult<TakeResult<T>>(new TakeResult<T>.Taken(value));
 45        }
 3346    }
 47
 1948    private sealed class StateEntry(object? value, DateTimeOffset expiresAt)
 49    {
 5250        public object? Value { get; } = value;
 5251        public DateTimeOffset ExpiresAt { get; } = expiresAt;
 4752        public bool IsConsumed { get; set; }
 53    }
 54}