< Summary

Information
Class: AsiBackbone.Core.Signing.SigningRequest
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Signing/SigningRequest.cs
Line coverage
100%
Covered lines: 37
Uncovered lines: 0
Coverable lines: 37
Total lines: 104
Line coverage: 100%
Branch coverage
81%
Covered branches: 13
Total branches: 16
Branch coverage: 81.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
get_SigningHash()100%11100%
get_HashAlgorithm()100%11100%
get_Purpose()100%11100%
get_KeyId()100%11100%
get_KeyVersion()100%11100%
get_Metadata()100%11100%
get_HasMetadata()100%11100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)78.57%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Signing/SigningRequest.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2
 3namespace AsiBackbone.Core.Signing;
 4
 5/// <summary>
 6/// Represents a provider-neutral request to sign a precomputed artifact hash.
 7/// </summary>
 8/// <remarks>
 9/// The request is intentionally hash-oriented so production providers can use key-based signing APIs without exposing r
 10/// </remarks>
 11public sealed class SigningRequest
 12{
 813    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 814        new ReadOnlyDictionary<string, string>(
 815            new Dictionary<string, string>(StringComparer.Ordinal));
 16
 17    /// <summary>
 18    /// Initializes a new instance of the <see cref="SigningRequest" /> class.
 19    /// </summary>
 12220    public SigningRequest(
 12221        string signingHash,
 12222        string? hashAlgorithm = null,
 12223        string? purpose = null,
 12224        string? keyId = null,
 12225        string? keyVersion = null,
 12226        IReadOnlyDictionary<string, string>? metadata = null)
 27    {
 12228        ArgumentException.ThrowIfNullOrWhiteSpace(signingHash);
 29
 12230        SigningHash = signingHash.Trim();
 12231        HashAlgorithm = NormalizeOptional(hashAlgorithm);
 12232        Purpose = NormalizeOptional(purpose);
 12233        KeyId = NormalizeOptional(keyId);
 12234        KeyVersion = NormalizeOptional(keyVersion);
 12235        Metadata = NormalizeMetadata(metadata);
 12236    }
 37
 38    /// <summary>
 39    /// Gets the precomputed artifact hash to sign.
 40    /// </summary>
 19841    public string SigningHash { get; }
 42
 43    /// <summary>
 44    /// Gets the hash algorithm or descriptor associated with <see cref="SigningHash" />, when supplied.
 45    /// </summary>
 24446    public string? HashAlgorithm { get; }
 47
 48    /// <summary>
 49    /// Gets the host-defined signing purpose, when supplied.
 50    /// </summary>
 18651    public string? Purpose { get; }
 52
 53    /// <summary>
 54    /// Gets the requested signing key identifier, when supplied.
 55    /// </summary>
 21856    public string? KeyId { get; }
 57
 58    /// <summary>
 59    /// Gets the requested signing key version, when supplied.
 60    /// </summary>
 25261    public string? KeyVersion { get; }
 62
 63    /// <summary>
 64    /// Gets additional provider-neutral request metadata.
 65    /// </summary>
 18066    public IReadOnlyDictionary<string, string> Metadata { get; }
 67
 68    /// <summary>
 69    /// Gets a value indicating whether metadata is present.
 70    /// </summary>
 271    public bool HasMetadata => Metadata.Count > 0;
 72
 73    private static string? NormalizeOptional(string? value)
 74    {
 48875        return string.IsNullOrWhiteSpace(value)
 48876            ? null
 48877            : value.Trim();
 78    }
 79
 80    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 81        IReadOnlyDictionary<string, string>? metadata)
 82    {
 12283        if (metadata is null || metadata.Count == 0)
 84        {
 10285            return EmptyMetadata;
 86        }
 87
 2088        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 89
 30490        foreach (KeyValuePair<string, string> item in metadata)
 91        {
 13292            if (string.IsNullOrWhiteSpace(item.Key))
 93            {
 94                continue;
 95            }
 96
 13097            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 98        }
 99
 20100        return normalizedMetadata.Count == 0
 20101            ? EmptyMetadata
 20102            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 103    }
 104}