Files
Omika/tests/Omika.Tests/Repositories/Batik/BatikMobileIdentityRepositoryTests.cs
2026-10-23 18:46:50 +02:00

158 lines
6.1 KiB
C#

using Omika.Core.Contracts.Mobile.Bootstrap;
using Omika.Data.Configuration;
using Omika.Data.Connection;
using Omika.Data.Repositories.Batik;
namespace Omika.Tests.Repositories.Batik;
/// <summary>
/// Tests du repository d'identité mobile Batik.
/// Vérifie que le chemin historique Batik continue de résoudre les permissions
/// (UT_IDTypeProfil → AccesEtDroit.AED_IDProfil + modules ParametreMetier) et
/// que l'utilisateur est désormais résolu par UT_PKID (et non par UT_Login).
/// </summary>
public class BatikMobileIdentityRepositoryTests
{
private const long UserIdTest = 1001;
private const long ProfilIdTest = 3001;
private const long ModulePkTest = 5001;
private const string LoginTest = "TEST_USER";
[Fact]
public async Task GetPermissionsAsync_ResoutParUT_PKID_EtRetourneALicMob()
{
var connection = new FakeHfsqlConnection(HfsqlConnectionState.Open);
connection.UtilisateurRows.Add(UtilisateurRow(UserIdTest, LoginTest, ProfilIdTest));
connection.ParametreMetierRows.Add(ModuleRow(ModulePkTest, "M.PlClb.11")); // → A.LIC.MOB
connection.AccesEtDroitRows.Add(DroitRow(ProfilIdTest, ModulePkTest, true));
var repository = new BatikMobileIdentityRepository(connection);
IReadOnlyDictionary<string, bool> permissions =
await repository.GetPermissionsAsync(UserIdTest.ToString());
Assert.True(permissions["A.LIC.MOB"]);
string utilisateurSql = connection.Queries.First(q => q.Contains("FROM Utilisateur", StringComparison.OrdinalIgnoreCase));
Assert.Contains("UT_PKID = ?", utilisateurSql);
Assert.DoesNotContain("UT_Login = ?", utilisateurSql);
}
[Fact]
public async Task GetLoginByUserIdAsync_RetourneLoginReel()
{
var connection = new FakeHfsqlConnection(HfsqlConnectionState.Open);
connection.UtilisateurRows.Add(UtilisateurRow(UserIdTest, LoginTest, ProfilIdTest));
var repository = new BatikMobileIdentityRepository(connection);
string? login = await repository.GetLoginByUserIdAsync(UserIdTest.ToString());
Assert.Equal(LoginTest, login);
}
[Fact]
public async Task GetProfileAsync_ResoutProfilBatik()
{
var connection = new FakeHfsqlConnection(HfsqlConnectionState.Open);
connection.UtilisateurRows.Add(UtilisateurRow(UserIdTest, LoginTest, ProfilIdTest));
connection.ParametreMetierRows.Add(ProfilRow(ProfilIdTest, "BATIK_PROFIL"));
var repository = new BatikMobileIdentityRepository(connection);
MobileProfileDto profile = await repository.GetProfileAsync(UserIdTest.ToString());
Assert.Equal("PROFIL", profile.Code);
Assert.Equal("BATIK_PROFIL", profile.Nom);
}
// ===== Fixtures =====
private static Dictionary<string, object?> UtilisateurRow(long pkId, string login, long profilId) => new()
{
["UT_PKID"] = pkId,
["UT_Login"] = login,
["UT_IDCollaborateur"] = 2001L,
["UT_IDTypeProfil"] = profilId,
["UT_AccesMobile"] = true
};
// Module de la catégorie 29 (« Modules intervenir ») : PA_Valeur = clé Batik.
private static Dictionary<string, object?> ModuleRow(long pkId, string valeur) => new()
{
["PA_PKID"] = pkId,
["PA_Code"] = "29",
["PA_Libelle"] = "Module",
["PA_Valeur"] = valeur,
["PA_Actif"] = true
};
private static Dictionary<string, object?> ProfilRow(long pkId, string libelle) => new()
{
["PA_PKID"] = pkId,
["PA_Code"] = "PROFIL",
["PA_Libelle"] = libelle,
["PA_Valeur"] = libelle,
["PA_Actif"] = true
};
private static Dictionary<string, object?> DroitRow(long profilId, long moduleId, bool acces) => new()
{
["AED_PKID"] = 4001L,
["AED_IDProfil"] = profilId,
["AED_IDModule"] = moduleId,
["AED_Acces"] = acces
};
// ===== Fake =====
private sealed class FakeHfsqlConnection : IHfsqlConnection
{
public FakeHfsqlConnection(HfsqlConnectionState state) => State = state;
public HfsqlOptions Options => new();
public HfsqlConnectionState State { get; private set; }
public List<Dictionary<string, object?>> UtilisateurRows { get; } = [];
public List<Dictionary<string, object?>> ParametreMetierRows { get; } = [];
public List<Dictionary<string, object?>> AccesEtDroitRows { get; } = [];
public List<string> Queries { get; } = [];
public Task OpenAsync(CancellationToken cancellationToken = default)
{
State = HfsqlConnectionState.Open;
return Task.CompletedTask;
}
public Task CloseAsync()
{
State = HfsqlConnectionState.Closed;
return Task.CompletedTask;
}
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
public Task<object?> ExecuteScalarAsync(string sql, IReadOnlyList<object?>? parameters = null, CancellationToken cancellationToken = default)
=> Task.FromResult<object?>(null);
public Task<int> ExecuteNonQueryAsync(string sql, IReadOnlyList<object?>? parameters = null, CancellationToken cancellationToken = default)
=> Task.FromResult(0);
public Task<IReadOnlyList<IReadOnlyDictionary<string, object?>>> QueryAsync(string sql, IReadOnlyList<object?>? parameters = null, CancellationToken cancellationToken = default)
{
Queries.Add(sql);
IReadOnlyList<IReadOnlyDictionary<string, object?>> result = sql switch
{
_ when sql.Contains("FROM Utilisateur", StringComparison.OrdinalIgnoreCase) => UtilisateurRows,
_ when sql.Contains("FROM ParametreMetier", StringComparison.OrdinalIgnoreCase) => ParametreMetierRows,
_ when sql.Contains("FROM AccesEtDroit", StringComparison.OrdinalIgnoreCase) => AccesEtDroitRows,
_ => []
};
return Task.FromResult(result);
}
public Task<IReadOnlyList<HfsqlColumnMetadata>> GetColumnsAsync(string tableName, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<HfsqlColumnMetadata>>([]);
}
}