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 }} 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