Open mparent61 opened 2 years ago
@kevin1024 Any plans for integrating this?
@mparent61 Is there any workaround right now? I have a multpart/form-data and I cannot use the cassete I record (which is actually a sending and recieving a small file).
@mezhaka - I've been using this workaround --
import re
import pytest
from requests_toolbelt.multipart import decoder
from vcr.matchers import _get_transformer, _identity
from vcr.util import read_body
def decode_multipart_request_body(request):
return decoder.MultipartDecoder(
content=request.body, content_type=request.headers["content-type"]
)
def is_multipart_form_data_request(request):
return re.match(
r"multipart/form-data(;|$)", request.headers.get("content-type", "").lower()
)
# This is a workaround for request body "multipart form" handling
def request_body_matcher(r1, r2) -> None:
if is_multipart_form_data_request(r1) and is_multipart_form_data_request(r2):
decoded1 = decode_multipart_request_body(r1)
decoded2 = decode_multipart_request_body(r2)
assert decoded1.encoding == decoded2.encoding
assert len(decoded1.parts) == len(decoded2.parts)
for part1, part2 in zip(decoded1.parts, decoded2.parts):
assert part1.headers == part2.headers
assert (
part1.content == part2.content
), f"Multipart data doesn't match for part with content type: {part1.headers}"
else:
# Copied directly from VCRPy's `body` matcher. For some reason PyTest's custom ASSERT handlers (with
# much better diagnostic info) does not work when the assert fires inside VCRPy.
transformer = _get_transformer(r1)
r2_transformer = _get_transformer(r2)
if transformer != r2_transformer:
transformer = _identity
body1 = read_body(r1)
body2 = read_body(r2)
assert transformer(body1) == transformer(body2)
and then to setup -
@pytest.fixture(scope="module")
def vcr(vcr):
# Override VCRPy's default body matcher to support Multipart form data, and provide better ASSERT messages.
vcr.register_matcher("body", request_body_matcher)
return vcr
Request bodies of content type
multipart/form-data
can have different "boundary" separators, but contain identical data. This can cause VCRPy's "body" matcher to fail on otherwise identical requests.This adds support for parsing the encoded body data, essentially stripping out the "boundary" values, and comparing the contents.
Also, a similar approach could be used for handling "replace_post_data_parameters" mentioned in https://github.com/kevin1024/vcrpy/issues/521.
Testing Notes
Added 3 unit tests to confirm matching behavior, using sample 1x1 PNG image data. and differing "boundary" delimiters.
Implementation Notes
headers
parameter, as this is needed to determine the multipart form data "boundary" separator.