Skip to content

Commit

Permalink
SNS: Improve PlatformApplication error handling (#6953)
Browse files Browse the repository at this point in the history
  • Loading branch information
bblommers authored Oct 26, 2023
1 parent 9c0724e commit 8fb053f
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 114 deletions.
2 changes: 1 addition & 1 deletion moto/sns/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class DuplicateSnsEndpointError(SNSException):
code = 400

def __init__(self, message: str):
super().__init__("DuplicateEndpoint", message)
super().__init__("InvalidParameter", message)


class SnsEndpointDisabled(SNSException):
Expand Down
13 changes: 8 additions & 5 deletions moto/sns/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ def enabled(self) -> bool:

def publish(self, message: str) -> str:
if not self.enabled:
raise SnsEndpointDisabled(f"Endpoint {self.id} disabled")
raise SnsEndpointDisabled("Endpoint is disabled")

# This is where we would actually send a message
message_id = str(mock_random.uuid4())
Expand Down Expand Up @@ -646,7 +646,7 @@ def get_application(self, arn: str) -> PlatformApplication:
try:
return self.applications[arn]
except KeyError:
raise SNSNotFoundError(f"Application with arn {arn} not found")
raise SNSNotFoundError("PlatformApplication does not exist")

def set_platform_application_attributes(
self, arn: str, attributes: Dict[str, Any]
Expand All @@ -673,13 +673,16 @@ def create_platform_endpoint(
) -> PlatformEndpoint:
for endpoint in self.platform_endpoints.values():
if token == endpoint.token:
if (
same_user_data = custom_user_data == endpoint.custom_user_data
same_attrs = (
attributes.get("Enabled", "").lower()
== endpoint.attributes["Enabled"]
):
)

if same_user_data and same_attrs:
return endpoint
raise DuplicateSnsEndpointError(
f"Duplicate endpoint token with different attributes: {token}"
f"Invalid parameter: Token Reason: Endpoint {endpoint.arn} already exists with the same Token, but different attributes."
)
platform_endpoint = PlatformEndpoint(
self.account_id,
Expand Down
1 change: 1 addition & 0 deletions moto/sns/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ def create_platform_endpoint(self) -> str:

def list_endpoints_by_platform_application(self) -> str:
application_arn = self._get_param("PlatformApplicationArn")
self.backend.get_application(application_arn)
endpoints = self.backend.list_endpoints_by_platform_application(application_arn)

if self.request_json:
Expand Down
49 changes: 48 additions & 1 deletion tests/test_sns/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,48 @@
# This file is intentionally left blank.
import boto3
import botocore
import os
from functools import wraps
from moto import mock_sns, mock_sts
from unittest import SkipTest


def sns_aws_verified(func):
"""
Function that is verified to work against AWS.
Can be run against AWS at any time by setting:
MOTO_TEST_ALLOW_AWS_REQUEST=true
If this environment variable is not set, the function runs in a `mock_ses` context.
"""

@wraps(func)
def pagination_wrapper():
allow_aws_request = (
os.environ.get("MOTO_TEST_ALLOW_AWS_REQUEST", "false").lower() == "true"
)

if allow_aws_request:
ssm = boto3.client("ssm", "us-east-1")
try:
param = ssm.get_parameter(
Name="/moto/tests/ses/firebase_api_key", WithDecryption=True
)
api_key = param["Parameter"]["Value"]
resp = func(api_key)
except botocore.exceptions.ClientError:
# SNS tests try to create a PlatformApplication that connects to GCM
# (Google Cloud Messaging, also known as Firebase Messaging)
# That requires an account and an API key
# If the API key has not been configured in SSM, we'll just skip the test
#
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns/client/create_platform_application.html
# AWS calls it 'API key', but Firebase calls it Server Key
#
# https://stackoverflow.com/a/75896532/13245310
raise SkipTest("Can't execute SNS tests without Firebase API key")
else:
with mock_sns(), mock_sts():
resp = func("mock_api_key")
return resp

return pagination_wrapper
Loading

0 comments on commit 8fb053f

Please sign in to comment.