mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-07 10:58:25 +02:00

* add bundle model and query logic * cleanup tests * add basic form * add success message * Add form tests * Add bundle list view * fix edit view * Add remove button * Add basic preview logic * Make pagination use absolute URLs * Hide bookmark edits when rendering preview * Render bookmark list in preview * Reorder bundles * Show bundles in bookmark view * Make bookmark search respect selected bundle * UI tweaks * Fix bookmark scope * Improve bundle preview * Skip preview if form is submitted * Show correct preview after invalid form submission * Add option to hide bundles * Merge new migrations * Add tests for bundle menu * Improve check for preview being removed
1554 lines
59 KiB
Python
1554 lines
59 KiB
Python
import datetime
|
|
import operator
|
|
|
|
from django.db.models import QuerySet
|
|
from django.test import TestCase
|
|
from django.utils import timezone
|
|
|
|
from bookmarks import queries
|
|
from bookmarks.models import BookmarkSearch, UserProfile
|
|
from bookmarks.tests.helpers import BookmarkFactoryMixin, random_sentence
|
|
from bookmarks.utils import unique
|
|
|
|
|
|
class QueriesTestCase(TestCase, BookmarkFactoryMixin):
|
|
def setUp(self):
|
|
self.profile = self.get_or_create_test_user().profile
|
|
|
|
def setup_bookmark_search_data(self) -> None:
|
|
tag1 = self.setup_tag(name="tag1")
|
|
tag2 = self.setup_tag(name="tag2")
|
|
self.setup_tag(name="unused_tag1")
|
|
|
|
self.other_bookmarks = [
|
|
self.setup_bookmark(),
|
|
self.setup_bookmark(),
|
|
self.setup_bookmark(),
|
|
]
|
|
self.term1_bookmarks = [
|
|
self.setup_bookmark(url="http://example.com/term1"),
|
|
self.setup_bookmark(title=random_sentence(including_word="term1")),
|
|
self.setup_bookmark(title=random_sentence(including_word="TERM1")),
|
|
self.setup_bookmark(description=random_sentence(including_word="term1")),
|
|
self.setup_bookmark(description=random_sentence(including_word="TERM1")),
|
|
self.setup_bookmark(notes=random_sentence(including_word="term1")),
|
|
self.setup_bookmark(notes=random_sentence(including_word="TERM1")),
|
|
]
|
|
self.term1_term2_bookmarks = [
|
|
self.setup_bookmark(url="http://example.com/term1/term2"),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="term1"),
|
|
description=random_sentence(including_word="term2"),
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="term1"),
|
|
title=random_sentence(including_word="term2"),
|
|
),
|
|
]
|
|
self.tag1_bookmarks = [
|
|
self.setup_bookmark(tags=[tag1]),
|
|
self.setup_bookmark(title=random_sentence(), tags=[tag1]),
|
|
self.setup_bookmark(description=random_sentence(), tags=[tag1]),
|
|
]
|
|
self.tag1_as_term_bookmarks = [
|
|
self.setup_bookmark(url="http://example.com/tag1"),
|
|
self.setup_bookmark(title=random_sentence(including_word="tag1")),
|
|
self.setup_bookmark(description=random_sentence(including_word="tag1")),
|
|
]
|
|
self.term1_tag1_bookmarks = [
|
|
self.setup_bookmark(url="http://example.com/term1", tags=[tag1]),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="term1"), tags=[tag1]
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="term1"), tags=[tag1]
|
|
),
|
|
]
|
|
self.tag2_bookmarks = [
|
|
self.setup_bookmark(tags=[tag2]),
|
|
]
|
|
self.tag1_tag2_bookmarks = [
|
|
self.setup_bookmark(tags=[tag1, tag2]),
|
|
]
|
|
|
|
def setup_tag_search_data(self):
|
|
tag1 = self.setup_tag(name="tag1")
|
|
tag2 = self.setup_tag(name="tag2")
|
|
self.setup_tag(name="unused_tag1")
|
|
|
|
self.other_bookmarks = [
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
]
|
|
self.term1_bookmarks = [
|
|
self.setup_bookmark(
|
|
url="http://example.com/term1", tags=[self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="term1"), tags=[self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="TERM1"), tags=[self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="term1"),
|
|
tags=[self.setup_tag()],
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="TERM1"),
|
|
tags=[self.setup_tag()],
|
|
),
|
|
self.setup_bookmark(
|
|
notes=random_sentence(including_word="term1"), tags=[self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
notes=random_sentence(including_word="TERM1"), tags=[self.setup_tag()]
|
|
),
|
|
]
|
|
self.term1_term2_bookmarks = [
|
|
self.setup_bookmark(
|
|
url="http://example.com/term1/term2", tags=[self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="term1"),
|
|
description=random_sentence(including_word="term2"),
|
|
tags=[self.setup_tag()],
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="term1"),
|
|
title=random_sentence(including_word="term2"),
|
|
tags=[self.setup_tag()],
|
|
),
|
|
]
|
|
self.tag1_bookmarks = [
|
|
self.setup_bookmark(tags=[tag1, self.setup_tag()]),
|
|
self.setup_bookmark(title=random_sentence(), tags=[tag1, self.setup_tag()]),
|
|
self.setup_bookmark(
|
|
description=random_sentence(), tags=[tag1, self.setup_tag()]
|
|
),
|
|
]
|
|
self.tag1_as_term_bookmarks = [
|
|
self.setup_bookmark(url="http://example.com/tag1"),
|
|
self.setup_bookmark(title=random_sentence(including_word="tag1")),
|
|
self.setup_bookmark(description=random_sentence(including_word="tag1")),
|
|
]
|
|
self.term1_tag1_bookmarks = [
|
|
self.setup_bookmark(
|
|
url="http://example.com/term1", tags=[tag1, self.setup_tag()]
|
|
),
|
|
self.setup_bookmark(
|
|
title=random_sentence(including_word="term1"),
|
|
tags=[tag1, self.setup_tag()],
|
|
),
|
|
self.setup_bookmark(
|
|
description=random_sentence(including_word="term1"),
|
|
tags=[tag1, self.setup_tag()],
|
|
),
|
|
]
|
|
self.tag2_bookmarks = [
|
|
self.setup_bookmark(tags=[tag2, self.setup_tag()]),
|
|
]
|
|
self.tag1_tag2_bookmarks = [
|
|
self.setup_bookmark(tags=[tag1, tag2, self.setup_tag()]),
|
|
]
|
|
|
|
def assertQueryResult(self, query: QuerySet, item_lists: list[list]):
|
|
expected_items = []
|
|
for item_list in item_lists:
|
|
expected_items = expected_items + item_list
|
|
|
|
expected_items = unique(expected_items, operator.attrgetter("id"))
|
|
|
|
self.assertCountEqual(list(query), expected_items)
|
|
|
|
def test_query_bookmarks_should_return_all_for_empty_query(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, BookmarkSearch(q=""))
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.other_bookmarks,
|
|
self.term1_bookmarks,
|
|
self.term1_term2_bookmarks,
|
|
self.tag1_bookmarks,
|
|
self.tag1_as_term_bookmarks,
|
|
self.term1_tag1_bookmarks,
|
|
self.tag2_bookmarks,
|
|
self.tag1_tag2_bookmarks,
|
|
],
|
|
)
|
|
|
|
def test_query_bookmarks_should_search_single_term(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term1")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.term1_bookmarks,
|
|
self.term1_term2_bookmarks,
|
|
self.term1_tag1_bookmarks,
|
|
],
|
|
)
|
|
|
|
def test_query_bookmarks_should_search_multiple_terms(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term2 term1")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.term1_term2_bookmarks])
|
|
|
|
def test_query_bookmarks_should_search_single_tag(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[self.tag1_bookmarks, self.tag1_tag2_bookmarks, self.term1_tag1_bookmarks],
|
|
)
|
|
|
|
def test_query_bookmarks_should_search_multiple_tags(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1 #tag2")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.tag1_tag2_bookmarks])
|
|
|
|
def test_query_bookmarks_should_search_multiple_tags_ignoring_casing(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#Tag1 #TAG2")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.tag1_tag2_bookmarks])
|
|
|
|
def test_query_bookmarks_should_search_terms_and_tags_combined(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #tag1")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.term1_tag1_bookmarks])
|
|
|
|
def test_query_bookmarks_in_strict_mode_should_not_search_tags_as_terms(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
self.profile.tag_search = UserProfile.TAG_SEARCH_STRICT
|
|
self.profile.save()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="tag1")
|
|
)
|
|
self.assertQueryResult(query, [self.tag1_as_term_bookmarks])
|
|
|
|
def test_query_bookmarks_in_lax_mode_should_search_tags_as_terms(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
self.profile.tag_search = UserProfile.TAG_SEARCH_LAX
|
|
self.profile.save()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="tag1")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.tag1_bookmarks,
|
|
self.tag1_as_term_bookmarks,
|
|
self.tag1_tag2_bookmarks,
|
|
self.term1_tag1_bookmarks,
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 term1")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.term1_tag1_bookmarks,
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 tag2")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.tag1_tag2_bookmarks,
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 #tag2")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.tag1_tag2_bookmarks,
|
|
],
|
|
)
|
|
|
|
def test_query_bookmarks_should_return_no_matches(self):
|
|
self.setup_bookmark_search_data()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term1 term3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #tag2")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#tag3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag combined with tag that is used
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1 #unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag combined with term that is used
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
def test_query_bookmarks_should_not_return_archived_bookmarks(self):
|
|
bookmark1 = self.setup_bookmark()
|
|
bookmark2 = self.setup_bookmark()
|
|
self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(is_archived=True)
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, BookmarkSearch(q=""))
|
|
|
|
self.assertQueryResult(query, [[bookmark1, bookmark2]])
|
|
|
|
def test_query_archived_bookmarks_should_not_return_unarchived_bookmarks(self):
|
|
bookmark1 = self.setup_bookmark(is_archived=True)
|
|
bookmark2 = self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark()
|
|
self.setup_bookmark()
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [[bookmark1, bookmark2]])
|
|
|
|
def test_query_bookmarks_should_only_return_user_owned_bookmarks(self):
|
|
other_user = self.setup_user()
|
|
owned_bookmarks = [
|
|
self.setup_bookmark(),
|
|
self.setup_bookmark(),
|
|
self.setup_bookmark(),
|
|
]
|
|
self.setup_bookmark(user=other_user)
|
|
self.setup_bookmark(user=other_user)
|
|
self.setup_bookmark(user=other_user)
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, BookmarkSearch(q=""))
|
|
|
|
self.assertQueryResult(query, [owned_bookmarks])
|
|
|
|
def test_query_archived_bookmarks_should_only_return_user_owned_bookmarks(self):
|
|
other_user = self.setup_user()
|
|
owned_bookmarks = [
|
|
self.setup_bookmark(is_archived=True),
|
|
self.setup_bookmark(is_archived=True),
|
|
self.setup_bookmark(is_archived=True),
|
|
]
|
|
self.setup_bookmark(is_archived=True, user=other_user)
|
|
self.setup_bookmark(is_archived=True, user=other_user)
|
|
self.setup_bookmark(is_archived=True, user=other_user)
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [owned_bookmarks])
|
|
|
|
def test_query_bookmarks_untagged_should_return_untagged_bookmarks_only(self):
|
|
tag = self.setup_tag()
|
|
untagged_bookmark = self.setup_bookmark()
|
|
self.setup_bookmark(tags=[tag])
|
|
self.setup_bookmark(tags=[tag])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged")
|
|
)
|
|
self.assertCountEqual(list(query), [untagged_bookmark])
|
|
|
|
def test_query_bookmarks_untagged_should_be_combinable_with_search_terms(self):
|
|
tag = self.setup_tag()
|
|
untagged_bookmark = self.setup_bookmark(title="term1")
|
|
self.setup_bookmark(title="term2")
|
|
self.setup_bookmark(tags=[tag])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged term1")
|
|
)
|
|
self.assertCountEqual(list(query), [untagged_bookmark])
|
|
|
|
def test_query_bookmarks_untagged_should_not_be_combinable_with_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark()
|
|
self.setup_bookmark(tags=[tag])
|
|
self.setup_bookmark(tags=[tag])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q=f"!untagged #{tag.name}")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
def test_query_archived_bookmarks_untagged_should_return_untagged_bookmarks_only(
|
|
self,
|
|
):
|
|
tag = self.setup_tag()
|
|
untagged_bookmark = self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged")
|
|
)
|
|
self.assertCountEqual(list(query), [untagged_bookmark])
|
|
|
|
def test_query_archived_bookmarks_untagged_should_be_combinable_with_search_terms(
|
|
self,
|
|
):
|
|
tag = self.setup_tag()
|
|
untagged_bookmark = self.setup_bookmark(is_archived=True, title="term1")
|
|
self.setup_bookmark(is_archived=True, title="term2")
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged term1")
|
|
)
|
|
self.assertCountEqual(list(query), [untagged_bookmark])
|
|
|
|
def test_query_archived_bookmarks_untagged_should_not_be_combinable_with_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q=f"!untagged #{tag.name}")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
def test_query_bookmarks_unread_should_return_unread_bookmarks_only(self):
|
|
unread_bookmarks = self.setup_numbered_bookmarks(5, unread=True)
|
|
read_bookmarks = self.setup_numbered_bookmarks(5, unread=False)
|
|
|
|
# Legacy query filter
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!unread")
|
|
)
|
|
self.assertCountEqual(list(query), unread_bookmarks)
|
|
|
|
# Bookmark search filter - off
|
|
query = queries.query_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_OFF),
|
|
)
|
|
self.assertCountEqual(list(query), read_bookmarks + unread_bookmarks)
|
|
|
|
# Bookmark search filter - yes
|
|
query = queries.query_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_YES),
|
|
)
|
|
self.assertCountEqual(list(query), unread_bookmarks)
|
|
|
|
# Bookmark search filter - no
|
|
query = queries.query_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_NO),
|
|
)
|
|
self.assertCountEqual(list(query), read_bookmarks)
|
|
|
|
def test_query_archived_bookmarks_unread_should_return_unread_bookmarks_only(self):
|
|
unread_bookmarks = self.setup_numbered_bookmarks(5, unread=True, archived=True)
|
|
read_bookmarks = self.setup_numbered_bookmarks(5, unread=False, archived=True)
|
|
|
|
# Legacy query filter
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="!unread")
|
|
)
|
|
self.assertCountEqual(list(query), unread_bookmarks)
|
|
|
|
# Bookmark search filter - off
|
|
query = queries.query_archived_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_OFF),
|
|
)
|
|
self.assertCountEqual(list(query), read_bookmarks + unread_bookmarks)
|
|
|
|
# Bookmark search filter - yes
|
|
query = queries.query_archived_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_YES),
|
|
)
|
|
self.assertCountEqual(list(query), unread_bookmarks)
|
|
|
|
# Bookmark search filter - no
|
|
query = queries.query_archived_bookmarks(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_NO),
|
|
)
|
|
self.assertCountEqual(list(query), read_bookmarks)
|
|
|
|
def test_query_bookmarks_filter_shared(self):
|
|
unshared_bookmarks = self.setup_numbered_bookmarks(5)
|
|
shared_bookmarks = self.setup_numbered_bookmarks(5, shared=True)
|
|
|
|
# Filter is off
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_OFF)
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), unshared_bookmarks + shared_bookmarks)
|
|
|
|
# Filter for shared
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_SHARED)
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), shared_bookmarks)
|
|
|
|
# Filter for unshared
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_UNSHARED)
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), unshared_bookmarks)
|
|
|
|
def test_query_bookmark_tags_should_return_all_tags_for_empty_query(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.other_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_term2_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag2_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_single_term(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term1")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.term1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_term2_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_multiple_terms(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term2 term1")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.term1_term2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_single_tag(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_multiple_tags(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1 #tag2")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_multiple_tags_ignoring_casing(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#Tag1 #TAG2")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_search_term_and_tag_combined(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #tag1")
|
|
)
|
|
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_in_strict_mode_should_not_search_tags_as_terms(self):
|
|
self.setup_tag_search_data()
|
|
|
|
self.profile.tag_search = UserProfile.TAG_SEARCH_STRICT
|
|
self.profile.save()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="tag1")
|
|
)
|
|
self.assertQueryResult(
|
|
query, self.get_tags_from_bookmarks(self.tag1_as_term_bookmarks)
|
|
)
|
|
|
|
def test_query_bookmark_tags_in_lax_mode_should_search_tags_as_terms(self):
|
|
self.setup_tag_search_data()
|
|
|
|
self.profile.tag_search = UserProfile.TAG_SEARCH_LAX
|
|
self.profile.save()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="tag1")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag1_as_term_bookmarks),
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 term1")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.term1_tag1_bookmarks),
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 tag2")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="tag1 #tag2")
|
|
)
|
|
self.assertQueryResult(
|
|
query,
|
|
[
|
|
self.get_tags_from_bookmarks(self.tag1_tag2_bookmarks),
|
|
],
|
|
)
|
|
|
|
def test_query_bookmark_tags_should_return_no_matches(self):
|
|
self.setup_tag_search_data()
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term1 term3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #tag2")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#tag3")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag combined with tag that is used
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="#tag1 #unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
# Unused tag combined with term that is used
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="term1 #unused_tag1")
|
|
)
|
|
self.assertQueryResult(query, [])
|
|
|
|
def test_query_bookmark_tags_should_return_tags_for_unarchived_bookmarks_only(self):
|
|
tag1 = self.setup_tag()
|
|
tag2 = self.setup_tag()
|
|
self.setup_bookmark(tags=[tag1])
|
|
self.setup_bookmark()
|
|
self.setup_bookmark(is_archived=True, tags=[tag2])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [[tag1]])
|
|
|
|
def test_query_bookmark_tags_should_return_distinct_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark(tags=[tag])
|
|
self.setup_bookmark(tags=[tag])
|
|
self.setup_bookmark(tags=[tag])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [[tag]])
|
|
|
|
def test_query_archived_bookmark_tags_should_return_tags_for_archived_bookmarks_only(
|
|
self,
|
|
):
|
|
tag1 = self.setup_tag()
|
|
tag2 = self.setup_tag()
|
|
self.setup_bookmark(tags=[tag1])
|
|
self.setup_bookmark()
|
|
self.setup_bookmark(is_archived=True, tags=[tag2])
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [[tag2]])
|
|
|
|
def test_query_archived_bookmark_tags_should_return_distinct_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [[tag]])
|
|
|
|
def test_query_bookmark_tags_should_only_return_user_owned_tags(self):
|
|
other_user = self.setup_user()
|
|
owned_bookmarks = [
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
self.setup_bookmark(tags=[self.setup_tag()]),
|
|
]
|
|
self.setup_bookmark(user=other_user, tags=[self.setup_tag(user=other_user)])
|
|
self.setup_bookmark(user=other_user, tags=[self.setup_tag(user=other_user)])
|
|
self.setup_bookmark(user=other_user, tags=[self.setup_tag(user=other_user)])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.get_tags_from_bookmarks(owned_bookmarks)])
|
|
|
|
def test_query_archived_bookmark_tags_should_only_return_user_owned_tags(self):
|
|
other_user = self.setup_user()
|
|
owned_bookmarks = [
|
|
self.setup_bookmark(is_archived=True, tags=[self.setup_tag()]),
|
|
self.setup_bookmark(is_archived=True, tags=[self.setup_tag()]),
|
|
self.setup_bookmark(is_archived=True, tags=[self.setup_tag()]),
|
|
]
|
|
self.setup_bookmark(
|
|
is_archived=True, user=other_user, tags=[self.setup_tag(user=other_user)]
|
|
)
|
|
self.setup_bookmark(
|
|
is_archived=True, user=other_user, tags=[self.setup_tag(user=other_user)]
|
|
)
|
|
self.setup_bookmark(
|
|
is_archived=True, user=other_user, tags=[self.setup_tag(user=other_user)]
|
|
)
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="")
|
|
)
|
|
|
|
self.assertQueryResult(query, [self.get_tags_from_bookmarks(owned_bookmarks)])
|
|
|
|
def test_query_bookmark_tags_untagged_should_never_return_any_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark()
|
|
self.setup_bookmark(title="term1")
|
|
self.setup_bookmark(title="term1", tags=[tag])
|
|
self.setup_bookmark(tags=[tag])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged term1")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q=f"!untagged #{tag.name}")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
def test_query_archived_bookmark_tags_untagged_should_never_return_any_tags(self):
|
|
tag = self.setup_tag()
|
|
self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(is_archived=True, title="term1")
|
|
self.setup_bookmark(is_archived=True, title="term1", tags=[tag])
|
|
self.setup_bookmark(is_archived=True, tags=[tag])
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="!untagged term1")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
query = queries.query_archived_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q=f"!untagged #{tag.name}")
|
|
)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
def test_query_bookmark_tags_filter_unread(self):
|
|
unread_bookmarks = self.setup_numbered_bookmarks(5, unread=True, with_tags=True)
|
|
read_bookmarks = self.setup_numbered_bookmarks(5, unread=False, with_tags=True)
|
|
unread_tags = self.get_tags_from_bookmarks(unread_bookmarks)
|
|
read_tags = self.get_tags_from_bookmarks(read_bookmarks)
|
|
|
|
# Legacy query filter
|
|
query = queries.query_bookmark_tags(
|
|
self.user, self.profile, BookmarkSearch(q="!unread")
|
|
)
|
|
self.assertCountEqual(list(query), unread_tags)
|
|
|
|
# Bookmark search filter - off
|
|
query = queries.query_bookmark_tags(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_OFF),
|
|
)
|
|
self.assertCountEqual(list(query), read_tags + unread_tags)
|
|
|
|
# Bookmark search filter - yes
|
|
query = queries.query_bookmark_tags(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_YES),
|
|
)
|
|
self.assertCountEqual(list(query), unread_tags)
|
|
|
|
# Bookmark search filter - no
|
|
query = queries.query_bookmark_tags(
|
|
self.user,
|
|
self.profile,
|
|
BookmarkSearch(unread=BookmarkSearch.FILTER_UNREAD_NO),
|
|
)
|
|
self.assertCountEqual(list(query), read_tags)
|
|
|
|
def test_query_bookmark_tags_filter_shared(self):
|
|
unshared_bookmarks = self.setup_numbered_bookmarks(5, with_tags=True)
|
|
shared_bookmarks = self.setup_numbered_bookmarks(5, with_tags=True, shared=True)
|
|
|
|
unshared_tags = self.get_tags_from_bookmarks(unshared_bookmarks)
|
|
shared_tags = self.get_tags_from_bookmarks(shared_bookmarks)
|
|
all_tags = unshared_tags + shared_tags
|
|
|
|
# Filter is off
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_OFF)
|
|
query = queries.query_bookmark_tags(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), all_tags)
|
|
|
|
# Filter for shared
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_SHARED)
|
|
query = queries.query_bookmark_tags(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), shared_tags)
|
|
|
|
# Filter for unshared
|
|
search = BookmarkSearch(shared=BookmarkSearch.FILTER_SHARED_UNSHARED)
|
|
query = queries.query_bookmark_tags(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), unshared_tags)
|
|
|
|
def test_query_shared_bookmarks(self):
|
|
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)
|
|
tag = self.setup_tag()
|
|
|
|
shared_bookmarks = [
|
|
self.setup_bookmark(user=user1, shared=True, title="test title"),
|
|
self.setup_bookmark(user=user2, shared=True),
|
|
self.setup_bookmark(user=user3, shared=True, tags=[tag]),
|
|
]
|
|
|
|
# Unshared bookmarks
|
|
self.setup_bookmark(user=user1, shared=False, title="test title"),
|
|
self.setup_bookmark(user=user2, shared=False),
|
|
self.setup_bookmark(user=user3, shared=False, tags=[tag]),
|
|
self.setup_bookmark(user=user4, shared=True, tags=[tag]),
|
|
|
|
# Should return shared bookmarks from all users
|
|
query_set = queries.query_shared_bookmarks(
|
|
None, self.profile, BookmarkSearch(q=""), False
|
|
)
|
|
self.assertQueryResult(query_set, [shared_bookmarks])
|
|
|
|
# Should respect search query
|
|
query_set = queries.query_shared_bookmarks(
|
|
None, self.profile, BookmarkSearch(q="test title"), False
|
|
)
|
|
self.assertQueryResult(query_set, [[shared_bookmarks[0]]])
|
|
|
|
query_set = queries.query_shared_bookmarks(
|
|
None, self.profile, BookmarkSearch(q=f"#{tag.name}"), False
|
|
)
|
|
self.assertQueryResult(query_set, [[shared_bookmarks[2]]])
|
|
|
|
def test_query_publicly_shared_bookmarks(self):
|
|
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
bookmark1 = self.setup_bookmark(user=user1, shared=True)
|
|
self.setup_bookmark(user=user2, shared=True)
|
|
|
|
query_set = queries.query_shared_bookmarks(
|
|
None, self.profile, BookmarkSearch(q=""), True
|
|
)
|
|
self.assertQueryResult(query_set, [[bookmark1]])
|
|
|
|
def test_query_shared_bookmark_tags(self):
|
|
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)
|
|
|
|
shared_tags = [
|
|
self.setup_tag(user=user1),
|
|
self.setup_tag(user=user2),
|
|
self.setup_tag(user=user3),
|
|
]
|
|
|
|
self.setup_bookmark(user=user1, shared=True, tags=[shared_tags[0]]),
|
|
self.setup_bookmark(user=user2, shared=True, tags=[shared_tags[1]]),
|
|
self.setup_bookmark(user=user3, shared=True, tags=[shared_tags[2]]),
|
|
|
|
self.setup_bookmark(
|
|
user=user1, shared=False, tags=[self.setup_tag(user=user1)]
|
|
),
|
|
self.setup_bookmark(
|
|
user=user2, shared=False, tags=[self.setup_tag(user=user2)]
|
|
),
|
|
self.setup_bookmark(
|
|
user=user3, shared=False, tags=[self.setup_tag(user=user3)]
|
|
),
|
|
self.setup_bookmark(user=user4, shared=True, tags=[self.setup_tag(user=user4)]),
|
|
|
|
query_set = queries.query_shared_bookmark_tags(
|
|
None, self.profile, BookmarkSearch(q=""), False
|
|
)
|
|
|
|
self.assertQueryResult(query_set, [shared_tags])
|
|
|
|
def test_query_publicly_shared_bookmark_tags(self):
|
|
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
tag1 = self.setup_tag(user=user1)
|
|
tag2 = self.setup_tag(user=user2)
|
|
|
|
self.setup_bookmark(user=user1, shared=True, tags=[tag1]),
|
|
self.setup_bookmark(user=user2, shared=True, tags=[tag2]),
|
|
|
|
query_set = queries.query_shared_bookmark_tags(
|
|
None, self.profile, BookmarkSearch(q=""), True
|
|
)
|
|
|
|
self.assertQueryResult(query_set, [[tag1]])
|
|
|
|
def test_query_shared_bookmark_users(self):
|
|
users_with_shared_bookmarks = [
|
|
self.setup_user(enable_sharing=True),
|
|
self.setup_user(enable_sharing=True),
|
|
]
|
|
users_without_shared_bookmarks = [
|
|
self.setup_user(enable_sharing=True),
|
|
self.setup_user(enable_sharing=True),
|
|
self.setup_user(enable_sharing=False),
|
|
]
|
|
|
|
# Shared bookmarks
|
|
self.setup_bookmark(
|
|
user=users_with_shared_bookmarks[0], shared=True, title="test title"
|
|
),
|
|
self.setup_bookmark(user=users_with_shared_bookmarks[1], shared=True),
|
|
|
|
# Unshared bookmarks
|
|
self.setup_bookmark(
|
|
user=users_without_shared_bookmarks[0], shared=False, title="test title"
|
|
),
|
|
self.setup_bookmark(user=users_without_shared_bookmarks[1], shared=False),
|
|
self.setup_bookmark(user=users_without_shared_bookmarks[2], shared=True),
|
|
|
|
# Should return users with shared bookmarks
|
|
query_set = queries.query_shared_bookmark_users(
|
|
self.profile, BookmarkSearch(q=""), False
|
|
)
|
|
self.assertQueryResult(query_set, [users_with_shared_bookmarks])
|
|
|
|
# Should respect search query
|
|
query_set = queries.query_shared_bookmark_users(
|
|
self.profile, BookmarkSearch(q="test title"), False
|
|
)
|
|
self.assertQueryResult(query_set, [[users_with_shared_bookmarks[0]]])
|
|
|
|
def test_query_publicly_shared_bookmark_users(self):
|
|
user1 = self.setup_user(enable_sharing=True, enable_public_sharing=True)
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
self.setup_bookmark(user=user1, shared=True)
|
|
self.setup_bookmark(user=user2, shared=True)
|
|
|
|
query_set = queries.query_shared_bookmark_users(
|
|
self.profile, BookmarkSearch(q=""), True
|
|
)
|
|
self.assertQueryResult(query_set, [[user1]])
|
|
|
|
def test_sorty_by_date_added_asc(self):
|
|
search = BookmarkSearch(sort=BookmarkSearch.SORT_ADDED_ASC)
|
|
|
|
bookmarks = [
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2021, 2, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2022, 3, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2023, 4, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2022, 5, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2021, 6, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2020, 7, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
]
|
|
sorted_bookmarks = sorted(bookmarks, key=lambda b: b.date_added)
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertEqual(list(query), sorted_bookmarks)
|
|
|
|
def test_sorty_by_date_added_desc(self):
|
|
search = BookmarkSearch(sort=BookmarkSearch.SORT_ADDED_DESC)
|
|
|
|
bookmarks = [
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2021, 2, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2022, 3, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2023, 4, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2022, 5, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2021, 6, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
self.setup_bookmark(
|
|
added=timezone.datetime(2020, 7, 1, tzinfo=datetime.timezone.utc)
|
|
),
|
|
]
|
|
sorted_bookmarks = sorted(bookmarks, key=lambda b: b.date_added, reverse=True)
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertEqual(list(query), sorted_bookmarks)
|
|
|
|
def setup_title_sort_data(self):
|
|
# lots of combinations to test effective title logic
|
|
bookmarks = [
|
|
self.setup_bookmark(title="a_1_1"),
|
|
self.setup_bookmark(title="A_1_2"),
|
|
self.setup_bookmark(title="b_1_1"),
|
|
self.setup_bookmark(title="B_1_2"),
|
|
self.setup_bookmark(title="", url="a_3_1"),
|
|
self.setup_bookmark(title="", url="A_3_2"),
|
|
self.setup_bookmark(title="", url="b_3_1"),
|
|
self.setup_bookmark(title="", url="B_3_2"),
|
|
self.setup_bookmark(title="a_5_1", url="0"),
|
|
self.setup_bookmark(title="A_5_2", url="0"),
|
|
self.setup_bookmark(title="b_5_1", url="0"),
|
|
self.setup_bookmark(title="B_5_2", url="0"),
|
|
self.setup_bookmark(title="", url="0"),
|
|
self.setup_bookmark(title="", url="0"),
|
|
self.setup_bookmark(title="", url="0"),
|
|
self.setup_bookmark(title="", url="0"),
|
|
]
|
|
return bookmarks
|
|
|
|
def test_sort_by_title_asc(self):
|
|
search = BookmarkSearch(sort=BookmarkSearch.SORT_TITLE_ASC)
|
|
|
|
bookmarks = self.setup_title_sort_data()
|
|
sorted_bookmarks = sorted(bookmarks, key=lambda b: b.resolved_title.lower())
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertEqual(list(query), sorted_bookmarks)
|
|
|
|
def test_sort_by_title_desc(self):
|
|
search = BookmarkSearch(sort=BookmarkSearch.SORT_TITLE_DESC)
|
|
|
|
bookmarks = self.setup_title_sort_data()
|
|
sorted_bookmarks = sorted(
|
|
bookmarks, key=lambda b: b.resolved_title.lower(), reverse=True
|
|
)
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertEqual(list(query), sorted_bookmarks)
|
|
|
|
def test_query_bookmarks_filter_modified_since(self):
|
|
# Create bookmarks with different modification dates
|
|
older_bookmark = self.setup_bookmark(title="old bookmark")
|
|
recent_bookmark = self.setup_bookmark(title="recent bookmark")
|
|
|
|
# Modify date field on bookmark directly to test modified_since
|
|
older_bookmark.date_modified = timezone.datetime(
|
|
2025, 1, 1, tzinfo=datetime.timezone.utc
|
|
)
|
|
older_bookmark.save()
|
|
recent_bookmark.date_modified = timezone.datetime(
|
|
2025, 5, 15, tzinfo=datetime.timezone.utc
|
|
)
|
|
recent_bookmark.save()
|
|
|
|
# Test with date between the two bookmarks
|
|
search = BookmarkSearch(modified_since="2025-03-01T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [recent_bookmark])
|
|
|
|
# Test with date before both bookmarks
|
|
search = BookmarkSearch(modified_since="2024-12-31T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
# Test with date after both bookmarks
|
|
search = BookmarkSearch(modified_since="2025-05-16T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
# Test with no modified_since - should return all bookmarks
|
|
search = BookmarkSearch()
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
# Test with invalid date format - should be ignored
|
|
search = BookmarkSearch(modified_since="invalid-date")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
def test_query_bookmarks_filter_added_since(self):
|
|
# Create bookmarks with different dates
|
|
older_bookmark = self.setup_bookmark(
|
|
title="old bookmark",
|
|
added=timezone.datetime(2025, 1, 1, tzinfo=datetime.timezone.utc),
|
|
)
|
|
recent_bookmark = self.setup_bookmark(
|
|
title="recent bookmark",
|
|
added=timezone.datetime(2025, 5, 15, tzinfo=datetime.timezone.utc),
|
|
)
|
|
|
|
# Test with date between the two bookmarks
|
|
search = BookmarkSearch(added_since="2025-03-01T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [recent_bookmark])
|
|
|
|
# Test with date before both bookmarks
|
|
search = BookmarkSearch(added_since="2024-12-31T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
# Test with date after both bookmarks
|
|
search = BookmarkSearch(added_since="2025-05-16T00:00:00Z")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [])
|
|
|
|
# Test with no added_since - should return all bookmarks
|
|
search = BookmarkSearch()
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
# Test with invalid date format - should be ignored
|
|
search = BookmarkSearch(added_since="invalid-date")
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertCountEqual(list(query), [older_bookmark, recent_bookmark])
|
|
|
|
def test_query_bookmarks_with_bundle_search_terms(self):
|
|
bundle = self.setup_bundle(search="search_term_A search_term_B")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(
|
|
title="search_term_A content", description="search_term_B also here"
|
|
),
|
|
self.setup_bookmark(url="http://example.com/search_term_A/search_term_B"),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(title="search_term_A only")
|
|
self.setup_bookmark(description="search_term_B only")
|
|
self.setup_bookmark(title="unrelated content")
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_search_and_bundle_search_terms(self):
|
|
bundle = self.setup_bundle(search="bundle_term_B")
|
|
search = BookmarkSearch(q="search_term_A", bundle=bundle)
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(
|
|
title="search_term_A content", description="bundle_term_B also here"
|
|
)
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(title="search_term_A only")
|
|
self.setup_bookmark(description="bundle_term_B only")
|
|
self.setup_bookmark(title="unrelated content")
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_bundle_any_tags(self):
|
|
bundle = self.setup_bundle(any_tags="bundleTag1 bundleTag2")
|
|
|
|
tag1 = self.setup_tag(name="bundleTag1")
|
|
tag2 = self.setup_tag(name="bundleTag2")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(tags=[tag1]),
|
|
self.setup_bookmark(tags=[tag2]),
|
|
self.setup_bookmark(tags=[tag1, tag2]),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(tags=[other_tag])
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_search_tags_and_bundle_any_tags(self):
|
|
bundle = self.setup_bundle(any_tags="bundleTagA bundleTagB")
|
|
search = BookmarkSearch(q="#searchTag1 #searchTag2", bundle=bundle)
|
|
|
|
search_tag1 = self.setup_tag(name="searchTag1")
|
|
search_tag2 = self.setup_tag(name="searchTag2")
|
|
bundle_tag_a = self.setup_tag(name="bundleTagA")
|
|
bundle_tag_b = self.setup_tag(name="bundleTagB")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2, bundle_tag_a]),
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2, bundle_tag_b]),
|
|
self.setup_bookmark(
|
|
tags=[search_tag1, search_tag2, bundle_tag_a, bundle_tag_b]
|
|
),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2, other_tag])
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2])
|
|
self.setup_bookmark(tags=[search_tag1, bundle_tag_a])
|
|
self.setup_bookmark(tags=[search_tag2, bundle_tag_b])
|
|
self.setup_bookmark(tags=[bundle_tag_a])
|
|
self.setup_bookmark(tags=[bundle_tag_b])
|
|
self.setup_bookmark(tags=[bundle_tag_a, bundle_tag_b])
|
|
self.setup_bookmark(tags=[other_tag])
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_bundle_all_tags(self):
|
|
bundle = self.setup_bundle(all_tags="bundleTag1 bundleTag2")
|
|
|
|
tag1 = self.setup_tag(name="bundleTag1")
|
|
tag2 = self.setup_tag(name="bundleTag2")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [self.setup_bookmark(tags=[tag1, tag2])]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(tags=[tag1])
|
|
self.setup_bookmark(tags=[tag2])
|
|
self.setup_bookmark(tags=[tag1, other_tag])
|
|
self.setup_bookmark(tags=[other_tag])
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_search_tags_and_bundle_all_tags(self):
|
|
bundle = self.setup_bundle(all_tags="bundleTagA bundleTagB")
|
|
search = BookmarkSearch(q="#searchTag1 #searchTag2", bundle=bundle)
|
|
|
|
search_tag1 = self.setup_tag(name="searchTag1")
|
|
search_tag2 = self.setup_tag(name="searchTag2")
|
|
bundle_tag_a = self.setup_tag(name="bundleTagA")
|
|
bundle_tag_b = self.setup_tag(name="bundleTagB")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(
|
|
tags=[search_tag1, search_tag2, bundle_tag_a, bundle_tag_b]
|
|
)
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2, bundle_tag_a])
|
|
self.setup_bookmark(tags=[search_tag1, bundle_tag_a, bundle_tag_b])
|
|
self.setup_bookmark(tags=[search_tag1, search_tag2])
|
|
self.setup_bookmark(tags=[bundle_tag_a, bundle_tag_b])
|
|
self.setup_bookmark(tags=[search_tag1, bundle_tag_a])
|
|
self.setup_bookmark(tags=[other_tag])
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_bookmarks(self.user, self.profile, search)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_bundle_excluded_tags(self):
|
|
bundle = self.setup_bundle(excluded_tags="excludeTag1 excludeTag2")
|
|
|
|
exclude_tag1 = self.setup_tag(name="excludeTag1")
|
|
exclude_tag2 = self.setup_tag(name="excludeTag2")
|
|
keep_tag = self.setup_tag(name="keepTag")
|
|
keep_other_tag = self.setup_tag(name="keepOtherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(tags=[keep_tag]),
|
|
self.setup_bookmark(tags=[keep_other_tag]),
|
|
self.setup_bookmark(tags=[keep_tag, keep_other_tag]),
|
|
self.setup_bookmark(),
|
|
]
|
|
|
|
# Bookmarks that should not be returned
|
|
self.setup_bookmark(tags=[exclude_tag1])
|
|
self.setup_bookmark(tags=[exclude_tag2])
|
|
self.setup_bookmark(tags=[exclude_tag1, keep_tag])
|
|
self.setup_bookmark(tags=[exclude_tag2, keep_tag])
|
|
self.setup_bookmark(tags=[exclude_tag1, exclude_tag2])
|
|
self.setup_bookmark(tags=[exclude_tag1, exclude_tag2, keep_tag])
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_bookmarks_with_bundle_combined_tags(self):
|
|
bundle = self.setup_bundle(
|
|
any_tags="anyTagA anyTagB",
|
|
all_tags="allTag1 allTag2",
|
|
excluded_tags="excludedTag",
|
|
)
|
|
|
|
any_tag_a = self.setup_tag(name="anyTagA")
|
|
any_tag_b = self.setup_tag(name="anyTagB")
|
|
all_tag_1 = self.setup_tag(name="allTag1")
|
|
all_tag_2 = self.setup_tag(name="allTag2")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
excluded_tag = self.setup_tag(name="excludedTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(tags=[any_tag_a, all_tag_1, all_tag_2]),
|
|
self.setup_bookmark(tags=[any_tag_b, all_tag_1, all_tag_2]),
|
|
self.setup_bookmark(tags=[any_tag_a, any_tag_b, all_tag_1, all_tag_2]),
|
|
self.setup_bookmark(tags=[any_tag_a, all_tag_1, all_tag_2, other_tag]),
|
|
self.setup_bookmark(tags=[any_tag_b, all_tag_1, all_tag_2, other_tag]),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(tags=[any_tag_a, all_tag_1])
|
|
self.setup_bookmark(tags=[any_tag_b, all_tag_2])
|
|
self.setup_bookmark(tags=[any_tag_a, any_tag_b, all_tag_1])
|
|
self.setup_bookmark(tags=[all_tag_1, all_tag_2])
|
|
self.setup_bookmark(tags=[all_tag_1, all_tag_2, other_tag])
|
|
self.setup_bookmark(tags=[any_tag_a])
|
|
self.setup_bookmark(tags=[any_tag_b])
|
|
self.setup_bookmark(tags=[all_tag_1])
|
|
self.setup_bookmark(tags=[all_tag_2])
|
|
self.setup_bookmark(tags=[any_tag_a, all_tag_1, all_tag_2, excluded_tag])
|
|
self.setup_bookmark(tags=[any_tag_b, all_tag_1, all_tag_2, excluded_tag])
|
|
self.setup_bookmark(tags=[other_tag])
|
|
self.setup_bookmark()
|
|
|
|
query = queries.query_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_archived_bookmarks_with_bundle(self):
|
|
bundle = self.setup_bundle(any_tags="bundleTag1 bundleTag2")
|
|
|
|
tag1 = self.setup_tag(name="bundleTag1")
|
|
tag2 = self.setup_tag(name="bundleTag2")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(is_archived=True, tags=[tag1]),
|
|
self.setup_bookmark(is_archived=True, tags=[tag2]),
|
|
self.setup_bookmark(is_archived=True, tags=[tag1, tag2]),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(is_archived=True, tags=[other_tag])
|
|
self.setup_bookmark(is_archived=True)
|
|
self.setup_bookmark(tags=[tag1]),
|
|
self.setup_bookmark(tags=[tag2]),
|
|
self.setup_bookmark(tags=[tag1, tag2]),
|
|
|
|
query = queries.query_archived_bookmarks(
|
|
self.user, self.profile, BookmarkSearch(q="", bundle=bundle)
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|
|
|
|
def test_query_shared_bookmarks_with_bundle(self):
|
|
user1 = self.setup_user(enable_sharing=True)
|
|
user2 = self.setup_user(enable_sharing=True)
|
|
|
|
bundle = self.setup_bundle(any_tags="bundleTag1 bundleTag2")
|
|
|
|
tag1 = self.setup_tag(name="bundleTag1")
|
|
tag2 = self.setup_tag(name="bundleTag2")
|
|
other_tag = self.setup_tag(name="otherTag")
|
|
|
|
matching_bookmarks = [
|
|
self.setup_bookmark(user=user1, shared=True, tags=[tag1]),
|
|
self.setup_bookmark(user=user2, shared=True, tags=[tag2]),
|
|
self.setup_bookmark(user=user1, shared=True, tags=[tag1, tag2]),
|
|
]
|
|
|
|
# Bookmarks that should not match
|
|
self.setup_bookmark(user=user1, shared=True, tags=[other_tag])
|
|
self.setup_bookmark(user=user2, shared=True)
|
|
self.setup_bookmark(user=user1, shared=False, tags=[tag1]),
|
|
self.setup_bookmark(user=user2, shared=False, tags=[tag2]),
|
|
self.setup_bookmark(user=user1, shared=False, tags=[tag1, tag2]),
|
|
|
|
query = queries.query_shared_bookmarks(
|
|
None, self.profile, BookmarkSearch(q="", bundle=bundle), False
|
|
)
|
|
self.assertQueryResult(query, [matching_bookmarks])
|