diff --git a/moto/sns/models.py b/moto/sns/models.py index 3d6f6507e..70587d980 100644 --- a/moto/sns/models.py +++ b/moto/sns/models.py @@ -247,11 +247,21 @@ class SNSBackend(BaseBackend): setattr(topic, attribute_name, attribute_value) def subscribe(self, topic_arn, endpoint, protocol): + # AWS doesn't create duplicates + old_subscription = self._find_subscription(topic_arn, endpoint, protocol) + if old_subscription: + return old_subscription topic = self.get_topic(topic_arn) subscription = Subscription(topic, endpoint, protocol) self.subscriptions[subscription.arn] = subscription return subscription + def _find_subscription(self, topic_arn, endpoint, protocol): + for subscription in self.subscriptions.values(): + if subscription.topic.arn == topic_arn and subscription.endpoint == endpoint and subscription.protocol == protocol: + return subscription + return None + def unsubscribe(self, subscription_arn): self.subscriptions.pop(subscription_arn) diff --git a/tests/test_sns/test_subscriptions_boto3.py b/tests/test_sns/test_subscriptions_boto3.py index 4446febfc..59cef221f 100644 --- a/tests/test_sns/test_subscriptions_boto3.py +++ b/tests/test_sns/test_subscriptions_boto3.py @@ -25,6 +25,23 @@ def test_subscribe_sms(): ) resp.should.contain('SubscriptionArn') +@mock_sns +def test_double_subscription(): + client = boto3.client('sns', region_name='us-east-1') + client.create_topic(Name="some-topic") + resp = client.create_topic(Name="some-topic") + arn = resp['TopicArn'] + + do_subscribe_sqs = lambda sqs_arn: client.subscribe( + TopicArn=arn, + Protocol='sqs', + Endpoint=sqs_arn + ) + resp1 = do_subscribe_sqs('arn:aws:sqs:elasticmq:000000000000:foo') + resp2 = do_subscribe_sqs('arn:aws:sqs:elasticmq:000000000000:foo') + + resp1['SubscriptionArn'].should.equal(resp2['SubscriptionArn']) + @mock_sns def test_subscribe_bad_sms():