Ejemplo n.º 1
0
def test_layabout_raises_type_error_with_string_connector():
    layabout = Layabout()

    with pytest.raises(TypeError) as exc:
        layabout.run(connector='', until=lambda e: False)

    assert str(exc.value) == ('Use layabout.Token or layabout.EnvVar '
                              'instead of str')
Ejemplo n.º 2
0
def test_layabout_can_connect_to_slack_with_existing_slack_client():
    """
    Test that layabout can use an existing SlackClient as a connector.
    """
    layabout = Layabout()
    _, slack = mock_slack(connections=(True, ))

    layabout.run(connector=slack, until=lambda e: False)
Ejemplo n.º 3
0
def test_layabout_raises_missing_token_with_empty_token():
    """
    Test that layabout raises a MissingToken if given an empty Slack API token.
    """
    layabout = Layabout()

    with pytest.raises(MissingToken) as exc:
        # until will exit early here just to be safe.
        layabout.run(connector=Token(''), until=lambda e: False)

    assert str(exc.value) == 'The empty string is an invalid Slack API token'
Ejemplo n.º 4
0
def test_layabout_raises_type_error_with_invalid_connector():
    """
    Test that layabout cannot connect to Slack with a pineapple.
    """
    layabout = Layabout()

    class Pineapple:
        pass

    with pytest.raises(TypeError):
        # Turns out you can't connect to Slack with a Pineapple.
        layabout.run(connector=Pineapple)
Ejemplo n.º 5
0
def test_layabout_can_connect_to_slack_with_token(monkeypatch):
    """
    Test that layabout can connect to the Slack API when given a valid Slack
    API token.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ))
    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.run(connector=TOKEN, until=lambda e: False)

    # Verify we instantiated a SlackClient with the given token.
    SlackClient.assert_called_with(token=TOKEN)
Ejemplo n.º 6
0
def test_layabout_raises_missing_token_without_token(monkeypatch):
    """
    Test that layabout raises a MissingToken if there is no Slack API token for
    it to use.
    """
    environ = dict()
    layabout = Layabout()

    monkeypatch.setattr(os, 'environ', environ)

    with pytest.raises(MissingToken) as exc:
        # until will exit early here just to be safe.
        layabout.run(until=lambda e: False)

    assert str(exc.value) == 'Could not acquire token from LAYABOUT_TOKEN'
Ejemplo n.º 7
0
def test_layabout_can_handle_an_event(events, run_once, monkeypatch):
    """
    Test that layabout can handle an event.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    handle_hello = MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('hello')(handle_hello)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    handle_hello.assert_called_once_with(slack, events[0])
Ejemplo n.º 8
0
def test_layabout_can_continue_after_successful_reconnection(monkeypatch):
    """
    Test that layabout can continue to handle events after successfully
    reconnecting to the Slack API.
    """
    layabout = Layabout()
    # Succeed with the first connection and the subsequent reconnection.
    connections = (True, True)
    # Raise an exception on the first read and return empty events next.
    reads = (TimeoutError, [])
    SlackClient, _ = mock_slack(connections=connections, reads=reads)

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.run(connector=TOKEN,
                 retries=1,
                 backoff=lambda r: 0,
                 until=lambda e: False)
Ejemplo n.º 9
0
def test_layabout_can_only_handle_events_that_happen(events, run_once,
                                                     monkeypatch):
    """
    Test that layabout only handles events that actually happen.
    """
    layabout = Layabout()
    SlackClient, _ = mock_slack(connections=(True, ), reads=(events, []))
    aint_happenin = MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('this will never happen')(aint_happenin)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    aint_happenin.assert_not_called()
Ejemplo n.º 10
0
def test_layabout_can_connect_to_slack_with_env_var(monkeypatch):
    """
    Test that layabout can discover and use a Slack API token from an
    environment variable when not given one directly.
    """
    env_var = EnvVar('_TEST_LAYABOUT_TOKEN')
    environ = {env_var: TOKEN}
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ))

    monkeypatch.setattr(os, 'environ', environ)
    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    # Purposefully don't provide a connector so we have to use an env var.
    layabout.run(connector=env_var, until=lambda e: False)

    # Verify we instantiated a SlackClient with the given token and used it to
    # connect to the Slack API.
    SlackClient.assert_called_with(token=TOKEN)
