@@ -733,6 +733,7 @@ def setUp(self):
733733 "actions" : [
734734 {
735735 "action" : "c2pa.opened"
736+ # Should have more parameters here, but omitted in tests
736737 }
737738 ]
738739 }
@@ -2323,6 +2324,78 @@ def test_builder_state_with_invalid_native_pointer(self):
23232324 with self .assertRaises (Error ):
23242325 builder .set_no_embed ()
23252326
2327+ def test_builder_minimal_manifest_add_actions_and_sign (self ):
2328+ # For testing, remove auto-added actions
2329+ load_settings ('{"builder":{"actions":{"auto_placed_action":{"enabled": false}}}}' )
2330+ load_settings ('{"builder":{"actions":{"auto_opened_action":{"enabled": false}}}}' )
2331+ load_settings ('{"builder":{"actions":{"auto_created_action":{"enabled": false}}}}' )
2332+
2333+ initial_manifest_definition = {
2334+ "claim_generator" : "python_test" ,
2335+ "claim_generator_info" : [{
2336+ "name" : "python_test" ,
2337+ "version" : "0.0.1" ,
2338+ }],
2339+ "format" : "image/jpeg" ,
2340+ "title" : "Python Test Image V2" ,
2341+ }
2342+ builder = Builder .from_json (self .manifestDefinition )
2343+
2344+ builder .add_action ('{ "action": "c2pa.created", "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/digitalCreation"}' )
2345+
2346+ with open (self .testPath2 , "rb" ) as file :
2347+ output = io .BytesIO (bytearray ())
2348+ builder .sign (self .signer , "image/jpeg" , file , output )
2349+ output .seek (0 )
2350+ reader = Reader ("image/jpeg" , output )
2351+ json_data = reader .json ()
2352+ print (json_data )
2353+ manifest_data = json .loads (json_data )
2354+
2355+ # Verify active manifest exists
2356+ self .assertIn ("active_manifest" , manifest_data )
2357+ active_manifest_id = manifest_data ["active_manifest" ]
2358+
2359+ # Verify active manifest object exists
2360+ self .assertIn ("manifests" , manifest_data )
2361+ self .assertIn (active_manifest_id , manifest_data ["manifests" ])
2362+ active_manifest = manifest_data ["manifests" ][active_manifest_id ]
2363+
2364+ # Verify assertions object exists in active manifest
2365+ self .assertIn ("assertions" , active_manifest )
2366+ assertions = active_manifest ["assertions" ]
2367+
2368+ # Find the c2pa.actions.v2 assertion
2369+ actions_assertion = None
2370+ for assertion in assertions :
2371+ if assertion .get ("label" ) == "c2pa.actions.v2" :
2372+ actions_assertion = assertion
2373+ break
2374+
2375+ self .assertIsNotNone (actions_assertion )
2376+
2377+ # Check what we added is there
2378+ self .assertIn ("data" , actions_assertion )
2379+ assertion_data = actions_assertion ["data" ]
2380+ # Verify the manifest now contains actions
2381+ self .assertIn ("actions" , assertion_data )
2382+ actions = assertion_data ["actions" ]
2383+ # Verify "c2pa.created" action exists anywhere in the actions array
2384+ created_action_found = False
2385+ for action in actions :
2386+ if action .get ("action" ) == "c2pa.created" :
2387+ created_action_found = True
2388+ break
2389+
2390+ self .assertTrue (created_action_found )
2391+
2392+ builder .close ()
2393+
2394+ # Reset settings
2395+ load_settings ('{"builder":{"actions":{"auto_placed_action":{"enabled": true}}}}' )
2396+ load_settings ('{"builder":{"actions":{"auto_opened_action":{"enabled": true}}}}' )
2397+ load_settings ('{"builder":{"actions":{"auto_created_action":{"enabled": true}}}}' )
2398+
23262399
23272400class TestStream (unittest .TestCase ):
23282401 def setUp (self ):
0 commit comments