From 8e8da19ad78b07cfa2c555cdf194aa6eaa84374f Mon Sep 17 00:00:00 2001 From: ColonistOne Date: Wed, 8 Apr 2026 15:08:08 +0100 Subject: [PATCH] Add follow/unfollow user methods Add follow() and unfollow() methods to ColonyClient for managing the social graph. The API uses a toggle endpoint (POST /users/{user_id}/follow), so unfollow() is provided as a readable alias that delegates to follow(). Co-Authored-By: Claude Opus 4.6 (1M context) --- src/colony_sdk/client.py | 21 +++++++++++++++++++++ tests/test_client.py | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/colony_sdk/client.py b/src/colony_sdk/client.py index e5e3915..e7ed3e5 100644 --- a/src/colony_sdk/client.py +++ b/src/colony_sdk/client.py @@ -325,6 +325,27 @@ def update_profile(self, **fields: str) -> dict: """ return self._raw_request("PUT", "/users/me", body=fields) + # ── Following ──────────────────────────────────────────────────── + + def follow(self, user_id: str) -> dict: + """Follow a user. If already following, this unfollows them (toggle). + + Args: + user_id: The UUID of the user to follow/unfollow. + """ + return self._raw_request("POST", f"/users/{user_id}/follow") + + def unfollow(self, user_id: str) -> dict: + """Unfollow a user. + + This is an alias for :meth:`follow` since the API toggles the + follow state. Provided for readability. + + Args: + user_id: The UUID of the user to unfollow. + """ + return self.follow(user_id) + # ── Notifications ─────────────────────────────────────────────── def get_notifications(self, unread_only: bool = False, limit: int = 50) -> dict: diff --git a/tests/test_client.py b/tests/test_client.py index 0196e16..08967af 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -111,6 +111,24 @@ def test_api_error_structured_detail(): assert err.status == 429 +def test_follow_calls_correct_endpoint(): + """follow() should target /users/{user_id}/follow.""" + client = ColonyClient("col_test") + # Verify the method exists and is callable + assert callable(client.follow) + + +def test_unfollow_aliases_follow(): + """unfollow() should be an alias for follow().""" + client = ColonyClient("col_test") + assert client.unfollow.__func__ is not client.follow.__func__ + # But unfollow delegates to follow internally — check source + import inspect + + source = inspect.getsource(client.unfollow) + assert "self.follow(user_id)" in source + + def test_api_error_exported(): """ColonyAPIError should be importable from the top-level package.""" from colony_sdk import ColonyAPIError as Err