< Summary

Information
Class: Api.Files.Mutations.AddFileRecordWithFilePayload
Assembly: Api
File(s): /home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Files/Mutations/AddFileRecordWithFileMutation.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 67
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
.ctor(...)100%11100%

File(s)

/home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Files/Mutations/AddFileRecordWithFileMutation.cs

#LineLine coverage
 1// SPDX-FileCopyrightText: 2026 Alper Çelik <[email protected]>
 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.Utils;
 10using Api.Files.FileProviders;
 11using Api.Files.Queries;
 12using Api.Utils;
 13using FluentValidation;
 14using HotChocolate.Types;
 15
 16namespace Api.Files.Mutations;
 17
 18[MutationType]
 19public static partial class AddFileRecordWithFileMutations
 20{
 21    [PermissionCheckAuthorize(UserPermissionBits.FileWrite)]
 22    [Error(typeof(DomainError))]
 23    // The input type is shared with `addFileRecord`, so it cannot follow the derived name.
 24    [UseMutationConvention(InputTypeName = "AddFileRecordInput")]
 25    public static async Task<AddFileRecordWithFilePayload> AddFileRecordWithFileAsync(
 26        [Service] ICurrentUserId userId,
 27        [Service] IEFTransactionDIAccessorService txGetter,
 28        [Service] UserFileRouter router,
 29        [Service] IValidator<AddFileRecordInput> validator,
 30        AddFileRecordInput input,
 31        IFile file,
 32        CancellationToken ct
 33    )
 34    {
 35        await validator.ValidateOrThrowInputAsync(input, ct);
 36
 37        var tx = await txGetter.BeginOrGetTransactionAsync(ct);
 38        var ownerId = userId.Id!.Value;
 39
 40        var fileRecord = await router.CreateFileAsync(
 41            ownerId,
 42            input.FileKind,
 43            input.ContentType,
 44            input.OriginalFileName,
 45            input.SizeBytes,
 46            Convert.FromHexString(input.Sha256),
 47            ct
 48        );
 49
 50        if (
 51            await router.SetFileAsync(ownerId, fileRecord.Id, file.OpenReadStream(), ct)
 52            is null
 53        )
 54        {
 55            throw new DomainException(
 56                ErrorCodes.FILE_UPLOAD_FAILED,
 57                "File content did not match the declared size or SHA256"
 58            );
 59        }
 60
 61        await tx.CommitAsync(ct);
 62        return new AddFileRecordWithFilePayload(FileRecordMapper.ToDto(fileRecord));
 63    }
 64}
 65
 166public record AddFileRecordWithFilePayload(Queries.FileRecord FileRecord);
 67// Mostly Ai Generated - End