< Summary

Line coverage
100%
Covered lines: 55
Uncovered lines: 0
Coverable lines: 55
Total lines: 201
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: GetSha256(...)100%11100%
File 1: GetByIdAsync()100%11100%
File 2: Initialize(...)100%22100%
File 2: GetSha256()100%11100%
File 2: GetSha256(...)100%11100%

File(s)

/home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Files/Queries/FileRecord.cs

#LineLine coverage
 1// SPDX-FileCopyrightText: 2026 Alper Çelik <alper@alper-celik.dev>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5// Mostly Ai Generated - Start
 6using Api.Auth.Handlers;
 7using Api.Auth.Models;
 8using Api.Auth.Utils;
 9using Api.Database;
 10using GreenDonut.Data;
 11using HotChocolate.Types.Pagination;
 12using Microsoft.EntityFrameworkCore;
 13using Riok.Mapperly.Abstractions;
 14using static Api.Files.Queries.FileRecordDataLoaders;
 15
 16namespace Api.Files.Queries;
 17
 18[QueryType]
 19public static partial class FileRecordQuery
 20{
 21    [PermissionCheckAuthorize(UserPermissionBits.FileRead)]
 22    [UseFiltering]
 23    [UseSorting]
 24    public static async Task<PageConnection<FileRecord>> GetFileRecords(
 25        [Service] PGContext db,
 26        [Service] ICurrentUserId userId,
 27        [Service] IFileRecordByIdDataLoader fileRecordById,
 28        QueryContext<FileRecord> qc,
 29        PagingArguments pagingArguments,
 30        CancellationToken ct
 31    )
 32    {
 33        return await db
 34            .FileRecords.Where(f => f.OwnerId == userId.Id)
 35            .ProjectToDto()
 36            .WithQueryContext(qc)
 37            .ToPageWithDataLoaderAsync(pagingArguments, fileRecordById, ct);
 38    }
 39}
 40
 41[ObjectType<FileRecord>]
 42public static partial class FileRecordNode
 43{
 44    [PermissionCheckAuthorize(UserPermissionBits.FileRead)]
 45    [GraphQLName("sha256")]
 46    public static string GetSha256([Parent] FileRecord fileRecord) =>
 147        Convert.ToHexStringLower(fileRecord.SHA256);
 48
 49    [PermissionCheckAuthorize(UserPermissionBits.FileRead)]
 50    [GraphQLIgnore]
 51    public static async Task<FileRecord?> GetByIdAsync(
 52        [Service] IFileRecordByIdDataLoader fileRecordById,
 53        Guid id,
 54        CancellationToken ct
 155    ) => await fileRecordById.LoadAsync(id, cancellationToken: ct);
 56}
 57
 58public static class FileRecordDataLoaders
 59{
 60    public interface IFileRecordByIdDataLoader : IBatchDataLoader<Guid, FileRecord>;
 61
 62    [GraphQLIgnore]
 63    [DataLoader<IFileRecordByIdDataLoader>]
 64    public static async Task<IDictionary<Guid, FileRecord>> GetFileRecordByIdAsync(
 65        IReadOnlyList<Guid> ids,
 66        [Service] PGContext db,
 67        [Service] ICurrentUserId userId,
 68        CancellationToken ct
 69    )
 70    {
 71        return await db
 72            .FileRecords.Where(f => f.OwnerId == userId.Id)
 73            .Where(f => ids.Contains(f.Id))
 74            .ProjectToDto()
 75            .ToDictionaryAsync(f => f.Id, cancellationToken: ct);
 76    }
 77}
 78
 79[Node(
 80    NodeResolverType = typeof(FileRecordNode),
 81    NodeResolver = nameof(FileRecordNode.GetByIdAsync)
 82)]
 83public class FileRecord : IEntityMetadata, INode
 84{
 85    public static byte IdPostfix => Models.FileRecord.IdPostfix;
 86
 87    public Guid Id { get; set; }
 88    public int RowVersion { get; set; }
 89    public NodaTime.Instant MetadataAddedAt { get; set; }
 90    public NodaTime.Instant MetadataUpdatedAt { get; set; }
 91
 92    public FileKind FileKind { get; set; }
 93    public Guid FileProviderBackendConfigId { get; set; }
 94
 95    public bool Uploaded { get; set; }
 96
 97    public string? OriginalFileName { get; set; }
 98    public required string ContentType { get; set; }
 99    public long SizeBytes { get; set; }
 100
 101    [GraphQLIgnore]
 102    public required byte[] SHA256 { get; set; }
 103}
 104
 105[Mapper]
 106public static partial class FileRecordMapper
 107{
 108    public static partial FileRecord? ToDto(Models.FileRecord? f);
 109
 110    public static partial IQueryable<FileRecord> ProjectToDto(
 111        this IQueryable<Models.FileRecord> q
 112    );
 113}
 114// Mostly Ai Generated - End

