docx-reader.tests.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. var assert = require("assert");
  2. var docxReader = require("../../lib/docx/docx-reader");
  3. var documents = require("../../lib/documents");
  4. var xml = require("../../lib/xml");
  5. var testing = require("../testing");
  6. var test = require("../test")(module);
  7. var testData = testing.testData;
  8. var createFakeDocxFile = testing.createFakeDocxFile;
  9. test("can read document with single paragraph with single run of text", function() {
  10. var expectedDocument = documents.Document([
  11. documents.Paragraph([
  12. documents.Run([
  13. documents.Text("Hello.")
  14. ])
  15. ])
  16. ]);
  17. var docxFile = createFakeDocxFile({
  18. "word/document.xml": testData("simple/word/document.xml")
  19. });
  20. return docxReader.read(docxFile).then(function(result) {
  21. assert.deepEqual(expectedDocument, result.value);
  22. });
  23. });
  24. test("hyperlink hrefs are read from relationships file", function() {
  25. var docxFile = createFakeDocxFile({
  26. "word/document.xml": testData("hyperlinks/word/document.xml"),
  27. "word/_rels/document.xml.rels": testData("hyperlinks/word/_rels/document.xml.rels")
  28. });
  29. return docxReader.read(docxFile).then(function(result) {
  30. var paragraph = result.value.children[0];
  31. assert.equal(1, paragraph.children.length);
  32. var hyperlink = paragraph.children[0];
  33. assert.equal(hyperlink.href, "http://www.example.com");
  34. assert.equal(hyperlink.children.length, 1);
  35. });
  36. });
  37. var relationshipNamespaces = {
  38. "r": "http://schemas.openxmlformats.org/package/2006/relationships"
  39. };
  40. test("main document is found using _rels/.rels", function() {
  41. var relationships = xml.element("r:Relationships", {}, [
  42. xml.element("r:Relationship", {
  43. "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  44. "Target": "/word/document2.xml"
  45. })
  46. ]);
  47. var docxFile = createFakeDocxFile({
  48. "word/document2.xml": testData("simple/word/document.xml"),
  49. "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
  50. });
  51. var expectedDocument = documents.Document([
  52. documents.Paragraph([
  53. documents.Run([
  54. documents.Text("Hello.")
  55. ])
  56. ])
  57. ]);
  58. return docxReader.read(docxFile).then(function(result) {
  59. assert.deepEqual(expectedDocument, result.value);
  60. });
  61. });
  62. test("error is thrown when main document part does not exist", function() {
  63. var relationships = xml.element("r:Relationships", {}, [
  64. xml.element("r:Relationship", {
  65. "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  66. "Target": "/word/document2.xml"
  67. })
  68. ]);
  69. var docxFile = createFakeDocxFile({
  70. "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
  71. });
  72. return docxReader.read(docxFile).then(function(result) {
  73. assert.ok(false, "Expected error");
  74. }, function(error) {
  75. assert.equal(error.message, "Could not find main document part. Are you sure this is a valid .docx file?");
  76. });
  77. });
  78. test("part paths", {
  79. "main document part is found using package relationships": function() {
  80. var relationships = xml.element("r:Relationships", {}, [
  81. xml.element("r:Relationship", {
  82. "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  83. "Target": "/word/document2.xml"
  84. })
  85. ]);
  86. var docxFile = createFakeDocxFile({
  87. "word/document2.xml": " ",
  88. "_rels/.rels": xml.writeString(relationships, relationshipNamespaces)
  89. });
  90. return docxReader._findPartPaths(docxFile).then(function(partPaths) {
  91. assert.equal(partPaths.mainDocument, "word/document2.xml");
  92. });
  93. },
  94. "word/document.xml is used as fallback location for main document part": function() {
  95. var docxFile = createFakeDocxFile({
  96. "word/document.xml": " "
  97. });
  98. return docxReader._findPartPaths(docxFile).then(function(partPaths) {
  99. assert.equal(partPaths.mainDocument, "word/document.xml");
  100. });
  101. }
  102. });
  103. [
  104. {
  105. name: "comments",
  106. type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
  107. },
  108. {
  109. name: "endnotes",
  110. type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"
  111. },
  112. {
  113. name: "footnotes",
  114. type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"
  115. },
  116. {
  117. name: "numbering",
  118. type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"
  119. },
  120. {
  121. name: "styles",
  122. type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
  123. }
  124. ].forEach(function(options) {
  125. test(options.name + " part is found using main document relationships", function() {
  126. var docxFile = createFakeDocxFile({
  127. "_rels/.rels": createPackageRelationships("word/document.xml"),
  128. "word/document.xml": " ",
  129. "word/_rels/document.xml.rels": xml.writeString(xml.element("r:Relationships", {}, [
  130. xml.element("r:Relationship", {
  131. "Type": options.type,
  132. "Target": "target-path.xml"
  133. })
  134. ]), relationshipNamespaces),
  135. "word/target-path.xml": " "
  136. });
  137. return docxReader._findPartPaths(docxFile).then(function(partPaths) {
  138. assert.equal(partPaths[options.name], "word/target-path.xml");
  139. });
  140. });
  141. test("word/" + options.name + ".xml is used as fallback location for " + options.name + " part", function() {
  142. var zipContents = {
  143. "_rels/.rels": createPackageRelationships("word/document.xml"),
  144. "word/document.xml": " "
  145. };
  146. zipContents["word/" + options.name + ".xml"] = " ";
  147. var docxFile = createFakeDocxFile(zipContents);
  148. return docxReader._findPartPaths(docxFile).then(function(partPaths) {
  149. assert.equal(partPaths[options.name], "word/" + options.name + ".xml");
  150. });
  151. });
  152. });
  153. function createPackageRelationships(mainDocumentPath) {
  154. return xml.writeString(xml.element("r:Relationships", {}, [
  155. xml.element("r:Relationship", {
  156. "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  157. "Target": mainDocumentPath
  158. })
  159. ]), relationshipNamespaces);
  160. }