|
| 1 | +// Copyright (c) Microsoft. All rights reserved. |
| 2 | +// Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| 3 | + |
| 4 | +using System; |
| 5 | +using System.Collections.Generic; |
| 6 | +using System.Drawing; |
| 7 | +using System.Drawing.Imaging; |
| 8 | +using System.IO; |
| 9 | +using System.Linq; |
| 10 | +using System.Text; |
| 11 | +using System.Threading.Tasks; |
| 12 | +using System.Xml.Linq; |
| 13 | +using DocumentFormat.OpenXml.Packaging; |
| 14 | +using DocumentFormat.OpenXml.Validation; |
| 15 | +using DocumentFormat.OpenXml.Wordprocessing; |
| 16 | +using OpenXmlPowerTools; |
| 17 | +using Xunit; |
| 18 | + |
| 19 | +#if !ELIDE_XUNIT_TESTS |
| 20 | + |
| 21 | +namespace OxPt |
| 22 | +{ |
| 23 | + public class FaTests |
| 24 | + { |
| 25 | + [Theory] |
| 26 | + [InlineData("FA001-00010", "FA/RevTracking/001-DeletedRun.docx")] |
| 27 | + [InlineData("FA001-00020", "FA/RevTracking/002-DeletedNumberedParagraphs.docx")] |
| 28 | + [InlineData("FA001-00030", "FA/RevTracking/003-DeletedFieldCode.docx")] |
| 29 | + [InlineData("FA001-00040", "FA/RevTracking/004-InsertedNumberingProperties.docx")] |
| 30 | + [InlineData("FA001-00050", "FA/RevTracking/005-InsertedNumberedParagraph.docx")] |
| 31 | + [InlineData("FA001-00060", "FA/RevTracking/006-DeletedTableRow.docx")] |
| 32 | + [InlineData("FA001-00070", "FA/RevTracking/007-InsertedTableRow.docx")] |
| 33 | + [InlineData("FA001-00080", "FA/RevTracking/008-InsertedFieldCode.docx")] |
| 34 | + [InlineData("FA001-00090", "FA/RevTracking/009-InsertedParagraph.docx")] |
| 35 | + [InlineData("FA001-00100", "FA/RevTracking/010-InsertedRun.docx")] |
| 36 | + [InlineData("FA001-00110", "FA/RevTracking/011-InsertedMathChar.docx")] |
| 37 | + [InlineData("FA001-00120", "FA/RevTracking/012-DeletedMathChar.docx")] |
| 38 | + [InlineData("FA001-00130", "FA/RevTracking/013-DeletedParagraph.docx")] |
| 39 | + [InlineData("FA001-00140", "FA/RevTracking/014-MovedParagraph.docx")] |
| 40 | + [InlineData("FA001-00150", "FA/RevTracking/015-InsertedContentControl.docx")] |
| 41 | + [InlineData("FA001-00160", "FA/RevTracking/016-DeletedContentControl.docx")] |
| 42 | + [InlineData("FA001-00170", "FA/RevTracking/017-NumberingChange.docx")] |
| 43 | + [InlineData("FA001-00180", "FA/RevTracking/018-ParagraphPropertiesChange.docx")] |
| 44 | + [InlineData("FA001-00190", "FA/RevTracking/019-RunPropertiesChange.docx")] |
| 45 | + [InlineData("FA001-00200", "FA/RevTracking/020-SectionPropertiesChange.docx")] |
| 46 | + [InlineData("FA001-00210", "FA/RevTracking/021-TableGridChange.docx")] |
| 47 | + [InlineData("FA001-00220", "FA/RevTracking/022-TablePropertiesChange.docx")] |
| 48 | + [InlineData("FA001-00230", "FA/RevTracking/023-CellPropertiesChange.docx")] |
| 49 | + [InlineData("FA001-00240", "FA/RevTracking/024-RowPropertiesChange.docx")] |
| 50 | + |
| 51 | + public void FA001_DocumentsWithRevTracking(string testId, string src) |
| 52 | + { |
| 53 | + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 54 | + // Load the source document |
| 55 | + DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/"); |
| 56 | + FileInfo sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src)); |
| 57 | + WmlDocument wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName); |
| 58 | + |
| 59 | + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 60 | + // Create the dir for the test |
| 61 | + var rootTempDir = TestUtil.TempDir; |
| 62 | + var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId)); |
| 63 | + if (thisTestTempDir.Exists) |
| 64 | + Assert.True(false, "Duplicate test id: " + testId); |
| 65 | + else |
| 66 | + thisTestTempDir.Create(); |
| 67 | + var tempDirFullName = thisTestTempDir.FullName; |
| 68 | + |
| 69 | + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 70 | + // Copy src DOCX to temp directory, for ease of review |
| 71 | + |
| 72 | + var sourceDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name)); |
| 73 | + if (!sourceDocxCopiedToDestFileName.Exists) |
| 74 | + wmlSourceDocument.SaveAs(sourceDocxCopiedToDestFileName.FullName); |
| 75 | + |
| 76 | + var sourceDocxAcceptedCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name.ToLower().Replace(".docx", "-accepted.docx"))); |
| 77 | + var wmlSourceAccepted = RevisionProcessor.AcceptRevisions(wmlSourceDocument); |
| 78 | + wmlSourceAccepted.SaveAs(sourceDocxAcceptedCopiedToDestFileName.FullName); |
| 79 | + |
| 80 | + var outFi = new FileInfo(Path.Combine(tempDirFullName, "Output.docx")); |
| 81 | + FormattingAssemblerSettings settings = new FormattingAssemblerSettings(); |
| 82 | + var assembledWml = FormattingAssembler.AssembleFormatting(wmlSourceDocument, settings); |
| 83 | + assembledWml.SaveAs(outFi.FullName); |
| 84 | + |
| 85 | + var outAcceptedFi = new FileInfo(Path.Combine(tempDirFullName, "Output-accepted.docx")); |
| 86 | + var assembledAcceptedWml = RevisionProcessor.AcceptRevisions(assembledWml); |
| 87 | + assembledAcceptedWml.SaveAs(outAcceptedFi.FullName); |
| 88 | + |
| 89 | + Validate(outFi); |
| 90 | + } |
| 91 | + |
| 92 | + private void Validate(FileInfo fi) |
| 93 | + { |
| 94 | + using (WordprocessingDocument wDoc = WordprocessingDocument.Open(fi.FullName, true)) |
| 95 | + { |
| 96 | + OpenXmlValidator v = new OpenXmlValidator(); |
| 97 | + var errors = v.Validate(wDoc).Where(ve => |
| 98 | + { |
| 99 | + var found = s_ExpectedErrors.Any(xe => ve.Description.Contains(xe)); |
| 100 | + return !found; |
| 101 | + }); |
| 102 | + |
| 103 | + if (errors.Count() != 0) |
| 104 | + { |
| 105 | + StringBuilder sb = new StringBuilder(); |
| 106 | + foreach (var item in errors) |
| 107 | + { |
| 108 | + sb.Append(item.Description).Append(Environment.NewLine); |
| 109 | + } |
| 110 | + var s = sb.ToString(); |
| 111 | + Assert.True(false, s); |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + private static List<string> s_ExpectedErrors = new List<string>() |
| 117 | + { |
| 118 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenHBand' attribute is not declared.", |
| 119 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:evenVBand' attribute is not declared.", |
| 120 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstColumn' attribute is not declared.", |
| 121 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstRow' attribute is not declared.", |
| 122 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstRowFirstColumn' attribute is not declared.", |
| 123 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:firstRowLastColumn' attribute is not declared.", |
| 124 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastColumn' attribute is not declared.", |
| 125 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastRow' attribute is not declared.", |
| 126 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastRowFirstColumn' attribute is not declared.", |
| 127 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:lastRowLastColumn' attribute is not declared.", |
| 128 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noHBand' attribute is not declared.", |
| 129 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:noVBand' attribute is not declared.", |
| 130 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:oddHBand' attribute is not declared.", |
| 131 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:oddVBand' attribute is not declared.", |
| 132 | + "The element has unexpected child element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:updateFields'.", |
| 133 | + "The attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:name' has invalid value 'useWord2013TrackBottomHyphenation'. The Enumeration constraint failed.", |
| 134 | + "The 'http://schemas.microsoft.com/office/word/2012/wordml:restartNumberingAfterBreak' attribute is not declared.", |
| 135 | + "Attribute 'id' should have unique value. Its current value '", |
| 136 | + "The 'urn:schemas-microsoft-com:mac:vml:blur' attribute is not declared.", |
| 137 | + "Attribute 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:id' should have unique value. Its current value '", |
| 138 | + "The element has unexpected child element 'http://schemas.microsoft.com/office/word/2012/wordml:", |
| 139 | + "The element has invalid child element 'http://schemas.microsoft.com/office/word/2012/wordml:", |
| 140 | + "The 'urn:schemas-microsoft-com:mac:vml:complextextbox' attribute is not declared.", |
| 141 | + "http://schemas.microsoft.com/office/word/2010/wordml:", |
| 142 | + "http://schemas.microsoft.com/office/word/2008/9/12/wordml:", |
| 143 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:allStyles' attribute is not declared.", |
| 144 | + "The 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:customStyles' attribute is not declared.", |
| 145 | + "The element has invalid child element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:ins'.", |
| 146 | + "The element has invalid child element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:del'.", |
| 147 | + }; |
| 148 | + } |
| 149 | +} |
| 150 | +#endif |
0 commit comments