File: test_phys_pkg.py

package info (click to toggle)
python-docx 0.8.11%2Bdfsg1-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 6,640 kB
  • sloc: xml: 25,311; python: 21,911; makefile: 168
file content (195 lines) | stat: -rw-r--r-- 6,560 bytes parent folder | download
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# encoding: utf-8

"""
Test suite for docx.opc.phys_pkg module
"""

from __future__ import absolute_import

try:
    from io import BytesIO  # Python 3
except ImportError:
    from StringIO import StringIO as BytesIO

import hashlib
import pytest

from zipfile import ZIP_DEFLATED, ZipFile

from docx.opc.exceptions import PackageNotFoundError
from docx.opc.packuri import PACKAGE_URI, PackURI
from docx.opc.phys_pkg import (
    _DirPkgReader, PhysPkgReader, PhysPkgWriter, _ZipPkgReader, _ZipPkgWriter
)

from ..unitutil.file import absjoin, test_file_dir
from ..unitutil.mock import class_mock, loose_mock, Mock


test_docx_path = absjoin(test_file_dir, 'test.docx')
dir_pkg_path = absjoin(test_file_dir, 'expanded_docx')
zip_pkg_path = test_docx_path


class DescribeDirPkgReader(object):

    def it_is_used_by_PhysPkgReader_when_pkg_is_a_dir(self):
        phys_reader = PhysPkgReader(dir_pkg_path)
        assert isinstance(phys_reader, _DirPkgReader)

    def it_doesnt_mind_being_closed_even_though_it_doesnt_need_it(
            self, dir_reader):
        dir_reader.close()

    def it_can_retrieve_the_blob_for_a_pack_uri(self, dir_reader):
        pack_uri = PackURI('/word/document.xml')
        blob = dir_reader.blob_for(pack_uri)
        sha1 = hashlib.sha1(blob).hexdigest()
        assert sha1 == '0e62d87ea74ea2b8088fd11ee97b42da9b4c77b0'

    def it_can_get_the_content_types_xml(self, dir_reader):
        sha1 = hashlib.sha1(dir_reader.content_types_xml).hexdigest()
        assert sha1 == '89aadbb12882dd3d7340cd47382dc2c73d75dd81'

    def it_can_retrieve_the_rels_xml_for_a_source_uri(self, dir_reader):
        rels_xml = dir_reader.rels_xml_for(PACKAGE_URI)
        sha1 = hashlib.sha1(rels_xml).hexdigest()
        assert sha1 == 'ebacdddb3e7843fdd54c2f00bc831551b26ac823'

    def it_returns_none_when_part_has_no_rels_xml(self, dir_reader):
        partname = PackURI('/ppt/viewProps.xml')
        rels_xml = dir_reader.rels_xml_for(partname)
        assert rels_xml is None

    # fixtures ---------------------------------------------

    @pytest.fixture
    def pkg_file_(self, request):
        return loose_mock(request)

    @pytest.fixture(scope='class')
    def dir_reader(self):
        return _DirPkgReader(dir_pkg_path)


class DescribePhysPkgReader(object):

    def it_raises_when_pkg_path_is_not_a_package(self):
        with pytest.raises(PackageNotFoundError):
            PhysPkgReader('foobar')


