@@ -95,8 +95,13 @@ async def test_sse_connection_lifecycle(mock_options, mock_features_response):
9595 patch ('growthbook.growthbook_client.EnhancedFeatureRepository.stopAutoRefresh' ) as mock_stop :
9696 await client .initialize ()
9797 # Allow the SSE lifecycle task to start and invoke startAutoRefresh
98- await asyncio .sleep (0 )
98+ await asyncio .sleep (0.1 )
9999 assert mock_start .called
100+
101+ # Verify the thread created is a daemon thread (if possible without real start)
102+ # Since we mock startAutoRefresh, we can't check the real thread here.
103+ # But we can check that SSEClient is initialized correctly if we don't mock it all.
104+
100105 await client .close ()
101106 assert mock_stop .called
102107
@@ -337,18 +342,14 @@ async def test_callback(features):
337342
338343@pytest .mark .asyncio
339344async def test_sse_event_handling (mock_options ):
340- """Test SSE event handling and reconnection logic """
345+ """Test SSE event handling including JSON parsing """
341346 events = [
342- {'type' : 'features' , 'data' : {'features' : {'feature1' : {'defaultValue' : 1 }}}},
343- {'type' : 'ping' , 'data' : {}}, # Should be ignored
344- {'type' : 'features' , 'data' : {'features' : {'feature1' : {'defaultValue' : 2 }}}}
347+ # Real SSE payload is a raw string in 'data'
348+ {'type' : 'features' , 'data' : json .dumps ({'features' : {'feature1' : {'defaultValue' : 1 }}})},
349+ {'type' : 'ping' , 'data' : '{}' }, # Should be ignored
350+ {'type' : 'features' , 'data' : json .dumps ({'features' : {'feature1' : {'defaultValue' : 2 }}})}
345351 ]
346352
347- async def mock_sse_handler (event_data ):
348- """Mock the SSE event handler to directly update feature cache"""
349- if event_data ['type' ] == 'features' :
350- await client ._features_repository ._handle_feature_update (event_data ['data' ])
351-
352353 with patch ('growthbook.FeatureRepository.load_features_async' ,
353354 new_callable = AsyncMock , return_value = {"features" : {}, "savedGroups" : {}}) as mock_load :
354355
@@ -364,16 +365,15 @@ async def mock_sse_handler(event_data):
364365 try :
365366 await client .initialize ()
366367
367- # Simulate SSE events directly
368+ # Simulate SSE events using the actual handler method
369+ # This now tests the json.loads parsing logic!
368370 for event in events :
369- if event ['type' ] == 'features' :
370- await client ._features_repository ._handle_feature_update (event ['data' ])
371+ await client ._features_repository ._handle_sse_event (event )
371372
372- # print(f"AFTER TEST: Current cache state: {client._features_repository._feature_cache.get_current_state()}")
373373 # Verify feature update happened
374- assert client ._features_repository ._feature_cache .get_current_state ()["features" ]["feature1" ]["defaultValue" ] == 2
374+ state = client ._features_repository ._feature_cache .get_current_state ()
375+ assert state ["features" ]["feature1" ]["defaultValue" ] == 2
375376 finally :
376- # Ensure we clean up the SSE connection
377377 await client .close ()
378378
379379@pytest .mark .asyncio
0 commit comments