2023-09-01 20:48:21 +00:00
|
|
|
import urllib.parse
|
2022-08-04 17:37:16 +00:00
|
|
|
from typing import List
|
|
|
|
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
from django.test import TestCase
|
|
|
|
from django.urls import reverse
|
|
|
|
|
2023-10-01 19:22:44 +00:00
|
|
|
from bookmarks.models import Bookmark, BookmarkSearch, Tag, UserProfile
|
|
|
|
from bookmarks.tests.helpers import BookmarkFactoryMixin, HtmlTestMixin
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
|
2023-09-26 06:34:43 +00:00
|
|
|
class BookmarkSharedViewTestCase(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def authenticate(self) -> None:
|
2022-08-04 17:37:16 +00:00
|
|
|
user = self.get_or_create_test_user()
|
|
|
|
self.client.force_login(user)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
def assertBookmarkCount(
|
|
|
|
self, html: str, bookmark: Bookmark, count: int, link_target: str = "_blank"
|
|
|
|
):
|
2022-08-04 17:37:16 +00:00
|
|
|
self.assertInHTML(
|
2023-08-24 17:11:36 +00:00
|
|
|
f'<a href="{bookmark.url}" target="{link_target}" rel="noopener">{bookmark.resolved_title}</a>',
|
2024-01-27 10:29:16 +00:00
|
|
|
html,
|
|
|
|
count=count,
|
2022-08-04 17:37:16 +00:00
|
|
|
)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
def assertVisibleBookmarks(
|
|
|
|
self, response, bookmarks: List[Bookmark], link_target: str = "_blank"
|
|
|
|
):
|
2023-10-01 19:22:44 +00:00
|
|
|
soup = self.make_soup(response.content.decode())
|
2024-01-27 10:29:16 +00:00
|
|
|
bookmark_list = soup.select_one(
|
|
|
|
f'ul.bookmark-list[data-bookmarks-total="{len(bookmarks)}"]'
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertIsNotNone(bookmark_list)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
bookmark_items = bookmark_list.select("li[ld-bookmark-item]")
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(len(bookmark_items), len(bookmarks))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
for bookmark in bookmarks:
|
2023-10-01 19:22:44 +00:00
|
|
|
bookmark_item = bookmark_list.select_one(
|
2024-01-27 10:29:16 +00:00
|
|
|
f'li[ld-bookmark-item] a[href="{bookmark.url}"][target="{link_target}"]'
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertIsNotNone(bookmark_item)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
def assertInvisibleBookmarks(
|
|
|
|
self, response, bookmarks: List[Bookmark], link_target: str = "_blank"
|
|
|
|
):
|
2023-10-01 19:22:44 +00:00
|
|
|
soup = self.make_soup(response.content.decode())
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
for bookmark in bookmarks:
|
2023-10-01 19:22:44 +00:00
|
|
|
bookmark_item = soup.select_one(
|
2024-01-27 10:29:16 +00:00
|
|
|
f'li[ld-bookmark-item] a[href="{bookmark.url}"][target="{link_target}"]'
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertIsNone(bookmark_item)
|
|
|
|
|
|
|
|
def assertVisibleTags(self, response, tags: List[Tag]):
|
|
|
|
soup = self.make_soup(response.content.decode())
|
2024-01-27 10:29:16 +00:00
|
|
|
tag_cloud = soup.select_one("div.tag-cloud")
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertIsNotNone(tag_cloud)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
tag_items = tag_cloud.select("a[data-is-tag-item]")
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(len(tag_items), len(tags))
|
|
|
|
|
|
|
|
tag_item_names = [tag_item.text.strip() for tag_item in tag_items]
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
for tag in tags:
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertTrue(tag.name in tag_item_names)
|
|
|
|
|
|
|
|
def assertInvisibleTags(self, response, tags: List[Tag]):
|
|
|
|
soup = self.make_soup(response.content.decode())
|
2024-01-27 10:29:16 +00:00
|
|
|
tag_items = soup.select("a[data-is-tag-item]")
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
tag_item_names = [tag_item.text.strip() for tag_item in tag_items]
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
for tag in tags:
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertFalse(tag.name in tag_item_names)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
def assertVisibleUserOptions(self, response, users: List[User]):
|
|
|
|
html = response.content.decode()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
user_options = ['<option value="" selected="">Everyone</option>']
|
2022-08-04 17:37:16 +00:00
|
|
|
for user in users:
|
2024-01-27 10:29:16 +00:00
|
|
|
user_options.append(
|
|
|
|
f'<option value="{user.username}">{user.username}</option>'
|
|
|
|
)
|
|
|
|
user_select_html = f"""
|
2023-09-01 20:48:21 +00:00
|
|
|
<select name="user" class="form-select" required="" id="id_user">
|
|
|
|
{''.join(user_options)}
|
|
|
|
</select>
|
2024-01-27 10:29:16 +00:00
|
|
|
"""
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-09-01 20:48:21 +00:00
|
|
|
self.assertInHTML(user_select_html, html)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-09-01 20:48:21 +00:00
|
|
|
def assertEditLink(self, response, url):
|
|
|
|
html = response.content.decode()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertInHTML(
|
|
|
|
f"""
|
2023-09-01 20:48:21 +00:00
|
|
|
<a href="{url}">Edit</a>
|
2024-01-27 10:29:16 +00:00
|
|
|
""",
|
|
|
|
html,
|
|
|
|
)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
def test_should_list_shared_bookmarks_from_all_users_that_have_sharing_enabled(
|
|
|
|
self,
|
|
|
|
):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
user3 = self.setup_user(enable_sharing=True)
|
|
|
|
user4 = self.setup_user(enable_sharing=False)
|
|
|
|
|
|
|
|
visible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=True, user=user1),
|
|
|
|
self.setup_bookmark(shared=True, user=user2),
|
|
|
|
self.setup_bookmark(shared=True, user=user3),
|
|
|
|
]
|
|
|
|
invisible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=False, user=user1),
|
|
|
|
self.setup_bookmark(shared=False, user=user2),
|
|
|
|
self.setup_bookmark(shared=False, user=user3),
|
|
|
|
self.setup_bookmark(shared=True, user=user4),
|
|
|
|
]
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks)
|
|
|
|
self.assertInvisibleBookmarks(response, invisible_bookmarks)
|
|
|
|
|
|
|
|
def test_should_list_shared_bookmarks_from_selected_user(self):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
user3 = self.setup_user(enable_sharing=True)
|
|
|
|
|
|
|
|
visible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=True, user=user1),
|
|
|
|
]
|
|
|
|
invisible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=True, user=user2),
|
|
|
|
self.setup_bookmark(shared=True, user=user3),
|
|
|
|
]
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?user=" + user1.username
|
2022-08-04 17:37:16 +00:00
|
|
|
response = self.client.get(url)
|
|
|
|
|
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks)
|
|
|
|
self.assertInvisibleBookmarks(response, invisible_bookmarks)
|
|
|
|
|
|
|
|
def test_should_list_bookmarks_matching_query(self):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user = self.setup_user(enable_sharing=True)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
visible_bookmarks = self.setup_numbered_bookmarks(
|
|
|
|
3, shared=True, user=user, prefix="foo"
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
invisible_bookmarks = self.setup_numbered_bookmarks(3, shared=True, user=user)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared") + "?q=foo")
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks)
|
|
|
|
self.assertInvisibleBookmarks(response, invisible_bookmarks)
|
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def test_should_list_only_publicly_shared_bookmarks_without_login(self):
|
|
|
|
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
visible_bookmarks = self.setup_numbered_bookmarks(
|
|
|
|
3, shared=True, user=user1, prefix="user1"
|
|
|
|
)
|
|
|
|
invisible_bookmarks = self.setup_numbered_bookmarks(
|
|
|
|
3, shared=True, user=user2, prefix="user2"
|
|
|
|
)
|
2023-08-14 22:20:52 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2023-08-14 22:20:52 +00:00
|
|
|
|
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks)
|
|
|
|
self.assertInvisibleBookmarks(response, invisible_bookmarks)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
def test_should_list_tags_for_shared_bookmarks_from_all_users_that_have_sharing_enabled(
|
|
|
|
self,
|
|
|
|
):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
user3 = self.setup_user(enable_sharing=True)
|
|
|
|
user4 = self.setup_user(enable_sharing=False)
|
|
|
|
visible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user3),
|
|
|
|
]
|
|
|
|
invisible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user3),
|
|
|
|
self.setup_tag(user=user4),
|
|
|
|
]
|
|
|
|
|
|
|
|
self.setup_bookmark(shared=True, user=user1, tags=[visible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user2, tags=[visible_tags[1]])
|
|
|
|
self.setup_bookmark(shared=True, user=user3, tags=[visible_tags[2]])
|
|
|
|
|
|
|
|
self.setup_bookmark(shared=False, user=user1, tags=[invisible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=False, user=user2, tags=[invisible_tags[1]])
|
|
|
|
self.setup_bookmark(shared=False, user=user3, tags=[invisible_tags[2]])
|
|
|
|
self.setup_bookmark(shared=True, user=user4, tags=[invisible_tags[3]])
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
self.assertVisibleTags(response, visible_tags)
|
|
|
|
self.assertInvisibleTags(response, invisible_tags)
|
|
|
|
|
|
|
|
def test_should_list_tags_for_shared_bookmarks_from_selected_user(self):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
user3 = self.setup_user(enable_sharing=True)
|
|
|
|
visible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
]
|
|
|
|
invisible_tags = [
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user3),
|
|
|
|
]
|
|
|
|
|
|
|
|
self.setup_bookmark(shared=True, user=user1, tags=[visible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user2, tags=[invisible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user3, tags=[invisible_tags[1]])
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?user=" + user1.username
|
2022-08-04 17:37:16 +00:00
|
|
|
response = self.client.get(url)
|
|
|
|
|
|
|
|
self.assertVisibleTags(response, visible_tags)
|
|
|
|
self.assertInvisibleTags(response, invisible_tags)
|
|
|
|
|
|
|
|
def test_should_list_tags_for_bookmarks_matching_query(self):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
user3 = self.setup_user(enable_sharing=True)
|
|
|
|
visible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user3),
|
|
|
|
]
|
|
|
|
invisible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user3),
|
|
|
|
]
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_bookmark(
|
|
|
|
shared=True, user=user1, title="searchvalue", tags=[visible_tags[0]]
|
|
|
|
)
|
|
|
|
self.setup_bookmark(
|
|
|
|
shared=True, user=user2, title="searchvalue", tags=[visible_tags[1]]
|
|
|
|
)
|
|
|
|
self.setup_bookmark(
|
|
|
|
shared=True, user=user3, title="searchvalue", tags=[visible_tags[2]]
|
|
|
|
)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
self.setup_bookmark(shared=True, user=user1, tags=[invisible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user2, tags=[invisible_tags[1]])
|
|
|
|
self.setup_bookmark(shared=True, user=user3, tags=[invisible_tags[2]])
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared") + "?q=searchvalue")
|
2022-08-04 17:37:16 +00:00
|
|
|
|
|
|
|
self.assertVisibleTags(response, visible_tags)
|
|
|
|
self.assertInvisibleTags(response, invisible_tags)
|
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def test_should_list_only_tags_for_publicly_shared_bookmarks_without_login(self):
|
|
|
|
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
|
|
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
|
|
|
|
visible_tags = [
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
self.setup_tag(user=user1),
|
|
|
|
]
|
|
|
|
invisible_tags = [
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
self.setup_tag(user=user2),
|
|
|
|
]
|
|
|
|
|
|
|
|
self.setup_bookmark(shared=True, user=user1, tags=[visible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user1, tags=[visible_tags[1]])
|
|
|
|
|
|
|
|
self.setup_bookmark(shared=True, user=user2, tags=[invisible_tags[0]])
|
|
|
|
self.setup_bookmark(shared=True, user=user2, tags=[invisible_tags[1]])
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2023-08-14 22:20:52 +00:00
|
|
|
|
|
|
|
self.assertVisibleTags(response, visible_tags)
|
|
|
|
self.assertInvisibleTags(response, invisible_tags)
|
|
|
|
|
2022-08-04 17:37:16 +00:00
|
|
|
def test_should_list_users_with_shared_bookmarks_if_sharing_is_enabled(self):
|
2023-08-14 22:20:52 +00:00
|
|
|
self.authenticate()
|
2022-08-04 17:37:16 +00:00
|
|
|
expected_visible_users = [
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_user(name="user_a", enable_sharing=True),
|
|
|
|
self.setup_user(name="user_b", enable_sharing=True),
|
2022-08-04 17:37:16 +00:00
|
|
|
]
|
|
|
|
self.setup_bookmark(shared=True, user=expected_visible_users[0])
|
|
|
|
self.setup_bookmark(shared=True, user=expected_visible_users[1])
|
|
|
|
|
2023-09-01 20:48:21 +00:00
|
|
|
self.setup_bookmark(shared=False, user=self.setup_user(enable_sharing=True))
|
|
|
|
self.setup_bookmark(shared=True, user=self.setup_user(enable_sharing=False))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2022-08-04 17:37:16 +00:00
|
|
|
self.assertVisibleUserOptions(response, expected_visible_users)
|
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def test_should_list_only_users_with_publicly_shared_bookmarks_without_login(self):
|
2023-09-01 20:48:21 +00:00
|
|
|
# users with public sharing enabled
|
2023-08-14 22:20:52 +00:00
|
|
|
expected_visible_users = [
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_user(
|
|
|
|
name="user_a", enable_sharing=True, enable_public_sharing=True
|
|
|
|
),
|
|
|
|
self.setup_user(
|
|
|
|
name="user_b", enable_sharing=True, enable_public_sharing=True
|
|
|
|
),
|
2023-08-14 22:20:52 +00:00
|
|
|
]
|
|
|
|
self.setup_bookmark(shared=True, user=expected_visible_users[0])
|
|
|
|
self.setup_bookmark(shared=True, user=expected_visible_users[1])
|
|
|
|
|
2023-09-01 20:48:21 +00:00
|
|
|
# users with public sharing disabled
|
|
|
|
self.setup_bookmark(shared=True, user=self.setup_user(enable_sharing=True))
|
|
|
|
self.setup_bookmark(shared=True, user=self.setup_user(enable_sharing=True))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2023-08-14 22:20:52 +00:00
|
|
|
self.assertVisibleUserOptions(response, expected_visible_users)
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-10-01 19:22:44 +00:00
|
|
|
def test_should_list_bookmarks_and_tags_for_search_preferences(self):
|
|
|
|
self.authenticate()
|
|
|
|
other_user = self.setup_user(enable_sharing=True)
|
|
|
|
|
|
|
|
user_profile = self.get_or_create_test_user().profile
|
|
|
|
user_profile.search_preferences = {
|
2024-01-27 10:29:16 +00:00
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
2023-10-01 19:22:44 +00:00
|
|
|
}
|
|
|
|
user_profile.save()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
unread_bookmarks = self.setup_numbered_bookmarks(
|
|
|
|
3,
|
|
|
|
shared=True,
|
|
|
|
unread=True,
|
|
|
|
with_tags=True,
|
|
|
|
prefix="unread",
|
|
|
|
tag_prefix="unread",
|
|
|
|
user=other_user,
|
|
|
|
)
|
|
|
|
read_bookmarks = self.setup_numbered_bookmarks(
|
|
|
|
3,
|
|
|
|
shared=True,
|
|
|
|
unread=False,
|
|
|
|
with_tags=True,
|
|
|
|
prefix="read",
|
|
|
|
tag_prefix="read",
|
|
|
|
user=other_user,
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
unread_tags = self.get_tags_from_bookmarks(unread_bookmarks)
|
|
|
|
read_tags = self.get_tags_from_bookmarks(read_bookmarks)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertVisibleBookmarks(response, unread_bookmarks)
|
|
|
|
self.assertInvisibleBookmarks(response, read_bookmarks)
|
|
|
|
self.assertVisibleTags(response, unread_tags)
|
|
|
|
self.assertInvisibleTags(response, read_tags)
|
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def test_should_open_bookmarks_in_new_page_by_default(self):
|
|
|
|
self.authenticate()
|
|
|
|
user = self.get_or_create_test_user()
|
|
|
|
user.profile.enable_sharing = True
|
|
|
|
user.profile.save()
|
|
|
|
visible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=True),
|
|
|
|
self.setup_bookmark(shared=True),
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_bookmark(shared=True),
|
2023-08-14 22:20:52 +00:00
|
|
|
]
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks, "_blank")
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
def test_should_open_bookmarks_in_same_page_if_specified_in_user_profile(self):
|
|
|
|
self.authenticate()
|
|
|
|
user = self.get_or_create_test_user()
|
|
|
|
user.profile.enable_sharing = True
|
|
|
|
user.profile.bookmark_link_target = UserProfile.BOOKMARK_LINK_TARGET_SELF
|
|
|
|
user.profile.save()
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2023-08-14 22:20:52 +00:00
|
|
|
visible_bookmarks = [
|
|
|
|
self.setup_bookmark(shared=True),
|
|
|
|
self.setup_bookmark(shared=True),
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_bookmark(shared=True),
|
2023-08-14 22:20:52 +00:00
|
|
|
]
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.get(reverse("bookmarks:shared"))
|
2022-08-04 17:37:16 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertVisibleBookmarks(response, visible_bookmarks, "_self")
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
def test_edit_link_return_url_respects_search_options(self):
|
|
|
|
self.authenticate()
|
|
|
|
user = self.get_or_create_test_user()
|
|
|
|
user.profile.enable_sharing = True
|
|
|
|
user.profile.save()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
bookmark = self.setup_bookmark(title="foo", shared=True, user=user)
|
|
|
|
edit_url = reverse("bookmarks:edit", args=[bookmark.id])
|
|
|
|
base_url = reverse("bookmarks:shared")
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
# without query params
|
|
|
|
return_url = urllib.parse.quote(base_url)
|
2024-01-27 10:29:16 +00:00
|
|
|
url = f"{edit_url}?return_url={return_url}"
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
response = self.client.get(base_url)
|
|
|
|
self.assertEditLink(response, url)
|
|
|
|
|
|
|
|
# with query
|
2024-01-27 10:29:16 +00:00
|
|
|
url_params = "?q=foo"
|
2023-09-01 20:48:21 +00:00
|
|
|
return_url = urllib.parse.quote(base_url + url_params)
|
2024-01-27 10:29:16 +00:00
|
|
|
url = f"{edit_url}?return_url={return_url}"
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
response = self.client.get(base_url + url_params)
|
|
|
|
self.assertEditLink(response, url)
|
|
|
|
|
|
|
|
# with query and user
|
2024-01-27 10:29:16 +00:00
|
|
|
url_params = f"?q=foo&user={user.username}"
|
2023-09-01 20:48:21 +00:00
|
|
|
return_url = urllib.parse.quote(base_url + url_params)
|
2024-01-27 10:29:16 +00:00
|
|
|
url = f"{edit_url}?return_url={return_url}"
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
response = self.client.get(base_url + url_params)
|
|
|
|
self.assertEditLink(response, url)
|
|
|
|
|
|
|
|
# with query and sort and page
|
2024-01-27 10:29:16 +00:00
|
|
|
url_params = "?q=foo&sort=title_asc&page=2"
|
2023-09-01 20:48:21 +00:00
|
|
|
return_url = urllib.parse.quote(base_url + url_params)
|
2024-01-27 10:29:16 +00:00
|
|
|
url = f"{edit_url}?return_url={return_url}"
|
2023-09-01 20:48:21 +00:00
|
|
|
|
|
|
|
response = self.client.get(base_url + url_params)
|
|
|
|
self.assertEditLink(response, url)
|
2023-09-26 06:34:43 +00:00
|
|
|
|
2023-10-01 19:22:44 +00:00
|
|
|
def test_apply_search_preferences(self):
|
|
|
|
# no params
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.post(reverse("bookmarks:shared"))
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(response.status_code, 302)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(response.url, reverse("bookmarks:shared"))
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# some params
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"q": "foo",
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(response.status_code, 302)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
response.url, reverse("bookmarks:shared") + "?q=foo&sort=title_asc"
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# params with default value are removed
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"q": "foo",
|
|
|
|
"user": "",
|
|
|
|
"sort": BookmarkSearch.SORT_ADDED_DESC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(response.status_code, 302)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
response.url, reverse("bookmarks:shared") + "?q=foo&unread=yes"
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# page is removed
|
2024-01-27 10:29:16 +00:00
|
|
|
response = self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"q": "foo",
|
|
|
|
"page": "2",
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
self.assertEqual(response.status_code, 302)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
response.url, reverse("bookmarks:shared") + "?q=foo&sort=title_asc"
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
def test_save_search_preferences(self):
|
|
|
|
self.authenticate()
|
|
|
|
user_profile = self.user.profile
|
|
|
|
|
|
|
|
# no params
|
2024-01-27 10:29:16 +00:00
|
|
|
self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"save": "",
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
user_profile.refresh_from_db()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
user_profile.search_preferences,
|
|
|
|
{
|
|
|
|
"sort": BookmarkSearch.SORT_ADDED_DESC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_OFF,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# with param
|
2024-01-27 10:29:16 +00:00
|
|
|
self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"save": "",
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
user_profile.refresh_from_db()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
user_profile.search_preferences,
|
|
|
|
{
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_OFF,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# add a param
|
2024-01-27 10:29:16 +00:00
|
|
|
self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"save": "",
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
user_profile.refresh_from_db()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
user_profile.search_preferences,
|
|
|
|
{
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# remove a param
|
2024-01-27 10:29:16 +00:00
|
|
|
self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"save": "",
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
user_profile.refresh_from_db()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
user_profile.search_preferences,
|
|
|
|
{
|
|
|
|
"sort": BookmarkSearch.SORT_ADDED_DESC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
|
|
|
# ignores non-preferences
|
2024-01-27 10:29:16 +00:00
|
|
|
self.client.post(
|
|
|
|
reverse("bookmarks:shared"),
|
|
|
|
{
|
|
|
|
"save": "",
|
|
|
|
"q": "foo",
|
|
|
|
"user": "john",
|
|
|
|
"page": "3",
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
user_profile.refresh_from_db()
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
user_profile.search_preferences,
|
|
|
|
{
|
|
|
|
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
|
|
|
"shared": BookmarkSearch.FILTER_SHARED_OFF,
|
|
|
|
"unread": BookmarkSearch.FILTER_UNREAD_OFF,
|
|
|
|
},
|
|
|
|
)
|
2023-10-01 19:22:44 +00:00
|
|
|
|
2023-09-26 06:34:43 +00:00
|
|
|
def test_url_encode_bookmark_actions_url(self):
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?q=%23foo"
|
2023-09-26 06:34:43 +00:00
|
|
|
response = self.client.get(url)
|
|
|
|
html = response.content.decode()
|
|
|
|
soup = self.make_soup(html)
|
2024-01-27 10:29:16 +00:00
|
|
|
actions_form = soup.select("form.bookmark-actions")[0]
|
2023-09-26 06:34:43 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertEqual(
|
|
|
|
actions_form.attrs["action"],
|
|
|
|
"/bookmarks/shared/action?q=%23foo&return_url=%2Fbookmarks%2Fshared%3Fq%3D%2523foo",
|
|
|
|
)
|
2023-12-08 20:53:54 +00:00
|
|
|
|
|
|
|
def test_encode_search_params(self):
|
|
|
|
self.authenticate()
|
|
|
|
user = self.get_or_create_test_user()
|
|
|
|
user.profile.enable_sharing = True
|
|
|
|
user.profile.save()
|
2024-01-27 10:29:16 +00:00
|
|
|
bookmark = self.setup_bookmark(description="alert('xss')", shared=True)
|
2023-12-08 20:53:54 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?q=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|
2023-12-08 20:53:54 +00:00
|
|
|
self.assertContains(response, bookmark.url)
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?sort=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|
2023-12-08 20:53:54 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?unread=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|
2023-12-08 20:53:54 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?shared=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|
2023-12-08 20:53:54 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?user=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|
2023-12-08 20:53:54 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:shared") + "?page=alert(%27xss%27)"
|
2023-12-08 20:53:54 +00:00
|
|
|
response = self.client.get(url)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.assertNotContains(response, "alert('xss')")
|