import datetime
import email
import urllib.parse
from django.test import TestCase
from django.urls import reverse
from bookmarks.tests.helpers import BookmarkFactoryMixin
from bookmarks.models import FeedToken, User
from bookmarks.feeds import sanitize
def rfc2822_date(date):
if not isinstance(date, datetime.datetime):
date = datetime.datetime.combine(date, datetime.time())
return email.utils.format_datetime(date)
class FeedsTestCase(TestCase, BookmarkFactoryMixin):
def setUp(self) -> None:
user = self.get_or_create_test_user()
self.client.force_login(user)
self.token = FeedToken.objects.get_or_create(user=user)[0]
def test_all_returns_404_for_unknown_feed_token(self):
response = self.client.get(reverse("bookmarks:feeds.all", args=["foo"]))
self.assertEqual(response.status_code, 404)
def test_all_metadata(self):
feed_url = reverse("bookmarks:feeds.all", args=[self.token.key])
response = self.client.get(feed_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
All bookmarks")
self.assertContains(response, "All bookmarks")
self.assertContains(response, f"http://testserver{feed_url}")
self.assertContains(
response, f''
)
def test_all_returns_all_unarchived_bookmarks(self):
bookmarks = [
self.setup_bookmark(description="test description"),
self.setup_bookmark(website_description="test website description"),
self.setup_bookmark(unread=True, description="test description"),
]
self.setup_bookmark(is_archived=True)
self.setup_bookmark(is_archived=True)
self.setup_bookmark(is_archived=True)
response = self.client.get(
reverse("bookmarks:feeds.all", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "- ", count=len(bookmarks))
for bookmark in bookmarks:
expected_item = (
"
- "
f"{bookmark.resolved_title}"
f"{bookmark.url}"
f"{bookmark.resolved_description}"
f"{rfc2822_date(bookmark.date_added)}"
f"{bookmark.url}"
"
"
)
self.assertContains(response, expected_item, count=1)
def test_all_with_query(self):
tag1 = self.setup_tag()
bookmark1 = self.setup_bookmark()
bookmark2 = self.setup_bookmark(tags=[tag1])
bookmark3 = self.setup_bookmark(tags=[tag1])
self.setup_bookmark()
self.setup_bookmark()
self.setup_bookmark()
feed_url = reverse("bookmarks:feeds.all", args=[self.token.key])
url = feed_url + f"?q={bookmark1.title}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "- ", count=1)
self.assertContains(response, f"{bookmark1.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote("#" + tag1.name)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=2)
self.assertContains(response, f"{bookmark2.url}", count=1)
self.assertContains(response, f"{bookmark3.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote(f"#{tag1.name} {bookmark2.title}")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=1)
self.assertContains(response, f"{bookmark2.url}", count=1)
def test_all_returns_only_user_owned_bookmarks(self):
other_user = User.objects.create_user(
"otheruser", "otheruser@example.com", "password123"
)
self.setup_bookmark(unread=True, user=other_user)
self.setup_bookmark(unread=True, user=other_user)
self.setup_bookmark(unread=True, user=other_user)
response = self.client.get(
reverse("bookmarks:feeds.all", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=0)
def test_strip_control_characters(self):
self.setup_bookmark(
title="test\n\r\t\0\x08title", description="test\n\r\t\0\x08description"
)
response = self.client.get(
reverse("bookmarks:feeds.all", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=1)
self.assertContains(response, f"test\n\r\ttitle", count=1)
self.assertContains(
response, f"test\n\r\tdescription", count=1
)
def test_sanitize_with_none_text(self):
self.assertEqual("", sanitize(None))
def test_unread_returns_404_for_unknown_feed_token(self):
response = self.client.get(reverse("bookmarks:feeds.unread", args=["foo"]))
self.assertEqual(response.status_code, 404)
def test_unread_metadata(self):
feed_url = reverse("bookmarks:feeds.unread", args=[self.token.key])
response = self.client.get(feed_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Unread bookmarks")
self.assertContains(response, "All unread bookmarks")
self.assertContains(response, f"http://testserver{feed_url}")
self.assertContains(
response, f''
)
def test_unread_returns_unread_and_unarchived_bookmarks(self):
self.setup_bookmark(unread=False)
self.setup_bookmark(unread=False)
self.setup_bookmark(unread=False)
self.setup_bookmark(unread=True, is_archived=True)
self.setup_bookmark(unread=True, is_archived=True)
self.setup_bookmark(unread=False, is_archived=True)
unread_bookmarks = [
self.setup_bookmark(unread=True, description="test description"),
self.setup_bookmark(
unread=True, website_description="test website description"
),
self.setup_bookmark(unread=True, description="test description"),
]
response = self.client.get(
reverse("bookmarks:feeds.unread", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=len(unread_bookmarks))
for bookmark in unread_bookmarks:
expected_item = (
"
- "
f"{bookmark.resolved_title}"
f"{bookmark.url}"
f"{bookmark.resolved_description}"
f"{rfc2822_date(bookmark.date_added)}"
f"{bookmark.url}"
"
"
)
self.assertContains(response, expected_item, count=1)
def test_unread_with_query(self):
tag1 = self.setup_tag()
bookmark1 = self.setup_bookmark(unread=True)
bookmark2 = self.setup_bookmark(unread=True, tags=[tag1])
bookmark3 = self.setup_bookmark(unread=True, tags=[tag1])
self.setup_bookmark(unread=True)
self.setup_bookmark(unread=True)
self.setup_bookmark(unread=True)
feed_url = reverse("bookmarks:feeds.unread", args=[self.token.key])
url = feed_url + f"?q={bookmark1.title}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "- ", count=1)
self.assertContains(response, f"{bookmark1.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote("#" + tag1.name)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=2)
self.assertContains(response, f"{bookmark2.url}", count=1)
self.assertContains(response, f"{bookmark3.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote(f"#{tag1.name} {bookmark2.title}")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=1)
self.assertContains(response, f"{bookmark2.url}", count=1)
def test_unread_returns_only_user_owned_bookmarks(self):
other_user = User.objects.create_user(
"otheruser", "otheruser@example.com", "password123"
)
self.setup_bookmark(unread=True, user=other_user)
self.setup_bookmark(unread=True, user=other_user)
self.setup_bookmark(unread=True, user=other_user)
response = self.client.get(
reverse("bookmarks:feeds.unread", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=0)
def test_shared_returns_404_for_unknown_feed_token(self):
response = self.client.get(reverse("bookmarks:feeds.shared", args=["foo"]))
self.assertEqual(response.status_code, 404)
def test_shared_metadata(self):
feed_url = reverse("bookmarks:feeds.shared", args=[self.token.key])
response = self.client.get(feed_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Shared bookmarks")
self.assertContains(response, "All shared bookmarks")
self.assertContains(response, f"http://testserver{feed_url}")
self.assertContains(
response, f''
)
def test_shared_returns_shared_bookmarks_only(self):
user1 = self.setup_user(enable_sharing=True)
user2 = self.setup_user(enable_sharing=False)
self.setup_bookmark()
self.setup_bookmark(shared=False, user=user1)
self.setup_bookmark(shared=True, user=user2)
shared_bookmarks = [
self.setup_bookmark(shared=True, user=user1, description="test"),
self.setup_bookmark(shared=True, user=user1, description="test"),
self.setup_bookmark(shared=True, user=user1, description="test"),
]
response = self.client.get(
reverse("bookmarks:feeds.shared", args=[self.token.key])
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=len(shared_bookmarks))
for bookmark in shared_bookmarks:
expected_item = (
"
- "
f"{bookmark.resolved_title}"
f"{bookmark.url}"
f"{bookmark.resolved_description}"
f"{rfc2822_date(bookmark.date_added)}"
f"{bookmark.url}"
"
"
)
self.assertContains(response, expected_item, count=1)
def test_shared_with_query(self):
user = self.setup_user(enable_sharing=True)
tag1 = self.setup_tag(user=user)
bookmark1 = self.setup_bookmark(shared=True, user=user)
bookmark2 = self.setup_bookmark(shared=True, tags=[tag1], user=user)
bookmark3 = self.setup_bookmark(shared=True, tags=[tag1], user=user)
self.setup_bookmark(shared=True, user=user)
self.setup_bookmark(shared=True, user=user)
self.setup_bookmark(shared=True, user=user)
feed_url = reverse("bookmarks:feeds.shared", args=[self.token.key])
url = feed_url + f"?q={bookmark1.title}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "- ", count=1)
self.assertContains(response, f"{bookmark1.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote("#" + tag1.name)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=2)
self.assertContains(response, f"{bookmark2.url}", count=1)
self.assertContains(response, f"{bookmark3.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote(f"#{tag1.name} {bookmark2.title}")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=1)
self.assertContains(response, f"{bookmark2.url}", count=1)
def test_public_shared_does_not_require_auth(self):
response = self.client.get(reverse("bookmarks:feeds.public_shared"))
self.assertEqual(response.status_code, 200)
def test_public_shared_metadata(self):
feed_url = reverse("bookmarks:feeds.public_shared")
response = self.client.get(feed_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Public shared bookmarks")
self.assertContains(
response, "All public shared bookmarks"
)
self.assertContains(response, f"http://testserver{feed_url}")
self.assertContains(
response, f''
)
def test_public_shared_returns_publicly_shared_bookmarks_only(self):
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
user2 = self.setup_user(enable_sharing=True)
user3 = self.setup_user(enable_sharing=False)
self.setup_bookmark()
self.setup_bookmark(shared=False, user=user1)
self.setup_bookmark(shared=False, user=user2)
self.setup_bookmark(shared=True, user=user2)
self.setup_bookmark(shared=True, user=user3)
public_shared_bookmarks = [
self.setup_bookmark(shared=True, user=user1, description="test"),
self.setup_bookmark(shared=True, user=user1, description="test"),
self.setup_bookmark(shared=True, user=user1, description="test"),
]
response = self.client.get(reverse("bookmarks:feeds.public_shared"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=len(public_shared_bookmarks))
for bookmark in public_shared_bookmarks:
expected_item = (
"
- "
f"{bookmark.resolved_title}"
f"{bookmark.url}"
f"{bookmark.resolved_description}"
f"{rfc2822_date(bookmark.date_added)}"
f"{bookmark.url}"
"
"
)
self.assertContains(response, expected_item, count=1)
def test_public_shared_with_query(self):
user = self.setup_user(enable_sharing=True, enable_public_sharing=True)
tag1 = self.setup_tag(user=user)
bookmark1 = self.setup_bookmark(shared=True, user=user)
bookmark2 = self.setup_bookmark(shared=True, tags=[tag1], user=user)
bookmark3 = self.setup_bookmark(shared=True, tags=[tag1], user=user)
self.setup_bookmark(shared=True, user=user)
self.setup_bookmark(shared=True, user=user)
self.setup_bookmark(shared=True, user=user)
feed_url = reverse("bookmarks:feeds.shared", args=[self.token.key])
url = feed_url + f"?q={bookmark1.title}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "- ", count=1)
self.assertContains(response, f"{bookmark1.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote("#" + tag1.name)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=2)
self.assertContains(response, f"{bookmark2.url}", count=1)
self.assertContains(response, f"{bookmark3.url}", count=1)
url = feed_url + "?q=" + urllib.parse.quote(f"#{tag1.name} {bookmark2.title}")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "
- ", count=1)
self.assertContains(response, f"{bookmark2.url}", count=1)