< Summary

Information
Class: FAU.Logica.Services.FilesystemStorageService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/FilesystemStorageService.cs
Line coverage
100%
Covered lines: 36
Uncovered lines: 0
Coverable lines: 36
Total lines: 71
Line coverage: 100%
Branch coverage
92%
Covered branches: 13
Total branches: 14
Branch coverage: 92.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)50%22100%
GuardarAsync()100%44100%
EliminarAsync(...)100%66100%
ObtenerAsync(...)100%22100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/FilesystemStorageService.cs

#LineLine coverage
 1using Microsoft.Extensions.Configuration;
 2using Microsoft.Extensions.Logging;
 3
 4namespace FAU.Logica.Services;
 5
 6public class FilesystemStorageService : IStorageService
 7{
 8    private readonly string _basePath;
 9    private readonly ILogger<FilesystemStorageService> _logger;
 10
 111    private static readonly HashSet<string> _allowedMimeTypes = new(StringComparer.OrdinalIgnoreCase)
 112    {
 113        "application/pdf",
 114        "image/jpeg",
 115        "image/jpg",
 116        "image/png",
 117        "image/tiff"
 118    };
 19
 820    public FilesystemStorageService(IConfiguration config, ILogger<FilesystemStorageService> logger)
 21    {
 822        _basePath = config["Storage:BasePath"]
 823            ?? throw new InvalidOperationException("Storage:BasePath no está configurado.");
 824        _logger = logger;
 825    }
 26
 27    public async Task<string> GuardarAsync(Stream contenido, string rutaRelativa, string contentType)
 28    {
 629        if (!_allowedMimeTypes.Contains(contentType))
 130            throw new ArgumentException($"Tipo de archivo no permitido: {contentType}. Tipos permitidos: PDF, JPG, PNG, 
 31
 532        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 533        var directorio   = Path.GetDirectoryName(rutaCompleta)!;
 34
 535        Directory.CreateDirectory(directorio);
 36
 537        await using var fs = new FileStream(rutaCompleta, FileMode.Create, FileAccess.Write);
 538        await contenido.CopyToAsync(fs);
 39
 540        _logger.LogInformation("Archivo guardado: {Ruta}", rutaRelativa);
 541        return rutaRelativa;
 542    }
 43
 44    public Task EliminarAsync(string rutaRelativa)
 45    {
 346        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 47
 348        if (File.Exists(rutaCompleta))
 49        {
 250            File.Delete(rutaCompleta);
 251            _logger.LogInformation("Archivo eliminado: {Ruta}", rutaRelativa);
 52
 253            var directorio = Path.GetDirectoryName(rutaCompleta)!;
 254            if (Directory.Exists(directorio) && !Directory.EnumerateFileSystemEntries(directorio).Any())
 255                Directory.Delete(directorio);
 56        }
 57
 358        return Task.CompletedTask;
 59    }
 60
 61    public Task<Stream> ObtenerAsync(string rutaRelativa)
 62    {
 263        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 64
 265        if (!File.Exists(rutaCompleta))
 166            throw new StorageFileNotFoundException($"Archivo no encontrado: {rutaRelativa}");
 67
 168        Stream stream = new FileStream(rutaCompleta, FileMode.Open, FileAccess.Read, FileShare.Read);
 169        return Task.FromResult(stream);
 70    }
 71}