diff --git a/machine/asyncio/core.py b/machine/asyncio/core.py index eb2dbbb8..a72ccad7 100644 --- a/machine/asyncio/core.py +++ b/machine/asyncio/core.py @@ -3,6 +3,7 @@ import asyncio import inspect import logging +import os import re import sys from typing import Callable, cast, Awaitable @@ -43,6 +44,37 @@ def __init__(self, settings: CaseInsensitiveDict | None = None): self._registered_actions = RegisteredActions() self._client = None + async def _setup(self) -> None: + announce("Initializing Slack Machine:") + + with indent(4): + found_local_settings = self._load_settings() + assert self._settings is not None + self._setup_logging() + if not found_local_settings: + warn("No local_settings found! Are you sure this is what you want?") + else: + logger.debug("Found local settings %s", self._settings) + + # Check if Slack token are present + if "SLACK_APP_TOKEN" not in self._settings: + error("No SLACK_APP_TOKEN found in settings! I need that to work...") + sys.exit(1) + if "SLACK_BOT_TOKEN" not in self._settings: + error("No SLACK_BOT_TOKEN found in settings! I need that to work...") + sys.exit(1) + + # Setup storage + self._setup_storage() + + # Setup Slack clients + await self._setup_slack_clients() + + # Load plugins + await self._load_plugins() + logger.debug("Registered plugin actions: %s", self._registered_actions) + logger.debug("Plugin help: %s", self._help) + def _setup_logging(self) -> None: assert self._settings is not None fmt = "[%(asctime)s][%(levelname)s] %(name)s %(filename)s:%(funcName)s:%(lineno)d | %(message)s" @@ -61,7 +93,8 @@ def _load_settings(self) -> bool: if self._settings is not None: found_local_settings = True else: - self._settings, found_local_settings = import_settings() + settings_module = os.environ.get("SM_SETTINGS_MODULE", "local_settings") + self._settings, found_local_settings = import_settings(settings_module=settings_module) puts("Settings loaded!") return found_local_settings @@ -85,37 +118,6 @@ async def _setup_slack_clients(self) -> None: self._client = SlackClient(self._socket_mode_client) await self._client.setup() - async def _setup(self) -> None: - announce("Initializing Slack Machine:") - - with indent(4): - found_local_settings = self._load_settings() - assert self._settings is not None - self._setup_logging() - if not found_local_settings: - warn("No local_settings found! Are you sure this is what you want?") - else: - logger.debug("Found local settings %s", self._settings) - - # Check if Slack token are present - if "SLACK_APP_TOKEN" not in self._settings: - error("No SLACK_APP_TOKEN found in settings! I need that to work...") - sys.exit(1) - if "SLACK_BOT_TOKEN" not in self._settings: - error("No SLACK_BOT_TOKEN found in settings! I need that to work...") - sys.exit(1) - - # Setup storage - self._setup_storage() - - # Setup Slack clients - await self._setup_slack_clients() - - # Load plugins - await self._load_plugins() - logger.debug("Registered plugin actions: %s", self._registered_actions) - logger.debug("Plugin help: %s", self._help) - # TODO: factor out plugin registration in separate class / set of functions async def _load_plugins(self) -> None: assert self._settings is not None diff --git a/tests/asyncio/local_test_settings.py b/tests/asyncio/local_test_settings.py new file mode 100644 index 00000000..c15810f1 --- /dev/null +++ b/tests/asyncio/local_test_settings.py @@ -0,0 +1,4 @@ +PLUGINS = ["tests.asyncio.fake_plugins"] +SLACK_BOT_TOKEN = "xoxb-abc123" +SLACK_APP_TOKEN = "xapp-abc123" +STORAGE_BACKEND = "machine.asyncio.storage.backends.memory.MemoryStorage" diff --git a/tests/asyncio/test_setup.py b/tests/asyncio/test_setup.py new file mode 100644 index 00000000..ec85b9c0 --- /dev/null +++ b/tests/asyncio/test_setup.py @@ -0,0 +1,40 @@ +import pytest + +from machine.asyncio import Machine +from machine.asyncio.storage.backends.memory import MemoryStorage + + +@pytest.fixture +def socket_mode_client(mocker): + socket_mode_client = mocker.patch("machine.asyncio.core.SocketModeClient", autospec=True) + socket_mode_client.return_value.socket_mode_request_listeners = [] + return socket_mode_client + + +@pytest.fixture +def slack_client(mocker): + socket_mode_client = mocker.patch("machine.asyncio.core.SlackClient", autospec=True) + socket_mode_client.return_value.socket_mode_request_listeners = [] + return slack_client + + +@pytest.fixture +def os_environ(mocker): + os_environ = mocker.patch( + "machine.asyncio.core.os.environ", new={"SM_SETTINGS_MODULE": "tests.asyncio.local_test_settings"} + ) + return os_environ + + +@pytest.mark.asyncio +async def test_setup(os_environ, socket_mode_client, slack_client): + m = Machine() + assert m._settings is None + await m._setup() + assert m._settings is not None + assert m._settings["PLUGINS"] == ["tests.asyncio.fake_plugins"] + assert m._settings["SLACK_BOT_TOKEN"] == "xoxb-abc123" + assert m._settings["SLACK_APP_TOKEN"] == "xapp-abc123" + assert m._settings["STORAGE_BACKEND"] == "machine.asyncio.storage.backends.memory.MemoryStorage" + assert isinstance(m._storage_backend, MemoryStorage) + assert "manual" in m._storage_backend._storage