diff --git a/src/newsreader/news/collection/forms.py b/src/newsreader/news/collection/forms.py index a8aac52..604500d 100644 --- a/src/newsreader/news/collection/forms.py +++ b/src/newsreader/news/collection/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.core.exceptions import ValidationError from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ @@ -6,15 +7,17 @@ import pytz from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.models import CollectionRule +from newsreader.news.collection.reddit import REDDIT_API_URL from newsreader.news.core.models import Category def get_reddit_help_text(): return mark_safe( - "Only subreddits are supported. For example: " - "https://www.reddit.com/r/aww." - " Note that subreddit urls should NOT include 'www' because Reddit is picky." + "Only subreddits are supported" + " see the 'listings' section in the reddit API docs." + " For example: https://oauth.reddit.com/r/aww" ) @@ -65,15 +68,19 @@ class SubRedditRuleForm(CollectionRuleForm): timezone = None + def clean_url(self): + url = self.cleaned_data["url"] + + if not url.startswith(REDDIT_API_URL): + raise ValidationError(_("This does not look like an Reddit API URL")) + + return url + def save(self, commit=True): instance = super().save(commit=False) instance.type = RuleTypeChoices.subreddit instance.timezone = str(pytz.utc) - instance.user = self.user - - if not instance.url.endswith(".json"): - instance.url = f"{instance.url}.json" if commit: instance.save() diff --git a/src/newsreader/news/collection/tests/views/test_subreddit_views.py b/src/newsreader/news/collection/tests/views/test_subreddit_views.py index a8de55e..0dff663 100644 --- a/src/newsreader/news/collection/tests/views/test_subreddit_views.py +++ b/src/newsreader/news/collection/tests/views/test_subreddit_views.py @@ -1,11 +1,12 @@ from django.test import TestCase from django.urls import reverse +from django.utils.translation import gettext as _ import pytz from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.models import CollectionRule -from newsreader.news.collection.reddit import REDDIT_URL +from newsreader.news.collection.reddit import REDDIT_API_URL, REDDIT_URL from newsreader.news.collection.tests.factories import SubredditFactory from newsreader.news.collection.tests.views.base import CollectionRuleViewTestCase from newsreader.news.core.tests.factories import CategoryFactory @@ -17,7 +18,7 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase): self.form_data = { "name": "new rule", - "url": "https://www.reddit.com/r/aww", + "url": f"{REDDIT_API_URL}/r/aww", "category": str(self.category.pk), } @@ -31,12 +32,19 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase): rule = CollectionRule.objects.get(name="new rule") self.assertEquals(rule.type, RuleTypeChoices.subreddit) - self.assertEquals(rule.url, "https://www.reddit.com/r/aww.json") + self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww") self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.favicon, None) self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.user.pk, self.user.pk) + def test_regular_reddit_url(self): + self.form_data.update(url=f"{REDDIT_URL}/r/aww") + + response = self.client.post(self.url, self.form_data) + + self.assertContains(response, _("This does not look like an Reddit API URL")) + class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): def setUp(self): @@ -44,7 +52,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): self.rule = SubredditFactory( name="Python", - url=f"{REDDIT_URL}/r/python.json", + url=f"{REDDIT_API_URL}/r/python.json", user=self.user, category=self.category, type=RuleTypeChoices.subreddit, @@ -97,7 +105,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): self.assertEquals(response.status_code, 404) def test_url_change(self): - self.form_data.update(name="aww", url=f"{REDDIT_URL}/r/aww") + self.form_data.update(name="aww", url=f"{REDDIT_API_URL}/r/aww") response = self.client.post(self.url, self.form_data) @@ -106,8 +114,15 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): rule = CollectionRule.objects.get(name="aww") self.assertEquals(rule.type, RuleTypeChoices.subreddit) - self.assertEquals(rule.url, f"{REDDIT_URL}/r/aww.json") + self.assertEquals(rule.url, f"{REDDIT_API_URL}/r/aww") self.assertEquals(rule.timezone, str(pytz.utc)) self.assertEquals(rule.favicon, None) self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.user.pk, self.user.pk) + + def test_regular_reddit_url(self): + self.form_data.update(url=f"{REDDIT_URL}/r/aww") + + response = self.client.post(self.url, self.form_data) + + self.assertContains(response, _("This does not look like an Reddit API URL")) diff --git a/src/newsreader/news/core/tests/factories.py b/src/newsreader/news/core/tests/factories.py index 182db0e..520f940 100644 --- a/src/newsreader/news/core/tests/factories.py +++ b/src/newsreader/news/core/tests/factories.py @@ -3,7 +3,7 @@ import factory.fuzzy import pytz from newsreader.accounts.tests.factories import UserFactory -from newsreader.news.collection.reddit import REDDIT_URL +from newsreader.news.collection.reddit import REDDIT_API_URL from newsreader.news.core.models import Category, Post @@ -38,7 +38,7 @@ class FeedPostFactory(PostFactory): class RedditPostFactory(PostFactory): - url = factory.fuzzy.FuzzyText(length=10, prefix=f"{REDDIT_URL}/") + url = factory.fuzzy.FuzzyText(length=10, prefix=f"{REDDIT_API_URL}/") rule = factory.SubFactory( "newsreader.news.collection.tests.factories.SubredditFactory" )