import json import time from promptledger_verifiable_provenance_and_l.core import LocalProvenanceBlock, MerkleAuditLog, DeltaSync from promptledger_verifiable_provenance_and_l import attach_signature from promptledger_verifiable_provenance_and_l.adapters import BlenderAdapter, FigmaAdapter def test_local_provenance_block_hash_and_signature(): b = LocalProvenanceBlock( author="alice", tool="Blender", action="create_asset", data={"asset_type": "mesh"}, license="MIT", ) # hash should be deterministic for the same content h1 = b.hash() h2 = b.hash() assert h1 == h2 attach_signature(b) assert isinstance(b.signature, str) and len(b.signature) > 0 assert b.verify_signature("alice:Blender") def test_merkle_audit_log_root_updates_with_blocks(): log = MerkleAuditLog() b1 = LocalProvenanceBlock("alice", "Blender", "create_asset", {"asset_type": "mesh"}, "MIT") attach_signature(b1) log.append(b1) root1 = log.get_root() b2 = LocalProvenanceBlock("bob", "Figma", "update_design", {"frame": "Intro"}, "MIT") attach_signature(b2) log.append(b2) root2 = log.get_root() assert root1 != "" assert root2 != "" assert root1 != root2 def test_delta_sync_between_logs(): old_log = MerkleAuditLog() b1 = LocalProvenanceBlock("alice", "Blender", "create_asset", {"asset_type": "mesh"}, "MIT") attach_signature(b1) old_log.append(b1) new_log = MerkleAuditLog() # copy old block into new log new_log.append(b1) # add a new block in new_log b2 = LocalProvenanceBlock("bob", "Figma", "update_design", {"frame": "Intro"}, "MIT") attach_signature(b2) new_log.append(b2) ds = DeltaSync(old_log) delta = ds.create_delta(new_log) recipient_log = MerkleAuditLog() recipient_sync = DeltaSync(recipient_log) recipient_sync.apply_delta(delta) assert recipient_log.get_root() == new_log.get_root() def test_adapters_emit_blocks(): bl = BlenderAdapter() fga = FigmaAdapter() b_block = bl.emit_block("b-blob", "transform") f_block = fga.emit_block("f-blob", "design") assert b_block.tool == "Blender" assert f_block.tool == "Figma" assert b_block.id == "b-blob" assert f_block.id == "f-blob"