This commit is contained in:
simonwt 2026-04-16 21:58:31 +01:00
parent 0bcec8163c
commit 41102d5348
9 changed files with 134 additions and 6 deletions

View file

@ -0,0 +1 @@
from .follow import follow

View file

@ -0,0 +1,12 @@
def follow(API, payload: dict) -> dict:
"""
Creates or updates a follow relationship in the API.
Args:
payload (dict): The data for the follow relationship.
Returns:
dict: The follow relationship data.
"""
follow_data = API.make_request("POST", "content", "relfollow", data=payload, authenticate=True)
return follow_data

View file

@ -5,3 +5,4 @@ from .make_post_sk import make_post_sk
from .get_child_spksk_from_paths import get_child_spksk_from_paths from .get_child_spksk_from_paths import get_child_spksk_from_paths
from .get_user_slug_from_path import get_user_slug_from_path from .get_user_slug_from_path import get_user_slug_from_path
from .get_userprofile_pksk_from_slug import get_userprofile_pksk_from_slug from .get_userprofile_pksk_from_slug import get_userprofile_pksk_from_slug
from .get_entity_from_str import get_entity_from_str

View file

@ -0,0 +1,34 @@
def get_entity_from_str(entity):
# Translate the more obvious names to our
# obscure internal ones - sorry about that!
if entity == 'branch':
entity = 'subwiki'
elif entity == 'user':
entity = 'userprofile'
elif entity == 'follow':
entity = 'relfollow'
elif entity == 'trust':
entity = 'reltrust'
elif entity == 'block':
entity = 'userblock'
elif entity == 'mute':
entity = 'usermute'
valid = [
'comment',
'post',
'reaction',
'relfollow',
'reltrust',
'subwiki',
'userblock',
'usermute',
'userprofile',
'vote',
]
if entity not in valid:
raise ValueError(f"Invalid entity: {entity}. Must be one of {', '.join(valid)}.")
return entity

View file

@ -1,13 +1,11 @@
from .get_entity_from_str import get_entity_from_str
def get_parent_pksk_from_path(parent_path): def get_parent_pksk_from_path(parent_path):
if parent_path == '/': if parent_path == '/':
return 'maintrunk#maintrunk' return 'maintrunk#maintrunk'
entity, slug = parent_path.strip('/').split('/') entity, slug = parent_path.strip('/').split('/')
if entity == 'branch': entity = get_entity_from_str(entity)
entity = 'subwiki'
elif entity == 'user':
entity = 'userprofile'
if entity not in ['userprofile', 'subwiki']: if entity not in ['userprofile', 'subwiki']:
raise ValueError(f"Invalid parent entity: {entity}. Must be 'userprofile' or 'subwiki'.") raise ValueError(f"Invalid parent entity: {entity}. Must be 'userprofile' or 'subwiki'.")

View file

@ -0,0 +1,39 @@
from trustcafeapiwrapper.utils.get_entity_from_str import get_entity_from_str
def follow(
entity: str,
is_following: bool,
parent_slug: str,
):
"""
Creates new or update existing follow entry in the API.
Args:
entity (str): The type of entity to follow (userprofile | subwiki).
is_following (bool): Indicates whether the entity is being followed.
parent_slug (str): The slug of the parent entity.
Returns:
dict: A dictionary containing the job name and payload for creating the post
that will be processed by the API client wrapper function.
"""
entity = get_entity_from_str(entity)
itemPKSK = f"{entity}#{parent_slug}"
return {
"job_function": "follow.follow",
"payload": {
"isFollowing": is_following,
"parent": {
"pk": itemPKSK,
"sk": itemPKSK
},
"followType": entity,
"preferences": {
"notification": True,
"emailNew": False,
"emailDigest": True
}
}
}

View file

@ -0,0 +1,19 @@
import unittest
from trustcafeapiwrapper.utils.get_entity_from_str import get_entity_from_str
class TestGetEntityFromStr(unittest.TestCase):
def test_branch(self):
self.assertEqual(get_entity_from_str('branch'), 'subwiki')
def test_user(self):
self.assertEqual(get_entity_from_str('user'), 'userprofile')
def test_subwiki(self):
self.assertEqual(get_entity_from_str('subwiki'), 'subwiki')
def test_userprofile(self):
self.assertEqual(get_entity_from_str('userprofile'), 'userprofile')
def test_invalid_entity(self):
with self.assertRaises(ValueError):
get_entity_from_str('invalidentity')

23
tests/wrappers/follow.py Normal file
View file

@ -0,0 +1,23 @@
import unittest
from trustcafeapiwrapper.wrappers.follow.follow import follow
class TestFollow(unittest.TestCase):
def test_follow(self):
result = follow(
entity='user',
is_following=True,
parent_slug='janedoe'
)
self.assertIsInstance(result, dict)
self.assertIn("job_function", result)
self.assertIn("payload", result)
self.assertEqual(result["job_function"], "follow.follow")
self.assertIsInstance(result["payload"], dict)
self.assertIn("isFollowing", result["payload"])
self.assertIn("parent", result["payload"])
self.assertIn("followType", result["payload"])
self.assertIn("preferences", result["payload"])
self.assertEqual(result["payload"]["isFollowing"], True)
self.assertEqual(result["payload"]["parent"]["pk"], "userprofile#janedoe")

View file

@ -2,6 +2,7 @@ import sys
sys.path.insert(0, './src/') sys.path.insert(0, './src/')
import unittest import unittest
from tests.utils.get_entity_from_str import TestGetEntityFromStr
from tests.utils.get_post_pksk import TestGetPostPksk from tests.utils.get_post_pksk import TestGetPostPksk
from tests.utils.get_parent_pksk_from_path import TestGetParentPkskFromPath from tests.utils.get_parent_pksk_from_path import TestGetParentPkskFromPath
from tests.utils.make_comment_sk import TestMakeCommentSk from tests.utils.make_comment_sk import TestMakeCommentSk
@ -16,7 +17,7 @@ from tests.wrappers.create_comment import TestCreateComment
from tests.wrappers.react import TestReact from tests.wrappers.react import TestReact
from tests.wrappers.vote import TestVoteCast from tests.wrappers.vote import TestVoteCast
from tests.wrappers.trust import TestTrustCreateOrUpdate from tests.wrappers.trust import TestTrustCreateOrUpdate
from tests.wrappers.follow import TestFollow
from tests.apiclient import TestAPIClient from tests.apiclient import TestAPIClient