Repository: getmoto/moto
Pull request #8181 (2024-09-30 20:35:44)

Update Shield exception for no subscription on describe_subscriptions
Resolves: #8180 & added test to validate

Code should be "ResourceNotFound"
Message should be "The subscription does not exist."

Reference: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/shield/client/describe_subscription.html

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/getmoto/moto/pull/8181?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 94.53%. Comparing base [(`caf67cc`)](https://app.codecov.io/gh/getmoto/moto/commit/caf67cce4c284045452ea225bd74f5326a0aa33e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) to head [(`36fe4ec`)](https://app.codecov.io/gh/getmoto/moto/commit/36fe4ecf2d6da5b352a4280f178fba58b75b2c95?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).
> Report is 4 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #8181   +/-   ##
=======================================
  Coverage   94.53%   94.53%           
=======================================
  Files        1155     1155           
  Lines       99714    99710    -4     
=======================================
- Hits        94266    94264    -2     
+ Misses       5448     5446    -2     
```

| [Flag](https://app.codecov.io/gh/getmoto/moto/pull/8181/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | Coverage Δ | |
|---|---|---|
| [servertests](https://app.codecov.io/gh/getmoto/moto/pull/8181/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `28.78% <0.00%> (+<0.01%)` | :arrow_up: |
| [unittests](https://app.codecov.io/gh/getmoto/moto/pull/8181/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `94.51% <100.00%> (+<0.01%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/getmoto/moto/pull/8181?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).


Patch:
diff --git a/moto/scheduler/models.py b/moto/scheduler/models.py
index 7a2bcc157..4f5cd0fc1 100644
--- a/moto/scheduler/models.py
+++ b/moto/scheduler/models.py
@@ -65,8 +65,8 @@ class Schedule(BaseModel):
         if self.schedule_expression.count("*") and start_date is not None:
             start_date_as_dt = utcfromtimestamp(cast(int, start_date))
             now = utcnow()
-            if start_date_as_dt.date() == now.date():
-                diff = abs(now - start_date_as_dt)
+            if start_date_as_dt < now:
+                diff = now - start_date_as_dt
                 rule = datetime.timedelta(minutes=5)
                 within_rule = diff <= rule
                 if not within_rule:
diff --git a/moto/shield/exceptions.py b/moto/shield/exceptions.py
index 0c9976c48..1ae2efb63 100644
--- a/moto/shield/exceptions.py
+++ b/moto/shield/exceptions.py
@@ -36,13 +36,3 @@ class ValidationException(JsonRESTError):
 
     def __init__(self, message: str):
         super().__init__("ValidationException", message)
-
-
-class SubscriptionNotFoundError(JsonRESTError):
-    code = 400
-
-    def __init__(self) -> None:
-        super().__init__(
-            "SubscriptionNotFoundException",
-            "No Shield subscription has been created for this account",
-        )
diff --git a/moto/shield/models.py b/moto/shield/models.py
index fc217e3ba..09fe1d6dc 100644
--- a/moto/shield/models.py
+++ b/moto/shield/models.py
@@ -14,7 +14,6 @@ from moto.shield.exceptions import (
     InvalidResourceException,
     ResourceAlreadyExistsException,
     ResourceNotFoundException,
-    SubscriptionNotFoundError,
     ValidationException,
 )
 from moto.utilities.tagging_service import TaggingService
@@ -329,7 +328,7 @@ class ShieldBackend(BaseBackend):
 
     def describe_subscription(self) -> Subscription:
         if self.subscription is None:
-            raise SubscriptionNotFoundError()
+            raise ResourceNotFoundException("The subscription does not exist.")
         return self.subscription
 
 


Test patch:
diff --git a/tests/test_scheduler/__init__.py b/tests/test_scheduler/__init__.py
index e69de29bb..a7b62c967 100644
--- a/tests/test_scheduler/__init__.py
+++ b/tests/test_scheduler/__init__.py
@@ -0,0 +1,32 @@
+from datetime import datetime, timedelta
+from typing import List, Tuple
+
+from moto.core.utils import utcnow
+
+
+def pytest_parametrize_test_create_get_schedule__with_start_date() -> (
+    List[Tuple[datetime, datetime]]
+):
+    now = utcnow()
+    timedelta_kwargs = {"days": 1, "hours": 1, "weeks": 1}
+    return_ = []
+    for k, v in timedelta_kwargs.items():
+        to_append = now + timedelta(**{k: v})
+        return_.append((to_append, to_append.replace(microsecond=0)))
+    else:
+        to_append = now.replace(year=now.year + 1)
+        return_.append((to_append, to_append.replace(microsecond=0)))
+    return return_
+
+
+def pytest_parametrize_test_create_schedule__exception_with_start_date() -> (
+    List[datetime]
+):
+    now = utcnow()
+    timedelta_kwargs = {"days": 1, "minutes": 6, "hours": 1, "weeks": 1}
+    return_ = []
+    for k, v in timedelta_kwargs.items():
+        return_.append(now - timedelta(**{k: v}))
+    else:
+        return_.append(now.replace(year=now.year - 1))
+    return return_
diff --git a/tests/test_scheduler/test_scheduler.py b/tests/test_scheduler/test_scheduler.py
index 6bb672f26..2ef384c63 100644
--- a/tests/test_scheduler/test_scheduler.py
+++ b/tests/test_scheduler/test_scheduler.py
@@ -1,4 +1,4 @@
-from datetime import datetime, timedelta, timezone
+from datetime import datetime, timezone
 
 import boto3
 import pytest
@@ -6,7 +6,10 @@ from botocore.client import ClientError
 
 from moto import mock_aws
 from moto.core import DEFAULT_ACCOUNT_ID
-from moto.core.utils import utcnow
+from tests.test_scheduler import (
+    pytest_parametrize_test_create_get_schedule__with_start_date,
+    pytest_parametrize_test_create_schedule__exception_with_start_date,
+)
 
 # See our Development Tips on writing tests for hints on how to write good tests:
 # http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
@@ -233,10 +236,11 @@ def test_delete_schedule_for_none_existing_schedule():
 
 
 @mock_aws
-def test_create_get_schedule__with_start_date():
-    # Arrange
-    expected_start_date = start_date = utcnow().replace(microsecond=0)
-
+@pytest.mark.parametrize(
+    "start_date,expected_start_date",
+    pytest_parametrize_test_create_get_schedule__with_start_date(),
+)
+def test_create_get_schedule__with_start_date(start_date, expected_start_date):
     # Act
     client = boto3.client("scheduler", region_name="eu-west-1")
     client.create_schedule(
@@ -262,14 +266,16 @@ def test_create_get_schedule__with_start_date():
 
 
 @mock_aws
-def test_create_schedule__exception_with_start_date():
+@pytest.mark.parametrize(
+    "start_date",
+    pytest_parametrize_test_create_schedule__exception_with_start_date(),
+)
+def test_create_schedule__exception_with_start_date(start_date):
     # Arrange
     expected_error = "ValidationException"
     expected_error_message = (
         "The StartDate you specify cannot be earlier than 5 minutes ago."
     )
-    start_date = utcnow() - timedelta(minutes=6)
-
     # Act
     with pytest.raises(ClientError) as exc:
         client = boto3.client("scheduler", region_name="eu-west-1")
diff --git a/tests/test_shield/test_shield.py b/tests/test_shield/test_shield.py
index 482e6f900..51c36d4c2 100644
--- a/tests/test_shield/test_shield.py
+++ b/tests/test_shield/test_shield.py
@@ -375,6 +375,14 @@ def test_untag_resource():
 @mock_aws
 def test_create_and_describe_subscription():
     client = boto3.client("shield", region_name="eu-west-1")
+
+    # Check exception when subscription does not exist
+    with pytest.raises(ClientError) as exc:
+        connection = client.describe_subscription()
+    err = exc.value.response["Error"]
+    assert err["Code"] == "ResourceNotFoundException"
+    assert err["Message"] == "The subscription does not exist."
+
     client.create_subscription()
     connection = client.describe_subscription()
     subscription = connection["Subscription"]