From 170056bf588c8bbdb1a1293fc258a626770aa849 Mon Sep 17 00:00:00 2001 From: TrisNol Date: Sat, 11 Nov 2023 11:43:10 +0100 Subject: [PATCH] test: Cover apps/fetch_news.py with unit tests --- .../apps/fetch_news.py | 14 ++- tests/apps/fetch_news_test.py | 93 +++++++++++++++++++ 2 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 tests/apps/fetch_news_test.py diff --git a/src/aki_prj23_transparenzregister/apps/fetch_news.py b/src/aki_prj23_transparenzregister/apps/fetch_news.py index a6d984b..7f2fd5f 100644 --- a/src/aki_prj23_transparenzregister/apps/fetch_news.py +++ b/src/aki_prj23_transparenzregister/apps/fetch_news.py @@ -27,12 +27,12 @@ from aki_prj23_transparenzregister.utils.mongo.news_mongo_service import ( ) -def fetch_news_cli() -> None: +def fetch_news_cli() -> None: # pragma: no cover """A cli interface to fetch latest news articles on a schedule.""" parser = argparse.ArgumentParser( - prog="Process and transform data", - description="Copy data from one SQL database to another.", - epilog="Example: 'data-transformation secrets.json' or 'data-transformation ENV_VARS_'", + prog="Fetch News on schedule", + description="Fetch latest news articles from various sources on a schedule and transfer them to MongoDB.", + epilog="Example: 'fetch-news-schedule secrets.json' or 'fetchh-news-schedule ENV_VARS_'", ) parser.add_argument( "config", @@ -52,11 +52,14 @@ def fetch_news_cli() -> None: time.sleep(30) -def schedule(config_provider: ConfigProvider) -> None: +def schedule(config_provider: ConfigProvider) -> int: """Scheduled job to fetch news articles and transfer them to MongoDB. Args: config_provider (ConfigProvider): ConfigProvider to get the MongoDB connection string + + Returns: + int: Number of new documents inserted into MongoDB """ logger.info("Starting scheduled job") mongo_news_service = MongoNewsService( @@ -95,3 +98,4 @@ def schedule(config_provider: ConfigProvider) -> None: ) logger.info("Finished scheduled job") logger.info("=========================================") + return count_new_documents diff --git a/tests/apps/fetch_news_test.py b/tests/apps/fetch_news_test.py new file mode 100644 index 0000000..81063f3 --- /dev/null +++ b/tests/apps/fetch_news_test.py @@ -0,0 +1,93 @@ +"""Testing apps/fetch_news.py.""" +from unittest.mock import Mock, patch + +from aki_prj23_transparenzregister.apps import fetch_news +from aki_prj23_transparenzregister.models.news import News + + +def test_import() -> None: + assert fetch_news is not None + + +@patch("aki_prj23_transparenzregister.apps.fetch_news.MongoNewsService") +@patch("aki_prj23_transparenzregister.apps.fetch_news.MongoConnector") +@patch("aki_prj23_transparenzregister.apps.fetch_news.HandelsblattRSS") +@patch("aki_prj23_transparenzregister.apps.fetch_news.TagesschauAPI") +def test_schedule( + mock_tagesschau_api: Mock, + mock_handelsblatt_rss: Mock, + mock_mongo_connector: Mock, + mock_mongo_news_service: Mock, +) -> None: + mock_mongo_connector.return_value = Mock() + mock_mongo_news_service.return_value = Mock( + get_by_id=Mock(return_value=None), insert=Mock(return_value=Mock) + ) + + mock_news_handelsblatt = [ + News( + id="test", + title="The oldest and strongest emotion of mankind is fear, and the oldest and strongest kind of fear is fear of the unknown", + date="2023-11-10T09:10:27+0100", + source_url="https://www.handelsblatt.com/test", + text="", + ), + News( + id="test", + title="That is not dead which can eternal lie, And with strange aeons even death may die.", + date="2023-11-10T09:10:27+0100", + source_url="https://www.handelsblatt.com/test", + text="", + ), + ] + mock_news_tagesschau = [ + News( + id="test", + title="I know always that I am an outsider; a stranger in this century and among those who are still men.", + date="2023-11-10T09:10:27+0100", + source_url="https://www.tagesschau.de/test", + text="", + ), + News( + id="test", + title="Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn.", + date="2023-11-10T09:10:27+0100", + source_url="https://www.tagesschau.de/test", + text="", + ), + ] + mock_tagesschau_api.return_value = Mock( + get_news_for_category=Mock(return_value=mock_news_tagesschau) + ) + mock_handelsblatt_rss.return_value = Mock( + get_news_for_category=Mock(return_value=mock_news_handelsblatt) + ) + assert fetch_news.schedule(Mock()) == len( + mock_news_handelsblatt + mock_news_tagesschau + ) + + +@patch("aki_prj23_transparenzregister.apps.fetch_news.MongoNewsService") +@patch("aki_prj23_transparenzregister.apps.fetch_news.MongoConnector") +@patch("aki_prj23_transparenzregister.apps.fetch_news.HandelsblattRSS") +@patch("aki_prj23_transparenzregister.apps.fetch_news.TagesschauAPI") +def test_schedule_error( + mock_tagesschau_api: Mock, + mock_handelsblatt_rss: Mock, + mock_mongo_connector: Mock, + mock_mongo_news_service: Mock, +) -> None: + mock_mongo_connector.return_value = Mock() + mock_mongo_news_service.return_value = Mock( + get_by_id=Mock(return_value=None), insert=Mock(return_value=Mock) + ) + + mock_news_handelsblatt = None + mock_news_tagesschau = None + mock_tagesschau_api.return_value = Mock( + get_news_for_category=Mock(return_value=mock_news_tagesschau) + ) + mock_handelsblatt_rss.return_value = Mock( + get_news_for_category=Mock(return_value=mock_news_handelsblatt) + ) + assert fetch_news.schedule(Mock()) == 0