diff options
Diffstat (limited to 'packages/meshbay-cli/tests/test_e2e_local.py')
| -rw-r--r-- | packages/meshbay-cli/tests/test_e2e_local.py | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/packages/meshbay-cli/tests/test_e2e_local.py b/packages/meshbay-cli/tests/test_e2e_local.py index 359ab06..fb251bd 100644 --- a/packages/meshbay-cli/tests/test_e2e_local.py +++ b/packages/meshbay-cli/tests/test_e2e_local.py @@ -1070,6 +1070,82 @@ async def test_the_interactive_chat_against_the_real_node(world, monkeypatch, tm assert r.stdout.strip().endswith(f"{USERNAME}: typed in the room"), r.stdout +async def test_put_and_get_in_the_interactive_chat_against_the_real_node( + world, monkeypatch, tmp_path): + """/put sends a file into the chat's folder on a real node and names it in + the chat, as the page's paperclip does: `chat` and the group page show it as + a file. /get saves a file of that folder into the current directory.""" + 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, ChatLog, ChatRoomScreen + from textual.widgets import DataTable, Input + + group = _handle() + r = await asyncio.to_thread(cli, world, "chat", "-1", group, home="cli-chat") + assert r.returncode == 0, "the chat tests above did not leave this machine linked" + monkeypatch.setenv("MESHBAY_CLI_HOME", str(world["root"] / "cli-chat")) + here = tmp_path / "here" + here.mkdir() + monkeypatch.chdir(here) + sent = secrets.token_bytes(3 * 1024 * 1024 + 17) # several chunks + (here / "from the room.bin").write_bytes(sent) + app = MeshBayApp(Context(main_module.build_parser().parse_args( + ["--hub", world["hub_url"]])), ChatGroupsScreen) + + def said(screen) -> str: + return "\n".join(t for *_, t in screen.query_one(ChatLog)._blocks) + + 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: "typed in the room" in said(room)) + + # No folder chosen for the chat: the first writable root, `share`. + room.query_one(Input).value = "/put from the room.bin" + await pilot.press("enter") + await until(pilot, lambda: "[file: from the room.bin, 3.0 MB]" in said(room)) + assert (world["share"] / "from the room.bin").read_bytes() == sent + + room.query_one(Input).value = "/get notes.txt" + await pilot.press("enter") + await until(pilot, lambda: "Saved " in said(room) or "! " in said(room)) + assert (here / "notes.txt").read_text() == "hello\n", said(room) + await pilot.press("escape") + + r = await asyncio.to_thread(cli, world, "chat", "-1", group, home="cli-chat") + assert r.stdout.strip().endswith(f"{USERNAME}: [file: from the room.bin, 3.0 MB]"), \ + r.stdout + r = await asyncio.to_thread(cli, world, "--json", "chat", "-1", group, home="cli-chat") + assert json.loads(r.stdout)[0]["attachment"] == { + "filename": "from the room.bin", "size": len(sent), "type": "file"} + + if shutil.which("google-chrome"): + await asyncio.to_thread(_the_page_shows_the_file, world, "from the room.bin") + + +def _the_page_shows_the_file(world: dict, name: str) -> None: + # Not revoke_the_others: `chat --follow` below runs on this machine's key. + chrome = _linked_group_page(world) + try: + files = chrome.until( + "[...document.querySelectorAll('.chat-attachment')].map(a => a.innerText)", + lambda found: any(name in f for f in found or [])) + assert any("3" in f and "MB" in f for f in files if name in f), files + assert '"attachment"' not in chrome.js("document.body.innerText") + finally: + chrome.close() + + def test_chat_follow_against_the_real_node(world): """`chat --follow` in its own process: messages posted from another run arrive as the node pushes them, across more than one liveness ping, and @@ -1083,7 +1159,7 @@ def test_chat_follow_against_the_real_node(world): stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) try: first = json.loads(follower.stdout.readline()) # the last one, at once - assert first["text"] + assert first["text"] or first.get("attachment") # /put's, above for text, wait in (("followed one", 0), ("followed two, after a ping", 36)): time.sleep(wait) r = cli(world, "chat", group, "-m", text, home="cli-chat") |