diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index 183a373a9129738ebe52e475acfba68698aee622..0000000000000000000000000000000000000000
--- a/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-"""Initialize Test Package."""
-# FIX for Poetry: https://github.com/python-poetry/poetry/issues/87
diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
new file mode 100644
index 0000000000000000000000000000000000000000..723e32e0374bcf9da477ed0bab5a310e99377dc9
--- /dev/null
+++ b/tests/unit/conftest.py
@@ -0,0 +1,19 @@
+"""Package's fixtures."""
+
+import pytest
+
+from notifications_routing.app import configure_logging
+from notifications_routing.config import load_config
+
+
+@pytest.fixture(scope="module")
+def config():
+    """Set up config."""
+    config = load_config()
+    yield config
+
+
+@pytest.fixture(scope="module")
+def appctx(config):
+    """Set up app context."""
+    configure_logging(config)
diff --git a/tests/unit/test_router.py b/tests/unit/test_router.py
index 52f52f437007bfd275fb24dbe2c3010ad033b184..ee688d3db4294e4a2f9bca0caa93d8748b17149e 100644
--- a/tests/unit/test_router.py
+++ b/tests/unit/test_router.py
@@ -2,12 +2,13 @@
 
 import datetime
 from unittest import mock
-from unittest.mock import MagicMock
+from unittest.mock import ANY, MagicMock
 
 import pytest
 
-from notifications_routing.data_source.postgres.postgres_data_source import User
+from notifications_routing.data_source.postgres.postgres_data_source import Device, Preference, User
 from notifications_routing.exceptions import NotFoundDataSourceError
+from notifications_routing.preferences import TargetPreference
 from notifications_routing.router import Router
 
 
@@ -16,8 +17,12 @@ def router_mock():
     """Private access record."""
     with mock.patch.object(Router, "__init__", return_value=None):
         mock_router = Router()
+        mock_router.publisher = MagicMock()
         mock_router.data_source = MagicMock()
         mock_router.data_source.USERNAME = "username"
+        mock_router.data_source.EMAIL = "email"
+        mock_router.data_source.LAST_LOGIN = "last_login"
+        mock_router.data_source.USER_ID = "user_id"
 
         return mock_router
 
@@ -91,6 +96,77 @@ def group_user_3():
     return {"username": "testuser3", "email": "testuser3@cern.ch"}
 
 
+@pytest.fixture(scope="function")
+def message():
+    """Message dict."""
+    return {
+        "id": "d53a7d79-0c5e-4b72-9d6f-8492b7415340",
+        "channel_id": "c3ccc15b-298f-4dc7-877f-2c8970331caf",
+        "channel_name": "Test channel",
+        "channel_slug": "test-channel",
+        "priority": "NORMAL",
+        "created_timestamp": "2021-02-26T13:59:40.754Z",
+        "message_body": "test",
+        "summary": "test",
+        "link": None,
+        "img_url": None,
+    }
+
+
+@pytest.fixture(scope="function")
+def message_critical():
+    """Message dict."""
+    return {
+        "id": "d53a7d79-0c5e-4b72-9d6f-8492b7415340",
+        "channel_id": "c3ccc15b-298f-4dc7-877f-2c8970331caf",
+        "channel_name": "Test channel",
+        "channel_slug": "test-channel",
+        "priority": "CRITICAL",
+        "created_timestamp": "2021-02-26T13:59:40.754Z",
+        "message_body": "test",
+        "summary": "test",
+        "link": None,
+        "img_url": None,
+    }
+
+
+@pytest.fixture(scope="function")
+def preference(device):
+    """Preference object."""
+    return Preference(
+        id="17fd2706-8baf-433b-82eb-8c7fada847da",
+        type="DAILY",
+        name="Daily preference",
+        userId="3eacfc35-42bd-49e8-9f2c-1e552c447ff3",
+        targetId="c3ccc15b-298f-4dc7-877f-2c8970331caf",
+        notificationPriority="NORMAL",
+        rangeStart=None,
+        rangeEnd=None,
+        scheduledTime=datetime.time(13, 0),
+        devices=[device],
+    )
+
+
+@pytest.fixture(scope="function")
+def device():
+    """Device object."""
+    return Device(
+        id="d4e15d11-a56e-4568-9e9f-497110426a72",
+        name="testuser1@cern.ch",
+        userId="3eacfc35-42bd-49e8-9f2c-1e552c447ff3",
+        info="Default",
+        type="MAIL",
+        subType=None,
+        token=None,
+    )
+
+
+@pytest.fixture(scope="function")
+def target_preference(preference):
+    """Target Preference object."""
+    return TargetPreference(preference.type, preference.devices, preference.userId, preference.scheduledDay)
+
+
 def test_get_channel_users_one_group_without_no_system_users(
     router_mock, system_user_1, system_user_2, group_user_1, group_user_2
 ):
