Exemple #1
0
    async def test_thinking_sleep(self):
        opsdroid = amock.CoroutineMock()
        mock_connector_int = Connector({
            'name': 'shell',
            'thinking-delay': 3,
            'type': 'connector',
            'module_path': 'opsdroid-modules.connector.shell'
        }, opsdroid=opsdroid)

        with amock.patch('asyncio.sleep') as mocksleep_int:
            message = events.Message("user", "default", mock_connector_int, "hi")
            with self.assertRaises(NotImplementedError):
                await message.respond("Hello there")

            self.assertTrue(mocksleep_int.called)

        # Test thinking-delay with a list

        mock_connector_list = Connector({
            'name': 'shell',
            'thinking-delay': [1, 4],
            'type': 'connector',
            'module_path': 'opsdroid-modules.connector.shell'
        }, opsdroid=opsdroid)

        with amock.patch('asyncio.sleep') as mocksleep_list:
            message = events.Message("user", "default", mock_connector_list, "hi")
            with self.assertRaises(NotImplementedError):
                await message.respond("Hello there")

            self.assertTrue(mocksleep_list.called)
 async def test_send_message_start_thread_is_true(self):
     connector = ConnectorSlack({"token": "abc123"}, opsdroid=self.od)
     connector.slack.api_call = amock.CoroutineMock()
     connector.start_thread = True
     event_id = "1582838099.000601"
     linked_event = events.Message(text="linked text",
                                   event_id=event_id,
                                   raw_event={})
     message = events.Message(
         text="test",
         user="******",
         target="room",
         connector=connector,
         linked_event=linked_event,
     )
     await connector.send(message)
     connector.slack.api_call.assert_called_once_with(
         "chat.postMessage",
         data={
             "channel": "room",
             "text": "test",
             "as_user": False,
             "username": "******",
             "icon_emoji": ":robot_face:",
             "thread_ts": "1582838099.000601",
         },
     )
Exemple #3
0
    async def run_skill(self, skill, config, event):
        """Execute a skill.

        Attempts to run the skill parsed and provides other arguments to the skill if necessary.
        Also handles the exception encountered if th e

        Args:
            skill: name of the skill to be run.
            config: The configuration the skill must be loaded in.
            event: Message/event to be parsed to the chat service.

        """
        # pylint: disable=broad-except
        # We want to catch all exceptions coming from a skill module and not
        # halt the application. If a skill throws an exception it just doesn't
        # give a response to the user, so an error response should be given.
        try:
            if len(inspect.signature(skill).parameters.keys()) > 1:
                return await skill(self, config, event)
            else:
                return await skill(event)
        except Exception:
            _LOGGER.exception(_("Exception when running skill '%s'."),
                              str(config["name"]))
            if event:
                await event.respond(
                    events.Message(_("Whoops there has been an error.")))
                await event.respond(
                    events.Message(_("Check the log for details.")))
Exemple #4
0
async def twim_bot(opsdroid, config, message):
    """
    React to a TWIM post.

    Check the contents of the message then put it in the opsdroid memory.
    """
    if isinstance(message, events.EditedMessage):
        return

    # If the message starts with TWIM and it's a reply then we use the parent event.
    if isinstance(message, events.Reply):
        message = message.linked_event

    post = await process_twim_event(opsdroid, message.target, message)
    _LOGGER.debug(f"Processed TWIM event, got: {post}")

    content = list(post.values())[0]
    nick = content['nick']

    try:
        await message.respond(
            events.Reaction(MAGIC_EMOJI + VARIATION_SELECTOR_16))
    except MatrixException:
        _LOGGER.error("Failed to react to submission with magic emoji.")
        pass

    # Send the update to the echo room.
    if "echo" in message.connector.rooms:
        echo_event_id = await message.respond(
            events.Message(format_update(post), target="echo"))
        echo_event_id = echo_event_id.event_id
        content['echo_event_id'] = echo_event_id

    await add_post_to_memory(opsdroid, message.target, post)
    async def test_send_reaction(self):
        message = events.Message(
            "hello",
            event_id="$11111",
            connector=self.connector,
            target="!test:localhost",
        )
        reaction = events.Reaction("⭕")
        with OpsDroid() as _:
            with amock.patch(
                    api_string.format("send_message_event")) as patched_send:
                patched_send.return_value = asyncio.Future()
                patched_send.return_value.set_result(None)

                await message.respond(reaction)

                content = {
                    "m.relates_to": {
                        "rel_type": "m.annotation",
                        "event_id": "$11111",
                        "key": reaction.emoji,
                    }
                }

                assert patched_send.called_once_with("!test:localhost",
                                                     "m.reaction", content)
    async def test_send_reply(self):
        message = events.Message(
            "hello",
            event_id="$11111",
            connector=self.connector,
            target="!test:localhost",
        )
        reply = events.Reply("reply")
        with OpsDroid() as _:
            with amock.patch(
                    api_string.format("send_message_event")) as patched_send:
                patched_send.return_value = asyncio.Future()
                patched_send.return_value.set_result(None)

                await message.respond(reply)

                content = self.connector._get_formatted_message_body(
                    reply.text, msgtype="m.text")

                content["m.relates_to"] = {
                    "m.in_reply_to": {
                        "event_id": message.event_id
                    }
                }

                assert patched_send.called_once_with("!test:localhost",
                                                     "m.room.message", content)
