Merge pull request #215 from cdent/json-lhs-expand

Template expansion in LHS of json path test
This commit is contained in:
Chris Dent 2017-07-07 14:03:39 +01:00 committed by GitHub
commit 00dd7c24d8
5 changed files with 71 additions and 6 deletions

View File

@ -274,7 +274,8 @@ All of these variables may be used in all of the following fields:
* ``data``
* ``request_headers``
* ``response_strings``
* ``response_json_paths`` (on the value side of the key value pair)
* ``response_json_paths`` (in both the key and value, see
:ref:`json path substitution <json-subs>` for more info)
* ``response_headers`` (on the value side of the key value pair)
* ``response_forbidden_headers``
* ``count`` and ``delay`` fields of ``poll``

View File

@ -81,6 +81,31 @@ Examples like this can be found in one of gabbi's `own tests`_.
There are more JSONPath examples in :doc:`example` and in the
`jsonpath_rw`_ and `jsonpath_rw_ext`_ documentation.
.. _json-subs:
Substitution
------------
:ref:`Substitutions <state-substitution>` can be made in both the
left (query) and right (expected) hand sides of the json path
expression. When subtitutions are used in the query, care must be
taken to ensure proper quoting of the resulting value. For example
if there is a uuid (with hyphens) at ``$RESPONSE['$.id']`` then this
expression may fail::
$.nested.structure.$RESPONSE['$.id'].name: foobar
as it will evaluate to something like::
$.nested.structure.ADC8AAFC-D564-40D1-9724-7680D3C010C2.name: foobar
which may be treated as an arithemtic expression by the json path
parser. The test author should write::
$.nested.structure["$RESPONSE['$.id']"].name: foobar
to quote the result of the substitution.
.. _jsonpath_rw: http://jsonpath-rw.readthedocs.io/en/latest/
.. _jsonpath_rw_ext: https://python-jsonpath-rw-ext.readthedocs.io/en/latest/
.. _own tests: https://github.com/cdent/gabbi/blob/master/gabbi/tests/gabbits_intercept/data.yaml

View File

@ -75,11 +75,8 @@ class JSONHandler(base.ContentHandler):
def action(self, test, path, value=None):
"""Test json_paths against json data."""
# NOTE: This process has some advantages over other process that
# might come along because the JSON data has already been
# processed (to provided for the magic template replacing).
# Other handlers that want access to data structures will need
# to do their own processing.
# Do template expansion in the left hand side.
path = test.replace_template(path)
try:
match = self.extract_json_path_value(
test.response_data, path)

View File

@ -0,0 +1,37 @@
defaults:
request_headers:
content-type: application/json
verbose: True
tests:
- name: left side json one
desc: for reuse on the next test
POST: /
data:
alpha: alpha1
beta: beta1
- name: expand left side
POST: /
data:
alpha1: alpha
beta1: beta
response_json_paths:
$["$RESPONSE['$.alpha']"]: alpha
- name: expand environ left side
POST: /
data:
alpha1: alpha
beta1: beta
1: cow
response_json_paths:
$.['$ENVIRON['ONE']']: cow
- name: set key and value
GET: /jsonator?key=$ENVIRON['ONE']&value=10
- name: check key and value
GET: /jsonator?key=$ENVIRON['ONE']&value=10
response_json_paths:
$.["$ENVIRON['ONE']"]: $RESPONSE['$['1']']

View File

@ -107,6 +107,11 @@ class SimpleWsgi(object):
# fall through if we've ended the loop
elif path_info == '/cookie':
headers.append(('Set-Cookie', 'session=1234; domain=.example.com'))
elif path_info == '/jsonator':
json_data = json.dumps({query_data['key'][0]:
query_data['value'][0]})
start_response('200 OK', [('Content-Type', 'application/json')])
return [json_data.encode('utf-8')]
start_response('200 OK', headers)