using System.Net; using System.Net.Http.Json; using BigRegister.Api.Contracts; using BigRegister.Api.Data; using Microsoft.AspNetCore.Mvc.Testing; namespace BigRegister.Tests; /// /// WP-25: the two HTML preview endpoints. Both are excluded from the OpenAPI doc /// (see the drift check in the API-client generation step) — these tests hit them /// as plain HTTP, the same way the hand-written FE fetch does. /// public class PreviewEndpointTests(TestWebApplicationFactory factory) : IClassFixture { private const string Registers = OrgTemplateSeed.Registers; private readonly HttpClient _client = factory.CreateClient(); private static LetterBlockDto FreeText(string id) => new("freeText", id, new RichTextBlockDto(new[] { new ParagraphDto(new[] { new RichTextNodeDto("text", Text: "inhoud") }) })); private static SaveBriefRequest FilledFrom(BriefDto brief) { var i = 0; var sections = brief.Sections .Select(s => new LetterSectionDto(s.SectionKey, s.Title, s.Required, s.Required ? new[] { FreeText($"local-{++i}") } : s.Blocks)) .ToList(); return new SaveBriefRequest(sections); } private static void ResetStores() { BriefStore.Reset(); OrgTemplateStore.Reset(); } private HttpRequestMessage Req(HttpMethod method, string path, string? role = null) => role is null ? new HttpRequestMessage(method, path) : new HttpRequestMessage(method, path) { Headers = { { "X-Role", role } } }; [Fact] public async Task Preview_of_an_unsent_brief_renders_live_with_a_watermark() { ResetStores(); await _client.GetAsync("/api/v1/brief"); // GetOrCreate the demo draft var res = await _client.GetAsync("/api/v1/brief/preview"); res.EnsureSuccessStatusCode(); Assert.Equal("text/html", res.Content.Headers.ContentType?.MediaType); var html = await res.Content.ReadAsStringAsync(); Assert.Contains("
("/api/v1/brief"))!.Brief; await _client.PutAsJsonAsync("/api/v1/brief", FilledFrom(brief)); await _client.SendAsync(Req(HttpMethod.Post, "/api/v1/brief/submit")); await _client.SendAsync(Req(HttpMethod.Post, "/api/v1/brief/approve", role: "approver")); await _client.SendAsync(Req(HttpMethod.Post, "/api/v1/brief/send")); var sentHtml = await (await _client.GetAsync("/api/v1/brief/preview")).Content.ReadAsStringAsync(); Assert.DoesNotContain("
())!.Draft; await _client.SendAsync(new HttpRequestMessage(HttpMethod.Put, $"/api/v1/admin/org-template/{Registers}") { Headers = { { "X-Role", "admin" } }, Content = JsonContent.Create(new SaveOrgTemplateRequest(draft with { OrgName = "Hertitelde organisatie" })), }); await _client.SendAsync(Req(HttpMethod.Post, $"/api/v1/admin/org-template/{Registers}/publish", role: "admin")); // The sent brief's preview is unchanged — still the archived rendering. var afterRepublish = await (await _client.GetAsync("/api/v1/brief/preview")).Content.ReadAsStringAsync(); Assert.Equal(sentHtml, afterRepublish); Assert.DoesNotContain("Hertitelde organisatie", afterRepublish); } [Fact] public async Task Proefbrief_is_admin_only_and_renders_the_draft_template() { ResetStores(); Assert.Equal(HttpStatusCode.Forbidden, (await _client.GetAsync($"/api/v1/admin/org-template/{Registers}/preview")).StatusCode); var res = await _client.SendAsync(Req(HttpMethod.Get, $"/api/v1/admin/org-template/{Registers}/preview", role: "admin")); res.EnsureSuccessStatusCode(); var html = await res.Content.ReadAsStringAsync(); Assert.Contains("BIG-register", html); Assert.Contains("