async def test_respond_failure(opsdroid, caplog):
    caplog.set_level(logging.DEBUG)

    connector = ConnectorTelegram(connector_config, opsdroid=opsdroid)

    response = amock.Mock()
    response.status = 500

    with amock.patch(
            "aiohttp.ClientSession.post",
            new=amock.CoroutineMock()) as patched_request, amock.patch.object(
                connector, "build_url") as mocked_build_url:
        patched_request.return_value = asyncio.Future()
        patched_request.return_value.set_result(response)

        assert opsdroid.__class__.instances

        test_message = opsdroid_events.Message(
            text="This is a test",
            user="******",
            target={"id": 12404},
            connector=connector,
        )

        patched_request.return_value = asyncio.Future()
        patched_request.return_value.set_result(response)

        await test_message.respond("Response")

        assert patched_request.called
        assert mocked_build_url.called
        assert "Responding" in caplog.text
        assert "Unable to respond" in caplog.text
Exemple #8
0
    async def test_message(self):
        opsdroid = amock.CoroutineMock()
        mock_connector = Connector({}, opsdroid=opsdroid)
        raw_message = {
            'text': 'Hello world',
            'user': '******',
            'room': 'default',
            'timestamp': '01/01/2000 19:23:00',
            'messageId': '101'
        }
        message = events.Message(
            "user",
            "default",
            mock_connector,
            "Hello world",
            raw_message)

        self.assertEqual(message.text, "Hello world")
        self.assertEqual(message.user, "user")
        self.assertEqual(message.room, "default")
        self.assertEqual(
            message.raw_event['timestamp'], '01/01/2000 19:23:00'
            )
        self.assertEqual(message.raw_event['messageId'], '101')
        with self.assertRaises(NotImplementedError):
            await message.respond("Goodbye world")
        # Also try responding with just some empty Event
        with self.assertRaises(NotImplementedError):
            await message.respond(events.Event(
                message.user, message.room, message.connector))
Exemple #9
0
    async def test_message(self):
        with OpsDroid() as opsdroid:
            mock_connector = Connector({}, opsdroid=opsdroid)
            raw_message = {
                "text": "Hello world",
                "user_id": "user_id",
                "user": "******",
                "room": "default",
                "timestamp": "01/01/2000 19:23:00",
                "messageId": "101",
            }
            message = events.Message(
                text="Hello world",
                user_id="user_id",
                user="******",
                target="default",
                connector=mock_connector,
                raw_event=raw_message,
            )

            self.assertEqual(message.text, "Hello world")
            self.assertEqual(message.user_id, "user_id")
            self.assertEqual(message.user, "user")
            self.assertEqual(message.target, "default")
            self.assertEqual(message.raw_event["timestamp"],
                             "01/01/2000 19:23:00")
            self.assertEqual(message.raw_event["messageId"], "101")
            with self.assertRaises(TypeError):
                await message.respond("Goodbye world")
            # Also try responding with just some empty Event
            with self.assertRaises(TypeError):
                await message.respond(
                    events.Event(message.user, message.target,
                                 message.connector))
