From 302ea35d9a394949abf1b9e8a8e49fa3b52663ec Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 6 Sep 2018 19:18:28 +0300 Subject: [PATCH] Fix matching on 'body' failing when Unicode symbols are present in them Matching on bodies uses urllib.parse.parse_qs(), which fails to handle UTF-8+URLEncoded POST bodies when the input is `bytes` rather than `str`, causing matching to fail.. Fixed this by always doing decode('ascii') on URLEncoded POST bodies first. --- tests/integration/test_requests.py | 14 ++++++++++++++ vcr/matchers.py | 9 ++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_requests.py b/tests/integration/test_requests.py index cc5e7f5..ba92741 100644 --- a/tests/integration/test_requests.py +++ b/tests/integration/test_requests.py @@ -282,3 +282,17 @@ def test_filter_post_params(tmpdir, httpbin_both): requests.post(url, data={'key': 'value'}) with vcr.use_cassette(cass_loc, filter_post_data_parameters=['key']) as cass: assert b'key=value' not in cass.requests[0].body + + +def test_post_unicode_match_on_body(tmpdir, httpbin_both): + '''Ensure that matching on POST body that contains Unicode characters works.''' + data = {'key1': 'value1', '●‿●': '٩(●̮̮̃•̃)۶'} + url = httpbin_both + '/post' + + with vcr.use_cassette(str(tmpdir.join('requests.yaml')), additional_matchers=('body',)): + req1 = requests.post(url, data).content + + with vcr.use_cassette(str(tmpdir.join('requests.yaml')), additional_matchers=('body',)): + req2 = requests.post(url, data).content + + assert req1 == req2 diff --git a/vcr/matchers.py b/vcr/matchers.py index ad04a45..a464a02 100644 --- a/vcr/matchers.py +++ b/vcr/matchers.py @@ -56,9 +56,12 @@ def _transform_json(body): _xml_header_checker = _header_checker('text/xml') _xmlrpc_header_checker = _header_checker('xmlrpc', header='User-Agent') _checker_transformer_pairs = ( - (_header_checker('application/x-www-form-urlencoded'), urllib.parse.parse_qs), - (_header_checker('application/json'), _transform_json), - (lambda request: _xml_header_checker(request) and _xmlrpc_header_checker(request), xmlrpc_client.loads), + (_header_checker('application/x-www-form-urlencoded'), + lambda body: urllib.parse.parse_qs(body.decode('ascii'))), + (_header_checker('application/json'), + _transform_json), + (lambda request: _xml_header_checker(request) and _xmlrpc_header_checker(request), + xmlrpc_client.loads), )