using System.Text.Json; using JdeScoping.ConfigManager.Core.Models; using Shouldly; using Xunit; namespace JdeScoping.ConfigManager.Core.Tests.Models; public class ConnectionStringsSectionConverterTests { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true }; [Fact] public void Deserialize_StandardDictionaryFormat_ParsesAllConnections() { // Arrange var json = """ { "LotFinder": "Server=localhost,1434;Database=ScopingTool;User Id=sa;Password=test", "JDE": "Data Source=jde-server:1521/JDEPROD;User Id=jdeuser;Password=jdepass", "CMS": "Data Source=cms-server:1521/CMSPROD;User Id=cmsuser;Password=cmspass" } """; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert section.ShouldNotBeNull(); section.Entries.Count.ShouldBe(3); var lotFinder = section.Entries.First(e => e.Name == "LotFinder"); lotFinder.Provider.ShouldBe(ConnectionProvider.SqlServer); lotFinder.Server.ShouldBe("localhost,1434"); // Port embedded in server, not parsed separately lotFinder.SqlServerPort.ShouldBeNull(); lotFinder.Database.ShouldBe("ScopingTool"); lotFinder.UserId.ShouldBe("sa"); var jde = section.Entries.First(e => e.Name == "JDE"); jde.Provider.ShouldBe(ConnectionProvider.Oracle); jde.Host.ShouldBe("jde-server"); jde.Port.ShouldBe(1521); jde.ServiceName.ShouldBe("JDEPROD"); } [Fact] public void Deserialize_SqlServerConnection_ParsesAllFields() { // Arrange var json = """ { "TestDb": "Server=myserver;Database=TestDB;User Id=testuser;Password=testpass;Encrypt=True;TrustServerCertificate=True;Connection Timeout=60;Application Name=TestApp" } """; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert section.ShouldNotBeNull(); section.Entries.Count.ShouldBe(1); var entry = section.Entries[0]; entry.Name.ShouldBe("TestDb"); entry.Provider.ShouldBe(ConnectionProvider.SqlServer); entry.Server.ShouldBe("myserver"); entry.Database.ShouldBe("TestDB"); entry.UserId.ShouldBe("testuser"); entry.Password.ShouldBe("testpass"); entry.Encrypt.ShouldBe("True"); entry.TrustServerCertificate.ShouldBeTrue(); entry.ConnectionTimeout.ShouldBe(60); entry.ApplicationName.ShouldBe("TestApp"); } [Fact] public void Deserialize_OracleConnection_ParsesHostPortService() { // Arrange var json = """ { "Oracle": "Data Source=//db-host:1523/PRODDB;User Id=orauser;Password=orapass" } """; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert section.ShouldNotBeNull(); section.Entries.Count.ShouldBe(1); var entry = section.Entries[0]; entry.Name.ShouldBe("Oracle"); entry.Provider.ShouldBe(ConnectionProvider.Oracle); entry.Host.ShouldBe("db-host"); entry.Port.ShouldBe(1523); entry.ServiceName.ShouldBe("PRODDB"); entry.UserId.ShouldBe("orauser"); entry.Password.ShouldBe("orapass"); } [Fact] public void Deserialize_EmptyObject_ReturnsEmptyEntries() { // Arrange var json = "{}"; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert section.ShouldNotBeNull(); section.Entries.ShouldBeEmpty(); } [Fact] public void Serialize_ToStandardDictionaryFormat() { // Arrange var section = new ConnectionStringsSection { Entries = new List { new() { Name = "TestDb", Provider = ConnectionProvider.SqlServer, Server = "myserver", Database = "TestDB", UserId = "testuser", Password = "testpass" } } }; // Act var json = JsonSerializer.Serialize(section, JsonOptions); // Assert json.ShouldNotBeNull(); json.ShouldContain("\"TestDb\""); json.ShouldContain("Server=myserver"); json.ShouldContain("Database=TestDB"); } [Fact] public void RoundTrip_PreservesConnections() { // Arrange var original = new ConnectionStringsSection { Entries = new List { new() { Name = "Primary", Provider = ConnectionProvider.SqlServer, Server = "server1", Database = "DB1", UserId = "user1", Password = "pass1" }, new() { Name = "Secondary", Provider = ConnectionProvider.Oracle, Host = "oracle-host", Port = 1521, ServiceName = "ORCL", UserId = "user2", Password = "pass2" } } }; // Act var json = JsonSerializer.Serialize(original, JsonOptions); var deserialized = JsonSerializer.Deserialize(json, JsonOptions); // Assert deserialized.ShouldNotBeNull(); deserialized.Entries.Count.ShouldBe(2); var primary = deserialized.Entries.First(e => e.Name == "Primary"); primary.Provider.ShouldBe(ConnectionProvider.SqlServer); primary.Server.ShouldBe("server1"); primary.Database.ShouldBe("DB1"); var secondary = deserialized.Entries.First(e => e.Name == "Secondary"); secondary.Provider.ShouldBe(ConnectionProvider.Oracle); secondary.Host.ShouldBe("oracle-host"); secondary.Port.ShouldBe(1521); secondary.ServiceName.ShouldBe("ORCL"); } [Fact] public void Deserialize_SqlServerWithEmbeddedPort_KeepsPortInServer() { // Arrange - connection string with port embedded in server name (legacy format) var json = """ { "TestDb": "Server=localhost,1434;Database=TestDB;User Id=testuser;Password=testpass" } """; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert - port is NOT parsed out, stays embedded in server name section.ShouldNotBeNull(); section.Entries.Count.ShouldBe(1); var entry = section.Entries[0]; entry.Name.ShouldBe("TestDb"); entry.Provider.ShouldBe(ConnectionProvider.SqlServer); entry.Server.ShouldBe("localhost,1434"); // Port stays in server name entry.SqlServerPort.ShouldBeNull(); // Port control not populated from parsing entry.Database.ShouldBe("TestDB"); } [Fact] public void Deserialize_SqlServerWithoutPort_ServerHasNoPort() { // Arrange var json = """ { "TestDb": "Server=myserver;Database=TestDB;User Id=testuser;Password=testpass" } """; // Act var section = JsonSerializer.Deserialize(json, JsonOptions); // Assert section.ShouldNotBeNull(); section.Entries.Count.ShouldBe(1); var entry = section.Entries[0]; entry.Server.ShouldBe("myserver"); entry.SqlServerPort.ShouldBeNull(); } [Fact] public void RoundTrip_SqlServerWithPort_EmbedsPortInServer() { // Arrange - entry with separate port control var original = new ConnectionStringsSection { Entries = new List { new() { Name = "WithPort", Provider = ConnectionProvider.SqlServer, Server = "localhost", SqlServerPort = 1434, Database = "DB1", UserId = "user1", Password = "pass1" } } }; // Act var json = JsonSerializer.Serialize(original, JsonOptions); var deserialized = JsonSerializer.Deserialize(json, JsonOptions); // Assert - after round trip, port is embedded in server name (not parsed back out) deserialized.ShouldNotBeNull(); var entry = deserialized.Entries.First(); entry.Server.ShouldBe("localhost,1434"); // Port embedded in server after round trip entry.SqlServerPort.ShouldBeNull(); // Port control not populated from parsing } }