Ejemplo n.º 11
0
def test_layabout_can_handle_all_events_with_a_splat_handler(
        events, run_once, monkeypatch):
    """
    Test that layabout can handle all events with a splat handler.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    splat = MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('*')(splat)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    splat.assert_has_calls([call(slack, e) for e in events])
Ejemplo n.º 12
0
def test_layabout_can_handle_multiple_events(events, run_once, monkeypatch):
    """
    Test that layabout calls all handlers for their respective events.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    handle_hello, handle_goodbye = MagicMock(), MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('hello')(handle_hello)
    layabout.handle('goodbye')(handle_goodbye)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    handle_hello.assert_called_once_with(slack, events[0])
    handle_goodbye.assert_called_once_with(slack, events[1])
Ejemplo n.º 13
0
def test_layabout_can_handle_an_event_with_kwargs(events, run_once,
                                                  monkeypatch):
    """
    Test that layabout can call an event handler that requires kwargs.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    kwargs = dict(caerbannog='🐰')
    handle_hello = MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('hello', kwargs=kwargs)(handle_hello)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    handle_hello.assert_called_once_with(slack, events[0], **kwargs)
Ejemplo n.º 14
0
def test_layabout_can_handle_one_event_multiple_times(events, run_once,
                                                      monkeypatch):
    """
    Test that layabout calls all handlers for a given event.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    handle_hello1, handle_hello2 = MagicMock(), MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('hello')(handle_hello1)
    layabout.handle('hello')(handle_hello2)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    handle_hello1.assert_called_once_with(slack, events[0])
    handle_hello2.assert_called_once_with(slack, events[0])
Ejemplo n.º 15
0
def test_layabout_can_handle_events_with_normal_and_splat_handlers(
        events, run_once, monkeypatch):
    """
    Test that layabout can handle an event with normal handlers as well as
    a splat handler.
    """
    layabout = Layabout()
    SlackClient, slack = mock_slack(connections=(True, ), reads=(events, []))
    handle_hello, splat = MagicMock(), MagicMock()

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    layabout.handle('hello')(handle_hello)
    layabout.handle('*')(splat)
    layabout.run(connector=TOKEN,
                 interval=0,
                 retries=0,
                 backoff=lambda r: 0,
                 until=run_once)

    handle_hello.assert_called_once_with(slack, events[0])
    splat.assert_has_calls([call(slack, e) for e in events])
Ejemplo n.º 16
0
def test_layabout_can_reuse_an_existing_client_to_reconnect(monkeypatch):
    """
    Test that layabout can reuse an existing SlackClient instance to reconnect
    to the Slack API rather than needlessly instantiating a new one on each
    reconnection attempt.
    """
    layabout = Layabout()
    # Fail initial connection, fail reconnection, succeed at last.
    connections = (False, False, True)
    SlackClient, _ = mock_slack(connections=connections)

    monkeypatch.setattr('layabout.SlackClient', SlackClient)

    # Retry connecting twice to verify reconnection logic was evaluated.
    # until will exit early just to be safe.
    layabout.run(connector=TOKEN,
                 retries=2,
                 backoff=lambda r: 0,
                 until=lambda e: False)

    # Make sure the SlackClient was only instantiated once so we know that we
    # reused the existing instance.
    SlackClient.assert_called_once_with(token=TOKEN)
Ejemplo n.º 17
0
from pprint import pformat
from layabout import Layabout

app = Layabout()


@app.handle('*')
def print_all(slack, event):
    """ * is a special event type that allows you to handle all event types """
    print(f"Got event:\n{pformat(event)}\n")


# We don't need to pass anything to run. By default the API token will
# be fetched from the LAYABOUT_TOKEN environment variable.
if __name__ == "__main__":
    print('Printing all events. Press Ctrl-C to quit.\n')
    app.run()