3333PROJECT_PATH = os .getcwd ()
3434FIXTURES_DIR = os .path .join (os .path .dirname (__file__ ), "fixtures" )
3535DEFAULT_TEST_FILE_NAME = "C.jpg"
36+ INGREDIENT_TEST_FILE_NAME = "A.jpg"
3637DEFAULT_TEST_FILE = os .path .join (FIXTURES_DIR , DEFAULT_TEST_FILE_NAME )
37- INGREDIENT_TEST_FILE = os .path .join (FIXTURES_DIR , "A.jpg" )
38+ INGREDIENT_TEST_FILE = os .path .join (FIXTURES_DIR , INGREDIENT_TEST_FILE_NAME )
3839ALTERNATIVE_INGREDIENT_TEST_FILE = os .path .join (FIXTURES_DIR , "cloud.jpg" )
3940
4041class TestC2paSdk (unittest .TestCase ):
@@ -816,7 +817,53 @@ def test_builder_sign_with_ingredient(self):
816817 assert builder ._builder is not None
817818
818819 # Test adding ingredient
819- ingredient_json = '{"title": "Test Ingredient"}'
820+ ingredient_json = '{ "title": "Test Ingredient" }'
821+ with open (self .testPath3 , 'rb' ) as f :
822+ builder .add_ingredient (ingredient_json , "image/jpeg" , f )
823+
824+ with open (self .testPath2 , "rb" ) as file :
825+ output = io .BytesIO (bytearray ())
826+ builder .sign (self .signer , "image/jpeg" , file , output )
827+ output .seek (0 )
828+ reader = Reader ("image/jpeg" , output )
829+ json_data = reader .json ()
830+ manifest_data = json .loads (json_data )
831+
832+ # Verify active manifest exists
833+ self .assertIn ("active_manifest" , manifest_data )
834+ active_manifest_id = manifest_data ["active_manifest" ]
835+
836+ # Verify active manifest object exists
837+ self .assertIn ("manifests" , manifest_data )
838+ self .assertIn (active_manifest_id , manifest_data ["manifests" ])
839+ active_manifest = manifest_data ["manifests" ][active_manifest_id ]
840+
841+ # Verify thumbnail for manifest is here
842+ self .assertIn ("thumbnail" , active_manifest )
843+ thumbnail_data = active_manifest ["thumbnail" ]
844+ self .assertIn ("format" , thumbnail_data )
845+ self .assertIn ("identifier" , thumbnail_data )
846+
847+ # Verify ingredients array exists in active manifest
848+ self .assertIn ("ingredients" , active_manifest )
849+ self .assertIsInstance (active_manifest ["ingredients" ], list )
850+ self .assertTrue (len (active_manifest ["ingredients" ]) > 0 )
851+
852+ # Verify the first ingredient's title matches what we set
853+ first_ingredient = active_manifest ["ingredients" ][0 ]
854+ self .assertEqual (first_ingredient ["title" ], "Test Ingredient" )
855+
856+ builder .close ()
857+
858+ def test_builder_sign_with_setting_no_thumbnail_and_ingredient (self ):
859+ builder = Builder .from_json (self .manifestDefinition )
860+ assert builder ._builder is not None
861+
862+ # The following removes the manifest's thumbnail
863+ load_settings ('{"builder": { "thumbnail": {"enabled": false}}}' )
864+
865+ # Test adding ingredient
866+ ingredient_json = '{ "title": "Test Ingredient" }'
820867 with open (self .testPath3 , 'rb' ) as f :
821868 builder .add_ingredient (ingredient_json , "image/jpeg" , f )
822869
@@ -826,6 +873,7 @@ def test_builder_sign_with_ingredient(self):
826873 output .seek (0 )
827874 reader = Reader ("image/jpeg" , output )
828875 json_data = reader .json ()
876+ #print(json_data)
829877 manifest_data = json .loads (json_data )
830878
831879 # Verify active manifest exists
@@ -837,6 +885,9 @@ def test_builder_sign_with_ingredient(self):
837885 self .assertIn (active_manifest_id , manifest_data ["manifests" ])
838886 active_manifest = manifest_data ["manifests" ][active_manifest_id ]
839887
888+ # There should be no thumbnail anymore here
889+ self .assertNotIn ("thumbnail" , active_manifest )
890+
840891 # Verify ingredients array exists in active manifest
841892 self .assertIn ("ingredients" , active_manifest )
842893 self .assertIsInstance (active_manifest ["ingredients" ], list )
@@ -848,6 +899,9 @@ def test_builder_sign_with_ingredient(self):
848899
849900 builder .close ()
850901
902+ # Settings are global, so we reset to the default "true" here
903+ load_settings ('{"builder": { "thumbnail": {"enabled": true}}}' )
904+
851905 def test_builder_sign_with_duplicate_ingredient (self ):
852906 builder = Builder .from_json (self .manifestDefinition )
853907 assert builder ._builder is not None
@@ -1635,6 +1689,59 @@ def test_read_ingredient_file(self):
16351689 self .assertEqual (ingredient_data ["format" ], "image/jpeg" )
16361690 self .assertIn ("thumbnail" , ingredient_data )
16371691
1692+ def test_read_ingredient_file_who_has_no_manifest (self ):
1693+ """Test reading a C2PA ingredient from a file."""
1694+ # Test reading ingredient from file with data_dir
1695+ temp_data_dir = os .path .join (self .data_dir , "temp_data" )
1696+ os .makedirs (temp_data_dir , exist_ok = True )
1697+
1698+ load_settings ('{"builder": { "thumbnail": {"enabled": false}}}' )
1699+
1700+ ingredient_json_with_dir = read_ingredient_file (self .testPath2 , temp_data_dir )
1701+
1702+ # Verify some fields
1703+ ingredient_data = json .loads (ingredient_json_with_dir )
1704+ self .assertEqual (ingredient_data ["title" ], INGREDIENT_TEST_FILE_NAME )
1705+ self .assertEqual (ingredient_data ["format" ], "image/jpeg" )
1706+ self .assertIn ("thumbnail" , ingredient_data )
1707+
1708+ def test_compare_read_ingredient_file_with_builder_added_ingredient (self ):
1709+ """Test reading a C2PA ingredient from a file."""
1710+ # Test reading ingredient from file with data_dir
1711+ temp_data_dir = os .path .join (self .data_dir , "temp_data" )
1712+ os .makedirs (temp_data_dir , exist_ok = True )
1713+
1714+ ingredient_json_with_dir = read_ingredient_file (self .testPath2 , temp_data_dir )
1715+
1716+ # Ingredient fields from read_ingredient_file
1717+ ingredient_data = json .loads (ingredient_json_with_dir )
1718+
1719+ # Compare with ingredient added by Builder
1720+ builder = Builder .from_json (self .manifestDefinition )
1721+ # Only the title is needed (filename), since title not extracted or guessed from filename
1722+ ingredient_json = '{ "title" : "A.jpg" }'
1723+ with open (self .testPath2 , 'rb' ) as f :
1724+ builder .add_ingredient (ingredient_json , "image/jpeg" , f )
1725+
1726+ with open (self .testPath2 , "rb" ) as file :
1727+ output = io .BytesIO (bytearray ())
1728+ builder .sign (self .signer , "image/jpeg" , file , output )
1729+ output .seek (0 )
1730+
1731+ # Get ingredient fields from signed manifest
1732+ reader = Reader ("image/jpeg" , output )
1733+ json_data = reader .json ()
1734+ manifest_data = json .loads (json_data )
1735+ active_manifest_id = manifest_data ["active_manifest" ]
1736+ active_manifest = manifest_data ["manifests" ][active_manifest_id ]
1737+ only_ingredient = active_manifest ["ingredients" ][0 ]
1738+
1739+ self .assertEqual (ingredient_data ["title" ], only_ingredient ["title" ])
1740+ self .assertEqual (ingredient_data ["format" ], only_ingredient ["format" ])
1741+ self .assertEqual (ingredient_data ["document_id" ], only_ingredient ["document_id" ])
1742+ self .assertEqual (ingredient_data ["instance_id" ], only_ingredient ["instance_id" ])
1743+ self .assertEqual (ingredient_data ["relationship" ], only_ingredient ["relationship" ])
1744+
16381745 def test_read_file (self ):
16391746 """Test reading a C2PA ingredient from a file."""
16401747 temp_data_dir = os .path .join (self .data_dir , "temp_data" )
0 commit comments