import pytest from unittest.mock import MagicMock, patch, call from scouter.activities.faker import Faker from logging import Logger from sientia_do.notifications.handlers import NotificationHandler @pytest.fixture def mock_kafka_producer(): with patch('scouter.activities.faker.KafkaProducer') as mock: producer = MagicMock() mock.return_value = producer yield producer @pytest.fixture def mock_datetime(): with patch('scouter.activities.faker.datetime') as mock_dt: mock_dt.now.return_value.strftime.return_value = '2025-05-14 14:54:24' yield mock_dt @pytest.fixture def faker_instance(mock_kafka_producer): logger = MagicMock(spec=Logger) notification_handler = MagicMock(spec=NotificationHandler) return Faker( bootstrap_servers='localhost:9092', logger=logger, notification_handler=notification_handler ) @pytest.mark.asyncio async def test_faker_init(faker_instance, mock_kafka_producer): """Test Faker initialization with correct parameters""" assert faker_instance.producer is not None assert len(faker_instance.tags) == 6 @pytest.mark.asyncio async def test_generate_and_send_data_default_count(faker_instance, mock_kafka_producer, mock_datetime): """Test generating data with default message count""" # Mock random.choice to control the output with patch('random.choice') as mock_choice, \ patch('random.uniform', return_value=42.5), \ patch('random.randint', return_value=3): # Setup mock for tag and name selection mock_choice.side_effect = [ 'ns=1;i=1001', 'ns=1;i=1002', 'ns=1;i=1003' ] # Call the method await faker_instance.generate_and_send_data({'topic': 'test_topic'}) # Verify the producer was called 3 times (default count) assert mock_kafka_producer.send.call_count == 3 mock_kafka_producer.flush.assert_called_once() # Verify the message format expected_data = { 'tag': 'ns=1;i=1001', 'name': 'Temperature Sensor', 'timestamp': '2025-05-14 14:54:24', 'value': 42.5 } mock_kafka_producer.send.assert_any_call( 'test_topic', value=expected_data) @pytest.mark.asyncio async def test_generate_and_send_data_custom_count(faker_instance, mock_kafka_producer): """Test generating data with custom message count""" # Call the method with custom count await faker_instance.generate_and_send_data({ 'topic': 'test_topic', 'num_messages': 2 }) # Verify the producer was called 2 times assert mock_kafka_producer.send.call_count == 2 mock_kafka_producer.flush.assert_called_once() @pytest.mark.asyncio async def test_generate_and_send_data_no_topic(faker_instance): """Test that ValueError is raised when no topic is provided""" with pytest.raises(ValueError, match="Topic must be specified in input_data"): await faker_instance.generate_and_send_data({}) @pytest.mark.asyncio async def test_generate_and_send_data_random_values(faker_instance, mock_kafka_producer): """Test that random values are within expected ranges""" # Call the method await faker_instance.generate_and_send_data({'topic': 'test_topic'}) # Get the call arguments call_args = mock_kafka_producer.send.call_args[1]['value'] # Verify the data structure assert 'tag' in call_args assert call_args['tag'] in faker_instance.tags assert 'value' in call_args assert 0 <= call_args['value'] <= 100