Skip to content
This repository was archived by the owner on Jun 19, 2019. It is now read-only.

Test-Initial Tests #15

Merged
merged 8 commits into from
Dec 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified requirements.txt
Binary file not shown.
22 changes: 15 additions & 7 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
new_event_logger = logging.getLogger(f'{__name__}.new_member')
all_event_logger = logging.getLogger(f'{__name__}.all_events')


# constants
MESSAGE = (
"Hi {real_name},\n\n Welcome to Operation Code! I'm a bot designed to help answer questions and get you on your way in our community.\n\n"
Expand Down Expand Up @@ -40,7 +41,9 @@ def event_handler(event_dict):

# can be used for development to trigger the event instead of the team_join
if event_dict['type'] == 'message' and 'user' in event_dict.keys():
pass

# Will need to be removed. Currently for testing
logger.info('Message event')
if event_dict['type'] == 'message' and 'user' in event_dict.keys() and event_dict['text'] == 'test4611':
event_dict['user'] = {'id': event_dict['user']}
new_member(event_dict)
Expand All @@ -57,13 +60,18 @@ def new_member(event_dict):
custom_message = build_message(MESSAGE,
real_name=user_name_from_id(user_id))

new_event_logger.info('Built message: {}'.format(custom_message))
slack_client.api_call('chat.postMessage',
channel=user_id,
text=custom_message,
as_user=True)

new_event_logger.info('New Member Slack response: {}'.format(event_dict))
new_event_logger.info('Built message: {}'.format(event_dict))
response = slack_client.api_call('chat.postMessage',
channel=user_id,
text=custom_message,
as_user=True)


if response['ok'] == 'true':
new_event_logger.info('New Member Slack response: {}'.format(response))
else:
new_event_logger.error('FAILED -- Message to new member returned error: {}'.format(response))


def parse_slack_output(slack_rtm_output):
Expand Down
Empty file added tests/__init__.py
Empty file.
1 change: 0 additions & 1 deletion tests/main.py

This file was deleted.

111 changes: 111 additions & 0 deletions tests/test_basic_functionality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from testfixtures import LogCapture
import unittest
import mock
import logging

from src import app
from .test_data import *


class EventHandlerTestCase(unittest.TestCase):

@mock.patch('src.app.new_member')
def test_event_handler_receives_team_join_calls_new_member(self, mock_new_member):
"""
Asserts event_handler correctly passes the event to the new_member function
when event type is 'team_join'
"""
app.event_handler(NEW_MEMBER)
mock_new_member.assert_called_with(NEW_MEMBER)

def test_event_handler_message_event_logs_event(self):
"""
Asserts event handler correctly logs message events.
Will be removed eventually...
"""
with LogCapture() as capture:
app.event_handler(MESSAGE_EVENT)
capture.check(('src.app', 'INFO', 'Message event'))


@mock.patch('src.app.slack_client')
class UserNameTestCase(unittest.TestCase):

def test_user_name_from_id_has_real_name(self, mock_client):
"""
Asserts the user_name_from_id method returns the user's real name
when it is present.
"""
mock_client.api_call.return_value = USER_INFO_HAS_REAL_NAME
real_name = app.user_name_from_id(USER_INFO_HAS_REAL_NAME['user']['id'])
self.assertEquals(real_name, 'Episod')

def test_user_name_from_id_real_name_blank_returns_name(self, mock_client):
"""
Asserts the user_name_from_id method returns the user's name
when their real name is absent but the username is present
"""
mock_client.api_call.return_value = USER_INFO_HAS_NAME
name = app.user_name_from_id(USER_INFO_HAS_NAME['user']['id'])
self.assertEquals(name, 'Spengler')

def test_user_name_from_id_no_name_return_new_member(self, mock_client):
"""
Asserts the user_name_from_id method defaults to returning New Member
when both real name and name are absent
"""
mock_client.api_call.return_value = USER_INFO_NO_NAME
name = app.user_name_from_id(USER_INFO_NO_NAME['user']['id'])
self.assertEquals(name, 'New Member')


@mock.patch('src.app.user_name_from_id', return_value='bob')
@mock.patch('src.app.build_message', return_value=MESSAGE)
class NewMemberTestCase(unittest.TestCase):

@mock.patch('src.app.slack_client.api_call', return_value={'ok': 'true', 'info': 'stuff goes here'})
def test_event_logged(self, mock_client, mock_builder, mock_username_from_id):
"""
Asserts messages are being logged properly when new_member is called
"""
with LogCapture() as capture:
app.new_member(NEW_MEMBER)
capture.check(
('src.app.new_member', 'INFO', 'Recieved json event: {}'.format(NEW_MEMBER)),
('root', 'INFO', 'team_join message'),
('src.app.new_member', 'INFO', 'Built message: {}'.format(NEW_MEMBER)),
('src.app.new_member', 'INFO',
'New Member Slack response: {}'.format({'ok': 'true', 'info': 'stuff goes here'}))
)

@mock.patch('src.app.slack_client')
def test_slack_client_called_with_correct_params(self, mock_client, mock_builder, mock_unfi):
"""
Asserts new_member calls the client api with correct params.
"""
app.new_member(NEW_MEMBER)
mock_client.api_call.assert_called_with('chat.postMessage',
channel=NEW_MEMBER['user']['id'],
text=MESSAGE, as_user=True)

#
@mock.patch('src.app.slack_client.api_call', return_value={'ok': 'false', 'info': 'stuff goes here'})
def test_slack_client_returns_error(self, mock_builder, mock_unfi, mock_client):
"""
Asserts an ERROR is logged when messaging a new member fails
"""
with LogCapture(level=logging.ERROR) as capture:
app.new_member(USER_INFO_HAS_REAL_NAME)
capture.check(
('src.app.new_member', 'ERROR',
"FAILED -- Message to new member returned error: {'ok': 'false', 'info': 'stuff goes here'}"))


class BuildMessageTestCase(unittest.TestCase):

def test_build_message(self):
"""
Asserts build_message function correctly formats message.
"""
message = app.build_message(MESSAGE, real_name='Bob')
self.assertEquals(message, MESSAGE.format(real_name='Bob'))
83 changes: 83 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
NEW_MEMBER = {'type': 'team_join',
'user': {'id': 'U8CGTR404', 'team_id': 'T85GYJ58B', 'name': 'azarion.vivaan', 'deleted': False,
'color': '84b22f', 'real_name': 'test33', 'tz': 'America/Los_Angeles',
'tz_label': 'Pacific Standard Time', 'tz_offset': -28800,
'profile': {'real_name': 'test33', 'display_name': 'test33', 'avatar_hash': 'g8abd5e5995c',
'title': '', 'real_name_normalized': 'test33', 'display_name_normalized': 'test33',
'email': 'azarion.vivaan@affricca.com',
'image_24': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F0180%2Fimg%2Favatars%2Fava_0021-24.png',
'image_32': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0021-32.png',
'image_48': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F3654%2Fimg%2Favatars%2Fava_0021-48.png',
'image_72': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0021-72.png',
'image_192': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0021-192.png',
'image_512': 'https://secure.gravatar.com/avatar/8abd5e5995cbe5a39001568d70725e0f.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F7fa9%2Fimg%2Favatars%2Fava_0021-512.png',
'fields': None, 'team': 'T85GYJ58B'}, 'is_admin': False, 'is_owner': False,
'is_primary_owner': False, 'is_restricted': False, 'is_ultra_restricted': False, 'is_bot': False,
'updated': 1512956397, 'is_app_user': False, 'presence': 'away'}, 'cache_ts': 1512956397,
'event_ts': '1512956397.000025'}

MESSAGE_EVENT = {'type': 'message', 'channel': 'C8DA69KM4', 'user': 'U8DG4B3EK', 'text': '.', 'ts': '1513003671.000412',
'source_team': 'T8CJ90MQV', 'team': 'T8CJ90MQV'}

USER_INFO_HAS_REAL_NAME = {
"ok": 'true',
"user": {
"id": "W012A3CDE",
"team_id": "T012AB3C4",
"name": "spengler",
"deleted": 'false',
"color": "9f69e7",
"real_name": "episod",
"tz": "America\/Los_Angeles",
"tz_label": "Pacific Daylight Time",
"tz_offset": -25200,
}
}

MESSAGE = (
"Hi {real_name},\n\n Welcome to Operation Code! I'm a bot designed to help answer questions and get you on your way in our community.\n\n"
"Please take a moment to review our <https://op.co.de/code-of-conduct|Code of Conduct.>\n\n"
"Our goal here at Operation Code is to get veterans and their families started on the path to a career in programming. "
"We do that through providing you with scholarships, mentoring, career development opportunities, conference tickets, and more!\n\n"
"You're currently in Slack, a chat application that serves as the hub of Operation Code. "
"If you're currently visiting us via your browser, Slack provides a stand alone program to make staying in touch even more convenient. "
"You can download it <https://slack.com/downloads|here.>\n\n"
"Want to make your first change to a program right now? "
"All active Operation Code Projects are located on our source control repository. "
"Our projects can be viewed on <https://github.com/OperationCode/START_HERE|Github.>")

USER_INFO_HAS_NAME = {
"ok": 'true',
"user": {
"id": "W012A3CDE",
"team_id": "T012AB3C4",
"name": "spengler",
"deleted": 'false',
"color": "9f69e7",
"real_name": "",
}
}

USER_INFO_NO_NAME = {
"ok": 'true',
"user": {
"id": "W012A3CDE",
"team_id": "T012AB3C4",
"name": "",
"deleted": 'false',
"color": "9f69e7",
"real_name": "",
}
}

CHANNELS = {
u'C8DA69KM4': {
u'last_read': u'0000000000.000000', u'created': 1459497074,
u'unread_count': 1, u'is_open': True, u'user': u'USLACKBOT',
u'unread_count_display': 1, u'latest': {
u'text': u'message from slackbot',
u'type': u'message', u'user': u'USLACKBOT',
u'ts': u'1459502580.797060'
}, u'is_im': True, u'id': u'D0X6385P1', u'has_pins': False
},
}