< Summary

Information
Class: Api.Works.Queries.Author
Assembly: Api
File(s): /home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Works/Queries/Author.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 123
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_IdPostfix()100%11100%

File(s)

/home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Works/Queries/Author.cs

#LineLine coverage
 1// SPDX-FileCopyrightText: 2026 Alper Çelik <alper@alper-celik.dev>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5using Api.Auth.Handlers;
 6using Api.Auth.Utils;
 7using Api.Database;
 8using GreenDonut.Data;
 9using HotChocolate.Types.Pagination;
 10using Microsoft.EntityFrameworkCore;
 11using Riok.Mapperly.Abstractions;
 12using static Api.Works.Queries.AuthorDataLoaders;
 13using static Api.Works.Queries.WorkDataLoaders;
 14
 15namespace Api.Works.Queries;
 16
 17[QueryType]
 18public static partial class AuthorQuery
 19{
 20    [PermissionCheckAuthorize(Auth.Models.UserPermissionBits.AuthorRead)]
 21    [UseFiltering]
 22    [UseSorting]
 23    public static async Task<PageConnection<Author>> GetAuthors(
 24        [Service] PGContext db,
 25        [Service] ICurrentUserId userId,
 26        [Service] IAuthorByIdDataLoader authorById,
 27        QueryContext<Author> qc,
 28        PagingArguments pg,
 29        CancellationToken ct
 30    ) =>
 31        await db
 32            .Authors.Where(a => a.OwnerId == userId.Id)
 33            .ProjectToDto()
 34            .WithQueryContext(qc)
 35            .ToPageWithDataLoaderAsync(pg, authorById, ct);
 36}
 37
 38[ObjectType<Author>]
 39public static partial class AuthorNode
 40{
 41    [PermissionCheckAuthorize(Auth.Models.UserPermissionBits.WorkRead)]
 42    [UseFiltering]
 43    [UseSorting]
 44    [GraphQLName("Works")]
 45    public static async Task<PageConnection<Work>> GetWorksByAuthor(
 46        [Parent] Author author,
 47        [Service] PGContext db,
 48        [Service] ICurrentUserId userId,
 49        [Service] IWorkByIdDataLoader workById,
 50        QueryContext<Work> qc,
 51        PagingArguments pagingArguments,
 52        CancellationToken ct
 53    )
 54    {
 55        return await db
 56            .Works.Where(w => w.OwnerId == userId.Id)
 57            .Where(w => w.Authors.Select(a => a.Id).Contains(author.Id))
 58            .ProjectToDto()
 59            .WithQueryContext(qc)
 60            .ToPageWithDataLoaderAsync(pagingArguments, workById, ct);
 61    }
 62
 63    [PermissionCheckAuthorize(Auth.Models.UserPermissionBits.AuthorRead)]
 64    [GraphQLIgnore]
 65    public static async Task<Author?> GetByIdAsync(
 66        IAuthorByIdDataLoader authorById,
 67        Guid id,
 68        CancellationToken ct
 69    ) => await authorById.LoadAsync(id, ct);
 70}
 71
 72public static class AuthorDataLoaders
 73{
 74    public interface IAuthorByIdDataLoader : IBatchDataLoader<Guid, Author>;
 75
 76    [GraphQLIgnore]
 77    [DataLoader<IAuthorByIdDataLoader>]
 78    public static async Task<IDictionary<Guid, Author>> GetAuthorByIdAsync(
 79        IReadOnlyList<Guid> ids,
 80        [Service] PGContext db,
 81        [Service] ICurrentUserId userId,
 82        CancellationToken ct
 83    )
 84    {
 85        return await db
 86            .Authors.Where(a => a.OwnerId == userId.Id)
 87            .Where(a => ids.Contains(a.Id))
 88            .ProjectToDto()
 89            .ToDictionaryAsync(a => a.Id, cancellationToken: ct);
 90    }
 91}
 92
 93[Node(
 94    NodeResolverType = typeof(AuthorNode),
 95    NodeResolver = nameof(AuthorNode.GetByIdAsync)
 96)]
 97public class Author : IEntityMetadata, INode
 98{
 199    public static byte IdPostfix => Models.Author.IdPostfix;
 100
 101    public Guid Id { get; set; }
 102    public int RowVersion { get; set; }
 103    public NodaTime.Instant MetadataAddedAt { get; set; }
 104    public NodaTime.Instant MetadataUpdatedAt { get; set; }
 105
 106    public string? FirstName { get; set; }
 107
 108    public string? LastName { get; set; }
 109
 110    public required string DisplayName { get; set; }
 111
 112    public required List<string> PenNames { get; set; }
 113}
 114
 115[Mapper]
 116public static partial class AuthorMapper
 117{
 118    public static partial IQueryable<Author> ProjectToDto(
 119        this IQueryable<Models.Author> q
 120    );
 121
 122    public static partial Author ToDto(Models.Author a);
 123}

Methods/Properties

get_IdPostfix()