aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_ops_links.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests/test_ops_links.py')
-rw-r--r--packages/meshbay-node/tests/test_ops_links.py32
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)