test_prompt_manager.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. """Regression tests for prompt handling."""
  2. from __future__ import annotations
  3. from typing import Any
  4. import pytest
  5. from cli.core.input.prompt_manager import PromptHandler
  6. from cli.core.template.variable import Variable
  7. TEST_REQUIRED_INTEGER = 42
  8. @pytest.mark.parametrize(
  9. "variable_data",
  10. [
  11. {"name": "puid", "type": "int"},
  12. {"name": "database_type", "type": "enum", "config": {"options": ["sqlite", "postgres"]}},
  13. {"name": "disable_local_login", "type": "bool"},
  14. ],
  15. )
  16. def test_optional_prompt_allows_blank_input(
  17. monkeypatch: pytest.MonkeyPatch,
  18. variable_data: dict[str, Any],
  19. ) -> None:
  20. """Optional variables without defaults should accept an empty response."""
  21. prompts: list[dict[str, Any]] = []
  22. def fake_ask(prompt_text: str, default: str = "", show_default: bool = False, **kwargs: Any) -> str:
  23. prompts.append(
  24. {
  25. "prompt_text": prompt_text,
  26. "default": default,
  27. "show_default": show_default,
  28. **kwargs,
  29. }
  30. )
  31. return ""
  32. monkeypatch.setattr("cli.core.input.prompt_manager.Prompt.ask", fake_ask)
  33. variable = Variable(variable_data)
  34. prompt_handler = PromptHandler()
  35. raw_value = prompt_handler._prompt_variable(variable)
  36. assert raw_value is None
  37. assert prompts
  38. assert prompts[0]["default"] == ""
  39. assert prompts[0]["show_default"] is False
  40. def test_required_integer_without_default_still_uses_integer_prompt(monkeypatch: pytest.MonkeyPatch) -> None:
  41. """Required integers should still use the integer prompt path instead of accepting blank input."""
  42. calls: list[tuple[str, Any]] = []
  43. def fake_integer(self, prompt: str, default: int | None = None, **kwargs: Any) -> int:
  44. del self, kwargs
  45. calls.append((prompt, default))
  46. return TEST_REQUIRED_INTEGER
  47. monkeypatch.setattr("cli.core.input.prompt_manager.InputManager.integer", fake_integer)
  48. variable = Variable({"name": "ports_http", "type": "int", "required": True})
  49. prompt_handler = PromptHandler()
  50. assert prompt_handler._prompt_variable(variable) == TEST_REQUIRED_INTEGER
  51. assert calls
  52. @pytest.mark.parametrize("origin", ["config", "var-file", "cli"])
  53. def test_applied_optional_string_defaults_are_shown_and_preserved(
  54. monkeypatch: pytest.MonkeyPatch,
  55. origin: str,
  56. ) -> None:
  57. """Applied defaults from external sources should be visible in prompts and kept on Enter."""
  58. prompts: list[dict[str, Any]] = []
  59. def fake_ask(prompt_text: str, default: str = "", show_default: bool = False, **kwargs: Any) -> str:
  60. prompts.append(
  61. {
  62. "prompt_text": prompt_text,
  63. "default": default,
  64. "show_default": show_default,
  65. **kwargs,
  66. }
  67. )
  68. return default
  69. monkeypatch.setattr("cli.core.input.prompt_manager.Prompt.ask", fake_ask)
  70. variable = Variable({"name": "service_name", "type": "str"})
  71. variable.value = "grafana"
  72. variable.origin = origin
  73. prompt_handler = PromptHandler()
  74. raw_value = prompt_handler._prompt_variable(variable)
  75. assert raw_value == "grafana"
  76. assert prompts
  77. assert prompts[0]["default"] == "grafana"
  78. assert prompts[0]["show_default"] is True
  79. @pytest.mark.parametrize("origin", ["config", "var-file", "cli"])
  80. def test_applied_optional_bool_defaults_are_shown_and_preserved(
  81. monkeypatch: pytest.MonkeyPatch,
  82. origin: str,
  83. ) -> None:
  84. """Applied boolean defaults should use confirm prompts with the current value as default."""
  85. calls: list[tuple[str, Any]] = []
  86. def fake_confirm(self, prompt: str, default: bool | None = None) -> bool:
  87. del self
  88. calls.append((prompt, default))
  89. assert default is True
  90. return default
  91. monkeypatch.setattr("cli.core.input.prompt_manager.InputManager.confirm", fake_confirm)
  92. variable = Variable({"name": "traefik_enabled", "type": "bool"})
  93. variable.value = True
  94. variable.origin = origin
  95. prompt_handler = PromptHandler()
  96. assert prompt_handler._prompt_variable(variable) is True
  97. assert calls