diff options
Diffstat (limited to 'packages/meshbay-hub/tests/test_group_description.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_group_description.py | 103 |
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 |