using System.Net; using System.Net.Http.Json; using System.Text; using System.Text.Json; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; /// /// Tests for cover sheet PDF generation endpoints and the PDF builder. /// [Collection("Database")] public class CoverSheetPdfTests : IAsyncLifetime { private readonly ApiFixture _fixture; private HttpClient _intakeClient = null!; public CoverSheetPdfTests(ApiFixture fixture) => _fixture = fixture; public async Task InitializeAsync() { using var scope = _fixture.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); await DbResetHelper.ResetAsync(db); await DataSeeder.SeedAsync(db); _intakeClient = await AuthHelper.LoginAsync(_fixture, "intake1"); } public Task DisposeAsync() => Task.CompletedTask; [Fact] public void Generate_ProducesValidPdfWithCoverSheetMetadata() { var sheet = new CoverSheet { Id = Guid.NewGuid(), Code = "VCR-CS-A3F7B2D1", BatchType = BatchType.VitalsSheet, Track = BatchTrack.Backfill, CreatedAt = new DateTimeOffset(2026, 6, 27, 12, 0, 0, TimeSpan.Zero), Patient = new Patient { Id = Guid.NewGuid(), FullName = "Maria Garcia", Mrn = "MRN-12345" }, AssignToUser = new User { Id = Guid.NewGuid(), FullName = "Entry Clerk One" } }; var pdf = CoverSheetPdfGenerator.Generate(sheet); var text = Encoding.ASCII.GetString(pdf); text.Should().StartWith("%PDF-1.4"); text.Should().Contain("VCR-CS-A3F7B2D1"); text.Should().Contain("VITALS_SHEET"); text.Should().Contain("BACKFILL"); text.Should().Contain("Maria Garcia"); text.Should().Contain("MRN-12345"); text.Should().Contain("Entry Clerk One"); text.Should().Contain("2026-06-27"); text.Should().Contain("Attach to front of chart section"); text.Should().Contain("/Subtype /Image"); } [Fact] public void GenerateBatch_ProducesMultiPagePdf() { var sheets = new[] { new CoverSheet { Id = Guid.NewGuid(), Code = "VCR-CS-11111111", BatchType = BatchType.VitalsSheet, Track = BatchTrack.Backfill, CreatedAt = DateTimeOffset.UtcNow }, new CoverSheet { Id = Guid.NewGuid(), Code = "VCR-CS-22222222", BatchType = BatchType.LabResults, Track = BatchTrack.Backfill, CreatedAt = DateTimeOffset.UtcNow } }; var pdf = CoverSheetPdfGenerator.GenerateBatch(sheets); var text = Encoding.ASCII.GetString(pdf); text.Should().Contain("/Count 2"); text.Should().Contain("VCR-CS-11111111"); text.Should().Contain("VCR-CS-22222222"); } [Fact] public async Task GeneratePdf_Endpoint_ReturnsPdfForCoverSheetId() { var sheetId = await GenerateCoverSheetIdAsync(); var response = await _intakeClient.PostAsync($"/api/v1/cover-sheets/{sheetId}/pdf", null); response.StatusCode.Should().Be(HttpStatusCode.OK); response.Content.Headers.ContentType!.MediaType.Should().Be("application/pdf"); var bytes = await response.Content.ReadAsByteArrayAsync(); var text = Encoding.ASCII.GetString(bytes); text.Should().StartWith("%PDF-1.4"); text.Should().Contain("VCR-CS-"); } [Fact] public async Task GenerateBatchPdf_Endpoint_ReturnsMultiPagePdf() { var ids = new List { await GenerateCoverSheetIdAsync(), await GenerateCoverSheetIdAsync() }; var response = await _intakeClient.PostAsJsonAsync( "/api/v1/cover-sheets/batch-pdf", new { coverSheetIds = ids }); response.StatusCode.Should().Be(HttpStatusCode.OK); response.Content.Headers.ContentType!.MediaType.Should().Be("application/pdf"); var text = Encoding.ASCII.GetString(await response.Content.ReadAsByteArrayAsync()); text.Should().Contain("/Count 2"); } [Fact] public async Task GeneratePdf_UnknownId_Returns404() { var response = await _intakeClient.PostAsync( $"/api/v1/cover-sheets/{Guid.NewGuid()}/pdf", null); response.StatusCode.Should().Be(HttpStatusCode.NotFound); } private async Task GenerateCoverSheetIdAsync() { var response = await _intakeClient.PostAsJsonAsync( "/api/v1/cover-sheets/generate", new { count = 1, batchType = "VITALS_SHEET", track = "BACKFILL" }); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadFromJsonAsync(); return body.GetProperty("data")[0].GetProperty("id").GetGuid(); } }