@@ -94,6 +94,18 @@ def counter_entity_function_raises_exception(context):
9494def counter_entity_function_raises_exception_with_pystein (context ):
9595 raise Exception ("boom!" )
9696
97+ def set_then_get_entity (context ):
98+ """Entity that sets state (without first reading it) in one operation and
99+ reads it in a later operation. Used to exercise set-then-get across a
100+ batch when the entity already has persisted state.
101+ """
102+ operation = context .operation_name
103+ if operation == "set" :
104+ context .set_state (10 )
105+ context .set_result ("set" )
106+ elif operation == "get" :
107+ context .set_result (context .get_state (lambda : 0 ))
108+
97109def test_entity_raises_exception ():
98110 # Create input batch
99111 batch = []
@@ -163,6 +175,40 @@ def test_entity_signal_then_call():
163175 #assert_valid_schema(result)
164176 assert_entity_state_equals (expected , result )
165177
178+ def test_entity_set_then_get_with_preexisting_raw_state ():
179+ """Regression test: an entity that already has persisted state must be
180+ able to set_state in one operation and get_state in a later operation
181+ within the same batch.
182+
183+ ``from_json`` keeps the persisted state in its raw (undecoded) form and
184+ marks it as raw so the first ``get_state`` can decode it lazily with a
185+ user-supplied ``expected_type``. ``set_state`` replaces that raw value
186+ with a live Python value, so it must clear the raw flag -- otherwise a
187+ later ``get_state`` would try to re-decode an already-live value and the
188+ operation would fail.
189+ """
190+ # Pre-existing persisted state (single-encoded JSON string) is what makes
191+ # from_json mark the loaded state as raw.
192+ batch = []
193+ add_to_batch (batch , name = "set" )
194+ add_to_batch (batch , name = "get" )
195+ context_builder = EntityContextBuilder (batch = batch , state = json .dumps (5 ))
196+
197+ # Run the entity, get observed result
198+ result = get_entity_state_result (
199+ context_builder ,
200+ set_then_get_entity ,
201+ )
202+
203+ # Both operations should succeed; the "get" must observe the value set by
204+ # the earlier "set" (10), not crash trying to re-decode it.
205+ expected_state = entity_base_expected_state ()
206+ apply_operation (expected_state , result = "set" , state = 10 )
207+ apply_operation (expected_state , result = 10 , state = 10 )
208+ expected = expected_state .to_json ()
209+
210+ assert_entity_state_equals (expected , result )
211+
166212def test_entity_signal_then_call_with_pystein ():
167213 """Tests that a simple counter entity outputs the correct value
168214 after a sequence of operations. Mostly just a sanity check.
0 commit comments