foxygit / digitalskrivare_merge Log in
commits tags

/tests/Remiss.Core.Tests/WorkflowTests.cs · 3.99 KB

raw
using Remiss.Core;
using Remiss.Core.Abstractions;
using Remiss.Core.Audit;
using Remiss.Core.Models;
using Remiss.Core.Pdf;
using Remiss.Core.Security;
using Xunit;

namespace Remiss.Core.Tests;

public sealed class WorkflowTests : IDisposable
{
    private readonly string _dir = Path.Combine(Path.GetTempPath(), "remiss-wf-" + Guid.NewGuid().ToString("N"));

    public WorkflowTests() => Directory.CreateDirectory(_dir);

    public void Dispose()
    {
        try { Directory.Delete(_dir, recursive: true); } catch { /* ignore */ }
    }

    private sealed class FakePrinter : IPrinter
    {
        public string? PrintedFile { get; private set; }
        public string? Printer { get; private set; }
        public void Print(string pdfPath, string? printerName)
        {
            Assert.True(File.Exists(pdfPath));       // mergad fil finns när utskrift anropas
            PrintedFile = pdfPath;
            Printer = printerName;
        }
    }

    [Fact]
    public void Run_generatesMergesPrintsAndWritesDebugCopy()
    {
        var source = Path.Combine(_dir, "remiss.pdf");
        CoverPageGenerator.Generate(source, new CoverInfo("Body", "hsa-body", DateTime.Now));

        var debugDir = Path.Combine(_dir, "debug");
        var cfg = new AppConfig { TargetPrinter = "TestPrinter", DebugOutputDir = debugDir };
        var audit = new AuditLogger(Path.Combine(_dir, "audit.jsonl"), Path.Combine(_dir, "error.log"));
        var printer = new FakePrinter();

        using (var temp = new SecureTempStore(Path.Combine(_dir, "tmp")))
        {
            new RemissWorkflow(cfg, printer, audit).Run(source, new Mottagning("Hud SU", "hsa-1"), temp);
        }

        Assert.Equal("TestPrinter", printer.Printer);
        var debugCopies = Directory.GetFiles(debugDir, "remiss-debug-*.pdf");
        Assert.Single(debugCopies);

        using var merged = PdfSharp.Pdf.IO.PdfReader.Open(debugCopies[0], PdfSharp.Pdf.IO.PdfDocumentOpenMode.Import);
        Assert.Equal(2, merged.PageCount); // försättsblad + "remiss"

        var auditText = File.ReadAllText(Path.Combine(_dir, "audit.jsonl"));
        Assert.Contains("remiss.sent", auditText);
    }

    [Fact]
    public void Run_withBlankTargetPrinter_passesBlankThroughAndAuditsAPrinter()
    {
        var source = Path.Combine(_dir, "remiss.pdf");
        CoverPageGenerator.Generate(source, new CoverInfo("Body", "hsa-body", DateTime.Now));

        var cfg = new AppConfig { TargetPrinter = "" };
        var audit = new AuditLogger(Path.Combine(_dir, "audit.jsonl"), Path.Combine(_dir, "error.log"));
        var printer = new FakePrinter();

        using (var temp = new SecureTempStore(Path.Combine(_dir, "tmp")))
        {
            new RemissWorkflow(cfg, printer, audit).Run(source, new Mottagning("Hud SU", "hsa-1"), temp);
        }

        Assert.True(string.IsNullOrEmpty(printer.Printer));   // SumatraPDF väljer -print-to-default
        Assert.Contains("printer=", File.ReadAllText(Path.Combine(_dir, "audit.jsonl")));
    }

    [Fact]
    public void Run_propagatesPrinterFailureAndAuditsTheStage()
    {
        var source = Path.Combine(_dir, "remiss.pdf");
        CoverPageGenerator.Generate(source, new CoverInfo("Body", "hsa-body", DateTime.Now));

        var cfg = new AppConfig { TargetPrinter = "X" };
        var audit = new AuditLogger(Path.Combine(_dir, "audit.jsonl"), Path.Combine(_dir, "error.log"));

        var boom = new ThrowingPrinter();
        using var temp = new SecureTempStore(Path.Combine(_dir, "tmp"));

        Assert.Throws<InvalidOperationException>(() =>
            new RemissWorkflow(cfg, boom, audit).Run(source, new Mottagning("Hud SU", "hsa-1"), temp));

        var auditText = File.ReadAllText(Path.Combine(_dir, "audit.jsonl"));
        Assert.Contains("remiss.failed", auditText);
        Assert.Contains("\"stage\":\"print\"", auditText);
    }

    private sealed class ThrowingPrinter : IPrinter
    {
        public void Print(string pdfPath, string? printerName) => throw new InvalidOperationException("no printer");
    }
}