add more tests
This commit is contained in:
parent
27828ec3c7
commit
6ae3355f3c
9 changed files with 925 additions and 77 deletions
|
@ -5,7 +5,6 @@ import logging
|
||||||
from diskcache import Cache
|
from diskcache import Cache
|
||||||
from nio.client import AsyncClient
|
from nio.client import AsyncClient
|
||||||
from nio.events import (
|
from nio.events import (
|
||||||
Event,
|
|
||||||
InviteMemberEvent,
|
InviteMemberEvent,
|
||||||
KeyVerificationCancel,
|
KeyVerificationCancel,
|
||||||
KeyVerificationKey,
|
KeyVerificationKey,
|
||||||
|
@ -470,10 +469,3 @@ class Callbacks:
|
||||||
raise SendRetryError(
|
raise SendRetryError(
|
||||||
f"{response_event.status_code} - {response_event.message}"
|
f"{response_event.status_code} - {response_event.message}"
|
||||||
)
|
)
|
||||||
|
|
||||||
async def debug(self, room: MatrixRoom, event: Event) -> None:
|
|
||||||
logger.debug(
|
|
||||||
f"Bot {self.matrix_client.user_id} | Room ID {room.room_id} | "
|
|
||||||
f"Event ID {event.event_id} | Sender {event.sender} | "
|
|
||||||
f"Received some event: {event.source}"
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
[pytest]
|
[pytest]
|
||||||
asyncio_mode=strict
|
asyncio_mode=strict
|
||||||
|
addopts=--cov=matrix_alertbot --cov-report=lcov:lcov.info --cov-report=term
|
||||||
|
|
|
@ -50,7 +50,8 @@ test =
|
||||||
flake8-comprehensions>=3.10.0
|
flake8-comprehensions>=3.10.0
|
||||||
isort>=5.10.1
|
isort>=5.10.1
|
||||||
mypy>=0.961
|
mypy>=0.961
|
||||||
pytest>=7.1.2
|
pytest>=7.4.0
|
||||||
|
pytest-cov>=4.1.0
|
||||||
pytest-asyncio>=0.18.3
|
pytest-asyncio>=0.18.3
|
||||||
freezegun>=1.2.1
|
freezegun>=1.2.1
|
||||||
types-PyYAML>=6.0.9
|
types-PyYAML>=6.0.9
|
||||||
|
|
|
@ -24,12 +24,6 @@ from matrix_alertbot.errors import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def update_silence_raise_silence_not_found(
|
|
||||||
fingerprint: str, user: str, duration_seconds: int, *, force: bool = False
|
|
||||||
) -> str:
|
|
||||||
raise SilenceNotFoundError
|
|
||||||
|
|
||||||
|
|
||||||
class FakeCache:
|
class FakeCache:
|
||||||
def __init__(self, cache_dict: Optional[Dict] = None) -> None:
|
def __init__(self, cache_dict: Optional[Dict] = None) -> None:
|
||||||
if cache_dict is None:
|
if cache_dict is None:
|
||||||
|
@ -533,14 +527,20 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual({"fingerprint1": ("silence2", 864000)}, fake_cache.cache)
|
self.assertEqual({"fingerprint1": ("silence2", 864000)}, fake_cache.cache)
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "update_silence")
|
@patch.object(
|
||||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "create_silence")
|
matrix_alertbot.alertmanager.AlertmanagerClient,
|
||||||
|
"update_silence",
|
||||||
|
side_effect=SilenceNotFoundError,
|
||||||
|
)
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.alertmanager.AlertmanagerClient,
|
||||||
|
"create_silence",
|
||||||
|
return_value="silence1",
|
||||||
|
)
|
||||||
async def test_create_or_update_silence_with_duration_and_silence_not_found(
|
async def test_create_or_update_silence_with_duration_and_silence_not_found(
|
||||||
self, fake_create_silence: Mock, fake_update_silence: Mock
|
self, fake_create_silence: Mock, fake_update_silence: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
fake_cache = Mock(spec=Cache)
|
fake_cache = Mock(spec=Cache)
|
||||||
fake_update_silence.side_effect = update_silence_raise_silence_not_found
|
|
||||||
fake_create_silence.return_value = "silence1"
|
|
||||||
|
|
||||||
alertmanager_client = AlertmanagerClient("http://localhost", fake_cache)
|
alertmanager_client = AlertmanagerClient("http://localhost", fake_cache)
|
||||||
async with aiotools.closing_async(alertmanager_client):
|
async with aiotools.closing_async(alertmanager_client):
|
||||||
|
@ -651,14 +651,20 @@ class AlertmanagerClientTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual({"fingerprint1": ("silence2", None)}, fake_cache.cache)
|
self.assertEqual({"fingerprint1": ("silence2", None)}, fake_cache.cache)
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "update_silence")
|
@patch.object(
|
||||||
@patch.object(matrix_alertbot.alertmanager.AlertmanagerClient, "create_silence")
|
matrix_alertbot.alertmanager.AlertmanagerClient,
|
||||||
|
"update_silence",
|
||||||
|
side_effect=SilenceNotFoundError,
|
||||||
|
)
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.alertmanager.AlertmanagerClient,
|
||||||
|
"create_silence",
|
||||||
|
return_value="silence1",
|
||||||
|
)
|
||||||
async def test_create_or_update_silence_without_duration_and_silence_not_found(
|
async def test_create_or_update_silence_without_duration_and_silence_not_found(
|
||||||
self, fake_create_silence: Mock, fake_update_silence: Mock
|
self, fake_create_silence: Mock, fake_update_silence: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
fake_cache = Mock(spec=Cache)
|
fake_cache = Mock(spec=Cache)
|
||||||
fake_update_silence.side_effect = update_silence_raise_silence_not_found
|
|
||||||
fake_create_silence.return_value = "silence1"
|
|
||||||
|
|
||||||
alertmanager_client = AlertmanagerClient("http://localhost", fake_cache)
|
alertmanager_client = AlertmanagerClient("http://localhost", fake_cache)
|
||||||
async with aiotools.closing_async(alertmanager_client):
|
async with aiotools.closing_async(alertmanager_client):
|
||||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from unittest.mock import MagicMock, Mock, patch
|
from unittest.mock import MagicMock, Mock, call, patch
|
||||||
|
|
||||||
import nio
|
import nio
|
||||||
import nio.crypto
|
import nio.crypto
|
||||||
|
@ -14,10 +14,6 @@ import matrix_alertbot.command
|
||||||
import matrix_alertbot.matrix
|
import matrix_alertbot.matrix
|
||||||
|
|
||||||
|
|
||||||
def key_verification_get_mac_raise_protocol_error():
|
|
||||||
raise nio.LocalProtocolError
|
|
||||||
|
|
||||||
|
|
||||||
class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
# Create a Callbacks object and give it some Mock'd objects to use
|
# Create a Callbacks object and give it some Mock'd objects to use
|
||||||
|
@ -67,6 +63,42 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
# Check that we attempted to join the room
|
# Check that we attempted to join the room
|
||||||
self.fake_matrix_client.join.assert_called_once_with(self.fake_room.room_id)
|
self.fake_matrix_client.join.assert_called_once_with(self.fake_room.room_id)
|
||||||
|
|
||||||
|
async def test_invite_in_unauthorized_room(self) -> None:
|
||||||
|
"""Tests the callback for InviteMemberEvents"""
|
||||||
|
# Tests that the bot attempts to join a room after being invited to it
|
||||||
|
fake_invite_event = Mock(spec=nio.InviteMemberEvent)
|
||||||
|
fake_invite_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
|
||||||
|
self.fake_room.room_id = "!unauthorizedroom@example.com"
|
||||||
|
|
||||||
|
# Pretend that we received an invite event
|
||||||
|
await self.callbacks.invite(self.fake_room, fake_invite_event)
|
||||||
|
|
||||||
|
# Check that we attempted to join the room
|
||||||
|
self.fake_matrix_client.join.assert_not_called()
|
||||||
|
|
||||||
|
async def test_invite_raise_join_error(self) -> None:
|
||||||
|
"""Tests the callback for InviteMemberEvents"""
|
||||||
|
# Tests that the bot attempts to join a room after being invited to it
|
||||||
|
fake_invite_event = Mock(spec=nio.InviteMemberEvent)
|
||||||
|
fake_invite_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
|
||||||
|
fake_join_error = Mock(spec=nio.JoinError)
|
||||||
|
fake_join_error.message = "error message"
|
||||||
|
self.fake_matrix_client.join.return_value = fake_join_error
|
||||||
|
|
||||||
|
# Pretend that we received an invite event
|
||||||
|
await self.callbacks.invite(self.fake_room, fake_invite_event)
|
||||||
|
|
||||||
|
# Check that we attempted to join the room
|
||||||
|
self.fake_matrix_client.join.assert_has_calls(
|
||||||
|
[
|
||||||
|
call("!abcdefg:example.com"),
|
||||||
|
call("!abcdefg:example.com"),
|
||||||
|
call("!abcdefg:example.com"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.callback.CommandFactory, "create", autospec=True)
|
@patch.object(matrix_alertbot.callback.CommandFactory, "create", autospec=True)
|
||||||
async def test_message_without_prefix(self, fake_command_create: Mock) -> None:
|
async def test_message_without_prefix(self, fake_command_create: Mock) -> None:
|
||||||
"""Tests the callback for RoomMessageText without any command prefix"""
|
"""Tests the callback for RoomMessageText without any command prefix"""
|
||||||
|
@ -82,6 +114,24 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
# Check that the command was not executed
|
# Check that the command was not executed
|
||||||
fake_command_create.assert_not_called()
|
fake_command_create.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.command, "HelpCommand", autospec=True)
|
||||||
|
async def test_message_help_client_not_in_pool(self, fake_command: Mock) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText without any command prefix"""
|
||||||
|
# Tests that the bot process messages in the room
|
||||||
|
fake_message_event = Mock(spec=nio.RoomMessageText)
|
||||||
|
fake_message_event.event_id = "some event id"
|
||||||
|
fake_message_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_message_event.body = "!alert help"
|
||||||
|
fake_message_event.source = {"content": {}}
|
||||||
|
|
||||||
|
self.fake_matrix_client_pool.matrix_client = None
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.message(self.fake_room, fake_message_event)
|
||||||
|
|
||||||
|
# Check that the command was not executed
|
||||||
|
fake_command.assert_not_called()
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.command, "HelpCommand", autospec=True)
|
@patch.object(matrix_alertbot.command, "HelpCommand", autospec=True)
|
||||||
async def test_message_help_not_in_reply_with_prefix(
|
async def test_message_help_not_in_reply_with_prefix(
|
||||||
self, fake_command: Mock
|
self, fake_command: Mock
|
||||||
|
@ -271,6 +321,72 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
)
|
)
|
||||||
fake_command.return_value.process.assert_called_once()
|
fake_command.return_value.process.assert_called_once()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.command, "AckAlertCommand", autospec=True)
|
||||||
|
async def test_message_raise_exception(
|
||||||
|
self, fake_command: Mock, fake_logger
|
||||||
|
) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
# Tests that the bot process messages in the room that contain a command
|
||||||
|
fake_message_event = Mock(spec=nio.RoomMessageText)
|
||||||
|
fake_message_event.event_id = "some event id"
|
||||||
|
fake_message_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_message_event.body = "!alert ack"
|
||||||
|
fake_message_event.source = {
|
||||||
|
"content": {
|
||||||
|
"m.relates_to": {"m.in_reply_to": {"event_id": "some alert event id"}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_command.return_value.process.side_effect = (
|
||||||
|
nio.exceptions.LocalProtocolError
|
||||||
|
)
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.message(self.fake_room, fake_message_event)
|
||||||
|
|
||||||
|
# Check that the command was not executed
|
||||||
|
fake_command.assert_called_once_with(
|
||||||
|
self.fake_matrix_client,
|
||||||
|
self.fake_cache,
|
||||||
|
self.fake_alertmanager_client,
|
||||||
|
self.fake_config,
|
||||||
|
self.fake_room,
|
||||||
|
fake_message_event.sender,
|
||||||
|
fake_message_event.event_id,
|
||||||
|
"some alert event id",
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
fake_command.return_value.process.assert_called_once()
|
||||||
|
|
||||||
|
fake_logger.exception.assert_called_once()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
||||||
|
async def test_reaction_client_not_in_pool(self, fake_command: Mock) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
# Tests that the bot process messages in the room that contain a command
|
||||||
|
fake_alert_event = Mock(spec=nio.RoomMessageText)
|
||||||
|
fake_alert_event.event_id = "some alert event id"
|
||||||
|
fake_alert_event.sender = self.fake_matrix_client.user_id
|
||||||
|
|
||||||
|
fake_reaction_event = Mock(spec=nio.ReactionEvent)
|
||||||
|
fake_reaction_event.event_id = "some event id"
|
||||||
|
fake_reaction_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_reaction_event.reacts_to = fake_alert_event.event_id
|
||||||
|
fake_reaction_event.key = "🤫"
|
||||||
|
|
||||||
|
fake_event_response = Mock(spec=nio.RoomGetEventResponse)
|
||||||
|
fake_event_response.event = fake_alert_event
|
||||||
|
self.fake_matrix_client.room_get_event.return_value = fake_event_response
|
||||||
|
|
||||||
|
self.fake_matrix_client_pool.matrix_client = None
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.reaction(self.fake_room, fake_reaction_event)
|
||||||
|
|
||||||
|
# Check that we attempted to execute the command
|
||||||
|
fake_command.assert_not_called()
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
||||||
async def test_reaction_to_existing_alert(self, fake_command: Mock) -> None:
|
async def test_reaction_to_existing_alert(self, fake_command: Mock) -> None:
|
||||||
"""Tests the callback for RoomMessageText with the command prefix"""
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
@ -365,6 +481,52 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
self.fake_room.room_id, fake_alert_event.event_id
|
self.fake_room.room_id, fake_alert_event.event_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
||||||
|
async def test_reaction_raise_exception(
|
||||||
|
self, fake_command: Mock, fake_logger: Mock
|
||||||
|
) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
# Tests that the bot process messages in the room that contain a command
|
||||||
|
fake_alert_event = Mock(spec=nio.RoomMessageText)
|
||||||
|
fake_alert_event.event_id = "some alert event id"
|
||||||
|
fake_alert_event.sender = self.fake_matrix_client.user_id
|
||||||
|
|
||||||
|
fake_reaction_event = Mock(spec=nio.ReactionEvent)
|
||||||
|
fake_reaction_event.event_id = "some event id"
|
||||||
|
fake_reaction_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_reaction_event.reacts_to = fake_alert_event.event_id
|
||||||
|
fake_reaction_event.key = "🤫"
|
||||||
|
|
||||||
|
fake_event_response = Mock(spec=nio.RoomGetEventResponse)
|
||||||
|
fake_event_response.event = fake_alert_event
|
||||||
|
self.fake_matrix_client.room_get_event.return_value = fake_event_response
|
||||||
|
|
||||||
|
fake_command.return_value.process.side_effect = (
|
||||||
|
nio.exceptions.LocalProtocolError
|
||||||
|
)
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.reaction(self.fake_room, fake_reaction_event)
|
||||||
|
|
||||||
|
# Check that we attempted to execute the command
|
||||||
|
fake_command.assert_called_once_with(
|
||||||
|
self.fake_matrix_client,
|
||||||
|
self.fake_cache,
|
||||||
|
self.fake_alertmanager_client,
|
||||||
|
self.fake_config,
|
||||||
|
self.fake_room,
|
||||||
|
fake_reaction_event.sender,
|
||||||
|
fake_reaction_event.event_id,
|
||||||
|
"some alert event id",
|
||||||
|
)
|
||||||
|
fake_command.return_value.process.assert_called_once()
|
||||||
|
self.fake_matrix_client.room_get_event.assert_called_once_with(
|
||||||
|
self.fake_room.room_id, fake_alert_event.event_id
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_logger.exception.assert_called_once()
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
@patch.object(matrix_alertbot.callback, "AckAlertCommand", autospec=True)
|
||||||
async def test_reaction_unknown(self, fake_command: Mock) -> None:
|
async def test_reaction_unknown(self, fake_command: Mock) -> None:
|
||||||
"""Tests the callback for RoomMessageText with the command prefix"""
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
@ -429,6 +591,28 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
fake_command.assert_not_called()
|
fake_command.assert_not_called()
|
||||||
self.fake_matrix_client.room_get_event.assert_not_called()
|
self.fake_matrix_client.room_get_event.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
||||||
|
async def test_redaction_client_not_in_pool(self, fake_command: Mock) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
# Tests that the bot process messages in the room that contain a command
|
||||||
|
fake_alert_event_id = "some alert event id"
|
||||||
|
|
||||||
|
fake_redaction_event = Mock(spec=nio.RedactionEvent)
|
||||||
|
fake_redaction_event.redacts = "some other event id"
|
||||||
|
fake_redaction_event.event_id = "some event id"
|
||||||
|
fake_redaction_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
|
||||||
|
fake_cache_dict = {fake_redaction_event.redacts: fake_alert_event_id}
|
||||||
|
self.fake_cache.__getitem__.side_effect = fake_cache_dict.__getitem__
|
||||||
|
|
||||||
|
self.fake_matrix_client_pool.matrix_client = None
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.redaction(self.fake_room, fake_redaction_event)
|
||||||
|
|
||||||
|
# Check that we attempted to execute the command
|
||||||
|
fake_command.assert_not_called()
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
||||||
async def test_redaction(self, fake_command: Mock) -> None:
|
async def test_redaction(self, fake_command: Mock) -> None:
|
||||||
"""Tests the callback for RoomMessageText with the command prefix"""
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
@ -459,6 +643,45 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
)
|
)
|
||||||
fake_command.return_value.process.assert_called_once()
|
fake_command.return_value.process.assert_called_once()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
||||||
|
async def test_redaction_raise_exception(
|
||||||
|
self, fake_command: Mock, fake_logger
|
||||||
|
) -> None:
|
||||||
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
# Tests that the bot process messages in the room that contain a command
|
||||||
|
fake_alert_event_id = "some alert event id"
|
||||||
|
|
||||||
|
fake_redaction_event = Mock(spec=nio.RedactionEvent)
|
||||||
|
fake_redaction_event.redacts = "some other event id"
|
||||||
|
fake_redaction_event.event_id = "some event id"
|
||||||
|
fake_redaction_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
|
||||||
|
fake_cache_dict = {fake_redaction_event.redacts: fake_alert_event_id}
|
||||||
|
self.fake_cache.__getitem__.side_effect = fake_cache_dict.__getitem__
|
||||||
|
|
||||||
|
fake_command.return_value.process.side_effect = (
|
||||||
|
nio.exceptions.LocalProtocolError
|
||||||
|
)
|
||||||
|
|
||||||
|
# Pretend that we received a text message event
|
||||||
|
await self.callbacks.redaction(self.fake_room, fake_redaction_event)
|
||||||
|
|
||||||
|
# Check that we attempted to execute the command
|
||||||
|
fake_command.assert_called_once_with(
|
||||||
|
self.fake_matrix_client,
|
||||||
|
self.fake_cache,
|
||||||
|
self.fake_alertmanager_client,
|
||||||
|
self.fake_config,
|
||||||
|
self.fake_room,
|
||||||
|
fake_redaction_event.sender,
|
||||||
|
fake_redaction_event.event_id,
|
||||||
|
fake_redaction_event.redacts,
|
||||||
|
)
|
||||||
|
fake_command.return_value.process.assert_called_once()
|
||||||
|
|
||||||
|
fake_logger.exception.assert_called_once()
|
||||||
|
|
||||||
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
@patch.object(matrix_alertbot.callback, "UnackAlertCommand", autospec=True)
|
||||||
async def test_ignore_redaction_sent_by_bot_user(self, fake_command: Mock) -> None:
|
async def test_ignore_redaction_sent_by_bot_user(self, fake_command: Mock) -> None:
|
||||||
"""Tests the callback for RoomMessageText with the command prefix"""
|
"""Tests the callback for RoomMessageText with the command prefix"""
|
||||||
|
@ -718,7 +941,7 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
fake_key_verification_event.transaction_id = fake_transaction_id
|
fake_key_verification_event.transaction_id = fake_transaction_id
|
||||||
|
|
||||||
fake_sas = Mock()
|
fake_sas = Mock()
|
||||||
fake_sas.get_mac.side_effect = key_verification_get_mac_raise_protocol_error
|
fake_sas.get_mac.side_effect = nio.exceptions.LocalProtocolError
|
||||||
fake_transactions_dict = {fake_transaction_id: fake_sas}
|
fake_transactions_dict = {fake_transaction_id: fake_sas}
|
||||||
self.fake_matrix_client.key_verifications = fake_transactions_dict
|
self.fake_matrix_client.key_verifications = fake_transactions_dict
|
||||||
|
|
||||||
|
@ -751,6 +974,81 @@ class CallbacksTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
fake_sas.get_mac.assert_called_once_with()
|
fake_sas.get_mac.assert_called_once_with()
|
||||||
self.fake_matrix_client.to_device.assert_called_once_with(fake_sas.get_mac())
|
self.fake_matrix_client.to_device.assert_called_once_with(fake_sas.get_mac())
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "logger", autospec=True)
|
||||||
|
async def test_decryption_failure(self, fake_logger) -> None:
|
||||||
|
fake_megolm_event = Mock(spec=nio.MegolmEvent)
|
||||||
|
fake_megolm_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_megolm_event.event_id = "some event id"
|
||||||
|
|
||||||
|
await self.callbacks.decryption_failure(self.fake_room, fake_megolm_event)
|
||||||
|
|
||||||
|
fake_logger.error.assert_called_once()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.callback, "logger", autospec=True)
|
||||||
|
async def test_decryption_failure_in_unauthorized_room(self, fake_logger) -> None:
|
||||||
|
fake_megolm_event = Mock(spec=nio.MegolmEvent)
|
||||||
|
fake_megolm_event.sender = "@some_other_fake_user:example.com"
|
||||||
|
fake_megolm_event.event_id = "some event id"
|
||||||
|
|
||||||
|
self.fake_room.room_id = "!unauthorizedroom@example.com"
|
||||||
|
|
||||||
|
await self.callbacks.decryption_failure(self.fake_room, fake_megolm_event)
|
||||||
|
|
||||||
|
fake_logger.error.assert_not_called()
|
||||||
|
|
||||||
|
async def test_unknown_message(self) -> None:
|
||||||
|
fake_room_unknown_event = Mock(spec=nio.RoomMessageUnknown)
|
||||||
|
fake_room_unknown_event.source = {
|
||||||
|
"content": {
|
||||||
|
"msgtype": "m.key.verification.request",
|
||||||
|
"methods": ["m.sas.v1"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fake_room_unknown_event.event_id = "some event id"
|
||||||
|
|
||||||
|
await self.callbacks.unknown_message(self.fake_room, fake_room_unknown_event)
|
||||||
|
|
||||||
|
self.fake_matrix_client.room_send.assert_called_once_with(
|
||||||
|
self.fake_room.room_id,
|
||||||
|
"m.room.message",
|
||||||
|
{
|
||||||
|
"msgtype": "m.key.verification.ready",
|
||||||
|
"methods": ["m.sas.v1"],
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.reference",
|
||||||
|
"event_id": fake_room_unknown_event.event_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
async def test_unknown_message_with_msgtype_not_verification_request(self) -> None:
|
||||||
|
fake_room_unknown_event = Mock(spec=nio.RoomMessageUnknown)
|
||||||
|
fake_room_unknown_event.source = {
|
||||||
|
"content": {
|
||||||
|
"msgtype": "unknown",
|
||||||
|
"methods": ["m.sas.v1"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fake_room_unknown_event.event_id = "some event id"
|
||||||
|
|
||||||
|
await self.callbacks.unknown_message(self.fake_room, fake_room_unknown_event)
|
||||||
|
|
||||||
|
self.fake_matrix_client.room_send.assert_not_called()
|
||||||
|
|
||||||
|
async def test_unknown_message_with_method_not_sas_v1(self) -> None:
|
||||||
|
fake_room_unknown_event = Mock(spec=nio.RoomMessageUnknown)
|
||||||
|
fake_room_unknown_event.source = {
|
||||||
|
"content": {
|
||||||
|
"msgtype": "m.key.verification.request",
|
||||||
|
"methods": [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fake_room_unknown_event.event_id = "some event id"
|
||||||
|
|
||||||
|
await self.callbacks.unknown_message(self.fake_room, fake_room_unknown_event)
|
||||||
|
|
||||||
|
self.fake_matrix_client.room_send.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import unittest
|
import unittest
|
||||||
from typing import Any, Dict, Optional
|
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import nio
|
import nio
|
||||||
|
@ -11,16 +10,6 @@ from matrix_alertbot.chat_functions import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def send_room_raise_send_retry_error(
|
|
||||||
room_id: str,
|
|
||||||
message_type: str,
|
|
||||||
content: Dict[Any, Any],
|
|
||||||
tx_id: Optional[str] = None,
|
|
||||||
ignore_unverified_devices: bool = False,
|
|
||||||
) -> nio.RoomSendResponse:
|
|
||||||
raise nio.SendRetryError
|
|
||||||
|
|
||||||
|
|
||||||
class ChatFunctionsTestCase(unittest.IsolatedAsyncioTestCase):
|
class ChatFunctionsTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
@ -179,7 +168,7 @@ class ChatFunctionsTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
|
|
||||||
async def test_send_text_to_room_raise_send_retry_error(self) -> None:
|
async def test_send_text_to_room_raise_send_retry_error(self) -> None:
|
||||||
fake_matrix_client = Mock(spec=nio.AsyncClient)
|
fake_matrix_client = Mock(spec=nio.AsyncClient)
|
||||||
fake_matrix_client.room_send.side_effect = send_room_raise_send_retry_error
|
fake_matrix_client.room_send.side_effect = nio.exceptions.SendRetryError
|
||||||
|
|
||||||
fake_room_id = "!abcdefgh:example.com"
|
fake_room_id = "!abcdefgh:example.com"
|
||||||
fake_plaintext_body = "some plaintext message"
|
fake_plaintext_body = "some plaintext message"
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
import matrix_alertbot.config
|
||||||
from matrix_alertbot.config import DEFAULT_REACTIONS, Config
|
from matrix_alertbot.config import DEFAULT_REACTIONS, Config
|
||||||
from matrix_alertbot.errors import (
|
from matrix_alertbot.errors import (
|
||||||
InvalidConfigError,
|
InvalidConfigError,
|
||||||
|
@ -38,8 +40,15 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
@patch("os.path.isdir")
|
@patch("os.path.isdir")
|
||||||
@patch("os.path.exists")
|
@patch("os.path.exists")
|
||||||
@patch("os.mkdir")
|
@patch("os.mkdir")
|
||||||
|
@patch.object(matrix_alertbot.config, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.config, "logging", autospec=True)
|
||||||
def test_read_minimal_config(
|
def test_read_minimal_config(
|
||||||
self, fake_mkdir: Mock, fake_path_exists: Mock, fake_path_isdir: Mock
|
self,
|
||||||
|
fake_logging: Mock,
|
||||||
|
fake_logger: Mock,
|
||||||
|
fake_mkdir: Mock,
|
||||||
|
fake_path_exists: Mock,
|
||||||
|
fake_path_isdir: Mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
fake_path_isdir.return_value = False
|
fake_path_isdir.return_value = False
|
||||||
fake_path_exists.return_value = False
|
fake_path_exists.return_value = False
|
||||||
|
@ -51,6 +60,11 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
fake_path_exists.assert_called_once_with("data/store")
|
fake_path_exists.assert_called_once_with("data/store")
|
||||||
fake_mkdir.assert_called_once_with("data/store")
|
fake_mkdir.assert_called_once_with("data/store")
|
||||||
|
|
||||||
|
fake_logger.setLevel.assert_called_once_with("INFO")
|
||||||
|
fake_logger.addHandler.assert_called_once()
|
||||||
|
fake_logging.StreamHandler.return_value.setLevel("INFO")
|
||||||
|
fake_logging.StreamHandler.assert_called_once_with(sys.stdout)
|
||||||
|
|
||||||
self.assertEqual({"@fakes_user:matrix.example.com"}, config.user_ids)
|
self.assertEqual({"@fakes_user:matrix.example.com"}, config.user_ids)
|
||||||
self.assertEqual(1, len(config.accounts))
|
self.assertEqual(1, len(config.accounts))
|
||||||
self.assertEqual("password", config.accounts[0].password)
|
self.assertEqual("password", config.accounts[0].password)
|
||||||
|
@ -82,8 +96,15 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
@patch("os.path.isdir")
|
@patch("os.path.isdir")
|
||||||
@patch("os.path.exists")
|
@patch("os.path.exists")
|
||||||
@patch("os.mkdir")
|
@patch("os.mkdir")
|
||||||
|
@patch.object(matrix_alertbot.config, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.config, "logging", autospec=True)
|
||||||
def test_read_full_config(
|
def test_read_full_config(
|
||||||
self, fake_mkdir: Mock, fake_path_exists: Mock, fake_path_isdir: Mock
|
self,
|
||||||
|
fake_logging: Mock,
|
||||||
|
fake_logger: Mock,
|
||||||
|
fake_mkdir: Mock,
|
||||||
|
fake_path_exists: Mock,
|
||||||
|
fake_path_isdir: Mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
fake_path_isdir.return_value = False
|
fake_path_isdir.return_value = False
|
||||||
fake_path_exists.return_value = False
|
fake_path_exists.return_value = False
|
||||||
|
@ -95,6 +116,11 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
fake_path_exists.assert_called_once_with("data/store")
|
fake_path_exists.assert_called_once_with("data/store")
|
||||||
fake_mkdir.assert_called_once_with("data/store")
|
fake_mkdir.assert_called_once_with("data/store")
|
||||||
|
|
||||||
|
fake_logger.setLevel.assert_called_once_with("DEBUG")
|
||||||
|
fake_logger.addHandler.assert_called_once()
|
||||||
|
fake_logging.FileHandler.return_value.setLevel("DEBUG")
|
||||||
|
fake_logging.FileHandler.assert_called_once_with("fake.log")
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{"@fakes_user:matrix.example.com", "@other_user:matrix.domain.tld"},
|
{"@fakes_user:matrix.example.com", "@other_user:matrix.domain.tld"},
|
||||||
config.user_ids,
|
config.user_ids,
|
||||||
|
@ -333,6 +359,60 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
with self.assertRaises(InvalidConfigError):
|
with self.assertRaises(InvalidConfigError):
|
||||||
config._parse_config_values()
|
config._parse_config_values()
|
||||||
|
|
||||||
|
@patch("os.path.isdir")
|
||||||
|
@patch("os.path.exists")
|
||||||
|
@patch("os.mkdir")
|
||||||
|
@patch.object(matrix_alertbot.config, "logger")
|
||||||
|
def test_parse_config_with_both_logging_disabled(
|
||||||
|
self,
|
||||||
|
fake_logger: Mock,
|
||||||
|
fake_mkdir: Mock,
|
||||||
|
fake_path_exists: Mock,
|
||||||
|
fake_path_isdir: Mock,
|
||||||
|
) -> None:
|
||||||
|
fake_path_isdir.return_value = False
|
||||||
|
fake_path_exists.return_value = False
|
||||||
|
|
||||||
|
config_path = os.path.join(CONFIG_RESOURCES_DIR, "config.full.yml")
|
||||||
|
config = DummyConfig(config_path)
|
||||||
|
config.config_dict["logging"]["file_logging"]["enabled"] = False
|
||||||
|
config.config_dict["logging"]["console_logging"]["enabled"] = False
|
||||||
|
|
||||||
|
config._parse_config_values()
|
||||||
|
|
||||||
|
fake_logger.addHandler.assert_not_called()
|
||||||
|
fake_logger.setLevel.assert_called_once_with("DEBUG")
|
||||||
|
|
||||||
|
@patch("os.path.isdir")
|
||||||
|
@patch("os.path.exists")
|
||||||
|
@patch("os.mkdir")
|
||||||
|
@patch.object(matrix_alertbot.config, "logger", autospec=True)
|
||||||
|
@patch.object(matrix_alertbot.config, "logging", autospec=True)
|
||||||
|
def test_parse_config_with_level_logging_different(
|
||||||
|
self,
|
||||||
|
fake_logging: Mock,
|
||||||
|
fake_logger: Mock,
|
||||||
|
fake_mkdir: Mock,
|
||||||
|
fake_path_exists: Mock,
|
||||||
|
fake_path_isdir: Mock,
|
||||||
|
) -> None:
|
||||||
|
fake_path_isdir.return_value = False
|
||||||
|
fake_path_exists.return_value = False
|
||||||
|
|
||||||
|
config_path = os.path.join(CONFIG_RESOURCES_DIR, "config.full.yml")
|
||||||
|
config = DummyConfig(config_path)
|
||||||
|
config.config_dict["logging"]["file_logging"]["enabled"] = True
|
||||||
|
config.config_dict["logging"]["file_logging"]["level"] = "WARN"
|
||||||
|
config.config_dict["logging"]["console_logging"]["enabled"] = True
|
||||||
|
config.config_dict["logging"]["console_logging"]["level"] = "ERROR"
|
||||||
|
|
||||||
|
config._parse_config_values()
|
||||||
|
|
||||||
|
self.assertEqual(2, fake_logger.addHandler.call_count)
|
||||||
|
fake_logger.setLevel.assert_called_once_with("DEBUG")
|
||||||
|
fake_logging.FileHandler.return_value.setLevel.assert_called_with("WARN")
|
||||||
|
fake_logging.StreamHandler.return_value.setLevel.assert_called_with("ERROR")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
302
tests/test_matrix.py
Normal file
302
tests/test_matrix.py
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import random
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import Mock, call, patch
|
||||||
|
|
||||||
|
import nio
|
||||||
|
from diskcache import Cache
|
||||||
|
|
||||||
|
import matrix_alertbot
|
||||||
|
import matrix_alertbot.matrix
|
||||||
|
from matrix_alertbot.alertmanager import AlertmanagerClient
|
||||||
|
from matrix_alertbot.config import AccountConfig, Config
|
||||||
|
from matrix_alertbot.matrix import MatrixClientPool
|
||||||
|
|
||||||
|
|
||||||
|
def mock_create_matrix_client(
|
||||||
|
matrix_client_pool: MatrixClientPool,
|
||||||
|
account: AccountConfig,
|
||||||
|
alertmanager_client: AlertmanagerClient,
|
||||||
|
cache: Cache,
|
||||||
|
config: Config,
|
||||||
|
) -> nio.AsyncClient:
|
||||||
|
fake_matrix_client = Mock(spec=nio.AsyncClient)
|
||||||
|
fake_matrix_client.logged_in = True
|
||||||
|
return fake_matrix_client
|
||||||
|
|
||||||
|
|
||||||
|
class FakeAsyncClientConfig:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
max_limit_exceeded: int,
|
||||||
|
max_timeouts: int,
|
||||||
|
store_sync_tokens: bool,
|
||||||
|
encryption_enabled: bool,
|
||||||
|
) -> None:
|
||||||
|
if encryption_enabled:
|
||||||
|
raise ImportWarning()
|
||||||
|
|
||||||
|
self.max_limit_exceeded = max_limit_exceeded
|
||||||
|
self.max_timeouts = max_timeouts
|
||||||
|
self.store_sync_tokens = store_sync_tokens
|
||||||
|
self.encryption_enabled = encryption_enabled
|
||||||
|
|
||||||
|
|
||||||
|
class MatrixClientPoolTestCase(unittest.IsolatedAsyncioTestCase):
|
||||||
|
async def asyncSetUp(self) -> None:
|
||||||
|
random.seed(42)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client = Mock(spec=AlertmanagerClient)
|
||||||
|
self.fake_cache = Mock(spec=Cache)
|
||||||
|
|
||||||
|
self.fake_account_config_1 = Mock(spec=AccountConfig)
|
||||||
|
self.fake_account_config_1.id = "@fake_user:matrix.example.com"
|
||||||
|
self.fake_account_config_1.homeserver_url = "https://matrix.example.com"
|
||||||
|
self.fake_account_config_1.device_id = "ABCDEFGH"
|
||||||
|
self.fake_account_config_1.token_file = "account1.token.secret"
|
||||||
|
self.fake_account_config_2 = Mock(spec=AccountConfig)
|
||||||
|
self.fake_account_config_2.id = "@other_user:chat.example.com"
|
||||||
|
self.fake_account_config_2.homeserver_url = "https://chat.example.com"
|
||||||
|
self.fake_account_config_2.device_id = "IJKLMNOP"
|
||||||
|
self.fake_account_config_2.token_file = "account2.token.secret"
|
||||||
|
self.fake_config = Mock(spec=Config)
|
||||||
|
self.fake_config.store_dir = "/dev/null"
|
||||||
|
self.fake_config.command_prefix = "!alert"
|
||||||
|
self.fake_config.accounts = [
|
||||||
|
self.fake_account_config_1,
|
||||||
|
self.fake_account_config_2,
|
||||||
|
]
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool, "_create_matrix_client", autospec=True
|
||||||
|
)
|
||||||
|
async def test_init_matrix_client_pool(self, fake_create_matrix_client) -> None:
|
||||||
|
fake_matrix_client = Mock(spec=nio.AsyncClient)
|
||||||
|
fake_create_matrix_client.return_value = fake_matrix_client
|
||||||
|
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_create_matrix_client.assert_has_calls(
|
||||||
|
[
|
||||||
|
call(
|
||||||
|
matrix_client_pool,
|
||||||
|
self.fake_account_config_1,
|
||||||
|
self.fake_alertmanager_client,
|
||||||
|
self.fake_cache,
|
||||||
|
self.fake_config,
|
||||||
|
),
|
||||||
|
call(
|
||||||
|
matrix_client_pool,
|
||||||
|
self.fake_account_config_2,
|
||||||
|
self.fake_alertmanager_client,
|
||||||
|
self.fake_cache,
|
||||||
|
self.fake_config,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_1, matrix_client_pool.account)
|
||||||
|
self.assertEqual(fake_matrix_client, matrix_client_pool.matrix_client)
|
||||||
|
self.assertEqual(2, len(matrix_client_pool._accounts))
|
||||||
|
self.assertEqual(2, len(matrix_client_pool._matrix_clients))
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool, "_create_matrix_client", autospec=True
|
||||||
|
)
|
||||||
|
async def test_close_matrix_client_pool(self, fake_create_matrix_client) -> None:
|
||||||
|
fake_matrix_client = Mock(spec=nio.AsyncClient)
|
||||||
|
fake_create_matrix_client.return_value = fake_matrix_client
|
||||||
|
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
await matrix_client_pool.close()
|
||||||
|
|
||||||
|
fake_matrix_client.close.assert_has_calls([(call(), call())])
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool,
|
||||||
|
"_create_matrix_client",
|
||||||
|
autospec=True,
|
||||||
|
side_effect=mock_create_matrix_client,
|
||||||
|
)
|
||||||
|
async def test_switch_active_client(self, fake_create_matrix_client) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_matrix_client_1 = matrix_client_pool.matrix_client
|
||||||
|
await matrix_client_pool.switch_active_client()
|
||||||
|
fake_matrix_client_2 = matrix_client_pool.matrix_client
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_2, matrix_client_pool.account)
|
||||||
|
self.assertNotEqual(fake_matrix_client_2, fake_matrix_client_1)
|
||||||
|
|
||||||
|
await matrix_client_pool.switch_active_client()
|
||||||
|
fake_matrix_client_3 = matrix_client_pool.matrix_client
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_1, matrix_client_pool.account)
|
||||||
|
self.assertEqual(fake_matrix_client_3, fake_matrix_client_1)
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool,
|
||||||
|
"_create_matrix_client",
|
||||||
|
autospec=True,
|
||||||
|
side_effect=mock_create_matrix_client,
|
||||||
|
)
|
||||||
|
async def test_switch_active_client_with_whoami_raise_exception(
|
||||||
|
self, fake_create_matrix_client
|
||||||
|
) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
for fake_matrix_client in matrix_client_pool._matrix_clients.values():
|
||||||
|
fake_matrix_client.whoami.side_effect = Exception
|
||||||
|
|
||||||
|
fake_matrix_client_1 = matrix_client_pool.matrix_client
|
||||||
|
await matrix_client_pool.switch_active_client()
|
||||||
|
fake_matrix_client_2 = matrix_client_pool.matrix_client
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_1, matrix_client_pool.account)
|
||||||
|
self.assertEqual(fake_matrix_client_2, fake_matrix_client_1)
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool,
|
||||||
|
"_create_matrix_client",
|
||||||
|
autospec=True,
|
||||||
|
side_effect=mock_create_matrix_client,
|
||||||
|
)
|
||||||
|
async def test_switch_active_client_with_whoami_error(
|
||||||
|
self, fake_create_matrix_client
|
||||||
|
) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
for fake_matrix_client in matrix_client_pool._matrix_clients.values():
|
||||||
|
fake_matrix_client.whoami.return_value = Mock(
|
||||||
|
spec=nio.responses.WhoamiError
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_matrix_client_1 = matrix_client_pool.matrix_client
|
||||||
|
await matrix_client_pool.switch_active_client()
|
||||||
|
fake_matrix_client_2 = matrix_client_pool.matrix_client
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_1, matrix_client_pool.account)
|
||||||
|
self.assertEqual(fake_matrix_client_2, fake_matrix_client_1)
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix.MatrixClientPool,
|
||||||
|
"_create_matrix_client",
|
||||||
|
autospec=True,
|
||||||
|
side_effect=mock_create_matrix_client,
|
||||||
|
)
|
||||||
|
async def test_switch_active_client_with_whoami_error_and_not_logged_in(
|
||||||
|
self, fake_create_matrix_client
|
||||||
|
) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
for fake_matrix_client in matrix_client_pool._matrix_clients.values():
|
||||||
|
fake_matrix_client.whoami.return_value = Mock(
|
||||||
|
spec=nio.responses.WhoamiError
|
||||||
|
)
|
||||||
|
fake_matrix_client.logged_in = False
|
||||||
|
|
||||||
|
fake_matrix_client_1 = matrix_client_pool.matrix_client
|
||||||
|
await matrix_client_pool.switch_active_client()
|
||||||
|
fake_matrix_client_2 = matrix_client_pool.matrix_client
|
||||||
|
|
||||||
|
self.assertEqual(self.fake_account_config_1, matrix_client_pool.account)
|
||||||
|
self.assertEqual(fake_matrix_client_2, fake_matrix_client_1)
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix, "AsyncClientConfig", spec=nio.AsyncClientConfig
|
||||||
|
)
|
||||||
|
async def test_create_matrix_client(self, fake_async_client_config: Mock) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
matrix_client_1 = matrix_client_pool._matrix_clients[self.fake_account_config_1]
|
||||||
|
self.assertEqual(self.fake_account_config_1.id, matrix_client_1.user)
|
||||||
|
self.assertEqual(
|
||||||
|
self.fake_account_config_1.device_id, matrix_client_1.device_id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.fake_account_config_1.homeserver_url, matrix_client_1.homeserver
|
||||||
|
)
|
||||||
|
self.assertEqual(self.fake_config.store_dir, matrix_client_1.store_path)
|
||||||
|
self.assertEqual(6, len(matrix_client_1.event_callbacks))
|
||||||
|
self.assertEqual(4, len(matrix_client_1.to_device_callbacks))
|
||||||
|
|
||||||
|
fake_async_client_config.assert_has_calls(
|
||||||
|
[
|
||||||
|
call(
|
||||||
|
max_limit_exceeded=5,
|
||||||
|
max_timeouts=3,
|
||||||
|
store_sync_tokens=True,
|
||||||
|
encryption_enabled=True,
|
||||||
|
),
|
||||||
|
call(
|
||||||
|
max_limit_exceeded=5,
|
||||||
|
max_timeouts=3,
|
||||||
|
store_sync_tokens=True,
|
||||||
|
encryption_enabled=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.matrix,
|
||||||
|
"AsyncClientConfig",
|
||||||
|
spec=nio.AsyncClientConfig,
|
||||||
|
side_effect=FakeAsyncClientConfig,
|
||||||
|
)
|
||||||
|
async def test_create_matrix_client_with_encryption_disabled(
|
||||||
|
self, fake_async_client_config: Mock
|
||||||
|
) -> None:
|
||||||
|
matrix_client_pool = MatrixClientPool(
|
||||||
|
alertmanager_client=self.fake_alertmanager_client,
|
||||||
|
cache=self.fake_cache,
|
||||||
|
config=self.fake_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
matrix_client_1 = matrix_client_pool._matrix_clients[self.fake_account_config_1]
|
||||||
|
self.assertEqual(self.fake_account_config_1.id, matrix_client_1.user)
|
||||||
|
self.assertEqual(
|
||||||
|
self.fake_account_config_1.device_id, matrix_client_1.device_id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.fake_account_config_1.homeserver_url, matrix_client_1.homeserver
|
||||||
|
)
|
||||||
|
self.assertEqual(self.fake_config.store_dir, matrix_client_1.store_path)
|
||||||
|
self.assertEqual(6, len(matrix_client_1.event_callbacks))
|
||||||
|
self.assertEqual(4, len(matrix_client_1.to_device_callbacks))
|
||||||
|
self.assertEqual(5, matrix_client_1.config.max_limit_exceeded)
|
||||||
|
self.assertEqual(3, matrix_client_1.config.max_timeouts)
|
||||||
|
self.assertTrue(matrix_client_1.config.store_sync_tokens)
|
||||||
|
self.assertFalse(matrix_client_1.config.encryption_enabled)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -4,27 +4,21 @@ from unittest.mock import Mock, call, patch
|
||||||
|
|
||||||
import aiohttp.test_utils
|
import aiohttp.test_utils
|
||||||
import nio
|
import nio
|
||||||
from aiohttp import web
|
from aiohttp import web, web_request
|
||||||
from diskcache import Cache
|
from diskcache import Cache
|
||||||
from nio.exceptions import LocalProtocolError
|
|
||||||
from nio.responses import RoomSendResponse
|
|
||||||
|
|
||||||
import matrix_alertbot.webhook
|
import matrix_alertbot.webhook
|
||||||
|
from matrix_alertbot.alert import Alert, AlertRenderer
|
||||||
from matrix_alertbot.alertmanager import AlertmanagerClient
|
from matrix_alertbot.alertmanager import AlertmanagerClient
|
||||||
from matrix_alertbot.config import Config
|
from matrix_alertbot.config import Config
|
||||||
from matrix_alertbot.errors import (
|
from matrix_alertbot.errors import (
|
||||||
AlertmanagerError,
|
AlertmanagerError,
|
||||||
|
MatrixClientError,
|
||||||
SilenceExtendError,
|
SilenceExtendError,
|
||||||
SilenceNotFoundError,
|
SilenceNotFoundError,
|
||||||
)
|
)
|
||||||
from matrix_alertbot.matrix import MatrixClientPool
|
from matrix_alertbot.matrix import MatrixClientPool
|
||||||
from matrix_alertbot.webhook import Webhook
|
from matrix_alertbot.webhook import Webhook, create_alert
|
||||||
|
|
||||||
|
|
||||||
def send_text_to_room_raise_error(
|
|
||||||
client: nio.AsyncClient, room_id: str, plaintext: str, html: str, notice: bool
|
|
||||||
) -> RoomSendResponse:
|
|
||||||
raise LocalProtocolError
|
|
||||||
|
|
||||||
|
|
||||||
def update_silence_raise_silence_not_found(fingerprint: str) -> str:
|
def update_silence_raise_silence_not_found(fingerprint: str) -> str:
|
||||||
|
@ -45,6 +39,7 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
self.fake_matrix_client_pool = Mock(spec=MatrixClientPool)
|
self.fake_matrix_client_pool = Mock(spec=MatrixClientPool)
|
||||||
self.fake_matrix_client_pool.matrix_client = self.fake_matrix_client
|
self.fake_matrix_client_pool.matrix_client = self.fake_matrix_client
|
||||||
self.fake_alertmanager_client = Mock(spec=AlertmanagerClient)
|
self.fake_alertmanager_client = Mock(spec=AlertmanagerClient)
|
||||||
|
self.fake_alert_renderer = Mock(spec=AlertRenderer)
|
||||||
self.fake_cache = Mock(spec=Cache)
|
self.fake_cache = Mock(spec=Cache)
|
||||||
|
|
||||||
self.fake_room_id = "!abcdefg:example.com"
|
self.fake_room_id = "!abcdefg:example.com"
|
||||||
|
@ -57,9 +52,16 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
self.fake_config.cache_expire_time = 0
|
self.fake_config.cache_expire_time = 0
|
||||||
self.fake_config.template_dir = None
|
self.fake_config.template_dir = None
|
||||||
|
|
||||||
self.fake_alerts = {
|
self.fake_request = Mock(spec=web_request.Request)
|
||||||
"alerts": [
|
self.fake_request.app = {
|
||||||
{
|
"alertmanager_client": self.fake_alertmanager_client,
|
||||||
|
"alert_renderer": self.fake_alert_renderer,
|
||||||
|
"matrix_client_pool": self.fake_matrix_client_pool,
|
||||||
|
"cache": self.fake_cache,
|
||||||
|
"config": self.fake_config,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.fake_alert_1 = {
|
||||||
"fingerprint": "fingerprint1",
|
"fingerprint": "fingerprint1",
|
||||||
"generatorURL": "http://example.com/alert1",
|
"generatorURL": "http://example.com/alert1",
|
||||||
"status": "firing",
|
"status": "firing",
|
||||||
|
@ -69,8 +71,8 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
"job": "job1",
|
"job": "job1",
|
||||||
},
|
},
|
||||||
"annotations": {"description": "some description1"},
|
"annotations": {"description": "some description1"},
|
||||||
},
|
}
|
||||||
{
|
self.fake_alert_2 = {
|
||||||
"fingerprint": "fingerprint2",
|
"fingerprint": "fingerprint2",
|
||||||
"generatorURL": "http://example.com/alert2",
|
"generatorURL": "http://example.com/alert2",
|
||||||
"status": "resolved",
|
"status": "resolved",
|
||||||
|
@ -80,7 +82,11 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
"job": "job2",
|
"job": "job2",
|
||||||
},
|
},
|
||||||
"annotations": {"description": "some description2"},
|
"annotations": {"description": "some description2"},
|
||||||
},
|
}
|
||||||
|
self.fake_alerts = {
|
||||||
|
"alerts": [
|
||||||
|
self.fake_alert_1,
|
||||||
|
self.fake_alert_2,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,13 +320,14 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
self.fake_cache.set.assert_not_called()
|
self.fake_cache.set.assert_not_called()
|
||||||
self.fake_cache.delete.assert_not_called()
|
self.fake_cache.delete.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "logger", autospec=True)
|
||||||
@patch.object(
|
@patch.object(
|
||||||
matrix_alertbot.webhook,
|
matrix_alertbot.webhook,
|
||||||
"send_text_to_room",
|
"send_text_to_room",
|
||||||
side_effect=send_text_to_room_raise_error,
|
side_effect=nio.exceptions.LocalProtocolError("Local protocol error"),
|
||||||
)
|
)
|
||||||
async def test_post_alerts_raise_send_error(
|
async def test_post_alerts_raise_send_error(
|
||||||
self, fake_send_text_to_room: Mock
|
self, fake_send_text_to_room: Mock, fake_logger: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
self.fake_alertmanager_client.update_silence.side_effect = (
|
self.fake_alertmanager_client.update_silence.side_effect = (
|
||||||
update_silence_raise_silence_not_found
|
update_silence_raise_silence_not_found
|
||||||
|
@ -341,6 +348,178 @@ class WebhookApplicationTestCase(aiohttp.test_utils.AioHTTPTestCase):
|
||||||
self.fake_cache.set.assert_not_called()
|
self.fake_cache.set.assert_not_called()
|
||||||
self.fake_cache.delete.assert_called_once_with("fingerprint1")
|
self.fake_cache.delete.assert_called_once_with("fingerprint1")
|
||||||
|
|
||||||
|
fake_logger.error.assert_called_once_with(
|
||||||
|
"Unable to send alert fingerprint1 to Matrix room !abcdefg:example.com: Local protocol error"
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "logger", autospec=True)
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.webhook,
|
||||||
|
"create_alert",
|
||||||
|
side_effect=MatrixClientError("Matrix client error"),
|
||||||
|
)
|
||||||
|
async def test_post_alerts_raise_matrix_client_error(
|
||||||
|
self, fake_create_alert: Mock, fake_logger: Mock
|
||||||
|
) -> None:
|
||||||
|
self.fake_alertmanager_client.update_silence.side_effect = (
|
||||||
|
update_silence_raise_silence_not_found
|
||||||
|
)
|
||||||
|
|
||||||
|
data = self.fake_alerts
|
||||||
|
async with self.client.request(
|
||||||
|
"POST", f"/alerts/{self.fake_room_id}", json=data
|
||||||
|
) as response:
|
||||||
|
self.assertEqual(500, response.status)
|
||||||
|
error_msg = await response.text()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"An error occured when sending alert with fingerprint 'fingerprint1' to Matrix room.",
|
||||||
|
error_msg,
|
||||||
|
)
|
||||||
|
fake_create_alert.assert_called_once()
|
||||||
|
|
||||||
|
fake_logger.error.assert_called_once_with(
|
||||||
|
"Unable to send alert fingerprint1 to Matrix room !abcdefg:example.com: Matrix client error"
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "logger", autospec=True)
|
||||||
|
@patch.object(
|
||||||
|
matrix_alertbot.webhook,
|
||||||
|
"send_text_to_room",
|
||||||
|
side_effect=Exception("Exception"),
|
||||||
|
)
|
||||||
|
async def test_post_alerts_raise_exception(
|
||||||
|
self, fake_send_text_to_room: Mock, fake_logger: Mock
|
||||||
|
) -> None:
|
||||||
|
self.fake_alertmanager_client.update_silence.side_effect = (
|
||||||
|
update_silence_raise_silence_not_found
|
||||||
|
)
|
||||||
|
|
||||||
|
data = self.fake_alerts
|
||||||
|
async with self.client.request(
|
||||||
|
"POST", f"/alerts/{self.fake_room_id}", json=data
|
||||||
|
) as response:
|
||||||
|
self.assertEqual(500, response.status)
|
||||||
|
error_msg = await response.text()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"An exception occured when sending alert with fingerprint 'fingerprint1' to Matrix room.",
|
||||||
|
error_msg,
|
||||||
|
)
|
||||||
|
fake_send_text_to_room.assert_called_once()
|
||||||
|
self.fake_cache.set.assert_not_called()
|
||||||
|
self.fake_cache.delete.assert_called_once_with("fingerprint1")
|
||||||
|
|
||||||
|
fake_logger.error.assert_called_once_with(
|
||||||
|
"Unable to send alert fingerprint1 to Matrix room !abcdefg:example.com: Exception"
|
||||||
|
)
|
||||||
|
|
||||||
|
async def test_create_alert_update_silence(self) -> None:
|
||||||
|
fake_alert = Mock(spec=Alert)
|
||||||
|
fake_alert.firing = True
|
||||||
|
fake_alert.fingerprint = "fingerprint"
|
||||||
|
|
||||||
|
await create_alert(fake_alert, self.fake_room_id, self.fake_request)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.assert_called_once_with(
|
||||||
|
fake_alert.fingerprint
|
||||||
|
)
|
||||||
|
self.fake_alert_renderer.render.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "send_text_to_room", autospec=True)
|
||||||
|
async def test_create_alert_with_silence_not_found_error(
|
||||||
|
self, fake_send_text_to_room: Mock
|
||||||
|
) -> None:
|
||||||
|
fake_alert = Mock(spec=Alert)
|
||||||
|
fake_alert.firing = True
|
||||||
|
fake_alert.fingerprint = "fingerprint"
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.side_effect = SilenceNotFoundError
|
||||||
|
|
||||||
|
await create_alert(fake_alert, self.fake_room_id, self.fake_request)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.assert_called_once_with(
|
||||||
|
fake_alert.fingerprint
|
||||||
|
)
|
||||||
|
self.fake_alert_renderer.render.assert_has_calls(
|
||||||
|
[call(fake_alert, html=False), call(fake_alert, html=True)]
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_send_text_to_room.assert_called_once()
|
||||||
|
|
||||||
|
self.fake_cache.set.assert_called_once_with(
|
||||||
|
fake_send_text_to_room.return_value.event_id,
|
||||||
|
fake_alert.fingerprint,
|
||||||
|
expire=self.fake_config.cache_expire_time,
|
||||||
|
)
|
||||||
|
self.fake_cache.delete.assert_called_once_with(fake_alert.fingerprint)
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "send_text_to_room", autospec=True)
|
||||||
|
async def test_create_alert_with_silence_extend_error(
|
||||||
|
self, fake_send_text_to_room: Mock
|
||||||
|
) -> None:
|
||||||
|
fake_alert = Mock(spec=Alert)
|
||||||
|
fake_alert.firing = True
|
||||||
|
fake_alert.fingerprint = "fingerprint"
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.side_effect = SilenceExtendError
|
||||||
|
|
||||||
|
await create_alert(fake_alert, self.fake_room_id, self.fake_request)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.assert_called_once_with(
|
||||||
|
fake_alert.fingerprint
|
||||||
|
)
|
||||||
|
self.fake_alert_renderer.render.assert_has_calls(
|
||||||
|
[call(fake_alert, html=False), call(fake_alert, html=True)]
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_send_text_to_room.assert_called_once()
|
||||||
|
|
||||||
|
self.fake_cache.set.assert_called_once_with(
|
||||||
|
fake_send_text_to_room.return_value.event_id,
|
||||||
|
fake_alert.fingerprint,
|
||||||
|
expire=self.fake_config.cache_expire_time,
|
||||||
|
)
|
||||||
|
self.fake_cache.delete.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "send_text_to_room", autospec=True)
|
||||||
|
async def test_create_alert_not_firing(self, fake_send_text_to_room: Mock) -> None:
|
||||||
|
fake_alert = Mock(spec=Alert)
|
||||||
|
fake_alert.firing = False
|
||||||
|
fake_alert.fingerprint = "fingerprint"
|
||||||
|
|
||||||
|
await create_alert(fake_alert, self.fake_room_id, self.fake_request)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.assert_not_called()
|
||||||
|
self.fake_alert_renderer.render.assert_has_calls(
|
||||||
|
[call(fake_alert, html=False), call(fake_alert, html=True)]
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_send_text_to_room.assert_called_once()
|
||||||
|
|
||||||
|
self.fake_cache.set.assert_not_called()
|
||||||
|
self.fake_cache.delete.assert_called_once_with(fake_alert.fingerprint)
|
||||||
|
|
||||||
|
@patch.object(matrix_alertbot.webhook, "send_text_to_room", autospec=True)
|
||||||
|
async def test_create_alert_not_firing_raise_matrix_client_error(
|
||||||
|
self, fake_send_text_to_room: Mock
|
||||||
|
) -> None:
|
||||||
|
fake_alert = Mock(spec=Alert)
|
||||||
|
fake_alert.firing = False
|
||||||
|
fake_alert.fingerprint = "fingerprint"
|
||||||
|
|
||||||
|
self.fake_matrix_client_pool.matrix_client = None
|
||||||
|
|
||||||
|
with self.assertRaises(MatrixClientError):
|
||||||
|
await create_alert(fake_alert, self.fake_room_id, self.fake_request)
|
||||||
|
|
||||||
|
self.fake_alertmanager_client.update_silence.assert_not_called()
|
||||||
|
self.fake_alert_renderer.render.assert_has_calls(
|
||||||
|
[call(fake_alert, html=False), call(fake_alert, html=True)]
|
||||||
|
)
|
||||||
|
|
||||||
|
fake_send_text_to_room.assert_not_called()
|
||||||
|
|
||||||
async def test_health(self) -> None:
|
async def test_health(self) -> None:
|
||||||
async with self.client.request("GET", "/health") as response:
|
async with self.client.request("GET", "/health") as response:
|
||||||
self.assertEqual(200, response.status)
|
self.assertEqual(200, response.status)
|
||||||
|
|
Loading…
Reference in a new issue