Skip to content

Commit

Permalink
Added basic talkback functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jessamynsmith committed Feb 3, 2015
1 parent 64ffcbd commit ad6bccd
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[run]
source = plugins
branch = 1
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# willtalkback
willtalkback
============

will plugin for talkbackbot


Development
-----------

Fork the project on github and git clone your fork, e.g.:

git clone https://github.com/<username>/willtalkback.git

Create a virtualenv and install dependencies:

mkvirtualenv willtalkback
pip install -r requirements/development.txt

Run tests and view coverage:

coverage run -m nose
coverage report

Check code style:

flake8
1 change: 1 addition & 0 deletions plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MODULE_DESCRIPTION = "Respond to \"That's what she said\" with a quotation"
38 changes: 38 additions & 0 deletions plugins/talk_back.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging
import requests
from will.plugin import WillPlugin
from will.decorators import respond_to


class TalkBackPlugin(WillPlugin):

QUOTES_URL = ("https://underquoted.herokuapp.com/api/v1/quotations/?"
"format=json&random=true&limit=1")

def get_quote(self):
quote = None
response = requests.get(self.QUOTES_URL)
if response.status_code == 200:
try:
quote_obj = response.json()['objects'][0]
quote = u'%s ~ %s' % (quote_obj['text'],
quote_obj['author']['name'])
except ValueError:
logging.error(
"Response from '%s' could not be decoded as JSON:\n%s"
% (self.QUOTES_URL, response))
except KeyError as e:
logging.error(
"Response from '%s' did not contain field: %s\n%s"
% (self.QUOTES_URL, e, response))

else:
logging.error("Got an error from '%s': %s\n%s"
% (self.QUOTES_URL, response.status_code, response))
return quote

@respond_to("that's what she said")
def talk_back(self, message):
quote = self.get_quote()
if quote:
self.reply(message, quote)
1 change: 1 addition & 0 deletions requirements/common.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
will
11 changes: 11 additions & 0 deletions requirements/development.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-r common.txt
PyYAML==3.11
coverage==3.7.1
coveralls==0.5
docopt==0.6.2
flake8==2.3.0
mccabe==0.3
mock==1.0.1
nose==1.3.4
pep8==1.5.7
pyflakes==0.8.1
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[flake8]
Empty file added tests/__init__.py
Empty file.
74 changes: 74 additions & 0 deletions tests/test_talk_back.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from mock import MagicMock, patch
import unittest

from plugins.talk_back import TalkBackPlugin


class TestTalkBackPlugin(unittest.TestCase):

def setUp(self):
self.plugin = TalkBackPlugin()

@patch('requests.get')
def test_get_quote_failure(self, mock_get):
mock_get.return_value = MagicMock(status_code=500)

quote = self.plugin.get_quote()

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
self.assertEqual(None, quote)

@patch('requests.get')
def test_get_quote_response_not_json(self, mock_get):
mock_json = MagicMock(side_effect=ValueError())
mock_get.return_value = MagicMock(status_code=200, json=mock_json)

quote = self.plugin.get_quote()

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
self.assertEqual(None, quote)

@patch('requests.get')
def test_get_quote_invalid_response_format(self, mock_get):
data = {'text': 'Hi!', 'author': {'name': 'An'}}
mock_json = MagicMock(return_value=data)
mock_get.return_value = MagicMock(status_code=200, json=mock_json)

quote = self.plugin.get_quote()

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
self.assertEqual(None, quote)

@patch('requests.get')
def test_get_quote_success(self, mock_get):
data = {'objects': [{'text': 'Hi!', 'author': {'name': 'An'}}]}
mock_json = MagicMock(return_value=data)
mock_get.return_value = MagicMock(status_code=200, json=mock_json)

quote = self.plugin.get_quote()

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
self.assertEqual('Hi! ~ An', quote)

@patch('will.plugin.WillPlugin.reply')
@patch('requests.get')
def test_talk_back_no_quote(self, mock_get, mock_reply):
mock_json = MagicMock(return_value={})
mock_get.return_value = MagicMock(status_code=200, json=mock_json)

self.plugin.talk_back("That's what she said")

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
self.assertFalse(mock_reply.called)

@patch('will.plugin.WillPlugin.reply')
@patch('requests.get')
def test_talk_back_success(self, mock_get, mock_reply):
data = {'objects': [{'text': 'Hi!', 'author': {'name': 'An'}}]}
mock_json = MagicMock(return_value=data)
mock_get.return_value = MagicMock(status_code=200, json=mock_json)

self.plugin.talk_back("That's what she said")

mock_get.assert_called_once_with(TalkBackPlugin.QUOTES_URL)
mock_reply.assert_called_once_with("That's what she said", 'Hi! ~ An')

0 comments on commit ad6bccd

Please sign in to comment.