@@ -178,3 +254,92 @@ def test_get_channel_users_no_groups(router_mock, system_user_1, system_user_2):
     router_mock.data_source.get_group_users.assert_not_called()
     router_mock.data_source.get_system_user.assert_not_called()
     assert router_mock.get_channel_users("c3ccc15b-298f-4dc7-877f-2c8970331caf") == [system_user_1, system_user_2]
+
+
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_no_channel_users(mock_get_channel_users, appctx, router_mock, message):
+    """Test process message for channel without users."""
+    mock_get_channel_users.return_value = []
+    assert router_mock.process_message(message) is None
+
+
+@mock.patch("notifications_routing.router.apply_default_preferences")
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_no_system_users(
+    mock_get_channel_users, mock_apply_default_preferences, appctx, router_mock, message, no_system_user_1
+):
+    """Test process message for non system users."""
+    mock_get_channel_users.return_value = [no_system_user_1]
+    router_mock.process_message(message)
+    mock_apply_default_preferences.assert_called_once_with(ANY, message, "nosystemuser1@cern.ch")
+
+
+@mock.patch("notifications_routing.router.apply_user_preferences")
+@mock.patch("notifications_routing.router.apply_default_preferences")
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_system_user_mute_active(
+    mock_get_channel_users,
+    mock_apply_default_preferences,
+    mock_apply_user_preferences,
+    appctx,
+    router_mock,
+    message,
+    system_user_1,
+):
+    """Test porcess message for system user with mute active."""
+    mock_get_channel_users.return_value = [system_user_1]
+    router_mock.data_source.is_user_mute_active.return_value = True
+    router_mock.process_message(message)
+    assert not mock_apply_default_preferences.called
+    assert not mock_apply_user_preferences.called
+
+
+@mock.patch("notifications_routing.router.apply_user_preferences")
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_system_user_with_preferences(
+    mock_get_channel_users,
+    mock_apply_user_preferences,
+    appctx,
+    router_mock,
+    message,
+    system_user_1,
+    preference,
+    target_preference,
+):
+    """Test process message for system user with preferences."""
+    mock_get_channel_users.return_value = [system_user_1]
+    router_mock.data_source.is_user_mute_active.return_value = False
+    router_mock.data_source.get_user_preferences.return_value = {
+        "email": "testuser1@cern.ch",
+        "preferences": [preference],
+    }
+    router_mock.data_source.get_delivery_methods_and_targets.return_value = {target_preference}
+    router_mock.process_message(message)
+    mock_apply_user_preferences.assert_called_once()
+
+
+@mock.patch("notifications_routing.router.apply_all")
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_critical_message(
+    mock_get_channel_users, mock_apply_all, appctx, router_mock, message_critical, system_user_1, device
+):
+    """Test process message for critical priority."""
+    mock_get_channel_users.return_value = [system_user_1]
+    router_mock.data_source.get_user_devices.return_value = [device]
+    router_mock.process_message(message_critical)
+    mock_apply_all.assert_called_once_with(ANY, message_critical, "testuser1@cern.ch", [device])
+
+
+@mock.patch("notifications_routing.router.apply_default_preferences")
+@mock.patch.object(Router, "get_channel_users")
+def test_process_message_not_found_datasource_error(
+    mock_get_channel_users, mock_apply_default_preferences, appctx, router_mock, message, system_user_1
+):
+    """Test process message when resource is not found on db."""
+    mock_get_channel_users.return_value = [system_user_1]
+    router_mock.data_source.is_user_mute_active.return_value = False
+    router_mock.data_source.get_user_preferences.side_effect = NotFoundDataSourceError(
+        User, id="3eacfc35-42bd-49e8-9f2c-1e552c447ff3"
+    )
+    router_mock.process_message(message)
+    mock_apply_default_preferences.assert_called_once_with(ANY, message, "testuser1@cern.ch")