Files
MeshTerm/tests/test_config.py
T
Jean-Pierre MartineauandClaude Opus 4.8 965783d276 Network (TCP) companions: connect, remember, and manage from the picker
Add TCP alongside serial and BLE as a first-class companion transport, end to
end: discovery/connection/selection learn a tcp: stable_id and host:port target,
--tcp and TCP config profiles reach a WiFi board or network proxy, and a network
companion -- which isn't discoverable -- is rebuilt into the picker from its
remembered endpoint.

Device picker gains the network-device affordances:
- "Add a network device" prompts for host:port, smoke-tests it, and remembers it.
  The row is marked "- experimental" in the cautionary hue.
- Delete on a network row opens a chromeless Cancel/Remove confirm (Cancel left,
  Remove right and default: Enter removes, Esc cancels), then DeviceStore.forget
  prunes it and re-draws the list. Serial/BLE rows stay inert.
- The "Del remove" footer atom now follows the highlight, surfacing on the box's
  bottom border only while the cursor sits on a deletable row; the box is sized
  to the fullest footer so it never widens mid-navigation.

Folds in the accompanying courier, channels, and config refinements built along
the way. Screens stay readable at 72 cols; full suite green (745 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 02:38:11 -04:00

69 lines
2.7 KiB
Python

"""Tests for application settings loading."""
from __future__ import annotations
from pathlib import Path
from meshterm.core.config import DIRECT_MESSAGE_MAX_SOFT_RETRIES, Settings
def test_connect_on_start_defaults_true() -> None:
"""Eager connect-at-launch is the default when nothing is configured."""
assert Settings().connect_on_start is True
def test_connect_on_start_loads_from_toml(tmp_path: Path) -> None:
"""The connect_on_start preference round-trips from the config file."""
config = tmp_path / "config.toml"
config.write_text("connect_on_start = false\n", encoding="utf-8")
assert Settings.load(config).connect_on_start is False
def test_direct_message_soft_retries_defaults_to_two() -> None:
"""Two soft retries (three tries total) is the out-of-the-box direct-message budget."""
assert Settings().direct_message_soft_retries == 2
assert DIRECT_MESSAGE_MAX_SOFT_RETRIES == 2
def test_direct_message_soft_retries_loads_from_toml(tmp_path: Path) -> None:
"""The soft-retry budget round-trips from the config file."""
config = tmp_path / "config.toml"
config.write_text("direct_message_soft_retries = 1\n", encoding="utf-8")
assert Settings.load(config).direct_message_soft_retries == 1
def test_direct_message_soft_retries_clamped_to_range(tmp_path: Path) -> None:
"""Out-of-range values are clamped to 0..2 so a DM never floods the mesh (or is dropped)."""
hot = tmp_path / "hot.toml"
hot.write_text("direct_message_soft_retries = 9\n", encoding="utf-8")
assert Settings.load(hot).direct_message_soft_retries == DIRECT_MESSAGE_MAX_SOFT_RETRIES
cold = tmp_path / "cold.toml"
cold.write_text("direct_message_soft_retries = -4\n", encoding="utf-8")
assert Settings.load(cold).direct_message_soft_retries == 0
def test_tcp_profile_inferred_and_loaded(tmp_path: Path) -> None:
"""A profile with a ``host`` loads as a TCP profile and exposes its host:port endpoint."""
config = tmp_path / "config.toml"
config.write_text(
"[profiles.wifi]\n"
'host = "192.168.1.50"\n'
"tcp_port = 6000\n",
encoding="utf-8",
)
profile = Settings.load(config).profiles["wifi"]
assert profile.is_tcp and profile.transport == "tcp"
assert profile.host == "192.168.1.50" and profile.tcp_port == 6000
assert profile.tcp_endpoint == "192.168.1.50:6000"
def test_tcp_profile_defaults_port(tmp_path: Path) -> None:
"""A TCP profile naming only a host takes the default port in its endpoint."""
config = tmp_path / "config.toml"
config.write_text(
'[profiles.wifi]\nhost = "meshcore.local"\n', encoding="utf-8"
)
profile = Settings.load(config).profiles["wifi"]
assert profile.is_tcp and profile.tcp_endpoint == "meshcore.local:5000"