Repository: getmoto/moto (python)

Issue:
EventBridge Scheduler get_schedule does not include ActionAfterCompletion in response
**Software versions**

moto version: 5.0.9
boto3 version: 1.34.130
Python version: 3.11.7

**Problem description**

When using the [boto3 EventBridgeScheduler client.get_schedule](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/scheduler/client/get_schedule.html) method, the response received when using moto for mocking purposes does not include `ActionAfterCompletion` in the response.

**Expected behaviour**

moto's implementation of [boto3 EventBridgeScheduler client.get_schedule](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/scheduler/client/get_schedule.html) method should match the response syntax documented by boto3.

**How to reproduce**

Execute the following code:

```python
#!/usr/bin/env python3

import json
from datetime import datetime

import boto3
import moto

if __name__ == "__main__":

    with moto.mock_aws():

        client = boto3.client("scheduler", region_name="us-east-1")
        client.create_schedule(
            FlexibleTimeWindow={"Mode": "OFF"},
            Name="foo",
            ScheduleExpression="cron(1 0 * * *)",
            StartDate=datetime(2024, 6, 19),
            EndDate=datetime(2024, 6, 26),
            ActionAfterCompletion="DELETE",
            Target={
                "Arn": "arn",
                "Input": json.dumps({"x": True}),
                "RoleArn": "role",
            }
        )

        response = client.get_schedule(Name="foo")
        assert "ActionAfterCompletion" in response
```

Pull request:
EventBridge Scheduler - get_schedule() now returns the ActionAfterCompletion
Fixes #7782 

Patch:
diff --git a/moto/rds/exceptions.py b/moto/rds/exceptions.py
index 678d1a78c..1829bc3f0 100644
--- a/moto/rds/exceptions.py
+++ b/moto/rds/exceptions.py
@@ -160,7 +160,7 @@ class DBClusterSnapshotAlreadyExistsError(RDSClientError):
 class ExportTaskAlreadyExistsError(RDSClientError):
     def __init__(self, export_task_identifier: str):
         super().__init__(
-            "ExportTaskAlreadyExistsFault",
+            "ExportTaskAlreadyExists",
             f"Cannot start export task because a task with the identifier {export_task_identifier} already exists.",
         )
 
@@ -168,7 +168,7 @@ class ExportTaskAlreadyExistsError(RDSClientError):
 class ExportTaskNotFoundError(RDSClientError):
     def __init__(self, export_task_identifier: str):
         super().__init__(
-            "ExportTaskNotFoundFault",
+            "ExportTaskNotFound",
             f"Cannot cancel export task because a task with the identifier {export_task_identifier} is not exist.",
         )
 
@@ -184,7 +184,7 @@ class InvalidExportSourceStateError(RDSClientError):
 class SubscriptionAlreadyExistError(RDSClientError):
     def __init__(self, subscription_name: str):
         super().__init__(
-            "SubscriptionAlreadyExistFault",
+            "SubscriptionAlreadyExist",
             f"Subscription {subscription_name} already exists.",
         )
 
@@ -192,7 +192,7 @@ class SubscriptionAlreadyExistError(RDSClientError):
 class SubscriptionNotFoundError(RDSClientError):
     def __init__(self, subscription_name: str):
         super().__init__(
-            "SubscriptionNotFoundFault", f"Subscription {subscription_name} not found."
+            "SubscriptionNotFound", f"Subscription {subscription_name} not found."
         )
 
 
diff --git a/moto/scheduler/models.py b/moto/scheduler/models.py
index 626194c66..124723b7b 100644
--- a/moto/scheduler/models.py
+++ b/moto/scheduler/models.py
@@ -27,6 +27,7 @@ class Schedule(BaseModel):
         kms_key_arn: Optional[str],
         start_date: Optional[str],
         end_date: Optional[str],
+        action_after_completion: Optional[str],
     ):
         self.name = name
         self.group_name = group_name
@@ -40,6 +41,7 @@ class Schedule(BaseModel):
         self.kms_key_arn = kms_key_arn
         self.start_date = start_date
         self.end_date = end_date
+        self.action_after_completion = action_after_completion
         self.creation_date = self.last_modified_date = unix_time()
 
     @staticmethod
@@ -61,6 +63,7 @@ class Schedule(BaseModel):
             "ScheduleExpressionTimezone": self.schedule_expression_timezone,
             "FlexibleTimeWindow": self.flexible_time_window,
             "Target": self.target,
+            "ActionAfterCompletion": self.action_after_completion,
             "State": self.state,
             "KmsKeyArn": self.kms_key_arn,
             "StartDate": self.start_date,
@@ -153,6 +156,7 @@ class EventBridgeSchedulerBackend(BaseBackend):
         start_date: str,
         state: str,
         target: Dict[str, Any],
