Added in publish by phone number
This commit is contained in:
parent
aad408b8ac
commit
56c65bc67c
@ -221,6 +221,12 @@ class SNSBackend(BaseBackend):
|
||||
except KeyError:
|
||||
raise SNSNotFoundError("Topic with arn {0} not found".format(arn))
|
||||
|
||||
def get_topic_from_phone_number(self, number):
|
||||
for subscription in self.subscriptions.values():
|
||||
if subscription.protocol == 'sms' and subscription.endpoint == number:
|
||||
return subscription.topic.arn
|
||||
raise SNSNotFoundError('Could not find valid subscription')
|
||||
|
||||
def set_topic_attribute(self, topic_arn, attribute_name, attribute_value):
|
||||
topic = self.get_topic(topic_arn)
|
||||
setattr(topic, attribute_name, attribute_value)
|
||||
|
@ -6,6 +6,8 @@ from collections import defaultdict
|
||||
from moto.core.responses import BaseResponse
|
||||
from moto.core.utils import camelcase_to_underscores
|
||||
from .models import sns_backends
|
||||
from .exceptions import SNSNotFoundError
|
||||
from .utils import is_e164
|
||||
|
||||
|
||||
class SNSResponse(BaseResponse):
|
||||
@ -136,6 +138,13 @@ class SNSResponse(BaseResponse):
|
||||
topic_arn = self._get_param('TopicArn')
|
||||
endpoint = self._get_param('Endpoint')
|
||||
protocol = self._get_param('Protocol')
|
||||
|
||||
if protocol == 'sms' and not is_e164(endpoint):
|
||||
return self._error(
|
||||
'InvalidParameter',
|
||||
'Phone number does not meet the E164 format'
|
||||
), dict(status=400)
|
||||
|
||||
subscription = self.backend.subscribe(topic_arn, endpoint, protocol)
|
||||
|
||||
if self.request_json:
|
||||
@ -229,7 +238,28 @@ class SNSResponse(BaseResponse):
|
||||
def publish(self):
|
||||
target_arn = self._get_param('TargetArn')
|
||||
topic_arn = self._get_param('TopicArn')
|
||||
arn = target_arn if target_arn else topic_arn
|
||||
phone_number = self._get_param('PhoneNumber')
|
||||
if phone_number is not None:
|
||||
# Check phone is correct syntax (e164)
|
||||
if not is_e164(phone_number):
|
||||
return self._error(
|
||||
'InvalidParameter',
|
||||
'Phone number does not meet the E164 format'
|
||||
), dict(status=400)
|
||||
|
||||
# Look up topic arn by phone number
|
||||
try:
|
||||
arn = self.backend.get_topic_from_phone_number(phone_number)
|
||||
except SNSNotFoundError:
|
||||
return self._error(
|
||||
'ParameterValueInvalid',
|
||||
'Could not find topic associated with phone number'
|
||||
), dict(status=400)
|
||||
elif target_arn is not None:
|
||||
arn = target_arn
|
||||
else:
|
||||
arn = topic_arn
|
||||
|
||||
message = self._get_param('Message')
|
||||
message_id = self.backend.publish(arn, message)
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
import uuid
|
||||
|
||||
E164_REGEX = re.compile(r'^\+?[1-9]\d{1,14}$')
|
||||
|
||||
|
||||
def make_arn_for_topic(account_id, name, region_name):
|
||||
return "arn:aws:sns:{0}:{1}:{2}".format(region_name, account_id, name)
|
||||
@ -9,3 +12,7 @@ def make_arn_for_topic(account_id, name, region_name):
|
||||
def make_arn_for_subscription(topic_arn):
|
||||
subscription_id = uuid.uuid4()
|
||||
return "{0}:{1}".format(topic_arn, subscription_id)
|
||||
|
||||
|
||||
def is_e164(number):
|
||||
return E164_REGEX.match(number) is not None
|
||||
|
@ -10,6 +10,7 @@ from freezegun import freeze_time
|
||||
import sure # noqa
|
||||
|
||||
from moto.packages.responses import responses
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_sns, mock_sqs
|
||||
from freezegun import freeze_time
|
||||
|
||||
@ -43,6 +44,49 @@ def test_publish_to_sqs():
|
||||
acquired_message.should.equal(expected)
|
||||
|
||||
|
||||
@mock_sns
|
||||
def test_publish_sms():
|
||||
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']
|
||||
|
||||
client.subscribe(
|
||||
TopicArn=arn,
|
||||
Protocol='sms',
|
||||
Endpoint='+15551234567'
|
||||
)
|
||||
|
||||
result = client.publish(PhoneNumber="+15551234567", Message="my message")
|
||||
result.should.contain('MessageId')
|
||||
|
||||
|
||||
@mock_sns
|
||||
def test_publish_bad_sms():
|
||||
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']
|
||||
|
||||
client.subscribe(
|
||||
TopicArn=arn,
|
||||
Protocol='sms',
|
||||
Endpoint='+15551234567'
|
||||
)
|
||||
|
||||
try:
|
||||
# Test invalid number
|
||||
client.publish(PhoneNumber="NAA+15551234567", Message="my message")
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('InvalidParameter')
|
||||
|
||||
try:
|
||||
# Test not found number
|
||||
client.publish(PhoneNumber="+44001234567", Message="my message")
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('ParameterValueInvalid')
|
||||
|
||||
|
||||
@mock_sqs
|
||||
@mock_sns
|
||||
def test_publish_to_sqs_dump_json():
|
||||
|
@ -11,6 +11,39 @@ from moto import mock_sns
|
||||
from moto.sns.models import DEFAULT_PAGE_SIZE
|
||||
|
||||
|
||||
@mock_sns
|
||||
def test_subscribe_sms():
|
||||
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']
|
||||
|
||||
resp = client.subscribe(
|
||||
TopicArn=arn,
|
||||
Protocol='sms',
|
||||
Endpoint='+15551234567'
|
||||
)
|
||||
resp.should.contain('SubscriptionArn')
|
||||
|
||||
|
||||
@mock_sns
|
||||
def test_subscribe_bad_sms():
|
||||
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']
|
||||
|
||||
try:
|
||||
# Test invalid number
|
||||
client.subscribe(
|
||||
TopicArn=arn,
|
||||
Protocol='sms',
|
||||
Endpoint='NAA+15551234567'
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('InvalidParameter')
|
||||
|
||||
|
||||
@mock_sns
|
||||
def test_creating_subscription():
|
||||
conn = boto3.client('sns', region_name='us-east-1')
|
||||
|
Loading…
Reference in New Issue
Block a user