stoobly-agent 1.4.2__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stoobly_agent/__init__.py +1 -1
- stoobly_agent/app/cli/helpers/handle_mock_service.py +6 -2
- stoobly_agent/app/cli/helpers/request_facade.py +5 -1
- stoobly_agent/app/cli/scaffold/constants.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +1 -0
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +19 -19
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +1 -1
- stoobly_agent/app/cli/scaffold/templates/constants.py +3 -3
- stoobly_agent/app/cli/scaffold/templates/factory.py +5 -5
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/configure +1 -8
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/fixtures.yml +1 -1
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/configure +1 -8
- stoobly_agent/app/cli/scaffold/templates/workflow/test/fixtures.yml +1 -1
- stoobly_agent/app/cli/scaffold/workflow_command.py +3 -3
- stoobly_agent/app/cli/scaffold/workflow_create_command.py +2 -2
- stoobly_agent/app/cli/scaffold_cli.py +5 -5
- stoobly_agent/app/proxy/context.py +4 -0
- stoobly_agent/app/proxy/handle_mock_service.py +81 -54
- stoobly_agent/app/proxy/handle_record_service.py +15 -3
- stoobly_agent/app/proxy/handle_replay_service.py +44 -18
- stoobly_agent/app/proxy/handle_test_service.py +75 -16
- stoobly_agent/app/proxy/intercept_handler.py +11 -16
- stoobly_agent/app/proxy/intercept_settings.py +17 -4
- stoobly_agent/app/proxy/mitmproxy/request_facade.py +5 -2
- stoobly_agent/app/proxy/mitmproxy/response_facade.py +5 -4
- stoobly_agent/app/proxy/mock/eval_fixtures_service.py +78 -14
- stoobly_agent/app/proxy/mock/eval_request_service.py +2 -2
- stoobly_agent/app/proxy/record/join_request_service.py +7 -8
- stoobly_agent/app/proxy/record/upload_request_service.py +2 -2
- stoobly_agent/app/proxy/replay/replay_request_service.py +4 -4
- stoobly_agent/app/proxy/test/helpers/upload_test_service.py +2 -2
- stoobly_agent/app/proxy/utils/allowed_request_service.py +3 -3
- stoobly_agent/app/proxy/utils/response_handler.py +0 -2
- stoobly_agent/app/proxy/utils/rewrite.py +72 -0
- stoobly_agent/app/settings/constants/request_component.py +4 -1
- stoobly_agent/cli.py +35 -28
- stoobly_agent/config/constants/intercept_policy.py +2 -0
- stoobly_agent/config/constants/mock_policy.py +4 -2
- stoobly_agent/config/constants/record_policy.py +4 -2
- stoobly_agent/config/constants/replay_policy.py +4 -2
- stoobly_agent/public/{18-es2015.583f191cc7ad512ee262.js → 18-es2015.503207073756a9c8211a.js} +1 -1
- stoobly_agent/public/{18-es5.583f191cc7ad512ee262.js → 18-es5.503207073756a9c8211a.js} +1 -1
- stoobly_agent/public/index.html +1 -1
- stoobly_agent/public/{main-es2015.2cc16523aa3fcaba51e5.js → main-es2015.d682619f3d6d53d64c6a.js} +1 -1
- stoobly_agent/public/{main-es5.2cc16523aa3fcaba51e5.js → main-es5.d682619f3d6d53d64c6a.js} +1 -1
- stoobly_agent/public/{runtime-es2015.b914470164e4d6e75d96.js → runtime-es2015.8c1efed946fc02c923fc.js} +1 -1
- stoobly_agent/public/{runtime-es5.b914470164e4d6e75d96.js → runtime-es5.8c1efed946fc02c923fc.js} +1 -1
- stoobly_agent/test/app/cli/helpers/openapi_endpoint_adapter_test.py +2 -1
- stoobly_agent/test/app/cli/scaffold/e2e_test.py +2 -2
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- stoobly_agent/test/app/proxy/mock/eval_fixtures_service_test.py +140 -71
- stoobly_agent/test/cli/lifecycle_hooks_test.py +66 -0
- stoobly_agent/test/cli/mock_test.py +53 -29
- stoobly_agent/test/cli/record_test.py +67 -0
- stoobly_agent/test/mock_data/lifecycle_hooks.py +35 -0
- {stoobly_agent-1.4.2.dist-info → stoobly_agent-1.5.0.dist-info}/LICENSE +1 -1
- {stoobly_agent-1.4.2.dist-info → stoobly_agent-1.5.0.dist-info}/METADATA +7 -12
- {stoobly_agent-1.4.2.dist-info → stoobly_agent-1.5.0.dist-info}/RECORD +62 -58
- /stoobly_agent/app/cli/scaffold/templates/workflow/mock/{fixtures/.keep → public/.gitignore} +0 -0
- /stoobly_agent/app/cli/scaffold/templates/workflow/test/{fixtures/.keep → public/.gitignore} +0 -0
- {stoobly_agent-1.4.2.dist-info → stoobly_agent-1.5.0.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.4.2.dist-info → stoobly_agent-1.5.0.dist-info}/entry_points.txt +0 -0
stoobly_agent/cli.py
CHANGED
@@ -159,6 +159,7 @@ def run(**kwargs):
|
|
159
159
|
@click.option('--format', type=click.Choice([RAW_FORMAT]), help='Format response')
|
160
160
|
@click.option('-H', '--header', multiple=True, help='Pass custom header(s) to server')
|
161
161
|
@click.option('--lifecycle-hooks-path', help='Path to lifecycle hooks script.')
|
162
|
+
@click.option('-o', '--output', help='Write to file instead of stdout')
|
162
163
|
@ConditionalDecorator(lambda f: click.option('--project-key')(f), is_remote)
|
163
164
|
@click.option('--public-directory-path', help='Path to public files. Used for mocking requests.')
|
164
165
|
@click.option('--response-fixtures-path', help='Path to response fixtures yaml. Used for mocking requests.')
|
@@ -169,16 +170,7 @@ def mock(**kwargs):
|
|
169
170
|
if kwargs.get('remote_project_key'):
|
170
171
|
validate_project_key(kwargs['remote_project_key'])
|
171
172
|
|
172
|
-
|
173
|
-
validate_scenario_key(kwargs['scenario_key'])
|
174
|
-
|
175
|
-
request = __build_request_from_curl(**kwargs)
|
176
|
-
|
177
|
-
context = ReplayContext.from_python_request(request)
|
178
|
-
response: requests.Response = replay_request(context, {
|
179
|
-
**kwargs,
|
180
|
-
'mode': mode.MOCK,
|
181
|
-
})
|
173
|
+
response = __replay(mode.MOCK, **kwargs)
|
182
174
|
|
183
175
|
if response.status_code == custom_response_codes.NOT_FOUND:
|
184
176
|
content = response.content
|
@@ -186,10 +178,15 @@ def mock(**kwargs):
|
|
186
178
|
sys.exit(1)
|
187
179
|
|
188
180
|
if kwargs['format'] == RAW_FORMAT:
|
189
|
-
print_raw_response(response)
|
181
|
+
print_raw_response(response, kwargs['output'])
|
190
182
|
else:
|
191
183
|
content = response.content
|
192
|
-
|
184
|
+
|
185
|
+
if not kwargs['output']:
|
186
|
+
print(decode(content), end='')
|
187
|
+
else:
|
188
|
+
with open(kwargs['output'], 'w') as fp:
|
189
|
+
fp.write(decode(content))
|
193
190
|
|
194
191
|
@main.command(
|
195
192
|
help="Record request"
|
@@ -197,30 +194,28 @@ def mock(**kwargs):
|
|
197
194
|
@click.option('-d', '--data', default='', help='HTTP POST data')
|
198
195
|
@click.option('--format', type=click.Choice([RAW_FORMAT]), help='Format response')
|
199
196
|
@click.option('-H', '--header', multiple=True, help='Pass custom header(s) to server')
|
197
|
+
@click.option('--lifecycle-hooks-path', help='Path to lifecycle hooks script.')
|
198
|
+
@click.option('-o', '--output', help='Write to file instead of stdout')
|
200
199
|
@ConditionalDecorator(lambda f: click.option('--project-key')(f), is_remote)
|
201
200
|
@click.option('-X', '--request', default='GET', help='Specify request command to use')
|
202
201
|
@click.option('--scenario-key')
|
203
202
|
@click.argument('url')
|
204
203
|
def record(**kwargs):
|
205
|
-
|
206
|
-
validate_scenario_key(kwargs['scenario_key'])
|
207
|
-
|
208
|
-
request = __build_request_from_curl(**kwargs)
|
209
|
-
|
210
|
-
context = ReplayContext.from_python_request(request)
|
211
|
-
response: requests.Response = replay_request(context, {
|
212
|
-
**kwargs,
|
213
|
-
'mode': mode.RECORD,
|
214
|
-
})
|
204
|
+
response = __replay(mode.RECORD, **kwargs)
|
215
205
|
|
216
206
|
if kwargs['format'] == RAW_FORMAT:
|
217
|
-
print_raw_response(response)
|
207
|
+
print_raw_response(response, kwargs['output'])
|
218
208
|
else:
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
209
|
+
content: bytes = response.raw.data
|
210
|
+
|
211
|
+
if not kwargs['output']:
|
212
|
+
try:
|
213
|
+
print(content.decode(json.detect_encoding(content)), end='')
|
214
|
+
except UnicodeDecodeError:
|
215
|
+
print('Warning: Binary output can mess up your terminal.')
|
216
|
+
else:
|
217
|
+
with open(kwargs['output'], 'w') as fp:
|
218
|
+
fp.write(content.decode(json.detect_encoding(content)))
|
224
219
|
|
225
220
|
def __build_request_from_curl(**kwargs):
|
226
221
|
headers = {}
|
@@ -238,3 +233,15 @@ def __build_request_from_curl(**kwargs):
|
|
238
233
|
method=kwargs['request'],
|
239
234
|
url=kwargs['url']
|
240
235
|
)
|
236
|
+
|
237
|
+
def __replay(mode, **kwargs):
|
238
|
+
if kwargs.get('scenario_key'):
|
239
|
+
validate_scenario_key(kwargs['scenario_key'])
|
240
|
+
|
241
|
+
request = __build_request_from_curl(**kwargs)
|
242
|
+
|
243
|
+
context = ReplayContext.from_python_request(request)
|
244
|
+
return replay_request(context, {
|
245
|
+
**kwargs,
|
246
|
+
'mode': mode,
|
247
|
+
})
|