Skip to content

Commit

Permalink
Merge pull request #69 from DankCity/28-add-unit-tests
Browse files Browse the repository at this point in the history
Reach 100% coverage with unit tests
  • Loading branch information
levi-rs committed Dec 4, 2016
2 parents e7e824e + 2988915 commit ac7634d
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
omit = dankbot/_version.py
10 changes: 5 additions & 5 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ machine:

general:
artifacts:
- .tox/tox/junit.xml
- .tox/tox/flake8.txt
- .tox/coverage.xml
- .tox/py3/junit.xml
- .tox/lint/flake8.txt
- coverage.xml

dependencies:
override:
Expand All @@ -20,8 +20,8 @@ test:
post:
- coveralls
- mkdir -p $CIRCLE_TEST_REPORTS/dankbot
- cp .tox/tox/junit.xml $CIRCLE_TEST_REPORTS/dankbot
- cp .tox/tox/flake8.txt $CIRCLE_TEST_REPORTS/dankbot
- cp .tox/py3/junit.xml $CIRCLE_TEST_REPORTS/dankbot
- cp .tox/lint/flake8.txt $CIRCLE_TEST_REPORTS/dankbot
- cp -R htmlcov $CIRCLE_TEST_REPORTS/dankbot
- cp coverage.xml $CIRCLE_TEST_REPORTS/dankbot

Expand Down
6 changes: 1 addition & 5 deletions dankbot/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from __future__ import print_function


import sys
import logging
Expand Down Expand Up @@ -55,7 +55,3 @@ def main():
DankBot(config, logger).find_and_post_memes()
except Exception: # pylint: disable=W0703
logger.exception("Caught exception:")


if __name__ == "__main__":
main()
11 changes: 5 additions & 6 deletions dankbot/dankbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(self, config, logger):
# pylint: disable=too-many-instance-attributes

self.slack_token = config['slack']['token']
self.channel = config['slack']['channel']
self.slack_channel = config['slack']['channel']

self.database = config['mysql']['database']
self.username = config['mysql']['username']
Expand Down Expand Up @@ -95,7 +95,7 @@ def get_memes(self):
self.logger.debug("Collecting memes from subreddit: {0}".format(sub))
try:
subreddit_memes = self._get_memes_from_subreddit(r_client, sub)
except HTTPException:
except HTTPException: # pragma: no cover
log = "API failed to get memes for subreddit: {0}"
self.logger.exception(log.format(sub))
continue
Expand All @@ -116,7 +116,7 @@ def get_memes(self):
def _get_memes_from_subreddit(client, subreddit):
return client.get_subreddit(subreddit).get_hot()