Exemple #10
0
    async def test_message(self):
        with OpsDroid() as opsdroid:
            mock_connector = Connector({}, opsdroid=opsdroid)
            raw_message = {
                'text': 'Hello world',
                'user': '******',
                'room': 'default',
                'timestamp': '01/01/2000 19:23:00',
                'messageId': '101'
            }
            message = events.Message("Hello world",
                                     "user",
                                     "default",
                                     mock_connector,
                                     raw_event=raw_message)

            self.assertEqual(message.text, "Hello world")
            self.assertEqual(message.user, "user")
            self.assertEqual(message.target, "default")
            self.assertEqual(message.raw_event['timestamp'],
                             '01/01/2000 19:23:00')
            self.assertEqual(message.raw_event['messageId'], '101')
            with self.assertRaises(TypeError):
                await message.respond("Goodbye world")
            # Also try responding with just some empty Event
            with self.assertRaises(TypeError):
                await message.respond(
                    events.Event(message.user, message.target,
                                 message.connector))
Exemple #11
0
    async def create_message(self, event, roomid):
        """Send a Message event."""
        kwargs = dict(
            text=event["content"]["body"],
            user_id=event["sender"],
            user=await self.connector.get_nick(roomid, event["sender"]),
            target=roomid,
            connector=self.connector,
            event_id=event["event_id"],
            raw_event=event,
        )
        if "m.relates_to" in event["content"]:
            relates_to = event["content"]["m.relates_to"]
            # Detect an edit.
            if relates_to.get("rel_type", "") == "m.replace":
                kwargs["text"] = event["content"]["m.new_content"]["body"]
                kwargs["linked_event"] = await self.create_event_from_eventid(
                    relates_to["event_id"], roomid)
                return events.EditedMessage(**kwargs)
            # Detect a reply
            if relates_to.get("m.in_reply_to"):
                kwargs["text"] = trim_reply_fallback_text(kwargs["text"])
                kwargs["linked_event"] = await self.create_event_from_eventid(
                    relates_to["m.in_reply_to"]["event_id"], roomid)
                return events.Reply(**kwargs)

        return events.Message(**kwargs)
Exemple #12
0
 async def test_response_effects(self):
     """Responding to a message shouldn't change the message."""
     opsdroid = amock.CoroutineMock()
     mock_connector = Connector({}, opsdroid=opsdroid)
     message_text = "Hello world"
     message = events.Message("user", "default", mock_connector, message_text)
     with self.assertRaises(NotImplementedError):
         await message.respond("Goodbye world")
     self.assertEqual(message_text, message.text)
 async def test_response_effects(self):
     """Responding to a message shouldn't change the message."""
     with OpsDroid() as opsdroid:
         mock_connector = Connector({}, opsdroid=opsdroid)
         message_text = "Hello world"
         message = events.Message(message_text, "user", "default", mock_connector)
         with self.assertRaises(TypeError):
             await message.respond("Goodbye world")
         self.assertEqual(message_text, message.text)
 async def test_respond(self):
     connector = ConnectorSlack({"token": "abc123"}, opsdroid=self.od)
     connector.slack.api_call = amock.CoroutineMock()
     await connector.send(
         events.Message(text="test",
                        user="******",
                        target="room",
                        connector=connector))
     self.assertTrue(connector.slack.api_call.called)
Exemple #15
0
 async def create_message(self, event, roomid):
     """Send a Message event."""
     return events.Message(event['content']['body'],
                           await
                           self.connector.get_nick(roomid, event['sender']),
                           roomid,
                           self.connector,
                           event_id=event['event_id'],
                           raw_event=event)
Exemple #16
0
async def test_send_reaction_invalid_name(send_event):
    message = events.Message(
        text="linked text",
        target="room",
        event_id="1582838099.000601",
        raw_event={"ts": 0},
    )
    event = events.Reaction("NOT_EMOJI", target=message.target, linked_event=message)
    await send_event(("/reactions.add",), event)
