source: flexoentity/tests/test_id_lifecycle.py@ a039f4a

main unify_backends
Last change on this file since a039f4a was a17e4f6, checked in by Enrico Schwass <ennoausberlin@…>, 7 weeks ago

add fork method to FlexoEntity to simplify copy / paste operations

  • Property mode set to 100644
File size: 4.9 KB
RevLine 
[59342ce]1import pytest
[8aa20c7]2from flexoentity import FlexOID, FlexoEntity, EntityState
[59342ce]3
4
[ef964d8]5def test_initial_state(sample_domain):
6 assert sample_domain.state == EntityState.DRAFT
7 assert sample_domain.flexo_id.version == 1
8 assert FlexoEntity.verify_integrity(sample_domain)
[59342ce]9
[ef964d8]10def test_approval_does_not_bump_version(sample_domain):
11 q = sample_domain
[02d288d]12 q.approve()
13 assert q.state == EntityState.APPROVED
[8aa20c7]14 assert q.flexo_id.version == 1
[59342ce]15
[ef964d8]16def test_signing_does_not_bump_version(sample_domain):
17 q = sample_domain
[02d288d]18 q.approve()
[5c72356]19 before = q.flexo_id
[02d288d]20 q.sign()
[5c72356]21 after = q.flexo_id
22
23 # state changed
[02d288d]24 assert q.state == EntityState.APPROVED_AND_SIGNED
[59342ce]25
[5c72356]26 # version unchanged
27 assert before.version == after.version
28
29 # only suffix letter differs
30 assert before.prefix == after.prefix
31 assert before.state_code == "A"
32 assert after.state_code == "S"
[59342ce]33
[5c72356]34
[ef964d8]35def test_publish_does_not_bump_version(sample_domain):
36 q = sample_domain
[02d288d]37 q.approve()
38 q.sign()
39 v_before = q.flexo_id.version
40 q.publish()
41 assert q.state == EntityState.PUBLISHED
[5c72356]42 assert q.flexo_id.version == v_before
[59342ce]43
44
[ef964d8]45def test_modify_content_changes_fingerprint(sample_signature):
46 sample_signature.comment += "Rephrased content" # simulate text change
47 changed = sample_signature._update_fingerprint()
[02d288d]48 assert changed
[59342ce]49
50
[ef964d8]51def test_no_version_bump_on_draft_edits(sample_signature):
52 sample_signature.comment = "Minor draft edit"
53 sample_signature._update_fingerprint()
54 assert sample_signature.flexo_id.version == 1
[59342ce]55
56
[ef964d8]57def test_version_bump_after_edit_and_sign(sample_signature):
58 sample_signature.approve()
59 v1 = str(sample_signature.flexo_id)
60 sample_signature.comment = "Changed comment"
61 sample_signature.sign()
62 assert str(sample_signature.flexo_id) != v1
[59342ce]63
64
[ef964d8]65def test_integrity_check_passes_and_fails(sample_signature):
66 sample_signature.approve()
67 assert FlexoEntity.verify_integrity(sample_signature)
[59342ce]68
[02d288d]69 # simulate tampering
[ef964d8]70 sample_signature.comment = "Tampered text"
71 assert not FlexoEntity.verify_integrity(sample_signature)
[02d288d]72
73
[ef964d8]74def test_obsolete_state(sample_domain):
75 q = sample_domain
[02d288d]76 q.approve()
77 q.sign()
78 q.publish()
79 q.obsolete()
80 assert q.state == EntityState.OBSOLETE
81
82
[ef964d8]83def test_clone_new_base_resets_lineage(sample_domain):
84 q = sample_domain
[02d288d]85 q.approve()
86 q.sign()
87 q.publish()
88 q.obsolete()
89 old_id = str(q.flexo_id)
90 q.clone_new_base()
91 assert str(q.flexo_id) != old_id
92 assert q.state == EntityState.DRAFT
93 assert q.flexo_id.version == 1
94
[ef964d8]95def test_clone_new_base_sets_origin(sample_domain):
96 q = sample_domain
[4ceca57]97 q.approve()
98 q.sign()
99 q.publish()
100 q.obsolete()
[ca39274]101 old_id = str(q.flexo_id)
[4ceca57]102 q.clone_new_base()
103 assert q.origin == old_id
104 assert q.state == EntityState.DRAFT
105 assert q.flexo_id.version == 1
106 assert q.flexo_id != old_id
[02d288d]107
[ef964d8]108def test_mass_version_increments_until_obsolete(sample_domain):
109 q = sample_domain
[02d288d]110 q.approve()
[8aa20c7]111 for _ in range(FlexOID.MAX_VERSION - 1):
[e198832]112 q.bump_version()
[5c72356]113
114 # Next one must raise
[59342ce]115 with pytest.raises(RuntimeError, match="mark obsolete"):
[5c72356]116 q.bump_version()
[a17e4f6]117
118def test_fork_creates_independent_domain(sample_domain):
119 original = sample_domain
120
121 forked = original.fork(domain_id="DST")
122
123 # ─── identity ───────────────────────────────────────────────────────
124 assert forked is not original
125 assert isinstance(forked.flexo_id, FlexOID)
126 assert forked.flexo_id != original.flexo_id
127
128 # ─── lifecycle reset ────────────────────────────────────────────────
129 assert forked.state == EntityState.DRAFT
130 assert forked.version == 1
131
132 # ─── provenance ─────────────────────────────────────────────────────
133 assert forked.origin == str(original.flexo_id)
134
135 # ─── domain reassigned ──────────────────────────────────────────────
136 assert forked.domain_id == "DST"
137
138def test_fork_does_not_mutate_original(sample_domain):
139 original = sample_domain
140 original_id = original.flexo_id
141 original_fp = original.fingerprint
142
143 _ = original.fork(domain_id="DST")
144
145 assert original.flexo_id == original_id
146 assert original.fingerprint == original_fp
147 assert original.origin is None
148
149def test_fork_does_not_shadow_state(sample_domain):
150 forked = sample_domain.fork(domain_id="DST")
151
152 # No instance attribute allowed
153 assert "state" not in forked.__dict__
154
155 # Property must still work
156 assert forked.state == EntityState.DRAFT
157
158def test_fork_without_origin(sample_domain):
159 forked = sample_domain.fork(domain_id="DST", keep_origin=False)
160
161 assert forked.origin is None
Note: See TracBrowser for help on using the repository browser.