using System.Text.Json; using Omika.Data.Connection; using Omika.Data.HfSql.Connection; namespace Omika.Tests.Connection; /// /// Tests d'intégration OLE DB HFSQL réels pour les tables Intervention. /// /// Ces tests nécessitent un serveur HFSQL accessible et le provider OLE DB /// PCSOFT.HFSQL installé. Ils sont ignorés automatiquement si la /// configuration locale n'est pas disponible ou si le serveur est injoignable. /// /// Aucun secret n'est affiché : les assertions portent uniquement sur les /// modes d'accès observés. /// public class HfSqlOleDbInterventionIntegrationTests { private const string ConfigPath = @"D:\Avalonia\Omika\config\hfsql-test.local.json"; private sealed class TestConfig { public int Port { get; set; } public string Server { get; set; } = ""; public string ProtectionPlusSecret { get; set; } = ""; public FilePasswordsConfig FilePasswords { get; set; } = new(); public DatabaseConfig Batik { get; set; } = new(); public DatabaseConfig Omika { get; set; } = new(); } private sealed class FilePasswordsConfig { public string? ProtectionStd { get; set; } public string? ProtectionPlus { get; set; } } private sealed class DatabaseConfig { public string Credential { get; set; } = ""; public string Database { get; set; } = ""; public string User { get; set; } = ""; public string? OriginalDatabaseName { get; set; } } private static TestConfig? LoadConfig() { if (!File.Exists(ConfigPath)) return null; try { var json = File.ReadAllText(ConfigPath); return JsonSerializer.Deserialize( json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } catch { return null; } } private static HfSqlConnectionOptions BuildOptions(TestConfig config, DatabaseConfig db) { return new HfSqlConnectionOptions { Server = config.Server, Port = config.Port, Database = db.Database, User = db.User, Credential = db.Credential, FilePasswords = new HfSqlFilePasswordOptions { ProtectionStd = config.FilePasswords.ProtectionStd, ProtectionPlus = config.FilePasswords.ProtectionPlus } }; } [Fact] public async Task ResolveAsync_Batik_Intervention_IsAccessible() { var config = LoadConfig(); if (config is null) return; // config absente : test ignoré var options = BuildOptions(config, config.Batik); var factory = new HfSqlOleDbConnectionFactory(); var resolver = new HfSqlFileAccessResolver(factory, options); var files = new List { new() { LogicalFile = "Intervention", ExpectedGroup = "ProtectionStd" } }; try { var result = await resolver.ResolveAsync(files); Assert.True(result["Intervention"].IsAccessible, $"Intervention Batik doit être accessible (mode observé : {result["Intervention"].ObservedAccess})"); } catch (Exception ex) when (IsServerUnavailable(ex)) { return; // serveur injoignable : test ignoré } } [Fact] public async Task ResolveAsync_Omika_Intervention_IsAccessible() { var config = LoadConfig(); if (config is null) return; var options = BuildOptions(config, config.Omika); var factory = new HfSqlOleDbConnectionFactory(); var resolver = new HfSqlFileAccessResolver(factory, options); var files = new List { new() { LogicalFile = "Intervention", ExpectedGroup = "ProtectionStd" } }; try { var result = await resolver.ResolveAsync(files); Assert.True(result["Intervention"].IsAccessible, $"Intervention Omika doit être accessible (mode observé : {result["Intervention"].ObservedAccess})"); } catch (Exception ex) when (IsServerUnavailable(ex)) { return; } } [Fact] public async Task ResolveAsync_Batik_EtatIntervention_IsAccessible() { var config = LoadConfig(); if (config is null) return; var options = BuildOptions(config, config.Batik); var factory = new HfSqlOleDbConnectionFactory(); var resolver = new HfSqlFileAccessResolver(factory, options); var files = new List { new() { LogicalFile = "EtatIntervention", ExpectedGroup = "ProtectionStd" } }; try { var result = await resolver.ResolveAsync(files); Assert.True(result["EtatIntervention"].IsAccessible, $"EtatIntervention Batik doit être accessible (mode observé : {result["EtatIntervention"].ObservedAccess})"); } catch (Exception ex) when (IsServerUnavailable(ex)) { return; } } [Fact(Skip = "ParametreMetier n'existe pas dans la base Batik de test (HFSQL 70114 : fichier non décrit) ; ce fichier n'existe qu'en schéma Omika. La cible du test est à revoir avant réactivation.")] public async Task ResolveAsync_Batik_ParametreMetier_IsAccessible() { var config = LoadConfig(); if (config is null) return; var options = BuildOptions(config, config.Batik); var factory = new HfSqlOleDbConnectionFactory(); var resolver = new HfSqlFileAccessResolver(factory, options); var files = new List { new() { LogicalFile = "ParametreMetier", ExpectedGroup = "ProtectionStd" } }; try { var result = await resolver.ResolveAsync(files); Assert.True(result["ParametreMetier"].IsAccessible, $"ParametreMetier Batik doit être accessible (mode observé : {result["ParametreMetier"].ObservedAccess})"); } catch (Exception ex) when (IsServerUnavailable(ex)) { return; } } [Fact] public async Task ResolveAsync_Omika_ParametreMetier_IsAccessible() { var config = LoadConfig(); if (config is null) return; var options = BuildOptions(config, config.Omika); var factory = new HfSqlOleDbConnectionFactory(); var resolver = new HfSqlFileAccessResolver(factory, options); var files = new List { new() { LogicalFile = "ParametreMetier", ExpectedGroup = "ProtectionStd" } }; try { var result = await resolver.ResolveAsync(files); Assert.True(result["ParametreMetier"].IsAccessible, $"ParametreMetier Omika doit être accessible (mode observé : {result["ParametreMetier"].ObservedAccess})"); } catch (Exception ex) when (IsServerUnavailable(ex)) { return; } } private static bool IsServerUnavailable(Exception ex) { var message = ex.Message; return message.Contains("provider", StringComparison.OrdinalIgnoreCase) || message.Contains("serveur", StringComparison.OrdinalIgnoreCase) || message.Contains("server", StringComparison.OrdinalIgnoreCase) || message.Contains("connexion", StringComparison.OrdinalIgnoreCase) || message.Contains("connection", StringComparison.OrdinalIgnoreCase) || message.Contains("E_FAIL", StringComparison.OrdinalIgnoreCase) || message.Contains("0x80004005", StringComparison.OrdinalIgnoreCase); } }