Merge pull request 'chore(tests): dotnet format sobre archivos pre-existentes' (#32) from chore/dotnet-format-testfixtures into main

This commit was merged in pull request #32.
This commit is contained in:
2026-04-19 10:41:14 +00:00
13 changed files with 110 additions and 102 deletions

View File

@@ -53,12 +53,12 @@ public sealed class FiscalController : ControllerBase
IValidator<UpdateIngresosBrutosCommand> updateIibbValidator, IValidator<UpdateIngresosBrutosCommand> updateIibbValidator,
IValidator<NuevaVersionIngresosBrutosCommand> nuevaVersionIibbValidator) IValidator<NuevaVersionIngresosBrutosCommand> nuevaVersionIibbValidator)
{ {
_dispatcher = dispatcher; _dispatcher = dispatcher;
_createIvaValidator = createIvaValidator; _createIvaValidator = createIvaValidator;
_updateIvaValidator = updateIvaValidator; _updateIvaValidator = updateIvaValidator;
_nuevaVersionIvaValidator = nuevaVersionIvaValidator; _nuevaVersionIvaValidator = nuevaVersionIvaValidator;
_createIibbValidator = createIibbValidator; _createIibbValidator = createIibbValidator;
_updateIibbValidator = updateIibbValidator; _updateIibbValidator = updateIibbValidator;
_nuevaVersionIibbValidator = nuevaVersionIibbValidator; _nuevaVersionIibbValidator = nuevaVersionIibbValidator;
} }
@@ -78,15 +78,15 @@ public sealed class FiscalController : ControllerBase
[FromQuery] bool? activo = null, [FromQuery] bool? activo = null,
[FromQuery] string? codigo = null) [FromQuery] string? codigo = null)
{ {
if (page < 1) return BadRequest(new { error = "page must be >= 1" }); if (page < 1) return BadRequest(new { error = "page must be >= 1" });
if (pageSize < 1) return BadRequest(new { error = "pageSize must be >= 1" }); if (pageSize < 1) return BadRequest(new { error = "pageSize must be >= 1" });
var query = new ListTiposDeIvaQuery(page, pageSize, activo, codigo); var query = new ListTiposDeIvaQuery(page, pageSize, activo, codigo);
var result = await _dispatcher.Send<ListTiposDeIvaQuery, PagedResult<TipoDeIvaDto>>(query); var result = await _dispatcher.Send<ListTiposDeIvaQuery, PagedResult<TipoDeIvaDto>>(query);
return Ok(new return Ok(new
{ {
Items = result.Items.Select(FiscalContractMapper.ToIvaResponse).ToList(), Items = result.Items.Select(FiscalContractMapper.ToIvaResponse).ToList(),
result.Page, result.Page,
result.PageSize, result.PageSize,
result.Total result.Total
@@ -102,7 +102,7 @@ public sealed class FiscalController : ControllerBase
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetIvaById([FromRoute] int id) public async Task<IActionResult> GetIvaById([FromRoute] int id)
{ {
var query = new GetTipoDeIvaByIdQuery(id); var query = new GetTipoDeIvaByIdQuery(id);
var result = await _dispatcher.Send<GetTipoDeIvaByIdQuery, TipoDeIvaDto>(query); var result = await _dispatcher.Send<GetTipoDeIvaByIdQuery, TipoDeIvaDto>(query);
return Ok(FiscalContractMapper.ToIvaResponse(result)); return Ok(FiscalContractMapper.ToIvaResponse(result));
} }
@@ -115,7 +115,7 @@ public sealed class FiscalController : ControllerBase
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<IActionResult> GetHistorialIva([FromRoute] int id) public async Task<IActionResult> GetHistorialIva([FromRoute] int id)
{ {
var query = new GetHistorialTipoDeIvaQuery(id); var query = new GetHistorialTipoDeIvaQuery(id);
var result = await _dispatcher.Send<GetHistorialTipoDeIvaQuery, IReadOnlyList<HistorialCadenaDto>>(query); var result = await _dispatcher.Send<GetHistorialTipoDeIvaQuery, IReadOnlyList<HistorialCadenaDto>>(query);
return Ok(result.Select(FiscalContractMapper.ToHistorialIvaResponse).ToList()); return Ok(result.Select(FiscalContractMapper.ToHistorialIvaResponse).ToList());
} }
@@ -143,10 +143,10 @@ public sealed class FiscalController : ControllerBase
} }
var command = new CreateTipoDeIvaCommand( var command = new CreateTipoDeIvaCommand(
Codigo: request.Codigo ?? string.Empty, Codigo: request.Codigo ?? string.Empty,
Descripcion: request.Descripcion ?? string.Empty, Descripcion: request.Descripcion ?? string.Empty,
Porcentaje: request.Porcentaje ?? 0m, Porcentaje: request.Porcentaje ?? 0m,
AplicaIVA: request.AplicaIVA ?? false, AplicaIVA: request.AplicaIVA ?? false,
VigenciaDesde: vigenciaDesde.Value, VigenciaDesde: vigenciaDesde.Value,
VigenciaHasta: vigenciaHasta); VigenciaHasta: vigenciaHasta);
@@ -202,11 +202,11 @@ public sealed class FiscalController : ControllerBase
return BadRequest(new { error = "Request body is required" }); return BadRequest(new { error = "Request body is required" });
var command = new UpdateTipoDeIvaCommand( var command = new UpdateTipoDeIvaCommand(
Id: id, Id: id,
Codigo: request.Codigo ?? string.Empty, Codigo: request.Codigo ?? string.Empty,
Descripcion: request.Descripcion ?? string.Empty, Descripcion: request.Descripcion ?? string.Empty,
AplicaIVA: request.AplicaIVA ?? false, AplicaIVA: request.AplicaIVA ?? false,
Activo: request.Activo ?? true); Activo: request.Activo ?? true);
var validation = await _updateIvaValidator.ValidateAsync(command); var validation = await _updateIvaValidator.ValidateAsync(command);
if (!validation.IsValid) if (!validation.IsValid)
@@ -239,9 +239,9 @@ public sealed class FiscalController : ControllerBase
return BadRequest(new { error = "vigenciaDesde must be a valid date (yyyy-MM-dd)" }); return BadRequest(new { error = "vigenciaDesde must be a valid date (yyyy-MM-dd)" });
var command = new NuevaVersionTipoDeIvaCommand( var command = new NuevaVersionTipoDeIvaCommand(
PredecesoraId: id, PredecesoraId: id,
NuevoPorcentaje: request.Porcentaje ?? 0m, NuevoPorcentaje: request.Porcentaje ?? 0m,
VigenciaDesde: vigenciaDesde.Value); VigenciaDesde: vigenciaDesde.Value);
var validation = await _nuevaVersionIvaValidator.ValidateAsync(command); var validation = await _nuevaVersionIvaValidator.ValidateAsync(command);
if (!validation.IsValid) if (!validation.IsValid)
@@ -269,7 +269,7 @@ public sealed class FiscalController : ControllerBase
public async Task<IActionResult> DeactivateIva([FromRoute] int id) public async Task<IActionResult> DeactivateIva([FromRoute] int id)
{ {
var command = new DeactivateTipoDeIvaCommand(id); var command = new DeactivateTipoDeIvaCommand(id);
var result = await _dispatcher.Send<DeactivateTipoDeIvaCommand, TipoDeIvaDto>(command); var result = await _dispatcher.Send<DeactivateTipoDeIvaCommand, TipoDeIvaDto>(command);
return Ok(FiscalContractMapper.ToIvaResponse(result)); return Ok(FiscalContractMapper.ToIvaResponse(result));
} }
@@ -283,7 +283,7 @@ public sealed class FiscalController : ControllerBase
public async Task<IActionResult> ReactivateIva([FromRoute] int id) public async Task<IActionResult> ReactivateIva([FromRoute] int id)
{ {
var command = new ReactivateTipoDeIvaCommand(id); var command = new ReactivateTipoDeIvaCommand(id);
var result = await _dispatcher.Send<ReactivateTipoDeIvaCommand, TipoDeIvaDto>(command); var result = await _dispatcher.Send<ReactivateTipoDeIvaCommand, TipoDeIvaDto>(command);
return Ok(FiscalContractMapper.ToIvaResponse(result)); return Ok(FiscalContractMapper.ToIvaResponse(result));
} }
@@ -303,7 +303,7 @@ public sealed class FiscalController : ControllerBase
[FromQuery] bool? activo = null, [FromQuery] bool? activo = null,
[FromQuery] string? provincia = null) [FromQuery] string? provincia = null)
{ {
if (page < 1) return BadRequest(new { error = "page must be >= 1" }); if (page < 1) return BadRequest(new { error = "page must be >= 1" });
if (pageSize < 1) return BadRequest(new { error = "pageSize must be >= 1" }); if (pageSize < 1) return BadRequest(new { error = "pageSize must be >= 1" });
ProvinciaArgentina? provinciaEnum = null; ProvinciaArgentina? provinciaEnum = null;
@@ -314,12 +314,12 @@ public sealed class FiscalController : ControllerBase
provinciaEnum = parsed; provinciaEnum = parsed;
} }
var query = new ListIngresosBrutosQuery(page, pageSize, activo, provinciaEnum); var query = new ListIngresosBrutosQuery(page, pageSize, activo, provinciaEnum);
var result = await _dispatcher.Send<ListIngresosBrutosQuery, PagedResult<IngresosBrutosDto>>(query); var result = await _dispatcher.Send<ListIngresosBrutosQuery, PagedResult<IngresosBrutosDto>>(query);
return Ok(new return Ok(new
{ {
Items = result.Items.Select(FiscalContractMapper.ToIibbResponse).ToList(), Items = result.Items.Select(FiscalContractMapper.ToIibbResponse).ToList(),
result.Page, result.Page,
result.PageSize, result.PageSize,
result.Total result.Total
@@ -335,7 +335,7 @@ public sealed class FiscalController : ControllerBase
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetIibbById([FromRoute] int id) public async Task<IActionResult> GetIibbById([FromRoute] int id)
{ {
var query = new GetIngresosBrutosByIdQuery(id); var query = new GetIngresosBrutosByIdQuery(id);
var result = await _dispatcher.Send<GetIngresosBrutosByIdQuery, IngresosBrutosDto>(query); var result = await _dispatcher.Send<GetIngresosBrutosByIdQuery, IngresosBrutosDto>(query);
return Ok(FiscalContractMapper.ToIibbResponse(result)); return Ok(FiscalContractMapper.ToIibbResponse(result));
} }
@@ -348,7 +348,7 @@ public sealed class FiscalController : ControllerBase
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<IActionResult> GetHistorialIibb([FromRoute] int id) public async Task<IActionResult> GetHistorialIibb([FromRoute] int id)
{ {
var query = new GetHistorialIngresosBrutosQuery(id); var query = new GetHistorialIngresosBrutosQuery(id);
var result = await _dispatcher.Send<GetHistorialIngresosBrutosQuery, IReadOnlyList<HistorialCadenaIibbDto>>(query); var result = await _dispatcher.Send<GetHistorialIngresosBrutosQuery, IReadOnlyList<HistorialCadenaIibbDto>>(query);
return Ok(result.Select(FiscalContractMapper.ToHistorialIibbResponse).ToList()); return Ok(result.Select(FiscalContractMapper.ToHistorialIibbResponse).ToList());
} }
@@ -397,9 +397,9 @@ public sealed class FiscalController : ControllerBase
} }
var command = new CreateIngresosBrutosCommand( var command = new CreateIngresosBrutosCommand(
Provincia: provinciaEnum, Provincia: provinciaEnum,
Descripcion: request.Descripcion ?? string.Empty, Descripcion: request.Descripcion ?? string.Empty,
Alicuota: request.Alicuota ?? 0m, Alicuota: request.Alicuota ?? 0m,
VigenciaDesde: vigenciaDesde.Value, VigenciaDesde: vigenciaDesde.Value,
VigenciaHasta: vigenciaHasta); VigenciaHasta: vigenciaHasta);
@@ -453,9 +453,9 @@ public sealed class FiscalController : ControllerBase
return BadRequest(new { error = "Request body is required" }); return BadRequest(new { error = "Request body is required" });
var command = new UpdateIngresosBrutosCommand( var command = new UpdateIngresosBrutosCommand(
Id: id, Id: id,
Descripcion: request.Descripcion ?? string.Empty, Descripcion: request.Descripcion ?? string.Empty,
Activo: request.Activo ?? true); Activo: request.Activo ?? true);
var validation = await _updateIibbValidator.ValidateAsync(command); var validation = await _updateIibbValidator.ValidateAsync(command);
if (!validation.IsValid) if (!validation.IsValid)
@@ -518,7 +518,7 @@ public sealed class FiscalController : ControllerBase
public async Task<IActionResult> DeactivateIibb([FromRoute] int id) public async Task<IActionResult> DeactivateIibb([FromRoute] int id)
{ {
var command = new DeactivateIngresosBrutosCommand(id); var command = new DeactivateIngresosBrutosCommand(id);
var result = await _dispatcher.Send<DeactivateIngresosBrutosCommand, IngresosBrutosDto>(command); var result = await _dispatcher.Send<DeactivateIngresosBrutosCommand, IngresosBrutosDto>(command);
return Ok(FiscalContractMapper.ToIibbResponse(result)); return Ok(FiscalContractMapper.ToIibbResponse(result));
} }
@@ -532,7 +532,7 @@ public sealed class FiscalController : ControllerBase
public async Task<IActionResult> ReactivateIibb([FromRoute] int id) public async Task<IActionResult> ReactivateIibb([FromRoute] int id)
{ {
var command = new ReactivateIngresosBrutosCommand(id); var command = new ReactivateIngresosBrutosCommand(id);
var result = await _dispatcher.Send<ReactivateIngresosBrutosCommand, IngresosBrutosDto>(command); var result = await _dispatcher.Send<ReactivateIngresosBrutosCommand, IngresosBrutosDto>(command);
return Ok(FiscalContractMapper.ToIibbResponse(result)); return Ok(FiscalContractMapper.ToIibbResponse(result));
} }

View File

@@ -9,7 +9,7 @@ namespace SIGCM2.Application.Common;
/// </summary> /// </summary>
public sealed record PermisosOverride( public sealed record PermisosOverride(
[property: JsonPropertyName("grant")] IReadOnlyList<string> Grant, [property: JsonPropertyName("grant")] IReadOnlyList<string> Grant,
[property: JsonPropertyName("deny")] IReadOnlyList<string> Deny) [property: JsonPropertyName("deny")] IReadOnlyList<string> Deny)
{ {
/// <summary>No overrides — empty grant and deny.</summary> /// <summary>No overrides — empty grant and deny.</summary>
public static readonly PermisosOverride Empty = public static readonly PermisosOverride Empty =
@@ -46,7 +46,7 @@ public sealed record PermisosOverride(
return new PermisosOverride( return new PermisosOverride(
parsed.Grant ?? Array.Empty<string>(), parsed.Grant ?? Array.Empty<string>(),
parsed.Deny ?? Array.Empty<string>()); parsed.Deny ?? Array.Empty<string>());
} }
catch (JsonException) catch (JsonException)
{ {

View File

@@ -37,7 +37,7 @@ public sealed class UpdateUsuarioPermisosOverridesCommandHandler
public async Task<UsuarioPermisosDto> Handle(UpdateUsuarioPermisosOverridesCommand command) public async Task<UsuarioPermisosDto> Handle(UpdateUsuarioPermisosOverridesCommand command)
{ {
var grant = command.Grant ?? []; var grant = command.Grant ?? [];
var deny = command.Deny ?? []; var deny = command.Deny ?? [];
// 1. Overlap check — grant ∩ deny → 400 // 1. Overlap check — grant ∩ deny → 400
var overlap = grant.Intersect(deny, StringComparer.Ordinal).ToArray(); var overlap = grant.Intersect(deny, StringComparer.Ordinal).ToArray();

View File

@@ -40,30 +40,30 @@ public static class ProvinciaArgentinaExtensions
{ {
private static readonly Dictionary<ProvinciaArgentina, string> DisplayNames = new() private static readonly Dictionary<ProvinciaArgentina, string> DisplayNames = new()
{ {
[ProvinciaArgentina.BuenosAires] = "Buenos Aires", [ProvinciaArgentina.BuenosAires] = "Buenos Aires",
[ProvinciaArgentina.Catamarca] = "Catamarca", [ProvinciaArgentina.Catamarca] = "Catamarca",
[ProvinciaArgentina.Chaco] = "Chaco", [ProvinciaArgentina.Chaco] = "Chaco",
[ProvinciaArgentina.Chubut] = "Chubut", [ProvinciaArgentina.Chubut] = "Chubut",
[ProvinciaArgentina.CiudadAutonomaDeBuenosAires] = "Ciudad Autónoma de Buenos Aires", [ProvinciaArgentina.CiudadAutonomaDeBuenosAires] = "Ciudad Autónoma de Buenos Aires",
[ProvinciaArgentina.Cordoba] = "Córdoba", [ProvinciaArgentina.Cordoba] = "Córdoba",
[ProvinciaArgentina.Corrientes] = "Corrientes", [ProvinciaArgentina.Corrientes] = "Corrientes",
[ProvinciaArgentina.EntreRios] = "Entre Ríos", [ProvinciaArgentina.EntreRios] = "Entre Ríos",
[ProvinciaArgentina.Formosa] = "Formosa", [ProvinciaArgentina.Formosa] = "Formosa",
[ProvinciaArgentina.Jujuy] = "Jujuy", [ProvinciaArgentina.Jujuy] = "Jujuy",
[ProvinciaArgentina.LaPampa] = "La Pampa", [ProvinciaArgentina.LaPampa] = "La Pampa",
[ProvinciaArgentina.LaRioja] = "La Rioja", [ProvinciaArgentina.LaRioja] = "La Rioja",
[ProvinciaArgentina.Mendoza] = "Mendoza", [ProvinciaArgentina.Mendoza] = "Mendoza",
[ProvinciaArgentina.Misiones] = "Misiones", [ProvinciaArgentina.Misiones] = "Misiones",
[ProvinciaArgentina.Neuquen] = "Neuquén", [ProvinciaArgentina.Neuquen] = "Neuquén",
[ProvinciaArgentina.RioNegro] = "Río Negro", [ProvinciaArgentina.RioNegro] = "Río Negro",
[ProvinciaArgentina.Salta] = "Salta", [ProvinciaArgentina.Salta] = "Salta",
[ProvinciaArgentina.SanJuan] = "San Juan", [ProvinciaArgentina.SanJuan] = "San Juan",
[ProvinciaArgentina.SanLuis] = "San Luis", [ProvinciaArgentina.SanLuis] = "San Luis",
[ProvinciaArgentina.SantaCruz] = "Santa Cruz", [ProvinciaArgentina.SantaCruz] = "Santa Cruz",
[ProvinciaArgentina.SantaFe] = "Santa Fe", [ProvinciaArgentina.SantaFe] = "Santa Fe",
[ProvinciaArgentina.SantiagoDelEstero] = "Santiago del Estero", [ProvinciaArgentina.SantiagoDelEstero] = "Santiago del Estero",
[ProvinciaArgentina.TierraDelFuego] = "Tierra del Fuego", [ProvinciaArgentina.TierraDelFuego] = "Tierra del Fuego",
[ProvinciaArgentina.Tucuman] = "Tucumán", [ProvinciaArgentina.Tucuman] = "Tucumán",
}; };
private static readonly Dictionary<string, ProvinciaArgentina> ByDisplayName = private static readonly Dictionary<string, ProvinciaArgentina> ByDisplayName =

View File

@@ -8,35 +8,35 @@ namespace SIGCM2.Domain.Permissions;
public static class Permiso public static class Permiso
{ {
// ── Ventas: contado ────────────────────────────────────────────────────── // ── Ventas: contado ──────────────────────────────────────────────────────
public const string VentasContadoCrear = "ventas:contado:crear"; public const string VentasContadoCrear = "ventas:contado:crear";
public const string VentasContadoModificar = "ventas:contado:modificar"; public const string VentasContadoModificar = "ventas:contado:modificar";
public const string VentasContadoCobrar = "ventas:contado:cobrar"; public const string VentasContadoCobrar = "ventas:contado:cobrar";
public const string VentasContadoFacturar = "ventas:contado:facturar"; public const string VentasContadoFacturar = "ventas:contado:facturar";
// ── Ventas: cuenta corriente ───────────────────────────────────────────── // ── Ventas: cuenta corriente ─────────────────────────────────────────────
public const string VentasCtacteCrear = "ventas:ctacte:crear"; public const string VentasCtacteCrear = "ventas:ctacte:crear";
public const string VentasCtacteFacturar = "ventas:ctacte:facturar"; public const string VentasCtacteFacturar = "ventas:ctacte:facturar";
// ── Textos ─────────────────────────────────────────────────────────────── // ── Textos ───────────────────────────────────────────────────────────────
public const string TextosEditar = "textos:editar"; public const string TextosEditar = "textos:editar";
public const string TextosReclamosVer = "textos:reclamos:ver"; public const string TextosReclamosVer = "textos:reclamos:ver";
// ── Pauta ──────────────────────────────────────────────────────────────── // ── Pauta ────────────────────────────────────────────────────────────────
public const string PautaAzanuVer = "pauta:azanu:ver"; public const string PautaAzanuVer = "pauta:azanu:ver";
public const string PautaLimpiar = "pauta:limpiar"; public const string PautaLimpiar = "pauta:limpiar";
public const string PautaRecursosFueraDeHora = "pauta:recursos:fueradehora"; public const string PautaRecursosFueraDeHora = "pauta:recursos:fueradehora";
// ── Productores ────────────────────────────────────────────────────────── // ── Productores ──────────────────────────────────────────────────────────
public const string ProductoresDeudaVer = "productores:deuda:ver"; public const string ProductoresDeudaVer = "productores:deuda:ver";
public const string ProductoresPendientesCrear = "productores:pendientes:crear"; public const string ProductoresPendientesCrear = "productores:pendientes:crear";
public const string ProductoresDeudaBypass = "productores:deuda:bypass"; public const string ProductoresDeudaBypass = "productores:deuda:bypass";
// ── Administración ─────────────────────────────────────────────────────── // ── Administración ───────────────────────────────────────────────────────
public const string AdministracionUsuariosGestionar = "administracion:usuarios:gestionar"; public const string AdministracionUsuariosGestionar = "administracion:usuarios:gestionar";
public const string AdministracionTarifariosGestionar = "administracion:tarifarios:gestionar"; public const string AdministracionTarifariosGestionar = "administracion:tarifarios:gestionar";
public const string AdministracionMediosGestionar = "administracion:medios:gestionar"; public const string AdministracionMediosGestionar = "administracion:medios:gestionar";
public const string AdministracionAuditoriaVer = "administracion:auditoria:ver"; public const string AdministracionAuditoriaVer = "administracion:auditoria:ver";
public const string AdministracionFiscalGestionar = "administracion:fiscal:gestionar"; public const string AdministracionFiscalGestionar = "administracion:fiscal:gestionar";
/// <summary> /// <summary>
/// Set completo de todos los códigos canónicos (útil para validación y seeds). /// Set completo de todos los códigos canónicos (útil para validación y seeds).

View File

@@ -57,7 +57,7 @@ public static class JsonSanitizer
} }
break; break;
// JsonValue: scalar, nothing to strip // JsonValue: scalar, nothing to strip
} }
} }
} }

View File

@@ -20,7 +20,7 @@ public sealed class FiscalControllerTests : IAsyncLifetime
private const string TestConnectionString = private const string TestConnectionString =
"Server=TECNICA3;Database=SIGCM2_Test;User Id=desarrollo;Password=desarrollo2026;TrustServerCertificate=True;"; "Server=TECNICA3;Database=SIGCM2_Test;User Id=desarrollo;Password=desarrollo2026;TrustServerCertificate=True;";
private const string IvaEndpoint = "/api/v1/admin/fiscal/iva"; private const string IvaEndpoint = "/api/v1/admin/fiscal/iva";
private const string IibbEndpoint = "/api/v1/admin/fiscal/iibb"; private const string IibbEndpoint = "/api/v1/admin/fiscal/iibb";
private const string AdminUsername = "admin"; private const string AdminUsername = "admin";
private const string AdminPassword = "@Diego550@"; private const string AdminPassword = "@Diego550@";

View File

@@ -44,7 +44,7 @@ public sealed class PermisoResolverTests
Assert.DoesNotContain("A", result); Assert.DoesNotContain("A", result);
Assert.Contains("B", result); Assert.Contains("B", result);
Assert.Equal(1, result.Count); Assert.Single(result);
} }
// R-04: Grant duplicado (ya en rol) → idempotente, no duplicados // R-04: Grant duplicado (ya en rol) → idempotente, no duplicados

View File

@@ -66,10 +66,10 @@ public class TempPasswordGeneratorTests
{ {
var pwd = TempPasswordGenerator.Generate(12); var pwd = TempPasswordGenerator.Generate(12);
Assert.True(pwd.Length >= 12); Assert.True(pwd.Length >= 12);
Assert.True(pwd.Any(char.IsUpper)); Assert.Contains(pwd, char.IsUpper);
Assert.True(pwd.Any(char.IsLower)); Assert.Contains(pwd, char.IsLower);
Assert.True(pwd.Any(char.IsDigit)); Assert.Contains(pwd, char.IsDigit);
Assert.True(pwd.Any(c => symbols.Contains(c))); Assert.Contains(pwd, c => symbols.Contains(c));
} }
} }

View File

@@ -154,9 +154,17 @@ public sealed class JsonSanitizerTests
var input = new var input = new
{ {
password = "1", passwordHash = "2", token = "3", refreshToken = "4", password = "1",
accessToken = "5", cvv = "6", card = "7", cardNumber = "8", passwordHash = "2",
secret = "9", apiKey = "10", privateKey = "11", token = "3",
refreshToken = "4",
accessToken = "5",
cvv = "6",
card = "7",
cardNumber = "8",
secret = "9",
apiKey = "10",
privateKey = "11",
keep = "yes", keep = "yes",
}; };

View File

@@ -30,8 +30,8 @@ public class AssignPermisosToRolCommandHandlerTests
public async Task Handle_HappyPath_CallsReplaceWithCorrectIds() public async Task Handle_HappyPath_CallsReplaceWithCorrectIds()
{ {
_rolRepository.GetByCodigoAsync("cajero").Returns(MakeRol(5, "cajero")); _rolRepository.GetByCodigoAsync("cajero").Returns(MakeRol(5, "cajero"));
var permisoCrear = MakePermiso(1, "ventas:contado:crear"); var permisoCrear = MakePermiso(1, "ventas:contado:crear");
var permisoFact = MakePermiso(2, "ventas:contado:facturar"); var permisoFact = MakePermiso(2, "ventas:contado:facturar");
_permisoRepository.GetByCodigosAsync(Arg.Any<IEnumerable<string>>()) _permisoRepository.GetByCodigosAsync(Arg.Any<IEnumerable<string>>())
.Returns(new List<Permiso> { permisoCrear, permisoFact }); .Returns(new List<Permiso> { permisoCrear, permisoFact });

View File

@@ -42,7 +42,7 @@ public class ListTiposDeIvaQueryHandlerTests
var result = await _handler.Handle(new ListTiposDeIvaQuery(1, 10, null, null)); var result = await _handler.Handle(new ListTiposDeIvaQuery(1, 10, null, null));
Assert.Equal(0, result.Items.Count); Assert.Empty(result.Items);
Assert.Equal(0, result.Total); Assert.Equal(0, result.Total);
} }

View File

@@ -23,7 +23,7 @@ public sealed class TestWebAppFactory : WebApplicationFactory<Program>, IAsyncLi
// Resolved once — absolute paths independent of working directory // Resolved once — absolute paths independent of working directory
private static readonly string RepoRoot = ResolveRepoRoot(); private static readonly string RepoRoot = ResolveRepoRoot();
private static readonly string PrivateKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "private.pem"); private static readonly string PrivateKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "private.pem");
private static readonly string PublicKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "public.pem"); private static readonly string PublicKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "public.pem");
private readonly SqlTestFixture _dbFixture = new(TestConnectionString); private readonly SqlTestFixture _dbFixture = new(TestConnectionString);
@@ -36,17 +36,17 @@ public sealed class TestWebAppFactory : WebApplicationFactory<Program>, IAsyncLi
// This ensures our paths win over appsettings.json // This ensures our paths win over appsettings.json
config.AddInMemoryCollection(new Dictionary<string, string?> config.AddInMemoryCollection(new Dictionary<string, string?>
{ {
["ConnectionStrings:SqlServer"] = TestConnectionString, ["ConnectionStrings:SqlServer"] = TestConnectionString,
["Jwt:Issuer"] = "sigcm2.api", ["Jwt:Issuer"] = "sigcm2.api",
["Jwt:Audience"] = "sigcm2.web", ["Jwt:Audience"] = "sigcm2.web",
["Jwt:AccessTokenMinutes"] = "60", ["Jwt:AccessTokenMinutes"] = "60",
["Jwt:RefreshTokenDays"] = "7", ["Jwt:RefreshTokenDays"] = "7",
["Jwt:PrivateKeyPath"] = PrivateKeyPath, ["Jwt:PrivateKeyPath"] = PrivateKeyPath,
["Jwt:PublicKeyPath"] = PublicKeyPath, ["Jwt:PublicKeyPath"] = PublicKeyPath,
["Jwt:PrivateKey"] = null, ["Jwt:PrivateKey"] = null,
["Jwt:PublicKey"] = null, ["Jwt:PublicKey"] = null,
["Cors:AllowedOrigins:0"] = "http://localhost:5173", ["Cors:AllowedOrigins:0"] = "http://localhost:5173",
["Serilog:MinimumLevel:Default"] = "Warning", ["Serilog:MinimumLevel:Default"] = "Warning",
}); });
}); });