Files
kernalix7--winpodx/tests/test_first_run_prompt.py
wehub-resource-sync 3e779be6f3
CI / lint (push) Failing after 13m4s
CI / test (3.11, ubuntu-latest) (push) Failing after 2m4s
CI / test (3.13, ubuntu-latest) (push) Successful in 13m30s
CI / test (3.14, ubuntu-latest) (push) Successful in 17m21s
CI / test (3.12, ubuntu-latest) (push) Successful in 17m55s
CI / discover-apps-ps (push) Successful in 1m56s
CI / test (3.9, ubuntu-latest) (push) Successful in 13m17s
CI / test (3.10, ubuntu-latest) (push) Successful in 26m21s
CI / audit (push) Successful in 13m38s
Deploy site / deploy (push) Has been cancelled
CI / test (3.14, ubuntu-24.04-arm) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:32:37 +08:00

195 lines
6.1 KiB
Python

# SPDX-License-Identifier: MIT
"""Tests for the CLI first-run setup prompt (#255 PR 1)."""
from __future__ import annotations
from winpodx.cli.first_run import (
_SKIP_COMMANDS,
maybe_run_first_run_prompt,
should_prompt,
)
from winpodx.core.config import Config
def _captured_print():
captured: list[str] = []
def _emit(line: str) -> None:
captured.append(line)
return _emit, captured
def _scripted_input(answers: list[str]):
it = iter(answers)
def _read(_prompt: str) -> str:
return next(it)
return _read
class TestShouldPrompt:
def test_none_command_skips(self):
assert should_prompt(None) is False
def test_skip_list_commands_skip(self):
for cmd in _SKIP_COMMANDS:
assert should_prompt(cmd) is False, f"{cmd} should be in skip list"
def test_other_commands_eligible(self, monkeypatch):
# Force TTY=True so the stdin check passes.
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
for cmd in ("app", "pod", "check", "timesync", "debloat"):
assert should_prompt(cmd) is True
def test_non_tty_stdin_skips(self, monkeypatch):
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
assert should_prompt("app") is False
class TestMaybeRunFirstRunPrompt:
def test_skipped_command_returns_false(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
out, _ = _captured_print()
ran = maybe_run_first_run_prompt(
"info",
input_fn=_scripted_input([]),
print_fn=out,
)
assert ran is False
def test_already_initialized_returns_false(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
cfg = Config()
cfg.pod.initialized = True
cfg.save()
out, _ = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input([]),
print_fn=out,
)
assert ran is False
def test_no_answer_skips(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save() # initialized = False
out, lines = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input(["n"]),
print_fn=out,
)
assert ran is False
joined = "\n".join(lines)
assert "Run setup now" in joined
def test_eof_skips(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save()
def _eof(_prompt):
raise EOFError
out, _ = _captured_print()
ran = maybe_run_first_run_prompt("app", input_fn=_eof, print_fn=out)
assert ran is False
def test_yes_invokes_setup_auto(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save()
called_with: dict = {}
def _fake_handle_setup(args):
called_with["non_interactive"] = args.non_interactive
called_with["customize"] = args.customize
monkeypatch.setattr("winpodx.cli.setup_cmd.handle_setup", _fake_handle_setup)
out, _ = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input(["y"]),
print_fn=out,
)
assert ran is True
assert called_with["non_interactive"] is True
assert called_with["customize"] is False
def test_custom_invokes_setup_customize(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save()
called_with: dict = {}
def _fake_handle_setup(args):
called_with["non_interactive"] = args.non_interactive
called_with["customize"] = args.customize
monkeypatch.setattr("winpodx.cli.setup_cmd.handle_setup", _fake_handle_setup)
out, _ = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input(["c"]),
print_fn=out,
)
assert ran is True
assert called_with["non_interactive"] is False
assert called_with["customize"] is True
def test_empty_answer_defaults_to_yes(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save()
called: list = []
monkeypatch.setattr(
"winpodx.cli.setup_cmd.handle_setup",
lambda args: called.append(("non_interactive", args.non_interactive)),
)
out, _ = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input([""]),
print_fn=out,
)
assert ran is True
assert called[0] == ("non_interactive", True)
def test_unrecognised_answer_skips(self, monkeypatch, tmp_path):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
Config().save()
out, lines = _captured_print()
ran = maybe_run_first_run_prompt(
"app",
input_fn=_scripted_input(["bogus"]),
print_fn=out,
)
assert ran is False
joined = "\n".join(lines)
assert "Unrecognised choice" in joined
class TestInstallSourceDetection:
"""Smoke test the install_source module from a known path."""
def test_unknown_when_no_binary(self):
from winpodx.utils.install_source import detect
result = detect(binary_path="/nonexistent/path/winpodx")
assert result.kind == "unknown"
assert "not detected" in result.label