"""Test suite for docx.opc.phys_pkg module.""" import hashlib import io from zipfile import ZIP_DEFLATED, ZipFile import pytest from docx.opc.exceptions import PackageNotFoundError from docx.opc.packuri import PACKAGE_URI, PackURI from docx.opc.phys_pkg import ( PhysPkgReader, PhysPkgWriter, _DirPkgReader, _ZipPkgReader, _ZipPkgWriter, ) from ..unitutil.file import absjoin, test_file_dir from ..unitutil.mock import Mock, class_mock, loose_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: 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: def it_raises_when_pkg_path_is_not_a_package(self): with pytest.raises(PackageNotFoundError): PhysPkgReader("foobar") class DescribeZipPkgReader: 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): phys_reader = _ZipPkgReader(zip_pkg_path) yield phys_reader phys_reader.close() @pytest.fixture def pkg_file_(self, request): return loose_mock(request) class DescribeZipPkgWriter: 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 = "".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): pkg_file = io.BytesIO() yield pkg_file pkg_file.close() # 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")