aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests')
-rw-r--r--packages/meshbay-hub/tests/test_group_description.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_group_description.py b/packages/meshbay-hub/tests/test_group_description.py
new file mode 100644
index 0000000..b18c90a
--- /dev/null
+++ b/packages/meshbay-hub/tests/test_group_description.py
@@ -0,0 +1,103 @@
+"""
+Editing a group's description.
+
+A description could only be set when the group was created, so every group made
+before anyone thought to write one stayed blank for good. What is deliberately
+*not* editable is as much the point: name, visibility and join policy are the
+terms members joined on.
+"""
+
+import base64
+import hashlib
+
+import pytest
+
+
+def _auth_key(password: str, username: str) -> str:
+ salt = hashlib.sha256(f"meshbay:auth:v1:{username}".encode()).digest()
+ return base64.b64encode(
+ hashlib.pbkdf2_hmac("sha512", password.encode(), salt, 600_000, 32)).decode()
+
+
+async def _user(client, username, password="a-long-enough-passphrase"):
+ await client.post("/v1/users/register", json={
+ "username": username, "email": f"{username}@example.com",
+ "auth_key": _auth_key(password, username)})
+ r = await client.post("/v1/users/login", json={
+ "username": username, "auth_key": _auth_key(password, username)})
+ return {"Authorization": f"Bearer {r.json()['access_token']}"}
+
+
+async def _group(client, headers, name="described", **kw):
+ r = await client.post("/v1/groups", json={"name": name, **kw}, headers=headers)
+ return r.json()["group_id"]
+
+
+@pytest.mark.asyncio
+async def test_the_owner_can_write_a_description(client):
+ owner = await _user(client, "writer")
+ gid = await _group(client, owner)
+
+ r = await client.patch(f"/v1/groups/{gid}",
+ json={"description": "host grenoble"}, headers=owner)
+ assert r.status_code == 200, r.text
+
+ mine = await client.get("/v1/groups/mine", headers=owner)
+ group = next(g for g in mine.json()["groups"] if g["id"] == gid)
+ assert group["description"] == "host grenoble"
+
+
+@pytest.mark.asyncio
+async def test_a_member_cannot(client):
+ owner = await _user(client, "owner2")
+ member = await _user(client, "member2")
+ gid = await _group(client, owner, name="not-yours")
+ await client.post(f"/v1/groups/{gid}/members/member2", json={}, headers=owner)
+
+ r = await client.patch(f"/v1/groups/{gid}",
+ json={"description": "mine now"}, headers=member)
+ assert r.status_code == 403
+
+
+@pytest.mark.asyncio
+async def test_an_empty_description_clears_it(client):
+ owner = await _user(client, "clearer")
+ gid = await _group(client, owner, name="clearme", description="temporary")
+
+ r = await client.patch(f"/v1/groups/{gid}", json={"description": " "},
+ headers=owner)
+ assert r.status_code == 200
+ assert r.json()["description"] == ""
+
+
+@pytest.mark.asyncio
+async def test_the_terms_members_joined_on_are_not_editable(client):
+ """
+ A private group that could quietly become public is not the group its
+ members agreed to be in. Changing that needs a decision about who gets told,
+ so the endpoint ignores it rather than half-implementing it.
+ """
+ owner = await _user(client, "sneaky")
+ gid = await _group(client, owner, name="private-please", visibility="private")
+
+ await client.patch(f"/v1/groups/{gid}",
+ json={"description": "hi", "visibility": "public",
+ "join_policy": "open", "name": "renamed"},
+ headers=owner)
+
+ mine = await client.get("/v1/groups/mine", headers=owner)
+ group = next(g for g in mine.json()["groups"] if g["id"] == gid)
+ assert group["visibility"] == "private"
+ assert group["join_policy"] == "invite"
+ assert group["name"] == "private-please"
+
+
+@pytest.mark.asyncio
+async def test_a_long_description_is_truncated_not_refused(client):
+ owner = await _user(client, "verbose")
+ gid = await _group(client, owner, name="long")
+
+ r = await client.patch(f"/v1/groups/{gid}", json={"description": "x" * 900},
+ headers=owner)
+ assert r.status_code == 200
+ assert len(r.json()["description"]) == 512