diff options
author | Wolfgang Müller | 2025-02-20 14:27:14 +0100 |
---|---|---|
committer | Wolfgang Müller | 2025-02-20 19:51:04 +0100 |
commit | c6bf35aea63969b90463d6e70cb02ed61e4e3270 (patch) | |
tree | 1e650689385e23b204754dd1bba156654f95612d | |
parent | 39ecba8f6c5a2bc3b4f0629aecac99560c270539 (diff) | |
download | hircine-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.ts | 13 | ||||
-rw-r--r-- | frontend/src/lib/Enums.ts | 11 | ||||
-rw-r--r-- | src/hircine/api/sort.py | 11 | ||||
-rw-r--r-- | tests/api/test_sort.py | 75 |
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] |