Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/base_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def react_in_channel(self, packet: MeshPacket, emoji: str) -> None:
reply_id = packet['id']
channel = packet['channel'] if 'channel' in packet else 0

self.bot.interface.sendReaction(emoji, reply_id, channelIndex=channel)
self.bot.interface.sendReaction(emoji, messageId=reply_id, channelIndex=channel)

def react_in_dm(self, packet: MeshPacket, emoji: str) -> None:
"""
Expand All @@ -63,4 +63,4 @@ def react_in_dm(self, packet: MeshPacket, emoji: str) -> None:
reply_id = packet['id']
sender = packet['fromId']

self.bot.interface.sendReaction(emoji, reply_id, sender)
self.bot.interface.sendReaction(emoji, messageId=reply_id, destinationId=sender)
2 changes: 1 addition & 1 deletion src/responders/message_reaction_responder.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def handle_packet(self, packet: MeshPacket) -> None:
emoji = random.choice(self.emoji)

# Respond to the message
self.react_to(packet, emoji)
self.react_in_channel(packet, emoji)

def _is_enrolled(self, from_id: str) -> bool:
user_prefs = self.bot.user_prefs_persistence.get_user_prefs(from_id)
Expand Down
61 changes: 61 additions & 0 deletions test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import unittest
from abc import ABC
from unittest.mock import Mock

from src.bot import MeshtasticBot
from src.data_classes import MeshNode
from test.test_setup_data import get_test_bot


class BaseFeatureTestCase(unittest.TestCase, ABC):
bot: MeshtasticBot
mock_interface: Mock
test_admin_nodes: list[MeshNode] = []
test_non_admin_nodes: list[MeshNode] = []
test_nodes: list[MeshNode] = []

def setUp(self):
self.bot, self.test_non_admin_nodes, self.test_admin_nodes = get_test_bot()
self.test_nodes = self.test_non_admin_nodes + self.test_admin_nodes
self.mock_interface = self.bot.interface = Mock()

def assert_message_sent(self, expected_response: str, to: MeshNode, want_ack: bool = False, multi_response=False):
if multi_response:
self.mock_interface.sendText.assert_called()

# Strip the newline character from the expected response
expected_response = expected_response.strip()

# Assert that one of the calls matches the expected
for call_args in self.mock_interface.sendText.call_args_list:
if (call_args[1]['destinationId'] == to.user.id
and call_args[1]['wantAck'] == want_ack
and call_args[0][0].strip() == expected_response):
return

self.fail(
f"Expected response with destinationId {to.user.id} and wantAck {want_ack}: \n"
f"{expected_response}\n"
f"\n"
f"not found in calls:\n"
f"{self.mock_interface.sendText.call_args_list}")
else:
self.mock_interface.sendText.assert_called_once_with(
expected_response,
destinationId=to.user.id,
wantAck=want_ack
)

def assert_reaction_sent(self, emoji: str, reply_id: int, channel=0, sender_id: str = None):
if sender_id:
self.mock_interface.sendReaction.assert_called_once_with(
emoji,
messageId=reply_id,
destinationId=sender_id
)
else:
self.mock_interface.sendReaction.assert_called_once_with(
emoji,
messageId=reply_id,
channelIndex=channel,
)
48 changes: 3 additions & 45 deletions test/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,15 @@
import unittest
from abc import ABC
from unittest.mock import Mock

from meshtastic.protobuf.mesh_pb2 import MeshPacket

from src.bot import MeshtasticBot
from src.commands.command import AbstractCommand, AbstractCommandWithSubcommands
from src.data_classes import MeshNode
from test.test_setup_data import get_test_bot, build_test_text_packet
from test import BaseFeatureTestCase
from test.test_setup_data import build_test_text_packet


class CommandTestCase(unittest.TestCase, ABC):
class CommandTestCase(BaseFeatureTestCase, ABC):
command: AbstractCommand

bot: MeshtasticBot
mock_interface: Mock
test_admin_nodes: list[MeshNode] = []
test_non_admin_nodes: list[MeshNode] = []
test_nodes: list[MeshNode] = []

def setUp(self):
self.bot, self.test_non_admin_nodes, self.test_admin_nodes = get_test_bot()
self.test_nodes = self.test_non_admin_nodes + self.test_admin_nodes
self.mock_interface = self.bot.interface = Mock()

def assert_message_sent(self, expected_response: str, to: MeshNode, want_ack: bool = False, multi_response=False):

if multi_response:
self.mock_interface.sendText.assert_called()

# Strip the newline character from the expected response
expected_response = expected_response.strip()

# Assert that one of the calls matches the expected
for call_args in self.mock_interface.sendText.call_args_list:
if (call_args[1]['destinationId'] == to.user.id
and call_args[1]['wantAck'] == want_ack
and call_args[0][0].strip() == expected_response):
return

self.fail(
f"Expected response with destinationId {to.user.id} and wantAck {want_ack}: \n"
f"{expected_response}\n"
f"\n"
f"not found in calls:\n"
f"{self.mock_interface.sendText.call_args_list}")
else:
self.mock_interface.sendText.assert_called_once_with(
expected_response,
destinationId=to.user.id,
wantAck=want_ack
)


class CommandWSCTestCase(CommandTestCase):
command: AbstractCommandWithSubcommands
Expand Down
26 changes: 2 additions & 24 deletions test/responders/__init__.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
import unittest
from abc import ABC
from unittest.mock import Mock

from src.bot import MeshtasticBot
from src.data_classes import MeshNode
from src.responders.responder import AbstractResponder
from test.test_setup_data import get_test_bot
from test import BaseFeatureTestCase


class ResponderTestCase(unittest.TestCase, ABC):
class ResponderTestCase(BaseFeatureTestCase, ABC):
responder: AbstractResponder

bot: MeshtasticBot
mock_interface: Mock
test_admin_nodes: list[MeshNode] = []
test_non_admin_nodes: list[MeshNode] = []
test_nodes: list[MeshNode] = []

def setUp(self):
self.bot, self.test_non_admin_nodes, self.test_admin_nodes = get_test_bot()
self.test_nodes = self.test_non_admin_nodes + self.test_admin_nodes
self.mock_interface = self.bot.interface = Mock()

def assert_message_sent(self, expected_response: str, to: MeshNode, want_ack: bool = False):
self.mock_interface.sendText.assert_called_once_with(
expected_response,
destinationId=to.user.id,
wantAck=want_ack
)
36 changes: 36 additions & 0 deletions test/responders/test_message_reaction_responder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest
from unittest.mock import patch

from src.responders.message_reaction_responder import MessageReactionResponder
from test.responders import ResponderTestCase
from test.test_setup_data import build_test_text_packet


class TestMessageReactionResponder(ResponderTestCase):
responder: MessageReactionResponder

def setUp(self):
super().setUp()
self.responder = MessageReactionResponder(bot=self.bot, emoji="👍😊🎉")

@patch('random.choice', return_value="👍")
def test_handle_packet(self, mock_random_choice):
sender_node = self.test_nodes[1]

packet = build_test_text_packet('Hello', sender_node.user.id, self.bot.my_id, channel=1)
self.responder.handle_packet(packet)

self.assert_reaction_sent("👍", packet['id'], channel=1)

def test_handle_packet_not_enrolled(self):
sender_node = self.test_nodes[1]

packet = build_test_text_packet('Hello', sender_node.user.id, self.bot.my_id, channel=1)
self.bot.user_prefs_persistence.get_user_prefs.return_value = None
self.responder.handle_packet(packet)

self.bot.interface.sendReaction.assert_not_called()


if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions test/test_base_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ def test_react_in_channel(self):
sender = self.test_non_admin_nodes[1]
packet = build_test_text_packet('!test', sender.user.id, self.bot.my_id, channel=1)
self.feature.react_in_channel(packet, "👍")
self.mock_interface.sendReaction.assert_called_once_with("👍", packet['id'], channelIndex=1)
self.mock_interface.sendReaction.assert_called_once_with("👍", messageId=packet['id'], channelIndex=1)

def test_react_in_dm(self):
sender = self.test_non_admin_nodes[1]
packet = build_test_text_packet('!test', sender.user.id, self.bot.my_id)
self.feature.react_in_dm(packet, "👍")
self.mock_interface.sendReaction.assert_called_once_with("👍", packet['id'], sender.user.id)
self.mock_interface.sendReaction.assert_called_once_with("👍", messageId=packet['id'], destinationId=sender.user.id)


if __name__ == '__main__':
Expand Down