Repository: getmoto/moto

Issue:
`describe_receipt_rule_set` for `ses` not implemented
It looks like `describe_receipt_rule_set` is not implemented [here](https://github.com/spulec/moto/blob/master/IMPLEMENTATION_COVERAGE.md#ses), I'll make a PR to add this feature shortly as my team also may need to use this function.


Discussion:

Resolving patch:
diff --git a/moto/ses/models.py b/moto/ses/models.py
--- a/moto/ses/models.py
+++ b/moto/ses/models.py
@@ -426,6 +426,14 @@ def create_receipt_rule(self, rule_set_name, rule):
         rule_set.append(rule)
         self.receipt_rule_set[rule_set_name] = rule_set
 
+    def describe_receipt_rule_set(self, rule_set_name):
+        rule_set = self.receipt_rule_set.get(rule_set_name)
+
+        if rule_set is None:
+            raise RuleSetDoesNotExist(f"Rule set does not exist: {rule_set_name}")
+
+        return rule_set
+
     def describe_receipt_rule(self, rule_set_name, rule_name):
         rule_set = self.receipt_rule_set.get(rule_set_name)
 
diff --git a/moto/ses/responses.py b/moto/ses/responses.py
--- a/moto/ses/responses.py
+++ b/moto/ses/responses.py
@@ -239,6 +239,23 @@ def create_receipt_rule(self):
         template = self.response_template(CREATE_RECEIPT_RULE)
         return template.render()
 
+    def describe_receipt_rule_set(self):
+        rule_set_name = self._get_param("RuleSetName")
+
+        rule_set = ses_backend.describe_receipt_rule_set(rule_set_name)
+
+        for i, rule in enumerate(rule_set):
+            formatted_rule = {}
+
+            for k, v in rule.items():
+                self._parse_param(k, v, formatted_rule)
+
+            rule_set[i] = formatted_rule
+
+        template = self.response_template(DESCRIBE_RECEIPT_RULE_SET)
+
+        return template.render(rule_set=rule_set, rule_set_name=rule_set_name)
+
     def describe_receipt_rule(self):
         rule_set_name = self._get_param("RuleSetName")
         rule_name = self._get_param("RuleName")
@@ -507,6 +524,57 @@ def describe_receipt_rule(self):
   </ResponseMetadata>
 </CreateReceiptRuleResponse>"""
 
+DESCRIBE_RECEIPT_RULE_SET = """<DescribeReceiptRuleSetResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
+  <DescribeReceiptRuleSetResult>
+    <Rules>
+      {% for rule in rule_set %}
+      <member>
+        <Recipients>
+          {% for recipient in rule["recipients"] %}
+          <member>{{recipient}}</member>
+          {% endfor %}
+        </Recipients>
+        <Name>{{rule["name"]}}</Name>
+        <Actions>
+          {% for action in rule["actions"] %}
+          <member>
+            {% if action["_s3_action"] %}
+            <S3Action>
+              <BucketName>{{action["_s3_action"]["_bucket_name"]}}</BucketName>
+              <KmsKeyArn>{{action["_s3_action"]["_kms_key_arn"]}}</KmsKeyArn>
+              <ObjectKeyPrefix>{{action["_s3_action"]["_object_key_prefix"]}}</ObjectKeyPrefix>
+              <TopicArn>{{action["_s3_action"]["_topic_arn"]}}</TopicArn>
+            </S3Action>
+            {% endif %}
+            {% if action["_bounce_action"] %}
+            <BounceAction>
+              <TopicArn>{{action["_bounce_action"]["_topic_arn"]}}</TopicArn>
+              <SmtpReplyCode>{{action["_bounce_action"]["_smtp_reply_code"]}}</SmtpReplyCode>
+              <StatusCode>{{action["_bounce_action"]["_status_code"]}}</StatusCode>
+              <Message>{{action["_bounce_action"]["_message"]}}</Message>
+              <Sender>{{action["_bounce_action"]["_sender"]}}</Sender>
+            </BounceAction>
+            {% endif %}
+          </member>
+          {% endfor %}
+        </Actions>
+        <TlsPolicy>{{rule["tls_policy"]}}</TlsPolicy>
+        <ScanEnabled>{{rule["scan_enabled"]}}</ScanEnabled>
+        <Enabled>{{rule["enabled"]}}</Enabled>
+      </member>
+      {% endfor %}
+    </Rules>
+    <Metadata>
+      <Name>{{rule_set_name}}</Name>
+      <CreatedTimestamp>2021-10-31</CreatedTimestamp>
+    </Metadata>
+  </DescribeReceiptRuleSetResult>
+  <ResponseMetadata>
+    <RequestId>15e0ef1a-9bf2-11e1-9279-01ab88cf109a</RequestId>
+  </ResponseMetadata>
+</DescribeReceiptRuleSetResponse>
+"""
+
 DESCRIBE_RECEIPT_RULE = """<DescribeReceiptRuleResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
   <DescribeReceiptRuleResult>
     <Rule>


Test patch:
diff --git a/tests/test_ses/test_ses_boto3.py b/tests/test_ses/test_ses_boto3.py
--- a/tests/test_ses/test_ses_boto3.py
+++ b/tests/test_ses/test_ses_boto3.py
@@ -481,6 +481,76 @@ def test_create_receipt_rule():
     ex.value.response["Error"]["Code"].should.equal("RuleSetDoesNotExist")
 
 
+@mock_ses
+def test_describe_receipt_rule_set():
+    conn = boto3.client("ses", region_name="us-east-1")
+    create_receipt_rule_set_response = conn.create_receipt_rule_set(
+        RuleSetName="testRuleSet"
+    )
+
+    create_receipt_rule_set_response["ResponseMetadata"]["HTTPStatusCode"].should.equal(
+        200
+    )
+
+    result = conn.describe_receipt_rule_set(RuleSetName="testRuleSet")
+
+    result["Metadata"]["Name"].should.equal("testRuleSet")
+    # result['Metadata']['CreatedTimestamp'].should.equal()
+
+    len(result["Rules"]).should.equal(0)
+
+
+@mock_ses
+def test_describe_receipt_rule_set_with_rules():
+    conn = boto3.client("ses", region_name="us-east-1")
+    create_receipt_rule_set_response = conn.create_receipt_rule_set(
+        RuleSetName="testRuleSet"
+    )
+
+    create_receipt_rule_set_response["ResponseMetadata"]["HTTPStatusCode"].should.equal(
+        200
+    )
+
+    receipt_rule = {
+        "Name": "testRule",
+        "Enabled": True,
+        "TlsPolicy": "Optional",
+        "Recipients": ["string"],
+        "Actions": [
+            {
+                "S3Action": {
+                    "TopicArn": "string",
+                    "BucketName": "string",
+                    "ObjectKeyPrefix": "string",
+                    "KmsKeyArn": "string",
+                },
+                "BounceAction": {
+                    "TopicArn": "string",
+                    "SmtpReplyCode": "string",
+                    "StatusCode": "string",
+                    "Message": "string",
+                    "Sender": "string",
+                },
+            }
+        ],
+        "ScanEnabled": False,
+    }
+
+    create_receipt_rule_response = conn.create_receipt_rule(
+        RuleSetName="testRuleSet", Rule=receipt_rule
+    )
+
+    create_receipt_rule_response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
+
+    result = conn.describe_receipt_rule_set(RuleSetName="testRuleSet")
+
+    result["Metadata"]["Name"].should.equal("testRuleSet")
+    # result['Metadata']['CreatedTimestamp'].should.equal()
+
+    len(result["Rules"]).should.equal(1)
+    result["Rules"][0].should.equal(receipt_rule)
+
+
 @mock_ses
 def test_describe_receipt_rule():
     conn = boto3.client("ses", region_name="us-east-1")