From f3e1471d1ab0893709cb206fa2a3b9e7fbe37874 Mon Sep 17 00:00:00 2001 From: Vlad Doloman Date: Wed, 24 Jun 2026 15:31:12 +0300 Subject: [PATCH] feat: double Esc to exit main menu; fix Cryptgeon test for new payload schema - First Esc in main screen shows "Press Esc again to quit" in footer; second Esc exits. Any other key resets the pending state. - Update test_posts_to_correct_endpoint to expect contents as base64 string and presence of meta field, matching the updated Cryptgeon API payload. Co-Authored-By: Claude Sonnet 4.6 --- openvpncertupdate.py | 14 +++++++++++++- tests/test_cryptgeon.py | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/openvpncertupdate.py b/openvpncertupdate.py index 0ea9e28..6c453f8 100644 --- a/openvpncertupdate.py +++ b/openvpncertupdate.py @@ -745,6 +745,7 @@ def show_main_screen( n_items = n_certs + len(_MENU_ITEMS) checked: set[str] = set(initial_checked) if initial_checked else set() cursor = clamp(initial_cursor, 0, max(0, n_items - 1)) + esc_pending = False def is_cert(idx): return idx < n_certs def menu_item(idx): return _MENU_ITEMS[idx - n_certs] if idx >= n_certs else None @@ -763,7 +764,10 @@ def show_main_screen( pass # Footer hint - hint = " ↑↓:Navigate Space:Check Enter:Confirm R:Revoke A:Toggle view Q:Quit" + if esc_pending: + hint = " Press Esc again to quit" + else: + hint = " ↑↓:Navigate Space:Check Enter:Confirm R:Revoke A:Toggle view Q:Quit" try: stdscr.addstr(sh - 1, 0, hint[:sw], curses.color_pair(COLOR_DISABLED)) except curses.error: @@ -810,6 +814,14 @@ def show_main_screen( draw() key = stdscr.getch() + if key == 27: # Esc + if esc_pending: + return ScreenResult(action=Action.EXIT) + esc_pending = True + continue + + esc_pending = False + if key in (ord("q"), ord("Q")): return ScreenResult(action=Action.EXIT) diff --git a/tests/test_cryptgeon.py b/tests/test_cryptgeon.py index b99338b..5781899 100644 --- a/tests/test_cryptgeon.py +++ b/tests/test_cryptgeon.py @@ -27,7 +27,8 @@ def test_posts_to_correct_endpoint(mock_open): req = mock_open.call_args[0][0] assert req.full_url == "https://cg.example.com/api/notes/" body = json.loads(req.data) - assert isinstance(body["contents"], list) + assert isinstance(body["contents"], str) + assert body["meta"] == "" assert body["views"] == 1 assert body["type"] == "text"