< Summary

Information
Class: Orchestrator.Commands.Utility.Snapshots.SnapshotsEncryptCommand
Assembly: Orchestrator
File(s): /home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotsEncryptCommand.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 72
Coverable lines: 72
Total lines: 129
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
ExecuteAsync()0%4260%
EncryptSnapshotsAsync()0%620%
<EncryptSnapshotsAsync()0%2040%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotsEncryptCommand.cs

#LineLine coverage
 1using Microsoft.Extensions.Logging;
 2using Spectre.Console;
 3using Spectre.Console.Cli;
 4
 5namespace Orchestrator.Commands.Utility.Snapshots;
 6
 7/// <summary>
 8/// Command for encrypting HTML snapshots for safe committing.
 9/// </summary>
 10public class SnapshotsEncryptCommand : AsyncCommand<SnapshotsEncryptSettings>
 11{
 12    private readonly IAnsiConsole _console;
 13    private readonly ILogger<SnapshotsEncryptCommand> _logger;
 14
 015    public SnapshotsEncryptCommand(IAnsiConsole console, ILogger<SnapshotsEncryptCommand> logger)
 16    {
 017        _console = console;
 018        _logger = logger;
 019    }
 20
 21    public override async Task<int> ExecuteAsync(CommandContext context, SnapshotsEncryptSettings settings)
 22    {
 23
 24        try
 25        {
 26            // Get encryption key from environment (loaded at startup)
 027            var encryptionKey = Environment.GetEnvironmentVariable("KICKTIPP_FIXTURE_KEY");
 028            if (string.IsNullOrEmpty(encryptionKey))
 29            {
 030                _console.MarkupLine("[red]Error: KICKTIPP_FIXTURE_KEY environment variable is not set.[/]");
 031                _console.WriteLine();
 032                _console.MarkupLine("[yellow]To generate a new key:[/]");
 033                _console.MarkupLine("[dim]  .\\Encrypt-Fixture.ps1 -GenerateKey[/]");
 034                _console.WriteLine();
 035                _console.MarkupLine("[yellow]Then store the key in:[/]");
 036                _console.MarkupLine("[dim]  <repo>/../KicktippAi.Secrets/tests/KicktippIntegration.Tests/.env[/]");
 037                return 1;
 38            }
 39
 040            var inputPath = Path.GetFullPath(settings.InputDirectory);
 41            // Output to community-specific subdirectory
 042            var outputPath = Path.GetFullPath(Path.Combine(settings.OutputDirectory, settings.Community));
 43
 044            if (!Directory.Exists(inputPath))
 45            {
 046                _console.MarkupLine($"[red]Error: Input directory not found: {inputPath}[/]");
 047                return 1;
 48            }
 49
 050            _console.MarkupLine("[green]Encrypting snapshots...[/]");
 051            _console.MarkupLine($"[blue]Community:[/] [yellow]{settings.Community}[/]");
 052            _console.MarkupLine($"[blue]Input directory:[/] [yellow]{inputPath}[/]");
 053            _console.MarkupLine($"[blue]Output directory:[/] [yellow]{outputPath}[/]");
 054            _console.WriteLine();
 55
 056            var (encryptedCount, deletedCount) = await EncryptSnapshotsAsync(
 057                _console, inputPath, outputPath, encryptionKey, settings.DeleteOriginals);
 58
 059            _console.WriteLine();
 060            _console.MarkupLine($"[green]Done![/] Encrypted {encryptedCount} file(s) to [yellow]{outputPath}[/]");
 61
 062            if (deletedCount > 0)
 63            {
 064                _console.MarkupLine($"[dim]Deleted {deletedCount} original HTML file(s)[/]");
 65            }
 66
 067            return 0;
 68        }
 069        catch (Exception ex)
 70        {
 071            _logger.LogError(ex, "Error encrypting snapshots");
 072            _console.MarkupLine($"[red]Error:[/] {ex.Message}");
 073            return 1;
 74        }
 075    }
 76
 77    internal static async Task<(int encryptedCount, int deletedCount)> EncryptSnapshotsAsync(
 78        IAnsiConsole console,
 79        string inputPath,
 80        string outputPath,
 81        string encryptionKey,
 82        bool deleteOriginals)
 83    {
 084        var encryptedCount = 0;
 085        var deletedCount = 0;
 86
 87        // Create output directory
 088        Directory.CreateDirectory(outputPath);
 89
 90        // Find all HTML files
 091        var htmlFiles = Directory.GetFiles(inputPath, "*.html");
 92
 093        if (htmlFiles.Length == 0)
 94        {
 095            console.MarkupLine("[yellow]No HTML files found to encrypt[/]");
 096            return (0, 0);
 97        }
 98
 099        await console.Status()
 0100            .StartAsync("Encrypting files...", async ctx =>
 0101            {
 0102                foreach (var htmlFile in htmlFiles)
 0103                {
 0104                    var fileName = Path.GetFileName(htmlFile);
 0105                    ctx.Status($"Encrypting {fileName}...");
 0106
 0107                    // Read and encrypt
 0108                    var content = await File.ReadAllTextAsync(htmlFile);
 0109                    var encrypted = SnapshotEncryptor.Encrypt(content, encryptionKey);
 0110
 0111                    // Write encrypted file
 0112                    var outputFile = Path.Combine(outputPath, $"{fileName}.enc");
 0113                    await File.WriteAllTextAsync(outputFile, encrypted);
 0114                    encryptedCount++;
 0115
 0116                    console.MarkupLine($"[green]✓[/] Encrypted {fileName} → {Path.GetFileName(outputFile)}");
 0117
 0118                    // Delete original if requested
 0119                    if (deleteOriginals)
 0120                    {
 0121                        File.Delete(htmlFile);
 0122                        deletedCount++;
 0123                    }
 0124                }
 0125            });
 126
 0127        return (encryptedCount, deletedCount);
 0128    }
 129}