Exemple #17
0
 async def run_skill(self, skill, config, message):
     """Execute a skill."""
     # pylint: disable=broad-except
     # We want to catch all exceptions coming from a skill module and not
     # halt the application. If a skill throws an exception it just doesn't
     # give a response to the user, so an error response should be given.
     try:
         if len(inspect.signature(skill).parameters.keys()) > 1:
             await skill(self, config, message)
         else:
             await skill(message)
     except Exception:
         _LOGGER.exception(_("Exception when running skill '%s' "),
                           str(config["name"]))
         if message:
             await message.respond(
                 events.Message(_("Whoops there has been an error")))
             await message.respond(
                 events.Message(_("Check the log for details")))
Exemple #18
0
 async def create_message(self, event, roomid):
     """Send a Message event."""
     return events.Message(
         event["content"]["body"],
         await self.connector.get_nick(roomid, event["sender"]),
         roomid,
         self.connector,
         event_id=event["event_id"],
         raw_event=event,
     )
Exemple #19
0
async def test_send_message(send_event, connector):
    event = events.Message(text="test", user="******", target="room", connector=connector)
    payload, response = await send_event(CHAT_POST_MESSAGE, event)
    assert payload == {
        "channel": "room",
        "text": "test",
        "username": "******",
        "icon_emoji": ":robot_face:",
    }
    assert response["ok"]
    async def test_parse_invalid_str(self):
        with OpsDroid() as opsdroid:
            mock_skill = await self.getMockSkill()
            opsdroid.skills.append(match_event("Message2")(mock_skill))

            mock_connector = amock.CoroutineMock()
            message = events.Message("Hello World", "user", "default", mock_connector)

            with self.assertRaises(ValueError):
                await parse_event_type(opsdroid, message)
Exemple #21
0
async def test_send_reaction_unknown_error(send_event):
    message = events.Message(
        text="linked text",
        target="room",
        event_id="1582838099.000601",
        raw_event={"ts": 0},
    )
    event = events.Reaction("NOT_EMOJI", target=message.target, linked_event=message)
    with pytest.raises(SlackApiError):
        _, response = await send_event(("/reactions.add",), event)
        assert not response["ok"]
async def test_send_message_event(opsdroid, caplog):
    caplog.set_level(logging.DEBUG)
    connector = ConnectorTwitch(connector_config, opsdroid=opsdroid)
    message_event = opsdroid_events.Message(text="Hello world!")

    connector.send_message = amock.CoroutineMock()

    await connector._send_message(message_event)

    assert connector.send_message.called
    assert "Hello world!" in caplog.text
    async def test_parse_str_event(self):
        with OpsDroid() as opsdroid:
            opsdroid.run_skill = amock.CoroutineMock()
            mock_skill = await self.getMockSkill()
            opsdroid.skills.append(match_event("Message")(mock_skill))

            mock_connector = amock.CoroutineMock()
            message = events.Message("Hello World", "user", "default", mock_connector)

            await opsdroid.parse(message)
            self.assertTrue(opsdroid.run_skill.called)
Exemple #24
0
    async def test_typing_delay(self):
        with OpsDroid() as opsdroid:
            mock_connector = Connector(
                {
                    "name": "shell",
                    "typing-delay": 0.3,
                    "type": "connector",
                    "module_path": "opsdroid-modules.connector.shell",
                },
                opsdroid=opsdroid,
            )
            with amock.patch(
                    "opsdroid.events.Message._typing_delay") as logmock:
                with amock.patch("asyncio.sleep") as mocksleep:
                    message = events.Message("hi", "user_id", "user",
                                             "default", mock_connector)
                    with self.assertRaises(TypeError):
                        await message.respond("Hello there")

                    self.assertTrue(logmock.called)
                    self.assertTrue(mocksleep.called)

            # Test thinking-delay with a list

            mock_connector_list = Connector(
                {
                    "name": "shell",
                    "typing-delay": [1, 4],
                    "type": "connector",
                    "module_path": "opsdroid-modules.connector.shell",
                },
                opsdroid=opsdroid,
            )

            with amock.patch("asyncio.sleep") as mocksleep_list:
                message = events.Message("hi", "user_id", "user", "default",
                                         mock_connector_list)
                with self.assertRaises(TypeError):
                    await message.respond("Hello there")

                self.assertTrue(mocksleep_list.called)
