@@ -2410,6 +2410,100 @@ def test_builder_add_action_to_manifest_no_auto_add(self):
24102410 load_settings ('{"builder":{"actions":{"auto_opened_action":{"enabled":true}}}}' )
24112411 load_settings ('{"builder":{"actions":{"auto_created_action":{"enabled":true}}}}' )
24122412
2413+ def test_builder_add_action_to_manifest_with_auto_add (self ):
2414+ # For testing, force settings
2415+ load_settings ('{"builder":{"actions":{"auto_placed_action":{"enabled":true}}}}' )
2416+ load_settings ('{"builder":{"actions":{"auto_opened_action":{"enabled":true}}}}' )
2417+ load_settings ('{"builder":{"actions":{"auto_created_action":{"enabled":true}}}}' )
2418+
2419+ initial_manifest_definition = {
2420+ "claim_generator" : "python_test" ,
2421+ "claim_generator_info" : [{
2422+ "name" : "python_test" ,
2423+ "version" : "0.0.1" ,
2424+ }],
2425+ # claim version 2 is the default
2426+ "claim_version" : 2 ,
2427+ "format" : "image/jpeg" ,
2428+ "title" : "Python Test Image V2" ,
2429+ "ingredients" : [],
2430+ "assertions" : [
2431+ {
2432+ "label" : "c2pa.actions" ,
2433+ "data" : {
2434+ "actions" : [
2435+ {
2436+ "action" : "c2pa.created" ,
2437+ "digitalSourceType" : "http://cv.iptc.org/newscodes/digitalsourcetype/digitalCreation"
2438+ }
2439+ ]
2440+ }
2441+ }
2442+ ]
2443+ }
2444+ builder = Builder .from_json (initial_manifest_definition )
2445+
2446+ action_json = '{"action": "c2pa.color_adjustments", "parameters": {"name": "brightnesscontrast"}}'
2447+ builder .add_action (action_json )
2448+
2449+ with open (self .testPath2 , "rb" ) as file :
2450+ output = io .BytesIO (bytearray ())
2451+ builder .sign (self .signer , "image/jpeg" , file , output )
2452+ output .seek (0 )
2453+ reader = Reader ("image/jpeg" , output )
2454+ json_data = reader .json ()
2455+ manifest_data = json .loads (json_data )
2456+
2457+ # Verify active manifest exists
2458+ self .assertIn ("active_manifest" , manifest_data )
2459+ active_manifest_id = manifest_data ["active_manifest" ]
2460+
2461+ # Verify active manifest object exists
2462+ self .assertIn ("manifests" , manifest_data )
2463+ self .assertIn (active_manifest_id , manifest_data ["manifests" ])
2464+ active_manifest = manifest_data ["manifests" ][active_manifest_id ]
2465+
2466+ # Verify assertions object exists in active manifest
2467+ self .assertIn ("assertions" , active_manifest )
2468+ assertions = active_manifest ["assertions" ]
2469+
2470+ # Find the c2pa.actions.v2 assertion to check what we added
2471+ actions_assertion = None
2472+ for assertion in assertions :
2473+ if assertion .get ("label" ) == "c2pa.actions.v2" :
2474+ actions_assertion = assertion
2475+ break
2476+
2477+ self .assertIsNotNone (actions_assertion )
2478+ self .assertIn ("data" , actions_assertion )
2479+ assertion_data = actions_assertion ["data" ]
2480+ # Verify the manifest now contains actions
2481+ self .assertIn ("actions" , assertion_data )
2482+ actions = assertion_data ["actions" ]
2483+ # Verify "c2pa.color_adjustments" action exists anywhere in the actions array
2484+ created_action_found = False
2485+ for action in actions :
2486+ if action .get ("action" ) == "c2pa.color_adjustments" :
2487+ created_action_found = True
2488+ break
2489+
2490+ self .assertTrue (created_action_found )
2491+
2492+ # Verify "c2pa.created" action exists only once in the actions array
2493+ created_count = 0
2494+ for action in actions :
2495+ if action .get ("action" ) == "c2pa.created" :
2496+ created_count += 1
2497+
2498+ self .assertEqual (created_count , 1 , "c2pa.created action should appear exactly once" )
2499+
2500+ builder .close ()
2501+
2502+ # Reset settings
2503+ load_settings ('{"builder":{"actions":{"auto_placed_action":{"enabled":true}}}}' )
2504+ load_settings ('{"builder":{"actions":{"auto_opened_action":{"enabled":true}}}}' )
2505+ load_settings ('{"builder":{"actions":{"auto_created_action":{"enabled":true}}}}' )
2506+
24132507
24142508 def test_builder_minimal_manifest_add_actions_and_sign_no_auto_add (self ):
24152509 # For testing, remove auto-added actions
0 commit comments