Merge pull request #127 from spulec/sns-support
Add basic SNS support. Closes #26.
This commit is contained in:
commit
7acc22d8d1
@ -12,6 +12,7 @@ from .iam import mock_iam
|
|||||||
from .s3 import mock_s3
|
from .s3 import mock_s3
|
||||||
from .s3bucket_path import mock_s3bucket_path
|
from .s3bucket_path import mock_s3bucket_path
|
||||||
from .ses import mock_ses
|
from .ses import mock_ses
|
||||||
|
from .sns import mock_sns
|
||||||
from .sqs import mock_sqs
|
from .sqs import mock_sqs
|
||||||
from .sts import mock_sts
|
from .sts import mock_sts
|
||||||
from .route53 import mock_route53
|
from .route53 import mock_route53
|
||||||
|
2
moto/sns/__init__.py
Normal file
2
moto/sns/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .models import sns_backend
|
||||||
|
mock_sns = sns_backend.decorator
|
155
moto/sns/models.py
Normal file
155
moto/sns/models.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
import datetime
|
||||||
|
import requests
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from moto.core import BaseBackend
|
||||||
|
from moto.core.utils import iso_8601_datetime
|
||||||
|
from moto.sqs.models import sqs_backend
|
||||||
|
from .utils import make_arn_for_topic, make_arn_for_subscription
|
||||||
|
|
||||||
|
DEFAULT_ACCOUNT_ID = 123456789012
|
||||||
|
|
||||||
|
|
||||||
|
class Topic(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
self.account_id = DEFAULT_ACCOUNT_ID
|
||||||
|
self.display_name = ""
|
||||||
|
self.policy = DEFAULT_TOPIC_POLICY
|
||||||
|
self.delivery_policy = ""
|
||||||
|
self.effective_delivery_policy = DEFAULT_EFFECTIVE_DELIVERY_POLICY
|
||||||
|
self.arn = make_arn_for_topic(self.account_id, name)
|
||||||
|
|
||||||
|
self.subscriptions_pending = 0
|
||||||
|
self.subscriptions_confimed = 0
|
||||||
|
self.subscriptions_deleted = 0
|
||||||
|
|
||||||
|
def publish(self, message):
|
||||||
|
message_id = unicode(uuid.uuid4())
|
||||||
|
subscriptions = sns_backend.list_subscriptions(self.arn)
|
||||||
|
for subscription in subscriptions:
|
||||||
|
subscription.publish(message, message_id)
|
||||||
|
return message_id
|
||||||
|
|
||||||
|
|
||||||
|
class Subscription(object):
|
||||||
|
def __init__(self, topic, endpoint, protocol):
|
||||||
|
self.topic = topic
|
||||||
|
self.endpoint = endpoint
|
||||||
|
self.protocol = protocol
|
||||||
|
self.arn = make_arn_for_subscription(self.topic.arn)
|
||||||
|
|
||||||
|
def publish(self, message, message_id):
|
||||||
|
if self.protocol == 'sqs':
|
||||||
|
queue_name = self.endpoint.split(":")[-1]
|
||||||
|
sqs_backend.send_message(queue_name, message)
|
||||||
|
elif self.protocol in ['http', 'https']:
|
||||||
|
post_data = self.get_post_data(message, message_id)
|
||||||
|
requests.post(self.endpoint, data=post_data)
|
||||||
|
|
||||||
|
def get_post_data(self, message, message_id):
|
||||||
|
return {
|
||||||
|
"Type": "Notification",
|
||||||
|
"MessageId": message_id,
|
||||||
|
"TopicArn": self.topic.arn,
|
||||||
|
"Subject": "my subject",
|
||||||
|
"Message": message,
|
||||||
|
"Timestamp": iso_8601_datetime(datetime.datetime.now()),
|
||||||
|
"SignatureVersion": "1",
|
||||||
|
"Signature": "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
|
||||||
|
"SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
|
||||||
|
"UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789012:some-topic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SNSBackend(BaseBackend):
|
||||||
|
def __init__(self):
|
||||||
|
self.topics = {}
|
||||||
|
self.subscriptions = {}
|
||||||
|
|
||||||
|
def create_topic(self, name):
|
||||||
|
topic = Topic(name)
|
||||||
|
self.topics[topic.arn] = topic
|
||||||
|
return topic
|
||||||
|
|
||||||
|
def list_topics(self):
|
||||||
|
return self.topics.values()
|
||||||
|
|
||||||
|
def delete_topic(self, arn):
|
||||||
|
self.topics.pop(arn)
|
||||||
|
|
||||||
|
def get_topic(self, arn):
|
||||||
|
return self.topics[arn]
|
||||||
|
|
||||||
|
def set_topic_attribute(self, topic_arn, attribute_name, attribute_value):
|
||||||
|
topic = self.get_topic(topic_arn)
|
||||||
|
setattr(topic, attribute_name, attribute_value)
|
||||||
|
|
||||||
|
def subscribe(self, topic_arn, endpoint, protocol):
|
||||||
|
topic = self.get_topic(topic_arn)
|
||||||
|
subscription = Subscription(topic, endpoint, protocol)
|
||||||
|
self.subscriptions[subscription.arn] = subscription
|
||||||
|
return subscription
|
||||||
|
|
||||||
|
def unsubscribe(self, subscription_arn):
|
||||||
|
self.subscriptions.pop(subscription_arn)
|
||||||
|
|
||||||
|
def list_subscriptions(self, topic_arn=None):
|
||||||
|
if topic_arn:
|
||||||
|
topic = self.get_topic(topic_arn)
|
||||||
|
return [sub for sub in self.subscriptions.values() if sub.topic == topic]
|
||||||
|
else:
|
||||||
|
return self.subscriptions.values()
|
||||||
|
|
||||||
|
def publish(self, topic_arn, message):
|
||||||
|
topic = self.get_topic(topic_arn)
|
||||||
|
message_id = topic.publish(message)
|
||||||
|
return message_id
|
||||||
|
|
||||||
|
|
||||||
|
sns_backend = SNSBackend()
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_TOPIC_POLICY = {
|
||||||
|
"Version": "2008-10-17",
|
||||||
|
"Id": "us-east-1/698519295917/test__default_policy_ID",
|
||||||
|
"Statement": [{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Sid": "us-east-1/698519295917/test__default_statement_ID",
|
||||||
|
"Principal": {
|
||||||
|
"AWS": "*"
|
||||||
|
},
|
||||||
|
"Action": [
|
||||||
|
"SNS:GetTopicAttributes",
|
||||||
|
"SNS:SetTopicAttributes",
|
||||||
|
"SNS:AddPermission",
|
||||||
|
"SNS:RemovePermission",
|
||||||
|
"SNS:DeleteTopic",
|
||||||
|
"SNS:Subscribe",
|
||||||
|
"SNS:ListSubscriptionsByTopic",
|
||||||
|
"SNS:Publish",
|
||||||
|
"SNS:Receive",
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:sns:us-east-1:698519295917:test",
|
||||||
|
"Condition": {
|
||||||
|
"StringLike": {
|
||||||
|
"AWS:SourceArn": "arn:aws:*:*:698519295917:*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_EFFECTIVE_DELIVERY_POLICY = {
|
||||||
|
'http': {
|
||||||
|
'disableSubscriptionOverrides': False,
|
||||||
|
'defaultHealthyRetryPolicy': {
|
||||||
|
'numNoDelayRetries': 0,
|
||||||
|
'numMinDelayRetries': 0,
|
||||||
|
'minDelayTarget': 20,
|
||||||
|
'maxDelayTarget': 20,
|
||||||
|
'numMaxDelayRetries': 0,
|
||||||
|
'numRetries': 3,
|
||||||
|
'backoffFunction': 'linear'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
175
moto/sns/responses.py
Normal file
175
moto/sns/responses.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from moto.core.responses import BaseResponse
|
||||||
|
from moto.core.utils import camelcase_to_underscores
|
||||||
|
from .models import sns_backend
|
||||||
|
|
||||||
|
|
||||||
|
class SNSResponse(BaseResponse):
|
||||||
|
|
||||||
|
def create_topic(self):
|
||||||
|
name = self._get_param('Name')
|
||||||
|
topic = sns_backend.create_topic(name)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
'CreateTopicResponse': {
|
||||||
|
'CreateTopicResult': {
|
||||||
|
'TopicArn': topic.arn,
|
||||||
|
},
|
||||||
|
'ResponseMetadata': {
|
||||||
|
'RequestId': 'a8dec8b3-33a4-11df-8963-01868b7c937a',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def list_topics(self):
|
||||||
|
topics = sns_backend.list_topics()
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
'ListTopicsResponse': {
|
||||||
|
'ListTopicsResult': {
|
||||||
|
'Topics': [{'TopicArn': topic.arn} for topic in topics]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'ResponseMetadata': {
|
||||||
|
'RequestId': 'a8dec8b3-33a4-11df-8963-01868b7c937a',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def delete_topic(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
sns_backend.delete_topic(topic_arn)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
'DeleteTopicResponse': {
|
||||||
|
'ResponseMetadata': {
|
||||||
|
'RequestId': 'a8dec8b3-33a4-11df-8963-01868b7c937a',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_topic_attributes(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
topic = sns_backend.get_topic(topic_arn)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"GetTopicAttributesResponse": {
|
||||||
|
"GetTopicAttributesResult": {
|
||||||
|
"Attributes": {
|
||||||
|
"Owner": topic.account_id,
|
||||||
|
"Policy": topic.policy,
|
||||||
|
"TopicArn": topic.arn,
|
||||||
|
"DisplayName": topic.display_name,
|
||||||
|
"SubscriptionsPending": topic.subscriptions_pending,
|
||||||
|
"SubscriptionsConfirmed": topic.subscriptions_confimed,
|
||||||
|
"SubscriptionsDeleted": topic.subscriptions_deleted,
|
||||||
|
"DeliveryPolicy": topic.delivery_policy,
|
||||||
|
"EffectiveDeliveryPolicy": topic.effective_delivery_policy,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "057f074c-33a7-11df-9540-99d0768312d3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def set_topic_attributes(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
attribute_name = self._get_param('AttributeName')
|
||||||
|
attribute_name = camelcase_to_underscores(attribute_name)
|
||||||
|
attribute_value = self._get_param('AttributeValue')
|
||||||
|
sns_backend.set_topic_attribute(topic_arn, attribute_name, attribute_value)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"SetTopicAttributesResponse": {
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "a8763b99-33a7-11df-a9b7-05d48da6f042"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def subscribe(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
endpoint = self._get_param('Endpoint')
|
||||||
|
protocol = self._get_param('Protocol')
|
||||||
|
subscription = sns_backend.subscribe(topic_arn, endpoint, protocol)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"SubscribeResponse": {
|
||||||
|
"SubscribeResult": {
|
||||||
|
"SubscriptionArn": subscription.arn,
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "a8763b99-33a7-11df-a9b7-05d48da6f042"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def unsubscribe(self):
|
||||||
|
subscription_arn = self._get_param('SubscriptionArn')
|
||||||
|
sns_backend.unsubscribe(subscription_arn)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"UnsubscribeResponse": {
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "a8763b99-33a7-11df-a9b7-05d48da6f042"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def list_subscriptions(self):
|
||||||
|
subscriptions = sns_backend.list_subscriptions()
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"ListSubscriptionsResponse": {
|
||||||
|
"ListSubscriptionsResult": {
|
||||||
|
"Subscriptions": [{
|
||||||
|
"TopicArn": subscription.topic.arn,
|
||||||
|
"Protocol": subscription.protocol,
|
||||||
|
"SubscriptionArn": subscription.arn,
|
||||||
|
"Owner": subscription.topic.account_id,
|
||||||
|
"Endpoint": subscription.endpoint,
|
||||||
|
} for subscription in subscriptions]
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def list_subscriptions_by_topic(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
subscriptions = sns_backend.list_subscriptions(topic_arn)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"ListSubscriptionsByTopicResponse": {
|
||||||
|
"ListSubscriptionsByTopicResult": {
|
||||||
|
"Subscriptions": [{
|
||||||
|
"TopicArn": subscription.topic.arn,
|
||||||
|
"Protocol": subscription.protocol,
|
||||||
|
"SubscriptionArn": subscription.arn,
|
||||||
|
"Owner": subscription.topic.account_id,
|
||||||
|
"Endpoint": subscription.endpoint,
|
||||||
|
} for subscription in subscriptions]
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def publish(self):
|
||||||
|
topic_arn = self._get_param('TopicArn')
|
||||||
|
message = self._get_param('Message')
|
||||||
|
message_id = sns_backend.publish(topic_arn, message)
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"PublishResponse": {
|
||||||
|
"PublishResult": {
|
||||||
|
"MessageId": message_id,
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RequestId": "384ac68d-3775-11df-8963-01868b7c937a",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
9
moto/sns/urls.py
Normal file
9
moto/sns/urls.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from .responses import SNSResponse
|
||||||
|
|
||||||
|
url_bases = [
|
||||||
|
"https?://sns.(.+).amazonaws.com"
|
||||||
|
]
|
||||||
|
|
||||||
|
url_paths = {
|
||||||
|
'{0}/$': SNSResponse().dispatch,
|
||||||
|
}
|
10
moto/sns/utils.py
Normal file
10
moto/sns/utils.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def make_arn_for_topic(account_id, name):
|
||||||
|
return "arn:aws:sns:us-east-1:{0}:{1}".format(account_id, name)
|
||||||
|
|
||||||
|
|
||||||
|
def make_arn_for_subscription(topic_arn):
|
||||||
|
subscription_id = uuid.uuid4()
|
||||||
|
return "{0}:{1}".format(topic_arn, subscription_id)
|
62
tests/test_sns/test_publishing.py
Normal file
62
tests/test_sns/test_publishing.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
from urlparse import parse_qs
|
||||||
|
|
||||||
|
import boto
|
||||||
|
from freezegun import freeze_time
|
||||||
|
import httpretty
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto import mock_sns, mock_sqs
|
||||||
|
|
||||||
|
|
||||||
|
@mock_sqs
|
||||||
|
@mock_sns
|
||||||
|
def test_publish_to_sqs():
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("some-topic")
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topic_arn = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"][0]['TopicArn']
|
||||||
|
|
||||||
|
sqs_conn = boto.connect_sqs()
|
||||||
|
sqs_conn.create_queue("test-queue")
|
||||||
|
|
||||||
|
conn.subscribe(topic_arn, "sqs", "arn:aws:sqs:us-east-1:123456789012:test-queue")
|
||||||
|
|
||||||
|
conn.publish(topic=topic_arn, message="my message")
|
||||||
|
|
||||||
|
queue = sqs_conn.get_queue("test-queue")
|
||||||
|
message = queue.read(1)
|
||||||
|
message.get_body().should.equal('my message')
|
||||||
|
|
||||||
|
|
||||||
|
@freeze_time("2013-01-01")
|
||||||
|
@mock_sns
|
||||||
|
def test_publish_to_http():
|
||||||
|
httpretty.HTTPretty.register_uri(
|
||||||
|
method="POST",
|
||||||
|
uri="http://example.com/foobar",
|
||||||
|
)
|
||||||
|
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("some-topic")
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topic_arn = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"][0]['TopicArn']
|
||||||
|
|
||||||
|
conn.subscribe(topic_arn, "http", "http://example.com/foobar")
|
||||||
|
|
||||||
|
response = conn.publish(topic=topic_arn, message="my message", subject="my subject")
|
||||||
|
message_id = response['PublishResponse']['PublishResult']['MessageId']
|
||||||
|
|
||||||
|
last_request = httpretty.last_request()
|
||||||
|
last_request.method.should.equal("POST")
|
||||||
|
parse_qs(last_request.body).should.equal({
|
||||||
|
"Type": ["Notification"],
|
||||||
|
"MessageId": [message_id],
|
||||||
|
"TopicArn": ["arn:aws:sns:us-east-1:123456789012:some-topic"],
|
||||||
|
"Subject": ["my subject"],
|
||||||
|
"Message": ["my message"],
|
||||||
|
"Timestamp": ["2013-01-01T00:00:00Z"],
|
||||||
|
"SignatureVersion": ["1"],
|
||||||
|
"Signature": ["EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc="],
|
||||||
|
"SigningCertURL": ["https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"],
|
||||||
|
"UnsubscribeURL": ["https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789012:some-topic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"],
|
||||||
|
})
|
0
tests/test_sns/test_server.py
Normal file
0
tests/test_sns/test_server.py
Normal file
49
tests/test_sns/test_subscriptions.py
Normal file
49
tests/test_sns/test_subscriptions.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import boto
|
||||||
|
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto import mock_sns
|
||||||
|
|
||||||
|
|
||||||
|
@mock_sns
|
||||||
|
def test_creating_subscription():
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("some-topic")
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topic_arn = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"][0]['TopicArn']
|
||||||
|
|
||||||
|
conn.subscribe(topic_arn, "http", "http://example.com/")
|
||||||
|
|
||||||
|
subscriptions = conn.get_all_subscriptions()["ListSubscriptionsResponse"]["ListSubscriptionsResult"]["Subscriptions"]
|
||||||
|
subscriptions.should.have.length_of(1)
|
||||||
|
subscription = subscriptions[0]
|
||||||
|
subscription["TopicArn"].should.equal(topic_arn)
|
||||||
|
subscription["Protocol"].should.equal("http")
|
||||||
|
subscription["SubscriptionArn"].should.contain(topic_arn)
|
||||||
|
subscription["Endpoint"].should.equal("http://example.com/")
|
||||||
|
|
||||||
|
# Now unsubscribe the subscription
|
||||||
|
conn.unsubscribe(subscription["SubscriptionArn"])
|
||||||
|
|
||||||
|
# And there should be zero subscriptions left
|
||||||
|
subscriptions = conn.get_all_subscriptions()["ListSubscriptionsResponse"]["ListSubscriptionsResult"]["Subscriptions"]
|
||||||
|
subscriptions.should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_sns
|
||||||
|
def test_getting_subscriptions_by_topic():
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("topic1")
|
||||||
|
conn.create_topic("topic2")
|
||||||
|
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topics = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"]
|
||||||
|
topic1_arn = topics[0]['TopicArn']
|
||||||
|
topic2_arn = topics[1]['TopicArn']
|
||||||
|
|
||||||
|
conn.subscribe(topic1_arn, "http", "http://example1.com/")
|
||||||
|
conn.subscribe(topic2_arn, "http", "http://example2.com/")
|
||||||
|
|
||||||
|
topic1_subscriptions = conn.get_all_subscriptions_by_topic(topic1_arn)["ListSubscriptionsByTopicResponse"]["ListSubscriptionsByTopicResult"]["Subscriptions"]
|
||||||
|
topic1_subscriptions.should.have.length_of(1)
|
||||||
|
topic1_subscriptions[0]['Endpoint'].should.equal("http://example1.com/")
|
54
tests/test_sns/test_topics.py
Normal file
54
tests/test_sns/test_topics.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import boto
|
||||||
|
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto import mock_sns
|
||||||
|
from moto.sns.models import DEFAULT_TOPIC_POLICY, DEFAULT_EFFECTIVE_DELIVERY_POLICY
|
||||||
|
|
||||||
|
|
||||||
|
@mock_sns
|
||||||
|
def test_create_and_delete_topic():
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("some-topic")
|
||||||
|
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topics = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"]
|
||||||
|
topics.should.have.length_of(1)
|
||||||
|
topics[0]['TopicArn'].should.equal("arn:aws:sns:us-east-1:123456789012:some-topic")
|
||||||
|
|
||||||
|
# Delete the topic
|
||||||
|
conn.delete_topic(topics[0]['TopicArn'])
|
||||||
|
|
||||||
|
# And there should now be 0 topics
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topics = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"]
|
||||||
|
topics.should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_sns
|
||||||
|
def test_topic_attributes():
|
||||||
|
conn = boto.connect_sns()
|
||||||
|
conn.create_topic("some-topic")
|
||||||
|
|
||||||
|
topics_json = conn.get_all_topics()
|
||||||
|
topic_arn = topics_json["ListTopicsResponse"]["ListTopicsResult"]["Topics"][0]['TopicArn']
|
||||||
|
|
||||||
|
attributes = conn.get_topic_attributes(topic_arn)['GetTopicAttributesResponse']['GetTopicAttributesResult']['Attributes']
|
||||||
|
attributes["TopicArn"].should.equal("arn:aws:sns:us-east-1:123456789012:some-topic")
|
||||||
|
attributes["Owner"].should.equal(123456789012)
|
||||||
|
attributes["Policy"].should.equal(DEFAULT_TOPIC_POLICY)
|
||||||
|
attributes["DisplayName"].should.equal("")
|
||||||
|
attributes["SubscriptionsPending"].should.equal(0)
|
||||||
|
attributes["SubscriptionsConfirmed"].should.equal(0)
|
||||||
|
attributes["SubscriptionsDeleted"].should.equal(0)
|
||||||
|
attributes["DeliveryPolicy"].should.equal("")
|
||||||
|
attributes["EffectiveDeliveryPolicy"].should.equal(DEFAULT_EFFECTIVE_DELIVERY_POLICY)
|
||||||
|
|
||||||
|
conn.set_topic_attributes(topic_arn, "Policy", {"foo": "bar"})
|
||||||
|
conn.set_topic_attributes(topic_arn, "DisplayName", "My display name")
|
||||||
|
conn.set_topic_attributes(topic_arn, "DeliveryPolicy", {"http": {"defaultHealthyRetryPolicy": {"numRetries": 5}}})
|
||||||
|
|
||||||
|
attributes = conn.get_topic_attributes(topic_arn)['GetTopicAttributesResponse']['GetTopicAttributesResult']['Attributes']
|
||||||
|
attributes["Policy"].should.equal("{'foo': 'bar'}")
|
||||||
|
attributes["DisplayName"].should.equal("My display name")
|
||||||
|
attributes["DeliveryPolicy"].should.equal("{'http': {'defaultHealthyRetryPolicy': {'numRetries': 5}}}")
|
Loading…
Reference in New Issue
Block a user