mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-08 11:18:28 +02:00
Add filter for shared state (#531)
* Add shared filter to bookmark search model * Add shared filter UI * Implement shared filter * Add API test * Use radio buttons * Rename shared parameter * Improve radio button CSS
This commit is contained in:
@@ -103,7 +103,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recent search suggestions
|
// Recent search suggestions
|
||||||
const search = searchHistory.getRecentSearches(value, 5).map(value => ({
|
const recentSearches = searchHistory.getRecentSearches(value, 5).map(value => ({
|
||||||
type: 'search',
|
type: 'search',
|
||||||
index: nextIndex(),
|
index: nextIndex(),
|
||||||
label: value,
|
label: value,
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSuggestions(search, bookmarks, tagSuggestions)
|
updateSuggestions(recentSearches, bookmarks, tagSuggestions)
|
||||||
|
|
||||||
if (hasSuggestions()) {
|
if (hasSuggestions()) {
|
||||||
open()
|
open()
|
||||||
@@ -143,17 +143,17 @@
|
|||||||
|
|
||||||
const debouncedLoadSuggestions = debounce(loadSuggestions)
|
const debouncedLoadSuggestions = debounce(loadSuggestions)
|
||||||
|
|
||||||
function updateSuggestions(search, bookmarks, tagSuggestions) {
|
function updateSuggestions(recentSearches, bookmarks, tagSuggestions) {
|
||||||
search = search || []
|
recentSearches = recentSearches || []
|
||||||
bookmarks = bookmarks || []
|
bookmarks = bookmarks || []
|
||||||
tagSuggestions = tagSuggestions || []
|
tagSuggestions = tagSuggestions || []
|
||||||
suggestions = {
|
suggestions = {
|
||||||
search,
|
recentSearches,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
tags: tagSuggestions,
|
tags: tagSuggestions,
|
||||||
total: [
|
total: [
|
||||||
...tagSuggestions,
|
...tagSuggestions,
|
||||||
...search,
|
...recentSearches,
|
||||||
...bookmarks,
|
...bookmarks,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -215,10 +215,10 @@
|
|||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
{#if suggestions.search.length > 0}
|
{#if suggestions.recentSearches.length > 0}
|
||||||
<li class="menu-item group-item">Recent Searches</li>
|
<li class="menu-item group-item">Recent Searches</li>
|
||||||
{/if}
|
{/if}
|
||||||
{#each suggestions.search as suggestion}
|
{#each suggestions.recentSearches as suggestion}
|
||||||
<li class="menu-item" class:selected={selectedIndex === suggestion.index}>
|
<li class="menu-item" class:selected={selectedIndex === suggestion.index}>
|
||||||
<a href="#" on:mousedown|preventDefault={() => completeSuggestion(suggestion)}>
|
<a href="#" on:mousedown|preventDefault={() => completeSuggestion(suggestion)}>
|
||||||
{suggestion.label}
|
{suggestion.label}
|
||||||
|
@@ -130,21 +130,28 @@ class BookmarkSearch:
|
|||||||
SORT_TITLE_ASC = 'title_asc'
|
SORT_TITLE_ASC = 'title_asc'
|
||||||
SORT_TITLE_DESC = 'title_desc'
|
SORT_TITLE_DESC = 'title_desc'
|
||||||
|
|
||||||
params = ['q', 'user', 'sort']
|
FILTER_SHARED_OFF = ''
|
||||||
|
FILTER_SHARED_SHARED = 'shared'
|
||||||
|
FILTER_SHARED_UNSHARED = 'unshared'
|
||||||
|
|
||||||
|
params = ['q', 'user', 'sort', 'shared']
|
||||||
defaults = {
|
defaults = {
|
||||||
'q': '',
|
'q': '',
|
||||||
'user': '',
|
'user': '',
|
||||||
'sort': SORT_ADDED_DESC,
|
'sort': SORT_ADDED_DESC,
|
||||||
|
'shared': FILTER_SHARED_OFF,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
q: str = defaults['q'],
|
q: str = defaults['q'],
|
||||||
query: str = defaults['q'], # alias for q
|
query: str = defaults['q'], # alias for q
|
||||||
user: str = defaults['user'],
|
user: str = defaults['user'],
|
||||||
sort: str = defaults['sort']):
|
sort: str = defaults['sort'],
|
||||||
|
shared: str = defaults['shared']):
|
||||||
self.q = q or query
|
self.q = q or query
|
||||||
self.user = user
|
self.user = user
|
||||||
self.sort = sort
|
self.sort = sort
|
||||||
|
self.shared = shared
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def query(self):
|
def query(self):
|
||||||
@@ -180,10 +187,16 @@ class BookmarkSearchForm(forms.Form):
|
|||||||
(BookmarkSearch.SORT_TITLE_ASC, 'Title ↑'),
|
(BookmarkSearch.SORT_TITLE_ASC, 'Title ↑'),
|
||||||
(BookmarkSearch.SORT_TITLE_DESC, 'Title ↓'),
|
(BookmarkSearch.SORT_TITLE_DESC, 'Title ↓'),
|
||||||
]
|
]
|
||||||
|
FILTER_SHARED_CHOICES = [
|
||||||
|
(BookmarkSearch.FILTER_SHARED_OFF, 'Off'),
|
||||||
|
(BookmarkSearch.FILTER_SHARED_SHARED, 'Shared'),
|
||||||
|
(BookmarkSearch.FILTER_SHARED_UNSHARED, 'Unshared'),
|
||||||
|
]
|
||||||
|
|
||||||
q = forms.CharField()
|
q = forms.CharField()
|
||||||
user = forms.ChoiceField()
|
user = forms.ChoiceField()
|
||||||
sort = forms.ChoiceField(choices=SORT_CHOICES)
|
sort = forms.ChoiceField(choices=SORT_CHOICES)
|
||||||
|
shared = forms.ChoiceField(choices=FILTER_SHARED_CHOICES, widget=forms.RadioSelect)
|
||||||
|
|
||||||
def __init__(self, search: BookmarkSearch, editable_fields: List[str] = None, users: List[User] = None):
|
def __init__(self, search: BookmarkSearch, editable_fields: List[str] = None, users: List[User] = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@@ -69,6 +69,12 @@ def _base_bookmarks_query(user: Optional[User], profile: UserProfile, search: Bo
|
|||||||
unread=True
|
unread=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Shared filter
|
||||||
|
if search.shared == BookmarkSearch.FILTER_SHARED_SHARED:
|
||||||
|
query_set = query_set.filter(shared=True)
|
||||||
|
elif search.shared == BookmarkSearch.FILTER_SHARED_UNSHARED:
|
||||||
|
query_set = query_set.filter(shared=False)
|
||||||
|
|
||||||
# Sort by date added
|
# Sort by date added
|
||||||
if search.sort == BookmarkSearch.SORT_ADDED_ASC:
|
if search.sort == BookmarkSearch.SORT_ADDED_ASC:
|
||||||
query_set = query_set.order_by('date_added')
|
query_set = query_set.order_by('date_added')
|
||||||
|
@@ -58,7 +58,7 @@
|
|||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown button {
|
.dropdown-toggle {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
.dropdown {
|
.dropdown {
|
||||||
.menu {
|
.menu {
|
||||||
padding: $unit-4;
|
padding: $unit-4;
|
||||||
min-width: 220px;
|
min-width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
@@ -85,6 +85,23 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio-group {
|
||||||
|
.form-label {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.form-radio.form-inline {
|
||||||
|
margin: 0 $unit-2 0 0;
|
||||||
|
padding: 0;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: $unit-1;
|
||||||
|
}
|
||||||
|
.form-icon {
|
||||||
|
top: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -63,6 +63,19 @@ a:visited:hover {
|
|||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix radio button sub-pixel size
|
||||||
|
.form-radio .form-icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-radio input:checked + .form-icon::before {
|
||||||
|
top: 3px;
|
||||||
|
left: 3px;
|
||||||
|
transform: unset;
|
||||||
|
}
|
||||||
|
|
||||||
// Make code work with light and dark theme
|
// Make code work with light and dark theme
|
||||||
code {
|
code {
|
||||||
color: $gray-color-dark;
|
color: $gray-color-dark;
|
||||||
|
@@ -44,6 +44,10 @@ a:focus, .btn:focus {
|
|||||||
border-color: $dt-primary-button-color;
|
border-color: $dt-primary-button-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-radio input:checked + .form-icon::before {
|
||||||
|
background: $light-color;
|
||||||
|
}
|
||||||
|
|
||||||
// Pagination
|
// Pagination
|
||||||
.pagination .page-item.active a {
|
.pagination .page-item.active a {
|
||||||
background: $dt-primary-button-color;
|
background: $dt-primary-button-color;
|
||||||
|
@@ -27,6 +27,16 @@
|
|||||||
<label for="{{ form.sort.id_for_label }}" class="form-label">Sort by</label>
|
<label for="{{ form.sort.id_for_label }}" class="form-label">Sort by</label>
|
||||||
{{ form.sort|add_class:"form-select select-sm" }}
|
{{ form.sort|add_class:"form-select select-sm" }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group radio-group">
|
||||||
|
<div class="form-label">Shared filter</div>
|
||||||
|
{% for radio in form.shared %}
|
||||||
|
<label for="{{ radio.id_for_label }}" class="form-radio form-inline">
|
||||||
|
{{ radio.tag }}
|
||||||
|
<i class="form-icon"></i>
|
||||||
|
{{ radio.choice_label }}
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="submit" class="btn btn-sm btn-primary">Apply</button>
|
<button type="submit" class="btn btn-sm btn-primary">Apply</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,6 +57,7 @@
|
|||||||
const search = {
|
const search = {
|
||||||
q: '{{ search.query }}',
|
q: '{{ search.query }}',
|
||||||
user: '{{ search.user }}',
|
user: '{{ search.user }}',
|
||||||
|
shared: '{{ search.shared }}',
|
||||||
}
|
}
|
||||||
const apiClient = new linkding.ApiClient('{% url 'bookmarks:api-root' %}')
|
const apiClient = new linkding.ApiClient('{% url 'bookmarks:api-root' %}')
|
||||||
const input = document.querySelector('#search input[name="q"]')
|
const input = document.querySelector('#search input[name="q"]')
|
||||||
|
@@ -22,7 +22,7 @@ def bookmark_form(context, form: BookmarkForm, cancel_url: str, bookmark_id: int
|
|||||||
def bookmark_search(context, search: BookmarkSearch, tags: [Tag], mode: str = ''):
|
def bookmark_search(context, search: BookmarkSearch, tags: [Tag], mode: str = ''):
|
||||||
tag_names = [tag.name for tag in tags]
|
tag_names = [tag.name for tag in tags]
|
||||||
tags_string = build_tag_string(tag_names, ' ')
|
tags_string = build_tag_string(tag_names, ' ')
|
||||||
form = BookmarkSearchForm(search, editable_fields=['q', 'sort'])
|
form = BookmarkSearchForm(search, editable_fields=['q', 'sort', 'shared'])
|
||||||
return {
|
return {
|
||||||
'request': context['request'],
|
'request': context['request'],
|
||||||
'search': search,
|
'search': search,
|
||||||
|
@@ -12,13 +12,18 @@ class BookmarkSearchFormTest(TestCase, BookmarkFactoryMixin):
|
|||||||
self.assertEqual(form['q'].initial, '')
|
self.assertEqual(form['q'].initial, '')
|
||||||
self.assertEqual(form['sort'].initial, BookmarkSearch.SORT_ADDED_DESC)
|
self.assertEqual(form['sort'].initial, BookmarkSearch.SORT_ADDED_DESC)
|
||||||
self.assertEqual(form['user'].initial, '')
|
self.assertEqual(form['user'].initial, '')
|
||||||
|
self.assertEqual(form['shared'].initial, '')
|
||||||
|
|
||||||
# with params
|
# with params
|
||||||
search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC, user='user123')
|
search = BookmarkSearch(q='search query',
|
||||||
|
sort=BookmarkSearch.SORT_ADDED_ASC,
|
||||||
|
user='user123',
|
||||||
|
shared=BookmarkSearch.FILTER_SHARED_SHARED)
|
||||||
form = BookmarkSearchForm(search)
|
form = BookmarkSearchForm(search)
|
||||||
self.assertEqual(form['q'].initial, 'search query')
|
self.assertEqual(form['q'].initial, 'search query')
|
||||||
self.assertEqual(form['sort'].initial, BookmarkSearch.SORT_ADDED_ASC)
|
self.assertEqual(form['sort'].initial, BookmarkSearch.SORT_ADDED_ASC)
|
||||||
self.assertEqual(form['user'].initial, 'user123')
|
self.assertEqual(form['user'].initial, 'user123')
|
||||||
|
self.assertEqual(form['shared'].initial, BookmarkSearch.FILTER_SHARED_SHARED)
|
||||||
|
|
||||||
def test_user_options(self):
|
def test_user_options(self):
|
||||||
users = [
|
users = [
|
||||||
@@ -43,16 +48,22 @@ class BookmarkSearchFormTest(TestCase, BookmarkFactoryMixin):
|
|||||||
self.assertEqual(len(form.hidden_fields()), 0)
|
self.assertEqual(len(form.hidden_fields()), 0)
|
||||||
|
|
||||||
# some modified params
|
# some modified params
|
||||||
search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC)
|
search = BookmarkSearch(q='search query',
|
||||||
|
sort=BookmarkSearch.SORT_ADDED_ASC)
|
||||||
form = BookmarkSearchForm(search)
|
form = BookmarkSearchForm(search)
|
||||||
self.assertCountEqual(form.hidden_fields(), [form['q'], form['sort']])
|
self.assertCountEqual(form.hidden_fields(), [form['q'], form['sort']])
|
||||||
|
|
||||||
# all modified params
|
# all modified params
|
||||||
search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC, user='user123')
|
search = BookmarkSearch(q='search query',
|
||||||
|
sort=BookmarkSearch.SORT_ADDED_ASC,
|
||||||
|
user='user123',
|
||||||
|
shared=BookmarkSearch.FILTER_SHARED_SHARED)
|
||||||
form = BookmarkSearchForm(search)
|
form = BookmarkSearchForm(search)
|
||||||
self.assertCountEqual(form.hidden_fields(), [form['q'], form['sort'], form['user']])
|
self.assertCountEqual(form.hidden_fields(), [form['q'], form['sort'], form['user'], form['shared']])
|
||||||
|
|
||||||
# some modified params are editable fields
|
# some modified params are editable fields
|
||||||
search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC, user='user123')
|
search = BookmarkSearch(q='search query',
|
||||||
|
sort=BookmarkSearch.SORT_ADDED_ASC,
|
||||||
|
user='user123')
|
||||||
form = BookmarkSearchForm(search, editable_fields=['q', 'user'])
|
form = BookmarkSearchForm(search, editable_fields=['q', 'user'])
|
||||||
self.assertCountEqual(form.hidden_fields(), [form['sort']])
|
self.assertCountEqual(form.hidden_fields(), [form['sort']])
|
||||||
|
@@ -13,6 +13,7 @@ class BookmarkSearchModelTest(TestCase):
|
|||||||
self.assertEqual(search.q, '')
|
self.assertEqual(search.q, '')
|
||||||
self.assertEqual(search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
self.assertEqual(search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
||||||
self.assertEqual(search.user, '')
|
self.assertEqual(search.user, '')
|
||||||
|
self.assertEqual(search.shared, '')
|
||||||
|
|
||||||
# some params
|
# some params
|
||||||
mock_request.GET = {
|
mock_request.GET = {
|
||||||
@@ -24,18 +25,21 @@ class BookmarkSearchModelTest(TestCase):
|
|||||||
self.assertEqual(bookmark_search.q, 'search query')
|
self.assertEqual(bookmark_search.q, 'search query')
|
||||||
self.assertEqual(bookmark_search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
self.assertEqual(bookmark_search.sort, BookmarkSearch.SORT_ADDED_DESC)
|
||||||
self.assertEqual(bookmark_search.user, 'user123')
|
self.assertEqual(bookmark_search.user, 'user123')
|
||||||
|
self.assertEqual(bookmark_search.shared, '')
|
||||||
|
|
||||||
# all params
|
# all params
|
||||||
mock_request.GET = {
|
mock_request.GET = {
|
||||||
'q': 'search query',
|
'q': 'search query',
|
||||||
'user': 'user123',
|
'user': 'user123',
|
||||||
'sort': BookmarkSearch.SORT_TITLE_ASC
|
'sort': BookmarkSearch.SORT_TITLE_ASC,
|
||||||
|
'shared': BookmarkSearch.FILTER_SHARED_SHARED,
|
||||||
}
|
}
|
||||||
|
|
||||||
search = BookmarkSearch.from_request(mock_request)
|
search = BookmarkSearch.from_request(mock_request)
|
||||||
self.assertEqual(search.q, 'search query')
|
self.assertEqual(search.q, 'search query')
|
||||||
self.assertEqual(search.user, 'user123')
|
self.assertEqual(search.user, 'user123')
|
||||||
self.assertEqual(search.sort, BookmarkSearch.SORT_TITLE_ASC)
|
self.assertEqual(search.sort, BookmarkSearch.SORT_TITLE_ASC)
|
||||||
|
self.assertEqual(search.shared, BookmarkSearch.FILTER_SHARED_SHARED)
|
||||||
|
|
||||||
def test_modified_params(self):
|
def test_modified_params(self):
|
||||||
# no params
|
# no params
|
||||||
@@ -44,7 +48,7 @@ class BookmarkSearchModelTest(TestCase):
|
|||||||
self.assertEqual(len(modified_params), 0)
|
self.assertEqual(len(modified_params), 0)
|
||||||
|
|
||||||
# params are default values
|
# params are default values
|
||||||
bookmark_search = BookmarkSearch(q='', sort=BookmarkSearch.SORT_ADDED_DESC, user='')
|
bookmark_search = BookmarkSearch(q='', sort=BookmarkSearch.SORT_ADDED_DESC, user='', shared='')
|
||||||
modified_params = bookmark_search.modified_params
|
modified_params = bookmark_search.modified_params
|
||||||
self.assertEqual(len(modified_params), 0)
|
self.assertEqual(len(modified_params), 0)
|
||||||
|
|
||||||
@@ -54,6 +58,6 @@ class BookmarkSearchModelTest(TestCase):
|
|||||||
self.assertCountEqual(modified_params, ['q', 'sort'])
|
self.assertCountEqual(modified_params, ['q', 'sort'])
|
||||||
|
|
||||||
# all modified params
|
# all modified params
|
||||||
bookmark_search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC, user='user123')
|
bookmark_search = BookmarkSearch(q='search query', sort=BookmarkSearch.SORT_ADDED_ASC, user='user123', shared=BookmarkSearch.FILTER_SHARED_SHARED)
|
||||||
modified_params = bookmark_search.modified_params
|
modified_params = bookmark_search.modified_params
|
||||||
self.assertCountEqual(modified_params, ['q', 'sort', 'user'])
|
self.assertCountEqual(modified_params, ['q', 'sort', 'user', 'shared'])
|
||||||
|
@@ -44,11 +44,13 @@ class BookmarkSearchTagTest(TestCase, BookmarkFactoryMixin):
|
|||||||
self.assertNoHiddenInput(rendered_template, 'user')
|
self.assertNoHiddenInput(rendered_template, 'user')
|
||||||
self.assertNoHiddenInput(rendered_template, 'q')
|
self.assertNoHiddenInput(rendered_template, 'q')
|
||||||
self.assertNoHiddenInput(rendered_template, 'sort')
|
self.assertNoHiddenInput(rendered_template, 'sort')
|
||||||
|
self.assertNoHiddenInput(rendered_template, 'shared')
|
||||||
|
|
||||||
# With params
|
# With params
|
||||||
url = '/test?q=foo&user=john&sort=title_asc'
|
url = '/test?q=foo&user=john&sort=title_asc&shared=shared'
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
|
||||||
self.assertHiddenInput(rendered_template, 'user', 'john')
|
self.assertHiddenInput(rendered_template, 'user', 'john')
|
||||||
self.assertNoHiddenInput(rendered_template, 'q')
|
self.assertNoHiddenInput(rendered_template, 'q')
|
||||||
self.assertNoHiddenInput(rendered_template, 'sort')
|
self.assertNoHiddenInput(rendered_template, 'sort')
|
||||||
|
self.assertNoHiddenInput(rendered_template, 'shared')
|
||||||
|
@@ -70,6 +70,25 @@ class BookmarksApiTestCase(LinkdingApiTestCase, BookmarkFactoryMixin):
|
|||||||
expected_status_code=status.HTTP_200_OK)
|
expected_status_code=status.HTTP_200_OK)
|
||||||
self.assertBookmarkListEqual(response.data['results'], bookmarks)
|
self.assertBookmarkListEqual(response.data['results'], bookmarks)
|
||||||
|
|
||||||
|
def test_list_bookmarks_filter_shared(self):
|
||||||
|
self.authenticate()
|
||||||
|
unshared_bookmarks = self.setup_numbered_bookmarks(5)
|
||||||
|
shared_bookmarks = self.setup_numbered_bookmarks(5, shared=True)
|
||||||
|
|
||||||
|
# Filter off
|
||||||
|
response = self.get(reverse('bookmarks:bookmark-list'), expected_status_code=status.HTTP_200_OK)
|
||||||
|
self.assertBookmarkListEqual(response.data['results'], unshared_bookmarks + shared_bookmarks)
|
||||||
|
|
||||||
|
# Filter shared
|
||||||
|
response = self.get(reverse('bookmarks:bookmark-list') + '?shared=shared',
|
||||||
|
expected_status_code=status.HTTP_200_OK)
|
||||||
|
self.assertBookmarkListEqual(response.data['results'], shared_bookmarks)
|
||||||
|
|
||||||
|
# Filter unshared
|
||||||
|
response = self.get(reverse('bookmarks:bookmark-list') + '?shared=unshared',
|
||||||
|
expected_status_code=status.HTTP_200_OK)
|
||||||
|
self.assertBookmarkListEqual(response.data['results'], unshared_bookmarks)
|
||||||
|
|
||||||
def test_list_bookmarks_should_respect_sort(self):
|
def test_list_bookmarks_should_respect_sort(self):
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
bookmarks = self.setup_numbered_bookmarks(5)
|
bookmarks = self.setup_numbered_bookmarks(5)
|
||||||
|
@@ -419,6 +419,25 @@ class QueriesTestCase(TestCase, BookmarkFactoryMixin):
|
|||||||
query = queries.query_archived_bookmarks(self.user, self.profile, BookmarkSearch(query='!unread'))
|
query = queries.query_archived_bookmarks(self.user, self.profile, BookmarkSearch(query='!unread'))
|
||||||
self.assertCountEqual(list(query), unread_bookmarks)
|
self.assertCountEqual(list(query), unread_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):
|
def test_query_bookmark_tags_should_return_all_tags_for_empty_query(self):
|
||||||
self.setup_tag_search_data()
|
self.setup_tag_search_data()
|
||||||
|
|
||||||
@@ -662,6 +681,29 @@ class QueriesTestCase(TestCase, BookmarkFactoryMixin):
|
|||||||
BookmarkSearch(query=f'!untagged #{tag.name}'))
|
BookmarkSearch(query=f'!untagged #{tag.name}'))
|
||||||
self.assertCountEqual(list(query), [])
|
self.assertCountEqual(list(query), [])
|
||||||
|
|
||||||
|
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):
|
def test_query_shared_bookmarks(self):
|
||||||
user1 = self.setup_user(enable_sharing=True)
|
user1 = self.setup_user(enable_sharing=True)
|
||||||
user2 = self.setup_user(enable_sharing=True)
|
user2 = self.setup_user(enable_sharing=True)
|
||||||
|
@@ -78,11 +78,13 @@ class UserSelectTagTest(TestCase, BookmarkFactoryMixin):
|
|||||||
self.assertNoHiddenInput(rendered_template, 'user')
|
self.assertNoHiddenInput(rendered_template, 'user')
|
||||||
self.assertNoHiddenInput(rendered_template, 'q')
|
self.assertNoHiddenInput(rendered_template, 'q')
|
||||||
self.assertNoHiddenInput(rendered_template, 'sort')
|
self.assertNoHiddenInput(rendered_template, 'sort')
|
||||||
|
self.assertNoHiddenInput(rendered_template, 'shared')
|
||||||
|
|
||||||
# With params
|
# With params
|
||||||
url = '/test?q=foo&user=john&sort=title_asc'
|
url = '/test?q=foo&user=john&sort=title_asc&shared=shared'
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
|
||||||
self.assertNoHiddenInput(rendered_template, 'user')
|
self.assertNoHiddenInput(rendered_template, 'user')
|
||||||
self.assertHiddenInput(rendered_template, 'q', 'foo')
|
self.assertHiddenInput(rendered_template, 'q', 'foo')
|
||||||
self.assertHiddenInput(rendered_template, 'sort', 'title_asc')
|
self.assertHiddenInput(rendered_template, 'sort', 'title_asc')
|
||||||
|
self.assertHiddenInput(rendered_template, 'shared', 'shared')
|
||||||
|
Reference in New Issue
Block a user