Ejemplo n.º 1
0
async def test_execute_view_async(module: Module) -> None:
    name = 'view'
    mock = AsyncMock(name='view')
    module.view(name, function=mock)

    await module.execute_action(f'view_submission:{name}')
    mock.assert_awaited_once()
Ejemplo n.º 2
0
async def test_execute_action_async(module: Module) -> None:
    name = 'action'
    mock = AsyncMock(name='action')
    module.action(name, function=mock)

    await module.execute_action(f'block_actions:{name}')
    mock.assert_awaited_once()
Ejemplo n.º 3
0
def test_add_view(module: Module) -> None:
    name = 'test'

    @module.view(name)
    async def view() -> None:
        pass

    assert module._views[name] == view  # noqa

    with pytest.raises(AssertionError):
        module.view(name, function=view)
Ejemplo n.º 4
0
def test_add_action(module: Module) -> None:
    name = 'test'

    @module.action(name)
    async def action() -> None:
        pass

    assert module._actions[name] == action  # noqa

    with pytest.raises(AssertionError):
        module.action(name, function=action)
Ejemplo n.º 5
0
def test_add_converter(module: Module) -> None:
    assert module._get_converter(int) == int  # noqa

    @module.converter(int)
    def convert_binary(binary_number: str) -> int:
        return int(binary_number, 2)

    assert module._get_converter(int) == convert_binary  # noqa

    with pytest.raises(AssertionError):
        module.converter(int, converter=convert_binary)
Ejemplo n.º 6
0
async def test_hearbeat(module: Module, monkeypatch) -> None:
    payload = module._build_module_payload()  # noqa
    mock_api = AsyncMock(name='register_module_api_modules_post')

    monkeypatch.setattr(AsyncMetabotApi, 'register_module_api_modules_post',
                        mock_api)

    module._start_heartbeat()  # noqa
    assert isinstance(module._heartbeat, Task)  # noqa
    await sleep(0)
    mock_api.assert_awaited_with(payload)

    module._stop_heartbeat()  # noqa
    assert module._heartbeat is None  # noqa
Ejemplo n.º 7
0
def module() -> Module:
    return Module(
        name='example',
        description='Example module',
        module_url='http://localhost:8000',
        metabot_url='http://localhost:8000',
        heartbeat_delay=0,
    )
Ejemplo n.º 8
0
def test_add_command(module: Module) -> None:
    name = 'test'
    description = 'description'

    @module.command(
        name,
        description=description,
    )
    async def test() -> None:
        pass

    command = module._commands[name]  # noqa
    assert isinstance(command, Command)
    assert command.name == name
    assert command.description == description
    assert command.func == test

    with pytest.raises(AssertionError):
        module.command(name, function=test, description=description)
Ejemplo n.º 9
0
def test_build_module_payload(module: Module) -> None:
    command_name = 'command'
    description = 'description'
    action_name = 'action'
    view_name = 'view'

    @module.command(command_name,
                    description=description,
                    arg_descriptions={'req': description})
    def command(req: str, opt: str = '') -> None:
        pass

    @module.action(action_name)
    def action() -> None:
        pass

    @module.view(view_name)
    def view() -> None:
        pass

    payload = jsonable_encoder(module._build_module_payload())  # noqa
    assert payload == {
        'name':
        module.name,
        'description':
        module.description,
        'url':
        module.module_url,
        'commands': {
            command_name: {
                'name':
                command_name,
                'description':
                description,
                'arguments': [
                    {
                        'name': 'req',
                        'is_optional': False,
                        'description': description
                    },
                    {
                        'name': 'opt',
                        'is_optional': True,
                        'description': None
                    },
                ]
            }
        },
        'actions': [
            f'block_actions:{action_name}',
            f'view_submission:{view_name}',
        ]
    }
Ejemplo n.º 10
0
def test_parse_arguments() -> None:
    async def func(arg1: str, arg2: int = 1) -> None:
        pass

    descriptions = {'arg1': 'HELLOOOOOOOOO'}
    required, optional = Module._parse_arguments(func, descriptions)  # noqa

    assert required.is_optional is False
    assert required.type == str
    assert required.name == 'arg1'
    assert required.description == descriptions['arg1']

    assert optional.is_optional is True
    assert optional.type == int
    assert optional.name == 'arg2'
    assert optional.description is None
Ejemplo n.º 11
0
def test_parse_arguments_fails() -> None:
    with pytest.raises(AssertionError):

        def func_with_args(*args: Any) -> None:
            pass

        Module._parse_arguments(func_with_args)  # noqa

    with pytest.raises(AssertionError):

        def func_with_kwargs(**kwargs: Any) -> None:
            pass

        Module._parse_arguments(func_with_kwargs)  # noqa

    with pytest.raises(AssertionError):

        def func_with_positional_only(a: Any, /, b: Any) -> None:  # noqa E225
            pass

        Module._parse_arguments(func_with_positional_only)  # noqa
Ejemplo n.º 12
0
from help.config import (
    MODULE_URL,
    METABOT_URL,
    COMMANDS_BUTTON_ACTION_ID,
    HEARTBEAT_DELAY
)
from fastapi_metabot.module import Module
from help.bl import get_module_name_from_button, send_help

log = logging.getLogger(__name__)
app = FastAPI()

module = Module(
    name='help',
    description=':sos: Get info about installed MetaBot modules and commands',
    module_url=MODULE_URL,
    metabot_url=METABOT_URL,
    heartbeat_delay=HEARTBEAT_DELAY,
)


@module.command(
    'me',
    description='Displays info about a module and lists available commands.\n'
                'When module name is not provided, displays short info about '
                'all modules.',
    arg_descriptions={
        'module_name': 'Module name',
    }
)
async def get_help(module_name: str = None) -> None:
Ejemplo n.º 13
0
def app(module: Module) -> FastAPI:
    app = FastAPI()
    module.install(app)
    app.include_router(router, prefix='/fake')
    return app
Ejemplo n.º 14
0
from vacations.config import (MODULE_URL, METABOT_URL, REQUEST_VIEW_ID,
                              APPROVE_BUTTON_ACTION_ID, DENY_BUTTON_ACTION_ID,
                              LEAVE_TYPES, HEARTBEAT_DELAY)
from vacations.event_handlers import start_app_handler, stop_app_handler
from vacations.bl import (send_ephemeral, open_request_view,
                          parse_request_view, get_request_id_from_button,
                          is_admin_channel, send_history, create_request,
                          add_days, approve_request, deny_request)

app = FastAPI()
app.add_event_handler('startup', start_app_handler(app))
app.add_event_handler('shutdown', stop_app_handler(app))

module = Module(
    name='vacations',
    description=':palm_tree: Manage vacations, days off & other leaves',
    module_url=MODULE_URL,
    metabot_url=METABOT_URL,
    heartbeat_delay=HEARTBEAT_DELAY)


class UserId(str):
    pass


@module.converter(UserId)
async def convert_user_id(user_id: str) -> UserId:
    user_id_search = search(r'<@(\w+)\|(\w+)>', user_id)

    if user_id_search:
        return UserId(user_id_search.group(1))
    else: