Skip to content

Commit ac1b5d7

Browse files
authored
Merge pull request #13 from cloudblue/feature/add-fake-data-generator
Feature/Add a fake data generator.
2 parents 33b9dfc + b29896c commit ac1b5d7

File tree

7 files changed

+149
-65
lines changed

7 files changed

+149
-65
lines changed

README.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,38 @@ Finally, the DevOps Testing Library also allows you to easily use Behave! BDD to
116116
the following code in your `features/environment.py` file
117117

118118
```python
119-
from connect.devops_testing.bdd.fixtures import use_connect_request_dispatcher, use_connect_request_builder
119+
from behave import use_fixture
120+
120121
# import the built-in steps for e2e testing.
121122
from connect.devops_testing.bdd import steps
123+
from connect.devops_testing.bdd.fixtures import (
124+
use_connect_request_dispatcher,
125+
use_connect_request_builder,
126+
use_connect_request_store,
127+
)
122128

123129

124130
def before_all(context):
125-
# attach the request dispatcher to the behave context if you want do e2e test.
126-
use_connect_request_dispatcher(context)
131+
# attach the request dispatcher to the behave context.
132+
use_fixture(
133+
fixture_func=use_connect_request_dispatcher,
134+
context=context,
135+
)
127136
# attach the request builder to the behave context.
128-
use_connect_request_builder(context)
137+
use_fixture(
138+
fixture_func=use_connect_request_builder,
139+
context=context,
140+
)
141+
142+
143+
def before_feature(context, feature):
144+
# reset the request store for each feature
145+
use_fixture(
146+
fixture_func=use_connect_request_store,
147+
context=context,
148+
reset=True
149+
)
150+
129151
```
130152

131153
It's time to define the feature file in `features/purchase.feature`:

connect/devops_testing/bdd/fixtures.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from typing import Optional
22

3+
from behave import fixture
34
from behave.runner import Context
45

56
from connect.client import ConnectClient
67
from connect.devops_testing.fixtures import make_request_builder, make_request_dispatcher
78

89

10+
@fixture
911
def use_connect_request_dispatcher(
1012
context: Context,
1113
api_key: Optional[str] = None,
@@ -37,9 +39,24 @@ def use_connect_request_dispatcher(
3739
)
3840
context.timeout = timeout
3941
context.max_attempts = max_attempts
40-
context.request = {}
4142

43+
use_connect_request_store(context)
4244

45+
46+
@fixture
47+
def use_connect_request_store(context: Context, reset: bool = False):
48+
"""
49+
Provides a simple way initialize (or reset) the request store.
50+
51+
:param context: Context
52+
:param reset: bool True to reset the request store.
53+
:return: None
54+
"""
55+
if not hasattr(context, 'request') or reset:
56+
context.request = {}
57+
58+
59+
@fixture
4360
def use_connect_request_builder(context: Context, parameters: Optional[dict] = None):
4461
"""
4562
Provides a connect request builder into the behave Context object.

connect/devops_testing/bdd/steps.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ def _raise_exception_on_request(*args, **kwargs):
2121

2222

2323
def _request_is_process(context: Context):
24-
context.request = context.connect.provision_request(
24+
if isinstance(context.request, dict) and context.request.get('id') is not None:
25+
context.builder.with_id(context.request.get('id'))
26+
27+
context.request.update(context.connect.provision_request(
2528
request=context.builder.build(),
2629
timeout=context.timeout,
2730
max_attempt=context.max_attempts,
28-
)
31+
))
2932

3033

3134
def _with_checkbox_parameter(context: Context, parameter: str, values: str, checked: bool):
@@ -70,11 +73,14 @@ def tier_configuration_request_is_processed(context: Context):
7073
@step('tier config request')
7174
def tier_config_request(context: Context):
7275
context.builder = context.builder.from_default_tier_config()
76+
context.builder = context.builder.with_tier_configuration_account('random')
7377

7478

7579
@step('asset request')
7680
def asset_request(context: Context):
7781
context.builder = context.builder.from_default_asset()
82+
context.builder = context.builder.with_asset_tier_customer('random')
83+
context.builder = context.builder.with_asset_tier_tier1('random')
7884

7985

8086
@step('request with id "{request_id}"')
@@ -92,6 +98,21 @@ def with_tier_config_account(context: Context, account_id: str):
9298
context.builder.with_tier_configuration_account(account_id)
9399

94100

101+
@step('request with asset customer "{customer_id}"')
102+
def with_asset_tier_customer(context: Context, customer_id: str):
103+
context.builder.with_asset_tier_customer(customer_id)
104+
105+
106+
@step('request with asset tier1 "{tier1_id}"')
107+
def with_asset_tier_tier1(context: Context, tier1_id: str):
108+
context.builder.with_asset_tier_tier1(tier1_id)
109+
110+
111+
@step('request with asset tier2 "{tier2_id}"')
112+
def with_asset_tier_tier2(context: Context, tier2_id: str):
113+
context.builder.with_asset_tier_tier2(tier2_id)
114+
115+
95116
@step('request with product "{product_id}"')
96117
def with_product_id(context: Context, product_id: str):
97118
handler = _get_request_handler(

connect/devops_testing/request.py

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from connect.client import ConnectClient
88
from connect.devops_testing.utils import find_by_id, merge, request_model, request_parameters
99

10+
from faker import Faker
11+
1012
import json
1113
import time
1214

@@ -26,58 +28,7 @@
2628
"type": "preview",
2729
},
2830
"params": [],
29-
"tiers": {
30-
"customer": {
31-
"id": "TA-0000-0000-0000",
32-
"external_id": "00000",
33-
"name": "Customer Name",
34-
"external_uid": "00000000-0000-0000-0000-000000000000",
35-
"contact_info": {
36-
"address_line1": "Address Line 1",
37-
"address_line2": "Address Line 2",
38-
"country": "US",
39-
"state": "California",
40-
"city": "Irvine",
41-
"postal_code": "00000",
42-
"contact": {
43-
"first_name": "First",
44-
"last_name": "Last",
45-
"email": "[email protected]",
46-
"phone_number": {
47-
"country_code": "+1",
48-
"area_code": "555",
49-
"phone_number": "8677089",
50-
"extension": "",
51-
},
52-
},
53-
},
54-
},
55-
"tier1": {
56-
"id": "TA-0-0000-0000-0000",
57-
"external_id": "00000",
58-
"name": "Tier 1 Name",
59-
"external_uid": "00000000-0000-0000-0000-000000000000",
60-
"contact_info": {
61-
"address_line1": "Address Line 1",
62-
"address_line2": "Address Line 2",
63-
"country": "US",
64-
"state": "California",
65-
"city": "Irvine",
66-
"postal_code": "00000",
67-
"contact": {
68-
"first_name": "First",
69-
"last_name": "Last",
70-
"email": "[email protected]",
71-
"phone_number": {
72-
"country_code": "+1",
73-
"area_code": "555",
74-
"phone_number": "8677089",
75-
"extension": "",
76-
},
77-
},
78-
},
79-
},
80-
},
31+
"tiers": {},
8132
"items": [],
8233
"configuration": {
8334
"params": [],
@@ -93,9 +44,7 @@
9344
"status": "pending",
9445
"configuration": {
9546
"status": "active",
96-
"account": {
97-
"id": "TA-0000-0000-0000",
98-
},
47+
"account": {},
9948
"product": {
10049
"id": "PRD-000-000-000",
10150
"status": "published",
@@ -135,6 +84,33 @@ def __init__(self, request: Optional[dict] = None):
13584

13685
self._original = deepcopy(request)
13786
self._request = deepcopy(request)
87+
self._fake = Faker(['en_US'])
88+
89+
def _make_tier(self, tier_type: str = 'customer') -> dict:
90+
return {
91+
"name": self._fake.company(),
92+
"type": tier_type,
93+
"external_uid": f"{self._fake.uuid4()}",
94+
"contact_info": {
95+
"address_line1": f"{self._fake.pyint(100, 999)}, {self._fake.street_name()}",
96+
"address_line2": self._fake.secondary_address(),
97+
"city": self._fake.city(),
98+
"state": self._fake.state(),
99+
"postal_code": self._fake.zipcode(),
100+
"country": self._fake.country(),
101+
"contact": {
102+
"first_name": self._fake.first_name(),
103+
"last_name": self._fake.last_name(),
104+
"email": self._fake.company_email(),
105+
"phone_number": {
106+
"country_code": f"+{self._fake.pyint(1, 99)}",
107+
"area_code": f"{self._fake.pyint(1, 99)}",
108+
"phone_number": f"{self._fake.pyint(1, 999999)}",
109+
"extension": f"{self._fake.pyint(1, 100)}",
110+
},
111+
},
112+
},
113+
}
138114

139115
@classmethod
140116
def from_file(cls, path: str) -> Builder:
@@ -190,6 +166,24 @@ def with_asset_marketplace(self, marketplace_id: str) -> Builder:
190166
self._request = merge(self._request, {'asset': {'marketplace': {'id': marketplace_id}}})
191167
return self
192168

169+
def with_asset_tier_customer(self, customer_id: str) -> Builder:
170+
customer = self._make_tier('customer') if customer_id == 'random' else {'id': customer_id}
171+
172+
self._request = merge(self._request, {'asset': {'tiers': {'customer': customer}}})
173+
return self
174+
175+
def with_asset_tier_tier1(self, tier1_id: str) -> Builder:
176+
tier1 = self._make_tier('reseller') if tier1_id == 'random' else {'id': tier1_id}
177+
178+
self._request = merge(self._request, {'asset': {'tiers': {'tier1': tier1}}})
179+
return self
180+
181+
def with_asset_tier_tier2(self, tier2_id: str) -> Builder:
182+
tier2 = self._make_tier('reseller') if tier2_id == 'random' else {'id': tier2_id}
183+
184+
self._request = merge(self._request, {'asset': {'tiers': {'tier2': tier2}}})
185+
return self
186+
193187
def with_asset_param(
194188
self,
195189
param_id: str,
@@ -307,8 +301,10 @@ def with_tier_configuration_marketplace(self, marketplace_id: str) -> Builder:
307301
self._request = merge(self._request, {'configuration': {'marketplace': {'id': marketplace_id}}})
308302
return self
309303

310-
def with_tier_configuration_account(self, account_id: str) -> Builder:
311-
self._request = merge(self._request, {'configuration': {'account': {'id': account_id}}})
304+
def with_tier_configuration_account(self, account_id: str = 'random') -> Builder:
305+
account = self._make_tier('reseller') if account_id == 'random' else {'id': account_id}
306+
307+
self._request = merge(self._request, {'configuration': {'account': account}})
312308
return self
313309

314310
def with_tier_configuration_tier_level(self, level: int) -> Builder:

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ classifiers = [
2626
python = "^3.8"
2727
behave = "^1.2.*"
2828
connect-openapi-client = "^23.*"
29+
Faker = "^9.8.2"
2930

3031
[tool.poetry.dev-dependencies]
3132
pytest = "^6.1.2"

tests/bdd/test_steps.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
subscription_request_is_processed, tier_configuration_request_is_processed, parameter_value_contains,
99
parameter_value_error_contains, parameter_value_match, parameter_value_error_match, with_parameter_checked,
1010
with_parameter_not_checked, with_parameter_without_value, with_parameter_without_value_error,
11+
with_asset_tier_customer, with_asset_tier_tier1, with_asset_tier_tier2,
1112
)
1213

1314
PARAM_ID_A = 'PARAM_ID_A'
@@ -94,6 +95,9 @@ def test_step_should_create_an_asset_request(behave_context):
9495
with_status(behave_context, 'pending')
9596
with_product_id(behave_context, 'PRD-000-000-000')
9697
with_marketplace_id(behave_context, 'MP-00000')
98+
with_asset_tier_customer(behave_context, 'TA-0000-0000-0000')
99+
with_asset_tier_tier1(behave_context, 'TA-0000-0000-0001')
100+
with_asset_tier_tier2(behave_context, 'TA-0000-0000-0002')
97101
with_parameter_with_value(behave_context, PARAM_ID_A, PARAM_ID_A_VALUE)
98102
with_parameter_with_value_error(behave_context, PARAM_ID_A, PARAM_ID_A_VALUE_ERROR)
99103
with_parameter_without_value(behave_context, PARAM_ID_NO_VALUE)
@@ -106,6 +110,9 @@ def test_step_should_create_an_asset_request(behave_context):
106110
assert request['type'] == 'purchase'
107111
assert request['asset']['product']['id'] == 'PRD-000-000-000'
108112
assert request['asset']['marketplace']['id'] == 'MP-00000'
113+
assert request['asset']['tiers']['customer']['id'] == 'TA-0000-0000-0000'
114+
assert request['asset']['tiers']['tier1']['id'] == 'TA-0000-0000-0001'
115+
assert request['asset']['tiers']['tier2']['id'] == 'TA-0000-0000-0002'
109116
assert request['asset']['params'][0]['id'] == PARAM_ID_A
110117
assert request['asset']['params'][0]['value'] == PARAM_ID_A_VALUE
111118
assert request['asset']['params'][0]['value_error'] == PARAM_ID_A_VALUE_ERROR
@@ -144,11 +151,12 @@ def test_step_should_successfully_process_the_request(sync_client_factory, respo
144151
tier_configuration_request_is_processed
145152
]
146153

154+
behave_context.request = {'id': 'PR-000-000-000-000'}
155+
147156
for process_step in process_steps:
148157
use_connect_request_builder(context=behave_context)
149158

150159
asset_request(behave_context)
151-
with_id(behave_context, 'PR-000-000-000-000')
152160
with_status(behave_context, 'pending')
153161

154162
mocked_client = sync_client_factory([

tests/test_request.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,25 @@ def test_request_builder_should_build_successfully_a_valid_tier_config_request()
149149
assert request['params'][2]['value_error'] == 'Some value error on configuration'
150150

151151

152+
def test_request_builder_should_build_successfully_a_valid_tier_config_request_with_random_account_data():
153+
request = (Builder()
154+
.with_type('setup')
155+
.with_status('approved')
156+
.with_id('TCR-000-000-000-100')
157+
.with_tier_configuration_id('TC-000-000-000')
158+
.with_tier_configuration_account('random'))
159+
160+
assert request.is_tier_config_request()
161+
162+
request = request.build()
163+
164+
assert request['id'] == 'TCR-000-000-000-100'
165+
assert request['type'] == 'setup'
166+
assert request['status'] == 'approved'
167+
168+
assert 'contact_info' in request['configuration']['account']
169+
170+
152171
def test_request_builder_should_build_successfully_a_valid_request_from_file_template():
153172
template = os.path.dirname(__file__) + TPL_REQUEST_ASSET
154173

0 commit comments

Comments
 (0)