diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-25 17:10:15 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-25 17:10:15 +0200 |
| commit | 90c69477d5f701158112b3c294eff26312f89da6 (patch) | |
| tree | 2691ca096da5cf93482bc750c7a03599fbc44dc8 /packages/meshbay-node/tests/test_ops_links.py | |
| parent | 8bb94a39609f57be2c486f579849eebb04606808 (diff) | |
| download | meshbay-90c69477d5f701158112b3c294eff26312f89da6.tar.gz | |
A link is redeemable by whoever opens it first, so it can be sent by any
messaging app. The address is optional (mail + label only); a link lives
7 days, fixed. Adds a Share button; see MESHBAY_DESIGN.md §3.4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_ops_links.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_ops_links.py | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/packages/meshbay-node/tests/test_ops_links.py b/packages/meshbay-node/tests/test_ops_links.py index 00258d3..9ad01d2 100644 --- a/packages/meshbay-node/tests/test_ops_links.py +++ b/packages/meshbay-node/tests/test_ops_links.py @@ -1,13 +1,15 @@ """ Invitation links from the operator's own machine (`member invite --link`). -The CLI makes both halves itself: the node's code, then the hub's ticket bound -to an address, then the link. What can go wrong is a half left behind — a code -the hub never ticketed, occupying one of the group's places, or a ticket whose -code was cancelled — and the CLI asking the hub to mail, which it may not. +The CLI makes both halves itself: the node's code, then the hub's ticket, then +the link. The address is optional and only labels the link. What can go wrong +is a half left behind — a code the hub never ticketed, occupying one of the +group's places, or a ticket whose code was cancelled — and the CLI asking the +hub to mail, which it may not. """ import re +from datetime import UTC, datetime, timedelta import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey @@ -76,12 +78,30 @@ async def test_a_refused_ticket_takes_the_code_back(roster): assert [i for i in await roster.list_invites() if i["kind"] == KIND_LINK] == [] -async def test_an_address_is_required(roster): +async def test_an_address_is_optional_but_must_be_one_when_given(roster): + hub = _Hub() + out = await ops.create_link_invitation(_state(roster, hub), GROUP) + assert LINK.match(out["link"]), out["link"] + assert hub.created == [(GROUP, "", out["invite_id"])] with pytest.raises(ops.OpError) as refused: - await ops.create_link_invitation(_state(roster, _Hub()), GROUP, "alice") + await ops.create_link_invitation(_state(roster, hub), GROUP, "alice") assert refused.value.status == 422 +async def test_a_link_lives_seven_days_whatever_the_invite_setting(roster): + class _Node: + invite_ttl_hours = 24 * 30 + + class _Config: + node = _Node() + + state = _state(roster, _Hub()) + state["config"] = _Config() + out = await ops.create_link_invite(state, GROUP) + left = datetime.fromisoformat(out["expires_at"]) - datetime.now(UTC) + assert timedelta(days=6, hours=23) < left <= timedelta(days=7) + + async def test_cancelling_takes_back_both_halves(roster): hub = _Hub() state = _state(roster, hub) |