Files
connexion/tests/test_cli.py
Robbe Sneyders 073f0d446e Update examples for Connexion 3.0 (#1615)
This PR updates the examples for Connexion 3.0 and merges them for
OpenAPI and Swagger.

2 examples required some changes to make them work:
- The reverse proxy example required some fixes to the
SwaggerUIMiddleware to leverage the `root_path` correctly. This is
included in the PR.
- The enforced defaults example requires the json validator to adapt the
body and pass it on. We currently pass on the original body after
validation, and I'm not sure if we should change this. I'll submit a
separate PR to discuss this.
2022-12-30 20:34:19 +01:00

237 lines
7.6 KiB
Python

import logging
from unittest.mock import MagicMock
import connexion
import pytest
from click.testing import CliRunner
from connexion.cli import main
from conftest import FIXTURES_FOLDER
@pytest.fixture()
def mock_app_run(mock_get_function_from_name):
test_server = MagicMock(wraps=connexion.FlaskApp(__name__))
test_server.run = MagicMock(return_value=True)
test_app = MagicMock(return_value=test_server)
mock_get_function_from_name.return_value = test_app
return test_app
@pytest.fixture()
def mock_get_function_from_name(monkeypatch):
get_function_from_name = MagicMock()
monkeypatch.setattr(
"connexion.cli.connexion.utils.get_function_from_name", get_function_from_name
)
return get_function_from_name
@pytest.fixture()
def expected_arguments():
"""
Default values arguments used to call `connexion.App` by cli.
"""
return {
"options": {
"serve_spec": True,
"swagger_ui": True,
"swagger_path": None,
"swagger_url": None,
},
"auth_all_paths": False,
}
@pytest.fixture()
def spec_file():
return str(FIXTURES_FOLDER / "simple/swagger.yaml")
def test_print_version():
runner = CliRunner()
result = runner.invoke(main, ["--version"], catch_exceptions=False)
assert f"Connexion {connexion.__version__}" in result.output
def test_run_missing_spec():
runner = CliRunner()
result = runner.invoke(main, ["run"], catch_exceptions=False)
assert "Missing argument" in result.output
def test_run_simple_spec(mock_app_run, spec_file):
runner = CliRunner()
runner.invoke(main, ["run", spec_file], catch_exceptions=False)
app_instance = mock_app_run()
app_instance.run.assert_called()
def test_run_spec_with_host(mock_app_run, spec_file):
runner = CliRunner()
runner.invoke(
main, ["run", spec_file, "--host", "custom.host"], catch_exceptions=False
)
app_instance = mock_app_run()
app_instance.run.assert_called()
def test_run_no_options_all_default(mock_app_run, expected_arguments, spec_file):
runner = CliRunner()
runner.invoke(main, ["run", spec_file], catch_exceptions=False)
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_hide_spec(mock_app_run, expected_arguments, spec_file):
runner = CliRunner()
runner.invoke(main, ["run", spec_file, "--hide-spec"], catch_exceptions=False)
expected_arguments["options"]["serve_spec"] = False
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_hide_console_ui(mock_app_run, expected_arguments, spec_file):
runner = CliRunner()
runner.invoke(main, ["run", spec_file, "--hide-console-ui"], catch_exceptions=False)
expected_arguments["options"]["swagger_ui"] = False
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_console_ui_from(mock_app_run, expected_arguments, spec_file):
user_path = "/some/path/here"
runner = CliRunner()
runner.invoke(
main, ["run", spec_file, "--console-ui-from", user_path], catch_exceptions=False
)
expected_arguments["options"]["swagger_path"] = user_path
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_console_ui_url(mock_app_run, expected_arguments, spec_file):
user_url = "/console_ui_test"
runner = CliRunner()
runner.invoke(
main, ["run", spec_file, "--console-ui-url", user_url], catch_exceptions=False
)
expected_arguments["options"]["swagger_url"] = user_url
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_auth_all_paths(mock_app_run, expected_arguments, spec_file):
runner = CliRunner()
runner.invoke(main, ["run", spec_file, "--auth-all-paths"], catch_exceptions=False)
expected_arguments["auth_all_paths"] = True
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_in_very_verbose_mode(
mock_app_run, expected_arguments, spec_file, monkeypatch
):
logging_config = MagicMock(name="connexion.cli.logging.basicConfig")
monkeypatch.setattr("connexion.cli.logging.basicConfig", logging_config)
runner = CliRunner()
runner.invoke(main, ["run", spec_file, "-vv"], catch_exceptions=False)
logging_config.assert_called_with(level=logging.DEBUG)
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_in_verbose_mode(mock_app_run, expected_arguments, spec_file, monkeypatch):
logging_config = MagicMock(name="connexion.cli.logging.basicConfig")
monkeypatch.setattr("connexion.cli.logging.basicConfig", logging_config)
runner = CliRunner()
runner.invoke(main, ["run", spec_file, "-v"], catch_exceptions=False)
logging_config.assert_called_with(level=logging.INFO)
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
def test_run_using_option_base_path(mock_app_run, expected_arguments, spec_file):
runner = CliRunner()
runner.invoke(
main, ["run", spec_file, "--base-path", "/foo"], catch_exceptions=False
)
expected_arguments = dict(
base_path="/foo",
resolver_error=None,
validate_responses=False,
strict_validation=False,
)
mock_app_run().add_api.assert_called_with(spec_file, **expected_arguments)
def test_run_unimplemented_operations_and_stub(mock_app_run):
runner = CliRunner()
spec_file = str(FIXTURES_FOLDER / "missing_implementation/swagger.yaml")
with pytest.raises(AttributeError):
runner.invoke(main, ["run", spec_file], catch_exceptions=False)
# yet can be run with --stub option
result = runner.invoke(main, ["run", spec_file, "--stub"], catch_exceptions=False)
assert result.exit_code == 0
spec_file = str(FIXTURES_FOLDER / "module_does_not_exist/swagger.yaml")
with pytest.raises(ImportError):
runner.invoke(main, ["run", spec_file], catch_exceptions=False)
# yet can be run with --stub option
result = runner.invoke(main, ["run", spec_file, "--stub"], catch_exceptions=False)
assert result.exit_code == 0
def test_run_unimplemented_operations_and_mock(mock_app_run):
runner = CliRunner()
spec_file = str(FIXTURES_FOLDER / "missing_implementation/swagger.yaml")
with pytest.raises(AttributeError):
runner.invoke(main, ["run", spec_file], catch_exceptions=False)
# yet can be run with --mock option
result = runner.invoke(
main, ["run", spec_file, "--mock=all"], catch_exceptions=False
)
assert result.exit_code == 0
def test_run_with_wsgi_containers(mock_app_run, spec_file):
runner = CliRunner()
# missing gevent
result = runner.invoke(
main, ["run", spec_file, "-w", "gevent"], catch_exceptions=False
)
assert "gevent library is not installed" in result.output
assert result.exit_code == 1
# missing tornado
result = runner.invoke(
main, ["run", spec_file, "-w", "tornado"], catch_exceptions=False
)
assert "tornado library is not installed" in result.output
assert result.exit_code == 1
# using flask
result = runner.invoke(
main, ["run", spec_file, "-w", "flask"], catch_exceptions=False
)
assert result.exit_code == 0
def test_run_with_wsgi_server_and_server_opts(mock_app_run, spec_file):
runner = CliRunner()
result = runner.invoke(
main, ["run", spec_file, "-w", "flask", "-s", "flask"], catch_exceptions=False
)
assert "these options are mutually exclusive" in result.output
assert result.exit_code == 2