def in_collection(self, meme):
def in_collection(self, meme): # pragma no cover
'''
Checks to see if the supplied meme is already in the collection of known
memes
Expand All @@ -143,7 +143,7 @@ def in_collection(self, meme):

return True if resp else False

def add_to_collection(self, meme):
def add_to_collection(self, meme): # pragma no cover
'''
Adds a meme to the collection
'''
Expand Down Expand Up @@ -176,7 +176,6 @@ def post_to_slack(self, memes):

slack = Slacker(self.slack_token)
for meme in memes:

try:
message = meme.format_for_slack()
except UndigestedError:
Expand All @@ -185,7 +184,7 @@ def post_to_slack(self, memes):

message = "from {0}: {1}".format(meme.source, meme.link)

resp = slack.chat.post_message(self.channel, message, as_user=True)
resp = slack.chat.post_message(self.slack_channel, message, as_user=True)

if resp.successful:
self.add_to_collection(meme)
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[pytest]
[tool:pytest]
testpaths = tests

[versioneer]
Expand All @@ -13,4 +13,4 @@ count = True
statistics = True
max-complexity = 10
max-line-length = 100
exclude = .git,__pycache__,old,build,dist,versioneer.py,dankbot/_version.py
exclude = .git,versioneer.py,dankbot/_version.py
30 changes: 30 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from configparser import ConfigParser
from unittest.mock import patch

from dankbot import cli


@patch('dankbot.cli.logging.getLogger')
@patch('dankbot.cli.RotatingFileHandler')
@patch('dankbot.cli.DankBot')
def test_main(dankbot, _, gl_mock):
gl_mock.return_value = gl_mock
dankbot.return_value = dankbot

cli.main()

assert dankbot.called
assert isinstance(dankbot.call_args[0][0], ConfigParser)
assert dankbot.call_args[0][1], gl_mock
assert dankbot.find_and_post_memes.called


@patch('dankbot.cli.configure_logger')
@patch('dankbot.cli.DankBot')
def test_main_exception(dankbot, logger_mock):
logger_mock.return_value = logger_mock
dankbot.return_value = ValueError("Mock exception")

cli.main()

assert logger_mock.exception.called
213 changes: 213 additions & 0 deletions tests/test_dankbot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import logging
from unittest import mock
from unittest.mock import patch, call
from configparser import ConfigParser

import pytest

from dankbot.dankbot import DankBot
from dankbot.memes import ImgurMeme

MOCK_TOKEN = "mock_token"
MOCK_CHANNEL = "mock_slack_channel"

MOCK_DB = "mock_db"
MOCK_UN = "mock_username"
MOCK_PW = "mock_password"

INCLUDE_NSFW = False
MAX_MEMES = 5

SUB_1 = "dankmemes"
SUB_2 = "fishpost"
SUB_3 = "memes"
SUBREDDITS = ", ".join([SUB_1, SUB_2, SUB_3])

IMGUR_CLIENT_ID = "mock imgur client id"
IMGUR_CLIENT_SECRET = "mock imgur secret"

DANK_MEME_URL = "http://dank.meme.url"
IMGUR_MEME_URL = "http://imgur.com/mockhash"


class MockMeme(object):
def __init__(self, over_18, url):
self.over_18 = False
self.url = url


@pytest.fixture(scope="function")
def slack():
with patch('dankbot.dankbot.Slacker') as slack:
slack.return_value = slack
slack.chat = slack
slack.post_message.return_value = slack
slack.successful = True

yield slack


@pytest.fixture(scope="function")
def praw(dank_meme):
with patch('dankbot.dankbot.praw') as praw:
praw.Reddit.return_value = praw
praw.get_subreddit.return_value = praw
praw.get_hot.return_value = [dank_meme, ]

yield praw


@pytest.fixture(scope="function")
def dank_meme():
return MockMeme(False, DANK_MEME_URL)


@pytest.fixture(scope="function")
def imgur_meme():
return MockMeme(False, IMGUR_MEME_URL)


@pytest.fixture(scope="function")
def config():
''' Returns a mock configuration object
'''
config_dict = {
'slack': {
'channel': MOCK_CHANNEL,
'token': MOCK_TOKEN,
},
'mysql': {
'database': MOCK_DB,
'username': MOCK_UN,
'password': MOCK_PW,
},
'misc': {
'include_nsfw': INCLUDE_NSFW,
'max_memes': MAX_MEMES
},
'reddit': {
'subreddits': SUBREDDITS
},
'imgur': {
'client_id': IMGUR_CLIENT_ID,
'client_secret': IMGUR_CLIENT_SECRET
}
}

config_ = ConfigParser()
config_.read_dict(config_dict)

return config_


@pytest.fixture(scope="function")
def logger():
''' Returns a mock logger
'''
return mock.create_autospec(logging.Logger)


def test___init__(config, logger):
dankbot = DankBot(config, logger)

assert dankbot.slack_token == MOCK_TOKEN
assert dankbot.slack_channel == MOCK_CHANNEL
assert dankbot.database == MOCK_DB
assert dankbot.username == MOCK_UN
assert dankbot.password == MOCK_PW
assert dankbot.include_nsfw == INCLUDE_NSFW
assert dankbot.max_memes == MAX_MEMES
assert SUB_1 in dankbot.subreddits
assert SUB_2 in dankbot.subreddits
assert SUB_3 in dankbot.subreddits
assert dankbot.logger == logger

assert ImgurMeme.client_id == IMGUR_CLIENT_ID
assert ImgurMeme.client_secret == IMGUR_CLIENT_SECRET


@patch.object(DankBot, 'add_to_collection')
@patch.object(DankBot, 'in_collection')
def test_find_and_post(ic, atc, praw, slack, config, logger):
ic.return_value = False

dankbot = DankBot(config, logger)
dankbot.subreddits = dankbot.subreddits[:1]

resp = dankbot.find_and_post_memes()

assert slack.post_message.called
assert resp is True
assert atc.called

message = "from {0}: {1}".format(SUB_1, DANK_MEME_URL)
assert slack.post_message.call_args == call(MOCK_CHANNEL, message, as_user=True)


@patch.object(DankBot, 'in_collection')
def test_find_and_post_in_collection(ic, praw, config, logger):
ic.return_value = True

dankbot = DankBot(config, logger)
dankbot.subreddits = dankbot.subreddits[:1]

resp = dankbot.find_and_post_memes()

assert resp is False


@patch.object(DankBot, 'in_collection')
def test_no_nsfw_and_18plus(ic, praw, config, logger):
ic.return_value = False
praw.get_hot.return_value[0].over_18 = True

dankbot = DankBot(config, logger)
dankbot.subreddits = dankbot.subreddits[:1]

resp = dankbot.find_and_post_memes()

assert resp is False


@patch.object(DankBot, 'add_to_collection')
@patch.object(DankBot, 'in_collection')
def test_yes_nsfw_and_18plus(ic, atc, slack, praw, config, logger):
ic.return_value = False
praw.get_hot.return_value[0].over_18 = True

dankbot = DankBot(config, logger)
dankbot.include_nsfw = True
dankbot.subreddits = dankbot.subreddits[:1]

resp = dankbot.find_and_post_memes()

assert slack.post_message.called
assert resp is True
assert atc.called

message = "from {0}: {1}".format(SUB_1, DANK_MEME_URL)
assert slack.post_message.call_args == call(MOCK_CHANNEL, message, as_user=True)


@patch('dankbot.dankbot.praw')
@patch('dankbot.memes.ImgurClient')
@patch.object(DankBot, 'add_to_collection')
@patch.object(DankBot, 'in_collection')
def test_post_imgur_meme(ic, atc, imgur, praw, slack, config, logger, imgur_meme):
ic.return_value = False
imgur.return_value = Exception("Preventing connection")
praw.Reddit.return_value = praw
praw.get_subreddit.return_value = praw
praw.get_hot.return_value = [imgur_meme, ]

dankbot = DankBot(config, logger)
dankbot.subreddits = dankbot.subreddits[:1]

resp = dankbot.find_and_post_memes()

assert slack.post_message.called
assert resp is True
assert atc.called

message = "from {0}: {1}".format(SUB_1, IMGUR_MEME_URL)
assert slack.post_message.call_args == call(MOCK_CHANNEL, message, as_user=True)
16 changes: 6 additions & 10 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
[tox]
skipdist = True
envlist = test
envlist = py3,lint

[testenv]
basepython = python3.5
envdir = {toxworkdir}/tox
commands =
py.test -s --cov dankbot --cov-report term-missing --cov-report html --cov-report xml --junitxml={envdir}/junit.xml tests []
deps =
pytest>=2.6.4
pytest-cov>=1.8.1
pytest-sugar
flake8
isort
tox-pyenv


[testenv:test]
[testenv:lint]
deps =
flake8==2.4.0
commands =
py.test --cov dankbot --cov-report term-missing --cov-report html --cov-report xml --junitxml={envdir}/junit.xml []
flake8 --output-file={envdir}/flake8.txt setup.py dankbot tests

[testenv:env]
Expand Down

0 comments on commit ac7634d

Please sign in to comment.