mirror of
https://github.com/pdxlocations/contact.git
synced 2026-11-02 17:02:19 +01:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82e7456248 | ||
|
|
7b21c9c886 | ||
|
|
392d236a40 | ||
|
|
546fab099c |
No files matched your search
@@ -141,6 +141,12 @@ def display_menu() -> tuple[object, object]:
|
||||
current_value = field_info[1] if isinstance(field_info, tuple) else ""
|
||||
full_key = ".".join(transformed_path + [option])
|
||||
display_name = field_mapping.get(full_key, option)
|
||||
if menu_state.menu_path == ["Main Menu", "Channels"] and isinstance(field_info, dict):
|
||||
# Keep slot keys for navigation/saving, but label rows with the
|
||||
# configured name. Empty names retain their slot label.
|
||||
channel_name = field_info.get("name", (None, ""))[1]
|
||||
if isinstance(channel_name, str) and channel_name.strip():
|
||||
display_name = channel_name
|
||||
|
||||
if full_key.startswith("config.network.ipv4_config.") and option in {"ip", "gateway", "subnet", "dns"}:
|
||||
if isinstance(current_value, int):
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "contact"
|
||||
version = "1.6.9"
|
||||
version = "1.6.11"
|
||||
description = "This Python curses client for Meshtastic is a terminal-based client designed to manage device settings, enable mesh chat communication, and handle configuration backups and restores."
|
||||
authors = [
|
||||
{name = "Ben Lipsey",email = "ben@pdxlocations.com"}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from argparse import Namespace
|
||||
from contextlib import ExitStack
|
||||
from types import SimpleNamespace
|
||||
import unittest
|
||||
from unittest import mock
|
||||
@@ -10,6 +11,36 @@ from tests.test_support import reset_singletons
|
||||
|
||||
|
||||
class ControlUiTests(unittest.TestCase):
|
||||
def test_channel_list_renders_names_without_changing_slot_keys(self):
|
||||
from meshtastic.protobuf import channel_pb2, config_pb2, module_config_pb2
|
||||
from contact.ui.menus import generate_menu_from_protobuf
|
||||
from contact.utilities.singleton import menu_state
|
||||
|
||||
channels = [channel_pb2.Channel(settings=channel_pb2.ChannelSettings(name=name))
|
||||
for name in ("Local", "Local", "", " ")]
|
||||
node = SimpleNamespace(
|
||||
localConfig=config_pb2.Config(), moduleConfig=module_config_pb2.ModuleConfig(),
|
||||
getChannelByChannelIndex=lambda i: channels[i] if i < len(channels) else None,
|
||||
)
|
||||
menu_state.menu_path = ["Main Menu", "Channels"]
|
||||
menu_state.current_menu = generate_menu_from_protobuf(None, node=node)["Main Menu"]["Channels"]
|
||||
win, pad = mock.Mock(), mock.Mock()
|
||||
win.getbegyx.return_value = (2, 2)
|
||||
win.getmaxyx.return_value = (10, 80)
|
||||
with ExitStack() as stack:
|
||||
for name, value in (("LINES", 24), ("COLS", 100)):
|
||||
stack.enter_context(mock.patch.object(control_ui.curses, name, value, create=True))
|
||||
stack.enter_context(mock.patch.object(control_ui.curses, "newwin", return_value=win))
|
||||
stack.enter_context(mock.patch.object(control_ui.curses, "newpad", return_value=pad))
|
||||
stack.enter_context(mock.patch.object(control_ui.curses, "curs_set"))
|
||||
stack.enter_context(mock.patch.object(control_ui, "get_menu_width", return_value=80))
|
||||
for name in ("get_color", "draw_help_window", "draw_arrows"):
|
||||
stack.enter_context(mock.patch.object(control_ui, name, return_value=0))
|
||||
control_ui.display_menu()
|
||||
labels = [call.args[2].strip() for call in pad.addstr.call_args_list]
|
||||
self.assertEqual(labels, ["Local", "Local", "Channel 3", "Channel 4"])
|
||||
self.assertEqual(list(menu_state.current_menu), [f"Channel {i}" for i in range(1, 5)])
|
||||
|
||||
def setUp(self) -> None:
|
||||
reset_singletons()
|
||||
|
||||
|
||||
Reference in new issue
Block a user