< 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
95%
Covered lines: 41
Uncovered lines: 2
Coverable lines: 43
Total lines: 82
Line coverage: 95.3%
Branch coverage
83%
Covered branches: 15
Total branches: 18
Branch coverage: 83.3%
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%4483.33%
VerificarBasePath()50%2266.66%
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"] ?? string.Empty;
 823        _logger = logger;
 24
 825        if (string.IsNullOrEmpty(_basePath))
 026            _logger.LogWarning("Storage:BasePath no está configurado. Las operaciones de archivo fallarán si se intentan
 827    }
 28
 29    private void VerificarBasePath()
 30    {
 1131        if (string.IsNullOrEmpty(_basePath))
 032            throw new InvalidOperationException("Storage:BasePath no está configurado. Defina la variable de entorno Sto
 1133    }
 34
 35    public async Task<string> GuardarAsync(Stream contenido, string rutaRelativa, string contentType)
 36    {
 637        VerificarBasePath();
 638        if (!_allowedMimeTypes.Contains(contentType))
 139            throw new ArgumentException($"Tipo de archivo no permitido: {contentType}. Tipos permitidos: PDF, JPG, PNG, 
 40
 541        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 542        var directorio   = Path.GetDirectoryName(rutaCompleta)!;
 43
 544        Directory.CreateDirectory(directorio);
 45
 546        await using var fs = new FileStream(rutaCompleta, FileMode.Create, FileAccess.Write);
 547        await contenido.CopyToAsync(fs);
 48
 549        _logger.LogInformation("Archivo guardado: {Ruta}", rutaRelativa);
 550        return rutaRelativa;
 551    }
 52
 53    public Task EliminarAsync(string rutaRelativa)
 54    {
 355        VerificarBasePath();
 356        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 57
 358        if (File.Exists(rutaCompleta))
 59        {
 260            File.Delete(rutaCompleta);
 261            _logger.LogInformation("Archivo eliminado: {Ruta}", rutaRelativa);
 62
 263            var directorio = Path.GetDirectoryName(rutaCompleta)!;
 264            if (Directory.Exists(directorio) && !Directory.EnumerateFileSystemEntries(directorio).Any())
 265                Directory.Delete(directorio);
 66        }
 67
 368        return Task.CompletedTask;
 69    }
 70
 71    public Task<Stream> ObtenerAsync(string rutaRelativa)
 72    {
 273        VerificarBasePath();
 274        var rutaCompleta = Path.Combine(_basePath, rutaRelativa);
 75
 276        if (!File.Exists(rutaCompleta))
 177            throw new StorageFileNotFoundException($"Archivo no encontrado: {rutaRelativa}");
 78
 179        Stream stream = new FileStream(rutaCompleta, FileMode.Open, FileAccess.Read, FileShare.Read);
 180        return Task.FromResult(stream);
 81    }
 82}