< Summary

Information
Class: Api.Jobs.Mutations.LeasePendingJobsInput
Assembly: Api
File(s): /home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Jobs/Mutations/LeaseJobsMutation.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 1
Coverable lines: 1
Total lines: 89
Line coverage: 0%
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%210%

File(s)

/home/runner/work/ProjectRead.ing/ProjectRead.ing/Api/Jobs/Mutations/LeaseJobsMutation.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 System.Diagnostics;
 6using Api.Auth.Handlers;
 7using Api.Auth.Utils;
 8using Api.Database;
 9using Api.Database.Utils;
 10using Api.Jobs.DTOs;
 11using Api.Utils;
 12using FluentValidation;
 13using HotChocolate.Authorization;
 14using Microsoft.EntityFrameworkCore;
 15
 16namespace Api.Jobs.Mutations;
 17
 018public record LeasePendingJobsInput(string[] JobTypes, int MaxJobs);
 19
 20public record LeasePendingJobsPayload(ILeasedJob[] Jobs);
 21
 22[MutationType]
 23public static partial class LeaseJobMutations
 24{
 25    [Authorize(PermissionPolicyProvider.RemoteServicePolicyName)]
 26    // TODO: remove once the Jobs slice is wired: there is no IJobsInterfae implementation and no
 27    // object type implementing ILeasedJob yet, which breaks schema validation and the generated
 28    // ZeroQL client. Re-add the [InterfaceType] attributes and validate the input explicitly
 29    // (validator.ValidateOrThrowInputAsync) at that point.
 30    [GraphQLIgnore]
 31    public static async Task<LeasePendingJobsPayload> LeasePendingJobs(
 32        [Service] ICurrentServiceId idGetter,
 33        [Service] IEFTransactionDIAccessorService tx,
 34        [Service] IJobsInterfae jobsInterfae,
 35        [Service] JobDTOBuilder j,
 36        LeasePendingJobsInput input,
 37        CancellationToken ct
 38    )
 39    {
 40        await tx.BeginOrGetTransactionAsync();
 41        var jobDatas = await jobsInterfae.LeasePendingJobs(
 42            0,
 43            (uint)input.MaxJobs,
 44            idGetter.Id ?? throw new ArgumentNullException(nameof(idGetter)),
 45            input.JobTypes,
 46            ct
 47        );
 48        var jobs = jobDatas
 49            .Select(jd =>
 50                (
 51                    j.CreateFrom(jd.JobType, jd)
 52                    ?? throw new UnreachableException(
 53                        "There must not exist a job with a unregistered type"
 54                    )
 55                ).AsLeased()
 56            )
 57            .ToArray();
 58
 59        await tx.SaveAndCommitTX(ct);
 60
 61        return new LeasePendingJobsPayload(jobs);
 62    }
 63}
 64
 65public class LeasePendingJobsInputValidator : AbstractValidator<LeasePendingJobsInput>
 66{
 67    public LeasePendingJobsInputValidator(
 68        PGContext db,
 69        IEFTransactionDIAccessorService tx,
 70        ICurrentServiceId idGetter
 71    )
 72    {
 73        RuleFor(i => i).BeginTransaction(tx);
 74
 75        RuleFor(i => i.MaxJobs).GreaterThan(0).LessThan(128);
 76
 77        RuleFor(i => i.JobTypes)
 78            .MustAsync(
 79                async (_, jobTypes, ctx, ct) =>
 80                    await db
 81                        .RemoteServices.Where(s => s.Id == idGetter.Id)
 82                        .Select(s => s.AllowedJobs)
 83                        .Select(allowedTypes =>
 84                            jobTypes.All(jt => allowedTypes.Contains(jt))
 85                        )
 86                        .FirstOrDefaultAsync(ct)
 87            );
 88    }
 89}

Methods/Properties

.ctor(string[], int)