Skip to content

Commit

Permalink
Merge pull request scrapinghub#160
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 3eea123
Author: Danny <[email protected]>
Date:   Sun Sep 10 17:40:02 2017 -0400

    fixed typos/replaced "group" with "private channel"

commit 55455e2
Author: Danny <[email protected]>
Date:   Sun Sep 10 07:05:00 2017 -0400

    Finished updates for private group/channel terminology changes

    Signed-off-by: Danny <[email protected]>
  • Loading branch information
jtatum committed Sep 10, 2017
1 parent 41bff48 commit fddc742
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 46 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ testbot_username = 'testbot'
driver_apitoken = 'xoxp-token'
driver_username = 'your username'
test_channel = 'testchannel'
test_group = 'testgroup'
test_private_channel = 'testprivatechannel'
```

**Important note:** The bot token can be obtained by adding a custom bot integration in Slack. User tokens can be obtained at https://api.slack.com/docs/oauth-test-tokens. Slack tokens are like passwords! Don't commit them. If you're using them in some kind of Github or Travis automation, ensure they are for Slacks that are only for testing.
Expand All @@ -104,6 +104,6 @@ Log in to Travis and enable tests for your slackbot fork. Open Travis settings.
- SLACKBOT_DRIVER_APITOKEN
- SLACKBOT_DRIVER_USERNAME
- SLACKBOT_TEST_CHANNEL
- SLACKBOT_TEST_GROUP
- SLACKBOT_TEST_PRIVATE_CHANNEL

You must also set `Limit concurrent jobs` to `1`. If you don't, you will see false positives/failures, especially in the test cases that verify slackbot's ability to automatically reconnect on disconnection.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ DEFAULT_REPLY = "Sorry but I didn't understand you"
##### Configure the docs answer
The `message` attribute passed to [your custom plugins](#create-plugins) has an special function `message.docs_reply()` that will parse all the plugins available and return the Docs in each of them.

##### Send all tracebacks directly to a channel, group, or user
Set `ERRORS_TO` in `slackbot_settings.py` to the desired recipient. It can be any channel, group, or user. Note that the bot must already be in the channel. If a user is specified, ensure that they have sent at least one DM to the bot first.
##### Send all tracebacks directly to a channel, private channel, or user
Set `ERRORS_TO` in `slackbot_settings.py` to the desired recipient. It can be any channel, private channel, or user. Note that the bot must already be in the channel. If a user is specified, ensure that they have sent at least one DM to the bot first.

```python
ERRORS_TO = 'some_channel'
Expand Down Expand Up @@ -110,8 +110,8 @@ A chat bot is meaningless unless you can extend/customize it to fit your own use

To write a new plugin, simplely create a function decorated by `slackbot.bot.respond_to` or `slackbot.bot.listen_to`:

- A function decorated with `respond_to` is called when a message matching the pattern is sent to the bot (direct message or @botname in a channel/group chat)
- A function decorated with `listen_to` is called when a message matching the pattern is sent on a channel/group chat (not directly sent to the bot)
- A function decorated with `respond_to` is called when a message matching the pattern is sent to the bot (direct message or @botname in a channel/private channel chat)
- A function decorated with `listen_to` is called when a message matching the pattern is sent on a channel/private channel chat (not directly sent to the bot)

