TheMathemagicians/penny_dreadful_downloader/downloader/test_downloader.py

176 lines
6.8 KiB
Python

#!/usr/bin/env python3
import unittest
from unittest.mock import Mock, call, mock_open
import requests
from bs4 import BeautifulSoup
import downloader
def get_mock_cards_response(text):
mock_response = Mock()
mock_response.text = text
return mock_response
class DownloaderTests(unittest.TestCase):
def test_download_seasons_html_calls_requests_get_with_correct_url(self):
requests.get = Mock()
requests.get.return_value.text = ''
downloader.download_seasons_html()
requests.get.assert_called_once_with("https://pennydreadfulmagic.com/seasons/")
def test_download_seasons_html_returns_soup_of_document(self):
mock_html = '<html></html>'
expected = BeautifulSoup(mock_html, "html.parser")
requests.get = Mock()
requests.get.return_value.text = mock_html
result = downloader.download_seasons_html()
self.assertEqual(expected, result)
def test_is_season_returns_true_when_tag_is_season(self):
tag = Mock()
tag.name = "section"
tag.attrs = {"class": "stats"}
is_season = downloader.is_season(tag)
self.assertEqual(is_season, True)
def test_is_season_returns_false_when_tag_name_is_not_div(self):
tag = Mock()
tag.name = "p"
tag.attrs = {"class": "stats"}
is_season = downloader.is_season(tag)
self.assertEqual(is_season, False)
def test_is_season_returns_false_when_tag_class_is_not_content_season(self):
tag = Mock()
tag.name = "section"
tag.attrs = {"class": "not-a-season"}
is_season = downloader.is_season(tag)
self.assertEqual(is_season, False)
def test_is_season_returns_false_when_tag_has_no_class(self):
tag = Mock()
tag.name = "section"
tag.attrs = {}
is_season = downloader.is_season(tag)
self.assertEqual(is_season, False)
def test_get_season_number_returns_correct_number(self):
expected_season_number = "29"
mock_soup = BeautifulSoup("<div><h2>Season " + expected_season_number + " (ONE)</h2></div>", "html.parser")
mock_tag = mock_soup.div
season_number = downloader.get_season_number(mock_tag)
self.assertEqual(season_number, expected_season_number)
def test_get_season_number_returns_correct_number_when_single_digit_season(self):
expected_season_number = "7"
mock_soup = BeautifulSoup("<div><h2>Season " + expected_season_number + " (RIX)</h2></div>", "html.parser")
mock_tag = mock_soup.div
season_number = downloader.get_season_number(mock_tag)
self.assertEqual(season_number, expected_season_number)
def test_get_season_cards_url_returns_correct_url_from_list(self):
expected_url = "TEST_SEASON_CARDS_URL"
mock_soup = BeautifulSoup('''<div class="content content-season"><section class="stats"><h2>Season 23 (VOW)</h2><p></p><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="''' + expected_url + '''">14,990 Legal Cards</a></li><li></li><li></li><li></li></ul></section></div>''', "html.parser")
mock_tag = mock_soup.div
season_url = downloader.get_season_cards_url(mock_tag)
self.assertEqual(season_url, expected_url)
def test_get_season_cards_url_returns_http_when_url_is_https(self):
expected_url = "http://pdmtgo.com/VOW_legal_cards.txt"
source_url = "https://pdmtgo.com/VOW_legal_cards.txt"
mock_soup = BeautifulSoup('''<div class="content content-season"><section class="stats"><h2>Season 23 (VOW)</h2><p></p><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="''' + source_url + '''">14,990 Legal Cards</a></li><li></li><li></li><li></li></ul></section></div>''', "html.parser")
mock_tag = mock_soup.div
season_url = downloader.get_season_cards_url(mock_tag)
self.assertEqual(season_url, expected_url)
def test_get_seasons_returns_dictionary_of_season_to_url(self):
expected_season_number = "23"
expected_url = "TEST_SEASON_CARDS_URL"
mock_soup = BeautifulSoup('''<html><body><main><div class="content content-seasons"><section class="stats"><h2>Season ''' + expected_season_number + ''' (VOW)</h2><p></p><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li><a href="''' + expected_url + '''">14,990 Legal Cards</a></li><li></li><li></li><li></li></ul></section></div></main></body></html>''', "html.parser")
seasons_list = downloader.get_seasons(mock_soup)
self.assertEqual(seasons_list, {expected_season_number: expected_url})
def test_download_season_lists_pulls_file_from_web(self):
expected_season_number = "23"
expected_url = "TEST_SEASON_CARDS_URL"
test_cards = "CARDS CARDS MORE CARDS"
requests.get = Mock(return_value=get_mock_cards_response(test_cards))
downloader.download_season_lists({expected_season_number: expected_url})
requests.get.assert_called_once_with(expected_url)
def test_download_season_lists_gets_all_files(self):
test_url_1 = "SEASON_23_URL"
test_url_2 = "SEASON_42_URL"
test_seasons = {
"23": test_url_1,
"42": test_url_2}
test_cards = "CARDS CARDS MORE CARDS"
requests.get = Mock(return_value=get_mock_cards_response(test_cards))
downloader.download_season_lists(test_seasons)
requests.get.assert_has_calls([call(test_url_1), call(test_url_2)])
def test_write_season_lists_writes_response_text_to_disk(self):
test_cards = "CARDS CARDS MORE CARDS"
test_responses = {"23": test_cards}
open_mock = mock_open()
with unittest.mock.patch("builtins.open", open_mock):
downloader.write_season_lists(test_responses)
handle = open_mock()
handle.write.assert_called_with(test_cards)
def test_main_runs_program(self):
mock_soup = BeautifulSoup("<html></html>", "html.parser")
downloader.download_seasons_html = Mock(return_value=mock_soup)
mock_seasons = {"23": "URL"}
downloader.get_seasons = Mock(return_value=mock_seasons)
mock_lists = {"23": "CARDS UPON CARDS"}
downloader.download_season_lists = Mock(return_value=mock_lists)
# downloader.write_season_lists = Mock() # TODO: Find out why this causes the above test to fail
with unittest.mock.patch("builtins.open", mock_open()):
downloader.main()
downloader.download_seasons_html.assert_called_once()
downloader.get_seasons.assert_called_once_with(mock_soup)
downloader.download_season_lists.assert_called_once_with(mock_seasons)
# downloader.write_season_lists.assert_called_once_with(mock_lists)
if __name__ == '__main__':
unittest.main()