Exemple #25
0
async def test_send_message_inside_thread_is_true(connector, send_event):
    connector.start_thread = True
    linked_event = events.Message(
        text="linked text", event_id="1582838099.000601", raw_event={}
    )
    event = events.Message(
        text="test",
        user="******",
        target="room",
        connector=connector,
        linked_event=linked_event,
    )
    payload, response = await send_event(CHAT_POST_MESSAGE, event)
    assert payload == {
        "channel": "room",
        "text": "test",
        "username": "******",
        "icon_emoji": ":robot_face:",
        "thread_ts": "1582838099.000601",
    }
    assert response["ok"]
Exemple #26
0
 async def test_react(self):
     opsdroid = amock.CoroutineMock()
     mock_connector = Connector({
         'name': 'shell',
         'thinking-delay': 2,
         'type': 'connector',
     }, opsdroid=opsdroid)
     with amock.patch('asyncio.sleep') as mocksleep:
         message = events.Message("user", "default", mock_connector, "Hello world")
         reacted = await message.react("emoji")
         self.assertTrue(mocksleep.called)
         self.assertFalse(reacted)
Exemple #27
0
    async def add_item(self, message):
        await message.respond(events.Message("Adding item to agenda"))

        db = self.opsdroid.get_database("matrix")

        with db.memory_in_room(message.target):
            all_items = await self.opsdroid.memory.get("agenda_items") or []

        all_items.append(message.regex.capturesdict()['item'][0])

        with db.memory_in_room(message.target):
            await self.opsdroid.memory.put("agenda_items", all_items)
Exemple #28
0
    async def test_typing_delay(self):
        with OpsDroid() as opsdroid:
            mock_connector = Connector(
                {
                    'name': 'shell',
                    'typing-delay': 0.3,
                    'type': 'connector',
                    'module_path': 'opsdroid-modules.connector.shell'
                },
                opsdroid=opsdroid)
            with amock.patch(
                    'opsdroid.events.Message._typing_delay') as logmock:
                with amock.patch('asyncio.sleep') as mocksleep:
                    message = events.Message("hi", "user", "default",
                                             mock_connector)
                    with self.assertRaises(TypeError):
                        await message.respond("Hello there")

                    self.assertTrue(logmock.called)
                    self.assertTrue(mocksleep.called)

            # Test thinking-delay with a list

            mock_connector_list = Connector(
                {
                    'name': 'shell',
                    'typing-delay': [1, 4],
                    'type': 'connector',
                    'module_path': 'opsdroid-modules.connector.shell'
                },
                opsdroid=opsdroid)

            with amock.patch('asyncio.sleep') as mocksleep_list:
                message = events.Message("hi", "user", "default",
                                         mock_connector_list)
                with self.assertRaises(TypeError):
                    await message.respond("Hello there")

                self.assertTrue(mocksleep_list.called)
 async def test_react(self):
     with OpsDroid() as opsdroid:
         mock_connector = Connector(
             {"name": "shell", "thinking-delay": 2, "type": "connector"},
             opsdroid=opsdroid,
         )
         with amock.patch("asyncio.sleep") as mocksleep:
             message = events.Message(
                 "Hello world", "user", "default", mock_connector
             )
             with self.assertRaises(TypeError):
                 await message.respond(events.Reaction("emoji"))
             self.assertTrue(mocksleep.called)
    async def test_parse_event_with_args(self):
        with OpsDroid() as opsdroid:
            opsdroid.run_skill = amock.CoroutineMock()
            mock_skill = await self.getMockSkill()
            opsdroid.skills.append(
                match_event(events.Message, value="click_me_123")(mock_skill)
            )

            mock_connector = amock.CoroutineMock()
            message1 = events.Message("Hello World", "user", "default", mock_connector)
            message1.update_entity("value", "click_me_123")

            await opsdroid.parse(message1)
            self.assertTrue(opsdroid.run_skill.called)

            opsdroid.run_skill.reset_mock()

            message2 = events.Message("Hello World", "user", "default", mock_connector)
            message2.update_entity("value", "click_me_456")

            await opsdroid.parse(message2)
            self.assertFalse(opsdroid.run_skill.called)