Skip to content

Commit 2d46b89

Browse files
committed
fix: Add test
1 parent 8b7aaa6 commit 2d46b89

File tree

3 files changed

+95
-67
lines changed

3 files changed

+95
-67
lines changed

src/c2pa/c2pa.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,14 @@ def sign_file(
742742
# Get the MIME type from the file extension
743743
mime_type = mimetypes.guess_type(str(source_path))[0]
744744
if not mime_type:
745-
raise C2paError.NotSupported(
746-
f"Could not determine MIME type for file: {source_path}")
745+
# If the file is extensionless, we may not be able to properly guess
746+
# So we attempt one more guessing round here
747+
other_mimetype_guess = _guess_mime_type_using_magic_number(source_path)
748+
if other_mimetype_guess:
749+
mime_type, _ = other_mimetype_guess
750+
else:
751+
raise C2paError.NotSupported(
752+
f"Could not determine MIME type for file: {source_path}")
747753

748754
if return_manifest_as_bytes:
749755
# Convert Python streams to Stream objects for internal signing
@@ -2018,8 +2024,14 @@ def sign_file(self,
20182024
# Get the MIME type from the file extension
20192025
mime_type = mimetypes.guess_type(str(source_path))[0]
20202026
if not mime_type:
2021-
raise C2paError.NotSupported(
2022-
f"Could not determine MIME type for file: {source_path}")
2027+
# If the file is extensionless, we may not be able to properly guess
2028+
# So we attempt one more guessing round here
2029+
other_mimetype_guess = _guess_mime_type_using_magic_number(source_path)
2030+
if other_mimetype_guess:
2031+
mime_type, _ = other_mimetype_guess
2032+
else:
2033+
raise C2paError.NotSupported(
2034+
f"Could not determine MIME type for file: {source_path}")
20232035

20242036
# Open source and destination files
20252037
with open(source_path, 'rb') as source_file, open(dest_path, 'wb') as dest_file:

tests/fixtures/extensionless-files/svg

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
33
<svg enable-background="new 0 0 2014 1674.641" version="1.1" viewBox="0 0 2014 1674.641" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
4-
<title>This is an XMP test</title>
5-
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
6-
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 9.1-c002 165.59ab891, 2024/09/18-09:57:10 ">
7-
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
8-
<rdf:Description rdf:about=""
9-
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
10-
xmlns:dc="http://purl.org/dc/elements/1.1/"
11-
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
12-
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
13-
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#">
14-
<Iptc4xmpCore:ExtDescrAccessibility>
15-
<rdf:Alt>
16-
<rdf:li xml:lang="x-default">Headphone outline</rdf:li>
17-
</rdf:Alt>
18-
</Iptc4xmpCore:ExtDescrAccessibility>
19-
<dc:title>
20-
<rdf:Alt>
21-
<rdf:li xml:lang="x-default">This is an XMP test</rdf:li>
22-
</rdf:Alt>
23-
</dc:title>
24-
<xmp:MetadataDate>2024-12-09T09:35:43-05:00</xmp:MetadataDate>
25-
<xmpMM:InstanceID>xmp.iid:f5ec1827-855b-4f69-b690-2bed159fa942</xmpMM:InstanceID>
26-
<xmpMM:DocumentID>xmp.did:f5ec1827-855b-4f69-b690-2bed159fa942</xmpMM:DocumentID>
27-
<xmpMM:OriginalDocumentID>xmp.did:f5ec1827-855b-4f69-b690-2bed159fa942</xmpMM:OriginalDocumentID>
28-
<xmpMM:History>
29-
<rdf:Seq>
30-
<rdf:li>
31-
<rdf:Description>
32-
<stEvt:action>saved</stEvt:action>
33-
<stEvt:instanceID>xmp.iid:f5ec1827-855b-4f69-b690-2bed159fa942</stEvt:instanceID>
34-
<stEvt:when>2024-12-09T09:35:43-05:00</stEvt:when>
35-
<stEvt:softwareAgent>Adobe Bridge 2025</stEvt:softwareAgent>
36-
<stEvt:changed>/metadata</stEvt:changed>
37-
</rdf:Description>
38-
</rdf:li>
39-
</rdf:Seq>
40-
</xmpMM:History>
41-
</rdf:Description>
42-
</rdf:RDF>
43-
</x:xmpmeta>
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
65-
<?xpacket end="w"?></metadata>
66-
<path d="m44.883 1173.3c0 169.58 92.136 317.37 229.08 396.59v-793.53c-136.94 79.216-229.08 227.37-229.08 396.94z"/>
4+
<metadata></metadata>
5+
<path d="m44.883 1173.3c0 169.58 92.136 317.37 229.08 396.59v-793.53c-136.94 79.216-229.08 227.37-229.08 396.94z"/>
676
<path d="m1496.5 173.21c-338.54-181.18-640.46-181.19-978.98 0-115.34 61.726-232.1 201.31-232.1 348.66v1048h125.99v-1048c0-100.78 121.24-229.18 225.54-272.38 280.15-116.04 460-116.04 740.11 0 104.3 43.203 225.54 171.6 225.54 272.38v1048h125.99v-1048c0-147.36-116.76-286.94-232.1-348.66z"/>
687
<path d="m1740 776.38v793.53c136.94-79.214 229.08-227 229.08-396.59 1e-3 -169.57-92.133-317.73-229.08-396.94z"/>
698
<path d="m541.72 709.03h-70.645c-27.201 0-49.252 22.051-49.252 49.253v829.79c0 27.201 22.05 49.252 49.252 49.252h70.645c27.201 0 49.252-22.051 49.252-49.252v-829.79c0-27.202-22.05-49.253-49.252-49.253z"/>

tests/test_unit_tests.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,82 @@ def test_sign_file(self):
788788
# Clean up the temporary directory
789789
shutil.rmtree(temp_dir)
790790

791+
def test_sign_extensionless_jpg_file(self):
792+
"""Test signing a file using the sign_file method."""
793+
# Create a temporary directory for the test
794+
temp_dir = tempfile.mkdtemp()
795+
try:
796+
# Use the extensionless jpg from the test files
797+
extensionless_dir = os.path.join(FIXTURES_DIR, "extensionless-files")
798+
source_path = os.path.join(extensionless_dir, "jpg")
799+
800+
output_path = os.path.join(temp_dir, "signed_output.jpg")
801+
802+
# Use the sign_file method
803+
builder = Builder(self.manifestDefinition)
804+
result, manifest_bytes = builder.sign_file(
805+
source_path=source_path,
806+
dest_path=output_path,
807+
signer=self.signer
808+
)
809+
810+
# Verify the output file was created
811+
self.assertTrue(os.path.exists(output_path))
812+
813+
# Verify we got both result and manifest bytes
814+
self.assertIsInstance(result, int)
815+
self.assertIsInstance(manifest_bytes, bytes)
816+
self.assertGreater(len(manifest_bytes), 0)
817+
818+
# Read the signed file and verify the manifest
819+
with open(output_path, "rb") as file:
820+
reader = Reader("image/jpeg", file)
821+
json_data = reader.json()
822+
self.assertIn("Python Test", json_data)
823+
self.assertNotIn("validation_status", json_data)
824+
825+
finally:
826+
# Clean up the temporary directory
827+
shutil.rmtree(temp_dir)
828+
829+
def test_sign_extensionless_svg_file(self):
830+
"""Test signing an extensionless SVG file using the sign_file method."""
831+
# Create a temporary directory for the test
832+
temp_dir = tempfile.mkdtemp()
833+
try:
834+
# Use the extensionless svg from the test files
835+
extensionless_dir = os.path.join(FIXTURES_DIR, "extensionless-files")
836+
source_path = os.path.join(extensionless_dir, "svg")
837+
838+
output_path = os.path.join(temp_dir, "signed_output.svg")
839+
840+
# Use the sign_file method
841+
builder = Builder(self.manifestDefinition)
842+
result, manifest_bytes = builder.sign_file(
843+
source_path=source_path,
844+
dest_path=output_path,
845+
signer=self.signer
846+
)
847+
848+
# Verify the output file was created
849+
self.assertTrue(os.path.exists(output_path))
850+
851+
# Verify we got both result and manifest bytes
852+
self.assertIsInstance(result, int)
853+
self.assertIsInstance(manifest_bytes, bytes)
854+
self.assertGreater(len(manifest_bytes), 0)
855+
856+
# Read the signed file and verify the manifest
857+
with open(output_path, "rb") as file:
858+
reader = Reader("image/svg+xml", file)
859+
json_data = reader.json()
860+
self.assertIn("Python Test", json_data)
861+
self.assertNotIn("validation_status", json_data)
862+
863+
finally:
864+
# Clean up the temporary directory
865+
shutil.rmtree(temp_dir)
866+
791867
def test_sign_file_callback_signer(self):
792868
"""Test signing a file using the sign_file method."""
793869

@@ -1201,6 +1277,7 @@ def error_callback_signer(data: bytes) -> bytes:
12011277
finally:
12021278
shutil.rmtree(temp_dir)
12031279

1280+
12041281
class TestStream(unittest.TestCase):
12051282
def setUp(self):
12061283
# Create a temporary file for testing

0 commit comments

Comments
 (0)