aboutsummaryrefslogtreecommitdiff
path: root/tests/docx/docx_tests.py
blob: a474b17be06322865c9b40464e7e75c502e3f9c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import io
import textwrap
import zipfile

from nose.tools import istest, assert_equal

from mammoth import docx, documents, zips
from ..testing import assert_raises, test_path


@istest
class ReadTests(object):
    @istest
    def can_read_document_with_single_paragraph_with_single_run_of_text(self):
        with open(test_path("single-paragraph.docx"), "rb") as fileobj:
            result = docx.read(fileobj=fileobj)
            expected_document = documents.document([
                documents.paragraph([
                    documents.run([
                        documents.text("Walking on imported air")
                    ])
                ])
            ])
            assert_equal(expected_document, result.value)


_relationship_namespaces = {
    "r": "http://schemas.openxmlformats.org/package/2006/relationships",
}


@istest
def main_document_is_found_using_package_relationships():
    fileobj = _create_zip({
        "word/document2.xml": textwrap.dedent("""\
            <?xml version="1.0" encoding="utf-8" ?>
            <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
                <w:body>
                    <w:p>
                        <w:r>
                            <w:t>Hello.</w:t>
                        </w:r>
                    </w:p>
                </w:body>
            </w:document>
        """),
        "_rels/.rels": textwrap.dedent("""\
            <?xml version="1.0" encoding="utf-8"?>
            <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
                <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/word/document2.xml" Id="rId1"/>
            </Relationships>
        """),
    })
    result = docx.read(fileobj=fileobj)
    expected_document = documents.document([
        documents.paragraph([
            documents.run([
                documents.text("Hello.")
            ])
        ])
    ])
    assert_equal(expected_document, result.value)


@istest
def error_is_raised_when_main_document_part_does_not_exist():
    fileobj = _create_zip({
        "_rels/.rels": textwrap.dedent("""\
            <?xml version="1.0" encoding="utf-8"?>
            <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
                <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/word/document2.xml" Id="rId1"/>
            </Relationships>
        """),
    })
    error = assert_raises(IOError, lambda: docx.read(fileobj=fileobj))
    assert_equal(
        "Could not find main document part. Are you sure this is a valid .docx file?",
        str(error),
    )

class TestPartPaths(object):
    @istest
    def main_document_part_is_found_using_package_relationships(self):
        fileobj = _create_zip({
            "word/document2.xml": " ",
            "_rels/.rels": textwrap.dedent("""\
                <?xml version="1.0" encoding="utf-8"?>
                <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
                    <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/word/document2.xml" Id="rId1"/>
                </Relationships>
            """),
        })
        part_paths = self._find_part_paths(fileobj)
        assert_equal("word/document2.xml", part_paths.main_document)
        
    @istest
    def when_relationship_for_main_document_cannot_be_found_then_fallback_is_used(self):
        fileobj = _create_zip({
            "word/document.xml": " ",
        })
        part_paths = self._find_part_paths(fileobj)
        assert_equal("word/document.xml", part_paths.main_document)
    
    def _find_part_paths(self, fileobj):
        return docx._find_part_paths(zips.open_zip(fileobj, "r"))


def _create_zip(files):
    fileobj = io.BytesIO()
    
    zip_file = zipfile.ZipFile(fileobj, "w")
    try:
        for name, contents in files.items():
            zip_file.writestr(name, contents)
    finally:
        zip_file.close()
    
    fileobj.seek(0)
    return fileobj