{layout.Sentinel}
", layout.Html, StringComparison.Ordinal) + .Replace(layout.Sentinel, layout.Html, StringComparison.Ordinal); + } + + return html; + } +} diff --git a/Core/Printing/PrintEntityType.cs b/Core/Printing/PrintEntityType.cs new file mode 100644 index 0000000..79f23be --- /dev/null +++ b/Core/Printing/PrintEntityType.cs @@ -0,0 +1,11 @@ +namespace Core.Printing; + +///{NoteTemplateMerger.PageBreakSentinel}
"); + + Assert.That(raw, Is.EqualTo($"x{NoteTemplateMerger.PageBreakHtml}y")); + Assert.That(wrapped, Is.EqualTo(NoteTemplateMerger.PageBreakHtml)); + } + + [Test] + public void Merge_AnswerSpace_IsSentinel() + { + var result = NoteTemplateMerger.Merge( + "Q?\n{{AnswerSpace}}\nNext", + PrintTokenMap.Create()); + + Assert.That(result, Does.Contain(NoteTemplateMerger.AnswerSpaceSentinel)); + Assert.That(result, Does.Not.Contain("{{AnswerSpace}}")); + } + + [Test] + public void ApplyLayout_ReplacesAnswerSpaceSentinelAndParagraphWrap() + { + var raw = NoteTemplateMerger.ApplyLayout( + $"x{NoteTemplateMerger.AnswerSpaceSentinel}y"); + var wrapped = NoteTemplateMerger.ApplyLayout( + $"{NoteTemplateMerger.AnswerSpaceSentinel}
"); + + Assert.That(raw, Is.EqualTo($"x{NoteTemplateMerger.AnswerSpaceHtml}y")); + Assert.That(wrapped, Is.EqualTo(NoteTemplateMerger.AnswerSpaceHtml)); + } +} diff --git a/Tests/Printing/PrintFieldCatalog_Tests.cs b/Tests/Printing/PrintFieldCatalog_Tests.cs new file mode 100644 index 0000000..b181bd7 --- /dev/null +++ b/Tests/Printing/PrintFieldCatalog_Tests.cs @@ -0,0 +1,39 @@ +using Core.Printing; + +namespace Tests.Printing; + +[TestFixture] +public class PrintFieldCatalog_Tests +{ + [Test] + public void BuiltInFor_StudentIncludesChapterAndStudentTokens() + { + var tokens = PrintFieldCatalog.BuiltInFor(PrintEntityType.Student); + + Assert.That(tokens, Does.Contain("FirstName")); + Assert.That(tokens, Does.Contain("Chapter.ShortName")); + Assert.That(tokens, Does.Not.Contain("Interview Time")); + } + + [Test] + public void BuiltInFor_TeamAndEventHaveExpectedNames() + { + Assert.That(PrintFieldCatalog.BuiltInFor(PrintEntityType.Team), Does.Contain("EventName")); + Assert.That(PrintFieldCatalog.BuiltInFor(PrintEntityType.Event), Does.Contain("RegionalEvent")); + } + + [Test] + public void Layout_IncludesPageBreakAndAnswerSpace() + { + Assert.That(PrintFieldCatalog.Layout, Does.Contain(NoteTemplateMerger.PageBreakToken)); + Assert.That(PrintFieldCatalog.Layout, Does.Contain(NoteTemplateMerger.AnswerSpaceToken)); + } + + [Test] + public void EntityTokens_MatchesCatalogArrays() + { + Assert.That(PrintFieldCatalog.EntityTokens(PrintEntityType.Student), Is.EqualTo(PrintFieldCatalog.Student)); + Assert.That(PrintFieldCatalog.EntityTokens(PrintEntityType.Team), Is.EqualTo(PrintFieldCatalog.Team)); + Assert.That(PrintFieldCatalog.EntityTokens(PrintEntityType.Event), Is.EqualTo(PrintFieldCatalog.Event)); + } +} diff --git a/Tests/Printing/PrintPresetFilters_Tests.cs b/Tests/Printing/PrintPresetFilters_Tests.cs new file mode 100644 index 0000000..6c8ee77 --- /dev/null +++ b/Tests/Printing/PrintPresetFilters_Tests.cs @@ -0,0 +1,54 @@ +using Core.Entities; +using Core.Printing; + +namespace Tests.Printing; + +[TestFixture] +public class PrintPresetFilters_Tests +{ + [Test] + public void JsonRoundTrip_PreservesStudentAndImportedFilters() + { + var filters = new PrintPresetFilters + { + Grade = 9, + TsaYear = 1, + IsOfficer = true, + RegionalOnly = true, + EventFormat = EventFormat.Team, + NewPagePerRecord = false, + FontSizePt = 14, + AnswerSpaceLines = 4 + }; + + var restored = PrintPresetFilters.FromJson(filters.ToJson()); + + Assert.That(restored.Grade, Is.EqualTo(9)); + Assert.That(restored.TsaYear, Is.EqualTo(1)); + Assert.That(restored.IsOfficer, Is.True); + Assert.That(restored.RegionalOnly, Is.True); + Assert.That(restored.EventFormat, Is.EqualTo(EventFormat.Team)); + Assert.That(restored.NewPagePerRecord, Is.False); + Assert.That(restored.FontSizePt, Is.EqualTo(14)); + Assert.That(restored.AnswerSpaceLines, Is.EqualTo(4)); + } + + [Test] + public void FromJson_EmptyOrInvalid_ReturnsDefaults() + { + Assert.That(PrintPresetFilters.FromJson(null).TsaYear, Is.Null); + Assert.That(PrintPresetFilters.FromJson("{}").Grade, Is.Null); + Assert.That(PrintPresetFilters.FromJson("{}").NewPagePerRecord, Is.True); + Assert.That(PrintPresetFilters.FromJson("{}").FontSizePt, Is.EqualTo(PrintPresetFilters.DefaultFontSizePt)); + Assert.That(PrintPresetFilters.FromJson("{}").AnswerSpaceLines, Is.EqualTo(PrintPresetFilters.DefaultAnswerSpaceLines)); + } + + [Test] + public void FromJson_ClampsPrintOptions() + { + var restored = PrintPresetFilters.FromJson("""{"fontSizePt":99,"answerSpaceLines":0}"""); + + Assert.That(restored.FontSizePt, Is.EqualTo(PrintPresetFilters.MaxFontSizePt)); + Assert.That(restored.AnswerSpaceLines, Is.EqualTo(PrintPresetFilters.MinAnswerSpaceLines)); + } +} diff --git a/Tests/Printing/PrintTokenMap_Tests.cs b/Tests/Printing/PrintTokenMap_Tests.cs new file mode 100644 index 0000000..57aba76 --- /dev/null +++ b/Tests/Printing/PrintTokenMap_Tests.cs @@ -0,0 +1,59 @@ +using Core.Printing; + +namespace Tests.Printing; + +[TestFixture] +public class PrintTokenMap_Tests +{ + [Test] + public void Build_BuiltInWinsOverImportedSameName() + { + var map = PrintTokenMap.Build( + new Dictionary