Files
Joseph Doherty 1fc7792cd1 refactor(configmanager): rename UI project and split test projects
Rename ConfigManager to ConfigManager.Ui to match the Core/CLI/UI project
structure, and split the monolithic test project into Core.Tests,
Cli.Tests, and Ui.Tests to align with the source project organization.
2026-01-28 10:24:36 -05:00

279 lines
9.2 KiB
C#

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<ConnectionStringsSection>(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<ConnectionStringsSection>(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<ConnectionStringsSection>(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<ConnectionStringsSection>(json, JsonOptions);
// Assert
section.ShouldNotBeNull();
section.Entries.ShouldBeEmpty();
}
[Fact]
public void Serialize_ToStandardDictionaryFormat()
{
// Arrange
var section = new ConnectionStringsSection
{
Entries = new List<ConnectionStringEntry>
{
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<ConnectionStringEntry>
{
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<ConnectionStringsSection>(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<ConnectionStringsSection>(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<ConnectionStringsSection>(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<ConnectionStringEntry>
{
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<ConnectionStringsSection>(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
}
}