mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-08 19:28:29 +02:00
Add bundles for organizing bookmarks (#1097)
* 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
This commit is contained in:
@@ -2,16 +2,23 @@ from django.http import QueryDict
|
||||
from django.test import TestCase
|
||||
|
||||
from bookmarks.models import BookmarkSearch
|
||||
from bookmarks.tests.helpers import BookmarkFactoryMixin
|
||||
|
||||
|
||||
class BookmarkSearchModelTest(TestCase):
|
||||
class MockRequest:
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
|
||||
|
||||
class BookmarkSearchModelTest(TestCase, BookmarkFactoryMixin):
|
||||
def test_from_request(self):
|
||||
# no params
|
||||
query_dict = QueryDict()
|
||||
|
||||
search = BookmarkSearch.from_request(query_dict)
|
||||
search = BookmarkSearch.from_request(None, query_dict)
|
||||
self.assertEqual(search.q, "")
|
||||
self.assertEqual(search.user, "")
|
||||
self.assertEqual(search.bundle, None)
|
||||
self.assertEqual(search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
||||
self.assertEqual(search.shared, BookmarkSearch.FILTER_SHARED_OFF)
|
||||
self.assertEqual(search.unread, BookmarkSearch.FILTER_UNREAD_OFF)
|
||||
@@ -19,7 +26,7 @@ class BookmarkSearchModelTest(TestCase):
|
||||
# some params
|
||||
query_dict = QueryDict("q=search query&user=user123")
|
||||
|
||||
bookmark_search = BookmarkSearch.from_request(query_dict)
|
||||
bookmark_search = BookmarkSearch.from_request(None, query_dict)
|
||||
self.assertEqual(bookmark_search.q, "search query")
|
||||
self.assertEqual(bookmark_search.user, "user123")
|
||||
self.assertEqual(bookmark_search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
||||
@@ -27,13 +34,16 @@ class BookmarkSearchModelTest(TestCase):
|
||||
self.assertEqual(search.unread, BookmarkSearch.FILTER_UNREAD_OFF)
|
||||
|
||||
# all params
|
||||
bundle = self.setup_bundle()
|
||||
request = MockRequest(self.get_or_create_test_user())
|
||||
query_dict = QueryDict(
|
||||
"q=search query&sort=title_asc&user=user123&shared=yes&unread=yes"
|
||||
f"q=search query&sort=title_asc&user=user123&bundle={bundle.id}&shared=yes&unread=yes"
|
||||
)
|
||||
|
||||
search = BookmarkSearch.from_request(query_dict)
|
||||
search = BookmarkSearch.from_request(request, query_dict)
|
||||
self.assertEqual(search.q, "search query")
|
||||
self.assertEqual(search.user, "user123")
|
||||
self.assertEqual(search.bundle, bundle)
|
||||
self.assertEqual(search.sort, BookmarkSearch.SORT_TITLE_ASC)
|
||||
self.assertEqual(search.shared, BookmarkSearch.FILTER_SHARED_SHARED)
|
||||
self.assertEqual(search.unread, BookmarkSearch.FILTER_UNREAD_YES)
|
||||
@@ -45,7 +55,7 @@ class BookmarkSearchModelTest(TestCase):
|
||||
}
|
||||
query_dict = QueryDict("q=search query")
|
||||
|
||||
search = BookmarkSearch.from_request(query_dict, preferences)
|
||||
search = BookmarkSearch.from_request(None, query_dict, preferences)
|
||||
self.assertEqual(search.q, "search query")
|
||||
self.assertEqual(search.user, "")
|
||||
self.assertEqual(search.sort, BookmarkSearch.SORT_TITLE_ASC)
|
||||
@@ -60,13 +70,110 @@ class BookmarkSearchModelTest(TestCase):
|
||||
}
|
||||
query_dict = QueryDict("sort=title_desc&shared=no&unread=off")
|
||||
|
||||
search = BookmarkSearch.from_request(query_dict, preferences)
|
||||
search = BookmarkSearch.from_request(None, query_dict, preferences)
|
||||
self.assertEqual(search.q, "")
|
||||
self.assertEqual(search.user, "")
|
||||
self.assertEqual(search.sort, BookmarkSearch.SORT_TITLE_DESC)
|
||||
self.assertEqual(search.shared, BookmarkSearch.FILTER_SHARED_UNSHARED)
|
||||
self.assertEqual(search.unread, BookmarkSearch.FILTER_UNREAD_OFF)
|
||||
|
||||
def test_from_request_ignores_invalid_bundle_param(self):
|
||||
self.setup_bundle()
|
||||
|
||||
# bundle does not exist
|
||||
request = MockRequest(self.get_or_create_test_user())
|
||||
query_dict = QueryDict("bundle=99999")
|
||||
search = BookmarkSearch.from_request(request, query_dict)
|
||||
self.assertIsNone(search.bundle)
|
||||
|
||||
# bundle belongs to another user
|
||||
other_user = self.setup_user()
|
||||
bundle = self.setup_bundle(user=other_user)
|
||||
query_dict = QueryDict(f"bundle={bundle.id}")
|
||||
search = BookmarkSearch.from_request(request, query_dict)
|
||||
self.assertIsNone(search.bundle)
|
||||
|
||||
def test_query_params(self):
|
||||
# no params
|
||||
search = BookmarkSearch()
|
||||
self.assertEqual(search.query_params, {})
|
||||
|
||||
# params are default values
|
||||
search = BookmarkSearch(
|
||||
q="", sort=BookmarkSearch.SORT_ADDED_DESC, user="", bundle=None, shared=""
|
||||
)
|
||||
self.assertEqual(search.query_params, {})
|
||||
|
||||
# some modified params
|
||||
search = BookmarkSearch(q="search query", sort=BookmarkSearch.SORT_ADDED_ASC)
|
||||
self.assertEqual(
|
||||
search.query_params,
|
||||
{"q": "search query", "sort": BookmarkSearch.SORT_ADDED_ASC},
|
||||
)
|
||||
|
||||
# all modified params
|
||||
bundle = self.setup_bundle()
|
||||
search = BookmarkSearch(
|
||||
q="search query",
|
||||
sort=BookmarkSearch.SORT_ADDED_ASC,
|
||||
user="user123",
|
||||
bundle=bundle,
|
||||
shared=BookmarkSearch.FILTER_SHARED_SHARED,
|
||||
unread=BookmarkSearch.FILTER_UNREAD_YES,
|
||||
)
|
||||
self.assertEqual(
|
||||
search.query_params,
|
||||
{
|
||||
"q": "search query",
|
||||
"sort": BookmarkSearch.SORT_ADDED_ASC,
|
||||
"user": "user123",
|
||||
"bundle": bundle.id,
|
||||
"shared": BookmarkSearch.FILTER_SHARED_SHARED,
|
||||
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
||||
},
|
||||
)
|
||||
|
||||
# preferences are not query params if they match default
|
||||
preferences = {
|
||||
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
||||
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
||||
}
|
||||
search = BookmarkSearch(preferences=preferences)
|
||||
self.assertEqual(search.query_params, {})
|
||||
|
||||
# param is not a query param if it matches the preference
|
||||
preferences = {
|
||||
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
||||
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
||||
}
|
||||
search = BookmarkSearch(
|
||||
sort=BookmarkSearch.SORT_TITLE_ASC,
|
||||
unread=BookmarkSearch.FILTER_UNREAD_YES,
|
||||
preferences=preferences,
|
||||
)
|
||||
self.assertEqual(search.query_params, {})
|
||||
|
||||
# overriding preferences is a query param
|
||||
preferences = {
|
||||
"sort": BookmarkSearch.SORT_TITLE_ASC,
|
||||
"shared": BookmarkSearch.FILTER_SHARED_SHARED,
|
||||
"unread": BookmarkSearch.FILTER_UNREAD_YES,
|
||||
}
|
||||
search = BookmarkSearch(
|
||||
sort=BookmarkSearch.SORT_TITLE_DESC,
|
||||
shared=BookmarkSearch.FILTER_SHARED_UNSHARED,
|
||||
unread=BookmarkSearch.FILTER_UNREAD_OFF,
|
||||
preferences=preferences,
|
||||
)
|
||||
self.assertEqual(
|
||||
search.query_params,
|
||||
{
|
||||
"sort": BookmarkSearch.SORT_TITLE_DESC,
|
||||
"shared": BookmarkSearch.FILTER_SHARED_UNSHARED,
|
||||
"unread": BookmarkSearch.FILTER_UNREAD_OFF,
|
||||
},
|
||||
)
|
||||
|
||||
def test_modified_params(self):
|
||||
# no params
|
||||
bookmark_search = BookmarkSearch()
|
||||
@@ -88,16 +195,18 @@ class BookmarkSearchModelTest(TestCase):
|
||||
self.assertCountEqual(modified_params, ["q", "sort"])
|
||||
|
||||
# all modified params
|
||||
bundle = self.setup_bundle()
|
||||
bookmark_search = BookmarkSearch(
|
||||
q="search query",
|
||||
sort=BookmarkSearch.SORT_ADDED_ASC,
|
||||
user="user123",
|
||||
bundle=bundle,
|
||||
shared=BookmarkSearch.FILTER_SHARED_SHARED,
|
||||
unread=BookmarkSearch.FILTER_UNREAD_YES,
|
||||
)
|
||||
modified_params = bookmark_search.modified_params
|
||||
self.assertCountEqual(
|
||||
modified_params, ["q", "sort", "user", "shared", "unread"]
|
||||
modified_params, ["q", "sort", "user", "bundle", "shared", "unread"]
|
||||
)
|
||||
|
||||
# preferences are not modified params
|
||||
@@ -180,7 +289,10 @@ class BookmarkSearchModelTest(TestCase):
|
||||
)
|
||||
|
||||
# only returns preferences
|
||||
bookmark_search = BookmarkSearch(q="search query", user="user123")
|
||||
bundle = self.setup_bundle()
|
||||
bookmark_search = BookmarkSearch(
|
||||
q="search query", user="user123", bundle=bundle
|
||||
)
|
||||
self.assertEqual(
|
||||
bookmark_search.preferences_dict,
|
||||
{
|
||||
|
Reference in New Issue
Block a user