Files
openvpncertupdate/tests/test_dialogs.py
Vlad Doloman 567c3e9759 fix: replace Ctrl-S confirm with Ctrl-G in Certificate Details form
Ctrl-S (0x13) is the XOFF flow-control character; terminals intercept it
before curses sees it, causing output suspension in Konsole and others.
Replaced with Ctrl-G (0x07 / BEL) which has no terminal-level meaning.
Updated hint bar and test stub accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 13:47:14 +03:00

98 lines
3.3 KiB
Python

"""Tests for TUI DIALOGS (show_confirm, show_cert_form).
Uses the same mock-curses approach as test_widgets.py — no real terminal needed.
"""
from unittest.mock import MagicMock, patch
import curses as _curses
# Stub curses constants before importing the module under test, mirroring
# what test_widgets.py does for InputField's dependencies.
_curses.color_pair = lambda x: 0
_curses.curs_set = lambda x: None
_curses.A_UNDERLINE = 0
_curses.A_BOLD = 0
_curses.KEY_BACKSPACE = 263
_curses.KEY_LEFT = 260
_curses.KEY_RIGHT = 261
_curses.KEY_HOME = 262
_curses.KEY_END = 360
_curses.KEY_DC = 330
_curses.KEY_BTAB = 353
_curses.KEY_F5 = 269
_curses.KEY_ENTER = 343
from openvpncertupdate import show_confirm, show_cert_form, CertFormResult
def _make_stdscr(rows=40, cols=120):
"""Return a minimal MagicMock that looks like a curses stdscr."""
stdscr = MagicMock()
stdscr.getmaxyx.return_value = (rows, cols)
return stdscr
def _make_win(rows=20, cols=60):
"""Return a minimal MagicMock for the subwindow created by curses.newwin."""
win = MagicMock()
win.getmaxyx.return_value = (rows, cols)
return win
# ---------------------------------------------------------------------------
# show_confirm tests
# ---------------------------------------------------------------------------
def test_show_confirm_yes():
"""Pressing 'y' returns True."""
stdscr = _make_stdscr()
win = _make_win()
win.getch.side_effect = [ord("y")]
with patch("curses.newwin", return_value=win):
result = show_confirm(stdscr, "Do you want to continue?")
assert result is True
def test_show_confirm_esc():
"""Pressing Escape (27) returns False."""
stdscr = _make_stdscr()
win = _make_win()
win.getch.side_effect = [27]
with patch("curses.newwin", return_value=win):
result = show_confirm(stdscr, "Do you want to continue?")
assert result is False
# ---------------------------------------------------------------------------
# show_cert_form tests
# ---------------------------------------------------------------------------
def test_show_cert_form_cancel():
"""Pressing Escape returns a CertFormResult with confirmed=False."""
stdscr = _make_stdscr()
win = _make_win(rows=20, cols=70)
win.getch.side_effect = [27]
with patch("curses.newwin", return_value=win):
result = show_cert_form(stdscr, cn="alice", email="alice@example.com")
assert isinstance(result, CertFormResult)
assert result.confirmed is False
def test_show_cert_form_confirm():
"""Pressing Enter three times advances through all 3 fields and confirms.
The form has 3 active fields (cn, email, password). Enter on field 0
advances to field 1; Enter on field 1 advances to field 2; Enter on
field 2 (the last) confirms. We therefore need 3 Enter keypresses.
"""
stdscr = _make_stdscr()
win = _make_win(rows=20, cols=70)
# Three Enter keypresses to advance through each field and confirm.
win.getch.side_effect = [10, 10, 10]
with patch("curses.newwin", return_value=win):
result = show_cert_form(stdscr, cn="bob", email="bob@example.com")
assert isinstance(result, CertFormResult)
assert result.confirmed is True
assert result.cn == "bob"
assert result.email == "bob@example.com"
assert len(result.password) > 0