diff --git a/moto/sns/models.py b/moto/sns/models.py index cdc50f640..680176bd3 100644 --- a/moto/sns/models.py +++ b/moto/sns/models.py @@ -397,10 +397,6 @@ class SNSBackend(BaseBackend): return self._get_values_nexttoken(self.topics, next_token) def delete_topic(self, arn): - topic = self.get_topic(arn) - subscriptions = self._get_topic_subscriptions(topic) - for sub in subscriptions: - self.unsubscribe(sub.arn) self.topics.pop(arn) def get_topic(self, arn): @@ -466,7 +462,7 @@ class SNSBackend(BaseBackend): return None def unsubscribe(self, subscription_arn): - self.subscriptions.pop(subscription_arn) + self.subscriptions.pop(subscription_arn, None) def list_subscriptions(self, topic_arn=None, next_token=None): if topic_arn: diff --git a/tests/test_sns/test_subscriptions.py b/tests/test_sns/test_subscriptions.py index fbd4274f4..f773438d7 100644 --- a/tests/test_sns/test_subscriptions.py +++ b/tests/test_sns/test_subscriptions.py @@ -54,9 +54,10 @@ def test_deleting_subscriptions_by_deleting_topic(): ]["Subscriptions"] subscriptions.should.have.length_of(1) subscription = subscriptions[0] + subscription_arn = subscription["SubscriptionArn"] subscription["TopicArn"].should.equal(topic_arn) subscription["Protocol"].should.equal("http") - subscription["SubscriptionArn"].should.contain(topic_arn) + subscription_arn.should.contain(topic_arn) subscription["Endpoint"].should.equal("http://example.com/") # Now delete the topic @@ -67,12 +68,25 @@ def test_deleting_subscriptions_by_deleting_topic(): topics = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"] topics.should.have.length_of(0) - # And there should be zero subscriptions left + # And the subscription should still be left + subscriptions = conn.get_all_subscriptions()["ListSubscriptionsResponse"][ + "ListSubscriptionsResult" + ]["Subscriptions"] + subscriptions.should.have.length_of(1) + subscription = subscriptions[0] + subscription["SubscriptionArn"].should.equal(subscription_arn) + + # Now delete hanging subscription + conn.unsubscribe(subscription_arn) + subscriptions = conn.get_all_subscriptions()["ListSubscriptionsResponse"][ "ListSubscriptionsResult" ]["Subscriptions"] subscriptions.should.have.length_of(0) + # Deleting it again should not result in any error + conn.unsubscribe(subscription_arn) + @mock_sns_deprecated def test_getting_subscriptions_by_topic(): diff --git a/tests/test_sns/test_subscriptions_boto3.py b/tests/test_sns/test_subscriptions_boto3.py index faf3ae4a5..d91b3566b 100644 --- a/tests/test_sns/test_subscriptions_boto3.py +++ b/tests/test_sns/test_subscriptions_boto3.py @@ -97,34 +97,48 @@ def test_creating_subscription(): @mock_sns -def test_deleting_subscriptions_by_deleting_topic(): - conn = boto3.client("sns", region_name="us-east-1") - conn.create_topic(Name="some-topic") - response = conn.list_topics() +def test_unsubscribe_from_deleted_topic(): + client = boto3.client("sns", region_name="us-east-1") + client.create_topic(Name="some-topic") + response = client.list_topics() topic_arn = response["Topics"][0]["TopicArn"] - conn.subscribe(TopicArn=topic_arn, Protocol="http", Endpoint="http://example.com/") + client.subscribe( + TopicArn=topic_arn, Protocol="http", Endpoint="http://example.com/" + ) - subscriptions = conn.list_subscriptions()["Subscriptions"] + subscriptions = client.list_subscriptions()["Subscriptions"] subscriptions.should.have.length_of(1) subscription = subscriptions[0] + subscription_arn = subscription["SubscriptionArn"] subscription["TopicArn"].should.equal(topic_arn) subscription["Protocol"].should.equal("http") - subscription["SubscriptionArn"].should.contain(topic_arn) + subscription_arn.should.contain(topic_arn) subscription["Endpoint"].should.equal("http://example.com/") # Now delete the topic - conn.delete_topic(TopicArn=topic_arn) + client.delete_topic(TopicArn=topic_arn) # And there should now be 0 topics - topics_json = conn.list_topics() + topics_json = client.list_topics() topics = topics_json["Topics"] topics.should.have.length_of(0) - # And there should be zero subscriptions left - subscriptions = conn.list_subscriptions()["Subscriptions"] + # And the subscription should still be left + subscriptions = client.list_subscriptions()["Subscriptions"] + subscriptions.should.have.length_of(1) + subscription = subscriptions[0] + subscription["SubscriptionArn"].should.equal(subscription_arn) + + # Now delete hanging subscription + client.unsubscribe(SubscriptionArn=subscription_arn) + + subscriptions = client.list_subscriptions()["Subscriptions"] subscriptions.should.have.length_of(0) + # Deleting it again should not result in any error + client.unsubscribe(SubscriptionArn=subscription_arn) + @mock_sns def test_getting_subscriptions_by_topic():