Files
Omika/tests/Omika.Tests/Mobile/Local/ParametreMetierLocalServiceTests.cs
2026-10-23 18:46:50 +02:00

184 lines
7.0 KiB
C#

using Omika.App.Local.Abstractions;
using Omika.App.Local.Models;
using Omika.App.Local.Services;
using Omika.Core.Contracts.Common;
using Omika.Core.Contracts.Configuration;
using Omika.Core.Contracts.Mobile.License;
namespace Omika.Tests.Mobile.Local;
/// <summary>
/// Tests du service local de référentiel ParametreMetier (TypeTemps).
/// Vérifie que <see cref="IParametreMetierLocalService.GetTypeTempsAsync"/>
/// retourne uniquement les types de temps depuis le bootstrap local, sans
/// aucun appel API, avec la clé métier canonique et le libellé métier.
/// </summary>
public sealed class ParametreMetierLocalServiceTests
{
[Fact]
public async Task GetTypeTempsAsync_RetourneUniquementLesTypeTemps_Batik()
{
// Arrange : référentiel Batik (groupe TypeTemps porté par PA_Code = "18").
var bootstrap = new LocalBootstrapState
{
ParametresMetier =
[
new ParametreMetierDto { Id = "TRAVAIL", Code = "18", Libelle = "Travail", Ordre = 1 },
new ParametreMetierDto { Id = "TRAJET", Code = "18", Libelle = "Trajet", Ordre = 2 },
new ParametreMetierDto { Id = "PAUSE", Code = "18", Libelle = "Pause", Ordre = 3 },
new ParametreMetierDto { Id = "AUTRE", Code = "99", Libelle = "Autre catégorie", Ordre = 4 }
]
};
var service = CreateService(bootstrap);
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert
Assert.Equal(3, result.Count);
Assert.All(result, r => Assert.Equal("18", r.Code));
Assert.Equal("TRAVAIL", result[0].Key);
Assert.Equal("Travail", result[0].Label);
Assert.Equal("TRAJET", result[1].Key);
Assert.Equal("Trajet", result[1].Label);
Assert.Equal("PAUSE", result[2].Key);
Assert.Equal("Pause", result[2].Label);
}
[Fact]
public async Task GetTypeTempsAsync_RetourneUniquementLesTypeTemps_Omika()
{
// Arrange : référentiel Omika (groupe TypeTemps porté par PA_Categorie = "18").
var bootstrap = new LocalBootstrapState
{
ParametresMetier =
[
new ParametreMetierDto { Id = "TT-01", Categorie = "18", Libelle = "Travail", Ordre = 1 },
new ParametreMetierDto { Id = "TT-02", Categorie = "18", Libelle = "Trajet", Ordre = 2 },
new ParametreMetierDto { Id = "AUTRE", Categorie = "99", Libelle = "Autre catégorie", Ordre = 3 }
]
};
var service = CreateService(bootstrap);
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert
Assert.Equal(2, result.Count);
Assert.Equal("TT-01", result[0].Key);
Assert.Equal("Travail", result[0].Label);
Assert.Equal("TT-02", result[1].Key);
Assert.Equal("Trajet", result[1].Label);
}
[Fact]
public async Task GetTypeTempsAsync_KeyEstLaCleMetierCanonique()
{
// Arrange : la clé exposée doit être la clé métier (Id), jamais un PK HFSQL.
var bootstrap = new LocalBootstrapState
{
ParametresMetier =
[
new ParametreMetierDto { Id = "CLE_METIER_TT", Code = "18", Libelle = "Travail", Ordre = 1 }
]
};
var service = CreateService(bootstrap);
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert
ReferenceValueDto option = Assert.Single(result);
Assert.Equal("CLE_METIER_TT", option.Key);
Assert.Equal("CLE_METIER_TT", option.Key);
}
[Fact]
public async Task GetTypeTempsAsync_LabelVientDuLibelleMetier()
{
// Arrange : le libellé exposé doit être le libellé métier, pas le code technique.
var bootstrap = new LocalBootstrapState
{
ParametresMetier =
[
new ParametreMetierDto { Id = "TT-01", Code = "18", Libelle = "Déplacement client", Ordre = 1 }
]
};
var service = CreateService(bootstrap);
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert
ReferenceValueDto option = Assert.Single(result);
Assert.Equal("Déplacement client", option.Label);
Assert.NotEqual("TT-01", option.Label);
}
[Fact]
public async Task GetTypeTempsAsync_SansBootstrap_RetourneListeVide()
{
// Arrange : aucune session / bootstrap local.
var service = new ParametreMetierLocalService(new FakeSessionService(null));
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert
Assert.Empty(result);
}
[Fact]
public async Task GetTypeTempsAsync_ConserveLOrdreMetier()
{
// Arrange : l'ordre du bootstrap (PA_Ordre) est conservé, pas de tri par libellé.
var bootstrap = new LocalBootstrapState
{
ParametresMetier =
[
new ParametreMetierDto { Id = "Z", Code = "18", Libelle = "Zulu", Ordre = 1 },
new ParametreMetierDto { Id = "A", Code = "18", Libelle = "Alpha", Ordre = 2 }
]
};
var service = CreateService(bootstrap);
// Act
IReadOnlyList<ReferenceValueDto> result = await service.GetTypeTempsAsync();
// Assert : l'ordre métier (Z avant A) est conservé, pas de tri alphabétique.
Assert.Equal("Z", result[0].Key);
Assert.Equal("A", result[1].Key);
}
private static ParametreMetierLocalService CreateService(LocalBootstrapState bootstrap)
=> new(new FakeSessionService(bootstrap));
private sealed class FakeSessionService : IMobileSessionService
{
private readonly LocalBootstrapState? _bootstrap;
public FakeSessionService(LocalBootstrapState? bootstrap) => _bootstrap = bootstrap;
public Task<bool> HasValidSessionAsync(CancellationToken cancellationToken = default) => Task.FromResult(true);
public Task<bool> HasExpiredSessionAsync(CancellationToken cancellationToken = default) => Task.FromResult(false);
public Task<LicenseResponse> ActivateAsync(string codeClient, string numeroLicence, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
public Task<LicenseResponse> ValidateAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
public Task<LocalBootstrapState?> GetBootstrapAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(_bootstrap);
public Task<string?> GetAccessTokenAsync(CancellationToken cancellationToken = default) => Task.FromResult<string?>(null);
public Task ClearSessionAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
public Task EnsureDevelopmentSessionAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
}
}