summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorWolfgang Müller2025-02-20 14:27:14 +0100
committerWolfgang Müller2025-02-20 19:51:04 +0100
commitc6bf35aea63969b90463d6e70cb02ed61e4e3270 (patch)
tree1e650689385e23b204754dd1bba156654f95612d
parent39ecba8f6c5a2bc3b4f0629aecac99560c270539 (diff)
downloadhircine-c6bf35aea63969b90463d6e70cb02ed61e4e3270.tar.gz
Add remaining association count sort options
Now that we have all association counts mapped to their respective models we can easily allow sorting on them as well.
Diffstat (limited to '')
-rw-r--r--frontend/src/gql/graphql.ts13
-rw-r--r--frontend/src/lib/Enums.ts11
-rw-r--r--src/hircine/api/sort.py11
-rw-r--r--tests/api/test_sort.py75
4 files changed, 108 insertions, 2 deletions
diff --git a/frontend/src/gql/graphql.ts b/frontend/src/gql/graphql.ts
index 63f2c55..ac8512a 100644
--- a/frontend/src/gql/graphql.ts
+++ b/frontend/src/gql/graphql.ts
@@ -140,6 +140,7 @@ export type ArtistFilterResult = {
export type ArtistResponse = Artist | IdNotFoundError;
export enum ArtistSort {
+ ComicCount = 'COMIC_COUNT',
CreatedAt = 'CREATED_AT',
Name = 'NAME',
Random = 'RANDOM',
@@ -226,6 +227,7 @@ export type CharacterFilterResult = {
export type CharacterResponse = Character | IdNotFoundError;
export enum CharacterSort {
+ ComicCount = 'COMIC_COUNT',
CreatedAt = 'CREATED_AT',
Name = 'NAME',
Random = 'RANDOM',
@@ -273,6 +275,7 @@ export type CircleFilterResult = {
export type CircleResponse = Circle | IdNotFoundError;
export enum CircleSort {
+ ComicCount = 'COMIC_COUNT',
CreatedAt = 'CREATED_AT',
Name = 'NAME',
Random = 'RANDOM',
@@ -355,6 +358,9 @@ export type ComicScraper = {
};
export enum ComicSort {
+ ArtistCount = 'ARTIST_COUNT',
+ CharacterCount = 'CHARACTER_COUNT',
+ CircleCount = 'CIRCLE_COUNT',
CreatedAt = 'CREATED_AT',
Date = 'DATE',
OriginalTitle = 'ORIGINAL_TITLE',
@@ -362,7 +368,8 @@ export enum ComicSort {
Random = 'RANDOM',
TagCount = 'TAG_COUNT',
Title = 'TITLE',
- UpdatedAt = 'UPDATED_AT'
+ UpdatedAt = 'UPDATED_AT',
+ WorldCount = 'WORLD_COUNT'
}
export type ComicSortInput = {
@@ -895,6 +902,7 @@ export enum NamespaceSort {
Name = 'NAME',
Random = 'RANDOM',
SortName = 'SORT_NAME',
+ TagCount = 'TAG_COUNT',
UpdatedAt = 'UPDATED_AT'
}
@@ -1196,8 +1204,10 @@ export type TagFilterResult = {
export type TagResponse = FullTag | IdNotFoundError;
export enum TagSort {
+ ComicCount = 'COMIC_COUNT',
CreatedAt = 'CREATED_AT',
Name = 'NAME',
+ NamespaceCount = 'NAMESPACE_COUNT',
Random = 'RANDOM',
UpdatedAt = 'UPDATED_AT'
}
@@ -1362,6 +1372,7 @@ export type WorldFilterResult = {
export type WorldResponse = IdNotFoundError | World;
export enum WorldSort {
+ ComicCount = 'COMIC_COUNT',
CreatedAt = 'CREATED_AT',
Name = 'NAME',
Random = 'RANDOM',
diff --git a/frontend/src/lib/Enums.ts b/frontend/src/lib/Enums.ts
index 5133d49..292ed7d 100644
--- a/frontend/src/lib/Enums.ts
+++ b/frontend/src/lib/Enums.ts
@@ -73,6 +73,10 @@ export const ComicSortLabel: Record<ComicSort, string> = {
[ComicSort.CreatedAt]: 'Created At',
[ComicSort.UpdatedAt]: 'Updated At',
[ComicSort.TagCount]: 'Tag Count',
+ [ComicSort.ArtistCount]: 'Artist Count',
+ [ComicSort.CharacterCount]: 'Character Count',
+ [ComicSort.CircleCount]: 'Circle Count',
+ [ComicSort.WorldCount]: 'World Count',
[ComicSort.PageCount]: 'Page Count',
[ComicSort.Random]: 'Random'
};
@@ -81,6 +85,7 @@ export const ArtistSortLabel: Record<ArtistSort, string> = {
[ArtistSort.Name]: 'Name',
[ArtistSort.CreatedAt]: 'Created At',
[ArtistSort.UpdatedAt]: 'Updated At',
+ [ArtistSort.ComicCount]: 'Comic Count',
[ArtistSort.Random]: 'Random'
};
@@ -88,6 +93,7 @@ export const CharacterSortLabel: Record<CharacterSort, string> = {
[CharacterSort.Name]: 'Name',
[CharacterSort.CreatedAt]: 'Created At',
[CharacterSort.UpdatedAt]: 'Updated At',
+ [CharacterSort.ComicCount]: 'Comic Count',
[CharacterSort.Random]: 'Random'
};
@@ -95,6 +101,7 @@ export const CircleSortLabel: Record<CircleSort, string> = {
[CircleSort.Name]: 'Name',
[CircleSort.CreatedAt]: 'Created At',
[CircleSort.UpdatedAt]: 'Updated At',
+ [CircleSort.ComicCount]: 'Comic Count',
[CircleSort.Random]: 'Random'
};
@@ -103,12 +110,15 @@ export const NamespaceSortLabel: Record<NamespaceSort, string> = {
[NamespaceSort.SortName]: 'Sort Name',
[NamespaceSort.CreatedAt]: 'Created At',
[NamespaceSort.UpdatedAt]: 'Updated At',
+ [NamespaceSort.TagCount]: 'Tag Count',
[NamespaceSort.Random]: 'Random'
};
export const TagSortLabel: Record<TagSort, string> = {
[TagSort.Name]: 'Name',
[TagSort.CreatedAt]: 'Created At',
+ [TagSort.ComicCount]: 'Comic Count',
+ [TagSort.NamespaceCount]: 'Namespace Count',
[TagSort.UpdatedAt]: 'Updated At',
[TagSort.Random]: 'Random'
};
@@ -117,6 +127,7 @@ export const WorldSortLabel: Record<WorldSort, string> = {
[WorldSort.Name]: 'Name',
[WorldSort.CreatedAt]: 'Created At',
[WorldSort.UpdatedAt]: 'Updated At',
+ [WorldSort.ComicCount]: 'Comic Count',
[WorldSort.Random]: 'Random'
};
diff --git a/src/hircine/api/sort.py b/src/hircine/api/sort.py
index 17043a6..a4ccaf1 100644
--- a/src/hircine/api/sort.py
+++ b/src/hircine/api/sort.py
@@ -22,6 +22,10 @@ class ComicSort(enum.Enum):
DATE = strawberry.enum_value(models.Comic.date)
CREATED_AT = strawberry.enum_value(models.Comic.created_at)
UPDATED_AT = strawberry.enum_value(models.Comic.updated_at)
+ ARTIST_COUNT = strawberry.enum_value(models.Comic.artist_count)
+ CHARACTER_COUNT = strawberry.enum_value(models.Comic.character_count)
+ CIRCLE_COUNT = strawberry.enum_value(models.Comic.circle_count)
+ WORLD_COUNT = strawberry.enum_value(models.Comic.world_count)
TAG_COUNT = strawberry.enum_value(models.Comic.tag_count)
PAGE_COUNT = strawberry.enum_value(models.Comic.page_count)
RANDOM = "Random"
@@ -41,6 +45,7 @@ class ArtistSort(enum.Enum):
NAME = strawberry.enum_value(models.Artist.name)
CREATED_AT = strawberry.enum_value(models.Artist.created_at)
UPDATED_AT = strawberry.enum_value(models.Artist.updated_at)
+ COMIC_COUNT = strawberry.enum_value(models.Artist.comic_count)
RANDOM = "Random"
@@ -49,6 +54,7 @@ class CharacterSort(enum.Enum):
NAME = strawberry.enum_value(models.Character.name)
CREATED_AT = strawberry.enum_value(models.Character.created_at)
UPDATED_AT = strawberry.enum_value(models.Character.updated_at)
+ COMIC_COUNT = strawberry.enum_value(models.Character.comic_count)
RANDOM = "Random"
@@ -57,6 +63,7 @@ class CircleSort(enum.Enum):
NAME = strawberry.enum_value(models.Circle.name)
CREATED_AT = strawberry.enum_value(models.Circle.created_at)
UPDATED_AT = strawberry.enum_value(models.Circle.updated_at)
+ COMIC_COUNT = strawberry.enum_value(models.Circle.comic_count)
RANDOM = "Random"
@@ -66,6 +73,7 @@ class NamespaceSort(enum.Enum):
NAME = strawberry.enum_value(models.Namespace.name)
CREATED_AT = strawberry.enum_value(models.Namespace.created_at)
UPDATED_AT = strawberry.enum_value(models.Namespace.updated_at)
+ TAG_COUNT = strawberry.enum_value(models.Namespace.tag_count)
RANDOM = "Random"
@@ -74,6 +82,8 @@ class TagSort(enum.Enum):
NAME = strawberry.enum_value(models.Tag.name)
CREATED_AT = strawberry.enum_value(models.Tag.created_at)
UPDATED_AT = strawberry.enum_value(models.Tag.updated_at)
+ COMIC_COUNT = strawberry.enum_value(models.Tag.comic_count)
+ NAMESPACE_COUNT = strawberry.enum_value(models.Tag.namespace_count)
RANDOM = "Random"
@@ -82,6 +92,7 @@ class WorldSort(enum.Enum):
NAME = strawberry.enum_value(models.World.name)
CREATED_AT = strawberry.enum_value(models.World.created_at)
UPDATED_AT = strawberry.enum_value(models.World.updated_at)
+ COMIC_COUNT = strawberry.enum_value(models.World.comic_count)
RANDOM = "Random"
diff --git a/tests/api/test_sort.py b/tests/api/test_sort.py
index 404e3d6..65a4990 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,33 @@ 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]