commits
tags
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");
}
}