aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-cli/tests/test_e2e_local.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-15 02:06:35 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-15 02:06:35 +0200
commit419af660eeb8a4403e37a63c54a15586d04d5a8e (patch)
treeb0c0cdd831a5fb2864d5bedf581681aa0ec86023 /packages/meshbay-cli/tests/test_e2e_local.py
parent47583c5e405f3011a526df73cc9485c46598f214 (diff)
downloadmeshbay-419af660eeb8a4403e37a63c54a15586d04d5a8e.tar.gz
feat(cli): chat — Tier 2 check on the signing device, interactive room
Each message's signing device is checked against the group's roster as the page checks it (a port of transport-roster.js, held to it by the parity test): chains of countersignatures walked from each account's roots, the keys accepted per account and node kept in the store, the roster read again once before a key is called changed. Only "changed" is said, under the message; --json carries every verdict. chat with no group opens the interactive chat: the groups, then one group's conversation IRC-style with pushed messages arriving live and a line to write in; Esc or /part goes back to the groups, /quit or Ctrl+Q quits. Like the bare command, it opens on the sign-in screen when nothing is stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/tests/test_e2e_local.py')
-rw-r--r--packages/meshbay-cli/tests/test_e2e_local.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/packages/meshbay-cli/tests/test_e2e_local.py b/packages/meshbay-cli/tests/test_e2e_local.py
index 19f5ca9..cf6a3b9 100644
--- a/packages/meshbay-cli/tests/test_e2e_local.py
+++ b/packages/meshbay-cli/tests/test_e2e_local.py
@@ -1017,3 +1017,54 @@ def test_chat_between_the_command_line_and_the_application(world):
break
assert time.monotonic() < deadline, (r.stdout, r.stderr)
time.sleep(1)
+
+
+async def test_the_interactive_chat_against_the_real_node(world, monkeypatch, tmp_path):
+ """The room open on a real group: a message posted from another run arrives
+ live, and one typed in the room is read back by `chat`. Runs after the
+ chat test above, on the machine it linked."""
+ from meshbay_cli import __main__ as main_module
+ from meshbay_cli.commands.context import Context
+ from meshbay_cli.tui.app import MeshBayApp
+ from meshbay_cli.tui.chat import ChatGroupsScreen, ChatRoomScreen
+ from textual.widgets import DataTable, Input, RichLog
+
+ group = _handle()
+ r = await asyncio.to_thread(cli, world, "chat", "-1", group, home="cli-chat")
+ assert r.returncode == 0, "the chat test above did not leave this machine linked"
+ monkeypatch.setenv("MESHBAY_CLI_HOME", str(world["root"] / "cli-chat"))
+ app = MeshBayApp(Context(main_module.build_parser().parse_args(
+ ["--hub", world["hub_url"]])), ChatGroupsScreen)
+
+ def text(screen) -> str:
+ return "\n".join("".join(s.text for s in strip)
+ for strip in screen.query_one(RichLog).lines)
+
+ async def until(pilot, cond, timeout=60):
+ deadline = time.monotonic() + timeout
+ while not cond():
+ assert time.monotonic() < deadline, [n.message for n in app._notifications]
+ await pilot.pause(0.1)
+
+ async with app.run_test(size=(140, 40)) as pilot:
+ await until(pilot, lambda: isinstance(app.screen, ChatGroupsScreen)
+ and app.screen.query_one(DataTable).row_count >= 1)
+ await pilot.press("enter")
+ await until(pilot, lambda: isinstance(app.screen, ChatRoomScreen))
+ room = app.screen
+ await until(pilot, lambda: "hello from the browser" in text(room))
+ assert "cannot be read" not in text(room) and "not seen before" not in text(room)
+
+ r = await asyncio.to_thread(cli, world, "chat", group, "-m",
+ "live from another run", home="cli-chat")
+ assert r.returncode == 0, r.stderr
+ await until(pilot, lambda: f"<{USERNAME}> live from another run" in text(room))
+
+ room.query_one(Input).value = "typed in the room"
+ await pilot.press("enter")
+ await until(pilot, lambda: f"<{USERNAME}> typed in the room" in text(room))
+ await pilot.press("escape")
+ await until(pilot, lambda: isinstance(app.screen, ChatGroupsScreen))
+
+ r = await asyncio.to_thread(cli, world, "chat", "-1", group, home="cli-chat")
+ assert r.stdout.strip().endswith(f"{USERNAME}: typed in the room"), r.stdout