Skip to content

Commit a95accf

Browse files
authored
Merge pull request #1 from OutSystems/maggie
initial code release
2 parents 2c81029 + 70d08e6 commit a95accf

22 files changed

Lines changed: 636 additions & 73 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# pact-python specific ignores
22
e2e/pacts
33
userserviceclient-userservice.json
4+
detectcontentlambda-contentprovider.json
45
pact/bin
56

67
# Byte-compiled / optimized / DLL files

examples/message/README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class MessageHandler(object):
4141
```
4242

4343
Below is a snippet from a test where the message handler has no error.
44-
Since the expected event contains a key `documentType` with value `microsoft-word`, message handler does not throw an error and a pact file `f"pacts/{expected_json}"` is expected to be generated.
44+
Since the expected event contains a key `documentType` with value `microsoft-word`, message handler does not throw an error and a pact file `f"{PACT_FILE}""` is expected to be generated.
4545

4646
```python
4747
def test_generate_new_pact_file(pact):
@@ -69,7 +69,7 @@ def test_generate_new_pact_file(pact):
6969
assert isfile(f"{PACT_FILE}") == 1
7070
```
7171

72-
For a similar test where the event does not contain a key `documentType` with value `microsoft-word`, a `CustomError` is generated and there there is no generated json file `f"pacts/{expected_json}"`.
72+
For a similar test where the event does not contain a key `documentType` with value `microsoft-word`, a `CustomError` is generated and there there is no generated json file `f"{PACT_FILE}"`.
7373

7474
```python
7575
def test_throw_exception_handler(pact):
@@ -97,8 +97,6 @@ def test_throw_exception_handler(pact):
9797
assert isfile(f"{PACT_FILE}") == 0
9898
```
9999

100-
Otherwise, no pact file is generated.
101-
102100
## Provider
103101

104102
Note: The current example only tests the consumer side.

examples/message/tests/consumer/test_message_consumer.py

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@
1616
PACT_BROKER_URL = "http://localhost"
1717
PACT_BROKER_USERNAME = "pactbroker"
1818
PACT_BROKER_PASSWORD = "pactbroker"
19-
PACT_DIR = 'pacts'
19+
PACT_DIR = "pacts"
2020

21-
CONSUMER_NAME = 'DetectContentLambda'
22-
PROVIDER_NAME = 'ContentProvider'
23-
PACT_FILE = (f"{PACT_DIR}/{CONSUMER_NAME.lower().replace(' ', '_')}_message-"
24-
+ f"{PROVIDER_NAME.lower().replace(' ', '_')}_message.json")
21+
CONSUMER_NAME = "DetectContentLambda"
22+
PROVIDER_NAME = "ContentProvider"
23+
PACT_FILE = (f"{PACT_DIR}/{CONSUMER_NAME.lower().replace(' ', '_')}-"
24+
+ f"{PROVIDER_NAME.lower().replace(' ', '_')}.json")
2525

26-
@pytest.fixture(scope='session')
26+
27+
@pytest.fixture(scope="session")
2728
def pact(request):
28-
version = request.config.getoption('--publish-pact')
29+
version = request.config.getoption("--publish-pact")
2930
publish = True if version else False
3031

