Add query_parameters field
This adds a query_parameters field which can be used to add query parameters to the url of the test in which it is used. It is a dict in a form suitable for being passed to the urlencode() method. This change is cumbersome because urlencoded in python2 and 3 have different behaviors: In python2 a utf-8 encoded string is required. In 3 it will figure out the right thing. So we here we just encode. We also need to deal with the fact that a numeral in YAML will be provided to Python as a numeric value and we need to stringify that in a version independent fashion.
This commit is contained in:
@@ -39,6 +39,9 @@ Many of these items allow substitutions (explained below).
|
|||||||
fully qualified URL (with host and scheme). If not qualified the
|
fully qualified URL (with host and scheme). If not qualified the
|
||||||
test builder will be responsible for determining host and scheme.
|
test builder will be responsible for determining host and scheme.
|
||||||
**Required**
|
**Required**
|
||||||
|
* ``query_parameters``: An optional dictionary of query parameters
|
||||||
|
that will be added to the ``url``. If there is an existing set of
|
||||||
|
query parameters they wil be extended.
|
||||||
* ``method``: The request method to use. Defaults to ``GET``.
|
* ``method``: The request method to use. Defaults to ``GET``.
|
||||||
* ``status``: The expected response status code. The default is
|
* ``status``: The expected response status code. The default is
|
||||||
``200``. If necessary you may indicate multiple response codes
|
``200``. If necessary you may indicate multiple response codes
|
||||||
@@ -110,6 +113,7 @@ character must be used at both ends.
|
|||||||
All of these variables may be used in all of the following fields:
|
All of these variables may be used in all of the following fields:
|
||||||
|
|
||||||
* ``url``
|
* ``url``
|
||||||
|
* ``query_parameters``
|
||||||
* ``data``
|
* ``data``
|
||||||
* ``request_headers``
|
* ``request_headers``
|
||||||
* ``response_strings``
|
* ``response_strings``
|
||||||
|
@@ -59,6 +59,7 @@ BASE_TEST = {
|
|||||||
'url': '',
|
'url': '',
|
||||||
'status': '200',
|
'status': '200',
|
||||||
'request_headers': {},
|
'request_headers': {},
|
||||||
|
'query_parameters': {},
|
||||||
'data': '',
|
'data': '',
|
||||||
'xfail': False,
|
'xfail': False,
|
||||||
'skip': '',
|
'skip': '',
|
||||||
@@ -170,6 +171,14 @@ class HTTPTestCase(unittest.TestCase):
|
|||||||
for handler in self.response_handlers:
|
for handler in self.response_handlers:
|
||||||
handler(self)
|
handler(self)
|
||||||
|
|
||||||
|
def _clean_query_value(self, value):
|
||||||
|
"""Clean up a single query from query_parameters."""
|
||||||
|
value = self.replace_template(value)
|
||||||
|
# stringify ints in Python version independent fashion
|
||||||
|
value = '%s' % value
|
||||||
|
value = value.encode('UTF-8')
|
||||||
|
return value
|
||||||
|
|
||||||
def _environ_replace(self, message):
|
def _environ_replace(self, message):
|
||||||
"""Replace an indicator in a message with the environment value."""
|
"""Replace an indicator in a message with the environment value."""
|
||||||
value = re.sub(self._replacer_regex('ENVIRON'),
|
value = re.sub(self._replacer_regex('ENVIRON'),
|
||||||
@@ -249,27 +258,49 @@ class HTTPTestCase(unittest.TestCase):
|
|||||||
Scheme and netloc are saved for later use in comparisons.
|
Scheme and netloc are saved for later use in comparisons.
|
||||||
"""
|
"""
|
||||||
parsed_url = urlparse.urlsplit(url)
|
parsed_url = urlparse.urlsplit(url)
|
||||||
url_scheme = parsed_url[0]
|
|
||||||
scheme = 'http'
|
scheme = 'http'
|
||||||
netloc = self.host
|
netloc = self.host
|
||||||
|
query_params = self.test_data['query_parameters']
|
||||||
|
|
||||||
if not url_scheme:
|
if not parsed_url.scheme:
|
||||||
if (self.port
|
if (self.port
|
||||||
and not (int(self.port) == 443 and ssl)
|
and not (int(self.port) == 443 and ssl)
|
||||||
and not (int(self.port) == 80 and not ssl)):
|
and not (int(self.port) == 80 and not ssl)):
|
||||||
netloc = '%s:%s' % (self.host, self.port)
|
netloc = '%s:%s' % (self.host, self.port)
|
||||||
|
|
||||||
if ssl:
|
if ssl:
|
||||||
scheme = 'https'
|
scheme = 'https'
|
||||||
|
|
||||||
path = parsed_url[2]
|
path = parsed_url[2]
|
||||||
if self.prefix:
|
if self.prefix:
|
||||||
path = '%s%s' % (self.prefix, path)
|
path = '%s%s' % (self.prefix, path)
|
||||||
|
|
||||||
|
if query_params:
|
||||||
|
encoded_query_params = {}
|
||||||
|
for param, value in query_params.items():
|
||||||
|
# isinstance used because we can iter a string
|
||||||
|
if isinstance(value, list):
|
||||||
|
encoded_query_params[param] = [
|
||||||
|
self._clean_query_value(subvalue)
|
||||||
|
for subvalue in value]
|
||||||
|
else:
|
||||||
|
encoded_query_params[param] = (
|
||||||
|
self._clean_query_value(value))
|
||||||
|
|
||||||
|
query_string = urlparse.urlencode(
|
||||||
|
encoded_query_params, doseq=True)
|
||||||
|
if parsed_url.query:
|
||||||
|
query_string = '&'.join([parsed_url.query, query_string])
|
||||||
|
else:
|
||||||
|
query_string = parsed_url.query
|
||||||
|
|
||||||
full_url = urlparse.urlunsplit((scheme, netloc, path,
|
full_url = urlparse.urlunsplit((scheme, netloc, path,
|
||||||
parsed_url[3], ''))
|
query_string, ''))
|
||||||
self.scheme = scheme
|
self.scheme = scheme
|
||||||
self.netloc = netloc
|
self.netloc = netloc
|
||||||
else:
|
else:
|
||||||
full_url = url
|
full_url = url
|
||||||
self.scheme = url_scheme
|
self.scheme = parsed_url.scheme
|
||||||
self.netloc = parsed_url[1]
|
self.netloc = parsed_url[1]
|
||||||
|
|
||||||
return full_url
|
return full_url
|
||||||
|
57
gabbi/gabbits_intercept/queryparams.yaml
Normal file
57
gabbi/gabbits_intercept/queryparams.yaml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# As a convenience a URL can be augmented with structured declaration
|
||||||
|
# of query parameters.
|
||||||
|
#
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
- name: simple param
|
||||||
|
url: /foo
|
||||||
|
query_parameters:
|
||||||
|
bar: 1
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?bar=1
|
||||||
|
|
||||||
|
- name: joined params
|
||||||
|
url: /foo?cow=moo
|
||||||
|
query_parameters:
|
||||||
|
bar: 1
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?cow=moo&bar=1
|
||||||
|
|
||||||
|
- name: multi params
|
||||||
|
url: /foo
|
||||||
|
request_headers:
|
||||||
|
accept: application/json
|
||||||
|
query_parameters:
|
||||||
|
bar:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?bar=1&bar=2
|
||||||
|
content-type: application/json
|
||||||
|
response_json_paths:
|
||||||
|
$.bar[0]: "1"
|
||||||
|
$.bar[1]: "2"
|
||||||
|
|
||||||
|
- name: replacers in params
|
||||||
|
url: /foo
|
||||||
|
query_parameters:
|
||||||
|
fromjson: $RESPONSE['$.bar[0]']
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?fromjson=1
|
||||||
|
|
||||||
|
- name: unicode
|
||||||
|
url: /foo
|
||||||
|
query_parameters:
|
||||||
|
snowman: ☃
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?snowman=%E2%98%83
|
||||||
|
|
||||||
|
- name: url in param
|
||||||
|
url: /foo
|
||||||
|
query_parameters:
|
||||||
|
redirect: http://example.com/treehouse?secret=true&password=hello
|
||||||
|
response_headers:
|
||||||
|
x-gabbi-url: $SCHEME://$NETLOC/foo?redirect=http%3A%2F%2Fexample.com%2Ftreehouse%3Fsecret%3Dtrue%26password%3Dhello
|
||||||
|
|
@@ -26,9 +26,11 @@ class UrlParseTest(unittest.TestCase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def make_test_case(host, port=8000, prefix=''):
|
def make_test_case(host, port=8000, prefix=''):
|
||||||
# attributes used are port, prefix and host and they must
|
# Attributes used are port, prefix and host and they must
|
||||||
# be set manually here, due to metaclass magics elsewhere
|
# be set manually here, due to metaclass magics elsewhere.
|
||||||
|
# test_data must have a base value.
|
||||||
http_case = case.HTTPTestCase('test_request')
|
http_case = case.HTTPTestCase('test_request')
|
||||||
|
http_case.test_data = case.BASE_TEST
|
||||||
http_case.host = host
|
http_case.host = host
|
||||||
http_case.port = port
|
http_case.port = port
|
||||||
http_case.prefix = prefix
|
http_case.prefix = prefix
|
||||||
|
Reference in New Issue
Block a user