diff options
Diffstat (limited to 'tests/api')
-rw-r--r-- | tests/api/test_filter.py | 99 | ||||
-rw-r--r-- | tests/api/test_sort.py | 76 | ||||
-rw-r--r-- | tests/api/test_statistics.py | 106 |
3 files changed, 257 insertions, 24 deletions
diff --git a/tests/api/test_filter.py b/tests/api/test_filter.py index 1438785..6eb2934 100644 --- a/tests/api/test_filter.py +++ b/tests/api/test_filter.py @@ -421,51 +421,59 @@ async def test_field_presence(query_comic_filter, gen_comic, empty_comic, filter "filter,ids", [ ( - {"include": {"artists": {"empty": True}}}, + {"include": {"artists": {"count": {"value": 0}}}}, [100], ), ( - {"include": {"artists": {"empty": False}}}, - [1, 2], + {"include": {"artists": {"count": {"value": 0, "operator": "EQUAL"}}}}, + [100], ), ( - {"exclude": {"artists": {"empty": True}}}, - [1, 2], + { + "include": { + "artists": {"count": {"value": 1, "operator": "GREATER_THAN"}} + } + }, + [1], ), ( - {"exclude": {"artists": {"empty": False}}}, - [100], + {"include": {"artists": {"count": {"value": 3, "operator": "LOWER_THAN"}}}}, + [1, 2, 100], ), ( - {"include": {"tags": {"empty": True}}}, - [100], + {"exclude": {"artists": {"count": {"value": 0}}}}, + [1, 2], ), ( - {"include": {"tags": {"empty": False}}}, + {"exclude": {"artists": {"count": {"value": 0, "operator": "EQUAL"}}}}, [1, 2], ), ( - {"exclude": {"tags": {"empty": True}}}, - [1, 2], + { + "exclude": { + "artists": {"count": {"value": 1, "operator": "GREATER_THAN"}} + } + }, + [2, 100], ), ( - {"exclude": {"tags": {"empty": False}}}, - [100], + {"exclude": {"artists": {"count": {"value": 3, "operator": "LOWER_THAN"}}}}, + [], ), ], ids=[ - "includes artist empty", - "includes artist not empty", - "excludes artist empty", - "excludes artist not empty", - "includes tags empty", - "includes tags not empty", - "excludes tags empty", - "excludes tags not empty", + "include equal (default)", + "include equal (explicit)", + "include greater than", + "include lower than", + "exclude equal (default)", + "exclude equal (explicit)", + "exclude greater than", + "exclude lower than", ], ) @pytest.mark.anyio -async def test_assoc_presence(query_comic_filter, gen_comic, empty_comic, filter, ids): +async def test_assoc_counts(query_comic_filter, gen_comic, empty_comic, filter, ids): await DB.add(next(gen_comic)) await DB.add(next(gen_comic)) await DB.add(empty_comic) @@ -520,3 +528,48 @@ async def test_tag_assoc_filter(query_tag_filter, gen_namespace, gen_tag, filter response.assert_is("TagFilterResult") assert id_list(response.edges) == ids + + +@pytest.mark.parametrize( + "filter,expect", + [ + ({"include": {"comics": {"count": {"value": 1}}}}, [2, 3]), + ({"include": {"comics": {"count": {"value": 2, "operator": "EQUAL"}}}}, [1, 4]), + ( + { + "include": { + "comics": {"count": {"value": 3, "operator": "GREATER_THAN"}} + } + }, + [], + ), + ( + {"include": {"comics": {"count": {"value": 2, "operator": "LOWER_THAN"}}}}, + [2, 3], + ), + ( + {"exclude": {"comics": {"count": {"value": 1}}}}, + [1, 4], + ), + ( + {"exclude": {"comics": {"count": {"value": 1, "operator": "LOWER_THAN"}}}}, + [1, 2, 3, 4], + ), + ], + ids=[ + "include equal (default)", + "include equal (explicit)", + "include greater than", + "include lower than", + "exclude equal (default)", + "exclude lower than", + ], +) +@pytest.mark.anyio +async def test_count_filter(query_string_filter, gen_comic, filter, expect): + await DB.add_all(*gen_comic) + + response = Response(await query_string_filter(filter)) + response.assert_is("ArtistFilterResult") + + assert id_list(response.edges) == expect diff --git a/tests/api/test_sort.py b/tests/api/test_sort.py index 404e3d6..02a7ec3 100644 --- a/tests/api/test_sort.py +++ b/tests/api/test_sort.py @@ -1,7 +1,7 @@ import pytest from conftest import DB, Response -from hircine.db.models import Namespace +from hircine.db.models import Namespace, Tag @pytest.fixture @@ -23,6 +23,24 @@ def query_comic_sort(execute_sort): @pytest.fixture +def query_artist_sort(execute_sort): + query = """ + query artists($sort: ArtistSortInput) { + artists(sort: $sort) { + __typename + count + edges { + id + name + } + } + } + """ + + return execute_sort(query) + + +@pytest.fixture def query_namespace_sort(execute_sort): query = """ query namespaces($sort: NamespaceSortInput) { @@ -88,6 +106,31 @@ async def test_query_comics_sort_tag_count(gen_comic, query_comic_sort, sort, re assert ids == [edge["id"] for edge in response.edges] +@pytest.mark.parametrize( + "sort,reverse,expect", + [ + ({"on": "COMIC_COUNT"}, False, [2, 3, 1, 4]), + ({"on": "COMIC_COUNT", "direction": "DESCENDING"}, True, [1, 4, 2, 3]), + ({"on": "COMIC_COUNT", "direction": "ASCENDING"}, False, [2, 3, 1, 4]), + ], + ids=[ + "ascending (default)", + "descending", + "ascending", + ], +) +@pytest.mark.anyio +async def test_query_artists_sort_comic_count( + gen_comic, query_artist_sort, sort, reverse, expect +): + await DB.add_all(*gen_comic) + + response = Response(await query_artist_sort(sort)) + response.assert_is("ArtistFilterResult") + + assert expect == [edge["id"] for edge in response.edges] + + @pytest.mark.anyio async def test_query_comics_sort_random(gen_comic, query_comic_sort): comics = await DB.add_all(*gen_comic) @@ -136,3 +179,34 @@ async def test_query_namespace_sort_sort_name(query_namespace_sort): response.assert_is("NamespaceFilterResult") assert [edge["name"] for edge in response.edges] == ["two", "one"] + + +@pytest.mark.parametrize( + "sort,reverse,expect", + [ + ({"on": "TAG_COUNT"}, False, [2, 1]), + ({"on": "TAG_COUNT", "direction": "DESCENDING"}, True, [1, 2]), + ({"on": "TAG_COUNT", "direction": "ASCENDING"}, False, [2, 1]), + ], + ids=[ + "ascending (default)", + "descending", + "ascending", + ], +) +@pytest.mark.anyio +async def test_query_namespace_sort_tag_count( + gen_comic, query_namespace_sort, sort, reverse, expect +): + namespace_foo = Namespace(id=1, name="foo") + namespace_bar = Namespace(id=2, name="bar") + + tag_foo = Tag(id=1, name="foo", namespaces=[namespace_foo]) + tag_bar = Tag(id=2, name="bar", namespaces=[namespace_foo, namespace_bar]) + + await DB.add_all(tag_foo, tag_bar) + + response = Response(await query_namespace_sort(sort)) + response.assert_is("NamespaceFilterResult") + + assert expect == [edge["id"] for edge in response.edges] diff --git a/tests/api/test_statistics.py b/tests/api/test_statistics.py new file mode 100644 index 0000000..98c8dc7 --- /dev/null +++ b/tests/api/test_statistics.py @@ -0,0 +1,106 @@ +import pytest +from conftest import DB, Response + +import hircine.plugins +from hircine.db.models import ( + Artist, + Character, + Circle, + Page, + Tag, + World, +) +from hircine.scraper import Scraper + +totals_fragment = """ + fragment Totals on Statistics { + total { + archives + artists + characters + circles + comics + namespaces + scrapers + tags + worlds + images + pages + comic { + artists + characters + circles + tags + worlds + } + } + } +""" + + +@pytest.fixture +def query_statistics(execute): + query = """ + query statistics { + statistics { + __typename + ... Totals + } + } + """ + + return execute(totals_fragment + query) + + +@pytest.mark.anyio +async def test_statistics_returns_totals( + gen_comic, gen_image, query_statistics, empty_plugins +): + comic = next(gen_comic) + await DB.add(comic) + await DB.add(Artist(name="foo")) + await DB.add(Character(name="foo")) + await DB.add(Circle(name="foo")) + await DB.add(World(name="foo")) + await DB.add(Tag(name="foo")) + + image = next(gen_image) + await DB.add(image) + await DB.add( + Page(id=100, index=100, path="100.png", image=image, archive=comic.archive) + ) + await DB.add( + Page(id=101, index=101, path="101.png", image=image, archive=comic.archive) + ) + + namespaces = set() + for tag in comic.tags: + namespaces.add(tag.namespace.id) + + class MockScraper(Scraper): + name = "Scraper" + + def scrape(self): + yield None + + hircine.plugins.register_scraper("mock", MockScraper) + + response = Response(await query_statistics()) + + response.assert_is("Statistics") + assert response.total["comics"] == 1 + assert response.total["archives"] == 1 + assert response.total["artists"] == len(comic.artists) + 1 + assert response.total["characters"] == len(comic.characters) + 1 + assert response.total["circles"] == len(comic.circles) + 1 + assert response.total["worlds"] == len(comic.worlds) + 1 + assert response.total["tags"] == len(comic.tags) + 1 + assert response.total["namespaces"] == len(namespaces) + assert response.total["images"] == len(comic.pages) + 1 + assert response.total["pages"] == len(comic.pages) + 2 + assert response.total["scrapers"] == 1 + assert response.total["comic"]["artists"] == len(comic.artists) + assert response.total["comic"]["characters"] == len(comic.characters) + assert response.total["comic"]["circles"] == len(comic.circles) + assert response.total["comic"]["tags"] == len(comic.tags) + assert response.total["comic"]["worlds"] == len(comic.worlds) |