Test dialog selections cancellation defaults and secret handling
This commit is contained in:
@@ -13,6 +13,86 @@ def bash(code, *args):
|
||||
|
||||
|
||||
class EnrollTests(unittest.TestCase):
|
||||
def run_ui(self, action, answer='', rc=0, tool='whiptail', rows=24):
|
||||
lib = SOURCE.rsplit('\nmain\n', 1)[0]
|
||||
lib = lib.replace('set -Eeuo pipefail', 'set -Eeo pipefail', 1)
|
||||
lib = lib.replace("[[ $EUID == 0 ]] || fail 'Bitte auf dem Proxmox-Host als root starten.'", ':')
|
||||
lib = lib.replace('for tool in pct timeout python3; do command -v "$tool" >/dev/null || fail "$tool fehlt auf dem Host."; done', ':')
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
p = Path(td)
|
||||
mocks = r'''
|
||||
exec 3<>"$1/terminal"
|
||||
exec 5>"$1/dialog-args"
|
||||
TERM=xterm
|
||||
command() {
|
||||
if [[ $1 == -v && ( $2 == whiptail || $2 == dialog ) ]]; then [[ $2 == $MOCK_TOOL ]];
|
||||
else builtin command "$@"; fi
|
||||
}
|
||||
stty() { printf '%s 100\n' "$MOCK_ROWS"; }
|
||||
whiptail() { printf '%s\n' "$@" >&5; printf '%s' "$MOCK_ANSWER" >&4; return "$MOCK_RC"; }
|
||||
dialog() { whiptail "$@"; }
|
||||
init_ui
|
||||
IDS=(101 103); NAMES[101]='first'; NAMES[103]='partial'
|
||||
TS[101]=0; WZ[101]=0; TUN[101]=0
|
||||
TS[103]=1; WZ[103]=0; TUN[103]=1
|
||||
'''
|
||||
setup = 'MOCK_TOOL=$2; MOCK_ROWS=$3; MOCK_RC=$4; MOCK_ANSWER=$5\n'
|
||||
r = bash('UI_TEST_ARGS=("$@"); set --\n' + lib + '\nset -- "${UI_TEST_ARGS[@]}"\n' +
|
||||
setup + mocks + action, td, tool, str(rows), str(rc), answer)
|
||||
return r, (p/'dialog-args').read_text(), (p/'terminal').read_text()
|
||||
|
||||
def test_checklist_captures_multiple_ids_and_shows_component_status(self):
|
||||
r, args, terminal = self.run_ui('choose_lxcs; echo "SELECTION=$SELECTION"', '101\n103\n')
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('SELECTION=101 103', r.stdout)
|
||||
self.assertIn('--separate-output', args)
|
||||
self.assertIn('--checklist', args)
|
||||
self.assertIn('partial | Tailscale: vorhanden | Wazuh: fehlt', args)
|
||||
self.assertEqual(args.splitlines().count('OFF'), 2)
|
||||
|
||||
def test_cancel_or_empty_checklist_stops_selection(self):
|
||||
for rc, answer in ((1, ''), (255, ''), (0, '')):
|
||||
r, args, terminal = self.run_ui(
|
||||
'if choose_lxcs; then echo CONTINUE; else echo CANCEL; fi', answer, rc)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('CANCEL', r.stdout)
|
||||
self.assertNotIn('CONTINUE', r.stdout)
|
||||
|
||||
def test_yes_no_dialog_preserves_default_and_handles_escape(self):
|
||||
r, args, terminal = self.run_ui('yes_no "Sudo? [j/N]" 0; echo "ANSWER=$REPLY"', rc=1)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('ANSWER=0', r.stdout)
|
||||
self.assertIn('--defaultno', args)
|
||||
self.assertNotIn('[j/N]', args)
|
||||
r, args, terminal = self.run_ui('yes_no "SSH? [J/n]" 1; echo "ANSWER=$REPLY"')
|
||||
self.assertIn('ANSWER=1', r.stdout)
|
||||
self.assertNotIn('--defaultno', args)
|
||||
r, args, terminal = self.run_ui('yes_no "SSH?" 1; echo CONTINUE', rc=255)
|
||||
self.assertNotEqual(r.returncode, 0)
|
||||
self.assertNotIn('CONTINUE', r.stdout)
|
||||
|
||||
def test_password_dialog_does_not_echo_secret_or_put_it_in_arguments(self):
|
||||
r, args, terminal = self.run_ui('secret "Key:"; echo "LENGTH=${#REPLY}"', 'fixture-private-key')
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('--passwordbox', args)
|
||||
self.assertNotIn('--insecure', args)
|
||||
self.assertNotIn('fixture-private-key', r.stdout + r.stderr + args + terminal)
|
||||
|
||||
def test_input_dialog_and_dialog_fallback(self):
|
||||
r, args, terminal = self.run_ui('ask "Nutzer:" "existing"; echo "INPUT=$REPLY"', 'chosen', tool='dialog')
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('--inputbox', args)
|
||||
self.assertIn('existing', args)
|
||||
self.assertIn('INPUT=chosen', r.stdout)
|
||||
|
||||
def test_no_tool_or_small_terminal_uses_text_without_installing_anything(self):
|
||||
for tool, rows in (('none', 24), ('whiptail', 12)):
|
||||
r, args, terminal = self.run_ui(
|
||||
'ask() { REPLY="101 103"; }; choose_lxcs; echo "SELECTION=$SELECTION"', tool=tool, rows=rows)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
self.assertIn('SELECTION=101 103', r.stdout)
|
||||
self.assertEqual(args, '')
|
||||
|
||||
def test_syntax(self):
|
||||
for code in (SOURCE, WORKER):
|
||||
r = subprocess.run(['bash', '-n'], input=code, text=True, capture_output=True)
|
||||
|
||||
Reference in New Issue
Block a user