mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-07-12 08:52:00 +02:00
fix: restore page navigation state (#933)
* refactor: store browsing history for navigation purposes * refactor: remove page_size from FilterState * refactor: move on from the term "filter" in favor of "BrowsingState" * fix: refactors didn't propagate to the tests * fix: ruff complaints * fix: remaing refactoring errors * fix: navigation works again * fix: also store and restore query
This commit is contained in:
@@ -3,7 +3,7 @@ from tempfile import TemporaryDirectory
|
||||
|
||||
import pytest
|
||||
|
||||
from tagstudio.core.library.alchemy.enums import FilterState
|
||||
from tagstudio.core.library.alchemy.enums import BrowsingState
|
||||
from tagstudio.core.library.alchemy.library import Library
|
||||
from tagstudio.core.utils.missing_files import MissingRegistry
|
||||
|
||||
@@ -28,5 +28,5 @@ def test_refresh_missing_files(library: Library):
|
||||
assert list(registry.fix_unlinked_entries()) == [0, 1]
|
||||
|
||||
# `bar.md` should be relinked to new correct path
|
||||
results = library.search_library(FilterState.from_path("bar.md", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
assert results[0].path == Path("bar.md")
|
||||
|
||||
@@ -135,7 +135,7 @@ def test_title_update(
|
||||
qt_driver.folders_to_tags_action = QAction(menu_bar)
|
||||
|
||||
# Trigger the update
|
||||
qt_driver.init_library(library_dir, open_status)
|
||||
qt_driver._init_library(library_dir, open_status)
|
||||
|
||||
# Assert the title is updated correctly
|
||||
qt_driver.main_window.setWindowTitle.assert_called_with(expected_title(library_dir, base_title))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from tagstudio.core.library.alchemy.enums import FilterState
|
||||
from tagstudio.core.library.alchemy.enums import BrowsingState
|
||||
from tagstudio.core.library.json.library import ItemType
|
||||
from tagstudio.qt.widgets.item_thumb import ItemThumb
|
||||
|
||||
@@ -66,7 +66,7 @@ if TYPE_CHECKING:
|
||||
# assert qt_driver.selected == [0, 1, 2]
|
||||
|
||||
|
||||
def test_library_state_update(qt_driver: "QtDriver"):
|
||||
def test_browsing_state_update(qt_driver: "QtDriver"):
|
||||
# Given
|
||||
for entry in qt_driver.lib.get_entries(with_joins=True):
|
||||
thumb = ItemThumb(ItemType.ENTRY, qt_driver.lib, qt_driver, (100, 100))
|
||||
@@ -74,27 +74,25 @@ def test_library_state_update(qt_driver: "QtDriver"):
|
||||
qt_driver.frame_content.append(entry)
|
||||
|
||||
# no filter, both items are returned
|
||||
qt_driver.filter_items()
|
||||
qt_driver.update_browsing_state()
|
||||
assert len(qt_driver.frame_content) == 2
|
||||
|
||||
# filter by tag
|
||||
state = FilterState.from_tag_name("foo", page_size=10)
|
||||
qt_driver.filter_items(state)
|
||||
assert qt_driver.filter.page_size == 10
|
||||
state = BrowsingState.from_tag_name("foo")
|
||||
qt_driver.update_browsing_state(state)
|
||||
assert len(qt_driver.frame_content) == 1
|
||||
entry = qt_driver.lib.get_entry_full(qt_driver.frame_content[0])
|
||||
assert list(entry.tags)[0].name == "foo"
|
||||
|
||||
# When state is not changed, previous one is still applied
|
||||
qt_driver.filter_items()
|
||||
assert qt_driver.filter.page_size == 10
|
||||
qt_driver.update_browsing_state()
|
||||
assert len(qt_driver.frame_content) == 1
|
||||
entry = qt_driver.lib.get_entry_full(qt_driver.frame_content[0])
|
||||
assert list(entry.tags)[0].name == "foo"
|
||||
|
||||
# When state property is changed, previous one is overwritten
|
||||
state = FilterState.from_path("*bar.md", page_size=qt_driver.settings.page_size)
|
||||
qt_driver.filter_items(state)
|
||||
state = BrowsingState.from_path("*bar.md")
|
||||
qt_driver.update_browsing_state(state)
|
||||
assert len(qt_driver.frame_content) == 1
|
||||
entry = qt_driver.lib.get_entry_full(qt_driver.frame_content[0])
|
||||
assert list(entry.tags)[0].name == "bar"
|
||||
|
||||
+34
-32
@@ -4,7 +4,7 @@ from tempfile import TemporaryDirectory
|
||||
import pytest
|
||||
|
||||
from tagstudio.core.enums import DefaultEnum, LibraryPrefs
|
||||
from tagstudio.core.library.alchemy.enums import FilterState
|
||||
from tagstudio.core.library.alchemy.enums import BrowsingState
|
||||
from tagstudio.core.library.alchemy.fields import TextField, _FieldID
|
||||
from tagstudio.core.library.alchemy.library import Library
|
||||
from tagstudio.core.library.alchemy.models import Entry, Tag
|
||||
@@ -123,7 +123,8 @@ def test_library_search(library: Library, generate_tag, entry_full):
|
||||
tag = list(entry_full.tags)[0]
|
||||
|
||||
results = library.search_library(
|
||||
FilterState.from_tag_name(tag.name, page_size=500),
|
||||
BrowsingState.from_tag_name(tag.name),
|
||||
page_size=500,
|
||||
)
|
||||
|
||||
assert results.total_count == 1
|
||||
@@ -152,7 +153,7 @@ def test_entries_count(library: Library):
|
||||
new_ids = library.add_entries(entries)
|
||||
assert len(new_ids) == 10
|
||||
|
||||
results = library.search_library(FilterState.show_all(page_size=5))
|
||||
results = library.search_library(BrowsingState.show_all(), page_size=5)
|
||||
|
||||
assert results.total_count == 12
|
||||
assert len(results) == 5
|
||||
@@ -199,9 +200,7 @@ def test_search_filter_extensions(library: Library, is_exclude: bool):
|
||||
library.set_prefs(LibraryPrefs.EXTENSION_LIST, ["md"])
|
||||
|
||||
# When
|
||||
results = library.search_library(
|
||||
FilterState.show_all(page_size=500),
|
||||
)
|
||||
results = library.search_library(BrowsingState.show_all(), page_size=500)
|
||||
|
||||
# Then
|
||||
assert results.total_count == 1
|
||||
@@ -221,7 +220,8 @@ def test_search_library_case_insensitive(library: Library):
|
||||
|
||||
# When
|
||||
results = library.search_library(
|
||||
FilterState.from_tag_name(tag.name.upper(), page_size=500),
|
||||
BrowsingState.from_tag_name(tag.name.upper()),
|
||||
page_size=500,
|
||||
)
|
||||
|
||||
# Then
|
||||
@@ -443,100 +443,102 @@ def test_library_prefs_multiple_identical_vals():
|
||||
|
||||
|
||||
def test_path_search_ilike(library: Library):
|
||||
results = library.search_library(FilterState.from_path("bar.md", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
assert len(results.items) == 1
|
||||
|
||||
|
||||
def test_path_search_like(library: Library):
|
||||
results = library.search_library(FilterState.from_path("BAR.MD", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("BAR.MD"), page_size=500)
|
||||
assert results.total_count == 0
|
||||
assert len(results.items) == 0
|
||||
|
||||
|
||||
def test_path_search_default_with_sep(library: Library):
|
||||
results = library.search_library(FilterState.from_path("one/two", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("one/two"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
assert len(results.items) == 1
|
||||
|
||||
|
||||
def test_path_search_glob_after(library: Library):
|
||||
results = library.search_library(FilterState.from_path("foo*", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("foo*"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
assert len(results.items) == 1
|
||||
|
||||
|
||||
def test_path_search_glob_in_front(library: Library):
|
||||
results = library.search_library(FilterState.from_path("*bar.md", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("*bar.md"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
assert len(results.items) == 1
|
||||
|
||||
|
||||
def test_path_search_glob_both_sides(library: Library):
|
||||
results = library.search_library(FilterState.from_path("*one/two*", page_size=500))
|
||||
results = library.search_library(BrowsingState.from_path("*one/two*"), page_size=500)
|
||||
assert results.total_count == 1
|
||||
assert len(results.items) == 1
|
||||
|
||||
|
||||
# TODO: deduplicate this code with pytest parametrisation or a for loop
|
||||
def test_path_search_ilike_glob_equality(library: Library):
|
||||
results_ilike = library.search_library(FilterState.from_path("one/two", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*one/two*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("one/two"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*one/two*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("bar.md", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*bar.md*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*bar.md*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("bar", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*bar*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("bar"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*bar*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("bar.md", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*bar.md*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*bar.md*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
|
||||
# TODO: isn't this the exact same as the one before?
|
||||
def test_path_search_like_glob_equality(library: Library):
|
||||
results_ilike = library.search_library(FilterState.from_path("ONE/two", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*ONE/two*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("ONE/two"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*ONE/two*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("BAR.MD", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*BAR.MD*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("BAR.MD"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*BAR.MD*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] == [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("BAR.MD", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*bar.md*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("BAR.MD"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*bar.md*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] != [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
results_ilike = library.search_library(FilterState.from_path("bar.md", page_size=500))
|
||||
results_glob = library.search_library(FilterState.from_path("*BAR.MD*", page_size=500))
|
||||
results_ilike = library.search_library(BrowsingState.from_path("bar.md"), page_size=500)
|
||||
results_glob = library.search_library(BrowsingState.from_path("*BAR.MD*"), page_size=500)
|
||||
assert [e.id for e in results_ilike.items] != [e.id for e in results_glob.items]
|
||||
results_ilike, results_glob = None, None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(["filetype", "num_of_filetype"], [("md", 1), ("txt", 1), ("png", 0)])
|
||||
def test_filetype_search(library: Library, filetype, num_of_filetype):
|
||||
results = library.search_library(FilterState.from_filetype(filetype, page_size=500))
|
||||
results = library.search_library(BrowsingState.from_filetype(filetype), page_size=500)
|
||||
assert len(results.items) == num_of_filetype
|
||||
|
||||
|
||||
@pytest.mark.parametrize(["filetype", "num_of_filetype"], [("png", 2), ("apng", 1), ("ng", 0)])
|
||||
def test_filetype_return_one_filetype(file_mediatypes_library: Library, filetype, num_of_filetype):
|
||||
results = file_mediatypes_library.search_library(
|
||||
FilterState.from_filetype(filetype, page_size=500)
|
||||
BrowsingState.from_filetype(filetype), page_size=500
|
||||
)
|
||||
assert len(results.items) == num_of_filetype
|
||||
|
||||
|
||||
@pytest.mark.parametrize(["mediatype", "num_of_mediatype"], [("plaintext", 2), ("image", 0)])
|
||||
def test_mediatype_search(library: Library, mediatype, num_of_mediatype):
|
||||
results = library.search_library(FilterState.from_mediatype(mediatype, page_size=500))
|
||||
results = library.search_library(BrowsingState.from_mediatype(mediatype), page_size=500)
|
||||
assert len(results.items) == num_of_mediatype
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import pytest
|
||||
|
||||
from tagstudio.core.library.alchemy.enums import FilterState
|
||||
from tagstudio.core.library.alchemy.enums import BrowsingState
|
||||
from tagstudio.core.library.alchemy.library import Library
|
||||
from tagstudio.core.query_lang.util import ParsingError
|
||||
|
||||
|
||||
def verify_count(lib: Library, query: str, count: int):
|
||||
results = lib.search_library(FilterState.from_search_query(query, page_size=500))
|
||||
results = lib.search_library(BrowsingState.from_search_query(query), page_size=500)
|
||||
assert results.total_count == count
|
||||
assert len(results.items) == count
|
||||
|
||||
@@ -136,4 +136,4 @@ def test_parent_tags(search_library: Library, query: str, count: int):
|
||||
)
|
||||
def test_syntax(search_library: Library, invalid_query: str):
|
||||
with pytest.raises(ParsingError) as e_info: # noqa: F841
|
||||
search_library.search_library(FilterState.from_search_query(invalid_query, page_size=500))
|
||||
search_library.search_library(BrowsingState.from_search_query(invalid_query), page_size=500)
|
||||
|
||||
Reference in New Issue
Block a user