import pytest from flexoentity import FlexOID, FlexoEntity, EntityState def test_initial_state(sample_domain): assert sample_domain.state == EntityState.DRAFT assert sample_domain.flexo_id.version == 1 assert FlexoEntity.verify_integrity(sample_domain) def test_approval_does_not_bump_version(sample_domain): q = sample_domain q.approve() assert q.state == EntityState.APPROVED assert q.flexo_id.version == 1 def test_signing_does_not_bump_version(sample_domain): q = sample_domain q.approve() before = q.flexo_id q.sign() after = q.flexo_id # state changed assert q.state == EntityState.APPROVED_AND_SIGNED # version unchanged assert before.version == after.version # only suffix letter differs assert before.prefix == after.prefix assert before.state_code == "A" assert after.state_code == "S" def test_publish_does_not_bump_version(sample_domain): q = sample_domain q.approve() q.sign() v_before = q.flexo_id.version q.publish() assert q.state == EntityState.PUBLISHED assert q.flexo_id.version == v_before def test_modify_content_changes_fingerprint(sample_signature): sample_signature.comment += "Rephrased content" # simulate text change changed = sample_signature._update_fingerprint() assert changed def test_no_version_bump_on_draft_edits(sample_signature): sample_signature.comment = "Minor draft edit" sample_signature._update_fingerprint() assert sample_signature.flexo_id.version == 1 def test_version_bump_after_edit_and_sign(sample_signature): sample_signature.approve() v1 = str(sample_signature.flexo_id) sample_signature.comment = "Changed comment" sample_signature.sign() assert str(sample_signature.flexo_id) != v1 def test_integrity_check_passes_and_fails(sample_signature): sample_signature.approve() assert FlexoEntity.verify_integrity(sample_signature) # simulate tampering sample_signature.comment = "Tampered text" assert not FlexoEntity.verify_integrity(sample_signature) def test_obsolete_state(sample_domain): q = sample_domain q.approve() q.sign() q.publish() q.obsolete() assert q.state == EntityState.OBSOLETE def test_clone_new_base_resets_lineage(sample_domain): q = sample_domain q.approve() q.sign() q.publish() q.obsolete() old_id = str(q.flexo_id) q.clone_new_base() assert str(q.flexo_id) != old_id assert q.state == EntityState.DRAFT assert q.flexo_id.version == 1 def test_clone_new_base_sets_origin(sample_domain): q = sample_domain q.approve() q.sign() q.publish() q.obsolete() old_id = str(q.flexo_id) q.clone_new_base() assert q.origin == old_id assert q.state == EntityState.DRAFT assert q.flexo_id.version == 1 assert q.flexo_id != old_id def test_mass_version_increments_until_obsolete(sample_domain): q = sample_domain q.approve() for _ in range(FlexOID.MAX_VERSION - 1): q.bump_version() # Next one must raise with pytest.raises(RuntimeError, match="mark obsolete"): q.bump_version()