/home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/obj/Debug/net10.0/generated/HotChocolate.Types.Analyzers/HotChocolate.Types.Analyzers.GraphQLServerGenerator/FileRecordNode.DBitlzXCyzNxvLaGVkShUA.hc.g.cs

#LineLine coverage
 1// <auto-generated/>
 2
 3#nullable enable
 4#pragma warning disable
 5
 6using System;
 7using System.Runtime.CompilerServices;
 8using HotChocolate;
 9using HotChocolate.Types;
 10using HotChocolate.Execution.Configuration;
 11using Microsoft.Extensions.DependencyInjection;
 12using HotChocolate.Internal;
 13
 14namespace Api.Files.Queries
 15{
 16    public static partial class FileRecordNode
 17    {
 18        internal static void Initialize(global::HotChocolate.Types.IObjectTypeDescriptor<global::Api.Files.Queries.FileR
 119        {
 120            var extension = descriptor.Extend();
 121            var configuration = extension.Configuration;
 122            var thisType = typeof(global::Api.Files.Queries.FileRecordNode);
 123            var bindingResolver = extension.Context.ParameterBindingResolver;
 124            var resolvers = new __Resolvers();
 25
 126            var naming = descriptor.Extend().Context.Naming;
 27
 128            descriptor
 129                .Field(naming.GetMemberName("sha256", global::HotChocolate.Types.MemberKind.ObjectField))
 130                .ExtendWith(static (field, context) =>
 131                {
 132                    var configuration = field.Configuration;
 133                    var typeInspector = field.Context.TypeInspector;
 134                    var bindingResolver = field.Context.ParameterBindingResolver;
 135                    var naming = field.Context.Naming;
 136
 137                    configuration.Type = global::HotChocolate.Types.Descriptors.TypeReference.Create(
 138                        typeInspector.GetTypeRef(typeof(string), HotChocolate.Types.TypeContext.Output),
 139                        new global::HotChocolate.Language.NonNullTypeNode(new global::HotChocolate.Language.NamedTypeNod
 140                    configuration.ResultType = typeof(string);
 141                    configuration.DeclaringType = context.ThisType;
 142
 143                    configuration.SetSourceGeneratorFlags();
 144
 145                    configuration.Member = context.ThisType.GetMethod(
 146                        "GetSha256",
 147                        global::HotChocolate.Utilities.ReflectionUtils.StaticMemberFlags,
 148                        new global::System.Type[]
 149                        {
 150                            typeof(global::Api.Files.Queries.FileRecord)
 151                        })!;
 152
 153                    var fieldDescriptor = global::HotChocolate.Types.Descriptors.ObjectFieldDescriptor.From(field.Contex
 154                    HotChocolate.Internal.ConfigurationHelper.ApplyConfiguration(
 155                        field.Context,
 156                        fieldDescriptor,
 157                        configuration.Member,
 158                        new global::Api.Auth.Handlers.PermissionCheckAuthorizeAttribute(global::Api.Auth.Models.UserPerm
 159                    configuration.ConfigurationsAreApplied = true;
 160                    fieldDescriptor.CreateConfiguration();
 161
 162                    configuration.Resolvers = context.Resolvers.GetSha256();
 163                },
 164                (Resolvers: resolvers, ThisType: thisType));
 65
 66            Configure(descriptor);
 167        }
 68
 69        static partial void Configure(global::HotChocolate.Types.IObjectTypeDescriptor<global::Api.Files.Queries.FileRec
 70
 71        private sealed class __Resolvers
 72        {
 73            public HotChocolate.Resolvers.FieldResolverDelegates GetSha256()
 174            {
 175                return new global::HotChocolate.Resolvers.FieldResolverDelegates(pureResolver: GetSha256);
 176            }
 77
 78            private global::System.Object? GetSha256(global::HotChocolate.Resolvers.IResolverContext context)
 179            {
 180                var args0 = context.Parent<global::Api.Files.Queries.FileRecord>();
 181                var result = global::Api.Files.Queries.FileRecordNode.GetSha256(args0);
 182                return result;
 183            }
 84        }
 85    }
 86}
 87