Skip to content

Commit 9ec2c3f

Browse files
committed
fix(ffi): use with_binary_body
The `with_binary_file` FFI function is perhaps poorly named, as it doesn't just set the (binary) body of an interaction, but it also sets the matcher to be a content type matcher. It would be best to have two separate FFI calls (which are now supported) of `with_binary_body` and `with_matching_rule`. Signed-off-by: JP-Ellis <[email protected]>
1 parent 18aeb4e commit 9ec2c3f

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

src/pact/v3/ffi.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6179,7 +6179,23 @@ def with_binary_body(
61796179
RuntimeError:
61806180
If the body could not be modified.
61816181
"""
6182-
raise NotImplementedError
6182+
if len(gc.get_referrers(body)) == 0:
6183+
warnings.warn(
6184+
"Make sure to assign the body to a variable to avoid having the byte array"
6185+
" modified.",
6186+
UserWarning,
6187+
stacklevel=3,
6188+
)
6189+
success: bool = lib.pactffi_with_binary_body(
6190+
interaction._ref,
6191+
part.value,
6192+
content_type.encode("utf-8") if content_type else ffi.NULL,
6193+
body if body else ffi.NULL,
6194+
len(body) if body else 0,
6195+
)
6196+
if not success:
6197+
msg = f"Unable to set body for {interaction}."
6198+
raise RuntimeError(msg)
61836199

61846200

61856201
def with_binary_file(

src/pact/v3/interaction/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def with_binary_body(
300300
body:
301301
Body of the request.
302302
"""
303-
pact.v3.ffi.with_binary_file(
303+
pact.v3.ffi.with_binary_body(
304304
self._handle,
305305
self._parse_interaction_part(part),
306306
content_type,

tests/v3/test_http_interaction.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import pytest
1414

1515
from pact.v3 import Pact
16+
from pact.v3.pact import MismatchesError
1617

1718
if TYPE_CHECKING:
1819
from pathlib import Path
@@ -362,7 +363,7 @@ async def test_with_body_response(pact: Pact, method: str) -> None:
362363
json={"test": True},
363364
) as resp:
364365
assert resp.status == 200
365-
assert await resp.json() == {"test": True}
366+
assert json.loads(await resp.content.read()) == {"test": True}
366367

367368

368369
@pytest.mark.asyncio()
@@ -382,7 +383,7 @@ async def test_with_body_explicit(pact: Pact) -> None:
382383
json={"request": True},
383384
) as resp:
384385
assert resp.status == 200
385-
assert await resp.json() == {"response": True}
386+
assert json.loads(await resp.content.read()) == {"response": True}
386387

387388

388389
def test_with_body_invalid(pact: Pact) -> None:
@@ -444,10 +445,10 @@ async def test_binary_file_request(pact: Pact) -> None:
444445
async with aiohttp.ClientSession(srv.url) as session:
445446
async with session.post("/", data=payload) as resp:
446447
assert resp.status == 200
448+
449+
with pytest.raises(MismatchesError), pact.serve() as srv: # noqa: PT012
450+
async with aiohttp.ClientSession(srv.url) as session:
447451
async with session.post("/", data=payload[:2]) as resp:
448-
# The match _only_ checks the content type, not the content
449-
# itself. See
450-
# https://pact-foundation.slack.com/archives/C02BXLDJ7JR/p1697032990681329
451452
assert resp.status == 200
452453

453454

0 commit comments

Comments
 (0)