# -*- encoding: utf-8 -*- import mock import pytest from vcr.request import Request from vcr.serialize import deserialize, serialize from vcr.serializers import yamlserializer, jsonserializer, compat def test_deserialize_old_yaml_cassette(): with open("tests/fixtures/migration/old_cassette.yaml", "r") as f: with pytest.raises(ValueError): deserialize(f.read(), yamlserializer) def test_deserialize_old_json_cassette(): with open("tests/fixtures/migration/old_cassette.json", "r") as f: with pytest.raises(ValueError): deserialize(f.read(), jsonserializer) def test_deserialize_new_yaml_cassette(): with open("tests/fixtures/migration/new_cassette.yaml", "r") as f: deserialize(f.read(), yamlserializer) def test_deserialize_new_json_cassette(): with open("tests/fixtures/migration/new_cassette.json", "r") as f: deserialize(f.read(), jsonserializer) REQBODY_TEMPLATE = """\ interactions: - request: body: {req_body} headers: Content-Type: [application/x-www-form-urlencoded] Host: [httpbin.org] method: POST uri: http://httpbin.org/post response: body: {{string: ""}} headers: content-length: ['0'] content-type: [application/json] status: {{code: 200, message: OK}} """ # A cassette generated under Python 2 stores the request body as a string, # but the same cassette generated under Python 3 stores it as "!!binary". # Make sure we accept both forms, regardless of whether we're running under # Python 2 or 3. @pytest.mark.parametrize( "req_body, expect", [ # Cassette written under Python 2 (pure ASCII body) ("x=5&y=2", b"x=5&y=2"), # Cassette written under Python 3 (pure ASCII body) ("!!binary |\n eD01Jnk9Mg==", b"x=5&y=2"), # Request body has non-ASCII chars (x=föo&y=2), encoded in UTF-8. ('!!python/str "x=f\\xF6o&y=2"', b"x=f\xc3\xb6o&y=2"), ("!!binary |\n eD1mw7ZvJnk9Mg==", b"x=f\xc3\xb6o&y=2"), # Same request body, this time encoded in UTF-16. In this case, we # write the same YAML file under both Python 2 and 3, so there's only # one test case here. ( "!!binary |\n //54AD0AZgD2AG8AJgB5AD0AMgA=", b"\xff\xfex\x00=\x00f\x00\xf6\x00o\x00&\x00y\x00=\x002\x00", ), # Same again, this time encoded in ISO-8859-1. ("!!binary |\n eD1m9m8meT0y", b"x=f\xf6o&y=2"), ], ) def test_deserialize_py2py3_yaml_cassette(tmpdir, req_body, expect): cfile = tmpdir.join("test_cassette.yaml") cfile.write(REQBODY_TEMPLATE.format(req_body=req_body)) with open(str(cfile)) as f: (requests, responses) = deserialize(f.read(), yamlserializer) assert requests[0].body == expect @mock.patch.object( jsonserializer.json, "dumps", side_effect=UnicodeDecodeError("utf-8", b"unicode error in serialization", 0, 10, "blew up"), ) def test_serialize_constructs_UnicodeDecodeError(mock_dumps): with pytest.raises(UnicodeDecodeError): jsonserializer.serialize({}) def test_serialize_empty_request(): request = Request(method="POST", uri="http://localhost/", body="", headers={}) serialize({"requests": [request], "responses": [{}]}, jsonserializer) def test_serialize_json_request(): request = Request(method="POST", uri="http://localhost/", body="{'hello': 'world'}", headers={}) serialize({"requests": [request], "responses": [{}]}, jsonserializer) def test_serialize_binary_request(): msg = "Does this HTTP interaction contain binary data?" request = Request(method="POST", uri="http://localhost/", body=b"\x8c", headers={}) try: serialize({"requests": [request], "responses": [{}]}, jsonserializer) except (UnicodeDecodeError, TypeError) as exc: assert msg in str(exc) def test_deserialize_no_body_string(): data = {"body": {"string": None}} output = compat.convert_to_bytes(data) assert data == output