Replace rest_framework_swagger with drf_yasg
rest_framework is deprecated see https://github.com/marcgibbons/django-rest-swagger#django-rest-swagger-deprecated-2019-06-04
This commit is contained in:
parent
ec45a661e5
commit
a6827e604d
24 changed files with 2728 additions and 311 deletions
|
|
@ -6,7 +6,7 @@ import { isEqual } from 'lodash';
|
||||||
import { fetchCategories } from './actions/categories';
|
import { fetchCategories } from './actions/categories';
|
||||||
|
|
||||||
import Sidebar from './components/sidebar/Sidebar.js';
|
import Sidebar from './components/sidebar/Sidebar.js';
|
||||||
import FeedList from './components/feedlist/FeedList.js';
|
import PostList from './components/postlist/PostList.js';
|
||||||
import PostModal from './components/PostModal.js';
|
import PostModal from './components/PostModal.js';
|
||||||
import Messages from '../../components/Messages.js';
|
import Messages from '../../components/Messages.js';
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ class App extends React.Component {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<FeedList />
|
<PostList />
|
||||||
|
|
||||||
{this.props.error && (
|
{this.props.error && (
|
||||||
<Messages messages={[{ type: 'error', text: this.props.error.message }]} />
|
<Messages messages={[{ type: 'error', text: this.props.error.message }]} />
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
|
||||||
import { unSelectPost, markPostRead } from '../actions/posts.js';
|
import { unSelectPost, markPostRead } from '../actions/posts.js';
|
||||||
|
import { CATEGORY_TYPE, RULE_TYPE, FEED, SUBREDDIT } from '../constants.js';
|
||||||
import { formatDatetime } from '../../../utils.js';
|
import { formatDatetime } from '../../../utils.js';
|
||||||
|
|
||||||
class PostModal extends React.Component {
|
class PostModal extends React.Component {
|
||||||
|
|
@ -43,6 +44,10 @@ class PostModal extends React.Component {
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
const publicationDate = formatDatetime(post.publicationDate);
|
const publicationDate = formatDatetime(post.publicationDate);
|
||||||
const titleClassName = post.read ? 'post__title post__title--read' : 'post__title';
|
const titleClassName = post.read ? 'post__title post__title--read' : 'post__title';
|
||||||
|
const ruleUrl =
|
||||||
|
this.props.rule.type === FEED
|
||||||
|
? `/collection/rules/${this.props.rule.id}/`
|
||||||
|
: `/collection/rules/subreddits/${this.props.rule.id}/`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="modal post-modal">
|
<div className="modal post-modal">
|
||||||
|
|
@ -70,11 +75,7 @@ class PostModal extends React.Component {
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<span className="badge post__rule" title={this.props.rule.name}>
|
<span className="badge post__rule" title={this.props.rule.name}>
|
||||||
<a
|
<a href={ruleUrl} target="_blank" rel="noopener noreferrer">
|
||||||
href={`/collection/rules/${this.props.rule.id}/`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{this.props.rule.name}
|
{this.props.rule.name}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { CATEGORY_TYPE, RULE_TYPE } from '../../constants.js';
|
import { CATEGORY_TYPE, RULE_TYPE, FEED, SUBREDDIT } from '../../constants.js';
|
||||||
import { selectPost } from '../../actions/posts.js';
|
import { selectPost } from '../../actions/posts.js';
|
||||||
import { formatDatetime } from '../../../../utils.js';
|
import { formatDatetime } from '../../../../utils.js';
|
||||||
|
|
||||||
|
|
@ -14,6 +14,11 @@ class PostItem extends React.Component {
|
||||||
? 'posts__header posts__header--read'
|
? 'posts__header posts__header--read'
|
||||||
: 'posts__header';
|
: 'posts__header';
|
||||||
|
|
||||||
|
const ruleUrl =
|
||||||
|
rule.type === FEED
|
||||||
|
? `/collection/rules/${rule.id}/`
|
||||||
|
: `/collection/rules/subreddits/${rule.id}/`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="posts__item">
|
<li className="posts__item">
|
||||||
<h5
|
<h5
|
||||||
|
|
@ -30,11 +35,7 @@ class PostItem extends React.Component {
|
||||||
</span>
|
</span>
|
||||||
{this.props.selected.type == CATEGORY_TYPE && (
|
{this.props.selected.type == CATEGORY_TYPE && (
|
||||||
<span className="badge">
|
<span className="badge">
|
||||||
<a
|
<a href={ruleUrl} target="_blank" rel="noopener noreferrer">
|
||||||
href={`/collection/rules/${rule.id}/`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{rule.name}
|
{rule.name}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -8,7 +8,7 @@ import { filterPosts } from './filters.js';
|
||||||
import LoadingIndicator from '../../../../components/LoadingIndicator.js';
|
import LoadingIndicator from '../../../../components/LoadingIndicator.js';
|
||||||
import PostItem from './PostItem.js';
|
import PostItem from './PostItem.js';
|
||||||
|
|
||||||
class FeedList extends React.Component {
|
class PostList extends React.Component {
|
||||||
checkScrollHeight = ::this.checkScrollHeight;
|
checkScrollHeight = ::this.checkScrollHeight;
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
@ -83,4 +83,4 @@ const mapDispatchToProps = dispatch => ({
|
||||||
fetchPostsBySection: (rule, page = false) => dispatch(fetchPostsBySection(rule, page)),
|
fetchPostsBySection: (rule, page = false) => dispatch(fetchPostsBySection(rule, page)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(FeedList);
|
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
|
||||||
|
|
@ -1,2 +1,5 @@
|
||||||
export const RULE_TYPE = 'RULE';
|
export const RULE_TYPE = 'RULE';
|
||||||
export const CATEGORY_TYPE = 'CATEGORY';
|
export const CATEGORY_TYPE = 'CATEGORY';
|
||||||
|
|
||||||
|
export const SUBREDDIT = 'subreddit';
|
||||||
|
export const FEED = 'feed';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,14 @@ from newsreader.news.collection.models import CollectionRule
|
||||||
class CollectionRuleAdmin(admin.ModelAdmin):
|
class CollectionRuleAdmin(admin.ModelAdmin):
|
||||||
fields = ("url", "name", "timezone", "category", "favicon", "user")
|
fields = ("url", "name", "timezone", "category", "favicon", "user")
|
||||||
|
|
||||||
list_display = ("name", "category", "url", "last_suceeded", "succeeded")
|
list_display = (
|
||||||
|
"name",
|
||||||
|
"type_display",
|
||||||
|
"category",
|
||||||
|
"url",
|
||||||
|
"last_suceeded",
|
||||||
|
"succeeded",
|
||||||
|
)
|
||||||
list_filter = ("user",)
|
list_filter = ("user",)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
|
|
@ -14,5 +21,8 @@ class CollectionRuleAdmin(admin.ModelAdmin):
|
||||||
obj.user = request.user
|
obj.user = request.user
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
||||||
|
def type_display(self, rule):
|
||||||
|
return rule.get_type_display()
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(CollectionRule, CollectionRuleAdmin)
|
admin.site.register(CollectionRule, CollectionRuleAdmin)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import gettext_lazy as _
|
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.choices import RuleTypeChoices
|
||||||
from newsreader.news.collection.models import CollectionRule
|
from newsreader.news.collection.models import CollectionRule
|
||||||
|
from newsreader.news.collection.reddit import REDDIT_API_URL
|
||||||
from newsreader.news.core.models import Category
|
from newsreader.news.core.models import Category
|
||||||
|
|
||||||
|
|
||||||
def get_reddit_help_text():
|
def get_reddit_help_text():
|
||||||
return mark_safe(
|
return mark_safe(
|
||||||
"Only subreddits are supported. For example: "
|
"Only subreddits are supported"
|
||||||
"<a className='link' target='_blank' rel='noopener noreferrer'"
|
" see the 'listings' section in <a className='link' target='_blank' rel='noopener noreferrer'"
|
||||||
" href='https://reddit.com/r/aww'>https://www.reddit.com/r/aww</a>."
|
" href='https://www.reddit.com/dev/api#section_listings'>the reddit API docs</a>."
|
||||||
" Note that subreddit urls should NOT include 'www' because Reddit is picky."
|
" For example: <a className='link' target='_blank' rel='noopener noreferrer'"
|
||||||
|
" href='https://oauth.reddit.com/r/aww'>https://oauth.reddit.com/r/aww</a>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -65,15 +68,19 @@ class SubRedditRuleForm(CollectionRuleForm):
|
||||||
|
|
||||||
timezone = None
|
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):
|
def save(self, commit=True):
|
||||||
instance = super().save(commit=False)
|
instance = super().save(commit=False)
|
||||||
|
|
||||||
instance.type = RuleTypeChoices.subreddit
|
instance.type = RuleTypeChoices.subreddit
|
||||||
instance.timezone = str(pytz.utc)
|
instance.timezone = str(pytz.utc)
|
||||||
instance.user = self.user
|
|
||||||
|
|
||||||
if not instance.url.endswith(".json"):
|
|
||||||
instance.url = f"{instance.url}.json"
|
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
instance.save()
|
instance.save()
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from uuid import uuid4
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.html import format_html
|
||||||
|
|
||||||
import bleach
|
import bleach
|
||||||
import pytz
|
import pytz
|
||||||
|
|
@ -42,6 +43,12 @@ REDDIT_API_URL = "https://oauth.reddit.com"
|
||||||
RATE_LIMIT = 60
|
RATE_LIMIT = 60
|
||||||
RATE_LIMIT_DURATION = timedelta(seconds=60)
|
RATE_LIMIT_DURATION = timedelta(seconds=60)
|
||||||
|
|
||||||
|
REDDIT_IMAGE_EXTENSIONS = (".jpg", ".png", ".gif")
|
||||||
|
REDDIT_VIDEO_EXTENSIONS = (".mp4", ".gifv", ".webm")
|
||||||
|
|
||||||
|
# see type prefixes on https://www.reddit.com/dev/api/
|
||||||
|
REDDIT_POST = "t3"
|
||||||
|
|
||||||
|
|
||||||
def get_reddit_authorization_url(user):
|
def get_reddit_authorization_url(user):
|
||||||
state = str(uuid4())
|
state = str(uuid4())
|
||||||
|
|
@ -114,30 +121,72 @@ class RedditBuilder(Builder):
|
||||||
results = {}
|
results = {}
|
||||||
|
|
||||||
for post in posts:
|
for post in posts:
|
||||||
if not "data" in post:
|
if not "data" in post or post["kind"] != REDDIT_POST:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
remote_identifier = post["data"]["id"]
|
data = post["data"]
|
||||||
title = truncate_text(Post, "title", post["data"]["title"])
|
|
||||||
author = truncate_text(Post, "author", post["data"]["author"])
|
remote_identifier = data["id"]
|
||||||
url_fragment = f"{post['data']['permalink']}"
|
title = truncate_text(Post, "title", data["title"])
|
||||||
|
author = truncate_text(Post, "author", data["author"])
|
||||||
|
post_url_fragment = data["permalink"]
|
||||||
|
direct_url = data["url"]
|
||||||
|
is_text_post = data["is_self"]
|
||||||
|
|
||||||
if remote_identifier in results:
|
if remote_identifier in results:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
uncleaned_body = post["data"]["selftext_html"]
|
if is_text_post:
|
||||||
unescaped_body = unescape(uncleaned_body) if uncleaned_body else ""
|
uncleaned_body = data["selftext_html"]
|
||||||
body = (
|
unescaped_body = unescape(uncleaned_body) if uncleaned_body else ""
|
||||||
bleach.clean(
|
body = (
|
||||||
unescaped_body,
|
bleach.clean(
|
||||||
tags=WHITELISTED_TAGS,
|
unescaped_body,
|
||||||
attributes=WHITELISTED_ATTRIBUTES,
|
tags=WHITELISTED_TAGS,
|
||||||
strip=True,
|
attributes=WHITELISTED_ATTRIBUTES,
|
||||||
strip_comments=True,
|
strip=True,
|
||||||
|
strip_comments=True,
|
||||||
|
)
|
||||||
|
if unescaped_body
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
elif direct_url.endswith(REDDIT_IMAGE_EXTENSIONS):
|
||||||
|
body = format_html(
|
||||||
|
"<div><img alt='{title}' src='{url}' loading='lazy' /></div>",
|
||||||
|
url=direct_url,
|
||||||
|
title=title,
|
||||||
|
)
|
||||||
|
elif data["is_video"]:
|
||||||
|
video_info = data["secure_media"]["reddit_video"]
|
||||||
|
|
||||||
|
body = format_html(
|
||||||
|
"<div><video controls muted><source src='{url}' type='video/mp4' /></video></div>",
|
||||||
|
url=video_info["fallback_url"],
|
||||||
|
)
|
||||||
|
elif direct_url.endswith(REDDIT_VIDEO_EXTENSIONS):
|
||||||
|
extension = next(
|
||||||
|
extension.replace(".", "")
|
||||||
|
for extension in REDDIT_VIDEO_EXTENSIONS
|
||||||
|
if direct_url.endswith(extension)
|
||||||
|
)
|
||||||
|
|
||||||
|
if extension == "gifv":
|
||||||
|
body = format_html(
|
||||||
|
"<div><video controls muted><source src='{url}' type='video/mp4' /></video></div>",
|
||||||
|
url=direct_url.replace(extension, "mp4"),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
body = format_html(
|
||||||
|
"<div><video controls muted><source src='{url}' type='video/{extension}' /></video></div>",
|
||||||
|
url=direct_url,
|
||||||
|
extension=extension,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
body = format_html(
|
||||||
|
"<div><a target='_blank' rel='noopener noreferrer' alt='{title}' href='{url}' class='link'>Direct url</a></div>",
|
||||||
|
url=direct_url,
|
||||||
|
title=title,
|
||||||
)
|
)
|
||||||
if unescaped_body
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed_date = datetime.fromtimestamp(post["data"]["created_utc"])
|
parsed_date = datetime.fromtimestamp(post["data"]["created_utc"])
|
||||||
|
|
@ -146,12 +195,12 @@ class RedditBuilder(Builder):
|
||||||
logging.warning(f"Failed parsing timestamp from {url_fragment}")
|
logging.warning(f"Failed parsing timestamp from {url_fragment}")
|
||||||
created_date = timezone.now()
|
created_date = timezone.now()
|
||||||
|
|
||||||
data = {
|
post_data = {
|
||||||
"remote_identifier": remote_identifier,
|
"remote_identifier": remote_identifier,
|
||||||
"title": title,
|
"title": title,
|
||||||
"body": body,
|
"body": body,
|
||||||
"author": author,
|
"author": author,
|
||||||
"url": f"{REDDIT_URL}{url_fragment}",
|
"url": f"{REDDIT_URL}{post_url_fragment}",
|
||||||
"publication_date": created_date,
|
"publication_date": created_date,
|
||||||
"rule": rule,
|
"rule": rule,
|
||||||
}
|
}
|
||||||
|
|
@ -159,13 +208,13 @@ class RedditBuilder(Builder):
|
||||||
if remote_identifier in self.existing_posts:
|
if remote_identifier in self.existing_posts:
|
||||||
existing_post = self.existing_posts[remote_identifier]
|
existing_post = self.existing_posts[remote_identifier]
|
||||||
|
|
||||||
for key, value in data.items():
|
for key, value in post_data.items():
|
||||||
setattr(existing_post, key, value)
|
setattr(existing_post, key, value)
|
||||||
|
|
||||||
results[existing_post.remote_identifier] = existing_post
|
results[existing_post.remote_identifier] = existing_post
|
||||||
continue
|
continue
|
||||||
|
|
||||||
results[remote_identifier] = Post(**data)
|
results[remote_identifier] = Post(**post_data)
|
||||||
|
|
||||||
return results.values()
|
return results.values()
|
||||||
|
|
||||||
|
|
@ -271,7 +320,7 @@ class RedditClient(Client):
|
||||||
|
|
||||||
yield response_data
|
yield response_data
|
||||||
except StreamDeniedException as e:
|
except StreamDeniedException as e:
|
||||||
logger.exception(
|
logger.warning(
|
||||||
f"Access token expired for user {stream.user.pk}"
|
f"Access token expired for user {stream.user.pk}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,4 @@ class RuleSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CollectionRule
|
model = CollectionRule
|
||||||
fields = ("id", "name", "url", "favicon", "category", "user", "unread")
|
fields = ("id", "type", "name", "url", "favicon", "category", "user", "unread")
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.models import Post
|
from newsreader.news.core.models import Post
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class CollectionRuleDetailViewTestCase(TestCase):
|
class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
|
|
@ -15,7 +15,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
||||||
|
|
@ -29,6 +29,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertTrue("url" in data)
|
self.assertTrue("url" in data)
|
||||||
self.assertTrue("favicon" in data)
|
self.assertTrue("favicon" in data)
|
||||||
self.assertTrue("category" in data)
|
self.assertTrue("category" in data)
|
||||||
|
self.assertTrue("type" in data)
|
||||||
|
|
||||||
def test_not_known(self):
|
def test_not_known(self):
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
|
|
@ -40,7 +41,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], "Not found.")
|
self.assertEquals(data["detail"], "Not found.")
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
||||||
|
|
@ -51,7 +52,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||||
|
|
||||||
def test_patch(self):
|
def test_patch(self):
|
||||||
rule = CollectionRuleFactory(name="BBC", user=self.user)
|
rule = FeedFactory(name="BBC", user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -67,7 +68,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
old_category = CategoryFactory(user=self.user)
|
old_category = CategoryFactory(user=self.user)
|
||||||
new_category = CategoryFactory(user=self.user)
|
new_category = CategoryFactory(user=self.user)
|
||||||
|
|
||||||
rule = CollectionRuleFactory(name="BBC", category=old_category, user=self.user)
|
rule = FeedFactory(name="BBC", category=old_category, user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -80,7 +81,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["category"], new_category.pk)
|
self.assertEquals(data["category"], new_category.pk)
|
||||||
|
|
||||||
def test_identifier_cannot_be_changed(self):
|
def test_identifier_cannot_be_changed(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -93,7 +94,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["id"], rule.pk)
|
self.assertEquals(data["id"], rule.pk)
|
||||||
|
|
||||||
def test_category_change(self):
|
def test_category_change(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
category = CategoryFactory(user=self.user)
|
category = CategoryFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
|
|
@ -108,7 +109,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["category"], category.pk)
|
self.assertEquals(data["category"], category.pk)
|
||||||
|
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
rule = CollectionRuleFactory(name="BBC", user=self.user)
|
rule = FeedFactory(name="BBC", user=self.user)
|
||||||
|
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -121,7 +122,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["name"], "BBC")
|
self.assertEquals(data["name"], "BBC")
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.delete(
|
response = self.client.delete(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
||||||
|
|
@ -132,7 +133,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
def test_rule_with_unauthenticated_user(self):
|
def test_rule_with_unauthenticated_user(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(name="BBC", user=self.user)
|
rule = FeedFactory(name="BBC", user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -144,7 +145,7 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_rule_with_unauthorized_user(self):
|
def test_rule_with_unauthorized_user(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(name="BBC", user=other_user)
|
rule = FeedFactory(name="BBC", user=other_user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
reverse("api:news:collection:rules-detail", args=[rule.pk]),
|
||||||
|
|
@ -155,10 +156,10 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 403)
|
||||||
|
|
||||||
def test_read_count(self):
|
def test_read_count(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=20, read=False, rule=rule)
|
||||||
PostFactory.create_batch(size=20, read=True, rule=rule)
|
FeedPostFactory.create_batch(size=20, read=True, rule=rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
||||||
|
|
@ -175,9 +176,9 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_rule_read(self):
|
def test_rule_read(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=20, read=False, rule=rule)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk])
|
reverse("api:news:collection:rules-read", args=[rule.pk])
|
||||||
|
|
@ -197,9 +198,9 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
def test_unauthenticated_user(self):
|
def test_unauthenticated_user(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=20, read=False, rule=rule)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk])
|
reverse("api:news:collection:rules-read", args=[rule.pk])
|
||||||
|
|
@ -209,9 +210,9 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
|
|
||||||
def test_unauthorized_user(self):
|
def test_unauthorized_user(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(user=other_user)
|
rule = FeedFactory(user=other_user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=20, read=False, rule=rule)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk])
|
reverse("api:news:collection:rules-read", args=[rule.pk])
|
||||||
|
|
@ -221,7 +222,7 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
self.assertEquals(Post.objects.filter(read=False).count(), 20)
|
self.assertEquals(Post.objects.filter(read=False).count(), 20)
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk])
|
reverse("api:news:collection:rules-read", args=[rule.pk])
|
||||||
|
|
@ -230,7 +231,7 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 405)
|
self.assertEquals(response.status_code, 405)
|
||||||
|
|
||||||
def test_patch(self):
|
def test_patch(self):
|
||||||
rule = CollectionRuleFactory(name="BBC", user=self.user)
|
rule = FeedFactory(name="BBC", user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk]),
|
reverse("api:news:collection:rules-read", args=[rule.pk]),
|
||||||
|
|
@ -241,7 +242,7 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 405)
|
self.assertEquals(response.status_code, 405)
|
||||||
|
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
rule = CollectionRuleFactory(name="BBC", user=self.user)
|
rule = FeedFactory(name="BBC", user=self.user)
|
||||||
|
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk]),
|
reverse("api:news:collection:rules-read", args=[rule.pk]),
|
||||||
|
|
@ -252,7 +253,7 @@ class CollectionRuleReadTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 405)
|
self.assertEquals(response.status_code, 405)
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.delete(
|
response = self.client.delete(
|
||||||
reverse("api:news:collection:rules-read", args=[rule.pk])
|
reverse("api:news:collection:rules-read", args=[rule.pk])
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ from django.urls import reverse
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class RuleListViewTestCase(TestCase):
|
class RuleListViewTestCase(TestCase):
|
||||||
|
|
@ -18,7 +18,7 @@ class RuleListViewTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
CollectionRuleFactory.create_batch(size=3, user=self.user)
|
FeedFactory.create_batch(size=3, user=self.user)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -30,19 +30,19 @@ class RuleListViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_ordering(self):
|
def test_ordering(self):
|
||||||
rules = [
|
rules = [
|
||||||
CollectionRuleFactory(
|
FeedFactory(
|
||||||
created=datetime.combine(
|
created=datetime.combine(
|
||||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
user=self.user,
|
user=self.user,
|
||||||
),
|
),
|
||||||
CollectionRuleFactory(
|
FeedFactory(
|
||||||
created=datetime.combine(
|
created=datetime.combine(
|
||||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
user=self.user,
|
user=self.user,
|
||||||
),
|
),
|
||||||
CollectionRuleFactory(
|
FeedFactory(
|
||||||
created=datetime.combine(
|
created=datetime.combine(
|
||||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
|
|
@ -63,7 +63,7 @@ class RuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["results"][2]["id"], rules[0].pk)
|
self.assertEquals(data["results"][2]["id"], rules[0].pk)
|
||||||
|
|
||||||
def test_pagination_count(self):
|
def test_pagination_count(self):
|
||||||
CollectionRuleFactory.create_batch(size=80, user=self.user)
|
FeedFactory.create_batch(size=80, user=self.user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-list"), {"count": 30}
|
reverse("api:news:collection:rules-list"), {"count": 30}
|
||||||
|
|
@ -124,7 +124,7 @@ class RuleListViewTestCase(TestCase):
|
||||||
def test_rules_with_unauthenticated_user(self):
|
def test_rules_with_unauthenticated_user(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
CollectionRuleFactory.create_batch(size=3, user=self.user)
|
FeedFactory.create_batch(size=3, user=self.user)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||||
|
|
||||||
|
|
@ -132,7 +132,7 @@ class RuleListViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_rules_with_unauthorized_user(self):
|
def test_rules_with_unauthorized_user(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
CollectionRuleFactory.create_batch(size=3, user=other_user)
|
FeedFactory.create_batch(size=3, user=other_user)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -149,8 +149,8 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
PostFactory.create_batch(size=5, rule=rule)
|
FeedPostFactory.create_batch(size=5, rule=rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||||
|
|
@ -164,8 +164,8 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["count"], 5)
|
self.assertEquals(data["count"], 5)
|
||||||
|
|
||||||
def test_pagination(self):
|
def test_pagination(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
PostFactory.create_batch(size=80, rule=rule)
|
FeedPostFactory.create_batch(size=80, rule=rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -178,7 +178,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(len(data["results"]), 30)
|
self.assertEquals(len(data["results"]), 30)
|
||||||
|
|
||||||
def test_empty(self):
|
def test_empty(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||||
|
|
@ -197,7 +197,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 404)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -210,7 +210,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||||
|
|
||||||
def test_patch(self):
|
def test_patch(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -223,7 +223,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||||
|
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -236,7 +236,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
response = self.client.delete(
|
response = self.client.delete(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -251,7 +251,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
def test_rule_with_unauthenticated_user(self):
|
def test_rule_with_unauthenticated_user(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(user=self.user)
|
rule = FeedFactory(user=self.user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||||
|
|
@ -261,7 +261,7 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_rule_with_unauthorized_user(self):
|
def test_rule_with_unauthorized_user(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(user=other_user)
|
rule = FeedFactory(user=other_user)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||||
|
|
@ -270,26 +270,24 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 403)
|
||||||
|
|
||||||
def test_posts_ordering(self):
|
def test_posts_ordering(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
posts = [
|
posts = [
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the first post",
|
title="I'm the first post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the second post",
|
title="I'm the second post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the third post",
|
title="I'm the third post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
|
|
@ -313,11 +311,11 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
||||||
|
|
||||||
def test_only_posts_from_rule_are_returned(self):
|
def test_only_posts_from_rule_are_returned(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
other_rule = CollectionRuleFactory.create(user=self.user)
|
other_rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=5, rule=rule)
|
FeedPostFactory.create_batch(size=5, rule=rule)
|
||||||
PostFactory.create_batch(size=5, rule=other_rule)
|
FeedPostFactory.create_batch(size=5, rule=other_rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||||
|
|
@ -334,10 +332,10 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(post["rule"], rule.pk)
|
self.assertEquals(post["rule"], rule.pk)
|
||||||
|
|
||||||
def test_unread_posts(self):
|
def test_unread_posts(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
@ -354,10 +352,10 @@ class NestedRuleListViewTestCase(TestCase):
|
||||||
self.assertEquals(post["read"], False)
|
self.assertEquals(post["read"], False)
|
||||||
|
|
||||||
def test_read_posts(self):
|
def test_read_posts(self):
|
||||||
rule = CollectionRuleFactory.create(user=self.user)
|
rule = FeedFactory.create(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=20, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}),
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from freezegun import freeze_time
|
||||||
from newsreader.news.collection.feed import FeedBuilder
|
from newsreader.news.collection.feed import FeedBuilder
|
||||||
from newsreader.news.collection.tests.factories import FeedFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.models import Post
|
from newsreader.news.core.models import Post
|
||||||
from newsreader.news.core.tests.factories import PostFactory
|
from newsreader.news.core.tests.factories import FeedPostFactory
|
||||||
|
|
||||||
from .mocks import *
|
from .mocks import *
|
||||||
|
|
||||||
|
|
@ -287,11 +287,11 @@ class FeedBuilderTestCase(TestCase):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
mock_stream = MagicMock(rule=rule)
|
mock_stream = MagicMock(rule=rule)
|
||||||
|
|
||||||
existing_first_post = PostFactory.create(
|
existing_first_post = FeedPostFactory.create(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule
|
||||||
)
|
)
|
||||||
|
|
||||||
existing_second_post = PostFactory.create(
|
existing_second_post = FeedPostFactory.create(
|
||||||
remote_identifier="a5479c66-8fae-11e9-8422-00163ef6bee7", rule=rule
|
remote_identifier="a5479c66-8fae-11e9-8422-00163ef6bee7", rule=rule
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ from newsreader.news.collection.feed import FeedCollector
|
||||||
from newsreader.news.collection.tests.factories import FeedFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.collection.utils import build_publication_date
|
from newsreader.news.collection.utils import build_publication_date
|
||||||
from newsreader.news.core.models import Post
|
from newsreader.news.core.models import Post
|
||||||
from newsreader.news.core.tests.factories import PostFactory
|
from newsreader.news.core.tests.factories import FeedPostFactory
|
||||||
|
|
||||||
from .mocks import duplicate_mock, empty_mock, multiple_mock, multiple_update_mock
|
from .mocks import duplicate_mock, empty_mock, multiple_mock, multiple_update_mock
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), pytz.utc
|
struct_time((2019, 5, 20, 16, 7, 37, 0, 140, 0)), pytz.utc
|
||||||
)
|
)
|
||||||
|
|
||||||
first_post = PostFactory(
|
first_post = FeedPostFactory(
|
||||||
url="https://www.bbc.co.uk/news/world-us-canada-48338168",
|
url="https://www.bbc.co.uk/news/world-us-canada-48338168",
|
||||||
title="Trump's 'genocidal taunts' will not end Iran - Zarif",
|
title="Trump's 'genocidal taunts' will not end Iran - Zarif",
|
||||||
body="Foreign Minister Mohammad Javad Zarif says the US "
|
body="Foreign Minister Mohammad Javad Zarif says the US "
|
||||||
|
|
@ -156,7 +156,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), pytz.utc
|
struct_time((2019, 5, 20, 12, 19, 19, 0, 140, 0)), pytz.utc
|
||||||
)
|
)
|
||||||
|
|
||||||
second_post = PostFactory(
|
second_post = FeedPostFactory(
|
||||||
url="https://www.bbc.co.uk/news/technology-48334739",
|
url="https://www.bbc.co.uk/news/technology-48334739",
|
||||||
title="Huawei's Android loss: How it affects you",
|
title="Huawei's Android loss: How it affects you",
|
||||||
body="Google's move to end business ties with Huawei will "
|
body="Google's move to end business ties with Huawei will "
|
||||||
|
|
@ -169,7 +169,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), pytz.utc
|
struct_time((2019, 5, 20, 16, 32, 38, 0, 140, 0)), pytz.utc
|
||||||
)
|
)
|
||||||
|
|
||||||
third_post = PostFactory(
|
third_post = FeedPostFactory(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Police are investigating the messages while an MP "
|
body="Police are investigating the messages while an MP "
|
||||||
|
|
@ -194,7 +194,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
self.mocked_parse.return_value = multiple_update_mock
|
self.mocked_parse.return_value = multiple_update_mock
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
first_post = PostFactory(
|
first_post = FeedPostFactory(
|
||||||
remote_identifier="https://www.bbc.co.uk/news/world-us-canada-48338168",
|
remote_identifier="https://www.bbc.co.uk/news/world-us-canada-48338168",
|
||||||
url="https://www.bbc.co.uk/",
|
url="https://www.bbc.co.uk/",
|
||||||
title="Trump",
|
title="Trump",
|
||||||
|
|
@ -203,7 +203,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
second_post = PostFactory(
|
second_post = FeedPostFactory(
|
||||||
remote_identifier="https://www.bbc.co.uk/news/technology-48334739",
|
remote_identifier="https://www.bbc.co.uk/news/technology-48334739",
|
||||||
url="https://www.bbc.co.uk/",
|
url="https://www.bbc.co.uk/",
|
||||||
title="Huawei's Android loss: How it affects you",
|
title="Huawei's Android loss: How it affects you",
|
||||||
|
|
@ -212,7 +212,7 @@ class FeedCollectorTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
third_post = PostFactory(
|
third_post = FeedPostFactory(
|
||||||
remote_identifier="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
remote_identifier="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from freezegun import freeze_time
|
||||||
from newsreader.news.collection.feed import FeedDuplicateHandler
|
from newsreader.news.collection.feed import FeedDuplicateHandler
|
||||||
from newsreader.news.collection.tests.factories import FeedFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.models import Post
|
from newsreader.news.core.models import Post
|
||||||
from newsreader.news.core.tests.factories import PostFactory
|
from newsreader.news.core.tests.factories import FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("2019-10-30 12:30:00")
|
@freeze_time("2019-10-30 12:30:00")
|
||||||
|
|
@ -19,17 +19,17 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
def test_duplicate_entries_with_remote_identifiers(self):
|
def test_duplicate_entries_with_remote_identifiers(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
existing_post = PostFactory.create(
|
existing_post = FeedPostFactory.create(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule
|
||||||
)
|
)
|
||||||
|
|
||||||
new_posts = PostFactory.build_batch(
|
new_posts = FeedPostFactory.build_batch(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now() - timedelta(days=7),
|
publication_date=timezone.now() - timedelta(days=7),
|
||||||
rule=rule,
|
rule=rule,
|
||||||
size=5,
|
size=5,
|
||||||
)
|
)
|
||||||
last_post = PostFactory.build(
|
last_post = FeedPostFactory.build(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now(),
|
publication_date=timezone.now(),
|
||||||
rule=rule,
|
rule=rule,
|
||||||
|
|
@ -54,7 +54,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
def test_duplicate_entries_with_different_remote_identifiers(self):
|
def test_duplicate_entries_with_different_remote_identifiers(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
existing_post = PostFactory(
|
existing_post = FeedPostFactory(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
url="https://bbc.com",
|
url="https://bbc.com",
|
||||||
title="New post",
|
title="New post",
|
||||||
|
|
@ -63,7 +63,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
new_posts = PostFactory.build_batch(
|
new_posts = FeedPostFactory.build_batch(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7Q",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7Q",
|
||||||
url="https://bbc.com",
|
url="https://bbc.com",
|
||||||
title="New post",
|
title="New post",
|
||||||
|
|
@ -72,7 +72,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
size=5,
|
size=5,
|
||||||
)
|
)
|
||||||
last_post = PostFactory.build(
|
last_post = FeedPostFactory.build(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7Q",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7Q",
|
||||||
url="https://bbc.com",
|
url="https://bbc.com",
|
||||||
title="New post",
|
title="New post",
|
||||||
|
|
@ -100,7 +100,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
def test_duplicate_entries_in_recent_database(self):
|
def test_duplicate_entries_in_recent_database(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
existing_post = PostFactory(
|
existing_post = FeedPostFactory(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -109,7 +109,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
new_posts = PostFactory.build_batch(
|
new_posts = FeedPostFactory.build_batch(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -119,7 +119,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
size=5,
|
size=5,
|
||||||
)
|
)
|
||||||
|
|
||||||
last_post = PostFactory.build(
|
last_post = FeedPostFactory.build(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -147,17 +147,17 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
def test_multiple_existing_entries_with_identifier(self):
|
def test_multiple_existing_entries_with_identifier(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
PostFactory.create_batch(
|
FeedPostFactory.create_batch(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule, size=5
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7", rule=rule, size=5
|
||||||
)
|
)
|
||||||
|
|
||||||
new_posts = PostFactory.build_batch(
|
new_posts = FeedPostFactory.build_batch(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now() - timedelta(hours=5),
|
publication_date=timezone.now() - timedelta(hours=5),
|
||||||
rule=rule,
|
rule=rule,
|
||||||
size=5,
|
size=5,
|
||||||
)
|
)
|
||||||
last_post = PostFactory.build(
|
last_post = FeedPostFactory.build(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now() - timedelta(minutes=5),
|
publication_date=timezone.now() - timedelta(minutes=5),
|
||||||
rule=rule,
|
rule=rule,
|
||||||
|
|
@ -189,7 +189,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
def test_duplicate_entries_outside_time_slot(self):
|
def test_duplicate_entries_outside_time_slot(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
|
|
||||||
existing_post = PostFactory(
|
existing_post = FeedPostFactory(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -198,7 +198,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
new_posts = PostFactory.build_batch(
|
new_posts = FeedPostFactory.build_batch(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -207,7 +207,7 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
size=5,
|
size=5,
|
||||||
)
|
)
|
||||||
last_post = PostFactory.build(
|
last_post = FeedPostFactory.build(
|
||||||
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
url="https://www.bbc.co.uk/news/uk-england-birmingham-48339080",
|
||||||
title="Birmingham head teacher threatened over LGBT lessons",
|
title="Birmingham head teacher threatened over LGBT lessons",
|
||||||
body="Google's move to end business ties with Huawei will affect current devices",
|
body="Google's move to end business ties with Huawei will affect current devices",
|
||||||
|
|
@ -235,14 +235,14 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
|
|
||||||
def test_duplicate_entries_in_collected_entries(self):
|
def test_duplicate_entries_in_collected_entries(self):
|
||||||
rule = FeedFactory()
|
rule = FeedFactory()
|
||||||
post_1 = PostFactory.build(
|
post_1 = FeedPostFactory.build(
|
||||||
title="title got updated",
|
title="title got updated",
|
||||||
body="body",
|
body="body",
|
||||||
url="https://bbc.com",
|
url="https://bbc.com",
|
||||||
publication_date=timezone.now(),
|
publication_date=timezone.now(),
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
duplicate_post_1 = PostFactory.build(
|
duplicate_post_1 = FeedPostFactory.build(
|
||||||
title="title got updated",
|
title="title got updated",
|
||||||
body="body",
|
body="body",
|
||||||
url="https://bbc.com",
|
url="https://bbc.com",
|
||||||
|
|
@ -250,11 +250,11 @@ class FeedDuplicateHandlerTestCase(TestCase):
|
||||||
rule=rule,
|
rule=rule,
|
||||||
)
|
)
|
||||||
|
|
||||||
post_2 = PostFactory.build(
|
post_2 = FeedPostFactory.build(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now(),
|
publication_date=timezone.now(),
|
||||||
)
|
)
|
||||||
duplicate_post_2 = PostFactory.build(
|
duplicate_post_2 = FeedPostFactory.build(
|
||||||
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
remote_identifier="28f79ae4-8f9a-11e9-b143-00163ef6bee7",
|
||||||
publication_date=timezone.now() - timedelta(minutes=5),
|
publication_date=timezone.now() - timedelta(minutes=5),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -86,7 +86,7 @@ class RedditBuilderTestCase(TestCase):
|
||||||
def test_update_posts(self):
|
def test_update_posts(self):
|
||||||
subreddit = SubredditFactory()
|
subreddit = SubredditFactory()
|
||||||
existing_post = RedditPostFactory(
|
existing_post = RedditPostFactory(
|
||||||
remote_identifier="hngsj8",
|
remote_identifier="hm0qct",
|
||||||
author="Old author",
|
author="Old author",
|
||||||
title="Old title",
|
title="Old title",
|
||||||
body="Old body",
|
body="Old body",
|
||||||
|
|
@ -108,17 +108,24 @@ class RedditBuilderTestCase(TestCase):
|
||||||
|
|
||||||
existing_post.refresh_from_db()
|
existing_post.refresh_from_db()
|
||||||
|
|
||||||
self.assertEquals(existing_post.remote_identifier, "hngsj8")
|
self.assertEquals(existing_post.remote_identifier, "hm0qct")
|
||||||
self.assertEquals(existing_post.author, "nixcraft")
|
self.assertEquals(existing_post.author, "AutoModerator")
|
||||||
self.assertEquals(existing_post.title, "KeePassXC 2.6.0 released")
|
self.assertEquals(
|
||||||
self.assertEquals(existing_post.body, "")
|
existing_post.title,
|
||||||
|
"Linux Experiences/Rants or Education/Certifications thread - July 06, 2020",
|
||||||
|
)
|
||||||
|
self.assertIn(
|
||||||
|
"This megathread is also to hear opinions from anyone just starting out "
|
||||||
|
"with Linux or those that have used Linux (GNU or otherwise) for a long time.",
|
||||||
|
existing_post.body,
|
||||||
|
)
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
existing_post.publication_date,
|
existing_post.publication_date,
|
||||||
pytz.utc.localize(datetime(2020, 7, 8, 15, 11, 6)),
|
pytz.utc.localize(datetime(2020, 7, 6, 6, 11, 22)),
|
||||||
)
|
)
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
existing_post.url,
|
existing_post.url,
|
||||||
"https://www.reddit.com/r/linux/comments/hngsj8/" "keepassxc_260_released/",
|
"https://www.reddit.com/r/linux/comments/hm0qct/linux_experiencesrants_or_educationcertifications/",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_html_sanitizing(self):
|
def test_html_sanitizing(self):
|
||||||
|
|
@ -219,3 +226,183 @@ class RedditBuilderTestCase(TestCase):
|
||||||
duplicate_post.title,
|
duplicate_post.title,
|
||||||
"Linux Experiences/Rants or Education/Certifications thread - July 06, 2020",
|
"Linux Experiences/Rants or Education/Certifications thread - July 06, 2020",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_image_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((image_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
posts = {post.remote_identifier: post for post in Post.objects.all()}
|
||||||
|
|
||||||
|
self.assertCountEqual(("hr64xh", "hr4bxo", "hr14y5", "hr2fv0"), posts.keys())
|
||||||
|
|
||||||
|
post = posts["hr64xh"]
|
||||||
|
|
||||||
|
title = (
|
||||||
|
"Ya’ll, I just can’t... this is my "
|
||||||
|
"son, Judah. My wife and I have no "
|
||||||
|
"idea how we created such a "
|
||||||
|
"beautiful child."
|
||||||
|
)
|
||||||
|
url = "https://i.redd.it/cm2qybia1va51.jpg"
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
"https://www.reddit.com/r/aww/comments/hr64xh/yall_i_just_cant_this_is_my_son_judah_my_wife_and/",
|
||||||
|
post.url,
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
f"<div><img alt='{title}' src='{url}' loading='lazy' /></div>", post.body
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_external_image_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((external_image_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
posts = {post.remote_identifier: post for post in Post.objects.all()}
|
||||||
|
|
||||||
|
self.assertCountEqual(("hr41am", "huoldn"), posts.keys())
|
||||||
|
|
||||||
|
post = posts["hr41am"]
|
||||||
|
|
||||||
|
url = "http://gfycat.com/thatalivedogwoodclubgall"
|
||||||
|
title = "Excited cows have a new brush!"
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
f"<div><a target='_blank' rel='noopener noreferrer' alt='{title}' href='{url}' class='link'>Direct url</a></div>",
|
||||||
|
post.body,
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
"https://www.reddit.com/r/aww/comments/hr41am/excited_cows_have_a_new_brush/",
|
||||||
|
post.url,
|
||||||
|
)
|
||||||
|
|
||||||
|
post = posts["huoldn"]
|
||||||
|
|
||||||
|
url = "https://i.imgur.com/usfMVUJ.jpg"
|
||||||
|
title = "Novosibirsk Zoo welcomes 16 cobalt-eyed Pallas’s cat kittens"
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
f"<div><img alt='{title}' src='{url}' loading='lazy' /></div>", post.body
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
"https://www.reddit.com/r/aww/comments/huoldn/novosibirsk_zoo_welcomes_16_cobalteyed_pallass/",
|
||||||
|
post.url,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_video_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((video_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
posts = {post.remote_identifier: post for post in Post.objects.all()}
|
||||||
|
|
||||||
|
self.assertCountEqual(("hr32jf", "hr1r00", "hqy0ny", "hr0uzh"), posts.keys())
|
||||||
|
|
||||||
|
post = posts["hr1r00"]
|
||||||
|
|
||||||
|
url = "https://v.redd.it/eyvbxaeqtta51/DASH_480.mp4?source=fallback"
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
post.url,
|
||||||
|
"https://www.reddit.com/r/aww/comments/hr1r00/cool_catt_and_his_clingy_girlfriend/",
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
f"<div><video controls muted><source src='{url}' type='video/mp4' /></video></div>",
|
||||||
|
post.body,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_external_video_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((external_video_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
post = Post.objects.get()
|
||||||
|
|
||||||
|
self.assertEquals(post.remote_identifier, "hulh8k")
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
post.url,
|
||||||
|
"https://www.reddit.com/r/aww/comments/hulh8k/dog_splashing_in_water/",
|
||||||
|
)
|
||||||
|
|
||||||
|
title = "Dog splashing in water"
|
||||||
|
url = "https://gfycat.com/excellentinfantileamericanwigeon"
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
f"<div><a target='_blank' rel='noopener noreferrer' alt='{title}' href='{url}' class='link'>Direct url</a></div>",
|
||||||
|
post.body,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_external_gifv_video_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((external_gifv_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
post = Post.objects.get()
|
||||||
|
|
||||||
|
self.assertEquals(post.remote_identifier, "humdlf")
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
post.url, "https://www.reddit.com/r/aww/comments/humdlf/if_i_fits_i_sits/"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
"<div><video controls muted><source src='https://i.imgur.com/grVh2AG.mp4' type='video/mp4' /></video></div>",
|
||||||
|
post.body,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_link_only_post(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((simple_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
post = Post.objects.get(remote_identifier="hngsj8")
|
||||||
|
|
||||||
|
title = "KeePassXC 2.6.0 released"
|
||||||
|
url = "https://keepassxc.org/blog/2020-07-07-2.6.0-released/"
|
||||||
|
|
||||||
|
self.assertIn(
|
||||||
|
f"<div><a target='_blank' rel='noopener noreferrer' alt='{title}' href='{url}' class='link'>Direct url</a></div>",
|
||||||
|
post.body,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
post.url,
|
||||||
|
"https://www.reddit.com/r/linux/comments/hngsj8/keepassxc_260_released/",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_skip_not_known_post_type(self):
|
||||||
|
builder = RedditBuilder
|
||||||
|
|
||||||
|
subreddit = SubredditFactory()
|
||||||
|
mock_stream = MagicMock(rule=subreddit)
|
||||||
|
|
||||||
|
with builder((unknown_mock, mock_stream)) as builder:
|
||||||
|
builder.save()
|
||||||
|
|
||||||
|
self.assertEquals(Post.objects.count(), 0)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from newsreader.news.collection.choices import RuleTypeChoices
|
from newsreader.news.collection.choices import RuleTypeChoices
|
||||||
from newsreader.news.collection.models import CollectionRule
|
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.factories import SubredditFactory
|
||||||
from newsreader.news.collection.tests.views.base import CollectionRuleViewTestCase
|
from newsreader.news.collection.tests.views.base import CollectionRuleViewTestCase
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory
|
from newsreader.news.core.tests.factories import CategoryFactory
|
||||||
|
|
@ -17,7 +18,7 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
|
|
||||||
self.form_data = {
|
self.form_data = {
|
||||||
"name": "new rule",
|
"name": "new rule",
|
||||||
"url": "https://www.reddit.com/r/aww",
|
"url": f"{REDDIT_API_URL}/r/aww",
|
||||||
"category": str(self.category.pk),
|
"category": str(self.category.pk),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,12 +32,19 @@ class SubRedditCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
rule = CollectionRule.objects.get(name="new rule")
|
rule = CollectionRule.objects.get(name="new rule")
|
||||||
|
|
||||||
self.assertEquals(rule.type, RuleTypeChoices.subreddit)
|
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.timezone, str(pytz.utc))
|
||||||
self.assertEquals(rule.favicon, None)
|
self.assertEquals(rule.favicon, None)
|
||||||
self.assertEquals(rule.category.pk, self.category.pk)
|
self.assertEquals(rule.category.pk, self.category.pk)
|
||||||
self.assertEquals(rule.user.pk, self.user.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):
|
class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
@ -44,7 +52,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
|
|
||||||
self.rule = SubredditFactory(
|
self.rule = SubredditFactory(
|
||||||
name="Python",
|
name="Python",
|
||||||
url=f"{REDDIT_URL}/r/python.json",
|
url=f"{REDDIT_API_URL}/r/python.json",
|
||||||
user=self.user,
|
user=self.user,
|
||||||
category=self.category,
|
category=self.category,
|
||||||
type=RuleTypeChoices.subreddit,
|
type=RuleTypeChoices.subreddit,
|
||||||
|
|
@ -97,7 +105,7 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
self.assertEquals(response.status_code, 404)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
def test_url_change(self):
|
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)
|
response = self.client.post(self.url, self.form_data)
|
||||||
|
|
||||||
|
|
@ -106,8 +114,15 @@ class SubRedditUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
|
||||||
rule = CollectionRule.objects.get(name="aww")
|
rule = CollectionRule.objects.get(name="aww")
|
||||||
|
|
||||||
self.assertEquals(rule.type, RuleTypeChoices.subreddit)
|
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.timezone, str(pytz.utc))
|
||||||
self.assertEquals(rule.favicon, None)
|
self.assertEquals(rule.favicon, None)
|
||||||
self.assertEquals(rule.category.pk, self.category.pk)
|
self.assertEquals(rule.category.pk, self.category.pk)
|
||||||
self.assertEquals(rule.user.pk, self.user.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"))
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class CategoryDetailViewTestCase(TestCase):
|
class CategoryDetailViewTestCase(TestCase):
|
||||||
|
|
@ -116,11 +116,11 @@ class CategoryDetailViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_read_count(self):
|
def test_read_count(self):
|
||||||
category = CategoryFactory(user=self.user)
|
category = CategoryFactory(user=self.user)
|
||||||
unread_rule = CollectionRuleFactory(category=category)
|
unread_rule = FeedFactory(category=category)
|
||||||
read_rule = CollectionRuleFactory(category=category)
|
read_rule = FeedFactory(category=category)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, read=False, rule=unread_rule)
|
FeedPostFactory.create_batch(size=20, read=False, rule=unread_rule)
|
||||||
PostFactory.create_batch(size=20, read=True, rule=read_rule)
|
FeedPostFactory.create_batch(size=20, read=True, rule=read_rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:categories-detail", args=[category.pk])
|
reverse("api:news:core:categories-detail", args=[category.pk])
|
||||||
|
|
@ -139,8 +139,8 @@ class CategoryReadTestCase(TestCase):
|
||||||
def test_category_read(self):
|
def test_category_read(self):
|
||||||
category = CategoryFactory(user=self.user)
|
category = CategoryFactory(user=self.user)
|
||||||
rules = [
|
rules = [
|
||||||
PostFactory.create_batch(size=5, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=5, read=False, rule=rule)
|
||||||
for rule in CollectionRuleFactory.create_batch(size=5, category=category)
|
for rule in FeedFactory.create_batch(size=5, category=category)
|
||||||
]
|
]
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
|
|
@ -165,8 +165,8 @@ class CategoryReadTestCase(TestCase):
|
||||||
|
|
||||||
category = CategoryFactory(user=self.user)
|
category = CategoryFactory(user=self.user)
|
||||||
rules = [
|
rules = [
|
||||||
PostFactory.create_batch(size=5, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=5, read=False, rule=rule)
|
||||||
for rule in CollectionRuleFactory.create_batch(
|
for rule in FeedFactory.create_batch(
|
||||||
size=5, category=category, user=self.user
|
size=5, category=category, user=self.user
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
@ -182,8 +182,8 @@ class CategoryReadTestCase(TestCase):
|
||||||
category = CategoryFactory(user=other_user)
|
category = CategoryFactory(user=other_user)
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
PostFactory.create_batch(size=5, read=False, rule=rule)
|
FeedPostFactory.create_batch(size=5, read=False, rule=rule)
|
||||||
for rule in CollectionRuleFactory.create_batch(
|
for rule in FeedFactory.create_batch(
|
||||||
size=5, category=category, user=other_user
|
size=5, category=category, user=other_user
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ from django.urls import reverse
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class CategoryListViewTestCase(TestCase):
|
class CategoryListViewTestCase(TestCase):
|
||||||
|
|
@ -125,7 +125,7 @@ class NestedCategoryListViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = CollectionRuleFactory.create_batch(size=5, category=category)
|
rules = FeedFactory.create_batch(size=5, category=category)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
||||||
|
|
@ -219,7 +219,7 @@ class NestedCategoryListViewTestCase(TestCase):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = CollectionRuleFactory.create_batch(size=5, category=category)
|
rules = FeedFactory.create_batch(size=5, category=category)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
||||||
|
|
@ -231,7 +231,7 @@ class NestedCategoryListViewTestCase(TestCase):
|
||||||
other_user = UserFactory.create()
|
other_user = UserFactory.create()
|
||||||
|
|
||||||
category = CategoryFactory.create(user=other_user)
|
category = CategoryFactory.create(user=other_user)
|
||||||
rules = CollectionRuleFactory.create_batch(size=5, category=category)
|
rules = FeedFactory.create_batch(size=5, category=category)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
||||||
|
|
@ -242,9 +242,9 @@ class NestedCategoryListViewTestCase(TestCase):
|
||||||
def test_ordering(self):
|
def test_ordering(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = [
|
rules = [
|
||||||
CollectionRuleFactory.create(category=category, name="Durp"),
|
FeedFactory.create(category=category, name="Durp"),
|
||||||
CollectionRuleFactory.create(category=category, name="Slurp"),
|
FeedFactory.create(category=category, name="Slurp"),
|
||||||
CollectionRuleFactory.create(category=category, name="Burp"),
|
FeedFactory.create(category=category, name="Burp"),
|
||||||
]
|
]
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
|
|
@ -261,13 +261,13 @@ class NestedCategoryListViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_only_rules_from_category_are_returned(self):
|
def test_only_rules_from_category_are_returned(self):
|
||||||
other_category = CategoryFactory(user=self.user)
|
other_category = CategoryFactory(user=self.user)
|
||||||
CollectionRuleFactory.create_batch(size=5, category=other_category)
|
FeedFactory.create_batch(size=5, category=other_category)
|
||||||
|
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = [
|
rules = [
|
||||||
CollectionRuleFactory.create(category=category, name="Durp"),
|
FeedFactory.create(category=category, name="Durp"),
|
||||||
CollectionRuleFactory.create(category=category, name="Slurp"),
|
FeedFactory.create(category=category, name="Slurp"),
|
||||||
CollectionRuleFactory.create(category=category, name="Burp"),
|
FeedFactory.create(category=category, name="Burp"),
|
||||||
]
|
]
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
|
|
@ -291,8 +291,8 @@ class NestedCategoryPostView(TestCase):
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = {
|
rules = {
|
||||||
rule.pk: PostFactory.create_batch(size=5, rule=rule)
|
rule.pk: FeedPostFactory.create_batch(size=5, rule=rule)
|
||||||
for rule in CollectionRuleFactory.create_batch(
|
for rule in FeedFactory.create_batch(
|
||||||
size=5, category=category, user=self.user
|
size=5, category=category, user=self.user
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -327,9 +327,7 @@ class NestedCategoryPostView(TestCase):
|
||||||
|
|
||||||
def test_no_posts(self):
|
def test_no_posts(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rules = CollectionRuleFactory.create_batch(
|
rules = FeedFactory.create_batch(size=5, user=self.user, category=category)
|
||||||
size=5, user=self.user, category=category
|
|
||||||
)
|
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:categories-nested-posts", kwargs={"pk": category.pk})
|
reverse("api:news:core:categories-nested-posts", kwargs={"pk": category.pk})
|
||||||
|
|
@ -427,25 +425,23 @@ class NestedCategoryPostView(TestCase):
|
||||||
def test_ordering(self):
|
def test_ordering(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
|
|
||||||
bbc_rule = CollectionRuleFactory.create(
|
bbc_rule = FeedFactory.create(name="BBC", category=category, user=self.user)
|
||||||
name="BBC", category=category, user=self.user
|
guardian_rule = FeedFactory.create(
|
||||||
)
|
|
||||||
guardian_rule = CollectionRuleFactory.create(
|
|
||||||
name="The Guardian", category=category, user=self.user
|
name="The Guardian", category=category, user=self.user
|
||||||
)
|
)
|
||||||
reuters_rule = CollectionRuleFactory.create(
|
reuters_rule = FeedFactory.create(
|
||||||
name="Reuters", category=category, user=self.user
|
name="Reuters", category=category, user=self.user
|
||||||
)
|
)
|
||||||
|
|
||||||
reuters_rule = [
|
reuters_rule = [
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="Second Reuters post",
|
title="Second Reuters post",
|
||||||
rule=reuters_rule,
|
rule=reuters_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="First Reuters post",
|
title="First Reuters post",
|
||||||
rule=reuters_rule,
|
rule=reuters_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
|
|
@ -455,14 +451,14 @@ class NestedCategoryPostView(TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
guardian_posts = [
|
guardian_posts = [
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="Second Guardian post",
|
title="Second Guardian post",
|
||||||
rule=guardian_rule,
|
rule=guardian_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="First Guardian post",
|
title="First Guardian post",
|
||||||
rule=guardian_rule,
|
rule=guardian_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
|
|
@ -472,14 +468,14 @@ class NestedCategoryPostView(TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
bbc_posts = [
|
bbc_posts = [
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="Second BBC post",
|
title="Second BBC post",
|
||||||
rule=bbc_rule,
|
rule=bbc_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory.create(
|
FeedPostFactory.create(
|
||||||
title="First BBC post",
|
title="First BBC post",
|
||||||
rule=bbc_rule,
|
rule=bbc_rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
|
|
@ -509,19 +505,19 @@ class NestedCategoryPostView(TestCase):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
other_category = CategoryFactory.create(user=self.user)
|
other_category = CategoryFactory.create(user=self.user)
|
||||||
|
|
||||||
guardian_rule = CollectionRuleFactory.create(
|
guardian_rule = FeedFactory.create(
|
||||||
name="BBC", category=category, user=self.user
|
name="BBC", category=category, user=self.user
|
||||||
)
|
)
|
||||||
other_rule = CollectionRuleFactory.create(name="The Guardian", user=self.user)
|
other_rule = FeedFactory.create(name="The Guardian", user=self.user)
|
||||||
|
|
||||||
guardian_posts = [
|
guardian_posts = [
|
||||||
PostFactory.create(rule=guardian_rule),
|
FeedPostFactory.create(rule=guardian_rule),
|
||||||
PostFactory.create(rule=guardian_rule),
|
FeedPostFactory.create(rule=guardian_rule),
|
||||||
]
|
]
|
||||||
|
|
||||||
other_posts = [
|
other_posts = [
|
||||||
PostFactory.create(rule=other_rule),
|
FeedPostFactory.create(rule=other_rule),
|
||||||
PostFactory.create(rule=other_rule),
|
FeedPostFactory.create(rule=other_rule),
|
||||||
]
|
]
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
|
|
@ -538,10 +534,10 @@ class NestedCategoryPostView(TestCase):
|
||||||
|
|
||||||
def test_unread_posts(self):
|
def test_unread_posts(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rule = CollectionRuleFactory(category=category)
|
rule = FeedFactory(category=category)
|
||||||
|
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse(
|
reverse(
|
||||||
|
|
@ -561,10 +557,10 @@ class NestedCategoryPostView(TestCase):
|
||||||
|
|
||||||
def test_read_posts(self):
|
def test_read_posts(self):
|
||||||
category = CategoryFactory.create(user=self.user)
|
category = CategoryFactory.create(user=self.user)
|
||||||
rule = CollectionRuleFactory(category=category)
|
rule = FeedFactory(category=category)
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=20, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse(
|
reverse(
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class PostDetailViewTestCase(TestCase):
|
class PostDetailViewTestCase(TestCase):
|
||||||
|
|
@ -14,10 +14,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -43,10 +41,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], "Not found.")
|
self.assertEquals(data["detail"], "Not found.")
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -57,10 +53,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||||
|
|
||||||
def test_patch(self):
|
def test_patch(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(title="This is clickbait for sure", rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(title="This is clickbait for sure", rule=rule)
|
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
@ -73,10 +67,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["title"], "This title is very accurate")
|
self.assertEquals(data["title"], "This title is very accurate")
|
||||||
|
|
||||||
def test_identifier_cannot_be_changed(self):
|
def test_identifier_cannot_be_changed(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(title="This is clickbait for sure", rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(title="This is clickbait for sure", rule=rule)
|
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
@ -89,13 +81,9 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["id"], post.pk)
|
self.assertEquals(data["id"], post.pk)
|
||||||
|
|
||||||
def test_rule_cannot_be_changed(self):
|
def test_rule_cannot_be_changed(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
new_rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
)
|
post = FeedPostFactory(title="This is clickbait for sure", rule=rule)
|
||||||
new_rule = CollectionRuleFactory(
|
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
|
||||||
)
|
|
||||||
post = PostFactory(title="This is clickbait for sure", rule=rule)
|
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
@ -115,10 +103,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertTrue(data["rule"], rule.pk)
|
self.assertTrue(data["rule"], rule.pk)
|
||||||
|
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(title="This is clickbait for sure", rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(title="This is clickbait for sure", rule=rule)
|
|
||||||
|
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
@ -131,10 +117,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["title"], "This title is very accurate")
|
self.assertEquals(data["title"], "This title is very accurate")
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.delete(
|
response = self.client.delete(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -147,8 +131,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
def test_post_with_unauthenticated_user_without_category(self):
|
def test_post_with_unauthenticated_user_without_category(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(user=self.user, category=None)
|
rule = FeedFactory(user=self.user, category=None)
|
||||||
post = PostFactory(rule=rule)
|
post = FeedPostFactory(rule=rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -159,10 +143,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
def test_post_with_unauthenticated_user_with_category(self):
|
def test_post_with_unauthenticated_user_with_category(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -172,8 +154,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_post_with_unauthorized_user_without_category(self):
|
def test_post_with_unauthorized_user_without_category(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(user=other_user, category=None)
|
rule = FeedFactory(user=other_user, category=None)
|
||||||
post = PostFactory(rule=rule)
|
post = FeedPostFactory(rule=rule)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -183,10 +165,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_post_with_unauthorized_user_with_category(self):
|
def test_post_with_unauthorized_user_with_category(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=other_user, category=CategoryFactory(user=other_user))
|
||||||
user=other_user, category=CategoryFactory(user=other_user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -196,10 +176,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
|
|
||||||
def test_post_with_different_user_for_category_and_rule(self):
|
def test_post_with_different_user_for_category_and_rule(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=other_user))
|
||||||
user=self.user, category=CategoryFactory(user=other_user)
|
post = FeedPostFactory(rule=rule)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk])
|
reverse("api:news:core:posts-detail", args=[post.pk])
|
||||||
|
|
@ -208,10 +186,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 403)
|
||||||
|
|
||||||
def test_mark_read(self):
|
def test_mark_read(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule, read=False)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule, read=False)
|
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
@ -224,10 +200,8 @@ class PostDetailViewTestCase(TestCase):
|
||||||
self.assertEquals(data["read"], True)
|
self.assertEquals(data["read"], True)
|
||||||
|
|
||||||
def test_mark_unread(self):
|
def test_mark_unread(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
post = FeedPostFactory(rule=rule, read=True)
|
||||||
)
|
|
||||||
post = PostFactory(rule=rule, read=True)
|
|
||||||
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
reverse("api:news:core:posts-detail", args=[post.pk]),
|
reverse("api:news:core:posts-detail", args=[post.pk]),
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ from django.urls import reverse
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
from newsreader.accounts.tests.factories import UserFactory
|
||||||
from newsreader.news.collection.tests.factories import CollectionRuleFactory
|
from newsreader.news.collection.tests.factories import FeedFactory
|
||||||
from newsreader.news.core.tests.factories import CategoryFactory, PostFactory
|
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||||
|
|
||||||
|
|
||||||
class PostListViewTestCase(TestCase):
|
class PostListViewTestCase(TestCase):
|
||||||
|
|
@ -16,10 +16,8 @@ class PostListViewTestCase(TestCase):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||||
)
|
|
||||||
PostFactory.create_batch(size=3, rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -30,26 +28,24 @@ class PostListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["count"], 3)
|
self.assertEquals(data["count"], 3)
|
||||||
|
|
||||||
def test_ordering(self):
|
def test_ordering(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
posts = [
|
posts = [
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the first post",
|
title="I'm the first post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the second post",
|
title="I'm the second post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PostFactory(
|
FeedPostFactory(
|
||||||
title="I'm the third post",
|
title="I'm the third post",
|
||||||
rule=rule,
|
rule=rule,
|
||||||
publication_date=datetime.combine(
|
publication_date=datetime.combine(
|
||||||
|
|
@ -71,10 +67,8 @@ class PostListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
||||||
|
|
||||||
def test_pagination_count(self):
|
def test_pagination_count(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
FeedPostFactory.create_batch(size=80, rule=rule)
|
||||||
)
|
|
||||||
PostFactory.create_batch(size=80, rule=rule)
|
|
||||||
page_size = 50
|
page_size = 50
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"), {"count": 50})
|
response = self.client.get(reverse("api:news:core:posts-list"), {"count": 50})
|
||||||
|
|
@ -126,7 +120,7 @@ class PostListViewTestCase(TestCase):
|
||||||
def test_posts_with_unauthenticated_user_without_category(self):
|
def test_posts_with_unauthenticated_user_without_category(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
PostFactory.create_batch(size=3, rule=CollectionRuleFactory(user=self.user))
|
FeedPostFactory.create_batch(size=3, rule=FeedFactory(user=self.user))
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
|
|
||||||
|
|
@ -137,8 +131,8 @@ class PostListViewTestCase(TestCase):
|
||||||
|
|
||||||
category = CategoryFactory(user=self.user)
|
category = CategoryFactory(user=self.user)
|
||||||
|
|
||||||
PostFactory.create_batch(
|
FeedPostFactory.create_batch(
|
||||||
size=3, rule=CollectionRuleFactory(user=self.user, category=category)
|
size=3, rule=FeedFactory(user=self.user, category=category)
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
|
|
@ -148,8 +142,8 @@ class PostListViewTestCase(TestCase):
|
||||||
def test_posts_with_unauthorized_user_without_category(self):
|
def test_posts_with_unauthorized_user_without_category(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(user=other_user, category=None)
|
rule = FeedFactory(user=other_user, category=None)
|
||||||
PostFactory.create_batch(size=3, rule=rule)
|
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -162,8 +156,8 @@ class PostListViewTestCase(TestCase):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
category = CategoryFactory(user=other_user)
|
category = CategoryFactory(user=other_user)
|
||||||
|
|
||||||
PostFactory.create_batch(
|
FeedPostFactory.create_batch(
|
||||||
size=3, rule=CollectionRuleFactory(user=other_user, category=category)
|
size=3, rule=FeedFactory(user=other_user, category=category)
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
|
|
@ -178,10 +172,8 @@ class PostListViewTestCase(TestCase):
|
||||||
def test_posts_with_authorized_rule_unauthorized_category(self):
|
def test_posts_with_authorized_rule_unauthorized_category(self):
|
||||||
other_user = UserFactory()
|
other_user = UserFactory()
|
||||||
|
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=other_user))
|
||||||
user=self.user, category=CategoryFactory(user=other_user)
|
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||||
)
|
|
||||||
PostFactory.create_batch(size=3, rule=rule)
|
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -192,8 +184,8 @@ class PostListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["count"], 0)
|
self.assertEquals(data["count"], 0)
|
||||||
|
|
||||||
def test_posts_with_authorized_user_without_category(self):
|
def test_posts_with_authorized_user_without_category(self):
|
||||||
rule = CollectionRuleFactory(user=self.user, category=None)
|
rule = FeedFactory(user=self.user, category=None)
|
||||||
PostFactory.create_batch(size=3, rule=rule)
|
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||||
|
|
||||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
@ -204,12 +196,10 @@ class PostListViewTestCase(TestCase):
|
||||||
self.assertEquals(data["count"], 3)
|
self.assertEquals(data["count"], 3)
|
||||||
|
|
||||||
def test_unread_posts(self):
|
def test_unread_posts(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-list"), {"read": "false"}
|
reverse("api:news:core:posts-list"), {"read": "false"}
|
||||||
|
|
@ -225,12 +215,10 @@ class PostListViewTestCase(TestCase):
|
||||||
self.assertEquals(post["read"], False)
|
self.assertEquals(post["read"], False)
|
||||||
|
|
||||||
def test_read_posts(self):
|
def test_read_posts(self):
|
||||||
rule = CollectionRuleFactory(
|
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||||
user=self.user, category=CategoryFactory(user=self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
PostFactory.create_batch(size=20, rule=rule, read=False)
|
FeedPostFactory.create_batch(size=20, rule=rule, read=False)
|
||||||
PostFactory.create_batch(size=10, rule=rule, read=True)
|
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("api:news:core:posts-list"), {"read": "true"}
|
reverse("api:news:core:posts-list"), {"read": "true"}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import factory.fuzzy
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from newsreader.accounts.tests.factories import UserFactory
|
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
|
from newsreader.news.core.models import Category, Post
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -33,9 +33,12 @@ class PostFactory(factory.django.DjangoModelFactory):
|
||||||
model = Post
|
model = Post
|
||||||
|
|
||||||
|
|
||||||
|
class FeedPostFactory(PostFactory):
|
||||||
|
rule = factory.SubFactory("newsreader.news.collection.tests.factories.FeedFactory")
|
||||||
|
|
||||||
|
|
||||||
class RedditPostFactory(PostFactory):
|
class RedditPostFactory(PostFactory):
|
||||||
remote_identifier = factory.Faker("uuid4")
|
url = factory.fuzzy.FuzzyText(length=10, prefix=f"{REDDIT_API_URL}/")
|
||||||
url = factory.fuzzy.FuzzyText(length=10, prefix=f"{REDDIT_URL}/")
|
|
||||||
rule = factory.SubFactory(
|
rule = factory.SubFactory(
|
||||||
"newsreader.news.collection.tests.factories.SubredditFactory"
|
"newsreader.news.collection.tests.factories.SubredditFactory"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -68,14 +68,9 @@
|
||||||
margin: 20px 0 5px 0;
|
margin: 20px 0 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& img {
|
& img, video {
|
||||||
padding: 10px 10px 30px 10px;
|
padding: 10px 0;
|
||||||
|
max-width: 100%;
|
||||||
max-width: 70%;
|
|
||||||
width: inherit;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue