From 0892de8c991d2a1293b804d5bc19e3e45efb9210 Mon Sep 17 00:00:00 2001 From: Lavissa Date: Wed, 17 Jan 2024 07:52:52 +0100 Subject: [PATCH] Fix news feed task timeout (#6250) --- InvenTree/common/tasks.py | 12 ++++-- InvenTree/common/test_tasks.py | 77 +++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/InvenTree/common/tasks.py b/InvenTree/common/tasks.py index fc20b9dbfe..04353ec613 100644 --- a/InvenTree/common/tasks.py +++ b/InvenTree/common/tasks.py @@ -10,6 +10,7 @@ from django.db.utils import IntegrityError, OperationalError from django.utils import timezone import feedparser +import requests from InvenTree.helpers_model import getModelsWithMixin from InvenTree.models import InvenTreeNotesMixin @@ -47,11 +48,16 @@ def update_news_feed(): logger.info("Could not perform 'update_news_feed' - App registry not ready") return + # News feed isn't defined, no need to continue + if not settings.INVENTREE_NEWS_URL or type(settings.INVENTREE_NEWS_URL) != str: + return + # Fetch and parse feed try: - d = feedparser.parse(settings.INVENTREE_NEWS_URL) - except Exception as entry: # pragma: no cover - logger.warning('update_news_feed: Error parsing the newsfeed', entry) + feed = requests.get(settings.INVENTREE_NEWS_URL) + d = feedparser.parse(feed.content) + except Exception: # pragma: no cover + logger.warning('update_news_feed: Error parsing the newsfeed') return # Get a reference list diff --git a/InvenTree/common/test_tasks.py b/InvenTree/common/test_tasks.py index 55821dbbf2..e8e86e294d 100644 --- a/InvenTree/common/test_tasks.py +++ b/InvenTree/common/test_tasks.py @@ -1,8 +1,9 @@ """Tests for tasks in app common.""" +from django.conf import settings from django.test import TestCase -from common.models import NotificationEntry +from common.models import NewsFeedEntry, NotificationEntry from InvenTree.tasks import offload_task from . import tasks as common_tasks @@ -16,3 +17,77 @@ class TaskTest(TestCase): # check empty run self.assertEqual(NotificationEntry.objects.all().count(), 0) offload_task(common_tasks.delete_old_notifications) + + +class NewsFeedTests(TestCase): + """Tests for update_news_feed task. + + Tests cover different networking and addressing possibilities. + """ + + def setUp(self): + """Setup for tests.""" + # Needs to be set to allow SQLite to store entries + settings.USE_TZ = True + + # Store setting to restore on teardown + self.news_url = settings.INVENTREE_NEWS_URL + + NewsFeedEntry.objects.all().delete() + + def tearDown(self): + """Teardown for tests.""" + # Restore proper setting + settings.INVENTREE_NEWS_URL = self.news_url + + NewsFeedEntry.objects.all().delete() + + def test_valid_url(self): + """Tests that news feed is updated when accessing a valid URL.""" + try: + common_tasks.update_news_feed() + except Exception as ex: + self.fail(f'News feed raised exceptions: {ex}') + + self.assertNotEqual(NewsFeedEntry.objects.all().count(), 0) + + def test_connection_error(self): + """Test connecting to an unavailable endpoint. + + This also emulates calling the endpoint behind a blocking proxy. + """ + settings.INVENTREE_NEWS_URL = 'http://10.255.255.1:81' + + with self.assertLogs('inventree', level='WARNING'): + common_tasks.update_news_feed() + + self.assertEqual(NewsFeedEntry.objects.all().count(), 0) + + def test_unset_url(self): + """Test that no call is made to news feed if URL setting is invalid.""" + settings.INVENTREE_NEWS_URL = '' + + self.assertTrue( + offload_task(common_tasks.update_news_feed) + ) # Task considered complete + self.assertEqual( + NewsFeedEntry.objects.all().count(), 0 + ) # No Feed entries created + + settings.INVENTREE_NEWS_URL = 0 + + self.assertTrue( + offload_task(common_tasks.update_news_feed) + ) # Task considered complete + self.assertEqual( + NewsFeedEntry.objects.all().count(), 0 + ) # No Feed entries created + + settings.INVENTREE_NEWS_URL = None + + self.assertTrue( + offload_task(common_tasks.update_news_feed) + ) # Task considered complete + self.assertEqual( + NewsFeedEntry.objects.all().count(), 0 + ) # No Feed entries created