using JobTrackerApi.Models; using JobTrackerApi.Services; using System.Text.Json; using Xunit; namespace JobTrackerApi.Tests; public sealed class CoverLetterDocumentContractTests { [Theory] [InlineData("en", "Cover letter", "Cover letter text")] [InlineData("nb-NO", "Søknadsbrev", "Brevtekst")] public void Empty_optional_details_do_not_create_empty_headings_or_an_unnamed_main_landmark(string language, string title, string bodyLabel) { var html = new CoverLetterDocumentRenderer().Render("Reviewed body", new() { Language = language }).Html; Assert.DoesNotContain("

", html); Assert.DoesNotContain("

", html); Assert.Contains($"{System.Net.WebUtility.HtmlEncode(title)}", html); Assert.Contains($"
", html); } [Theory] [InlineData(null, "en")] [InlineData("{}", "en")] [InlineData("{\"senderName\":\"Legacy sender\"}", "en")] [InlineData("{\"language\":\"en\"}", "en")] [InlineData("{\"language\":\"nb\"}", "nb-NO")] [InlineData("{\"language\":\"nb-NO\"}", "nb-NO")] [InlineData("{\"language\":\" NB-no \"}", "nb-NO")] [InlineData("{\"language\":null}", "en")] [InlineData("{\"language\":\"fr\"}", "en")] [InlineData("{\"language\":\"en\\\" onload=alert(1)\"}", "en")] public void Document_language_defaults_normalizes_and_roundtrips_only_supported_values(string? json, string expected) { var settings = CoverLetterDocumentSettingsJson.Deserialize(json); var normalized = CoverLetterDocumentSettingsJson.Serialize(settings); Assert.Equal(expected, JsonDocument.Parse(normalized).RootElement.GetProperty("language").GetString()); Assert.Equal(normalized, CoverLetterDocumentSettingsJson.Serialize(CoverLetterDocumentSettingsJson.Deserialize(normalized))); var html = new CoverLetterDocumentRenderer().Render("Reviewed letter — æøå", settings).Html; Assert.Contains($"", html); Assert.DoesNotContain("onload=", html); } [Fact] public void Document_style_reuses_cv_allowlists_clamps_non_finite_values_and_escapes_all_metadata() { var settings = CoverLetterDocumentSettingsJson.Normalize(new() { ThemeId = "unknown", BodyFont = "Arial; background:url(https://invalid.test)", AccentColor = "#fff;bad", BaseFontSizePt = 100, LineHeight = double.PositiveInfinity, PageMarginMm = -10, PageSize = "