diff --git a/moto/sqs/exceptions.py b/moto/sqs/exceptions.py index 872c25412..91f21a550 100644 --- a/moto/sqs/exceptions.py +++ b/moto/sqs/exceptions.py @@ -123,9 +123,10 @@ class InvalidParameterValue(RESTError): class MissingParameter(RESTError): code = 400 - def __init__(self): + def __init__(self, parameter): super(MissingParameter, self).__init__( - "MissingParameter", "The request must contain the parameter Actions." + "MissingParameter", + "The request must contain the parameter {}.".format(parameter), ) diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 6ec47f2ab..84664d53b 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -706,7 +706,13 @@ class SQSBackend(BaseBackend): message.sequence_number = "".join( random.choice(string.digits) for _ in range(20) ) - if group_id is not None: + + if group_id is None: + # MessageGroupId is a mandatory parameter for all + # messages in a fifo queue + if queue.fifo_queue: + raise MissingParameter("MessageGroupId") + else: message.group_id = group_id if message_attributes: @@ -925,7 +931,7 @@ class SQSBackend(BaseBackend): queue = self.get_queue(queue_name) if not actions: - raise MissingParameter() + raise MissingParameter("Actions") if not account_ids: raise InvalidParameterValue( @@ -998,14 +1004,11 @@ class SQSBackend(BaseBackend): queue = self.get_queue(queue_name) if not len(tags): - raise RESTError( - "MissingParameter", "The request must contain the parameter Tags." - ) + raise MissingParameter("Tags") if len(tags) > 50: - raise RESTError( - "InvalidParameterValue", - "Too many tags added for queue {}.".format(queue_name), + raise InvalidParameterValue( + "Too many tags added for queue {}.".format(queue_name) ) queue.tags.update(tags) diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py index 7e879ed89..591c8a2e6 100644 --- a/moto/sqs/responses.py +++ b/moto/sqs/responses.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import re +from moto.core.exceptions import RESTError from moto.core.responses import BaseResponse from moto.core.utils import ( amz_crc32, @@ -234,23 +235,19 @@ class SQSResponse(BaseResponse): queue_name = self._get_queue_name() - if not message_group_id: - queue = self.sqs_backend.get_queue(queue_name) - if queue.attributes.get("FifoQueue", False): - return self._error( - "MissingParameter", - "The request must contain the parameter MessageGroupId.", - ) + try: + message = self.sqs_backend.send_message( + queue_name, + message, + message_attributes=message_attributes, + delay_seconds=delay_seconds, + deduplication_id=message_dedupe_id, + group_id=message_group_id, + system_attributes=system_message_attributes, + ) + except RESTError as err: + return self._error(err.error_type, err.message) - message = self.sqs_backend.send_message( - queue_name, - message, - message_attributes=message_attributes, - delay_seconds=delay_seconds, - deduplication_id=message_dedupe_id, - group_id=message_group_id, - system_attributes=system_message_attributes, - ) template = self.response_template(SEND_MESSAGE_RESPONSE) return template.render(message=message, message_attributes=message_attributes) diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py index 3fe2e025c..41de7e7c3 100644 --- a/tests/test_sqs/test_sqs.py +++ b/tests/test_sqs/test_sqs.py @@ -2555,7 +2555,7 @@ def test_list_queues_limits_to_1000_queues(): @mock_sqs -def test_send_messages_to_fifo_without_message_group_id(): +def test_send_message_to_fifo_without_message_group_id(): sqs = boto3.resource("sqs", region_name="eu-west-3") queue = sqs.create_queue( QueueName="blah.fifo", @@ -2571,6 +2571,25 @@ def test_send_messages_to_fifo_without_message_group_id(): ) +@mock_sqs +def test_send_messages_to_fifo_without_message_group_id(): + sqs = boto3.resource("sqs", region_name="eu-west-3") + queue = sqs.create_queue( + QueueName="blah.fifo", + Attributes={"FifoQueue": "true", "ContentBasedDeduplication": "true"}, + ) + + with pytest.raises(Exception) as e: + queue.send_messages( + Entries=[{"Id": "id_1", "MessageBody": "body_1",},] + ) + ex = e.value + ex.response["Error"]["Code"].should.equal("MissingParameter") + ex.response["Error"]["Message"].should.equal( + "The request must contain the parameter MessageGroupId." + ) + + @mock_logs @mock_lambda @mock_sqs