0.2.3 #99
15 changed files with 95 additions and 30 deletions
|
|
@ -11,6 +11,7 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.AlterModelManagers(
|
||||
name="user", managers=[("objects", newsreader.accounts.models.UserManager())]
|
||||
name="user",
|
||||
managers=[("objects", newsreader.accounts.models.UserManager())],
|
||||
)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ urlpatterns = [
|
|||
path("logout/", LogoutView.as_view(), name="logout"),
|
||||
path("register/", RegistrationView.as_view(), name="register"),
|
||||
path(
|
||||
"register/complete/", RegistrationCompleteView.as_view(), name="register-complete"
|
||||
"register/complete/",
|
||||
RegistrationCompleteView.as_view(),
|
||||
name="register-complete",
|
||||
),
|
||||
path("register/closed/", RegistrationClosedView.as_view(), name="register-closed"),
|
||||
path(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@ from newsreader.news.collection.exceptions import StreamException
|
|||
from newsreader.news.collection.feed import FeedClient
|
||||
|
||||
|
||||
LINK_RELS = ["icon", "shortcut icon", "apple-touch-icon", "apple-touch-icon-precomposed"]
|
||||
LINK_RELS = [
|
||||
"icon",
|
||||
"shortcut icon",
|
||||
"apple-touch-icon",
|
||||
"apple-touch-icon-precomposed",
|
||||
]
|
||||
|
||||
|
||||
class FaviconBuilder(Builder):
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ import pytz
|
|||
from feedparser import parse
|
||||
|
||||
from newsreader.news.collection.base import Builder, Client, Collector, Stream
|
||||
from newsreader.news.collection.constants import WHITELISTED_ATTRIBUTES, WHITELISTED_TAGS
|
||||
from newsreader.news.collection.constants import (
|
||||
WHITELISTED_ATTRIBUTES,
|
||||
WHITELISTED_TAGS,
|
||||
)
|
||||
from newsreader.news.collection.exceptions import (
|
||||
StreamDeniedException,
|
||||
StreamException,
|
||||
|
|
@ -30,7 +33,8 @@ class FeedBuilder(Builder):
|
|||
_, stream = self.stream
|
||||
self.instances = []
|
||||
self.existing_posts = {
|
||||
post.remote_identifier: post for post in Post.objects.filter(rule=stream.rule)
|
||||
post.remote_identifier: post
|
||||
for post in Post.objects.filter(rule=stream.rule)
|
||||
}
|
||||
|
||||
return super().__enter__()
|
||||
|
|
|
|||
|
|
@ -112,15 +112,24 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
("America/Argentina/Cordoba", "America/Argentina/Cordoba"),
|
||||
("America/Argentina/Jujuy", "America/Argentina/Jujuy"),
|
||||
("America/Argentina/La_Rioja", "America/Argentina/La_Rioja"),
|
||||
(
|
||||
"America/Argentina/La_Rioja",
|
||||
"America/Argentina/La_Rioja",
|
||||
),
|
||||
("America/Argentina/Mendoza", "America/Argentina/Mendoza"),
|
||||
(
|
||||
"America/Argentina/Rio_Gallegos",
|
||||
"America/Argentina/Rio_Gallegos",
|
||||
),
|
||||
("America/Argentina/Salta", "America/Argentina/Salta"),
|
||||
("America/Argentina/San_Juan", "America/Argentina/San_Juan"),
|
||||
("America/Argentina/San_Luis", "America/Argentina/San_Luis"),
|
||||
(
|
||||
"America/Argentina/San_Juan",
|
||||
"America/Argentina/San_Juan",
|
||||
),
|
||||
(
|
||||
"America/Argentina/San_Luis",
|
||||
"America/Argentina/San_Luis",
|
||||
),
|
||||
("America/Argentina/Tucuman", "America/Argentina/Tucuman"),
|
||||
("America/Argentina/Ushuaia", "America/Argentina/Ushuaia"),
|
||||
("America/Aruba", "America/Aruba"),
|
||||
|
|
@ -183,7 +192,10 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
("America/Indiana/Knox", "America/Indiana/Knox"),
|
||||
("America/Indiana/Marengo", "America/Indiana/Marengo"),
|
||||
("America/Indiana/Petersburg", "America/Indiana/Petersburg"),
|
||||
(
|
||||
"America/Indiana/Petersburg",
|
||||
"America/Indiana/Petersburg",
|
||||
),
|
||||
("America/Indiana/Tell_City", "America/Indiana/Tell_City"),
|
||||
("America/Indiana/Vevay", "America/Indiana/Vevay"),
|
||||
("America/Indiana/Vincennes", "America/Indiana/Vincennes"),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ class CollectionRule(TimeStampedModel):
|
|||
name = models.CharField(max_length=100)
|
||||
|
||||
url = models.URLField(max_length=1024)
|
||||
website_url = models.URLField(max_length=1024, editable=False, blank=True, null=True)
|
||||
website_url = models.URLField(
|
||||
max_length=1024, editable=False, blank=True, null=True
|
||||
)
|
||||
favicon = models.URLField(blank=True, null=True)
|
||||
|
||||
timezone = models.CharField(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ class CollectionRuleFactory(factory.django.DjangoModelFactory):
|
|||
url = factory.Faker("url")
|
||||
website_url = factory.Faker("url")
|
||||
|
||||
category = factory.SubFactory("newsreader.news.core.tests.factories.CategoryFactory")
|
||||
category = factory.SubFactory(
|
||||
"newsreader.news.core.tests.factories.CategoryFactory"
|
||||
)
|
||||
|
||||
user = factory.SubFactory(UserFactory)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,13 @@ class FeedBuilderTestCase(TestCase):
|
|||
self.assertEquals(Post.objects.count(), 1)
|
||||
|
||||
self.assertEquals(
|
||||
post.remote_identifier, "https://www.bbc.co.uk/news/world-us-canada-48338168"
|
||||
post.remote_identifier,
|
||||
"https://www.bbc.co.uk/news/world-us-canada-48338168",
|
||||
)
|
||||
|
||||
self.assertEquals(post.url, "https://www.bbc.co.uk/news/world-us-canada-48338168")
|
||||
self.assertEquals(
|
||||
post.url, "https://www.bbc.co.uk/news/world-us-canada-48338168"
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
post.title, "Trump's 'genocidal taunts' will not end Iran - Zarif"
|
||||
|
|
@ -92,7 +95,9 @@ class FeedBuilderTestCase(TestCase):
|
|||
second_post.url, "https://www.bbc.co.uk/news/technology-48334739"
|
||||
)
|
||||
|
||||
self.assertEquals(second_post.title, "Huawei's Android loss: How it affects you")
|
||||
self.assertEquals(
|
||||
second_post.title, "Huawei's Android loss: How it affects you"
|
||||
)
|
||||
|
||||
def test_entry_without_remote_identifier(self):
|
||||
builder = FeedBuilder
|
||||
|
|
@ -332,7 +337,9 @@ class FeedBuilderTestCase(TestCase):
|
|||
|
||||
self.assertEquals(Post.objects.count(), 1)
|
||||
|
||||
self.assertFalse("Foreign Minister Mohammad Javad Zarif says the US" in post.body)
|
||||
self.assertFalse(
|
||||
"Foreign Minister Mohammad Javad Zarif says the US" in post.body
|
||||
)
|
||||
self.assertTrue("Federal Communications Commission" in post.body)
|
||||
|
||||
def test_content_detail_is_not_prioritized_if_shorter(self):
|
||||
|
|
@ -347,7 +354,9 @@ class FeedBuilderTestCase(TestCase):
|
|||
|
||||
self.assertEquals(Post.objects.count(), 1)
|
||||
|
||||
self.assertTrue("Foreign Minister Mohammad Javad Zarif says the US" in post.body)
|
||||
self.assertTrue(
|
||||
"Foreign Minister Mohammad Javad Zarif says the US" in post.body
|
||||
)
|
||||
|
||||
def test_content_detail_is_concatinated(self):
|
||||
builder = FeedBuilder
|
||||
|
|
|
|||
|
|
@ -238,7 +238,9 @@ class FeedCollectorTestCase(TestCase):
|
|||
first_post.title, "Trump's 'genocidal taunts' will not end Iran - Zarif"
|
||||
)
|
||||
|
||||
self.assertEquals(second_post.title, "Huawei's Android loss: How it affects you")
|
||||
self.assertEquals(
|
||||
second_post.title, "Huawei's Android loss: How it affects you"
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
third_post.title, "Birmingham head teacher threatened over LGBT lessons"
|
||||
|
|
|
|||
|
|
@ -178,7 +178,9 @@ class OPMLImportTestCase(TestCase):
|
|||
self.assertEquals(len(rules), 4)
|
||||
|
||||
def test_existing_rules(self):
|
||||
CollectionRuleFactory(url="http://www.engadget.com/rss-full.xml", user=self.user)
|
||||
CollectionRuleFactory(
|
||||
url="http://www.engadget.com/rss-full.xml", user=self.user
|
||||
)
|
||||
CollectionRuleFactory(url="https://news.ycombinator.com/rss", user=self.user)
|
||||
CollectionRuleFactory(
|
||||
url="http://feeds.feedburner.com/Techcrunch", user=self.user
|
||||
|
|
@ -200,7 +202,9 @@ class OPMLImportTestCase(TestCase):
|
|||
self.assertEquals(len(rules), 8)
|
||||
|
||||
def test_skip_existing_rules(self):
|
||||
CollectionRuleFactory(url="http://www.engadget.com/rss-full.xml", user=self.user)
|
||||
CollectionRuleFactory(
|
||||
url="http://www.engadget.com/rss-full.xml", user=self.user
|
||||
)
|
||||
CollectionRuleFactory(url="https://news.ycombinator.com/rss", user=self.user)
|
||||
CollectionRuleFactory(
|
||||
url="http://feeds.feedburner.com/Techcrunch", user=self.user
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ class Migration(migrations.Migration):
|
|||
model_name="category",
|
||||
name="user",
|
||||
field=models.ForeignKey(
|
||||
on_delete="Owner", related_name="categories", to=settings.AUTH_USER_MODEL
|
||||
on_delete="Owner",
|
||||
related_name="categories",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ from newsreader.news.core.models import Category, Post
|
|||
|
||||
|
||||
class PostSerializer(serializers.ModelSerializer):
|
||||
publicationDate = serializers.DateTimeField(source="publication_date", required=False)
|
||||
publicationDate = serializers.DateTimeField(
|
||||
source="publication_date", required=False
|
||||
)
|
||||
remoteIdentifier = serializers.CharField(source="remote_identifier", required=False)
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ class CategoryDetailViewTestCase(TestCase):
|
|||
def test_post(self):
|
||||
category = CategoryFactory(user=self.user)
|
||||
|
||||
response = self.client.post(reverse("api:categories-detail", args=[category.pk]))
|
||||
response = self.client.post(
|
||||
reverse("api:categories-detail", args=[category.pk])
|
||||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
|
|
@ -206,6 +208,8 @@ class CategoryReadTestCase(TestCase):
|
|||
def test_delete(self):
|
||||
category = CategoryFactory(name="Clickbait", user=self.user)
|
||||
|
||||
response = self.client.delete(reverse("api:categories-read", args=[category.pk]))
|
||||
response = self.client.delete(
|
||||
reverse("api:categories-read", args=[category.pk])
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
|
|
|
|||
|
|
@ -122,7 +122,9 @@ class CategoryUpdateViewTestCase(CategoryViewTestCase, TestCase):
|
|||
current_rules = CollectionRuleFactory.create_batch(size=3, user=self.user)
|
||||
self.category.rules.set([*current_rules])
|
||||
|
||||
self.assertCountEqual(self.category.rule_ids, [rule.pk for rule in current_rules])
|
||||
self.assertCountEqual(
|
||||
self.category.rule_ids, [rule.pk for rule in current_rules]
|
||||
)
|
||||
|
||||
data = {
|
||||
"name": self.category.name,
|
||||
|
|
@ -142,7 +144,9 @@ class CategoryUpdateViewTestCase(CategoryViewTestCase, TestCase):
|
|||
current_rules = CollectionRuleFactory.create_batch(size=3, user=self.user)
|
||||
self.category.rules.set([*current_rules])
|
||||
|
||||
self.assertCountEqual(self.category.rule_ids, [rule.pk for rule in current_rules])
|
||||
self.assertCountEqual(
|
||||
self.category.rule_ids, [rule.pk for rule in current_rules]
|
||||
)
|
||||
|
||||
data = {"name": "durp", "user": self.user.pk}
|
||||
self.client.post(self.url, data)
|
||||
|
|
@ -187,7 +191,9 @@ class CategoryUpdateViewTestCase(CategoryViewTestCase, TestCase):
|
|||
current_rules = CollectionRuleFactory.create_batch(size=3, user=self.user)
|
||||
self.category.rules.set([*current_rules])
|
||||
|
||||
self.assertCountEqual(self.category.rule_ids, [rule.pk for rule in current_rules])
|
||||
self.assertCountEqual(
|
||||
self.category.rule_ids, [rule.pk for rule in current_rules]
|
||||
)
|
||||
|
||||
data = {
|
||||
"name": self.category.name,
|
||||
|
|
@ -200,10 +206,14 @@ class CategoryUpdateViewTestCase(CategoryViewTestCase, TestCase):
|
|||
self.assertContains(response, "not one of the available choices")
|
||||
|
||||
self.category.refresh_from_db()
|
||||
self.assertCountEqual(self.category.rule_ids, [rule.pk for rule in current_rules])
|
||||
self.assertCountEqual(
|
||||
self.category.rule_ids, [rule.pk for rule in current_rules]
|
||||
)
|
||||
|
||||
other_category.refresh_from_db()
|
||||
self.assertCountEqual(other_category.rule_ids, [rule.pk for rule in other_rules])
|
||||
self.assertCountEqual(
|
||||
other_category.rule_ids, [rule.pk for rule in other_rules]
|
||||
)
|
||||
|
||||
def test_unique_together(self):
|
||||
other_category = CategoryFactory(name="other category", user=self.user)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,12 @@ endpoints = [
|
|||
path("posts/", ListPostView.as_view(), name="posts-list"),
|
||||
path("posts/<int:pk>/", DetailPostView.as_view(), name="posts-detail"),
|
||||
path("categories/", ListCategoryView.as_view(), name="categories-list"),
|
||||
path("categories/<int:pk>/", DetailCategoryView.as_view(), name="categories-detail"),
|
||||
path("categories/<int:pk>/read/", CategoryReadView.as_view(), name="categories-read"),
|
||||
path(
|
||||
"categories/<int:pk>/", DetailCategoryView.as_view(), name="categories-detail"
|
||||
),
|
||||
path(
|
||||
"categories/<int:pk>/read/", CategoryReadView.as_view(), name="categories-read"
|
||||
),
|
||||
path(
|
||||
"categories/<int:pk>/rules/",
|
||||
NestedRuleCategoryView.as_view(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue