初始提交
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import importlib
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
import pytest
|
||||
|
||||
BACKEND_DIR = Path(__file__).resolve().parents[3]
|
||||
|
||||
if str(BACKEND_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(BACKEND_DIR))
|
||||
|
||||
|
||||
def _load_module(module_name: str) -> ModuleType:
|
||||
sys.modules.pop(module_name, None)
|
||||
sys.modules.pop('cli', None)
|
||||
return importlib.import_module(module_name)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def backend_dir() -> Path:
|
||||
return BACKEND_DIR
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def load_module() -> Callable[[str], ModuleType]:
|
||||
return _load_module
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cli_main(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.main')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_run_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.app_run')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cache_clear_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.cache_clear')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def db_upgrade_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.db_upgrade')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def gen_export_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.gen_export')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def gen_import_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.gen_import')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def prod_check_flow(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.wizard.flows.prod_check')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def exit_codes(load_module: Callable[[str], ModuleType]) -> ModuleType:
|
||||
return load_module('cli.exit_codes')
|
||||
@@ -0,0 +1,33 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_app_run_wizard_execs_nested_cli_after_confirmation(
|
||||
monkeypatch: MonkeyPatch,
|
||||
app_run_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['dev', False, True])
|
||||
monkeypatch.setattr(
|
||||
app_run_flow.AppRunWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': next(answers),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_run_flow.AppRunWizardFlow.context_factory,
|
||||
'build_readonly',
|
||||
lambda env, output: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_run_flow.AppRunWizardFlow,
|
||||
'nested_live_command_runner',
|
||||
lambda *arguments: captured.update({'arguments': arguments}),
|
||||
)
|
||||
|
||||
app_run_flow.run_app_run_wizard()
|
||||
|
||||
assert captured['arguments'] == ('app', 'run', '--env=dev')
|
||||
@@ -0,0 +1,88 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_cache_clear_wizard_cancels_when_confirmation_rejected(
|
||||
monkeypatch: MonkeyPatch,
|
||||
cache_clear_flow: ModuleType,
|
||||
exit_codes: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['dev', 'cache-name', 'sys_config', True, False])
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': next(answers),
|
||||
prompt_choice=lambda prompt_text, choices, default_value: next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': next(answers),
|
||||
prompt_optional_text=lambda prompt_text, default_value='': '',
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: captured.update({'ctx': ctx, 'result': result}),
|
||||
)
|
||||
|
||||
cache_clear_flow.run_cache_clear_wizard('text')
|
||||
|
||||
assert captured['ctx'].env == 'dev'
|
||||
assert captured['result'].exit_code == exit_codes.GUARD_REJECTED
|
||||
assert captured['result'].data['message'] == '已取消向导执行:wizard cache-clear'
|
||||
|
||||
|
||||
def test_cache_clear_wizard_accepts_default_context_values(
|
||||
monkeypatch: MonkeyPatch,
|
||||
cache_clear_flow: ModuleType,
|
||||
) -> None:
|
||||
captured_defaults: dict[str, object] = {}
|
||||
captured_confirm_defaults: list[tuple[str, bool]] = []
|
||||
answers = iter(['dev', 'cache-name', 'sys_config', True, False])
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': captured_defaults.update({'env': default_env}) or next(answers),
|
||||
prompt_choice=lambda prompt_text, choices, default_value: (
|
||||
captured_defaults.update({'mode': default_value}) or next(answers)
|
||||
),
|
||||
prompt_required_text=lambda prompt_text, default_value='': (
|
||||
captured_defaults.update({'cache_name': default_value}) or next(answers)
|
||||
),
|
||||
prompt_optional_text=lambda prompt_text, default_value='': '',
|
||||
prompt_confirm=lambda prompt_text, default_value=False: (
|
||||
captured_confirm_defaults.append((prompt_text, default_value)) or next(answers)
|
||||
),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cache_clear_flow.CacheClearWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: None,
|
||||
)
|
||||
|
||||
cache_clear_flow.run_cache_clear_wizard(
|
||||
'text',
|
||||
default_env='dev',
|
||||
default_mode='cache-name',
|
||||
default_cache_name='sys_config',
|
||||
default_dry_run=True,
|
||||
)
|
||||
|
||||
assert captured_defaults['env'] == 'dev'
|
||||
assert captured_defaults['mode'] == 'cache-name'
|
||||
assert captured_defaults['cache_name'] == 'sys_config'
|
||||
assert captured_confirm_defaults[0][1] is True
|
||||
@@ -0,0 +1,24 @@
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
from typer.testing import CliRunner
|
||||
|
||||
|
||||
def test_wizard_help_lists_supported_subcommands(
|
||||
monkeypatch: MonkeyPatch,
|
||||
backend_dir: Path,
|
||||
cli_main: ModuleType,
|
||||
) -> None:
|
||||
runner = CliRunner()
|
||||
monkeypatch.chdir(backend_dir)
|
||||
|
||||
result = runner.invoke(cli_main.CLI_APPLICATION_BUILDER.build(), ['wizard', '--help'])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert 'app-run' in result.stdout
|
||||
assert 'db-upgrade' in result.stdout
|
||||
assert 'cache-clear' in result.stdout
|
||||
assert 'gen-export' in result.stdout
|
||||
assert 'gen-import' in result.stdout
|
||||
assert 'prod-check' in result.stdout
|
||||
@@ -0,0 +1,99 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_db_upgrade_wizard_executes_nested_cli_with_confirmed_inputs(
|
||||
monkeypatch: MonkeyPatch,
|
||||
db_upgrade_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': 'dev',
|
||||
prompt_required_text=lambda prompt_text, default_value='': 'head',
|
||||
prompt_confirm=lambda prompt_text, default_value=False: True,
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(
|
||||
env=env,
|
||||
output=output,
|
||||
allow_prod=allow_prod,
|
||||
yes=yes,
|
||||
dry_run=dry_run,
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow,
|
||||
'nested_command_runner',
|
||||
lambda *arguments, parse_json=False: SimpleNamespace(
|
||||
returncode=0,
|
||||
payload={'ok': True, 'message': '数据库已升级到 head', 'dryRun': True},
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow.execution_service,
|
||||
'complete_payload',
|
||||
lambda ctx, payload, default_exit_code=0: captured.update(
|
||||
{
|
||||
'ctx': ctx,
|
||||
'payload': payload,
|
||||
'default_exit_code': default_exit_code,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
db_upgrade_flow.run_db_upgrade_wizard('json')
|
||||
|
||||
assert captured['ctx'].env == 'dev'
|
||||
assert captured['ctx'].output == 'json'
|
||||
assert captured['ctx'].dry_run is True
|
||||
assert captured['payload'] == {'ok': True, 'message': '数据库已升级到 head', 'dryRun': True}
|
||||
|
||||
|
||||
def test_db_upgrade_wizard_accepts_default_context_values(
|
||||
monkeypatch: MonkeyPatch,
|
||||
db_upgrade_flow: ModuleType,
|
||||
) -> None:
|
||||
captured_defaults: dict[str, object] = {}
|
||||
captured_confirm_defaults: list[tuple[str, bool]] = []
|
||||
confirm_answers = iter([True, False])
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': captured_defaults.update({'env': default_env}) or 'dev',
|
||||
prompt_required_text=lambda prompt_text, default_value='': (
|
||||
captured_defaults.update({'revision': default_value}) or 'head'
|
||||
),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: (
|
||||
captured_confirm_defaults.append((prompt_text, default_value)) or next(confirm_answers)
|
||||
),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
db_upgrade_flow.DbUpgradeWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: None,
|
||||
)
|
||||
|
||||
db_upgrade_flow.run_db_upgrade_wizard(
|
||||
'text',
|
||||
default_env='dev',
|
||||
default_revision='head',
|
||||
default_dry_run=True,
|
||||
)
|
||||
|
||||
assert captured_defaults['env'] == 'dev'
|
||||
assert captured_defaults['revision'] == 'head'
|
||||
assert captured_confirm_defaults[0][1] is True
|
||||
@@ -0,0 +1,120 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_gen_export_wizard_executes_nested_cli_with_selected_tables(
|
||||
monkeypatch: MonkeyPatch,
|
||||
gen_export_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['dev', 'sys_user,sys_role', 'zip', 'build/demo.zip', True, True])
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': next(answers),
|
||||
prompt_choice=lambda prompt_text, choices, default_value: next(answers),
|
||||
prompt_optional_text=lambda prompt_text, default_value='': next(answers),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(
|
||||
env=env,
|
||||
output=output,
|
||||
allow_prod=allow_prod,
|
||||
yes=yes,
|
||||
dry_run=dry_run,
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow,
|
||||
'nested_command_runner',
|
||||
lambda *arguments, parse_json=False: SimpleNamespace(
|
||||
returncode=0,
|
||||
payload={
|
||||
'ok': True,
|
||||
'message': '代码导出演练完成,未执行实际导出',
|
||||
'dryRun': True,
|
||||
'mode': 'zip',
|
||||
'tableNames': ['sys_user', 'sys_role'],
|
||||
'outputFile': '/tmp/demo.zip',
|
||||
},
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow.execution_service,
|
||||
'complete_payload',
|
||||
lambda ctx, payload, default_exit_code=0: captured.update(
|
||||
{
|
||||
'ctx': ctx,
|
||||
'payload': payload,
|
||||
'default_exit_code': default_exit_code,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
gen_export_flow.run_gen_export_wizard('json')
|
||||
|
||||
assert captured['ctx'].env == 'dev'
|
||||
assert captured['ctx'].output == 'json'
|
||||
assert captured['ctx'].dry_run is True
|
||||
assert captured['payload']['tableNames'] == ['sys_user', 'sys_role']
|
||||
assert captured['payload']['mode'] == 'zip'
|
||||
|
||||
|
||||
def test_gen_export_wizard_accepts_default_context_values(
|
||||
monkeypatch: MonkeyPatch,
|
||||
gen_export_flow: ModuleType,
|
||||
) -> None:
|
||||
captured_defaults: dict[str, object] = {}
|
||||
captured_confirm_defaults: list[tuple[str, bool]] = []
|
||||
answers = iter(['dev', 'sys_user', 'zip', 'build/demo.zip', True, False])
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': captured_defaults.update({'env': default_env}) or next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': (
|
||||
captured_defaults.update({'table_names': default_value}) or next(answers)
|
||||
),
|
||||
prompt_choice=lambda prompt_text, choices, default_value: (
|
||||
captured_defaults.update({'mode': default_value}) or next(answers)
|
||||
),
|
||||
prompt_optional_text=lambda prompt_text, default_value='': (
|
||||
captured_defaults.update({'output_file': default_value}) or next(answers)
|
||||
),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: (
|
||||
captured_confirm_defaults.append((prompt_text, default_value)) or next(answers)
|
||||
),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_export_flow.GenExportWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: None,
|
||||
)
|
||||
|
||||
gen_export_flow.run_gen_export_wizard(
|
||||
'text',
|
||||
default_env='dev',
|
||||
default_table_names='sys_user',
|
||||
default_mode='zip',
|
||||
default_output_file='build/demo.zip',
|
||||
default_dry_run=True,
|
||||
)
|
||||
|
||||
assert captured_defaults['env'] == 'dev'
|
||||
assert captured_defaults['table_names'] == 'sys_user'
|
||||
assert captured_defaults['mode'] == 'zip'
|
||||
assert captured_defaults['output_file'] == 'build/demo.zip'
|
||||
assert captured_confirm_defaults[0][1] is True
|
||||
@@ -0,0 +1,164 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_gen_import_wizard_executes_nested_cli_with_selected_tables(
|
||||
monkeypatch: MonkeyPatch,
|
||||
gen_import_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['dev', 'sys_user,sys_role', True, True])
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': next(answers),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(
|
||||
env=env,
|
||||
output=output,
|
||||
allow_prod=allow_prod,
|
||||
yes=yes,
|
||||
dry_run=dry_run,
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow,
|
||||
'nested_command_runner',
|
||||
lambda *arguments, parse_json=False: SimpleNamespace(
|
||||
returncode=0,
|
||||
payload={
|
||||
'ok': True,
|
||||
'message': '物理表导入预演完成,未执行实际导入',
|
||||
'dryRun': True,
|
||||
'tableNames': ['sys_user', 'sys_role'],
|
||||
},
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.execution_service,
|
||||
'complete_payload',
|
||||
lambda ctx, payload, default_exit_code=0: captured.update(
|
||||
{
|
||||
'ctx': ctx,
|
||||
'payload': payload,
|
||||
'default_exit_code': default_exit_code,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
gen_import_flow.run_gen_import_wizard('json')
|
||||
|
||||
assert captured['ctx'].env == 'dev'
|
||||
assert captured['ctx'].output == 'json'
|
||||
assert captured['ctx'].dry_run is True
|
||||
assert captured['payload']['tableNames'] == ['sys_user', 'sys_role']
|
||||
|
||||
|
||||
def test_gen_import_wizard_accepts_default_context_values(
|
||||
monkeypatch: MonkeyPatch,
|
||||
gen_import_flow: ModuleType,
|
||||
) -> None:
|
||||
captured_defaults: dict[str, object] = {}
|
||||
captured_confirm_defaults: list[tuple[str, bool]] = []
|
||||
answers = iter(['dev', 'sys_user', True, False])
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': captured_defaults.update({'env': default_env}) or next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': (
|
||||
captured_defaults.update({'table_names': default_value}) or next(answers)
|
||||
),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: (
|
||||
captured_confirm_defaults.append((prompt_text, default_value)) or next(answers)
|
||||
),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: None,
|
||||
)
|
||||
|
||||
gen_import_flow.run_gen_import_wizard(
|
||||
'text',
|
||||
default_env='dev',
|
||||
default_table_names='sys_user',
|
||||
default_dry_run=True,
|
||||
)
|
||||
|
||||
assert captured_defaults['env'] == 'dev'
|
||||
assert captured_defaults['table_names'] == 'sys_user'
|
||||
assert captured_confirm_defaults[0][1] is True
|
||||
|
||||
|
||||
def test_gen_import_wizard_falls_back_to_failure_payload_when_nested_result_has_no_dict_payload(
|
||||
monkeypatch: MonkeyPatch,
|
||||
gen_import_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['dev', 'sys_notice', True, True])
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='dev': next(answers),
|
||||
prompt_required_text=lambda prompt_text, default_value='': next(answers),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.context_factory,
|
||||
'build_regular',
|
||||
lambda env, output, allow_prod, yes, dry_run: SimpleNamespace(
|
||||
env=env,
|
||||
output=output,
|
||||
allow_prod=allow_prod,
|
||||
yes=yes,
|
||||
dry_run=dry_run,
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow,
|
||||
'nested_command_runner',
|
||||
lambda *arguments, parse_json=False: SimpleNamespace(
|
||||
returncode=0,
|
||||
stdout='OK SUCCESS\nmessage: 导入表结构演练完成,未执行实际写入',
|
||||
stderr='',
|
||||
payload=[],
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gen_import_flow.GenImportWizardFlow.execution_service,
|
||||
'complete_payload',
|
||||
lambda ctx, payload, default_exit_code=0: captured.update(
|
||||
{
|
||||
'ctx': ctx,
|
||||
'payload': payload,
|
||||
'default_exit_code': default_exit_code,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
gen_import_flow.run_gen_import_wizard('text')
|
||||
|
||||
assert captured['ctx'].env == 'dev'
|
||||
assert captured['payload'] == {
|
||||
'ok': False,
|
||||
'message': '代码生成导入向导执行失败',
|
||||
'error': 'OK SUCCESS\nmessage: 导入表结构演练完成,未执行实际写入',
|
||||
'exit_code': 0,
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
from types import ModuleType, SimpleNamespace
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
|
||||
def test_prod_check_wizard_aggregates_nested_cli_payloads(
|
||||
monkeypatch: MonkeyPatch,
|
||||
prod_check_flow: ModuleType,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
answers = iter(['prod', True, True])
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='prod': next(answers),
|
||||
prompt_confirm=lambda prompt_text, default_value=False: next(answers),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow.context_factory,
|
||||
'build_readonly',
|
||||
lambda env, output: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
|
||||
def fake_run_nested_cli_command(*arguments: str, parse_json: bool = False) -> SimpleNamespace:
|
||||
del parse_json
|
||||
if arguments[0:2] == ('app', 'env'):
|
||||
return SimpleNamespace(
|
||||
payload={
|
||||
'ok': True,
|
||||
'runtime': {
|
||||
'cliEnv': 'prod',
|
||||
'configEnv': 'prod',
|
||||
'envFile': '.env.prod',
|
||||
'envFileExists': True,
|
||||
},
|
||||
}
|
||||
)
|
||||
if arguments[0:2] == ('app', 'doctor'):
|
||||
return SimpleNamespace(payload={'ok': True, 'message': '应用启动前检查通过'})
|
||||
return SimpleNamespace(
|
||||
payload={
|
||||
'ok': True,
|
||||
'config': {
|
||||
'name': 'demo',
|
||||
'host': '0.0.0.0',
|
||||
'port': 9099,
|
||||
'dbType': 'mysql',
|
||||
'redisHost': '127.0.0.1',
|
||||
'redisPort': 6379,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow,
|
||||
'nested_command_runner',
|
||||
fake_run_nested_cli_command,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow.execution_service,
|
||||
'complete_payload',
|
||||
lambda ctx, payload, default_exit_code=0: captured.update({'ctx': ctx, 'payload': payload}),
|
||||
)
|
||||
|
||||
prod_check_flow.run_prod_check_wizard('json')
|
||||
|
||||
assert captured['ctx'].env == 'prod'
|
||||
assert captured['payload']['ok'] is True
|
||||
assert captured['payload']['doctor']['message'] == '应用启动前检查通过'
|
||||
assert captured['payload']['runtime']['cliEnv'] == 'prod'
|
||||
assert captured['payload']['config']['name'] == 'demo'
|
||||
|
||||
|
||||
def test_prod_check_wizard_accepts_default_context_values(
|
||||
monkeypatch: MonkeyPatch,
|
||||
prod_check_flow: ModuleType,
|
||||
) -> None:
|
||||
captured_defaults: dict[str, object] = {}
|
||||
confirm_answers = iter([True, False])
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow,
|
||||
'prompt_service',
|
||||
SimpleNamespace(
|
||||
prompt_env=lambda default_env='prod': captured_defaults.update({'env': default_env}) or 'prod',
|
||||
prompt_confirm=lambda prompt_text, default_value=False: (
|
||||
captured_defaults.update({'include_config': default_value}) or next(confirm_answers)
|
||||
),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow.context_factory,
|
||||
'build_readonly',
|
||||
lambda env, output: SimpleNamespace(env=env, output=output),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
prod_check_flow.ProdCheckWizardFlow.execution_service,
|
||||
'complete_result',
|
||||
lambda ctx, result: None,
|
||||
)
|
||||
|
||||
prod_check_flow.run_prod_check_wizard(
|
||||
'text',
|
||||
default_env='prod',
|
||||
default_include_config=True,
|
||||
)
|
||||
|
||||
assert captured_defaults['env'] == 'prod'
|
||||
assert captured_defaults['include_config'] is True
|
||||
Reference in New Issue
Block a user