Skip to content

Commit

Permalink
chore: adjust tests to use new Mismatch class
Browse files Browse the repository at this point in the history
Signed-off-by: JP-Ellis <[email protected]>
  • Loading branch information
JP-Ellis committed Oct 9, 2024
1 parent e67352d commit 80fd458
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 36 deletions.
134 changes: 100 additions & 34 deletions tests/v3/compatibility_suite/util/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,23 @@
import pytest
import requests
from pytest_bdd import given, parsers, then, when
from typing_extensions import TypeGuard
from yarl import URL

from pact.v3 import Pact
from pact.v3.error import (
BodyMismatch,
BodyTypeMismatch,
HeaderMismatch,
MetadataMismatch,
Mismatch,
MissingRequest,
PathMismatch,
QueryMismatch,
RequestMismatch,
RequestNotFound,
StatusMismatch,
)
from tests.v3.compatibility_suite.util import (
FIXTURES_ROOT,
PactInteractionTuple,
Expand All @@ -35,6 +49,62 @@

logger = logging.getLogger(__name__)


MISMATCH_MAP: dict[str, type[Mismatch]] = {
"query": QueryMismatch,
"header": HeaderMismatch,
"body": BodyMismatch,
"body-content-type": BodyTypeMismatch,
}


def _mismatch_with_path(
mismatch: Mismatch,
) -> TypeGuard[MissingRequest | RequestNotFound | RequestMismatch | BodyMismatch]:
"""
Check if a mismatch has a `path` attribute.
This function is used to check if the mismatch in question is one of the
variants that have a `path` attribute. This has little purpose at runtime,
but is useful for type checking.
"""
return isinstance(
mismatch, (MissingRequest, RequestNotFound, RequestMismatch, BodyMismatch)
)


def _mismatch_with_mismatch(
mismatch: Mismatch,
) -> TypeGuard[
PathMismatch
| StatusMismatch
| QueryMismatch
| HeaderMismatch
| BodyTypeMismatch
| BodyMismatch
| MetadataMismatch
]:
"""
Check if a mismatch has a `mismatch` attribute.
This function is used to check if the mismatch in question is one of the
variants that have a `mismatch` attribute. This has little purpose at runtime,
but is useful for type checking.
"""
return isinstance(
mismatch,
(
PathMismatch,
StatusMismatch,
QueryMismatch,
HeaderMismatch,
BodyTypeMismatch,
BodyMismatch,
MetadataMismatch,
),
)


################################################################################
## Given
################################################################################
Expand Down Expand Up @@ -285,7 +355,11 @@ def _(
indent=2,
),
)
logger.info("Mismatches:\n%s", json.dumps(srv.mismatches, indent=2))
msg = "\n".join([
"Mismatches:",
*(f" ({i + 1}) {m}" for i, m in enumerate(srv.mismatches)),
])
logger.info(msg)
assert response.status_code == code


Expand Down Expand Up @@ -363,9 +437,9 @@ def _(

for mismatch in srv.mismatches:
if (
mismatch["method"] == interaction_definitions[n].method
and mismatch["path"] == interaction_definitions[n].path
and mismatch["type"] == "missing-request"
isinstance(mismatch, MissingRequest)
and mismatch.method == interaction_definitions[n].method
and mismatch.path == interaction_definitions[n].path
):
return
pytest.fail("Expected mismatch not found")
Expand Down Expand Up @@ -397,10 +471,10 @@ def _(

for mismatch in srv.mismatches:
if (
mismatch["method"] == interaction_definitions[n].method
and mismatch["request"]["method"] == method
and mismatch["path"] == interaction_definitions[n].path
and mismatch["type"] == "request-not-found"
isinstance(mismatch, RequestNotFound)
and mismatch.method == interaction_definitions[n].method
and mismatch.method == method
and mismatch.path == interaction_definitions[n].path
):
return
pytest.fail("Expected mismatch not found")
Expand Down Expand Up @@ -431,9 +505,9 @@ def _(

for mismatch in srv.mismatches:
if (
mismatch["request"]["method"] == method
and mismatch["path"] == path
and mismatch["type"] == "request-not-found"
isinstance(mismatch, RequestNotFound)
and mismatch.method == method
and mismatch.path == path
):
return
pytest.fail("Expected mismatch not found")
Expand Down Expand Up @@ -470,27 +544,17 @@ def _(
"""
The mismatches will contain a mismatch with the error.
"""
if mismatch_type == "query":
mismatch_type = "QueryMismatch"
elif mismatch_type == "header":
mismatch_type = "HeaderMismatch"
elif mismatch_type == "body":
mismatch_type = "BodyMismatch"
elif mismatch_type == "body-content-type":
mismatch_type = "BodyTypeMismatch"
else:
msg = f"Unexpected mismatch type: {mismatch_type}"
raise ValueError(msg)

logger.info("Expecting mismatch: %s", mismatch_type)
logger.info("With error: %s", error)
for mismatch in srv.mismatches:
for sub_mismatch in mismatch["mismatches"]:
if (
error in sub_mismatch["mismatch"]
and sub_mismatch["type"] == mismatch_type
):
return
if isinstance(mismatch, RequestMismatch):
for sub_mismatch in mismatch.mismatches:
if (
isinstance(sub_mismatch, MISMATCH_MAP[mismatch_type])
and _mismatch_with_mismatch(sub_mismatch)
and error in sub_mismatch.mismatch
):
return
pytest.fail("Expected mismatch not found")


Expand All @@ -514,13 +578,15 @@ def _(
"""
The mismatches will contain a mismatch with the error.
"""
mismatch_type = "BodyMismatch" if mismatch_type == "body" else mismatch_type
for mismatch in srv.mismatches:
for sub_mismatch in mismatch["mismatches"]:
assert isinstance(mismatch, RequestMismatch)
for sub_mismatch in mismatch.mismatches:
if (
sub_mismatch["mismatch"] == error
and sub_mismatch["type"] == mismatch_type
and sub_mismatch["path"] == path
isinstance(sub_mismatch, MISMATCH_MAP[mismatch_type])
and _mismatch_with_mismatch(sub_mismatch)
and sub_mismatch.mismatch == error
and _mismatch_with_path(sub_mismatch)
and sub_mismatch.path == path
):
return
pytest.fail("Expected mismatch not found")
Expand Down
5 changes: 3 additions & 2 deletions tests/v3/test_http_interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import pytest

from pact.v3 import Pact, match
from pact.v3.error import RequestMismatch, RequestNotFound
from pact.v3.pact import MismatchesError

if TYPE_CHECKING:
Expand Down Expand Up @@ -71,7 +72,7 @@ async def test_basic_request_method(pact: Pact, method: str) -> None:

# As we are making unexpected requests, we should have mismatches
for mismatch in srv.mismatches:
assert mismatch["type"] == "request-not-found"
assert isinstance(mismatch, RequestNotFound)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -208,7 +209,7 @@ async def test_set_header_request_repeat(
assert resp.status == 500

assert len(srv.mismatches) == 1
assert srv.mismatches[0]["type"] == "request-mismatch"
assert isinstance(srv.mismatches[0], RequestMismatch)


@pytest.mark.parametrize(
Expand Down

0 comments on commit 80fd458

Please sign in to comment.