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
|
||||
test builder will be responsible for determining host and scheme.
|
||||
**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``.
|
||||
* ``status``: The expected response status code. The default is
|
||||
``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:
|
||||
|
||||
* ``url``
|
||||
* ``query_parameters``
|
||||
* ``data``
|
||||
* ``request_headers``
|
||||
* ``response_strings``
|
||||
|
@@ -59,6 +59,7 @@ BASE_TEST = {
|
||||
'url': '',
|
||||
'status': '200',
|
||||
'request_headers': {},
|
||||
'query_parameters': {},
|
||||
'data': '',
|
||||
'xfail': False,
|
||||
'skip': '',
|
||||
@@ -170,6 +171,14 @@ class HTTPTestCase(unittest.TestCase):
|
||||
for handler in self.response_handlers:
|
||||
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):
|
||||
"""Replace an indicator in a message with the environment value."""
|
||||
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.
|
||||
"""
|
||||
parsed_url = urlparse.urlsplit(url)
|
||||
url_scheme = parsed_url[0]
|
||||
scheme = 'http'
|
||||
netloc = self.host
|
||||
query_params = self.test_data['query_parameters']
|
||||
|
||||
if not url_scheme:
|
||||
if not parsed_url.scheme:
|
||||
if (self.port
|
||||
and not (int(self.port) == 443 and ssl)
|
||||
and not (int(self.port) == 80 and not ssl)):
|
||||
netloc = '%s:%s' % (self.host, self.port)
|
||||
|
||||
if ssl:
|
||||
scheme = 'https'
|
||||
|
||||
path = parsed_url[2]
|
||||
if self.prefix:
|
||||
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,
|
||||
parsed_url[3], ''))
|
||||
query_string, ''))
|
||||
self.scheme = scheme
|
||||
self.netloc = netloc
|
||||
else:
|
||||
full_url = url
|
||||
self.scheme = url_scheme
|
||||
self.scheme = parsed_url.scheme
|
||||
self.netloc = parsed_url[1]
|
||||
|
||||
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
|
||||
def make_test_case(host, port=8000, prefix=''):
|
||||
# attributes used are port, prefix and host and they must
|
||||
# be set manually here, due to metaclass magics elsewhere
|
||||
# Attributes used are port, prefix and host and they must
|
||||
# be set manually here, due to metaclass magics elsewhere.
|
||||
# test_data must have a base value.
|
||||
http_case = case.HTTPTestCase('test_request')
|
||||
http_case.test_data = case.BASE_TEST
|
||||
http_case.host = host
|
||||
http_case.port = port
|
||||
http_case.prefix = prefix
|
||||
|
Reference in New Issue
Block a user