Merge pull request #3051 from lbryio/comments-v2
Comments v2 with Reactions
This commit is contained in:
commit
43c2e8d8e9
5 changed files with 363 additions and 34 deletions
|
@ -611,7 +611,7 @@ class Config(CLIConfig):
|
|||
('lbrynet4.lbry.com', 4444) # ASIA
|
||||
])
|
||||
|
||||
comment_server = String("Comment server API URL", "https://comments.lbry.com/api")
|
||||
comment_server = String("Comment server API URL", "https://comments.lbry.com/api/v2")
|
||||
|
||||
# blockchain
|
||||
blockchain_name = String("Blockchain name - lbrycrd_main, lbrycrd_regtest, or lbrycrd_testnet", 'lbrycrd_main')
|
||||
|
|
|
@ -52,11 +52,21 @@ def sign_comment(comment: dict, channel: Output, abandon=False):
|
|||
'signing_ts': timestamp
|
||||
})
|
||||
|
||||
def sign_reaction(reaction: dict, channel: Output):
|
||||
timestamp = str(int(time.time()))
|
||||
signing_field = reaction['channel_name']
|
||||
pieces = [timestamp.encode(), channel.claim_hash, signing_field.encode()]
|
||||
digest = sha256(b''.join(pieces))
|
||||
signature = channel.private_key.sign_digest_deterministic(digest, hashfunc=hashlib.sha256)
|
||||
reaction.update({
|
||||
'signature': binascii.hexlify(signature).decode(),
|
||||
'signing_ts': timestamp
|
||||
})
|
||||
|
||||
async def jsonrpc_post(url: str, method: str, params: dict = None, **kwargs) -> any:
|
||||
params = params or {}
|
||||
params.update(kwargs)
|
||||
json_body = {'jsonrpc': '2.0', 'id': None, 'method': method, 'params': params}
|
||||
json_body = {'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': params}
|
||||
async with utils.aiohttp_request('POST', url, json=json_body) as response:
|
||||
try:
|
||||
result = await response.json()
|
||||
|
|
|
@ -5048,8 +5048,9 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
if hidden ^ visible:
|
||||
result = await comment_client.jsonrpc_post(
|
||||
self.conf.comment_server,
|
||||
'get_claim_hidden_comments',
|
||||
'comment.List',
|
||||
claim_id=claim_id,
|
||||
visible=visible,
|
||||
hidden=hidden,
|
||||
page=page,
|
||||
page_size=page_size
|
||||
|
@ -5057,7 +5058,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
else:
|
||||
result = await comment_client.jsonrpc_post(
|
||||
self.conf.comment_server,
|
||||
'get_claim_comments',
|
||||
'comment.List',
|
||||
claim_id=claim_id,
|
||||
parent_id=parent_id,
|
||||
page=page,
|
||||
|
@ -5132,7 +5133,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
}
|
||||
comment_client.sign_comment(comment_body, channel)
|
||||
|
||||
response = await comment_client.jsonrpc_post(self.conf.comment_server, 'create_comment', comment_body)
|
||||
response = await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Create', comment_body)
|
||||
response.update({
|
||||
'is_claim_signature_valid': comment_client.is_comment_signed_by_channel(response, channel)
|
||||
})
|
||||
|
@ -5169,7 +5170,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
"""
|
||||
channel = await comment_client.jsonrpc_post(
|
||||
self.conf.comment_server,
|
||||
'get_channel_from_comment_id',
|
||||
'comment.GetChannelFromCommentID',
|
||||
comment_id=comment_id
|
||||
)
|
||||
if 'error' in channel:
|
||||
|
@ -5186,7 +5187,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
}
|
||||
comment_client.sign_comment(edited_comment, channel_claim)
|
||||
return await comment_client.jsonrpc_post(
|
||||
self.conf.comment_server, 'edit_comment', edited_comment
|
||||
self.conf.comment_server, 'comment.Edit', edited_comment
|
||||
)
|
||||
|
||||
@requires(WALLET_COMPONENT)
|
||||
|
@ -5212,7 +5213,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||
abandon_comment_body = {'comment_id': comment_id}
|
||||
channel = await comment_client.jsonrpc_post(
|
||||
self.conf.comment_server, 'get_channel_from_comment_id', comment_id=comment_id
|
||||
self.conf.comment_server, 'comment.GetChannelFromCommentID', comment_id=comment_id
|
||||
)
|
||||
if 'error' in channel:
|
||||
return {comment_id: {'abandoned': False}}
|
||||
|
@ -5222,7 +5223,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
'channel_name': channel.claim_name,
|
||||
})
|
||||
comment_client.sign_comment(abandon_comment_body, channel, abandon=True)
|
||||
return await comment_client.jsonrpc_post(self.conf.comment_server, 'abandon_comment', abandon_comment_body)
|
||||
return await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Abandon', abandon_comment_body)
|
||||
|
||||
@requires(WALLET_COMPONENT)
|
||||
async def jsonrpc_comment_hide(self, comment_ids: typing.Union[str, list], wallet_id=None):
|
||||
|
@ -5268,7 +5269,115 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
piece = {'comment_id': comment['comment_id']}
|
||||
comment_client.sign_comment(piece, channel, abandon=True)
|
||||
pieces.append(piece)
|
||||
return await comment_client.jsonrpc_post(self.conf.comment_server, 'hide_comments', pieces=pieces)
|
||||
return await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Hide', pieces=pieces)
|
||||
|
||||
@requires(WALLET_COMPONENT)
|
||||
async def jsonrpc_comment_react(
|
||||
self, comment_ids, channel_name=None, channel_id=None,
|
||||
channel_account_id=None, remove=False, clear_types=None, react_type=None, wallet_id=None):
|
||||
"""
|
||||
Create and associate a reaction emoji with a comment using your channel identity.
|
||||
|
||||
Usage:
|
||||
comment_react (--comment_ids=<comment_ids>)
|
||||
(--channel_id=<channel_id>)
|
||||
(--channel_name=<channel_name>)
|
||||
(--react_type=<react_type>)
|
||||
[(--remove) | (--clear_types=<clear_types>)]
|
||||
[--channel_account_id=<channel_account_id>...] [--wallet_id=<wallet_id>]
|
||||
|
||||
Options:
|
||||
--comment_ids=<comment_ids> : (str) one or more comment id reacted to, comma delimited
|
||||
--channel_id=<claim_id> : (str) The ID of channel reacting
|
||||
--channel_name=<claim_name> : (str) The name of the channel reacting
|
||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
||||
--react_type=<react_type> : (str) name of reaction type
|
||||
--remove : (bool) remove specified react_type
|
||||
--clear_types=<clear_types> : (str) types to clear when adding another type
|
||||
|
||||
|
||||
Returns:
|
||||
(dict) Reaction object if successfully made, (None) otherwise
|
||||
{
|
||||
"Reactions": {
|
||||
<comment_id>: {
|
||||
<reaction_type>: (int) Count for this reaction
|
||||
...
|
||||
}
|
||||
}
|
||||
"""
|
||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||
channel = await self.get_channel_or_error(
|
||||
wallet, channel_account_id, channel_id, channel_name, for_signing=True
|
||||
)
|
||||
|
||||
react_body = {
|
||||
'comment_ids': comment_ids,
|
||||
'channel_id': channel_id,
|
||||
'channel_name': channel.claim_name,
|
||||
'type': react_type,
|
||||
'remove': remove,
|
||||
'clear_types': clear_types,
|
||||
}
|
||||
comment_client.sign_reaction(react_body, channel)
|
||||
|
||||
response = await comment_client.jsonrpc_post(self.conf.comment_server, 'reaction.React', react_body)
|
||||
|
||||
return response
|
||||
|
||||
@requires(WALLET_COMPONENT)
|
||||
async def jsonrpc_comment_react_list(
|
||||
self, comment_ids, channel_name=None, channel_id=None,
|
||||
channel_account_id=None, react_types=None, wallet_id=None):
|
||||
"""
|
||||
List reactions emoji with a claim using your channel identity.
|
||||
|
||||
Usage:
|
||||
comment_react_list (--comment_ids=<comment_ids>)
|
||||
[(--channel_id=<channel_id>)(--channel_name=<channel_name>)]
|
||||
[--react_types=<react_types>]
|
||||
|
||||
Options:
|
||||
--comment_ids=<comment_ids> : (str) The comment ids reacted to, comma delimited
|
||||
--channel_id=<claim_id> : (str) The ID of channel reacting
|
||||
--channel_name=<claim_name> : (str) The name of the channel reacting
|
||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
||||
--react_types=<react_type> : (str) comma delimited reaction types
|
||||
|
||||
Returns:
|
||||
(dict) Comment object if successfully made, (None) otherwise
|
||||
{
|
||||
"my_reactions": {
|
||||
<comment_id>: {
|
||||
<reaction_type>: (int) Count for this reaction type
|
||||
...
|
||||
}
|
||||
}
|
||||
"other_reactions": {
|
||||
<comment_id>: {
|
||||
<reaction_type>: (int) Count for this reaction type
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||
react_list_body = {
|
||||
'comment_ids': comment_ids,
|
||||
}
|
||||
if channel_id:
|
||||
channel = await self.get_channel_or_error(
|
||||
wallet, channel_account_id, channel_id, channel_name, for_signing=True
|
||||
)
|
||||
react_list_body['channel_id'] = channel_id
|
||||
react_list_body['channel_name'] = channel.claim_name
|
||||
|
||||
if react_types:
|
||||
react_list_body['types'] = react_types
|
||||
if channel_id:
|
||||
comment_client.sign_reaction(react_list_body, channel)
|
||||
response = await comment_client.jsonrpc_post(self.conf.comment_server, 'reaction.List', react_list_body)
|
||||
return response
|
||||
|
||||
async def broadcast_or_release(self, tx, blocking=False):
|
||||
await self.wallet_manager.broadcast_or_release(tx, blocking)
|
||||
|
|
|
@ -2,7 +2,7 @@ __node_daemon__ = 'lbrycrdd'
|
|||
__node_cli__ = 'lbrycrd-cli'
|
||||
__node_bin__ = ''
|
||||
__node_url__ = (
|
||||
'https://github.com/lbryio/lbrycrd/releases/download/v0.17.4.5/lbrycrd-linux-1745.zip'
|
||||
'https://github.com/lbryio/lbrycrd/releases/download/v0.17.4.6/lbrycrd-linux-1746.zip'
|
||||
)
|
||||
__spvserver__ = 'lbry.wallet.server.coin.LBCRegTest'
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import re
|
||||
|
||||
import time
|
||||
import typing
|
||||
from math import ceil
|
||||
|
@ -32,6 +31,16 @@ class MockedCommentServer:
|
|||
'is_hidden': False,
|
||||
}
|
||||
|
||||
REACT_SCHEMA = {
|
||||
'react_id': None,
|
||||
'comment_id': None,
|
||||
'reaction_type': None,
|
||||
'timestamp': None,
|
||||
'signature': None,
|
||||
'channel_id': None,
|
||||
'channel_name': None
|
||||
}
|
||||
|
||||
def __init__(self, port=2903):
|
||||
self.port = port
|
||||
self.app = web.Application(debug=True)
|
||||
|
@ -39,7 +48,9 @@ class MockedCommentServer:
|
|||
self.runner = None
|
||||
self.server = None
|
||||
self.comments = []
|
||||
self.reacts = {}
|
||||
self.comment_id = 0
|
||||
self.react_id = 0
|
||||
|
||||
@classmethod
|
||||
def _create_comment(cls, **kwargs):
|
||||
|
@ -47,6 +58,12 @@ class MockedCommentServer:
|
|||
schema.update(**kwargs)
|
||||
return schema
|
||||
|
||||
@classmethod
|
||||
def _react(cls, **kwargs):
|
||||
schema = cls.REACT_SCHEMA.copy()
|
||||
schema.update(**kwargs)
|
||||
return schema
|
||||
|
||||
def create_comment(self, claim_id=None, parent_id=None, channel_name=None, channel_id=None, **kwargs):
|
||||
comment_id = self.comment_id
|
||||
channel_url = 'lbry://' + channel_name + '#' + channel_id if channel_id else None
|
||||
|
@ -117,27 +134,18 @@ class MockedCommentServer:
|
|||
'visible': list(comment_ids - set(hidden))
|
||||
}
|
||||
|
||||
def get_claim_comments(self, claim_id, page=1, page_size=50,**kwargs):
|
||||
def get_claim_comments(self, claim_id, hidden=False, visible=False, page=1, page_size=50,**kwargs):
|
||||
comments = list(filter(lambda c: c['claim_id'] == claim_id, self.comments))
|
||||
if hidden ^ visible:
|
||||
comments = list(filter(lambda c: c['is_hidden'] == hidden, comments))
|
||||
|
||||
return {
|
||||
'page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': ceil(len(comments)/page_size),
|
||||
'total_items': len(comments),
|
||||
'items': [self.clean(c) for c in (comments[::-1])[(page - 1) * page_size: page * page_size]],
|
||||
'has_hidden_comments': bool(list(filter(lambda x: x['is_hidden'], comments)))
|
||||
}
|
||||
|
||||
def get_claim_hidden_comments(self, claim_id, hidden=True, page=1, page_size=50):
|
||||
comments = list(filter(lambda c: c['claim_id'] == claim_id, self.comments))
|
||||
select_comments = list(filter(lambda c: c['is_hidden'] == hidden, comments))
|
||||
return {
|
||||
'page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': ceil(len(select_comments) / page_size),
|
||||
'total_items': len(select_comments),
|
||||
'items': [self.clean(c) for c in (select_comments[::-1])[(page - 1) * page_size: page * page_size]],
|
||||
'has_hidden_comments': bool(list(filter(lambda c: c['is_hidden'], comments)))
|
||||
'has_hidden_comments': bool(list(filter(lambda x: x['is_hidden'], self.comments)))
|
||||
}
|
||||
|
||||
def get_comment_channel_by_id(self, comment_id: int, **kwargs):
|
||||
|
@ -157,15 +165,98 @@ class MockedCommentServer:
|
|||
'has_hidden_comments': bool({c for c in comments if c['is_hidden']})
|
||||
}
|
||||
|
||||
def react(
|
||||
self,
|
||||
comment_ids=None,
|
||||
channel_name=None,
|
||||
channel_id=None,
|
||||
remove=None,
|
||||
clear_types=None,
|
||||
type=None,
|
||||
signing_ts=None,
|
||||
**kwargs
|
||||
):
|
||||
comment_batch = comment_ids.split(',')
|
||||
for item in comment_batch:
|
||||
react_id = self.react_id
|
||||
c_id = item.strip()
|
||||
reacts_for_comment_id = [r for r in list(self.reacts.values()) if r['comment_id'] == c_id]
|
||||
channels_reacts_for_comment_id = [r for r in reacts_for_comment_id if r['channel_id'] == channel_id]
|
||||
if remove:
|
||||
matching_react = None
|
||||
for reaction in channels_reacts_for_comment_id:
|
||||
if reaction['reaction_type'] == type:
|
||||
matching_react = reaction
|
||||
break
|
||||
if matching_react:
|
||||
self.reacts.pop(int(matching_react['react_id']), None)
|
||||
else:
|
||||
if clear_types:
|
||||
for r_type in clear_types.split(','):
|
||||
for reaction in channels_reacts_for_comment_id:
|
||||
if reaction['reaction_type'] == r_type:
|
||||
x = self.reacts.pop(int(reaction['react_id']), None)
|
||||
react = self._react(
|
||||
react_id=str(react_id),
|
||||
comment_id=str(c_id),
|
||||
channel_name=channel_name,
|
||||
channel_id=channel_id,
|
||||
reaction_type=type,
|
||||
timestamp=str(int(time.time())),
|
||||
**kwargs
|
||||
)
|
||||
self.reacts[self.react_id] = react
|
||||
self.react_id += 1
|
||||
self.clean(react)
|
||||
return True
|
||||
|
||||
def list_reacts(self, comment_ids, channel_id, channel_name, types=None, **kwargs):
|
||||
all_types = list(set([r['reaction_type'] for r in list(self.reacts.values())]))
|
||||
comment_id_list = comment_ids.split(',')
|
||||
# _reacts: {'a1': {'like': 0, 'dislike': 0}, 'a2': {'like': 0, 'dislike': 0}}
|
||||
own_reacts = {}
|
||||
other_reacts = {}
|
||||
|
||||
# for each comment_id
|
||||
# add comment_id: {} to own_reacts and other_reacts
|
||||
# for each react in own_reacts
|
||||
# for each react in other_reacts
|
||||
for cid in comment_id_list:
|
||||
own_reacts[cid] = {}
|
||||
other_reacts[cid] = {}
|
||||
|
||||
for r_type in all_types:
|
||||
own_reacts[cid][r_type] = 0
|
||||
other_reacts[cid][r_type] = 0
|
||||
# process that comment ids reactions for own and other categories
|
||||
reacts_for_comment = list(filter(lambda c: c['comment_id'] == cid, list(self.reacts.values())))
|
||||
if types:
|
||||
reacts_for_comment = list(filter(lambda c: c['reaction_type'] in types.split(','), reacts_for_comment))
|
||||
own_reacts_for_comment = list(filter(lambda c: c['channel_id'] == channel_id, reacts_for_comment))
|
||||
other_reacts_for_comment = list(filter(lambda c: c['channel_id'] != channel_id, reacts_for_comment))
|
||||
|
||||
if own_reacts_for_comment:
|
||||
for react in own_reacts_for_comment:
|
||||
own_reacts[cid][react['reaction_type']] += 1
|
||||
if other_reacts_for_comment:
|
||||
for react in other_reacts_for_comment:
|
||||
other_reacts[cid][react['reaction_type']] += 1
|
||||
|
||||
return {
|
||||
'my_reactions': own_reacts,
|
||||
'others_reactions': other_reacts,
|
||||
}
|
||||
|
||||
methods = {
|
||||
'get_claim_comments': get_claim_comments,
|
||||
'comment.List': get_claim_comments,
|
||||
'get_comments_by_id': get_comments_by_id,
|
||||
'create_comment': create_comment,
|
||||
'abandon_comment': abandon_comment,
|
||||
'get_channel_from_comment_id': get_comment_channel_by_id,
|
||||
'get_claim_hidden_comments': get_claim_hidden_comments,
|
||||
'hide_comments': hide_comments,
|
||||
'edit_comment': edit_comment,
|
||||
'comment.Create': create_comment,
|
||||
'comment.Abandon': abandon_comment,
|
||||
'comment.GetChannelFromCommentID': get_comment_channel_by_id,
|
||||
'comment.Hide': hide_comments,
|
||||
'comment.Edit': edit_comment,
|
||||
'reaction.React': react,
|
||||
'reaction.List': list_reacts,
|
||||
}
|
||||
|
||||
def process_json(self, body) -> dict:
|
||||
|
@ -450,7 +541,6 @@ class CommentCommands(CommandTestCase):
|
|||
channel_id=bee['claim_id']
|
||||
)
|
||||
all_comments = [other_comment, owner_comment, hidden_comment]
|
||||
|
||||
normal_list = await self.daemon.jsonrpc_comment_list(claim_id)
|
||||
self.assertEqual(
|
||||
{'items', 'page', 'page_size', 'has_hidden_comments', 'total_items', 'total_pages'},
|
||||
|
@ -532,3 +622,123 @@ class CommentCommands(CommandTestCase):
|
|||
comment='If you see it and you mean then you know you have to go',
|
||||
comment_id=original_cid
|
||||
)
|
||||
|
||||
async def test06_reactions(self):
|
||||
# wherein a bee insulted by a rude moth accidentally
|
||||
# 1) likes an insult
|
||||
# 2) clicks dislike instead, testing "clear_types"
|
||||
# 3) then clicks dislike again, testing "remove"
|
||||
# calls from the point of view of the moth
|
||||
|
||||
moth = (await self.channel_create('@InconspicuousMoth'))['outputs'][0]
|
||||
bee = (await self.channel_create('@LazyBumblebee'))['outputs'][0]
|
||||
stream = await self.stream_create('Cool_Lamps_to_Sit_On', channel_id=moth['claim_id'])
|
||||
claim_id = stream['outputs'][0]['claim_id']
|
||||
|
||||
first_comment = await self.daemon.jsonrpc_comment_create(
|
||||
comment='Go away you yellow freak',
|
||||
claim_id=claim_id,
|
||||
channel_id=moth['claim_id'],
|
||||
)
|
||||
second_comment = await self.daemon.jsonrpc_comment_create(
|
||||
comment='I got my swim trunks and my flippy-floppies',
|
||||
claim_id=claim_id,
|
||||
channel_id=bee['claim_id']
|
||||
)
|
||||
all_comments = [second_comment, first_comment]
|
||||
comment_list = await self.daemon.jsonrpc_comment_list(claim_id)
|
||||
self.assertEqual(
|
||||
{'items', 'page', 'page_size', 'has_hidden_comments', 'total_items', 'total_pages'},
|
||||
set(comment_list)
|
||||
)
|
||||
self.assertEqual(comment_list['total_items'], 2)
|
||||
|
||||
bee_like_reaction = await self.daemon.jsonrpc_comment_react(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=bee['claim_id'],
|
||||
channel_name=bee['name'],
|
||||
react_type='like',
|
||||
)
|
||||
|
||||
moth_like_reaction = await self.daemon.jsonrpc_comment_react(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
react_type='like',
|
||||
)
|
||||
reactions = await self.daemon.jsonrpc_comment_react_list(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
)
|
||||
# {'my_reactions': {'0': {'like': 1}}, 'others_reactions': {'0': {'like': 1}}}
|
||||
self.assertEqual(reactions['my_reactions']['0']['like'], 1)
|
||||
self.assertEqual(reactions['others_reactions']['0']['like'], 1)
|
||||
|
||||
bee_dislike_reaction = await self.daemon.jsonrpc_comment_react(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=bee['claim_id'],
|
||||
channel_name=bee['name'],
|
||||
react_type='dislike',
|
||||
clear_types='like',
|
||||
)
|
||||
|
||||
reactions_after_bee_dislikes = await self.daemon.jsonrpc_comment_react_list(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
)
|
||||
# {'my_reactions': {'0': {'like': 1, 'dislike', 0}}, 'others_reactions': {'0': {'like': 0, 'dislike': 1}}}
|
||||
self.assertEqual(reactions_after_bee_dislikes['my_reactions']['0']['like'], 1)
|
||||
self.assertEqual(reactions_after_bee_dislikes['my_reactions']['0']['dislike'], 0)
|
||||
self.assertEqual(reactions_after_bee_dislikes['others_reactions']['0']['dislike'], 1)
|
||||
self.assertEqual(reactions_after_bee_dislikes['others_reactions']['0']['like'], 0)
|
||||
|
||||
only_likes_after_bee_dislikes = await self.daemon.jsonrpc_comment_react_list(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
react_types='like',
|
||||
)
|
||||
|
||||
self.assertEqual(only_likes_after_bee_dislikes['my_reactions']['0']['like'], 1)
|
||||
self.assertEqual(only_likes_after_bee_dislikes['my_reactions']['0']['dislike'], 0)
|
||||
self.assertEqual(only_likes_after_bee_dislikes['others_reactions']['0']['dislike'], 0)
|
||||
self.assertEqual(only_likes_after_bee_dislikes['others_reactions']['0']['like'], 0)
|
||||
|
||||
bee_un_dislike_reaction = await self.daemon.jsonrpc_comment_react(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=bee['claim_id'],
|
||||
channel_name=bee['name'],
|
||||
remove=True,
|
||||
react_type='dislike',
|
||||
)
|
||||
|
||||
reactions_after_bee_absconds = await self.daemon.jsonrpc_comment_react_list(
|
||||
comment_ids=first_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
)
|
||||
|
||||
self.assertEqual(reactions_after_bee_absconds['my_reactions']['0']['like'], 1)
|
||||
self.assertNotIn('dislike', reactions_after_bee_absconds['my_reactions']['0'])
|
||||
self.assertEqual(reactions_after_bee_absconds['others_reactions']['0']['like'], 0)
|
||||
self.assertNotIn('dislike', reactions_after_bee_absconds['others_reactions']['0'])
|
||||
|
||||
bee_reacts_to_both_comments = await self.daemon.jsonrpc_comment_react(
|
||||
comment_ids=first_comment['comment_id'] + ',' + second_comment['comment_id'],
|
||||
channel_id=bee['claim_id'],
|
||||
channel_name=bee['name'],
|
||||
react_type='frozen_tom',
|
||||
)
|
||||
|
||||
reactions_after_double_frozen_tom = await self.daemon.jsonrpc_comment_react_list(
|
||||
comment_ids=first_comment['comment_id'] + ',' + second_comment['comment_id'],
|
||||
channel_id=moth['claim_id'],
|
||||
channel_name=moth['name'],
|
||||
)
|
||||
|
||||
self.assertEqual(reactions_after_double_frozen_tom['my_reactions']['0']['like'], 1)
|
||||
self.assertNotIn('dislike', reactions_after_double_frozen_tom['my_reactions']['0'])
|
||||
self.assertEqual(reactions_after_double_frozen_tom['others_reactions']['0']['frozen_tom'], 1)
|
||||
self.assertEqual(reactions_after_double_frozen_tom['others_reactions']['1']['frozen_tom'], 1)
|
||||
|
|
Loading…
Reference in a new issue