< Summary

Information
Class: AsiBackbone.Storage.InMemory.Audit.InMemoryDecisionReceiptLifecycleStore
Assembly: AsiBackbone.Storage.InMemory
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Storage.InMemory/Audit/InMemoryDecisionReceiptLifecycleStore.cs
Line coverage
100%
Covered lines: 26
Uncovered lines: 0
Coverable lines: 26
Total lines: 77
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
AppendAsync(...)100%22100%
FindByEventIdAsync(...)100%11100%
FindByCorrelationIdAsync(...)100%11100%
FindByDecisionReceiptIdAsync(...)100%11100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Storage.InMemory/Audit/InMemoryDecisionReceiptLifecycleStore.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2using AsiBackbone.Core.Audit;
 3
 4namespace AsiBackbone.Storage.InMemory.Audit;
 5
 6/// <summary>
 7/// In-memory decision receipt lifecycle store for tests, samples, and development hosts.
 8/// </summary>
 9/// <remarks>
 10/// This store is not durable across process restarts. Production hosts should use a durable provider such as EF Core or
 11/// </remarks>
 12public sealed class InMemoryDecisionReceiptLifecycleStore : IDecisionReceiptLifecycleStore
 13{
 2414    private readonly ConcurrentDictionary<string, DecisionReceiptLifecycleEvent> events = new(StringComparer.Ordinal);
 15
 16    /// <inheritdoc />
 17    public ValueTask<DecisionReceiptLifecycleEvent> AppendAsync(
 18        DecisionReceiptLifecycleEvent lifecycleEvent,
 19        CancellationToken cancellationToken = default)
 20    {
 1821        ArgumentNullException.ThrowIfNull(lifecycleEvent);
 1722        cancellationToken.ThrowIfCancellationRequested();
 23
 1624        return !events.TryAdd(lifecycleEvent.EventId, lifecycleEvent)
 1625            ? throw new InvalidOperationException($"Lifecycle event '{lifecycleEvent.EventId}' already exists.")
 1626            : ValueTask.FromResult(lifecycleEvent);
 27    }
 28
 29    /// <inheritdoc />
 30    public ValueTask<DecisionReceiptLifecycleEvent?> FindByEventIdAsync(
 31        string eventId,
 32        CancellationToken cancellationToken = default)
 33    {
 1834        ArgumentException.ThrowIfNullOrWhiteSpace(eventId);
 1735        cancellationToken.ThrowIfCancellationRequested();
 36
 1637        _ = events.TryGetValue(eventId.Trim(), out DecisionReceiptLifecycleEvent? lifecycleEvent);
 38
 1639        return ValueTask.FromResult(lifecycleEvent);
 40    }
 41
 42    /// <inheritdoc />
 43    public ValueTask<IReadOnlyList<DecisionReceiptLifecycleEvent>> FindByCorrelationIdAsync(
 44        string correlationId,
 45        CancellationToken cancellationToken = default)
 46    {
 447        ArgumentException.ThrowIfNullOrWhiteSpace(correlationId);
 348        cancellationToken.ThrowIfCancellationRequested();
 49
 250        string normalizedCorrelationId = correlationId.Trim();
 51
 252        IReadOnlyList<DecisionReceiptLifecycleEvent> matches = [.. events.Values
 253            .Where(lifecycleEvent => string.Equals(lifecycleEvent.CorrelationId, normalizedCorrelationId, StringComparis
 254            .OrderBy(lifecycleEvent => lifecycleEvent.OccurredUtc)
 255            .ThenBy(lifecycleEvent => lifecycleEvent.EventId)];
 56
 257        return ValueTask.FromResult(matches);
 58    }
 59
 60    /// <inheritdoc />
 61    public ValueTask<IReadOnlyList<DecisionReceiptLifecycleEvent>> FindByDecisionReceiptIdAsync(
 62        string decisionReceiptId,
 63        CancellationToken cancellationToken = default)
 64    {
 465        ArgumentException.ThrowIfNullOrWhiteSpace(decisionReceiptId);
 366        cancellationToken.ThrowIfCancellationRequested();
 67
 268        string normalizedDecisionReceiptId = decisionReceiptId.Trim();
 69
 270        IReadOnlyList<DecisionReceiptLifecycleEvent> matches = [.. events.Values
 271            .Where(lifecycleEvent => string.Equals(lifecycleEvent.DecisionReceiptId, normalizedDecisionReceiptId, String
 272            .OrderBy(lifecycleEvent => lifecycleEvent.OccurredUtc)
 273            .ThenBy(lifecycleEvent => lifecycleEvent.EventId)];
 74
 275        return ValueTask.FromResult(matches);
 76    }
 77}