+        action_after_completion: Optional[str],
     ) -> Schedule:
         """
         The ClientToken parameter is not yet implemented
@@ -174,6 +178,7 @@ class EventBridgeSchedulerBackend(BaseBackend):
             kms_key_arn=kms_key_arn,
             start_date=start_date,
             end_date=end_date,
+            action_after_completion=action_after_completion,
         )
         group.add_schedule(schedule)
         return schedule
diff --git a/moto/scheduler/responses.py b/moto/scheduler/responses.py
index cbd6ed3ad..5d3cea723 100644
--- a/moto/scheduler/responses.py
+++ b/moto/scheduler/responses.py
@@ -33,6 +33,7 @@ class EventBridgeSchedulerResponse(BaseResponse):
         start_date = self._get_param("StartDate")
         state = self._get_param("State")
         target = self._get_param("Target")
+        action_after_completion = self._get_param("ActionAfterCompletion")
         schedule = self.scheduler_backend.create_schedule(
             description=description,
             end_date=end_date,
@@ -45,6 +46,7 @@ class EventBridgeSchedulerResponse(BaseResponse):
             start_date=start_date,
             state=state,
             target=target,
+            action_after_completion=action_after_completion,
         )
         return json.dumps(dict(ScheduleArn=schedule.arn))
 


Test patch:
diff --git a/tests/test_rds/test_rds_event_subscriptions.py b/tests/test_rds/test_rds_event_subscriptions.py
index 1dd3a6839..ff7f4dadc 100644
--- a/tests/test_rds/test_rds_event_subscriptions.py
+++ b/tests/test_rds/test_rds_event_subscriptions.py
@@ -74,7 +74,7 @@ def test_create_event_fail_already_exists():
 
     err = ex.value.response["Error"]
 
-    assert err["Code"] == "SubscriptionAlreadyExistFault"
+    assert err["Code"] == "SubscriptionAlreadyExist"
     assert err["Message"] == "Subscription db-primary-1-events already exists."
 
 
@@ -85,7 +85,7 @@ def test_delete_event_subscription_fails_unknown_subscription():
         client.delete_event_subscription(SubscriptionName="my-db-events")
 
     err = ex.value.response["Error"]
-    assert err["Code"] == "SubscriptionNotFoundFault"
+    assert err["Code"] == "SubscriptionNotFound"
     assert err["Message"] == "Subscription my-db-events not found."
 
 
@@ -133,5 +133,5 @@ def test_describe_event_subscriptions_fails_unknown_subscription():
 
     err = ex.value.response["Error"]
 
-    assert err["Code"] == "SubscriptionNotFoundFault"
+    assert err["Code"] == "SubscriptionNotFound"
     assert err["Message"] == "Subscription my-db-events not found."
diff --git a/tests/test_rds/test_rds_export_tasks.py b/tests/test_rds/test_rds_export_tasks.py
index 82c87c65b..dd3c7ee26 100644
--- a/tests/test_rds/test_rds_export_tasks.py
+++ b/tests/test_rds/test_rds_export_tasks.py
@@ -142,7 +142,7 @@ def test_start_export_task_fail_already_exists():
         )
 
     err = ex.value.response["Error"]
-    assert err["Code"] == "ExportTaskAlreadyExistsFault"
+    assert err["Code"] == "ExportTaskAlreadyExists"
     assert err["Message"] == (
         "Cannot start export task because a task with the identifier "
         "export-snapshot-1 already exists."
@@ -156,7 +156,7 @@ def test_cancel_export_task_fails_unknown_task():
         client.cancel_export_task(ExportTaskIdentifier="export-snapshot-1")
 
     err = ex.value.response["Error"]
-    assert err["Code"] == "ExportTaskNotFoundFault"
+    assert err["Code"] == "ExportTaskNotFound"
     assert err["Message"] == (
         "Cannot cancel export task because a task with the identifier "
         "export-snapshot-1 is not exist."
@@ -207,7 +207,7 @@ def test_describe_export_tasks_fails_unknown_task():
         client.describe_export_tasks(ExportTaskIdentifier="export-snapshot-1")
 
     err = ex.value.response["Error"]
-    assert err["Code"] == "ExportTaskNotFoundFault"
+    assert err["Code"] == "ExportTaskNotFound"
     assert err["Message"] == (
         "Cannot cancel export task because a task with the identifier "
         "export-snapshot-1 is not exist."
diff --git a/tests/test_scheduler/test_scheduler.py b/tests/test_scheduler/test_scheduler.py
index 04c7d4f7f..6d4512241 100644
--- a/tests/test_scheduler/test_scheduler.py
+++ b/tests/test_scheduler/test_scheduler.py
@@ -25,6 +25,7 @@ def test_create_get_schedule():
             "Arn": "not supported yet",
             "RoleArn": "n/a",
         },
+        ActionAfterCompletion="DELETE",
     )["ScheduleArn"]
 
     assert (
@@ -40,6 +41,7 @@ def test_create_get_schedule():
         "MaximumWindowInMinutes": 4,
         "Mode": "OFF",
     }
+    assert resp["ActionAfterCompletion"] == "DELETE"
     assert resp["Target"] == {
         "Arn": "not supported yet",
         "RoleArn": "n/a",