diff options
| author | Barry Warsaw | 2011-04-20 04:51:25 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-04-20 04:51:25 -0400 |
| commit | f9dfad95995685c18adf509630e1f6307ea332a1 (patch) | |
| tree | 446ad657c2b1d2e7ba6fe41689fd1efb18752bb0 /src/mailman/testing/helpers.py | |
| parent | 6b4a3ebc37e5e11d74161fed12b3cf75eca6c339 (diff) | |
| download | mailman-f9dfad95995685c18adf509630e1f6307ea332a1.tar.gz mailman-f9dfad95995685c18adf509630e1f6307ea332a1.tar.zst mailman-f9dfad95995685c18adf509630e1f6307ea332a1.zip | |
Diffstat (limited to 'src/mailman/testing/helpers.py')
| -rw-r--r-- | src/mailman/testing/helpers.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index bd52d5d6e..b5df649e0 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ 'TestableMaster', + 'call_api', 'digest_mbox', 'event_subscribers', 'get_lmtp_client', @@ -33,6 +34,7 @@ __all__ = [ import os +import json import time import errno import signal @@ -41,7 +43,11 @@ import smtplib import datetime import threading +from base64 import b64encode from contextlib import contextmanager +from httplib2 import Http +from urllib import urlencode +from urllib2 import HTTPError from zope import event from zope.component import getUtility @@ -243,6 +249,53 @@ def wait_for_webservice(): break +def call_api(url, data=None, method=None, username=None, password=None): + """'Call a URL with a given HTTP method and return the resulting object. + + The object will have been JSON decoded. + + :param url: The url to open, read, and print. + :type url: string + :param data: Data to use to POST to a URL. + :type data: dict + :param method: Alternative HTTP method to use. + :type method: str + :param username: The HTTP Basic Auth user name. None means use the value + from the configuration. + :type username: str + :param password: The HTTP Basic Auth password. None means use the value + from the configuration. + :type username: str + :return: The response object and the JSON decoded content, if there is + any. If not, the second tuple item will be None. + :raises HTTPError: when a non-2xx return code is received. + """ + headers = {} + if data is not None: + data = urlencode(data, doseq=True) + headers['Content-Type'] = 'application/x-www-form-urlencoded' + if method is None: + if data is None: + method = 'GET' + else: + method = 'POST' + method = method.upper() + basic_auth = '{0}:{1}'.format( + (config.webservice.admin_user if username is None else username), + (config.webservice.admin_pass if password is None else password)) + headers['Authorization'] = 'Basic ' + b64encode(basic_auth) + response, content = Http().request(url, method, data, headers) + # If we did not get a 2xx status code, make this look like a urllib2 + # exception, for backward compatibility with existing doctests. + if response.status // 100 != 2: + raise HTTPError(url, response.status, content, response, None) + if len(content) == 0: + return None, response + # XXX Workaround http://bugs.python.org/issue10038 + content = unicode(content) + return json.loads(content), response + + @contextmanager def event_subscribers(*subscribers): |
