< Summary - Envilder .NET SDK

Information
Class: Envilder.Application.SecretValidationExtensions
Assembly: Envilder
File(s): /home/runner/work/envilder/envilder/src/sdks/dotnet/Application/SecretValidationExtensions.cs
Tag: 299_25910610327
Line coverage
100%
Covered lines: 11
Uncovered lines: 0
Coverable lines: 11
Total lines: 98
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ValidateSecrets(...)100%1010100%

File(s)

/home/runner/work/envilder/envilder/src/sdks/dotnet/Application/SecretValidationExtensions.cs

#LineLine coverage
 1namespace Envilder.Application;
 2
 3using System;
 4using System.Collections.Generic;
 5using System.Linq;
 6
 7/// <summary>
 8/// Thrown by <see cref="SecretValidationExtensions.ValidateSecrets"/> when one or
 9/// more resolved secrets are missing (empty, whitespace-only, or the dictionary is empty).
 10/// </summary>
 11/// <example>
 12/// <code>
 13/// var secrets = Envilder.ResolveFile("envilder.json");
 14/// try
 15/// {
 16///     secrets.ValidateSecrets();
 17/// }
 18/// catch (SecretValidationException ex)
 19/// {
 20///     Console.WriteLine($"Missing: {string.Join(", ", ex.MissingKeys)}");
 21/// }
 22/// </code>
 23/// </example>
 24public class SecretValidationException : Exception
 25{
 26  /// <summary>
 27  /// Keys whose values were null, empty, or whitespace.
 28  /// Empty when the entire dictionary was empty.
 29  /// </summary>
 30  public IReadOnlyList<string> MissingKeys { get; }
 31
 32  /// <summary>
 33  /// Initializes a new instance with the keys that failed validation.
 34  /// </summary>
 35  /// <param name="missingKeys">
 36  /// Keys whose values were null, empty, or whitespace.
 37  /// Pass an empty list when the entire dictionary was empty.
 38  /// </param>
 39  public SecretValidationException(IReadOnlyList<string> missingKeys)
 40    : base(BuildMessage(missingKeys))
 41  {
 42    MissingKeys = missingKeys;
 43  }
 44
 45  private static string BuildMessage(IReadOnlyList<string> missingKeys)
 46  {
 47    if (missingKeys.Count == 0)
 48    {
 49      return "No secrets were resolved.";
 50    }
 51
 52    return $"The following secrets have empty or missing values: {string.Join(", ", missingKeys)}";
 53  }
 54}
 55
 56/// <summary>
 57/// Extension methods for validating resolved secret dictionaries.
 58/// </summary>
 59public static class SecretValidationExtensions
 60{
 61  /// <summary>
 62  /// Validates that the dictionary is not empty and every value is non-null
 63  /// and non-whitespace. Throws <see cref="SecretValidationException"/> on failure.
 64  /// </summary>
 65  /// <param name="secrets">The resolved secrets to validate.</param>
 66  /// <exception cref="ArgumentNullException">When <paramref name="secrets"/> is null.</exception>
 67  /// <exception cref="SecretValidationException">
 68  /// When the dictionary is empty or any value is null, empty, or whitespace.
 69  /// </exception>
 70  /// <example>
 71  /// <code>
 72  /// var secrets = Envilder.ResolveFile("envilder.json");
 73  /// secrets.ValidateSecrets(); // throws if any value is empty
 74  /// </code>
 75  /// </example>
 76  public static void ValidateSecrets(this IReadOnlyDictionary<string, string> secrets)
 77  {
 178    if (secrets is null)
 79    {
 180      throw new ArgumentNullException(nameof(secrets));
 81    }
 82
 183    if (secrets.Count == 0)
 84    {
 185      throw new SecretValidationException(Array.Empty<string>());
 86    }
 87
 188    var missingKeys = secrets
 189      .Where(kvp => string.IsNullOrWhiteSpace(kvp.Value))
 190      .Select(kvp => kvp.Key)
 191      .ToList();
 92
 193    if (missingKeys.Count > 0)
 94    {
 195      throw new SecretValidationException(missingKeys);
 96    }
 197  }
 98}