diff --git a/moto/backends.py b/moto/backends.py
index b45e0fa5e..b46d56c06 100644
--- a/moto/backends.py
+++ b/moto/backends.py
@@ -8,6 +8,7 @@ from moto.ec2 import ec2_backend
from moto.elb import elb_backend
from moto.emr import emr_backend
from moto.glacier import glacier_backend
+from moto.iam import iam_backend
from moto.kinesis import kinesis_backend
from moto.kms import kms_backend
from moto.rds import rds_backend
@@ -15,6 +16,7 @@ from moto.redshift import redshift_backend
from moto.s3 import s3_backend
from moto.s3bucket_path import s3bucket_path_backend
from moto.ses import ses_backend
+from moto.sns import sns_backend
from moto.sqs import sqs_backend
from moto.sts import sts_backend
from moto.route53 import route53_backend
@@ -29,6 +31,7 @@ BACKENDS = {
'elb': elb_backend,
'emr': emr_backend,
'glacier': glacier_backend,
+ 'iam': iam_backend,
'kinesis': kinesis_backend,
'kms': kms_backend,
'redshift': redshift_backend,
@@ -36,6 +39,7 @@ BACKENDS = {
's3': s3_backend,
's3bucket_path': s3bucket_path_backend,
'ses': ses_backend,
+ 'sns': sns_backend,
'sqs': sqs_backend,
'sts': sts_backend,
'route53': route53_backend
diff --git a/moto/iam/responses.py b/moto/iam/responses.py
index be1601a83..b490ee302 100644
--- a/moto/iam/responses.py
+++ b/moto/iam/responses.py
@@ -559,8 +559,7 @@ USER_TEMPLATE = """<{{ action }}UserResponse>
{{ user.path }}
{{ user.name }}
{{ user.id }}
- arn:aws:iam::123456789012:user/{{ user.path }}/{{ user.name }}
-
+ arn:aws:iam::123456789012:user/{{ user.path }}/{{ user.name }}
{{ action }}UserResult>
diff --git a/moto/server.py b/moto/server.py
index 4a7de1a70..d32c6f45e 100644
--- a/moto/server.py
+++ b/moto/server.py
@@ -1,11 +1,15 @@
from __future__ import unicode_literals
+import json
import re
import sys
import argparse
+from six.moves.urllib.parse import urlencode
+
from threading import Lock
from flask import Flask
+from flask.testing import FlaskClient
from werkzeug.routing import BaseConverter
from werkzeug.serving import run_simple
@@ -60,18 +64,38 @@ class RegexConverter(BaseConverter):
self.regex = items[0]
+class AWSTestHelper(FlaskClient):
+
+ def action_data(self, action_name, **kwargs):
+ """
+ Method calls resource with action_name and returns data of response.
+ """
+ opts = {"Action": action_name}
+ opts.update(kwargs)
+ res = self.get("/?{0}".format(urlencode(opts)),
+ headers={"Host": "{0}.us-east-1.amazonaws.com".format(self.application.service)})
+ return res.data.decode("utf-8")
+
+ def action_json(self, action_name, **kwargs):
+ """
+ Method calls resource with action_name and returns object obtained via
+ deserialization of output.
+ """
+ return json.loads(self.action_data(action_name, **kwargs))
+
+
def create_backend_app(service):
from werkzeug.routing import Map
# Create the backend_app
backend_app = Flask(__name__)
backend_app.debug = True
+ backend_app.service = service
# Reset view functions to reset the app
backend_app.view_functions = {}
backend_app.url_map = Map()
backend_app.url_map.converters['regex'] = RegexConverter
-
backend = BACKENDS[service]
for url_path, handler in backend.flask_paths.items():
if handler.__name__ == 'dispatch':
@@ -91,6 +115,7 @@ def create_backend_app(service):
view_func=convert_flask_to_httpretty_response(handler),
)
+ backend_app.test_client_class = AWSTestHelper
return backend_app
diff --git a/tests/test_cloudformation/test_server.py b/tests/test_cloudformation/test_server.py
index 47a094630..ffbc5c608 100644
--- a/tests/test_cloudformation/test_server.py
+++ b/tests/test_cloudformation/test_server.py
@@ -19,23 +19,13 @@ def test_cloudformation_server_get():
template_body = {
"Resources": {},
}
- res = test_client.get(
- '/?{0}'.format(
- urlencode({
- "Action": "CreateStack",
- "StackName": stack_name,
- "TemplateBody": json.dumps(template_body)
- })
- ),
- headers={"Host": "cloudformation.us-east-1.amazonaws.com"}
- )
- stack_id = json.loads(res.data.decode("utf-8"))["CreateStackResponse"]["CreateStackResult"]["StackId"]
+ res = test_client.action_json("CreateStack", StackName=stack_name,
+ TemplateBody=json.dumps(template_body))
+ stack_id = res["CreateStackResponse"]["CreateStackResult"]["StackId"]
- res = test_client.get(
- '/?Action=ListStacks',
- headers={"Host": "cloudformation.us-east-1.amazonaws.com"}
- )
- stacks = re.search("(.*)", res.data.decode('utf-8'))
+ data = test_client.action_data("ListStacks")
+
+ stacks = re.search("(.*)", data)
list_stack_id = stacks.groups()[0]
assert stack_id == list_stack_id
diff --git a/tests/test_iam/test_server.py b/tests/test_iam/test_server.py
new file mode 100644
index 000000000..1b1c3bfe3
--- /dev/null
+++ b/tests/test_iam/test_server.py
@@ -0,0 +1,25 @@
+from __future__ import unicode_literals
+
+import json
+
+import re
+import sure # noqa
+
+import moto.server as server
+
+'''
+Test the different server responses
+'''
+
+
+def test_iam_server_get():
+ backend = server.create_backend_app("iam")
+ test_client = backend.test_client()
+
+ group_data = test_client.action_data("CreateGroup", GroupName="test group", Path="/")
+ group_id = re.search("(.*)", group_data).groups()[0]
+
+ groups_data = test_client.action_data("ListGroups")
+ groups_ids = re.findall("(.*)", groups_data)
+
+ assert group_id in groups_ids
\ No newline at end of file
diff --git a/tests/test_sns/test_server.py b/tests/test_sns/test_server.py
index baffc4882..1813f7798 100644
--- a/tests/test_sns/test_server.py
+++ b/tests/test_sns/test_server.py
@@ -1 +1,24 @@
from __future__ import unicode_literals
+
+import json
+
+import re
+import sure # noqa
+
+import moto.server as server
+
+'''
+Test the different server responses
+'''
+
+
+def test_sns_server_get():
+ backend = server.create_backend_app("sns")
+ test_client = backend.test_client()
+
+ topic_data = test_client.action_json("CreateTopic", Name="test topic")
+ topic_arn = topic_data["CreateTopicResponse"]["CreateTopicResult"]["TopicArn"]
+ topics_data = test_client.action_json("ListTopics")
+ topics_arns = [t["TopicArn"] for t in topics_data["ListTopicsResponse"]["ListTopicsResult"]["Topics"]]
+
+ assert topic_arn in topics_arns
\ No newline at end of file