def test_addContentType():
    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.addContentType("lol", "audio/x-laughing")
    package.close()

    stream.seek(0)
    #This time, open as .zip to just inspect the file contents.
    archive = zipfile.ZipFile(stream)
    assert "/[Content_Types].xml" in archive.namelist()
    content_types = archive.open("/[Content_Types].xml").read()
    content_types_element = ET.fromstring(content_types)

    defaults = content_types_element.findall(
        "{http://schemas.openxmlformats.org/package/2006/content-types}Default"
    )
    assert len(
        defaults
    ) == 2  #We only added one content type, but there must also be the .rels content type.
    for default in defaults:
        assert "Extension" in default.attrib
        assert "ContentType" in default.attrib
        assert default.attrib["Extension"] in ["lol", "rels"]
        if default.attrib["Extension"] == "lol":
            assert default.attrib["ContentType"] == "audio/x-laughing"
        elif default.attrib["Extension"] == "rels":
            assert default.attrib[
                "ContentType"] == "application/vnd.openxmlformats-package.relationships+xml"
def single_resource_read_opc() -> OpenPackagingConvention:
    result = OpenPackagingConvention()
    result.openStream(
        open(os.path.join(os.path.dirname(__file__), "resources", "hello.opc"),
             "rb"))
    yield result
    result.close()
def empty_read_opc() -> Generator[OpenPackagingConvention, None, None]:
    result = OpenPackagingConvention()
    result.openStream(
        open(os.path.join(os.path.dirname(__file__), "resources", "empty.opc"),
             "rb"))
    yield result
    result.close()
def test_cycleSetDataGetData(virtual_path: str):
    test_data = b"Let's see if we can read this data back."

    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.setData({virtual_path: test_data})
    package.close()

    stream.seek(0)
    package = OpenPackagingConvention()
    package.openStream(stream)
    result = package.getData(virtual_path)

    assert len(result) == 1  #This data must be the only data we've found.
    assert virtual_path in result  #The path must be in the dictionary.
    assert result[virtual_path] == test_data  #The data itself is still correct.
def test_getWriteStream_forbidOnRels(empty_write_opc: OpenPackagingConvention,
                                     virtual_path: str):
    with pytest.raises(OPCError):
        empty_write_opc.getStream(virtual_path)
def test_getWriteStream(empty_write_opc: OpenPackagingConvention,
                        virtual_path: str):
    stream = empty_write_opc.getStream(virtual_path)
    stream.write(b"The test is successful.")
def test_listPathsEmpty(empty_read_opc: OpenPackagingConvention):
    assert len(empty_read_opc.listPaths()) == 0
def empty_write_opc() -> OpenPackagingConvention:
    result = OpenPackagingConvention()
    result.openStream(io.BytesIO(), "application/x-opc", OpenMode.WriteOnly)
    yield result
    result.close()
def test_addRelation():
    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.setData({
        "/whoo.txt": b"Boo",
        "/whoo.enhanced.txt": b"BOOOO!",
        "/whoo.enforced.txt": b"BOOOOOOOOOO!"
    })  #Need 3 files: One base and two that are related.
    package.addRelation("whoo.enhanced.txt", "An enhanced version of it.",
                        "whoo.txt")
    package.addRelation("whoo.enforced.txt",
                        "A greatly enhanced version of it.", "whoo.txt")
    package.close()

    stream.seek(0)
    #This time, open as .zip to just inspect the file contents.
    archive = zipfile.ZipFile(stream)
    assert "/_rels/whoo.txt.rels" in archive.namelist(
    )  #It must create a file specifically for whoo.txt
    relations = archive.open("/_rels/whoo.txt.rels").read()
    relations_element = ET.fromstring(relations)

    both_relations = relations_element.findall(
        "{http://schemas.openxmlformats.org/package/2006/relationships}Relationship"
    )
    assert len(both_relations) == 2  #We added two relations.
    for relation in both_relations:
        assert "Id" in relation.attrib
        assert "Target" in relation.attrib
        assert "Type" in relation.attrib
        assert relation.attrib[
            "Target"] == "/whoo.enhanced.txt" or relation.attrib[
                "Target"] == "/whoo.enforced.txt"
        if relation.attrib["Target"] == "/whoo.enhanced.txt":
            assert relation.attrib["Type"] == "An enhanced version of it."
        elif relation.attrib["Target"] == "/whoo.enforced.txt":
            assert relation.attrib[
                "Type"] == "A greatly enhanced version of it."
    assert both_relations[0].attrib["Id"] != both_relations[1].attrib[
        "Id"]  #Id must be unique.
def test_toByteArrayStream():
    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.setData(
        {"/hello.txt": b"Hello world!"}
    )  #Add some arbitrary data so that the file size is not trivial regardless of what format is used.
    package.close()

    stream.seek(0)
    package = OpenPackagingConvention()
    package.openStream(stream)
    result = package.toByteArray()

    assert len(result) > 0  #There must be some data in it.
def test_cycleSetMetadataGetMetadata(virtual_path: str):
    test_data = "Hasta la vista, baby."

    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.setData({"/hello.txt": b"Hello world!"
                     })  #Add a file to attach non-global metadata to.
    package.setMetadata({virtual_path: test_data})
    package.close()

    stream.seek(0)
    package = OpenPackagingConvention()
    package.openStream(stream)
    result = package.getMetadata(virtual_path)

    prefixed_virtual_path = "/metadata{}".format(virtual_path)

    assert len(result) == 1  #Only one metadata entry was set.
    assert prefixed_virtual_path in result  #And it was the correct entry.
    assert result[prefixed_virtual_path] == test_data  #With the correct value.
def test_cycleStreamWriteRead(virtual_path: str):
    test_data = b"Softly does the river flow, flow, flow."

    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package.openStream(stream, mode=OpenMode.WriteOnly)
    resource = package.getStream(virtual_path)
    resource.write(test_data)
    package.close()

    stream.seek(0)
    package = OpenPackagingConvention()
    package.openStream(stream)
    resource = package.getStream(virtual_path)
    result = resource.read()

    assert result == test_data
def test_aliases_replacement(virtual_path: str, path_list: List[str]):
    test_data = b"Let's see if we can read this data back."

    stream = io.BytesIO()
    package = OpenPackagingConvention()
    package._aliases = OrderedDict([(r"/materials", "/files/materials")])
    package.openStream(stream, mode=OpenMode.WriteOnly)
    package.setData({virtual_path: test_data})
    package.close()

    stream.seek(0)
    package = OpenPackagingConvention()
    package.openStream(stream)
    result = package.listPaths()

    assert result == path_list