"""Test SQS queue module.""" import json from unittest.mock import Mock import boto3 import pytest from cache_manager import response from cache_manager import sqs_queue fixture_config = { 'QUEUE_NAME': 'test-ft-queue', 'POLLING_TIME': 0 } def get_queue(): """Create a test queue based on fixture config. Returns: sqs.Queue: SQS Queue object. """ sqs = boto3.resource('sqs') return sqs.create_queue( QueueName=fixture_config.get('QUEUE_NAME'), Attributes={ 'ReceiveMessageWaitTimeSeconds': str( fixture_config.get('POLLING_TIME'))}) def delete_queue(): """Delete the test queue.""" queue = get_queue() queue.delete() @pytest.mark.parametrize('payload, expected', [ (None, 'uuid_123'), ('{"a": invalid}', 'uuid_456'), ('{"a": "A"}', 'uuid_456'), ('{"a": "A", "correlation_id": "123"}', '123.1') ]) def test_get_correlation_id(payload, expected, monkeypatch): """Test getting a correlation_id from a message.""" # Mocking uuid_mock = Mock(return_value=expected) monkeypatch.setattr(sqs_queue.uuid, 'uuid1', uuid_mock) # Loading a dict from the payload string try: payload_dict = json.loads(payload) except (TypeError, ValueError): payload_dict = dict() correlation_id = sqs_queue.get_correlation_id(Mock(body=payload)) # Asserts if not payload_dict.get('correlation_id'): assert uuid_mock.called assert correlation_id == expected def test_poll(monkeypatch): """Test polling the message queue. Regular mocking used because moto does not play well with boto3 and SQS. Messages do not get deleted properly from the queue. """ # Mocks # For messages message_mock_attributes = {'body': '', 'delete.return_value': None} message_1 = Mock(message_id='id_123', **message_mock_attributes) message_2 = Mock(message_id='id_456', **message_mock_attributes) message_3 = Mock(message_id='id_789', **message_mock_attributes) # For queue queue_mock = Mock() queue_mock.receive_messages.side_effect = [ [message_1], [message_2], [message_3]] # For sqs_queue.handlers.process function cache_handler_process_mock = Mock(side_effect=[ response.Response(), response.create_validation_error_response('Invalid message'), response.create_error_response('Uh oh') ]) # For sqs_queue.handlers.get_correlation_id function get_correlation_id_mock = Mock() # Patching # For sqs_queue.get_queue_by_name function get_queue_by_name_mock = Mock(return_value=queue_mock) monkeypatch.setattr( sqs_queue.sqs, 'get_queue_by_name', get_queue_by_name_mock) # For sqs_queue.handlers.process function monkeypatch.setattr( sqs_queue.handlers, 'process', cache_handler_process_mock) # For sqs_queue.get_correlation_id monkeypatch.setattr( sqs_queue, 'get_correlation_id', get_correlation_id_mock) # For config monkeypatch.setattr(sqs_queue.config, 'SQS', fixture_config) # Calls sqs_queue.poll() sqs_queue.poll() sqs_queue.poll() # Asserts get_queue_by_name_mock.assert_called_with( QueueName=fixture_config.get('QUEUE_NAME')) assert get_queue_by_name_mock.call_count is 3 assert cache_handler_process_mock.call_count is 3 assert get_correlation_id_mock.call_count is 3 assert queue_mock.receive_messages.call_count is 3 assert message_1.delete.called assert message_2.delete.called assert message_3.delete.called