def test_get_contextual_events_basic_retrieval():
    """
    Tests basic retrieval of events, ensuring correct count, order, and string formatting.
    All events in this test are of types that are NOT filtered out by default.
    """
    mock_event_stream = MagicMock(spec=EventStream)
    target_event_id = 5
    context_size = 4  # Hardcoded in _get_contextual_events

    # Define all events that *could* be in the stream for this test
    all_event_specs = [
        {'id': 1, 'type': MessageAction, 'content': 'message_1'},
        {'id': 2, 'type': CmdRunAction, 'command': 'command_2'},
        {
            'id': 3,
            'type': CmdOutputObservation,
            'content': 'observation_3',
            'command_id': 2,
            'command': 'command_2',
        },
        {'id': 4, 'type': MessageAction, 'content': 'message_4'},
        {'id': 5, 'type': CmdRunAction, 'command': 'command_5_target'},  # Target Event
        {
            'id': 6,
            'type': CmdOutputObservation,
            'content': 'observation_6',
            'command_id': 5,
            'command': 'command_5_target',
        },
        {'id': 7, 'type': MessageAction, 'content': 'message_7'},
        {'id': 8, 'type': CmdRunAction, 'command': 'command_8'},
        {
            'id': 9,
            'type': CmdOutputObservation,
            'content': 'observation_9',
            'command_id': 8,
            'command': 'command_8',
        },
        {'id': 10, 'type': MessageAction, 'content': 'message_10'},
        {
            'id': 11,
            'type': CmdRunAction,
            'command': 'command_11',
        },  # Extra event, should not be included in 'after' due to limit
    ]
    all_events_objects = create_test_events(all_event_specs)

    # Map IDs to objects for easy lookup
    events_by_id = {e.id: e for e in all_events_objects}

    # Define what search_events should return for the "before" call
    # (event_id=5, limit=4, reverse=True) -> expects [5, 4, 3, 2]
    events_to_return_before = [
        events_by_id[5],
        events_by_id[4],
        events_by_id[3],
        events_by_id[2],
    ]

    # Define what search_events should return for the "after" call
    # (start_id=6, limit=5) -> expects [6, 7, 8, 9, 10]
    events_to_return_after = [
        events_by_id[6],
        events_by_id[7],
        events_by_id[8],
        events_by_id[9],
        events_by_id[10],
    ]

    mock_event_stream.search_events.side_effect = [
        events_to_return_before,
        events_to_return_after,
    ]

    result_str = _get_contextual_events(mock_event_stream, target_event_id)

    # Expected final list of events after processing (chronological order):
    # [event_obj_2, event_obj_3, event_obj_4, event_obj_5, (from before, reversed)
    #  event_obj_6, event_obj_7, event_obj_8, event_obj_9, event_obj_10 (from after)]
    expected_final_event_objects = [
        events_by_id[2],
        events_by_id[3],
        events_by_id[4],
        events_by_id[5],
        events_by_id[6],
        events_by_id[7],
        events_by_id[8],
        events_by_id[9],
        events_by_id[10],
    ]

    # The output string is joined by newlines, using event.__str__
    expected_output_str = '\n'.join(str(e) for e in expected_final_event_objects)

    assert result_str == expected_output_str

    # Check calls to search_events
    calls = mock_event_stream.search_events.call_args_list
    assert len(calls) == 2

    # Call 1: Before events
    args_before, kwargs_before = calls[0]
    assert kwargs_before['start_id'] == target_event_id
    assert isinstance(kwargs_before['filter'], EventFilter)
    assert kwargs_before['reverse'] is True
    assert kwargs_before['limit'] == context_size

    # Call 2: After events
    args_after, kwargs_after = calls[1]
    assert kwargs_after['start_id'] == target_event_id + 1
    assert isinstance(kwargs_after['filter'], EventFilter)
    assert (
        'reverse' not in kwargs_after or kwargs_after['reverse'] is False
    )  # default is False
    assert kwargs_after['limit'] == context_size + 1

    Tests basic retrieval of events, ensuring correct count, order, and string formatting.
    All events in this test are of types that are NOT filtered out by default.
    
tests/unit/test_contextual_events.py