< Summary

Line coverage
85%
Covered lines: 17
Uncovered lines: 3
Coverable lines: 20
Total lines: 534
Line coverage: 85%
Branch coverage
100%
Covered branches: 6
Total branches: 6
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: .cctor()100%210%
File 2: .ctor(...)100%11100%
File 2: get_Order()100%210%
File 2: CanInvoke(...)100%44100%
File 2: InvokeAsync()100%22100%

File(s)

/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs

File '/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs' does not exist (any more).

/home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Middlewares/ImageProxyMiddleware.cs

#LineLine coverage
 1using Anichron.Core.Domain;
 2using Anichron.Worker.Ingestion.Pipeline;
 3using Anichron.Worker.Ingestion.Proxy;
 4using SixLabors.ImageSharp;
 5using SixLabors.ImageSharp.PixelFormats;
 6using System.IO.Abstractions;
 7
 8namespace Anichron.Worker.Ingestion.Middlewares;
 9
 2010internal sealed partial class ImageProxyMiddleware(
 2011    IEnumerable<IImageProxyGenerator> generators,
 2012    IProxyDirectoryStrategy proxyDirectoryStrategy,
 2013    ProxyStagingWriter stagingWriter,
 2014    IFileSystem fileSystem,
 2015    ILogger<ImageProxyMiddleware> logger) : IIngestionMiddleware
 16{
 017    public int Order => IngestionOrder.ImageProxy;
 18    public bool CanInvoke(IngestionContext context)
 319        => context.Item.PrimaryMediaType is MediaType.Image or MediaType.LivePhoto;
 20
 21    public async Task InvokeAsync(IngestionContext context, IngestionDelegate next, CancellationToken ct)
 1722    {
 23        // Ordering guarantees ContentHashingMiddleware ran first; suppression is safe.
 1724        var proxyDirectoryName = proxyDirectoryStrategy.GetDirectory(context.Config.Id, context.ContentHash!);
 1725        var sourceBytes = await fileSystem.File.ReadAllBytesAsync(context.Item.AbsolutePath, ct);
 26
 1727        await using var ms = new MemoryStream(sourceBytes);
 1728        using var image = await Image.LoadAsync<Rgba32>(ms, ct);
 29
 1730        var writes = generators.Select(WriteProxyAsync).ToArray();
 1731        await Task.WhenAll(writes);
 32
 1633        Log.ProxiesGenerated(logger, writes.Length, context.Item.RelativePath);
 1634        await next(context, ct);
 35
 36        Task WriteProxyAsync(IImageProxyGenerator generator)
 37        {
 38            return stagingWriter.WriteAsync(
 39                context,
 40                $"{proxyDirectoryName}/{generator.FileName}",
 41                generator.ProxyType,
 42                ProduceAsync,
 43                ct);
 44
 45            async Task ProduceAsync(string temporaryPath, CancellationToken token)
 46            {
 47                using var clone = image.Clone();
 48                var bytes = await generator.GenerateAsync(clone, token);
 49                await fileSystem.File.WriteAllBytesAsync(temporaryPath, bytes, token);
 50            }
 51        }
 1652    }
 53
 54    private static partial class Log
 55    {
 56        [LoggerMessage(Level = LogLevel.Information, Message = "Generated {Count} proxy files for {RelativePath}.")]
 57        public static partial void ProxiesGenerated(ILogger logger, int count, string relativePath);
 58    }
 59}