Skip to content

Commit 73ba5aa

Browse files
Copilotchefgs
andcommitted
Fix init wizard: add Space instruction to checkbox so selections are captured
Co-authored-by: chefgs <7605658+chefgs@users.noreply.github.com>
1 parent 38052b7 commit 73ba5aa

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

cli/devopsos.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def init(
9393
selected = inquirer.checkbox(
9494
message=f"Select {group_label}:",
9595
choices=group_info["choices"],
96+
instruction="(Space to select, ↑↓ to navigate, Enter to confirm)",
9697
).execute()
9798
selected_by_group[group_label] = selected
9899

cli/test_cli.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,99 @@ def test_init_dir_option_creates_devcontainer_in_specified_dir():
6969
"Expected devcontainer.env.json inside .devcontainer"
7070
)
7171

72+
def test_init_checkbox_includes_space_instruction():
73+
"""Each checkbox prompt must include an instruction so users know to press Space."""
74+
from unittest.mock import MagicMock, patch, call
75+
from typer.testing import CliRunner
76+
from cli.devopsos import app
77+
78+
checkbox_mock = MagicMock()
79+
checkbox_mock.execute.return_value = []
80+
81+
confirm_proceed = MagicMock()
82+
confirm_proceed.execute.return_value = True
83+
confirm_skip = MagicMock()
84+
confirm_skip.execute.return_value = False
85+
86+
with tempfile.TemporaryDirectory() as tmp:
87+
with patch("cli.devopsos.inquirer.checkbox", return_value=checkbox_mock) as mock_cb, \
88+
patch("cli.devopsos.inquirer.confirm",
89+
side_effect=[confirm_proceed, confirm_skip]):
90+
CliRunner().invoke(app, ["init", "--dir", tmp])
91+
92+
# Every checkbox call must pass a non-empty 'instruction' keyword argument
93+
assert mock_cb.call_count > 0, "checkbox was never called"
94+
for c in mock_cb.call_args_list:
95+
instruction = c.kwargs.get("instruction", "")
96+
assert instruction, (
97+
f"checkbox call missing 'instruction' kwarg — "
98+
f"users cannot tell they must press Space to select items. Call: {c}"
99+
)
100+
assert "space" in instruction.lower(), (
101+
f"instruction '{instruction}' should mention Space so users know how to select"
102+
)
103+
104+
def test_init_selections_written_to_config():
105+
"""Selections made in the wizard must be reflected as True in devcontainer.env.json."""
106+
from unittest.mock import MagicMock, patch
107+
from typer.testing import CliRunner
108+
from cli.devopsos import app
109+
110+
# Simulate user selecting one tool in each group
111+
selections = [
112+
["python"], # Languages
113+
["docker"], # Containerization
114+
["gradle"], # Build Tools
115+
["sonarqube"], # Test & Quality
116+
["kubectl", "k9s"], # Kubernetes
117+
["github_actions"], # CI/CD & Deploy
118+
["prometheus"], # SRE & Monitoring
119+
]
120+
sel_iter = iter(selections)
121+
122+
def _checkbox_factory(**kwargs):
123+
mock = MagicMock()
124+
mock.execute.return_value = next(sel_iter)
125+
return mock
126+
127+
text_mock = MagicMock()
128+
text_mock.execute.return_value = "3.11"
129+
130+
confirm_proceed = MagicMock()
131+
confirm_proceed.execute.return_value = True
132+
confirm_skip = MagicMock()
133+
confirm_skip.execute.return_value = False
134+
135+
with tempfile.TemporaryDirectory() as tmp:
136+
with patch("cli.devopsos.inquirer.checkbox", side_effect=_checkbox_factory), \
137+
patch("cli.devopsos.inquirer.text", return_value=text_mock), \
138+
patch("cli.devopsos.inquirer.confirm",
139+
side_effect=[confirm_proceed, confirm_skip]):
140+
result = CliRunner().invoke(app, ["init", "--dir", tmp])
141+
142+
assert result.exit_code == 0, result.output
143+
144+
cfg_path = Path(tmp) / ".devcontainer" / "devcontainer.env.json"
145+
assert cfg_path.exists()
146+
cfg = json.loads(cfg_path.read_text())
147+
148+
# Selected tools must be True; unselected must be False
149+
assert cfg["languages"]["python"] is True, "python should be True"
150+
assert cfg["languages"]["java"] is False, "java should be False"
151+
assert cfg["cicd"]["docker"] is True, "docker should be True"
152+
assert cfg["cicd"]["podman"] is False, "podman should be False"
153+
assert cfg["cicd"]["github_actions"] is True, "github_actions should be True"
154+
# kubectl and helm are mapped into the "cicd" section
155+
assert cfg["cicd"]["kubectl"] is True, "kubectl should be True"
156+
assert cfg["cicd"]["helm"] is False, "helm (not selected) should be False"
157+
assert cfg["kubernetes"]["k9s"] is True, "k9s should be True"
158+
assert cfg["kubernetes"]["flux"] is False, "flux should be False"
159+
assert cfg["build_tools"]["gradle"] is True, "gradle should be True"
160+
assert cfg["build_tools"]["maven"] is False, "maven should be False"
161+
assert cfg["code_analysis"]["sonarqube"] is True, "sonarqube should be True"
162+
assert cfg["devops_tools"]["prometheus"] is True, "prometheus should be True"
163+
assert cfg["devops_tools"]["grafana"] is False, "grafana should be False"
164+
72165
def test_scaffold_unknown():
73166
result = _run(["-m", "cli.devopsos", "scaffold", "unknown"])
74167
assert "Unknown scaffold target" in result.stdout

0 commit comments

Comments
 (0)