class DescribeZipPkgReader(object):

    def it_is_used_by_PhysPkgReader_when_pkg_is_a_zip(self):
        phys_reader = PhysPkgReader(zip_pkg_path)
        assert isinstance(phys_reader, _ZipPkgReader)

    def it_is_used_by_PhysPkgReader_when_pkg_is_a_stream(self):
        with open(zip_pkg_path, 'rb') as stream:
            phys_reader = PhysPkgReader(stream)
        assert isinstance(phys_reader, _ZipPkgReader)

    def it_opens_pkg_file_zip_on_construction(self, ZipFile_, pkg_file_):
        _ZipPkgReader(pkg_file_)
        ZipFile_.assert_called_once_with(pkg_file_, 'r')

    def it_can_be_closed(self, ZipFile_):
        # mockery ----------------------
        zipf = ZipFile_.return_value
        zip_pkg_reader = _ZipPkgReader(None)
        # exercise ---------------------
        zip_pkg_reader.close()
        # verify -----------------------
        zipf.close.assert_called_once_with()

    def it_can_retrieve_the_blob_for_a_pack_uri(self, phys_reader):
        pack_uri = PackURI('/word/document.xml')
        blob = phys_reader.blob_for(pack_uri)
        sha1 = hashlib.sha1(blob).hexdigest()
        assert sha1 == 'b9b4a98bcac7c5a162825b60c3db7df11e02ac5f'

    def it_has_the_content_types_xml(self, phys_reader):
        sha1 = hashlib.sha1(phys_reader.content_types_xml).hexdigest()
        assert sha1 == 'cd687f67fd6b5f526eedac77cf1deb21968d7245'

    def it_can_retrieve_rels_xml_for_source_uri(self, phys_reader):
        rels_xml = phys_reader.rels_xml_for(PACKAGE_URI)
        sha1 = hashlib.sha1(rels_xml).hexdigest()
        assert sha1 == '90965123ed2c79af07a6963e7cfb50a6e2638565'

    def it_returns_none_when_part_has_no_rels_xml(self, phys_reader):
        partname = PackURI('/ppt/viewProps.xml')
        rels_xml = phys_reader.rels_xml_for(partname)
        assert rels_xml is None

    # fixtures ---------------------------------------------

    @pytest.fixture(scope='class')
    def phys_reader(self, request):
        phys_reader = _ZipPkgReader(zip_pkg_path)
        request.addfinalizer(phys_reader.close)
        return phys_reader

    @pytest.fixture
    def pkg_file_(self, request):
        return loose_mock(request)


class DescribeZipPkgWriter(object):

    def it_is_used_by_PhysPkgWriter_unconditionally(self, tmp_docx_path):
        phys_writer = PhysPkgWriter(tmp_docx_path)
        assert isinstance(phys_writer, _ZipPkgWriter)

    def it_opens_pkg_file_zip_on_construction(self, ZipFile_):
        pkg_file = Mock(name='pkg_file')
        _ZipPkgWriter(pkg_file)
        ZipFile_.assert_called_once_with(
            pkg_file, 'w', compression=ZIP_DEFLATED
        )

    def it_can_be_closed(self, ZipFile_):
        # mockery ----------------------
        zipf = ZipFile_.return_value
        zip_pkg_writer = _ZipPkgWriter(None)
        # exercise ---------------------
        zip_pkg_writer.close()
        # verify -----------------------
        zipf.close.assert_called_once_with()

    def it_can_write_a_blob(self, pkg_file):
        # setup ------------------------
        pack_uri = PackURI('/part/name.xml')
        blob = '<BlobbityFooBlob/>'.encode('utf-8')
        # exercise ---------------------
        pkg_writer = PhysPkgWriter(pkg_file)
        pkg_writer.write(pack_uri, blob)
        pkg_writer.close()
        # verify -----------------------
        written_blob_sha1 = hashlib.sha1(blob).hexdigest()
        zipf = ZipFile(pkg_file, 'r')
        retrieved_blob = zipf.read(pack_uri.membername)
        zipf.close()
        retrieved_blob_sha1 = hashlib.sha1(retrieved_blob).hexdigest()
        assert retrieved_blob_sha1 == written_blob_sha1

    # fixtures ---------------------------------------------

    @pytest.fixture
    def pkg_file(self, request):
        pkg_file = BytesIO()
        request.addfinalizer(pkg_file.close)
        return pkg_file


# fixtures -------------------------------------------------

@pytest.fixture
def tmp_docx_path(tmpdir):
    return str(tmpdir.join('test_python-docx.docx'))


@pytest.fixture
def ZipFile_(request):
    return class_mock(request, 'docx.opc.phys_pkg.ZipFile')