Files
Ludarium release export df869819ce
Public source validation / source (push) Successful in 2m16s
Publish Ludarium source
2026-09-03 02:08:58 +02:00

58 lines
2.8 KiB
C#

using System.IO.Compression;
using System.Reflection;
using Ludarium.Application;
using Ludarium.Domain;
using Ludarium.Infrastructure;
namespace Ludarium.IntegrationTests;
public sealed class SupportBundleServiceTests
{
[Fact]
public async Task BundleRedactsPathsErrorsAndFindingDiagnosticsByConstruction()
{
const string secret = "super-secret-token";
var now = DateTimeOffset.UtcNow;
var libraryId = Guid.NewGuid();
var store = DispatchProxy.Create<ILudariumStore, SupportStoreProxy>();
var proxy = (SupportStoreProxy)(object)store;
proxy.Libraries = [new(libraryId, "Games", $"/mnt/{secret}", LibraryKind.Mixed, true, HashPolicy.Sha256, false, 1, true, true, true, true, now)];
proxy.Scans = [new(Guid.NewGuid(), libraryId, ScanMode.Deep, ScanState.Failed, "failed", 1, 1, 10, 10, null, false, now, now, now, $"Host=database;Password={secret}")];
proxy.Findings = [new(Guid.NewGuid(), "Integrity", Severity.Critical, $"API key {secret} found at /mnt/private/game.rom", null, null, now)];
var directory = Path.Combine(Path.GetTempPath(), "ludarium-support-tests", Guid.NewGuid().ToString("N"));
try
{
var result = await new SupportBundleService(store, directory).CreateAsync(CancellationToken.None);
using var archive = ZipFile.OpenRead(Path.Combine(directory, result.FileName));
var text = string.Join('\n', archive.Entries.Select(entry =>
{
using var reader = new StreamReader(entry.Open());
return reader.ReadToEnd();
}));
Assert.DoesNotContain(secret, text, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("/mnt/private", text, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("Password=", text, StringComparison.OrdinalIgnoreCase);
Assert.Contains("[redacted]", text, StringComparison.OrdinalIgnoreCase);
}
finally
{
if (Directory.Exists(directory)) Directory.Delete(directory, true);
}
}
public class SupportStoreProxy : DispatchProxy
{
public IReadOnlyList<LibraryRoot> Libraries { get; set; } = [];
public IReadOnlyList<ScanRun> Scans { get; set; } = [];
public IReadOnlyList<Finding> Findings { get; set; } = [];
protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) => targetMethod?.Name switch
{
nameof(ILudariumStore.ListLibrariesAsync) => Task.FromResult(Libraries),
nameof(ILudariumStore.ListScansAsync) => Task.FromResult(Scans),
nameof(ILudariumStore.ListFindingsAsync) => Task.FromResult(Findings),
_ => throw new NotSupportedException(targetMethod?.Name)
};
}
}