3132
pact = MessageConsumer(CONSUMER_NAME, version=version).has_pact_with(
@@ -54,57 +55,59 @@ def progressive_delay(file, time_to_wait=10, second_interval=0.5, verbose=False)
5455
time.sleep(second_interval)
5556
time_counter += 1
5657
if verbose:
57-
print(f'Trying for {time_counter*second_interval} seconds')
58+
print(f"Trying for {time_counter*second_interval} seconds")
5859
if time_counter > time_to_wait:
5960
if verbose:
60-
print(f'Already waited {time_counter*second_interval} seconds')
61+
print(f"Already waited {time_counter*second_interval} seconds")
6162
break
6263

6364

6465
def test_throw_exception_handler(pact):
6566
cleanup_json(PACT_FILE)
67+
6668
wrong_event = {
67-
'documentName': 'spreadsheet.xls',
68-
'creator': 'WI',
69-
'documentType': 'microsoft-excel'
69+
"event": "ObjectCreated:Put",
70+
"documentName": "spreadsheet.xls",
71+
"creator": "WI",
72+
"documentType": "microsoft-excel"
7073
}
7174

7275
(pact
73-
.given('Another document in Document Service')
74-
.expects_to_receive('Description')
76+
.given("Document unsupported type")
77+
.expects_to_receive("Description")
7578
.with_content(wrong_event)
7679
.with_metadata({
77-
'Content-Type': 'application/json'
80+
"Content-Type": "application/json"
7881
}))
7982

8083
with pytest.raises(CustomError):
8184
with pact:
82-
# handler needs 'documentType' == 'microsoft-word'
85+
# handler needs "documentType" == "microsoft-word"
8386
MessageHandler(wrong_event)
8487

8588
progressive_delay(f"{PACT_FILE}")
8689
assert isfile(f"{PACT_FILE}") == 0
8790

8891

89-
def test_generate_new_pact_file(pact):
92+
def test_put_file(pact):
9093
cleanup_json(PACT_FILE)
9194

9295
expected_event = {
93-
'documentName': 'document.doc',
94-
'creator': 'TP',
95-
'documentType': 'microsoft-word'
96+
"event": "ObjectCreated:Put",
97+
"documentName": "document.doc",
98+
"creator": "TP",
99+
"documentType": "microsoft-word"
96100
}
97101

98102
(pact
99-
.given('A document create in Document Service')
100-
.expects_to_receive('Description')
103+
.given("A document created successfully")
104+
.expects_to_receive("Description")
101105
.with_content(expected_event)
102106
.with_metadata({
103-
'Content-Type': 'application/json'
107+
"Content-Type": "application/json"
104108
}))
105109

106110
with pact:
107-
# handler needs 'documentType' == 'microsoft-word'
108111
MessageHandler(expected_event)
109112

110113
progressive_delay(f"{PACT_FILE}")
@@ -121,17 +124,18 @@ def test_publish_to_broker(pact):
121124
`pytest tests/consumer/test_message_consumer.py::test_publish_pact_to_broker --publish-pact 2`
122125
"""
123126
expected_event = {
124-
'documentName': 'document.doc',
125-
'creator': 'TP',
126-
'documentType': 'microsoft-word'
127+
"event": "ObjectCreated:Delete",
128+
"documentName": "document.doc",
129+
"creator": "TP",
130+
"documentType": "microsoft-word"
127131
}
128132

129133
(pact
130-
.given('A document create in Document Service with broker')
131-
.expects_to_receive('Description with broker')
134+
.given("A document deleted successfully")
135+
.expects_to_receive("Description with broker")
132136
.with_content(expected_event)
133137
.with_metadata({
134-
'Content-Type': 'application/json'
138+
"Content-Type": "application/json"
135139
}))
136140

137141
with pact:

examples/message/tests/provider/__init__.py

Whitespace-only changes.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import pytest
2+
from pact import MessageProvider
3+
4+
5+
def document_created_handler():
6+
return {
7+
"event": "ObjectCreated:Put",
8+
"documentName": "document.doc",
9+
"creator": "TP",
10+
"documentType": "microsoft-word"
11+
}
12+
13+
14+
def document_deleted_handler():
15+
return {
16+
"event": "ObjectCreated:Delete",
17+
"documentName": "document.doc",
18+
"creator": "TP",
19+
"documentType": "microsoft-word"
20+
}
21+
22+
23+
def test_verify_success():
24+
provider = MessageProvider(
25+
message_providers={
26+
'A document created successfully': document_created_handler,
27+
'A document deleted successfully': document_deleted_handler
28+
},
29+
provider='ContentProvider',
30+
consumer='DetectContentLambda',
31+
pact_dir='pacts'
32+
33+
)
34+
with provider:
35+
provider.verify()
36+
37+
38+
def test_verify_failure_when_a_provider_missing():
39+
provider = MessageProvider(
40+
message_providers={
41+
'A document created successfully': document_created_handler,
42+
},
43+
provider='ContentProvider',
44+
consumer='DetectContentLambda',
45+
pact_dir='pacts'
46+
47+
)
48+
49+
with pytest.raises(AssertionError):
50+
with provider:
51+
provider.verify()

pact/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
from .broker import Broker
33
from .consumer import Consumer
44
from .matchers import EachLike, Like, SomethingLike, Term, Format
5-
from .message_pact import MessagePact
65
from .message_consumer import MessageConsumer
6+
from .message_pact import MessagePact
7+
from .message_provider import MessageProvider
78
from .pact import Pact
89
from .provider import Provider
910
from .verifier import Verifier
1011

1112
from .__version__ import __version__ # noqa: F401
1213

13-
__all__ = ('Broker', 'Consumer', 'EachLike', 'Like', 'MessageConsumer', 'MessagePact',
14+
__all__ = ('Broker', 'Consumer', 'EachLike', 'Like',
15+
'MessageConsumer', 'MessagePact', 'MessageProvider',
1416
'Pact', 'Provider', 'SomethingLike', 'Term', 'Format', 'Verifier')

pact/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Pact version info."""
22

3-
__version__ = '1.3.9'
3+
__version__ = '1.3.0'

pact/broker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def publish(self, consumer_name, version, pact_dir=None,
6161
os.listdir(pact_dir),
6262
self._normalize_consumer_name(consumer_name) + '*.json'
6363
)
64-
pact_files = list(map(lambda pact_file: f'{pact_dir}/{pact_file}', pact_files))
64+
pact_files[0] = f'{pact_dir}/{pact_files[0]}'
6565
command = [
6666
BROKER_CLIENT_PATH,
6767
'publish',
@@ -85,7 +85,7 @@ def publish(self, consumer_name, version, pact_dir=None,
8585
for tag in consumer_tags:
8686
command.extend(['-t', tag])
8787

88-
print(f"PactBroker command: {command}")
88+
log.debug(f"PactBroker publish command: {command}")
8989

9090
publish_process = Popen(command)
9191
publish_process.wait()

pact/consumer.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ def has_pact_with(self, provider, host_name='localhost', port=1234,
4949
cors=False, publish_to_broker=False,
5050
broker_base_url=None, broker_username=None,
5151
broker_password=None, broker_token=None, pact_dir=None,
52-
specification_version='2.0.0',
53-
file_write_mode='overwrite'):
52+
version='2.0.0', file_write_mode='overwrite'):
5453
"""
5554
Create a contract between the `provider` and this consumer.
5655
@@ -109,8 +108,8 @@ def has_pact_with(self, provider, host_name='localhost', port=1234,
109108
:param pact_dir: Directory where the resulting pact files will be
110109
written. Defaults to the current directory.
111110
:type pact_dir: str
112-
:param specification_version: The Pact Specification version to use.
113-
Defaults to '2.0.0'.
111+
:param version: The Pact Specification version to use, defaults to
112+
'2.0.0'.
114113
:type version: str
115114
:param file_write_mode: How the mock service should apply multiple
116115
calls to .verify(). Pass 'overwrite' to overwrite the generated
@@ -143,5 +142,5 @@ def has_pact_with(self, provider, host_name='localhost', port=1234,
143142
cors=cors,
144143
pact_dir=pact_dir,
145144
publish_to_broker=publish_to_broker,
146-
specification_version=specification_version,
145+
version=version,
147146
file_write_mode=file_write_mode)

0 commit comments

Comments
 (0)