@@ -20,6 +20,17 @@ def mock_yroom_with_notebook(self):
2020 # Create a real YDoc and YNotebook
2121 ydoc = pycrdt .Doc ()
2222 awareness = MagicMock (spec = pycrdt .Awareness ) # Mock awareness instead of using real one
23+
24+ # Mock the local state to track changes
25+ local_state = {}
26+ awareness .get_local_state = MagicMock (return_value = local_state )
27+
28+ # Mock set_local_state_field to actually update the local_state dict
29+ def mock_set_local_state_field (field , value ):
30+ local_state [field ] = value
31+
32+ awareness .set_local_state_field = MagicMock (side_effect = mock_set_local_state_field )
33+
2334 ynotebook = YNotebook (ydoc , awareness )
2435
2536 # Add a simple notebook structure with one cell
@@ -54,6 +65,18 @@ def mock_yroom_with_notebook(self):
5465 yroom .get_jupyter_ydoc = AsyncMock (return_value = ynotebook )
5566 yroom .get_awareness = MagicMock (return_value = awareness )
5667
68+ # Add persistent cell execution state storage
69+ yroom ._cell_execution_states = {}
70+
71+ def mock_get_cell_execution_states ():
72+ return yroom ._cell_execution_states
73+
74+ def mock_set_cell_execution_state (cell_id , execution_state ):
75+ yroom ._cell_execution_states [cell_id ] = execution_state
76+
77+ yroom .get_cell_execution_states = MagicMock (side_effect = mock_get_cell_execution_states )
78+ yroom .set_cell_execution_state = MagicMock (side_effect = mock_set_cell_execution_state )
79+
5780 return yroom , ynotebook
5881
5982 @pytest .fixture
@@ -109,7 +132,7 @@ async def test_execute_input_updates_execution_count(self, kernel_client_with_yr
109132
110133 @pytest .mark .asyncio
111134 async def test_status_message_updates_cell_execution_state (self , kernel_client_with_yroom ):
112- """Test that status messages update cell execution state in YDoc ."""
135+ """Test that status messages update cell execution state in YRoom for persistence and awareness for real-time updates ."""
113136 client , yroom , ynotebook = kernel_client_with_yroom
114137
115138 # Mock message cache to return cell_id and channel
@@ -129,11 +152,16 @@ async def test_status_message_updates_cell_execution_state(self, kernel_client_w
129152 # Process the message
130153 await client .handle_document_related_message (msg_parts [1 :]) # Skip delimiter
131154
132- # Verify the cell execution state was updated to 'running' (converted from 'busy')
133- cells = ynotebook .get_cell_list ()
134- target_cell = next ((cell for cell in cells if cell .get ("id" ) == cell_id ), None )
135- assert target_cell is not None
136- assert target_cell .get ("execution_state" ) == "running"
155+ # Verify the cell execution state was stored in YRoom for persistence
156+ cell_states = yroom .get_cell_execution_states ()
157+ assert cell_states [cell_id ] == "busy"
158+
159+ # Verify it's also in awareness for real-time updates
160+ awareness = yroom .get_awareness ()
161+ local_state = awareness .get_local_state ()
162+ assert local_state is not None
163+ assert "cell_execution_states" in local_state
164+ assert local_state ["cell_execution_states" ][cell_id ] == "busy"
137165
138166 @pytest .mark .asyncio
139167 async def test_kernel_info_reply_updates_language_info (self , kernel_client_with_yroom ):
@@ -304,12 +332,16 @@ async def test_complete_execution_flow(self, kernel_client_with_yroom):
304332 )
305333 await client .handle_document_related_message (msg_parts [1 :])
306334
307- # Verify final state of the cell in YDoc
335+ # Verify final state of the cell in YDoc and awareness
308336 cells = ynotebook .get_cell_list ()
309337 target_cell = next ((cell for cell in cells if cell .get ("id" ) == cell_id ), None )
310338 assert target_cell is not None
311339 assert target_cell .get ("execution_count" ) == 1
312- assert target_cell .get ("execution_state" ) == "idle"
340+
341+ # Verify execution state is stored in awareness, not YDoc
342+ awareness = yroom .get_awareness ()
343+ cell_execution_states = awareness .get_local_state ().get ("cell_execution_states" , {})
344+ assert cell_execution_states .get (cell_id ) == "idle"
313345
314346 # Verify output processor was called for the result
315347 client .output_processor .process_output .assert_called_with (
@@ -383,15 +415,12 @@ def mock_get(msg_id):
383415 )
384416 await client .handle_document_related_message (msg_parts2 [1 :])
385417
386- # Verify both cells have correct states
387- cells = ynotebook .get_cell_list ()
388- cell1 = next ((cell for cell in cells if cell .get ("id" ) == "test-cell-1" ), None )
389- cell2 = next ((cell for cell in cells if cell .get ("id" ) == "test-cell-2" ), None )
418+ # Verify both cells have correct states in awareness
419+ awareness = yroom .get_awareness ()
420+ cell_execution_states = awareness .get_local_state ().get ("cell_execution_states" , {})
390421
391- assert cell1 is not None
392- assert cell1 .get ("execution_state" ) == "running" # 'busy' -> 'running'
393- assert cell2 is not None
394- assert cell2 .get ("execution_state" ) == "idle"
422+ assert cell_execution_states .get ("test-cell-1" ) == "busy" # 'busy' state
423+ assert cell_execution_states .get ("test-cell-2" ) == "idle"
395424
396425 @pytest .mark .asyncio
397426 async def test_message_without_cell_id_skips_cell_updates (self , kernel_client_with_yroom ):
0 commit comments