From 442141fa04fe6dd2a823ed806e013c48a2769697 Mon Sep 17 00:00:00 2001 From: Jay Zoldak Date: Thu, 11 Apr 2013 14:08:32 -0400 Subject: [PATCH 1/2] Create a mock comment service that will listen for HTTP requests on a port --- .../tests/mock_cs_server/__init__.py | 0 .../tests/mock_cs_server/mock_cs_server.py | 77 +++++++++++++++++++ .../mock_cs_server/test_mock_cs_server.py | 61 +++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 lms/djangoapps/django_comment_client/tests/mock_cs_server/__init__.py create mode 100644 lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py create mode 100644 lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py diff --git a/lms/djangoapps/django_comment_client/tests/mock_cs_server/__init__.py b/lms/djangoapps/django_comment_client/tests/mock_cs_server/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py b/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py new file mode 100644 index 0000000000..d2601fe70d --- /dev/null +++ b/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py @@ -0,0 +1,77 @@ +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +import json +import urlparse +from logging import getLogger +logger = getLogger(__name__) + + +class MockCommentServiceRequestHandler(BaseHTTPRequestHandler): + ''' + A handler for Comment Service POST requests. + ''' + protocol = "HTTP/1.0" + + def do_POST(self): + ''' + Handle a POST request from the client + Used by the APIs for comment threads, commentables, comments, + subscriptions, commentables, users + ''' + # Retrieve the POST data into a dict. + # It should have been sent in json format + length = int(self.headers.getheader('content-length')) + data_string = self.rfile.read(length) + post_dict = json.loads(data_string) + + # Log the request + logger.debug("Comment Service received POST request %s to path %s" % + (json.dumps(post_dict), self.path)) + + # Every good post has at least an API key + if 'api_key' in post_dict: + response = self.server._response_str + # Log the response + logger.debug("Comment Service: sending response %s" % json.dumps(response)) + + # Send a response back to the client + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.end_headers() + self.wfile.write(response) + + else: + # Respond with failure + self.send_response(500, 'Bad Request: does not contain API key') + self.send_header('Content-type', 'text/plain') + self.end_headers() + return False + + +class MockCommentServiceServer(HTTPServer): + ''' + A mock Comment Service server that responds + to POST requests to localhost. + ''' + def __init__(self, port_num, + response={'username': 'new', 'external_id': 1}): + ''' + Initialize the mock Comment Service server instance. + *port_num* is the localhost port to listen to + *response* is a dictionary that will be JSON-serialized + and sent in response to comment service requests. + ''' + self._response_str = json.dumps(response) + + handler = MockCommentServiceRequestHandler + address = ('', port_num) + HTTPServer.__init__(self, address, handler) + + def shutdown(self): + ''' + Stop the server and free up the port + ''' + # First call superclass shutdown() + HTTPServer.shutdown(self) + + # We also need to manually close the socket + self.socket.close() diff --git a/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py b/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py new file mode 100644 index 0000000000..bf86f89dc7 --- /dev/null +++ b/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py @@ -0,0 +1,61 @@ +import mock +import unittest +import threading +import json +import urllib +import urllib2 +from mock_cs_server import MockCommentServiceServer, MockCommentServiceRequestHandler +from nose.plugins.skip import SkipTest + + +class MockCommentServiceServerTest(unittest.TestCase): + ''' + A mock version of the Comment Service server that listens on a local + port and responds with pre-defined grade messages. + ''' + + def setUp(self): + # This is a test of the test setup, + # so it does not need to run as part of the unit test suite + # You can re-enable it by commenting out the line below + # raise SkipTest + + # Create the server + server_port = 4567 + self.server_url = 'http://127.0.0.1:%d' % server_port + + # Start up the server and tell it that by default it should + # return this as its json response + self.expected_response = {'username': 'user100', 'external_id': '4'} + self.server = MockCommentServiceServer(port_num=server_port, + response=self.expected_response) + + # Start the server in a separate daemon thread + server_thread = threading.Thread(target=self.server.serve_forever) + server_thread.daemon = True + server_thread.start() + + def tearDown(self): + # Stop the server, freeing up the port + self.server.shutdown() + + def test_new_user_request(self): + """ + Test the mock comment service using an example + of how you would create a new user + """ + # Send a request + values = {'username': u'user100', 'api_key': 'TEST_API_KEY', + 'external_id': '4', 'email': u'user100@edx.org'} + data = json.dumps(values) + headers = {'Content-Type': 'application/json', 'Content-Length': len(data)} + req = urllib2.Request(self.server_url + '/api/v1/users/4', data, headers) + + # Send the request to the mock cs server + response = urllib2.urlopen(req) + + # Receive the reply from the mock cs server + response_dict = json.loads(response.read()) + + # You should have received the response specified in the setup above + self.assertEqual(response_dict, self.expected_response) From 88852c4b260567c045154ea371c4c601f621cb6f Mon Sep 17 00:00:00 2001 From: Jay Zoldak Date: Thu, 11 Apr 2013 14:11:30 -0400 Subject: [PATCH 2/2] pep8 and pylint cleanup of new files --- .../tests/mock_cs_server/mock_cs_server.py | 1 - .../tests/mock_cs_server/test_mock_cs_server.py | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py b/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py index d2601fe70d..6fbc88fb31 100644 --- a/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py +++ b/lms/djangoapps/django_comment_client/tests/mock_cs_server/mock_cs_server.py @@ -1,6 +1,5 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler import json -import urlparse from logging import getLogger logger = getLogger(__name__) diff --git a/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py b/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py index bf86f89dc7..9b1977cbff 100644 --- a/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py +++ b/lms/djangoapps/django_comment_client/tests/mock_cs_server/test_mock_cs_server.py @@ -1,10 +1,8 @@ -import mock import unittest import threading import json -import urllib import urllib2 -from mock_cs_server import MockCommentServiceServer, MockCommentServiceRequestHandler +from mock_cs_server import MockCommentServiceServer from nose.plugins.skip import SkipTest @@ -18,7 +16,7 @@ class MockCommentServiceServerTest(unittest.TestCase): # This is a test of the test setup, # so it does not need to run as part of the unit test suite # You can re-enable it by commenting out the line below - # raise SkipTest + raise SkipTest # Create the server server_port = 4567