summaryrefslogtreecommitdiffstatshomepage
path: root/tests/api
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/api/test_archive.py7
-rw-r--r--tests/api/test_artist.py1
-rw-r--r--tests/api/test_character.py1
-rw-r--r--tests/api/test_circle.py1
-rw-r--r--tests/api/test_comic.py13
-rw-r--r--tests/api/test_comic_tag.py1
-rw-r--r--tests/api/test_db.py23
-rw-r--r--tests/api/test_filter.py100
-rw-r--r--tests/api/test_image.py1
-rw-r--r--tests/api/test_namespace.py1
-rw-r--r--tests/api/test_page.py1
-rw-r--r--tests/api/test_scraper_api.py5
-rw-r--r--tests/api/test_sort.py79
-rw-r--r--tests/api/test_statistics.py106
-rw-r--r--tests/api/test_tag.py1
-rw-r--r--tests/api/test_world.py1
16 files changed, 296 insertions, 46 deletions
diff --git a/tests/api/test_archive.py b/tests/api/test_archive.py
index 0ef3425..6e6d0b7 100644
--- a/tests/api/test_archive.py
+++ b/tests/api/test_archive.py
@@ -2,13 +2,14 @@ import os
from datetime import datetime as dt
from pathlib import Path
+import pytest
+from conftest import DB, Response
+from sqlalchemy import select
+
import hircine.config
import hircine.db as database
import hircine.thumbnailer as thumb
-import pytest
-from conftest import DB, Response
from hircine.db.models import Archive, Comic, Image, Page
-from sqlalchemy import select
@pytest.fixture
diff --git a/tests/api/test_artist.py b/tests/api/test_artist.py
index 8cb2f1a..fa58012 100644
--- a/tests/api/test_artist.py
+++ b/tests/api/test_artist.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import Artist
diff --git a/tests/api/test_character.py b/tests/api/test_character.py
index 567d2a4..3737d49 100644
--- a/tests/api/test_character.py
+++ b/tests/api/test_character.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import Character
diff --git a/tests/api/test_circle.py b/tests/api/test_circle.py
index a03ba89..bea46d7 100644
--- a/tests/api/test_circle.py
+++ b/tests/api/test_circle.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import Circle
diff --git a/tests/api/test_comic.py b/tests/api/test_comic.py
index d3fa51e..dcc5822 100644
--- a/tests/api/test_comic.py
+++ b/tests/api/test_comic.py
@@ -3,6 +3,7 @@ from datetime import datetime as dt
import pytest
from conftest import DB, Response
+
from hircine.db.models import (
Artist,
Circle,
@@ -1096,7 +1097,7 @@ async def test_upsert_comic_tags_uses_existing(upsert_comics, empty_comic):
@pytest.mark.parametrize(
- "key,list",
+ "key,items",
[
("artists", ["arty", "farty"]),
("tags", ["alien:medium", "human:tiny"]),
@@ -1115,11 +1116,11 @@ async def test_upsert_comic_tags_uses_existing(upsert_comics, empty_comic):
],
)
@pytest.mark.anyio
-async def test_upsert_comic_creates(upsert_comics, empty_comic, key, list):
+async def test_upsert_comic_creates(upsert_comics, empty_comic, key, items):
original_comic = await DB.add(empty_comic)
input = {
- key: {"names": list, "options": {"onMissing": "CREATE"}},
+ key: {"names": items, "options": {"onMissing": "CREATE"}},
}
response = Response(await upsert_comics(original_comic.id, input))
response.assert_is("UpsertSuccess")
@@ -1127,7 +1128,7 @@ async def test_upsert_comic_creates(upsert_comics, empty_comic, key, list):
comic = await DB.get(Comic, original_comic.id, full=True)
assert comic is not None
- assert set(list) == set([o.name for o in getattr(comic, key)])
+ assert set(items) == set([o.name for o in getattr(comic, key)])
@pytest.mark.anyio
@@ -1184,7 +1185,9 @@ async def test_upsert_comic_fails_creating_invalid_tag(upsert_comics, gen_comic,
response = Response(await upsert_comics(comic.id, input))
response.assert_is("InvalidParameterError")
assert response.parameter == "name"
- msg = "Invalid parameter 'name': ComicTag name must be specified as <namespace>:<tag>" # noqa: E501
+ msg = (
+ "Invalid parameter 'name': ComicTag name must be specified as <namespace>:<tag>"
+ )
assert response.message == msg
diff --git a/tests/api/test_comic_tag.py b/tests/api/test_comic_tag.py
index f536b79..d0878e2 100644
--- a/tests/api/test_comic_tag.py
+++ b/tests/api/test_comic_tag.py
@@ -2,6 +2,7 @@ from functools import partial
import pytest
from conftest import DB, Response
+
from hircine.db.models import Namespace, Tag
diff --git a/tests/api/test_db.py b/tests/api/test_db.py
index f53b90f..b030035 100644
--- a/tests/api/test_db.py
+++ b/tests/api/test_db.py
@@ -1,10 +1,16 @@
from datetime import datetime, timedelta, timezone
+import pytest
+from conftest import DB
+from sqlalchemy.exc import StatementError
+from sqlalchemy.orm import (
+ Mapped,
+ mapped_column,
+)
+
import hircine.db as database
import hircine.db.models as models
import hircine.db.ops as ops
-import pytest
-from conftest import DB
from hircine.db.models import (
Artist,
Base,
@@ -16,11 +22,6 @@ from hircine.db.models import (
Tag,
TagNamespaces,
)
-from sqlalchemy.exc import StatementError
-from sqlalchemy.orm import (
- Mapped,
- mapped_column,
-)
class Date(MixinID, Base):
@@ -66,8 +67,8 @@ async def test_models_retained_when_clearing_association(
comic = await DB.add(comic)
async with database.session() as s:
- object = await s.get(Comic, comic.id)
- setattr(object, key, [])
+ obj = await s.get(Comic, comic.id)
+ setattr(obj, key, [])
await s.commit()
assert await DB.get(assoccls, (comic.id, model.id)) is None
@@ -86,8 +87,8 @@ async def test_models_retained_when_clearing_comictag(empty_comic):
await DB.add(ct)
async with database.session() as s:
- object = await s.get(Comic, comic.id)
- object.tags = []
+ obj = await s.get(Comic, comic.id)
+ obj.tags = []
await s.commit()
assert await DB.get(ComicTag, (comic.id, ct.namespace_id, ct.tag_id)) is None
diff --git a/tests/api/test_filter.py b/tests/api/test_filter.py
index 67a953f..6eb2934 100644
--- a/tests/api/test_filter.py
+++ b/tests/api/test_filter.py
@@ -1,5 +1,6 @@
import pytest
from conftest import DB, Response
+
from hircine.db.models import Namespace, Tag
@@ -420,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)
@@ -519,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_image.py b/tests/api/test_image.py
index c8c26b3..e0e9251 100644
--- a/tests/api/test_image.py
+++ b/tests/api/test_image.py
@@ -1,5 +1,6 @@
import pytest
from conftest import DB
+
from hircine.api.types import Image
diff --git a/tests/api/test_namespace.py b/tests/api/test_namespace.py
index 450075b..2ffc118 100644
--- a/tests/api/test_namespace.py
+++ b/tests/api/test_namespace.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import Namespace
diff --git a/tests/api/test_page.py b/tests/api/test_page.py
index debd69a..cb06e3e 100644
--- a/tests/api/test_page.py
+++ b/tests/api/test_page.py
@@ -2,6 +2,7 @@ from datetime import datetime, timezone
import pytest
from conftest import DB
+
from hircine.api.types import Page
from hircine.db.models import Archive
diff --git a/tests/api/test_scraper_api.py b/tests/api/test_scraper_api.py
index 1edd74f..b917e39 100644
--- a/tests/api/test_scraper_api.py
+++ b/tests/api/test_scraper_api.py
@@ -1,8 +1,9 @@
+import pytest
+from conftest import DB, Response
+
import hircine.enums as enums
import hircine.plugins
import hircine.scraper.types as scraped
-import pytest
-from conftest import DB, Response
from hircine.scraper import ScrapeError, Scraper, ScrapeWarning
diff --git a/tests/api/test_sort.py b/tests/api/test_sort.py
index b3c8562..02a7ec3 100644
--- a/tests/api/test_sort.py
+++ b/tests/api/test_sort.py
@@ -1,6 +1,7 @@
import pytest
from conftest import DB, Response
-from hircine.db.models import Namespace
+
+from hircine.db.models import Namespace, Tag
@pytest.fixture
@@ -22,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) {
@@ -87,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)
@@ -134,4 +178,35 @@ async def test_query_namespace_sort_sort_name(query_namespace_sort):
response = Response(await query_namespace_sort({"on": "SORT_NAME"}))
response.assert_is("NamespaceFilterResult")
- assert ["two", "one"] == [edge["name"] for edge in response.edges]
+ 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)
diff --git a/tests/api/test_tag.py b/tests/api/test_tag.py
index c863a00..7970f3d 100644
--- a/tests/api/test_tag.py
+++ b/tests/api/test_tag.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import Namespace, Tag
diff --git a/tests/api/test_world.py b/tests/api/test_world.py
index a3926d1..3546c2c 100644
--- a/tests/api/test_world.py
+++ b/tests/api/test_world.py
@@ -3,6 +3,7 @@ from datetime import timezone
import pytest
from conftest import DB, Response
+
from hircine.db.models import World