```python
from slackbot.bot import respond_to
Expand Down Expand Up @@ -179,19 +179,19 @@ Besides specifying `DEFAULT_REPLY` in `slackbot_settings.py`, you can also decor

```python
@default_reply
def my_default_hanlder(message):
def my_default_handler(messsage):
message.reply('...')
```

Here is another variant of the decorator:

```python
@default_reply(r'hello.*)')
def my_default_hanlder(message):
def my_default_handler(messsage):
message.reply('...')
```

The above default handler would only handle the messages which must (1) match the specified pattern and (2) can't be handled by any other registered hanlder.
The above default handler would only handle the messages which must (1) match the specified pattern and (2) can't be handled by any other registered handler.

## List of third party plugins

Expand Down
31 changes: 16 additions & 15 deletions tests/functional/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ class Driver(object):
"""Functional tests driver. It handles the communication with slack api, so that
the tests code can concentrate on higher level logic.
"""
def __init__(self, driver_apitoken, driver_username, testbot_username, channel, group):
def __init__(self, driver_apitoken, driver_username, testbot_username, channel, private_channel):
self.slacker = slacker.Slacker(driver_apitoken)
self.driver_username = driver_username
self.driver_userid = None
self.test_channel = channel
self.test_group = group
self.test_private_channel = private_channel
self.users = {}
self.testbot_username = testbot_username
self.testbot_userid = None
# public channel
self.cm_chan = None
# direct message channel
self.dm_chan = None
# private group channel
# private private_channel channel
self.gm_chan = None
self._start_ts = time.time()
self._websocket = None
Expand Down Expand Up @@ -77,7 +77,7 @@ def _send_channel_message(self, chan, msg, **kwargs):
def send_channel_message(self, msg, **kwargs):
self._send_channel_message(self.cm_chan, msg, **kwargs)

def send_group_message(self, msg, **kwargs):
def send_private_channel_message(self, msg, **kwargs):
self._send_channel_message(self.gm_chan, msg, **kwargs)

def wait_for_bot_direct_message(self, match):
Expand All @@ -90,13 +90,13 @@ def wait_for_bot_direct_messages(self, matches):
def wait_for_bot_channel_message(self, match, tosender=True):
self._wait_for_bot_message(self.cm_chan, match, tosender=tosender)

def wait_for_bot_group_message(self, match, tosender=True):
def wait_for_bot_private_channel_message(self, match, tosender=True):
self._wait_for_bot_message(self.gm_chan, match, tosender=tosender)

def wait_for_bot_channel_thread_message(self, match, tosender=False):
self._wait_for_bot_message(self.gm_chan, match, tosender=tosender, thread=True)

def wait_for_bot_group_thread_message(self, match, tosender=False):
def wait_for_bot_private_channel_thread_message(self, match, tosender=False):
self._wait_for_bot_message(self.gm_chan, match, tosender=tosender,
thread=True)

Expand Down Expand Up @@ -258,22 +258,23 @@ def _join_test_channel(self):
self.cm_chan = response.body['channel']['id']
self._invite_testbot_to_channel()

groups = self.slacker.groups.list(self.test_group).body['groups']
for group in groups:
if self.test_group == group['name']:
self.gm_chan = group['id']
self._invite_testbot_to_group(group)
# Slacker/Slack API's still references to private_channels as 'groups'
private_channels = self.slacker.groups.list(self.test_private_channel).body['groups']
for private_channel in private_channels:
if self.test_private_channel == private_channel['name']:
self.gm_chan = private_channel['id']
self._invite_testbot_to_private_channel(private_channel)
break
else:
raise RuntimeError('Have you created the private group {} for testing?'.format(
self.test_group))
raise RuntimeError('Have you created the private channel {} for testing?'.format(
self.test_private_channel))

def _invite_testbot_to_channel(self):
if self.testbot_userid not in self.slacker.channels.info(self.cm_chan).body['channel']['members']:
self.slacker.channels.invite(self.cm_chan, self.testbot_userid)

def _invite_testbot_to_group(self, group):
if self.testbot_userid not in group['members']:
def _invite_testbot_to_private_channel(self, private_channel):
if self.testbot_userid not in private_channel['members']:
self.slacker.groups.invite(self.gm_chan, self.testbot_userid)

def _is_bot_message(self, msg):
Expand Down
12 changes: 9 additions & 3 deletions tests/functional/slackbot_settings.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os

os.environ['SLACKBOT_TEST'] = 'true'

ALIASES = ",".join(["!", "$"])

def load_driver_settings():
Expand All @@ -11,12 +10,19 @@ def load_driver_settings():
'driver_apitoken',
'driver_username',
'test_channel',
'test_group',
'test_private_channel',
)

_private_group_patch = 'SLACKBOT_TEST_GROUP'

for key in KEYS:
envkey = 'SLACKBOT_' + key.upper()
globals()[key] = os.environ.get(envkey, None)

# Backwards compatibility patch for TravisCI env variables
if 'PRIVATE_CHANNEL' in envkey and os.environ.get(_private_group_patch):
globals()[key] = os.environ.get(_private_group_patch, None)
else:
globals()[key] = os.environ.get(envkey, None)

load_driver_settings()

Expand Down
38 changes: 19 additions & 19 deletions tests/functional/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from tests.functional.driver import Driver
from tests.functional.slackbot_settings import (
testbot_apitoken, testbot_username,
driver_apitoken, driver_username, test_channel, test_group
driver_apitoken, driver_username, test_channel, test_private_channel
)

TRAVIS = 'TRAVIS' in os.environ
Expand Down Expand Up @@ -43,7 +43,7 @@ def driver():
driver_username,
testbot_username,
test_channel,
test_group)
test_private_channel)
driver.start()
p = _start_bot_process()
driver.wait_for_bot_online()
Expand Down Expand Up @@ -140,16 +140,16 @@ def test_bot_channel_reply_to_name_colon(driver):
driver.wait_for_bot_channel_message('hello channel!', tosender=False)


def test_bot_group_reply_to_name_colon(driver):
driver.send_group_message('hello', tobot=False, toname=True)
driver.wait_for_bot_group_message('hello sender!')
driver.send_group_message('hello', tobot=False, toname=True, space=False)
driver.wait_for_bot_group_message('hello sender!')
driver.send_group_message('hello', tobot=False, toname=True, colon=False)
driver.wait_for_bot_group_message('hello channel!', tosender=False)
driver.send_group_message('hello', tobot=False, toname=True, colon=False,
def test_bot_private_channel_reply_to_name_colon(driver):
driver.send_private_channel_message('hello', tobot=False, toname=True)
driver.wait_for_bot_private_channel_message('hello sender!')
driver.send_private_channel_message('hello', tobot=False, toname=True, space=False)
driver.wait_for_bot_private_channel_message('hello sender!')
driver.send_private_channel_message('hello', tobot=False, toname=True, colon=False)
driver.wait_for_bot_private_channel_message('hello channel!', tosender=False)
driver.send_private_channel_message('hello', tobot=False, toname=True, colon=False,
space=False)
driver.wait_for_bot_group_message('hello channel!', tosender=False)
driver.wait_for_bot_private_channel_message('hello channel!', tosender=False)


def test_bot_listen_to_channel_message(driver):
Expand All @@ -162,11 +162,11 @@ def test_bot_react_to_channel_message(driver):
driver.ensure_reaction_posted('eggplant')


def test_bot_reply_to_group_message(driver):
driver.send_group_message('hello')
driver.wait_for_bot_group_message('hello sender!')
driver.send_group_message('hello', colon=False)
driver.wait_for_bot_group_message('hello sender!')
def test_bot_reply_to_private_channel_message(driver):
driver.send_private_channel_message('hello')
driver.wait_for_bot_private_channel_message('hello sender!')
driver.send_private_channel_message('hello', colon=False)
driver.wait_for_bot_private_channel_message('hello sender!')


def test_bot_ignores_non_related_message_response_tosender(driver):
Expand Down Expand Up @@ -232,6 +232,6 @@ def test_bot_reply_thread_in_channel(driver):
driver.wait_for_bot_channel_thread_message('I started a thread', tosender=False)


def test_bot_reply_thread_in_group(driver):
driver.send_group_message('start a thread', tobot=False, colon=False)
driver.wait_for_bot_group_thread_message('I started a thread', tosender=False)
def test_bot_reply_thread_in_private_channel(driver):
driver.send_private_channel_message('start a thread', tobot=False, colon=False)
driver.wait_for_bot_private_channel_thread_message('I started a thread', tosender=False)
3 changes: 3 additions & 0 deletions tests/unit/test_slackclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ def test_parse_channel_data(slack_client):
}])
assert slack_client.find_channel_by_name('fun') is None
assert slack_client.find_channel_by_name('fun2') == 'C024BE91L'

# Although Slack has changed terminology for 'Groups' (now 'private channels'),
# The Slack API still uses the `is_group` property for private channels (as of 09/10/2017)
assert slack_client.find_channel_by_name('test-group-joined') is None
slack_client.parse_channel_data([{
'created': 1497473029,
Expand Down

0 comments on commit fddc742

Please sign in to comment.