Skip to content

Commit

Permalink
Merge pull request #154 from marco-santamaria/master
Browse files Browse the repository at this point in the history
Filter parameters from 'application/json' content-type POST requests
  • Loading branch information
colonelpanic8 committed May 14, 2015
2 parents 2323b9d + 59aa351 commit c338d5d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
13 changes: 13 additions & 0 deletions tests/integration/test_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from six.moves.urllib.parse import urlencode
from six.moves.urllib.error import HTTPError
import vcr
import json


def _request_with_auth(url, username, password):
Expand Down Expand Up @@ -66,6 +67,18 @@ def test_filter_post_data(tmpdir):
assert b'id=secret' not in cass.requests[0].body


def test_filter_json_post_data(tmpdir):
data = json.dumps({'id': 'secret', 'foo': 'bar'}).encode('utf-8')
request = Request('http://httpbin.org/post', data=data)
request.add_header('Content-Type', 'application/json')

cass_file = str(tmpdir.join('filter_jpd.yaml'))
with vcr.use_cassette(cass_file, filter_post_data_parameters=['id']):
urlopen(request)
with vcr.use_cassette(cass_file, filter_post_data_parameters=['id']) as cass:
assert b'"id": "secret"' not in cass.requests[0].body


def test_filter_callback(tmpdir):
url = 'http://httpbin.org/get'
cass_file = str(tmpdir.join('basic_auth_filter.yaml'))
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
remove_post_data_parameters
)
from vcr.request import Request
import json


def test_remove_headers():
Expand Down Expand Up @@ -67,3 +68,29 @@ def test_remove_nonexistent_post_data_parameters():
request = Request('POST', 'http://google.com', body, {})
remove_post_data_parameters(request, ['id'])
assert request.body == b''


def test_remove_json_post_data_parameters():
body = b'{"id": "secret", "foo": "bar", "baz": "qux"}'
request = Request('POST', 'http://google.com', body, {})
request.add_header('Content-Type', 'application/json')
remove_post_data_parameters(request, ['id'])
request_body_json = json.loads(request.body.decode('utf-8'))
expected_json = json.loads(b'{"foo": "bar", "baz": "qux"}'.decode('utf-8'))
assert request_body_json == expected_json


def test_remove_all_json_post_data_parameters():
body = b'{"id": "secret", "foo": "bar"}'
request = Request('POST', 'http://google.com', body, {})
request.add_header('Content-Type', 'application/json')
remove_post_data_parameters(request, ['id', 'foo'])
assert request.body == b'{}'


def test_remove_nonexistent_json_post_data_parameters():
body = b'{}'
request = Request('POST', 'http://google.com', body, {})
request.add_header('Content-Type', 'application/json')
remove_post_data_parameters(request, ['id'])
assert request.body == b'{}'
27 changes: 18 additions & 9 deletions vcr/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
except ImportError:
from backport_collections import OrderedDict
import copy
import json


def remove_headers(request, headers_to_remove):
Expand All @@ -31,13 +32,21 @@ def remove_query_parameters(request, query_parameters_to_remove):

def remove_post_data_parameters(request, post_data_parameters_to_remove):
if request.method == 'POST' and not isinstance(request.body, BytesIO):
post_data = OrderedDict()
for k, sep, v in [p.partition(b'=') for p in request.body.split(b'&')]:
if k in post_data:
post_data[k].append(v)
elif len(k) > 0 and k.decode('utf-8') not in post_data_parameters_to_remove:
post_data[k] = [v]
request.body = b'&'.join(
b'='.join([k, v])
for k, vals in post_data.items() for v in vals)
if ('Content-Type' in request.headers and
request.headers['Content-Type'] == 'application/json'):
json_data = json.loads(request.body.decode('utf-8'))
for k in list(json_data.keys()):
if k in post_data_parameters_to_remove:
del json_data[k]
request.body = json.dumps(json_data).encode('utf-8')
else:
post_data = OrderedDict()
for k, sep, v in [p.partition(b'=') for p in request.body.split(b'&')]:
if k in post_data:
post_data[k].append(v)
elif len(k) > 0 and k.decode('utf-8') not in post_data_parameters_to_remove:
post_data[k] = [v]
request.body = b'&'.join(
b'='.join([k, v])
for k, vals in post_data.items() for v in vals)
return request

0 comments on commit c338d5d

Please sign in to comment.