From 1ee3702ac531ebe81fecf4d676d86dc9060a3207 Mon Sep 17 00:00:00 2001 From: Mattias Rasmusson Date: Thu, 22 May 2025 17:31:02 -0700 Subject: [PATCH] Add unit test for header field merge --- .../FunctionalSpecs/DomainExtensions.cs | 29 +++++++++++++++++++ .../GivenFldSimpleMergeField.cs | 19 ++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/MailMerge.Tests/FunctionalSpecs/DomainExtensions.cs b/MailMerge.Tests/FunctionalSpecs/DomainExtensions.cs index 4314218..c6bd877 100644 --- a/MailMerge.Tests/FunctionalSpecs/DomainExtensions.cs +++ b/MailMerge.Tests/FunctionalSpecs/DomainExtensions.cs @@ -1,7 +1,9 @@ +using DocumentFormat.OpenXml.Packaging; using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using TestBase; namespace MailMerge.Tests.FunctionalSpecs @@ -34,5 +36,32 @@ public static (string asText, string asXml) AsWordDocumentMainPartTextAndXml(thi return (asText, asXml); } + + public static (string allHeaderText, string allHeaderXml) GetCombinedHeadersTextAndXml(this Stream documentStream) + { + var sbHeaderText = new StringBuilder(); + var sbHeaderXml = new StringBuilder(); + + if (documentStream.CanSeek) + { + documentStream.Position = 0; + } + + using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(documentStream, isEditable: false)) + { + if (wordDoc.MainDocumentPart != null) + { + foreach (HeaderPart headerPart in wordDoc.MainDocumentPart.HeaderParts) + { + if (headerPart.Header != null) + { + sbHeaderText.Append(headerPart.Header.InnerText); + sbHeaderXml.Append(headerPart.Header.OuterXml); + } + } + } + } + return (sbHeaderText.ToString(), sbHeaderXml.ToString()); + } } } \ No newline at end of file diff --git a/MailMerge.Tests/FunctionalSpecs/GivenFldSimpleMergeField.cs b/MailMerge.Tests/FunctionalSpecs/GivenFldSimpleMergeField.cs index 194f810..781a05d 100644 --- a/MailMerge.Tests/FunctionalSpecs/GivenFldSimpleMergeField.cs +++ b/MailMerge.Tests/FunctionalSpecs/GivenFldSimpleMergeField.cs @@ -15,6 +15,7 @@ public class GivenFldSimpleMergeField { const string TestDocDir = "TestDocuments"; const string DocWithSimpleMergeFieldDocx = "DocWithSimpleMergeField.docx"; + const string DocWithFieldInHeaderDocx = "DocWithFieldInHeader.docx"; MailMerger sut; static Dictionary SingleLine = new Dictionary @@ -26,9 +27,17 @@ public class GivenFldSimpleMergeField { {"SimpleMergeField","SimpleMergeField Was\nReplaced\nwith multiple lines\ndelimited by newlines/"} }; - + + static readonly Dictionary HeaderAndBodyFields = new Dictionary + { + { "FieldInHeader", "Yes, you can!" }, // Expected in header + { "FirstName", "A replaced first name field" }, // Expected in body + { "LastName", "A replaced last name field" } // Expected in body + }; + [TestCase(DocWithSimpleMergeFieldDocx, nameof(SingleLine))] [TestCase(DocWithSimpleMergeFieldDocx, nameof(MultiLine))] + [TestCase(DocWithFieldInHeaderDocx, nameof(HeaderAndBodyFields))] public void Returns_TheDocumentWithMergeFieldsReplaced(string source, string sourceFieldsSource) { source = Path.Combine(TestDocDir, source); @@ -45,6 +54,9 @@ public void Returns_TheDocumentWithMergeFieldsReplaced(string source, string sou var (outputText, outputXml) = output.AsWordDocumentMainPartTextAndXml(); + var (headerPartText, headerXml) = output.GetCombinedHeadersTextAndXml(); + + var combinedDocumentText = outputText + " " + headerPartText; using (var outFile = new FileInfo(source.Replace(".", $" {sourceFieldsSource} Output.")).OpenWrite()) { output.Position = 0; @@ -53,15 +65,16 @@ public void Returns_TheDocumentWithMergeFieldsReplaced(string source, string sou if (exceptions.InnerExceptions.Any()) { throw exceptions; } + var combinedOutputXml = outputXml + " " + headerXml; sourceFields .Values .Cast() - .ShouldHaveBeenSplitOnNewLinesAndEachLineInserted(outputXml); + .ShouldHaveBeenSplitOnNewLinesAndEachLineInserted(combinedOutputXml); sourceFields .Keys - .ShouldAll(k => outputText.ShouldNotContain("«" + k + "»")); + .ShouldAll(k => combinedDocumentText.ShouldNotContain("«" + k + "»")); } finally{ output?.Dispose(); }