Skip to content

Commit 928f478

Browse files
committed
chore(test/v3): add v2 consumer compatibility suite
Signed-off-by: JP-Ellis <josh@jpellis.me>
1 parent f4f3fc5 commit 928f478

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
"""Basic HTTP consumer feature tests."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
7+
from pytest_bdd import given, parsers, scenario
8+
9+
from tests.v3.compatiblity_suite.util import InteractionDefinition, parse_markdown_table
10+
from tests.v3.compatiblity_suite.util.consumer import (
11+
a_response_is_returned,
12+
request_n_is_made_to_the_mock_server,
13+
request_n_is_made_to_the_mock_server_with_the_following_changes,
14+
the_content_type_will_be_set_as,
15+
the_mismatches_will_contain_a_mismatch_with_path_with_the_error,
16+
the_mismatches_will_contain_a_mismatch_with_the_error,
17+
the_mock_server_is_started_with_interaction_n_but_with_the_following_changes,
18+
the_mock_server_is_started_with_interactions,
19+
the_mock_server_status_will_be,
20+
the_mock_server_status_will_be_an_expected_but_not_received_error_for_interaction_n,
21+
the_mock_server_status_will_be_an_unexpected_request_received_for_interaction_n,
22+
the_mock_server_status_will_be_an_unexpected_request_received_for_path,
23+
the_mock_server_status_will_be_mismatches,
24+
the_mock_server_will_write_out_a_pact_file_for_the_interaction_when_done,
25+
the_nth_interaction_request_content_type_will_be,
26+
the_nth_interaction_request_query_parameters_will_be,
27+
the_nth_interaction_request_will_be_for_method,
28+
the_nth_interaction_request_will_contain_the_document,
29+
the_nth_interaction_request_will_contain_the_header,
30+
the_nth_interaction_will_contain_the_document,
31+
the_pact_file_will_contain_n_interactions,
32+
the_pact_test_is_done,
33+
the_payload_will_contain_the_json_document,
34+
)
35+
36+
logger = logging.getLogger(__name__)
37+
38+
################################################################################
39+
## Scenario
40+
################################################################################
41+
42+
43+
@scenario(
44+
"definition/features/V2/http_consumer.feature",
45+
"Supports a regex matcher (negative case)",
46+
)
47+
def test_supports_a_regex_matcher_negative_case() -> None:
48+
"""Supports a regex matcher (negative case)."""
49+
50+
51+
@scenario(
52+
"definition/features/V2/http_consumer.feature",
53+
"Supports a regex matcher (positive case)",
54+
)
55+
def test_supports_a_regex_matcher_positive_case() -> None:
56+
"""Supports a regex matcher (positive case)."""
57+
58+
59+
@scenario(
60+
"definition/features/V2/http_consumer.feature",
61+
"Supports a type matcher (negative case)",
62+
)
63+
def test_supports_a_type_matcher_negative_case() -> None:
64+
"""Supports a type matcher (negative case)."""
65+
66+
67+
@scenario(
68+
"definition/features/V2/http_consumer.feature",
69+
"Supports a type matcher (positive case)",
70+
)
71+
def test_supports_a_type_matcher_positive_case() -> None:
72+
"""Supports a type matcher (positive case)."""
73+
74+
75+
@scenario(
76+
"definition/features/V2/http_consumer.feature",
77+
"Supports matchers for repeated request headers (negative case)",
78+
)
79+
def test_supports_matchers_for_repeated_request_headers_negative_case() -> None:
80+
"""Supports matchers for repeated request headers (negative case)."""
81+
82+
83+
@scenario(
84+
"definition/features/V2/http_consumer.feature",
85+
"Supports matchers for repeated request headers (positive case)",
86+
)
87+
def test_supports_matchers_for_repeated_request_headers_positive_case() -> None:
88+
"""Supports matchers for repeated request headers (positive case)."""
89+
90+
91+
@scenario(
92+
"definition/features/V2/http_consumer.feature",
93+
"Supports matchers for repeated request query parameters (negative case)",
94+
)
95+
def test_supports_matchers_for_repeated_request_query_parameters_negative_case() -> (
96+
None
97+
):
98+
"""Supports matchers for repeated request query parameters (negative case)."""
99+
100+
101+
@scenario(
102+
"definition/features/V2/http_consumer.feature",
103+
"Supports matchers for repeated request query parameters (positive case)",
104+
)
105+
def test_supports_matchers_for_repeated_request_query_parameters_positive_case() -> (
106+
None
107+
):
108+
"""Supports matchers for repeated request query parameters (positive case)."""
109+
110+
111+
@scenario(
112+
"definition/features/V2/http_consumer.feature",
113+
"Supports matchers for request bodies",
114+
)
115+
def test_supports_matchers_for_request_bodies() -> None:
116+
"""Supports matchers for request bodies."""
117+
118+
119+
@scenario(
120+
"definition/features/V2/http_consumer.feature",
121+
"Supports matchers for request headers",
122+
)
123+
def test_supports_matchers_for_request_headers() -> None:
124+
"""Supports matchers for request headers."""
125+
126+
127+
@scenario(
128+
"definition/features/V2/http_consumer.feature",
129+
"Supports matchers for request query parameters",
130+
)
131+
def test_supports_matchers_for_request_query_parameters() -> None:
132+
"""Supports matchers for request query parameters."""
133+
134+
135+
@scenario(
136+
"definition/features/V2/http_consumer.feature",
137+
"Type matchers cascade to children (negative case)",
138+
)
139+
def test_type_matchers_cascade_to_children_negative_case() -> None:
140+
"""Type matchers cascade to children (negative case)."""
141+
142+
143+
@scenario(
144+
"definition/features/V2/http_consumer.feature",
145+
"Type matchers cascade to children (positive case)",
146+
)
147+
def test_type_matchers_cascade_to_children_positive_case() -> None:
148+
"""Type matchers cascade to children (positive case)."""
149+
150+
151+
@scenario(
152+
"definition/features/V2/http_consumer.feature",
153+
"Supports a matcher for request paths",
154+
)
155+
def test_supports_a_matcher_for_request_paths() -> None:
156+
"""Supports a matcher for request paths."""
157+
158+
159+
################################################################################
160+
## Given
161+
################################################################################
162+
163+
164+
@given(
165+
parsers.parse("the following HTTP interactions have been defined:\n{content}"),
166+
target_fixture="interaction_definitions",
167+
)
168+
def the_following_http_interactions_have_been_defined(
169+
content: str,
170+
) -> dict[int, InteractionDefinition]:
171+
"""
172+
Parse the HTTP interactions table into a dictionary.
173+
174+
The table columns are expected to be:
175+
176+
- No
177+
- method
178+
- path
179+
- query
180+
- headers
181+
- body
182+
- matching rules
183+
184+
The first row is ignored, as it is assumed to be the column headers. The
185+
order of the columns is similarly ignored.
186+
"""
187+
table = parse_markdown_table(content)
188+
189+
# Check that the table is well-formed
190+
assert len(table[0]) == 7, f"Expected 7 columns, got {len(table[0])}"
191+
assert "No" in table[0], "'No' column not found"
192+
193+
# Parse the table into a more useful format
194+
interactions: dict[int, InteractionDefinition] = {}
195+
for row in table:
196+
interactions[int(row["No"])] = InteractionDefinition(**row)
197+
198+
return interactions
199+
200+
201+
################################################################################
202+
## When
203+
################################################################################
204+
205+
request_n_is_made_to_the_mock_server()
206+
request_n_is_made_to_the_mock_server_with_the_following_changes()
207+
the_mock_server_is_started_with_interactions("V2")
208+
the_mock_server_is_started_with_interaction_n_but_with_the_following_changes("V2")
209+
the_pact_test_is_done()
210+
211+
################################################################################
212+
## Then
213+
################################################################################
214+
215+
a_response_is_returned()
216+
the_content_type_will_be_set_as()
217+
the_mismatches_will_contain_a_mismatch_with_path_with_the_error()
218+
the_mismatches_will_contain_a_mismatch_with_the_error()
219+
the_mock_server_status_will_be()
220+
the_mock_server_status_will_be_an_expected_but_not_received_error_for_interaction_n()
221+
the_mock_server_status_will_be_an_unexpected_request_received_for_interaction_n()
222+
the_mock_server_status_will_be_an_unexpected_request_received_for_path()
223+
the_mock_server_status_will_be_mismatches()
224+
the_mock_server_will_write_out_a_pact_file_for_the_interaction_when_done()
225+
the_nth_interaction_request_content_type_will_be()
226+
the_nth_interaction_request_query_parameters_will_be()
227+
the_nth_interaction_request_will_be_for_method()
228+
the_nth_interaction_request_will_contain_the_document()
229+
the_nth_interaction_request_will_contain_the_header()
230+
the_nth_interaction_will_contain_the_document()
231+
the_pact_file_will_contain_n_interactions()
232+
the_payload_will_contain_the_json_document()

0 commit comments

Comments
 (0)