diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-15 02:06:35 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-15 02:06:35 +0200 |
| commit | 419af660eeb8a4403e37a63c54a15586d04d5a8e (patch) | |
| tree | b0c0cdd831a5fb2864d5bedf581681aa0ec86023 /packages/meshbay-cli/tests/test_e2e_local.py | |
| parent | 47583c5e405f3011a526df73cc9485c46598f214 (diff) | |
| download | meshbay-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.py | 51 |
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 |