diff --git a/campus_python/api/v1/circles.py b/campus_python/api/v1/circles.py index 3302498..2eb243f 100644 --- a/campus_python/api/v1/circles.py +++ b/campus_python/api/v1/circles.py @@ -73,22 +73,23 @@ class CircleMembers(Resource): """Campus API Circle Members resource.""" path = "members" - def list(self) -> "list[dict[str, int]]": - resp = self.client.get(self.make_path()) + def list(self) -> dict[str, int]: + """Return the circle's {member_id: access_value} mapping.""" + resp = self.client.get(self.make_path(end_slash=True)) resp.raise_for_status() - return resp.json()["members"] + return resp.json() def add(self, member_id: str, access_value: int) -> None: resp = self.client.post( - self.make_path(), - json={"member_id": member_id, "access": access_value} + self.make_path("add"), + json={"member_id": member_id, "access_value": access_value} ) resp.raise_for_status() return None def remove(self, member_id: str) -> None: resp = self.client.delete( - self.make_path(), + self.make_path("remove"), json={"member_id": member_id} ) resp.raise_for_status() diff --git a/tests/unit/test_nested_resources.py b/tests/unit/test_nested_resources.py index 732b67c..6049345 100644 --- a/tests/unit/test_nested_resources.py +++ b/tests/unit/test_nested_resources.py @@ -1,4 +1,4 @@ -"""Regression tests for nested resource paths (issue #38). +"""Regression tests for nested resource paths (issues #38, #42). Nested resources must be constructed with their path part so that their paths extend the parent resource's path instead of collapsing onto it. @@ -11,7 +11,9 @@ - POST /api/v1/assignments//links - GET /api/v1/timetable//entries - GET /api/v1/timetable//metadata -- GET /api/v1/circles//members +- GET /api/v1/circles//members/ +- POST /api/v1/circles//members/add +- DELETE /api/v1/circles//members/remove """ import unittest @@ -139,10 +141,27 @@ def test_metadata_get_gets_metadata_endpoint(self): ) def test_members_list_gets_members_endpoint(self): - self.client.get.return_value.json.return_value = {"members": {}} + """members.list() must GET the canonical /members/ route (#42).""" + self.client.get.return_value.json.return_value = {"cir-2": 7} self.api.circles["cir-1"].members.list() self.client.get.assert_called_once_with( - "/api/v1/circles/cir-1/members" + "/api/v1/circles/cir-1/members/" + ) + + def test_members_add_posts_to_members_add_endpoint(self): + """members.add() must POST the /members/add route with access_value (#42).""" + self.api.circles["cir-1"].members.add(member_id="cir-2", access_value=7) + self.client.post.assert_called_once_with( + "/api/v1/circles/cir-1/members/add", + json={"member_id": "cir-2", "access_value": 7}, + ) + + def test_members_remove_deletes_members_remove_endpoint(self): + """members.remove() must DELETE the /members/remove route (#42).""" + self.api.circles["cir-1"].members.remove(member_id="cir-2") + self.client.delete.assert_called_once_with( + "/api/v1/circles/cir-1/members/remove", + json={"member_id": "cir-2"}, ) def test_assignments_list_passes_query_argument(self):