< Summary

Information
Class: Api.Works.Queries.Tag
Assembly: Api
File(s): /home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Works/Queries/Tag.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 116
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/Tag.cs

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

Methods/Properties

get_IdPostfix()